Makefile 配方更改时如何重建
我想知道是否已经有人问过这个问题。搜索并不容易Makefile 配方更改时如何重建,makefile,gnu-make,Makefile,Gnu Make,我想知道是否已经有人问过这个问题。搜索并不容易 make的设计假设Makefile有点像上帝。它完全了解项目的未来,除了添加新的源文件之外,不需要任何修改。这显然不是真的 我曾经让Makefile中的所有目标都依赖于Makefile本身。因此,如果我更改了Makefile中的任何内容,整个项目都将重建 这有两个主要限制: 它重建得太频繁了。添加链接器选项或新的源文件将重建所有内容 如果我在命令行上传递一个变量,比如makecflags=-O3,它将不会重建 我看到了一些正确的方法,但乍一看没有一
make
的设计假设Makefile有点像上帝。它完全了解项目的未来,除了添加新的源文件之外,不需要任何修改。这显然不是真的
我曾经让Makefile中的所有目标都依赖于Makefile本身。因此,如果我更改了Makefile中的任何内容,整个项目都将重建
这有两个主要限制:
makecflags=-O3
,它将不会重建make
是在这样一个时代设计的:源代码树位于一个分层的文件系统中,这是您需要了解的关于软件配置管理的所有知识,它将这个想法带到了逻辑的结果中,即所有这些都是一个文件(带有时间戳)。因此,将链接器选项、定位表、编译器标志和除厨房水槽之外的所有内容都放在一个文件中,并将其依赖项也放在一个文件中,就make
而言,将产生一个一致、完整且无错误的构建环境
这意味着必须通过文件命令行参数将数据传递给进程(也就是说,该进程依赖于该数据),因为make变量滥用了make的功能并导致错误的结果<代码>清理是系统性不当行为的技术补救措施。如果软件工程师正确地设计了make过程,就没有必要了
问题是干净的构建过程很难设计和维护。但是:在现代软件过程中,瞬态/易失性构建参数(如使所有CFLAGS=O3
无论如何都没有位置,因为它们破坏了配置管理的所有良好基础
对make
唯一可以批评的可能是它不是软件构建的最终解决方案。我怀疑一个具有此任务的程序是否会达到make
s受欢迎程度的1%
TL;博士
将编译器/链接器/定位器选项放在单独的文件中(位于一个中心、突出、易于维护和理解的逻辑位置),通过信息的粒度决定控制级别(例如,一个文件中的编译器标志,另一个文件中的链接器标志),并记录所有文件的真正相关性,瞧,您将拥有完全必要的编译量和正确的构建。我有针对多个平台编译的项目。在构建以前为不同体系结构编译的单个项目时,可以手动强制重建。但是,在为OpenWRT编译所有项目时,手动清理是不可管理的 我的解决方案是创建一个标识平台的标记。如果丢失,所有内容都将重新编译
ARCH ?= $(shell uname -m)
CROSS ?= $(shell uname -s).$(ARCH)
# marker for the last built architecture
BUILT_MARKER := out/$(CROSS).built
$(BUILT_MARKER) :
@-rm -f out/*.built
@touch $(BUILT_MARKER)
build: $(BUILT_MARKER)
# TODO: add your build commands here
如果您的标志太长,您可以将其减少为校验和。我认为您无法获得比第一种方法更直接的结果,但没有一种方法是万无一失的:Make通常无法判断哪些更改会影响哪个目标。人们通常不会经常修改他们的makefile,从而使这种工作变得有价值。@Beta,我知道,在正确重建之前,我通常只花几分钟就意识到我需要
清除。但我想也许有一个很好的方法让事情一劳永逸。永远。所以,基本上,“让我们再次使makefile保持静态”,哈?事实上,我认为make的瞬态参数是一种特性,而不是一种副作用滥用,我想完全支持它。这是一种测试各种编译器、链接器和选项的快速简便的方法。@Celelibi完全由您决定是否具有可控性、可跟踪性和基线功能。有些项目不需要这种开销,但大多数都需要。这种解决方案是否慢取决于(双关语)你的编辑工具,而不是方法。我宁愿在命令行文件中编辑,也不愿尝试恢复昨天的shell历史来再次找到开关,这使得难以找到的Heisen bug在上一次构建中重新出现。顺便说一句,yo要求“一劳永逸地解决问题”。正确使用make
的规则是利用文件系统,而不是别的。如果你不喜欢这种哲学,make
是错误的工具。