问题描述
我是 CMake 新手,想知道是否有可能根据变量从 target_sources()
中排除某些来源。
假设我在下面有这个
target_sources(myTarget
PUBLIC
PRIVATE
myDir1/src/a.c
myDir2/src/b.c
myDir3/src/c.c
INTERFACE
)
target_include_directories(myTarget
PUBLIC
PRIVATE
myDir1/inc
myDir2/inc
myDir3/inc
INTERFACE
)
我想根据名为 myFlag
的标志从 myDir3 中排除/包含源/目录。我怎样才能做到这一点?
target_sources(myTarget
PUBLIC
PRIVATE
myDir1/src/a.c
myDir2/src/b.c
if(DEFINED myFlag)
myDir3/src/c.c
endif()
INTERFACE
)
target_include_directories(myTarget
PUBLIC
PRIVATE
myDir1/inc
myDir2/inc
if(DEFINED myFlag)
myDir3/inc
endif()
INTERFACE
)
解决方法
您不能将 if 语句放在命令的参数列表中。 target_*
命令不会覆盖,而是追加,因此最简单的解决方案如下:
target_sources(
myTarget
PRIVATE
myDir1/src/a.c
myDir2/src/b.c
)
if (myFlag)
target_sources(myTarget PRIVATE myDir3/src/c.c)
endif ()
target_include_directories(
myTarget
PRIVATE
myDir1/inc
myDir2/inc
)
if (myFlag)
target_include_directories(myTarget PRIVATE myDir3/inc)
endif ()
另一个更具声明性的选项是使用生成器表达式,如下所示:
target_sources(
myTarget
PRIVATE
myDir1/src/a.c
myDir2/src/b.c
$<$<BOOL:${myFlag}>:myDir3/src/c.c>
)
,
根据您尝试这样做的原因,将它们保留为源文件也可能有意义(因此它们显示在例如 Visual Studio 的目标视图中),但将它们标记为标头以便它们不会被编译:
if (NOT myFlag)
set_source_files_properties(
srcfile1.cpp
srcfile2.cpp
PROPERTIES
HEADER_FILE_ONLY ON
)
endif()
CMake 的 documentation 甚至为此推荐这样做:
如果您有一些源文件,这很有用 预处理,然后通过添加这些预处理源 add_library() 或 add_executable()。通常,在 IDE 中,不会有 原始来源的参考,仅这些预处理 来源。因此,通过为所有原始源文件设置此属性 到 ON,然后调用 add_library() 或 add_executable() 同时 传递预处理源和原始源,或通过 使用 target_sources() 添加原始源文件将完全正确 人们会期望什么,即原始源文件将是可见的 在 IDE 中,不会被构建。