Skip to content

Commit 6e2ca69

Browse files
author
Dan Liew
committed
[CMake] Change the WARNINGS_AS_ERRORS option from BOOL to STRING
to allow a new mode `SERIOUS_ONLY`. Modes: `ON` - All warnings are treated as errors (same as before) `OFF` - Warnings are not treated as errors (same as before) `SERIOUS_ONLY` - A subset of "serious" warnings are treated as errors. Upgrade code is included to upgrade old CMake cache's to use the new type of `WARNINGS_AS_ERRORS`. We should remove it eventually. The user's previous setting is preserved when doing this. Very few warnings are treated as errors for now. Developers can add more later as they see fit.
1 parent 2af08a3 commit 6e2ca69

File tree

3 files changed

+111
-8
lines changed

3 files changed

+111
-8
lines changed

README-CMake.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,8 @@ The following useful options can be passed to CMake whilst configuring.
266266
Disabling this is useful for faster incremental builds. The documentation can be manually built by invoking the ``api_docs`` target.
267267
* ``LINK_TIME_OPTIMIZATION`` - BOOL. If set to ``TRUE`` link time optimization will be enabled.
268268
* ``API_LOG_SYNC`` - BOOL. If set to ``TRUE`` will enable experimental API log sync feature.
269+
* ``WARNINGS_AS_ERRORS`` - STRING. If set to ``TRUE`` compiler warnings will be treated as errors. If set to ``False`` compiler warnings will not be treated as errors.
270+
If set to ``SERIOUS_ONLY`` a subset of compiler warnings will be treated as errors.
269271

270272
On the command line these can be passed to ``cmake`` using the ``-D`` option. In ``ccmake`` and ``cmake-gui`` these can be set in the user interface.
271273

@@ -381,3 +383,13 @@ It is tempting use file-globbing in ``CMakeLists.txt`` to find a set for files m
381383
use them as the sources to build a target. This however is a bad idea because it prevents CMake from knowing when it needs to rerun itself. This is why source file names are explicitly listed in the ``CMakeLists.txt`` so that when changes are made the source files used to build a target automatically triggers a rerun of CMake.
382384

383385
Long story short. Don't use file globbing.
386+
387+
### Serious warning flags
388+
389+
By default the `WARNINGS_AS_ERRORS` flag is set to `SERIOUS_ONLY` which means
390+
some warnings will be treated as errors. These warnings are controlled by the
391+
relevant `*_WARNINGS_AS_ERRORS` list defined in
392+
`cmake/compiler_warnings.cmake`.
393+
394+
Additional warnings should only be added here if the warnings has no false
395+
positives.

cmake/compiler_warnings.cmake

Lines changed: 91 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,61 @@
1+
################################################################################
2+
# Compiler warning flags
3+
################################################################################
4+
# These are passed to relevant compiler provided they are supported
15
set(GCC_AND_CLANG_WARNINGS
2-
"-Wall"
6+
"-Wall"
37
)
48
set(GCC_ONLY_WARNINGS "")
59
set(CLANG_ONLY_WARNINGS "")
610
set(MSVC_WARNINGS "/W3")
711

12+
################################################################################
13+
# Serious warnings
14+
################################################################################
15+
# This declares the flags that are passed to the compiler when
16+
# `WARNINGS_AS_ERRORS` is set to `SERIOUS_ONLY`. Only flags that are supported
17+
# by the compiler are used.
18+
#
19+
# In effect this a "whitelist" approach where we explicitly tell the compiler
20+
# which warnings we want to be treated as errors. The alternative would be a
21+
# "blacklist" approach where we ask the compiler to treat all warnings are
22+
# treated as errors but then we explicitly list which warnings which should be
23+
# allowed.
24+
#
25+
# The "whitelist" approach seems simpiler because we can incrementally add
26+
# warnings we "think are serious".
27+
28+
# TODO: Add more warnings that are considered serious enough that we should
29+
# treat them as errors.
30+
set(GCC_AND_CLANG_WARNINGS_AS_ERRORS
31+
# https://clang.llvm.org/docs/DiagnosticsReference.html#wodr
32+
"-Werror=odr"
33+
)
34+
set(GCC_WARNINGS_AS_ERRORS
35+
""
36+
)
37+
set(CLANG_WARNINGS_AS_ERRORS
38+
# https://clang.llvm.org/docs/DiagnosticsReference.html#wdelete-non-virtual-dtor
39+
"-Werror=delete-non-virtual-dtor"
40+
# https://clang.llvm.org/docs/DiagnosticsReference.html#woverloaded-virtual
41+
"-Werror=overloaded-virtual"
42+
)
43+
44+
################################################################################
45+
# Test warning/error flags
46+
################################################################################
847
set(WARNING_FLAGS_TO_CHECK "")
48+
set(WARNING_AS_ERROR_FLAGS_TO_CHECK "")
949
if ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU")
1050
list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS})
1151
list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_ONLY_WARNINGS})
52+
list(APPEND WARNING_AS_ERROR_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS_AS_ERRORS})
53+
list(APPEND WARNING_AS_ERROR_FLAGS_TO_CHECK ${GCC_WARNINGS_AS_ERRORS})
1254
elseif ("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang")
1355
list(APPEND WARNING_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS})
1456
list(APPEND WARNING_FLAGS_TO_CHECK ${CLANG_ONLY_WARNINGS})
57+
list(APPEND WARNING_AS_ERROR_FLAGS_TO_CHECK ${GCC_AND_CLANG_WARNINGS_AS_ERRORS})
58+
list(APPEND WARNING_AS_ERROR_FLAGS_TO_CHECK ${CLANG_WARNINGS_AS_ERRORS})
1559
# FIXME: Remove "x.." when CMP0054 is set to NEW
1660
elseif ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
1761
list(APPEND WARNING_FLAGS_TO_CHECK ${MSVC_WARNINGS})
@@ -31,8 +75,40 @@ foreach (flag ${WARNING_FLAGS_TO_CHECK})
3175
z3_add_cxx_flag("${flag}")
3276
endforeach()
3377

