cmake

Reuse target_compile_options from variable for multiple targets (CMake)


I have several build targets and want to set the same set of compile options like this:

set(app_compile_options "-Wall -Wextra -Wshadow -Wnon-virtual-dtor \
    -Wold-style-cast \
    -Woverloaded-virtual -Wzero-as-null-pointer-constant \
    -pedantic -fPIE -fstack-protector-all -fno-rtti")

add_executable(foo foo.cpp)
target_compile_options(foo PUBLIC ${app_compile_options})

add_executable(bar bar.cpp)
target_compile_options(bar PUBLIC ${app_compile_options})

When compiling I get the following error:

error: unrecognized command line option ‘-Wall -Wextra -Wshadow -Wnon-virtual-dtor -Wold-style-cast     -Woverloaded-virtual -Wzero-as-null-pointer-constant     -pedantic -fPIE -fstack-protector-all -fno-rtti’

Do I need another format or special syntax to define the compile options in a variable?


Solution

  • In addition of @squaresstkittles's answer, I'd add that you can use interface targets for this purpose:

    add_library(common INTERFACE)
    
    target_compile_options(common INTERFACE
        -Wall -Wextra -Wshadow -Wnon-virtual-dtor
        -Wold-style-cast
        -Woverloaded-virtual -Wzero-as-null-pointer-constant
        -pedantic -fPIE -fstack-protector-all -fno-rtti
    )
    
    target_link_libraries(foo PRIVATE common)
    target_link_libraries(bar PRIVATE common)
    

    Even better, you can define those flags in CMakePresets.json without affecting your cmake files. This would also allow different flags for different environment (dev, ci, etc.)