Cmake 在多个目标的库依赖项中定义编译定义

Cmake 在多个目标的库依赖项中定义编译定义,cmake,dependencies,Cmake,Dependencies,是否有一种方法可以为链接的库目标设置编译定义,但每个目标使用的库具有不同的定义集(对于与每个目标链接的库,编译定义是互斥的) target\u compile\u definitions() 我能想到的唯一方法是创建一个函数来添加新的库目标,这样就可以用不同的编译定义定义多个库目标。假设lib是在同一个CMake构建树中创建的另一个目标,这可能适用于您列出的简单案例。您可以使用获取TargetA和TargetB的LINK\u库属性列表。如果lib在一级链接依赖项列表中,则可以将编译定义添加到li

是否有一种方法可以为链接的库目标设置编译定义,但每个目标使用的库具有不同的定义集(对于与每个目标链接的库,编译定义是互斥的)

target\u compile\u definitions()


我能想到的唯一方法是创建一个函数来添加新的库目标,这样就可以用不同的编译定义定义多个库目标。

假设
lib
是在同一个CMake构建树中创建的另一个目标,这可能适用于您列出的简单案例。您可以使用获取
TargetA
TargetB
LINK\u库
属性列表。如果
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
是一个接口库,则必须获取该属性


根据回答反馈进行编辑:如果编译定义
DEF_A
DEF_B
lib
目标中相互排斥。最干净的方法可能是创建一个单独的
lib
target,一个用于
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)

在CMake中创建的每个库目标最终都会生成单个库文件。编译此文件时,它只能使用一组编译选项。如果要使用不同的选项集构建库,则需要为它们创建单独的目标。但是,如果TargetA和TargetB都与lib链接,那么这将同时将
DEF_A
DEF_B
添加到lib compile defs?这正是我试图避免的,我不希望目标A的lib具有
DEF_B
定义。或者是
${LIB}
中的
${LIB}
${LIB}
中的
${LIB}
不同?@Nick Yes,在这种情况下,
定义A
定义B
都是
LIB
的编译定义。从你的问题帖上看,他们相互排斥的要求并不明确。。。如果这是您想要的,那么您必须给出一个库首选项(如果A则不是B,或者如果B则不是A),以便只添加
DEF_A
DEF_B
。另一个解决方案是,正如建议的那样,为每个案例创建单独的目标。我已经更新了,以使问题更清楚。“所以我认为最好使用函数从TargetA/B范围创建库目标。”Nick同意。这仍然是一个非常简单的解决方案;我已经扩展了我的答案,以显示它可能是什么样子。希望这有帮助!谢谢由于这个库是第三方库,我想用一种通用的方式来实现这一点,所以我定义了一个函数来创建一个具有给定名称的库目标。通过这种方式,我可以在自定义目标上指定我想要的任何编译定义。
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)