At the beginning of my CMake project, I'm setting general compilation flags in the variable CMAKE_CXX_FLAGS, like
set(CMAKE_CXX_FLAGS "-W -Wall ${CMAKE_CXX_FLAGS}")
Later on, I need to append additional configuration-specific compilation flags (stored in BUILD_FLAGS). Can I use the following command for this:
set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS ${BUILD_FLAGS})
or do I have to add the CMAKE_CXX_FLAGS manually:
set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS "${CMAKE_CXX_FLAGS} ${BUILD_FLAGS}")
to prevent CMAKE_CXX_FLAGS being overriden by BUILD_FLAGS?
The accepted answer is still working but outdated since 2013.
This answer is based and new functions from CMake v2.8.12, v3.3 and v3.13.
Two new commands to set CMAKE_CXX_FLAGS
:
target_compile_options()
(for one single target)add_compile_options()
(for all targets)The documentation of last version has not changed a lot since cmake-2.8.12:
target_compile_options()
add_compile_options()
In you case you can use:
target_compile_options(${TARGET} PRIVATE ${BUILD_FLAGS})
Or simply if you have a single target:
add_compile_options(${BUILD_FLAGS})
target_compile_options(mylib PRIVATE -O2) # only internal target_compile_options(mylib INTERFACE -gl) # only external target_compile_options(mylib PUBLIC -g) # same as PRIVATE + INTERFACE # multiple targets and flags target_compile_options(mylib1 mylib2 PRIVATE -Wall -Wextra) target_compile_options( mylib PUBLIC -DUSEXX) # Bad target_compile_definitions(mylib PUBLIC -DUSEXX) # OK add_compile_options(-Wall -Wextra) # for all targets in current directory add_compile_options(-DUSEXX) # Bad add_definitions(-DUSEXX) # OK
COMPILE_FLAGS
cmake-3.0 documentation flags COMPILE_FLAGS
as deprecated:
COMPILE_FLAGS
Additional flags to use when compiling this target’s sources.
The
COMPILE_FLAGS
property sets additional compiler flags used to build sources within the target. UseCOMPILE_DEFINITIONS
to pass additional preprocessor definitions.This property is deprecated. Use the
COMPILE_OPTIONS
property or thetarget_compile_options
command instead.
If you still want to use set_target_properties()
you may use COMPILE_OPTIONS
instead of COMPILE_FLAGS
:
set_target_properties(${TARGET} PROPERTIES COMPILE_OPTIONS ${BUILD_FLAGS})
Anton Petrov suggests to use generator expressions as presented in an answer of ar31.
The CMake generator expressions applies your ${BUILD_FLAGS}
to:
$<COMPILE_LANGUAGE:CXX>
(can also be C
, CUDA
...)$<CXX_COMPILER_ID:Clang>
GNU
for gcc
, or MSVC
for Visual C++... see full list)$<C_COMPILER_ID:Clang>
instead if language is C)In you case you can use:
target_compile_options(${TARGET} PRIVATE $<$<COMPILE_LANGUAGE:CXX>:${BUILD_FLAGS_FOR_CXX}> $<$<COMPILE_LANGUAGE:C>:${BUILD_FLAGS_FOR_C}>)
or about compilers:
target_compile_options(${TARGET} PRIVATE $<$<CXX_COMPILER_ID:Clang>:${BUILD_FLAGS_FOR_CLANG}> $<$<CXX_COMPILER_ID:GNU>:${BUILD_FLAGS_FOR_GCC}> $<$<CXX_COMPILER_ID:MSVC>:${BUILD_FLAGS_FOR_VISUAL}>)
A new function target_link_options()
allow to pass options to the linker, as mentioned by Craig Scott.
The best way is to distinguish C files and C++ files using two different targets.
Use the first one:
set_target_properties(${TARGET} PROPERTIES COMPILE_FLAGS ${BUILD_FLAGS})
The flags stored in BUILD_FLAGS are appended after CMAKE_CXX_FLAGS when compiling the sources of TARGET. The documentation hints at this, but I've just tried it to make sure.
COMPILE_FLAGS
Additional flags to use when compiling this target's sources. The COMPILE_FLAGS property sets additional compiler flags used to build sources within the target. Use COMPILE_DEFINITIONS to pass additional preprocessor definitions.
The full command line will be the equivalent of:
${CMAKE_CXX_COMPILER} ${CMAKE_CXX_FLAGS} ${COMPILE_FLAGS} -o foo.o -c foo.cc
And as Ramon said, you can always check with make VERBOSE=1
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With