如何强制 makefile 重建目标?

2024-10-23 08:47:00
admin
原创
248
摘要:问题描述:我有一个 makefile,它构建后会调用另一个 makefile。由于这个 makefile 调用了更多 makefile 来完成工作,因此它实际上并没有改变。因此它一直认为项目已构建且是最新的。dnetdev11 ~ # make make: `release' is up t...

问题描述:

我有一个 makefile,它构建后会调用另一个 makefile。由于这个 makefile 调用了更多 makefile 来完成工作,因此它实际上并没有改变。因此它一直认为项目已构建且是最新的。

dnetdev11 ~ # make
make: `release' is up to date.

我如何强制 makefile 重建目标?

clean = $(MAKE) -f ~/xxx/xxx_compile.workspace.mak clean


build = svn up ~/xxx                                                       \n        $(clean)                                                                \n        ~/cbp2mak/cbp2mak -C ~/xxx ~/xxx/xxx_compile.workspace        \n        $(MAKE) -f ~/xxx/xxx_compile.workspace.mak $(1)                    \n

release:
        $(build )

debug:
        $(build DEBUG=1)

clean:
        $(clean)

install:
        cp ~/xxx/source/xxx_utility/release/xxx_util /usr/local/bin
        cp ~/xxx/source/xxx_utility/release/xxxcore.so /usr/local/lib

注:为保护无辜者,姓名被删除

最终修复版本:

clean = $(MAKE) -f xxx_compile.workspace.mak clean;


build = svn up;                                         \n        $(clean)                                        \n        ./cbp2mak/cbp2mak -C . xxx_compile.workspace;   \n        $(MAKE) -f xxx_compile.workspace.mak    $(1);   \n

.PHONY: release debug clean install

release:
        $(call build,)

debug:
        $(call build,DEBUG=1)

clean:
        $(clean)

install:
        cp ./source/xxx_utillity/release/xxx_util /usr/bin
        cp ./dlls/Release/xxxcore.so /usr/lib

解决方案 1:

make 的开关-B,其完整形式为--always-make,指示make忽略时间戳并生成指定的目标。这可能会违背使用 make 的目的,但这可能是您所需要的。

解决方案 2:

你可以将你的一个或多个目标声明为虚假的。

伪目标实际上并不是文件的名称;它只是您发出明确请求时要执行的配方的名称。使用伪目标有两个原因:避免与同名文件发生冲突,以及提高性能。

...

虚假目标不应是真实目标文件的先决条件;如果是,则每次 make 更新该文件时都会运行其配方。只要虚假目标永远不是真实目标的先决条件,则仅当虚假目标是指定目标时才会执行虚假目标配方

解决方案 3:

Sun 手册中曾经记录过一个技巧,即make使用(不存在的)目标“.FORCE”。您可以通过创建文件 force.mk 来实现此目的,该文件包含:

.FORCE:
$(FORCE_DEPS): .FORCE

然后,假设您现有的 makefile 名为makefile,您可以运行:

make FORCE_DEPS=release -f force.mk -f makefile release

由于.FORCE不存在,任何依赖它的东西都会过时并被重建。

所有这些都适用于任何版本的make;在 Linux 上,您拥有 GNU Make,因此可以使用所讨论的 .PHONY 目标。

还值得考虑为什么make认为 release 是最新的。这可能是因为touch release在执行的命令中有一个命令;可能是因为有一个名为“release”的文件或目录存在并且没有依赖项,因此是最新的。然后是实际原因...

解决方案 4:

其他人建议使用 .PHONY,这绝对是正确的。对于输入和输出之间的日期比较无效的任何规则,都应使用 .PHONY。由于您没有任何格式的目标,因此output: input您应该对所有目标使用 .PHONY!

尽管如此,您可能应该在 makefile 的顶部为各种文件名定义一些变量,并定义具有输入和输出部分的实际 make 规则,以便您可以利用 make 的好处,即您实际上只会编译编译所需的东西!

编辑:添加了示例。未经测试,但这就是执行 .PHONY 的方法

.PHONY: clean    
clean:
    $(clean)

解决方案 5:

make clean删除所有已编译的目标文件。

解决方案 6:

如果我没记错的话,“make”使用时间戳(文件修改时间)来确定目标是否是最新的。强制重新构建的常用方法是使用“touch”命令更新该时间戳。您可以尝试在 makefile 中调用“touch”来更新其中一个目标(可能是其中一个子 makefile)的时间戳,这可能会强制 Make 执行该命令。

解决方案 7:

我尝试过这个,它对我有用

将这些行添加到 Makefile

clean:
    rm *.o output

new: clean
    $(MAKE)     #use variable $(MAKE) instead of make to get recursive make calls

保存并立即调用

make new 

它将再次重新编译所有内容

发生了什么?

1) 'new' 调用 clean。'clean' 执行 'rm',删除所有以 '.o' 为扩展名的目标文件。

2) 'new' 调用 'make'。'make' 发现没有 '.o' 文件,因此再次创建所有 '.o'。然后链接器将所有 .o 文件链接到一个可执行输出

祝你好运

解决方案 8:

这种简单的技术可以让 makefile 在不需要强制时正常运行。在makefile末尾创建一个名为force的新目标。force目标将触及默认目标所依赖的文件。在下面的示例中,我添加了touch myprogram.cpp 。我还添加了对make 的递归调用。这将导致每次键入make force时都会生成默认目标。

yourProgram: yourProgram.cpp
       g++ -o yourProgram yourProgram.cpp 

force:
       touch yourProgram.cpp
       make

解决方案 9:

正如 abernier 指出的那样,GNU make 手册中有一个推荐的解决方案,它使用“假”目标来强制重建目标:

clean: FORCE
        rm $(objects)
FORCE: ; 

无论任何其他依赖项如何,它都将干净运行。

我从手册中为解决方案添加了分号,否则需要一个空行。

解决方案 10:

根据 Miller 的《递归 Make 被认为有害》一文,您应该避免调用$(MAKE)!在您展示的情况下,它是无害的,因为这实际上不是一个 makefile,只是一个包装器脚本,它可能也是用 Shell 编写的。但是您说您会在更深的递归级别继续这样做,所以您可能遇到了那篇令人大开眼界的文章中显示的问题。

当然,使用 GNU make 时,避免这个问题会很麻烦。尽管他们意识到了这个问题,但这是他们记录在案的做事方式。

另一方面,makepp就是为了解决这个问题而创建的。您可以在每个目录级别编写 makefile,但它们都会被集中到项目的完整视图中。

但是传统的 makefile 是递归编写的。因此,有一种解决方法,它$(MAKE)什么也不做,只是将子请求引导回主 makepp 进程。只有当您在子 make 之间执行了冗余或更糟的矛盾操作时,您才必须请求--traditional-recursive-make(这当然会破坏 makepp 的这一优势)。我不知道您的其他 makefile,但如果它们编写得干净利落,那么使用 makepp 所需的重建应该会自动进行,而无需其他人在此处建议的任何黑客攻击。

解决方案 11:

已经提到过了,但我认为我可以补充使用touch

如果您touch要编译所有源文件,该touch命令会将文件的时间戳更改为touch执行命令的系统时间。

源文件时间戳用于make“知道”文件已更改,需要重新编译

例如:如果该项目是 C++ 项目,则执行touch *.cpp,然后再次运行make,make 应该重新编译整个项目。

解决方案 12:

如果你不需要保留任何已经成功编译的输出

nmake /A 

重建所有

解决方案 13:

这实际上取决于目标是什么。如果是虚假目标(即目标与文件无关),则应将其声明为 .PHONY。

但是,如果目标不是虚假目标,但您只是出于某种原因想要重建它(例如当您使用 TIME 预处理宏时),您应该使用此处的答案中描述的 FORCE 方案。

解决方案 14:

在我的 Linux 系统 (Centos 6.2) 上,当规则确实创建与目标匹配的文件时,声明目标 .PHONY 和创建对 FORCE 的虚假依赖之间存在显著差异。当每次都必须重新生成文件时,它既需要对文件进行虚假依赖 FORCE,又需要对虚假依赖进行 .PHONY。

错误的:

date > $@

正确的:

FORCE
    date > $@
FORCE:
    .PHONY: FORCE
相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   2560  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   1552  
  IPD(Integrated Product Development)流程作为一种先进的产品开发管理模式,在众多企业中得到了广泛应用。其中,技术评审与决策评审是IPD流程中至关重要的环节,它们既有明显的区别,又存在紧密的协同关系。深入理解这两者的区别与协同,对于企业有效实施IPD流程,提升产品开发效率与质量具有重要意义...
IPD管理流程   1  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、ClickUp、Freshdesk、GanttPRO、Planview、Smartsheet、Asana、Nifty、HubPlanner、Teamwork。在当今快速变化的商业环境中,项目管理软件已成为企业提升效率、优化资源分配和确保项目按时交付的关键工具。然而...
项目管理系统   2  
  建设工程项目质量关乎社会公众的生命财产安全,也影响着企业的声誉和可持续发展。高质量的建设工程不仅能为使用者提供舒适、安全的环境,还能提升城市形象,推动经济的健康发展。在实际的项目操作中,诸多因素会对工程质量产生影响,从规划设计到施工建设,再到后期的验收维护,每一个环节都至关重要。因此,探寻并运用有效的方法来提升建设工程...
工程项目管理制度   3  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用