Reputation: 4248
Is there a way to set compile definitions for a linked library target but with different sets of definitions for the library used by each target (compile defs are mutually exclusive for the lib linked with each target)?
Target A > lib with -DDEF_A only
Target B > lib with -DDEF_B only
target_compile_definitions()
only allows you to set definitions on a target, but if set on the library target this would be set for both targets.
The only way I can think of doing it is to create a function to add new library targets, so multiple library targets can be defined with different compile definitions.
Upvotes: 2
Views: 1267
Reputation: 18243
This could work with the simple case you've laid out, assuming lib
is another target created within the same CMake build tree. You could use get_target_property()
to get the LINK_LIBRARIES
property list for TargetA
and TargetB
. If lib
is in the list of first-level link dependencies, then you can add the compile definition to lib
.
# Get the list of first-level link dependencies for TargetA and TargetB.
get_target_property(TARGETA_LIBS TargetA LINK_LIBRARIES)
get_target_property(TARGETB_LIBS TargetB LINK_LIBRARIES)
# Loop through the TargetA dependencies.
foreach(LIB ${TARGETA_LIBS})
# Was the 'lib' library added as a dependency to TargetA?
if (${LIB} STREQUAL lib)
# Yes, so add the compile definitions to 'lib'.
target_compile_definitions(${LIB} PRIVATE DEF_A)
endif()
endforeach()
# Loop through the TargetB dependencies.
foreach(LIB ${TARGETB_LIBS})
# Was the 'lib' library added as a dependency to TargetB?
if (${LIB} STREQUAL lib)
# Yes, so add the compile definitions to 'lib'.
target_compile_definitions(${LIB} PRIVATE DEF_B)
endif()
endforeach()
Note, this only works if lib
is a first-level dependency of the target, it does not search dependencies recursively, as shown in this answer. Also, if lib
is an interface library, you'll have to get the INTERFACE_LINK_LIBRARIES
property instead.
EDIT Based on answer feedback: If the compile definitions DEF_A
and DEF_B
are mutually exclusive in the lib
target. The cleanest approach may be to create a separate lib
target, one catered for TargetA
and another catered for TargetB
. This could look something like this:
set(LIB_SOURCES
Class1.cpp
...
)
# Create the 'lib' target to link to TargetA.
add_library(lib_forTargetA SHARED ${LIB_SOURCES})
target_compile_definitions(lib_forTargetA PRIVATE DEF_A)
# Create the 'lib' target to link to TargetB.
add_library(lib_forTargetB SHARED ${LIB_SOURCES})
target_compile_definitions(lib_forTargetB PRIVATE DEF_B)
Upvotes: 1