Reputation: 131525
I've been told it's bad practice to do things like seting CFLAGS
directly in CMake, and that, instead, I should use the target_compile_definitions()
command.
Ok, but - what if I want to use similar/identical definitions for multiple (independent) targets? I don't want to repeat myself over and over again.
Upvotes: 4
Views: 9437
Reputation: 131525
tl;dr: You can iterate the targets in a loop.
If you have a bunch of targets with some common/similar features, you may want to simply manipulate them all in a loop! Remember - CMake is not like GNU Make, it's a full-fledged scripting language (well, sort of). So you could write:
set(my_targets
foo
bar
baz)
foreach(TARGET ${my_targets})
add_executable(${TARGET} "${TARGET}.cu")
target_compile_options(${TARGET} PRIVATE "--some_option=some_value")
target_link_libraries(${TARGET} PRIVATE some_lib)
# and so on
set_target_properties(
${TARGET}
PROPERTIES
C_STANDARD 99
C_STANDARD_REQUIRED YES
C_EXTENSIONS NO )
endforeach(TARGET)
And you could also initialize an empty list of targets, then add to it here-and-there, and only finally apply your common options and settings to all of them, centrally.
Note: In this example I added PRIVATE
compile options, but if you need some of them to propagate to targets using your targets, you can make them PUBLIC
).
Upvotes: 3
Reputation: 425
another neat solution is to define an interface library target (a fake target that does not produce any binaries) with all required properties and compiler definitions, then link the other existing targets against it
example:
add_library(myfakelib INTERFACE)
target_compile_definitions(myfakelib INTERFACE MY_NEEDED_DEFINITION)
add_executable(actualtarget1 main1.cpp)
add_executable(actualtarget2 main2.cpp)
set_property(
TARGET actualtarget1 actualtarget2
APPEND PROPERTY LINK_LIBRARIES myfakelib
)
refs:
https://cmake.org/cmake/help/latest/command/add_library.html#interface-libraries
Upvotes: 1
Reputation: 42852
I see three possible ways:
The preferred one using target_compile_definitions(... INTERFACE/PUBLIC ...)
which would self-propagate the compiler definitions to targets depending on it via target_link_libraries()
command.
Using the set_property(TARGET target1 target2 ... APPEND PROPERTY COMPILE_DEFINITIONS ...)
to set the same definitions to multiple targets.
You may still use the "old commands" of add_definitions()
and remove_definitions()
to modify COMPILE_DEFINITIONS
directory property (which would pre-set all COMPILE_DEFINITIONS
target properties in this directories scope).
Upvotes: 8