我可以控制 CMake 中 target_sources 的源排除吗?

问题描述

我是 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 中,不会被构建。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...