34-
option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" OFF)
35-
if (WARNINGS_AS_ERRORS)
78+
# TODO: Remove this eventually.
79+
# Detect legacy `WARNINGS_AS_ERRORS` boolean option and covert to new
80+
# to new option type.
81+
get_property(
82+
WARNINGS_AS_ERRORS_CACHE_VAR_TYPE
83+
CACHE
84+
WARNINGS_AS_ERRORS
85+
PROPERTY
86+
TYPE
87+
)
88+
if ("${WARNINGS_AS_ERRORS_CACHE_VAR_TYPE}" STREQUAL "BOOL")
89+
message(WARNING "Detected legacy WARNINGS_AS_ERRORS option. Upgrading")
90+
set(WARNINGS_AS_ERRORS_DEFAULT "${WARNINGS_AS_ERRORS}")
91+
# Delete old entry
92+
unset(WARNINGS_AS_ERRORS CACHE)
93+
else()
94+
set(WARNINGS_AS_ERRORS_DEFAULT "SERIOUS_ONLY")
95+
endif()
96+
97+
set(WARNINGS_AS_ERRORS
98+
${WARNINGS_AS_ERRORS_DEFAULT}
99+
CACHE STRING
100+
"Treat warnings as errors. ON, OFF, or SERIOUS_ONLY"
101+
)
102+
# Set GUI options
103+
set_property(
104+
CACHE
105+
WARNINGS_AS_ERRORS
106+
PROPERTY STRINGS
107+
"ON;OFF;SERIOUS_ONLY"
108+
)
109+
110+
if ("${WARNINGS_AS_ERRORS}" STREQUAL "ON")
111+
message(STATUS "Treating compiler warnings as errors")
36112
if (("${CMAKE_CXX_COMPILER_ID}" MATCHES "Clang") OR ("${CMAKE_CXX_COMPILER_ID}" MATCHES "GNU"))
37113
list(APPEND Z3_COMPONENT_CXX_FLAGS "-Werror")
38114
# FIXME: Remove "x.." when CMP0054 is set to NEW
@@ -41,8 +117,14 @@ if (WARNINGS_AS_ERRORS)
41117
else()
42118
message(AUTHOR_WARNING "Unknown compiler")
43119
endif()
44-
message(STATUS "Treating compiler warnings as errors")
45-
else()
120+
elseif ("${WARNINGS_AS_ERRORS}" STREQUAL "SERIOUS_ONLY")
121+
message(STATUS "Treating only serious compiler warnings as errors")
122+
# Loop through the flags
123+
foreach (flag ${WARNING_AS_ERROR_FLAGS_TO_CHECK})
124+
# Add globally because some flags need to be passed at link time.
125+
z3_add_cxx_flag("${flag}" GLOBAL)
126+
endforeach()
127+
elseif ("${WARNINGS_AS_ERRORS}" STREQUAL "OFF")
46128
message(STATUS "Not treating compiler warnings as errors")
47129
# FIXME: Remove "x.." when CMP0054 is set to NEW
48130
if ("x${CMAKE_CXX_COMPILER_ID}" STREQUAL "xMSVC")
@@ -51,4 +133,8 @@ else()
51133
# build system.
52134
list(APPEND Z3_COMPONENT_CXX_FLAGS "/WX-")
53135
endif()
136+
else()
137+
message(FATAL_ERROR
138+
"WARNINGS_AS_ERRORS set to unsupported value \"${WARNINGS_AS_ERRORS}\""
139+
)
54140
endif()

cmake/z3_add_cxx_flag.cmake

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ include(CheckCXXCompilerFlag)
22
include(CMakeParseArguments)
33

44
function(z3_add_cxx_flag flag)
5-
CMAKE_PARSE_ARGUMENTS(z3_add_flag "REQUIRED" "" "" ${ARGN})
5+
CMAKE_PARSE_ARGUMENTS(z3_add_flag "REQUIRED;GLOBAL" "" "" ${ARGN})
66
string(REPLACE "-" "_" SANITIZED_FLAG_NAME "${flag}")
77
string(REPLACE "/" "_" SANITIZED_FLAG_NAME "${SANITIZED_FLAG_NAME}")
88
string(REPLACE "=" "_" SANITIZED_FLAG_NAME "${SANITIZED_FLAG_NAME}")
@@ -16,8 +16,13 @@ function(z3_add_cxx_flag flag)
1616
endif()
1717
if (HAS_${SANITIZED_FLAG_NAME})
1818
message(STATUS "C++ compiler supports ${flag}")
19-
list(APPEND Z3_COMPONENT_CXX_FLAGS "${flag}")
20-
set(Z3_COMPONENT_CXX_FLAGS "${Z3_COMPONENT_CXX_FLAGS}" PARENT_SCOPE)
19+
if (z3_add_flag_GLOBAL)
20+
# Set globally
21+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${flag} " PARENT_SCOPE)
22+
else()
23+
list(APPEND Z3_COMPONENT_CXX_FLAGS "${flag}")
24+
set(Z3_COMPONENT_CXX_FLAGS "${Z3_COMPONENT_CXX_FLAGS}" PARENT_SCOPE)
25+
endif()
2126
else()
2227
message(STATUS "C++ compiler does not support ${flag}")
2328
endif()

0 commit comments

Comments
 (0)