为什么 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 框中则不区分大小写。
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 框中则不区分大小写。