CMake 3.24+ Solution
If your minimum required CMake version for the project is equal to or greater than v3.24, you can use the CMAKE_COMPILE_WARNING_AS_ERROR
variable:
This variable is used to initialize the COMPILE_WARNING_AS_ERROR
property on all the targets.
So just set the variable to a desired value at the top of each variable scope where you want a specific value to be used inside that scope. CMake non-cache variables are scoped to directories and functions. Ex.
set(COMPILE_WARNING_AS_ERROR YES)
add_library(foo foo.cpp)
set(COMPILE_WARNING_AS_ERROR NO)
add_subdirectory(bar)
set(COMPILE_WARNING_AS_ERROR YES)
add_executable(baz baz.cpp)
For the specific case of variable scoping for external projects, if you are adding it with add_subdirectory
, I'm assuming you don't want to touch the external project's CMakeLists.txt file, so you can instead wrap your call to add_subdirectory
with a fuction, and set the variable inside the function, and then call the function.
There are several benefits to this approach:
- Cross-Platform with Less boilerplate: No more explicitly written generator expressions to use the right flag for each compiler.
- Allows user-override: Not all users will want to build with warnings as errors. This new feature comes with a
--compile-no-warning-as-error
command-line flag that users can use to disable any effects of this variable/target-property when set by a dev in a CMakeLists.txt file.
Pre-3.24 Solution: If you are adding the external directory via add_subdirectory
or FetchContent
In the CMakeLists.txt file at the subdirectory for proj
, do
# add `-Werror` to the current directory's `COMPILE_OPTIONS`
add_compile_options(-Werror)
# retrieve a copy of the current directory's `COMPILE_OPTIONS`
get_directory_property(old_dir_compile_options COMPILE_OPTIONS)
# modify the actual value of the current directory's `COMPILE_OPTIONS` (copy from above line remains unchanged). subdirectories inherit a copy of their parent's `COMPILE_OPTIONS` at the time the subdirectory is processed.
add_compile_options(-Wno-error)
# add you subdirectory (whichever way you do it)
# add_subdirectory(external ...)
# FetchContent_MakeAvailable(...)
# restore the current directory's old `COMPILE_OPTIONS`
set_directory_properties(PROPERTIES COMPILE_OPTIONS "${old_dir_compile_options}")
Docs:
If you are adding it via ExternalProject_Add
You probably don't need to do anything unless the external project itself is adding -Werror
, in which case I don't know if you can do anything about it.
Obligatory caveats / comments:
-Werror
is a flag for gcc and friends (clang, etc.). If you want to support MSVC, you need to put guards in either via if(...)
, or via generator expressions.
- whether or not to use
-Werror
is not without controversy. If you want to support other users using your project and you want to satisfy both sides of the debate, use some mechanism to either guard these lines of configuration behind a CMake options, or isolate them to your local build only.