小编典典

使用 CMake 自动将文件夹中的所有文件添加到目标?

all

我正在考虑将跨平台项目从 Visual C++、XCode 和 makefile 中的单独构建管理系统切换到 CMake。

我需要的一项基本功能是将目录中的所有文件自动添加到目标。虽然使用 make 很容易做到这一点,但使用 Visual C++ 和 XCode
却不容易做到(如果我错了,请纠正我)。是否可以直接在 CMake 中完成?如何?


阅读 427

收藏
2022-07-12

共1个答案

小编典典

从 CMake 3.1+ 开始,开发人员 强烈反对 用户使用file(GLOBfile(GLOB_RECURSE收集源文件列表。

注意: 我们不建议使用 GLOB 从源代码树中收集源文件列表。如果在添加或删除源时没有 CMakeLists.txt
文件更改,则生成的构建系统无法知道何时要求 CMake 重新生成。CONFIGURE_DEPENDS
标志可能无法在所有生成器上可靠地工作,或者如果将来添加不能支持它的新生成器,使用它的项目将被卡住。即使 CONFIGURE_DEPENDS
工作可靠,在每次重建时执行检查仍然是有成本的。

请参阅此处的文档

这里有两个很好的答案([1]

CMake 的创建者自己建议不要使用通配符。

见:https ://cmake.org/cmake/help/v3.15/command/file.html?highlight=glob#file

(我们不建议使用 GLOB 从源代码树中收集源文件列表。如果在添加或删除源代码时没有更改 CMakeLists.txt 文件,则生成的构建系统无法知道何时要求 CMake 重新生成。)

当然,您可能想知道缺点是什么 -请继续阅读!


当 Globbing 失败时:

globbing 的最大缺点是创建/删除文件不会自动更新构建系统。

如果您是添加文件的人,这似乎是一个可以接受的权衡,但是这会给构建您的代码的其他人带来问题,他们从版本控制更新项目,运行构建,然后联系您,抱怨
“构建的破碎的”。

更糟糕的是,失败通常会给出一些链接错误,而这些错误并没有给出问题原因的任何提示,并且会浪费时间来解决问题。

在我从事的一个项目中,我们开始使用 globbing,但在添加新文件时收到了很多抱怨,因此有足够的理由明确列出文件而不是 globbing。

这也破坏了常见的 git 工作流程
git bisect以及功能分支之间的切换)。

所以我不能推荐这个,它导致的问题远远超过了方便,当有人因此无法构建你的软件时,他们可能会浪费很多时间来追踪问题或者干脆放弃。

另一个注意事项,仅仅记住触摸CMakeLists.txt并不总是足够的,对于使用 globbing 的自动构建,我必须在每次构建cmake之前运行,因为自上次构建以来可能已经添加/删除了文件*.

规则的例外情况:

有时使用 globbing 更可取:

  • CMakeLists.txt用于为不使用 CMake 的现有项目设置文件。
    它是获取所有引用源的快速方法(一旦构建系统运行 - 用显式文件列表替换 globbing)。
  • 当 CMake 不用作主要构建系统时,例如,如果您正在使用不使用 CMake 的项目,并且您希望为其维护自己的构建系统。
  • 对于文件列表经常更改以至于维护变得不切实际的任何情况。在这种情况下,它可能很有用,但是您必须接受每次cmake运行以生成构建文件以获得可靠/正确的构建(这违背了 CMake 的意图 - 将配置与构建分离的能力)

*是的,我本可以编写代码来比较更新前后磁盘上的文件树,但这不是一个很好的解决方法,最好留给构建系统。

[2]),详细说明了手动列出源文件的原因。


有可能的。例如file(GLOB

cmake_minimum_required(VERSION 2.8)

file(GLOB helloworld_SRC
     "*.h"
     "*.cpp"
)

add_executable(helloworld ${helloworld_SRC})

请注意,如果添加或删除源文件,这需要 手动 重新运行cmake,因为生成的构建系统不知道何时要求 CMake
重新生成,并且在每次构建时都这样做会增加构建时间。

从 CMake 3.12 开始,您可以将CONFIGURE_DEPENDS标志传递给以file(GLOB在调用构建时自动检查和重置文件列表。你会写:

cmake_minimum_required(VERSION 3.12)

file(GLOB helloworld_SRC CONFIGURE_DEPENDS "*.h" "*.cpp")

这至少可以避免每次添加文件时手动重新运行 CMake。

2022-07-12