【问题标题】:Why is cmake file GLOB evil?为什么 cmake 文件 GLOB 是邪恶的?
【发布时间】:2015-12-01 10:23:39
【问题描述】:

CMake 文档中提到了命令 file GLOB:

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

网络上的几个讨论线程秒,通配源文件是邪恶的。

但是,要让构建系统知道某个源已被添加或删除,只需说明一下

touch CMakeLists.txt

对吗?

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

这个论点有什么问题?

【问题讨论】:

  • 另见讨论here。正如我的回答中所述,我使用了一种混合方法:在CMakeLists.txt 文件中列出所有源文件(也因为有时我会为不同的构建配置手动挑选源文件)和头文件的通配符(出于方便使用它们在 VS 项目中)。我建议了一个解决方法,例如gitconfigure_file(${CMAKE_SOURCE_DIR}/.git/index ${PROJECT_BINARY_DIR}/git_index.tmp) 类似。

标签: cmake glob


【解决方案1】:

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

假设项目有开发者 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 参数,这使得 globbing 扫描新文件:https://cmake.org/cmake/help/v3.12/command/file.html#filesystem

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

【讨论】:

  • 好点,谢谢。在我接受这个答案(并可能开始考虑解决方法)之前,请让我等一下,看看是否会提出更多问题。
  • @Jean-MichaëlCelerier 解决方法#1:在 git pull 之后运行 cmake(严重),解决方法#2:在 CMakeLists 中,将 globbing 的结果写入文件(有条件地,如果它没有'不存在)并将其置于源代码控制之下。使CMakeLists 包含该文件。添加新文件时,删除 globresult 文件。
  • 我不同意这些变通方法:第一种方法是在添加文件的人以外的人身上工作(根据经验,这不适用于 >3 人)。第二个为开发人员增加了更多的精神开销(在我的 CMakeLists 中添加文件和记住创建/删除文件之间......)。
  • @Jean-MichaëlCelerier :嗯,这是没有免费午餐的事情。我认为 sw 开发人员是聪明人,可以相信记住 #1 或进行心理飞跃 #2。但当然,选择应该取决于项目、观众和品味。每个替代方案(包括手动编辑CMakeList)都有其缺点。
  • @Uri:不,因为 globbing 本身的概念不能移植到 CMake 支持的所有构建类型 - 例如,它在 Visual Studio 解决方案或 XCode 项目中如何工作?
【解决方案2】:

这不是 固有的 邪恶 - 它有优点和缺点,在 StackOverflow 上的 this answer 中得到了较好的介绍。但是如果你不小心使用它,你最终可能会忽略依赖关系的变化,并需要对大部分代码库进行干净的重建。

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

【讨论】:

  • 有许多微妙的情况,在某些情况下,您必须将干净的构建作为唯一的救援。我认为它不适合大型项目
  • @Fei:这取决于你正在构建什么。在一个大型项目中,您可能会为其中的一小部分设置全局变量,但对于整个项目来说肯定不是。
  • 我的偏好也发生了变化,但从避免 globbing 到到处使用它,至少在同事允许的地方。我敢打赌你会再次改变你的偏好并编写一些脚本来让 globbing 更安全。
  • @PatrickFromberg:所以,答案的那一部分谈到了个人偏好;一般部分代表我是否喜欢更多,更少或根本不......
  • 我支持你的观点,手动添加文件色调很糟糕。不要告诉我有关 aux_source_directory 的事情。
【解决方案3】:

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

【讨论】:

  • 这听起来令人担忧——您能在 CMake 开发人员邮件列表中提出它吗?
  • 我听从了您的建议并试图打开问题,但是,我发现有人在 3 年前就已经这样做了 :-) gitlab.kitware.com/cmake/cmake/issues/15941
【解决方案4】:

通配符会破坏诸如 CLion 之类的所有代码检查,否则它们会理解 CMakeLists.txt 的有限子集,并且不会也永远不会支持通配符,因为它是不安全的。

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

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

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

【讨论】:

  • 甚至没有脚本:只是 Vim 中的 :read ! ls *.cc *.hh,bam,就是你的文件列表。
猜你喜欢
  • 2020-08-10
  • 2010-09-16
  • 2010-11-22
  • 2011-02-04
  • 2012-10-10
  • 2010-10-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多