【问题标题】:CMake: set directory for target sourcesCMake:为目标源设置目录
【发布时间】:2021-10-23 23:08:04
【问题描述】:

我有一个 C++ 项目,其中所有实现源文件 (*.cpp) 都位于项目目录中的 src 目录中。一些文件位于其他子目录中。假设 src/foo/ 中有 50 个文件。我需要将这些文件列为add_library 和/或target_sources 函数的一部分。

现在,无论在哪里,都不鼓励自动添加目录中的所有文件,这对我来说很好。所以我要手动列出所有文件;但是将通用前缀 src/foo/ 重复 50 次似乎真的很愚蠢而且很烦人。

the documentation for target_sources 中说

相对源文件路径被解释为相对于当前源目录(即 CMAKE_CURRENT_SOURCE_DIR)。

所以我在调用target_source 之前添加了set(CMAKE_CURRENT_SOURCE_DIR "src/foo/"),但它不起作用。 (我收到“找不到源文件”错误。)

那么,如果可能的话,实现我想要的正确方法是什么?

注意:项目的(公共)头文件 (*.hpp) 位于 include 目录中(在 src 之外)。使用 target_include_directories 函数很好地配置(无需列出单个文件)。

【问题讨论】:

  • 我认为@Kamil Cuk 的回答回答了你的问题。但我想添加设置 CMAKE_CURRENT_SOURCE_DIR 不起作用,因为这是一个 CMake 设置变量。此外,根据 CMake 的“源”目录不一定与源文件的目录有任何关系。这只是 CMake 正在处理的当前目录(即当前 CMakeLists.txt 所在的位置)。
  • 关于第一部分,是的,你是对的,谢谢。我还发现路径扩展至少需要 CMake 3.13 并设置cmake_policy(SET CMP0076 NEW)。关于第二部分,这有点可惜。如果有一个清晰、一致的命名法会很好(我认为),其中 SOURCE 总是指实现文件,而 INCLUDE 总是指头文件。
  • 可以安全地假设,如果一个变量以CMAKE_ 开头,它(通常)由 CMake 管理。当您在项目中使用 add_subdirectory() 并且需要知道 CMake 当前正在处理脚本的确切位置时,CMAKE_CURRENT_SOURCE_DIR 相对于 CMAKE_SOURCE_DIR 的用处就显现出来了。

标签: c++ cmake


【解决方案1】:

但重复公共前缀 src/foo/ 50 次

只需将前缀添加到来源即可。

set(target_sources
    source1.c
    source2.c
)
list(TRANSFORM target_sources PREPEND "src/foo/")

【讨论】:

  • 即使 CMake 的“新方式”(如某些人所说)应该摆脱(直接)设置变量,转向“基于属性的”,它仍然有效且非常优雅(恕我直言)方法。此外,对于阅读本文的 CMake 初学者,转换后的列表将用作 add_library(MyProj SHARED ${target_sources})
  • 请注意,TRANSFORM 仅从 CMake 3.12 开始可用。
【解决方案2】:

CMAKE_CURRENT_SOURCE_DIR 设置为旧CMAKE_CURRENT_SOURCE_DIR 的相对变量是行不通的。如果它被设置为一个值,那么可以假设删除该值并使用自定义值是错误的,因为您错过了之前设置的值。

您可能希望将其设置为绝对路径,或者使用set(CMAKE_CURRENT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src/foo/"),或者像很多其他人一样一直复制粘贴前缀。这是标准做法(这也是我仍然使用 GLOB 的原因之一,因为我很懒),显式跟进比隐式跟进更好(这就是不使用GLOB 的重点)。

【讨论】:

  • 谢谢,我确实忘记连接到 CMAKE_CURRENT_SOURCE_DIR 的附加路径,但这不是问题的核心(仍然没有工作)。
【解决方案3】:

您也可以在src/foo 中使用add_subdirectory(src/foo)CMakeLists.txt,您只需将其放入

target_sources( <your target> PRIVATE|PUBLIC|INTERFACE
  your
  list
  of
  sources
)

我觉得这样会比较优雅。

【讨论】:

    【解决方案4】:

    我会建议(如果你有 bash 或类似的 shell)

    function prepend() { while read line; do echo "${1}${line}"; done; }
    ls *.cc *hh | sort | prepend  "\${CMAKE_CURRENT_SOURCE_DIR}/"
    

    然后复制粘贴:)

    【讨论】:

      猜你喜欢
      • 2021-12-07
      • 2023-01-25
      • 2018-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多