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

CMake中目标PRIVATE与INTERFACE编译选项/定义的选用时机

CMake项目编译配置作用域选择问题

我有一个C++ CMake项目,包含3个目标:

  • 接口库目标MyProjectInterfaces(在hpp文件中定义若干接口)
  • 库MyProjectFoo(实现MyProjectInterfaces中一半的接口)
  • 库MyProjectBar(实现MyProjectInterfaces中另一半的接口)

下游项目使用我的库时,可能有几种需求:自行实现MyProjectInterfaces的接口,或使用Foo的实现、Bar的实现,或两者兼用。

我希望为项目内所有目标统一添加编译特性、选项和定义,同时尽量减少代码重复,目前想到两种实现方式:

方法1:接口库添加INTERFACE作用域配置

最简便的方式是将这些设置以INTERFACE作用域添加到MyProjectInterfaces中:

set(DEBUG_COMPILE_OPTIONS
    -Wall -Werror
)
set(RELEASE_COMPILE_OPTIONS
)
        
target_compile_features(MyProjectInterfaces INTERFACE
    cxx_std_17
)

target_compile_definitions(MyProjectInterfaces INTERFACE
    SDK_VERSION_MAJOR=${CMAKE_PROJECT_VERSION_MAJOR}
    SDK_VERSION_MINOR=${CMAKE_PROJECT_VERSION_MINOR}
    SDK_VERSION_PATCH=${CMAKE_PROJECT_VERSION_PATCH}
)

target_compile_options(MyProjectInterfaces INTERFACE
    $<$<CONFIG:Debug>:${DEBUG_COMPILE_OPTIONS}>
    $<$<CONFIG:Release>:${RELEASE_COMPILE_OPTIONS}>
)

方法2:宏封装PRIVATE作用域配置

另一种方式是改用PRIVATE作用域,把target_compile_XXX调用封装到宏中,为每个实际编译的目标调用该宏:

macro(set_options myTarget)
target_compile_features(${myTarget} PRIVATE
    cxx_std_17
)

target_compile_definitions(${myTarget} PRIVATE
    SDK_VERSION_MAJOR=${CMAKE_PROJECT_VERSION_MAJOR}
    SDK_VERSION_MINOR=${CMAKE_PROJECT_VERSION_MINOR}
    SDK_VERSION_PATCH=${CMAKE_PROJECT_VERSION_PATCH}
)

target_compile_options(${myTarget} PRIVATE
    $<$<CONFIG:Debug>:${DEBUG_COMPILE_OPTIONS}>
    $<$<CONFIG:Release>:${RELEASE_COMPILE_OPTIONS}>
)
endmacro()

# 接口库目标可能不需要或无效,故注释
# set_options(MyProjectInterface) 

# 为实际编译的库设置编译选项
set_options(MyProjectFoo)
set_options(MyProjectBar)

我知道两种方法都能给项目内所有目标配置所需的定义和选项,但方法1会把这些选项、定义传递给下游项目。这种传递是否可取?

网上有很多关于target_compile_XXX(...)中PRIVATE/PUBLIC/INTERFACE参数用法的文档,但很少有资料讲如何、何时选择这些作用域。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 04:06:19