Это может работать в простом случае, который вы изложили, предполагая, что lib
- еще одна цель, созданная в том же дереве сборки CMake. Вы можете использовать get_target_property()
, чтобы получить список свойств LINK_LIBRARIES
для TargetA
и TargetB
. Если lib
находится в списке зависимостей ссылок первого уровня, вы можете добавить определение компиляции в 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()
Обратите внимание, это работает, только если lib
является зависимость цели первого уровня, не рекурсивно ищет зависимости, как показано в этом ответе . Кроме того, если lib
является интерфейсной библиотекой, вам нужно вместо этого получить свойство INTERFACE_LINK_LIBRARIES
.
РЕДАКТИРОВАТЬ Основано на ответной реакции: если определения компиляции DEF_A
и DEF_B
являются взаимоисключающими в цели lib
. Самым чистым подходом может быть создание отдельной цели lib
, одна из которых предназначена для TargetA
, а другая - для TargetB
. Это может выглядеть примерно так:
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)