You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用同一CMake目标适配Scheme S7库的两种不同配置场景?

CMake适配Scheme S7两种使用场景的方案

不需要创建两个完全独立的目标,更合理的做法是基于基础配置派生不同的子目标,既复用公共设置,又能满足各自的编译需求。下面是具体实现:

推荐方案:基础目标+派生配置目标

先定义一个仅提供头文件路径的基础目标,作为两个场景的公共依赖:

# 基础目标:仅包含头文件路径,无额外编译配置
add_library(third_party_scheme_base INTERFACE)
add_library(third_party::scheme_base ALIAS third_party_scheme_base)

target_include_directories(third_party_scheme_base
    INTERFACE
        "${CMAKE_CURRENT_SOURCE_DIR}/scheme"
)

基于这个基础目标,分别创建适配两种场景的子目标:

场景1:包含源文件+特定编译宏

add_library(third_party_scheme_with_src INTERFACE)
add_library(third_party::scheme_with_src ALIAS third_party_scheme_with_src)

# 继承基础目标的头文件配置
target_link_libraries(third_party_scheme_with_src
    INTERFACE
        third_party::scheme_base
)

# 添加S7源文件和对应编译宏
target_sources(third_party_scheme_with_src
    INTERFACE
        "${CMAKE_CURRENT_SOURCE_DIR}/scheme/s7.c"
)

target_compile_definitions(third_party_scheme_with_src
    INTERFACE 
        S7_EXPORT_LIB
        S7_OUTPUT_FUNCTION_FULL_STRING
)

场景2:仅头文件+另一组编译宏

add_library(third_party_scheme_header_only INTERFACE)
add_library(third_party::scheme_header_only ALIAS third_party_scheme_header_only)

# 继承基础目标的头文件配置
target_link_libraries(third_party_scheme_header_only
    INTERFACE
        third_party::scheme_base
)

# 添加专属编译宏(替换成你的第二组宏即可)
target_compile_definitions(third_party_scheme_header_only
    INTERFACE 
        S7_STATIC_LIB
        S7_NO_OUTPUT_REDIRECT
)

之后两个自研库直接依赖对应的目标就行:

  • 需要编译S7源文件的库:target_link_libraries(your_lib1 PRIVATE third_party::scheme_with_src)
  • 仅用头文件的库:target_link_libraries(your_lib2 PRIVATE third_party::scheme_header_only)

备选方案:单目标通过条件控制(不推荐)

如果硬要使用单个目标,可以通过CMake的生成器表达式实现条件配置,但会让目标逻辑变得复杂,可读性差:

add_library(third_party_scheme INTERFACE)
add_library(third_party::scheme ALIAS third_party_scheme)

target_include_directories(third_party_scheme
    INTERFACE
        "${CMAKE_CURRENT_SOURCE_DIR}/scheme"
)

# 通过依赖方的目标属性控制是否包含源文件
target_sources(third_party_scheme
    INTERFACE
        $<$<BOOL:$<TARGET_PROPERTY:USE_S7_SRC>>:"${CMAKE_CURRENT_SOURCE_DIR}/scheme/s7.c">
)

# 按属性切换编译宏
target_compile_definitions(third_party_scheme
    INTERFACE 
        $<$<BOOL:$<TARGET_PROPERTY:USE_S7_SRC>>:S7_EXPORT_LIB;S7_OUTPUT_FUNCTION_FULL_STRING>
        $<$<BOOL:$<TARGET_PROPERTY:USE_S7_HEADER_ONLY>>:S7_STATIC_LIB;S7_NO_OUTPUT_REDIRECT>
)

依赖时需要给自研库设置属性:

# 场景1的库
add_library(your_lib1 STATIC ...)
set_target_properties(your_lib1 PROPERTIES USE_S7_SRC ON)
target_link_libraries(your_lib1 PRIVATE third_party::scheme)

# 场景2的库
add_library(your_lib2 STATIC ...)
set_target_properties(your_lib2 PROPERTIES USE_S7_HEADER_ONLY ON)
target_link_libraries(your_lib2 PRIVATE third_party::scheme)

总结

优先选择基础目标+派生子目标的方案,每个目标职责明确,依赖方可以直接选择对应配置,避免逻辑混乱和编译冲突。

内容的提问来源于stack exchange,提问作者Dess

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 07:10:11