为什么cmakefileglob是邪恶的?

为什么cmakefileglob是邪恶的?,cmake,glob,Cmake,Glob,CMake文档说明了该命令: 我们不建议使用GLOB从源代码树中收集源文件列表。如果在添加或删除源时没有更改CMakeLists.txt文件,则生成的生成系统无法知道何时要求CMake重新生成 网络上的几个讨论线程都认为,全球化源文件是邪恶的 然而,为了让构建系统知道源代码已经被添加或删除,只需说 touch CMakeLists.txt 对吧? 然后,这比编辑CMakeLists.txt插入或删除源文件名要省力。记住也不难。所以我看不出有什么好的理由反对文件GLOB 这个论点有什么问题?问题

CMake文档说明了该命令:

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

网络上的几个讨论线程都认为,全球化源文件是邪恶的

然而,为了让构建系统知道源代码已经被添加或删除,只需说

touch CMakeLists.txt
对吧?

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


这个论点有什么问题?

问题在于你不是一个人在做一个项目

假设项目有开发者A和开发者B

A添加新的源文件
x.c
。他不会更改
CMakeLists.txt
,并在完成
x.c
的实现后提交

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

2020年编辑:CMake 3.12在
文件(GLOB
中引入了
CONFIGURE\u dependens
参数,使globbing扫描新文件:

但是,这是不可移植的(因为Visual Studio或Xcode解决方案不支持此功能)因此,请仅将其用作第一近似值,否则其他人在他们选择的IDE下构建您的CMake文件时可能会遇到问题!

这并不是天生的邪恶-它有优点和缺点,在StackOverflow一文中介绍得比较好。但如果您不小心使用它,您可能会忽略依赖项更改并需要对代码库的大部分进行干净的重建


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

Globbing打破了像CLion这样理解li的东西的所有代码检查CMakeLists.txt的斜接子集不支持也永远不会支持全局搜索,因为它是不安全的

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

在任何情况下,都不应该自动链接掉到某个目录中的某个随机文件,这就是特洛伊木马发生的原因


另外,CLion没有上下文跳转到已知的定义,就像赤脚徒步旅行一样///为什么麻烦呢。

除了其他人在这里发布的原因之外,glob最糟糕的问题是它可以在不同的平台上生成不同的文件列表。在我看来,这是一个bug。在OSX中,glob忽略了大小写敏感度,在ubuntu框中没有。

好的,谢谢。在我接受这个答案(可能开始考虑解决办法)之前,请让我等一下,看看是否还会出现更多的问题。@Jean-MichaëlCelerier解决办法1:在git pull之后运行cmake(认真地),解决办法2:在
CMakeLists
中,将全局绑定的结果写入一个文件(有条件地,如果它不存在)并将其置于源代码管理下。使
CMakeLists
包含该文件。在添加新文件时,删除globresult文件。我不同意这些解决方法:第一种方法需要对添加文件的人以外的人进行工作(根据经验,这对>3人不起作用)。第二种方法会给开发人员带来更多的精神负担(在我的CMakeLists中添加文件和记住创建/删除文件之间…)@Jean-MichaëlCelerier:嗯,这不是免费的午餐。我认为软件开发者是聪明的人,可以相信他们会记住“1”或做“精神飞跃2”。但当然,选择应该取决于项目、观众和口味。每种选择(包括手动编辑
CMakeList
)有它们的缺点。@Uri:没有,因为globbing的概念本身并不能移植到CMake支持的所有构建类型中——例如,它在Visual Studio解决方案或XCode项目中如何工作?另请参见讨论。正如我在回答中所述,我使用的是混合方法:在
CMakeLists.txt文件(也因为有时我为不同的构建配置手工挑选源文件)和头文件的全局化(为了方便在VS项目中使用它们)。我建议了一种解决方法,例如使用
configure\u文件(${CMAKE\u source\u DIR}/.git/index${PROJECT\u BINARY\u DIR}/git\u index.tmp)
。有许多微妙的情况,在某些情况下,你必须进行干净的构建作为唯一的补救措施。我认为这对大型项目不好projects@Fei:这取决于您正在构建的内容。在一个大型项目中,您可能会对其中的一小部分使用glob,这是有意义的,但肯定不会对整个项目使用glob。我的偏好也发生了变化,但是PatrickFromberg:答案的这一部分是关于个人偏好的,一般的部分是关于我是否更喜欢全球化,这听起来很糟糕你能在CMake开发者的邮件列表上提出来吗?我听从了你的建议,试图打开这个问题,然而,我发现3年前有人已经这么做了:-)甚至连一个脚本都没有:只是
:read!ls*.cc*.hh
在Vim中,砰,这就是你的文件列表。