很多博客和关于CMake的讨论告诉你不使用文件通配来建立你的资源。也就是说,这很糟糕:
file(GLOB SOURCES *.cxx)
虽然这很好:
set(SOURCES a.cxx b.cxx c.cxx d.cxx e.cxx [...])
我的理解是,其根本原因在于,虽然某些构建系统支持通配,但其他构建系统不支持通配,而CMake正试图在这种情况下构建系统不可知。这看似合理。
但是,在我个人的情况下,我将使用的所有构建系统(例如make和ninja)做支持globbing。无论如何在CMake中总是将globbing转发到构建中,以获得两个世界中最好的 - 缩写的globbing,自动获取新文件而不必重新运行CMake?
答案 0 :(得分:3)
我的理解是,其根本原因在于,虽然某些构建系统支持通配,但其他构建系统不支持通配,而CMake正试图在这种情况下构建系统不可知。
主要原因在manual:
中说明注意:我们不建议使用GLOB从源树中收集源文件列表。如果没有CMakeLists.txt文件更改时 添加或删除源,然后生成的构建系统无法知道 何时要求CMake重新生成。
这是事实。如果添加新的源文件,则需要重新运行CMake。因此建议手动列出源文件的方法,因为你不能忘记这样做;忘记重新运行CMake会导致沮丧。如果有CMake集成,IDE会自动为您执行此操作。
但是,在我个人的情况下,我将使用的所有构建系统(例如make和ninja)都支持globbing。无论如何在CMake中总是将globbing转发到构建中,以获得两个世界中最好的 - 缩写的globbing,自动获取新文件而不必重新运行CMake?
不,没有。如果有,IDE的/插件将不需要实现此功能。所以你需要朝这个方向看。
答案 1 :(得分:1)
CMake 3.12 向 file(GLOB)
添加了一个新的参数,它就是这样做的:
file(GLOB SOURCES CONFIGURE_DEPENDS *.cxx)
<块引用>
如果指定了 CONFIGURE_DEPENDS 标志,CMake 将向主构建系统检查目标添加逻辑,以在构建时重新运行标记的 GLOB 命令。如果任何输出发生变化,CMake 将重新生成构建系统。
附注:
<块引用>注意 我们不建议使用 GLOB 从源树中收集源文件列表。如果在添加或删除源时没有 CMakeLists.txt 文件更改,则生成的构建系统无法知道何时要求 CMake 重新生成。 CONFIGURE_DEPENDS 标志可能无法在所有生成器上可靠地工作,或者如果将来添加了不能支持它的新生成器,使用它的项目将被卡住。即使 CONFIGURE_DEPENDS 可靠地工作,在每次重建时执行检查仍然存在成本。
但是有了这些警告,功能就在那里。
答案 2 :(得分:0)
你不应该像你展示的那样创建一个变量来添加源文件。
您应该改用 target_sources。
target_sources(foobar PRIVATE
main.cpp
...
)
target_sources 对于 3.13+ 用户的另一个好处是您可以如何使用它。
Craig Scott 写了一篇关于它的好文章:
https://crascit.com/2016/01/31/enhanced-source-file-handling-with-target_sources/
==========================
但是,CMake 3.12 向 file(GLOB) 添加了一个新参数,它正是这样做的:
文件(GLOB SOURCES CONFIGURE_DEPENDS *.cxx)
关于 CONFIGURE_DEPENDS 我会看到这个 cmake 讨论: https://discourse.cmake.org/t/is-glob-still-considered-harmful-with-configure-depends/808
来自 Ben Boerkel(CMake 开发人员):
“检查成本取决于平台(可能还有生成器)。我不知道性能成本,但那是因为我个人发现即使它是高性能的,我也至少遇到了一个问题往往足以让它不值得。
我仍然强烈反对通配符,因为文件可能会出现在您不打算构建的源代码树中。我遇到的主要情况是,在 git 中解决冲突期间,冲突中文件的其他版本被命名为 ${base}${origin}${pid}.$ {ext},所以如果你试图在冲突中构建,你将把这些文件放在一起。
另一个原因是现在您的构建系统差异中不存在文件的添加/删除,因此跟踪“您更改了什么?”调试报告的问题可能会更难,因为没有证据表明在正常的 ${vcs} 差异输出中意外添加/删除了文件。”
================================