为什么 cmake 文件 GLOB 是邪恶的?

Why is cmake file GLOB evil?

CMake 文档介绍了命令 file GLOB:

We do not recommend using GLOB to collect a list of source files from your source tree. If no CMakeLists.txt file changes when a source is added or removed then the generated build system cannot know when to ask CMake to regenerate.

Web 上的多个讨论线程认为通配源文件是邪恶的。

但是,要让构建系统知道已添加或删除源,只需说

touch CMakeLists.txt

对吧?

那么这比编辑 CMakeLists.txt 插入或删除源文件名更省力。也不难记住。所以我看不出有什么好的理由反对 file GLOB.

这个论点有什么问题?

问题是当你不是一个人在做一个项目时。

假设项目有开发人员 A 和 B。

A 添加了一个新的源文件x.c。他没有更改 CMakeLists.txt 并在完成 x.c.

后提交

现在 B 执行 git pull,并且由于 CMakeLists.txt 没有任何修改,CMake 不再 运行 并且 B 在编译时导致链接器错误,因为 x.c 尚未添加到其源文件列表中。

2020 编辑:CMake 3.12 向 file(GLOB 引入了 CONFIGURE_DEPENDS 参数,它对新文件进行通配扫描:https://cmake.org/cmake/help/v3.12/command/file.html#filesystem

然而,这不可移植(因为 Visual Studio 或 Xcode 解决方案不支持该功能)所以请仅将其用作第一近似值,否则其他人可能无法构建您的 CMake他们 IDE 选择的文件!

本质上不是邪恶的 - 它有优点也有缺点,在 Whosebug 上的 this answer 中介绍得相对较好。但是,如果您不小心使用它,您最终可能会忽略依赖项更改并需要干净地重建大部分代码库。

我个人赞成使用它 - 在较小的项目中,或在较大项目的某些子目录中 - 以避免必须将每个文件手动输入到构建文件中。 编辑:我的偏好已经改变,我目前倾向于避免它。

Globbing 破坏了 CLion 等东西中的所有代码检查,否则这些代码可以理解 CMakeLists.txt 的有限子集,并且不会也永远不会支持 globbing,因为它是不安全的。

编写脚本来转储 globbed 列表并将其粘贴进去,这非常简单,然后 CLion 可以实际找到引用的文件并推断它们有用。甚至可以将这样的脚本放入树中,以便其他开发人员可以 运行 它而不是白痴,或者设置 git 钩子来实现它。

在任何情况下,放入某个目录的随机文件都不应自动链接,这就是特洛伊木马程序的发生方式。

此外,没有上下文跳转到已知定义的 CLion 就像赤脚徒步旅行一样 /// 何必呢。

除了这里其他人发布的原因之外,恕我直言,glob 最糟糕的问题是它可以在不同平台上产生不同的文件列表。在我看来,这是一个错误。在 OSX 中,glob 忽略区分大小写,而在 ubuntu 框中则不区分大小写。