c++cmake

How to selectively enable or disable -Werror argument for entire (external project) directories in my project?


I have a project in which I would like to use -Werror. Let's call its directory proj. There is a directory within proj/external and that is an exception so I don't want to use the -Werror for that.

Is there a way to create an exception for an entire directory in CMake for using or not using a compiler argument?


Solution

  • 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:

    CMake 4.0 adds the LINK_WARNING_AS_ERROR target property, CMAKE_LINK_WARNING_AS_ERROR variable, and --cmake-link-no-warning-as-error commandline argument.

    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: