你如何强制makefile来重build目标

我有一个生成的文件,然后调用另一个生成文件。 由于这个makefile调用了更多的makefile,所以它并没有真正改变。 因此,它一直在考虑项目的build立和最新。

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

我如何强制makefile重build目标?

 clean = $(MAKE) -f ~/xxx/xxx_compile.workspace.mak clean build = svn up ~/xxx \ $(clean) \ ~/cbp2mak/cbp2mak -C ~/xxx ~/xxx/xxx_compile.workspace \ $(MAKE) -f ~/xxx/xxx_compile.workspace.mak $(1) \ 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; \ $(clean) \ ./cbp2mak/cbp2mak -C . xxx_compile.workspace; \ $(MAKE) -f xxx_compile.workspace.mak $(1); \ .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 

你可以宣称你的一个或多个目标是虚假的 。

虚假的目标是一个不是真正的文件的名称; 相反,它只是一个当您提出明确请求时要执行的配方的名称。 使用虚假目标有两个原因:避免与同名文件冲突,并提高性能。

虚假目标不应成为真实目标文件的先决条件; 如果是的话,它的配方会在每次更新该文件时运行。 只要虚假目标不是真正目标的先决条件,虚假目标配方将只在虚假目标是指定目标

-B开关长,其forms是“ --always-makemake忽略时间戳并制定指定的目标。 这可能会破坏使用make的目的,但这可能是你需要的。

曾经在Sun手册中logging的一个技巧是使用(不存在的)目标“.FORCE”。 你可以通过创build一个包含以下内容的文件force.mk来实现:

 .FORCE: $(FORCE_DEPS): .FORCE 

然后,假设你现有的makefile被称为makefile ,你可以运行:

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

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

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

同样值得考虑的是为什么认为发布是最新的。 这可能是因为在执行的命令中有一个touch release命令; 这可能是因为有一个名为“释放”的文件或目录存在,并且没有依赖关系,因此是最新的。 那么这就是真正的原因

其他人build议.PHONY这是绝对正确的。 .PHONY应该用于input和输出之间的date比较无效的任何规则。 由于你没有任何formsoutput: input目标output: input你应该使用.PHONY所有的!

所有这一切,你可能应该在你的makefile的顶部为各种文件名定义一些variables,并且定义具有input和输出部分的真正的make规则,所以你可以使用make的好处,也就是说你只能实际编译事情是必要的copmile!

编辑:添加示例。 未经testing,但这是你如何做.PHONY

 .PHONY: clean clean: $(clean) 

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

这种简单的技术将允许makefile在不需要强制的情况下正常工作。 在makefile的最后创build一个名为force的新目标。 强制目标将触及默认目标所依赖的文件。 在下面的例子中,我添加了触摸myprogram.cpp 。 我还添加了一个recursion调用。 这会导致每次inputmake force时都会产生默认目标。

 yourProgram: yourProgram.cpp g++ -o yourProgram yourProgram.cpp force: touch yourProgram.cpp make 

我试过这个,它为我工作

将这些行添加到Makefile

 clean: rm *.o output new: clean make 

保存并现在打电话

 make new 

它会重新编译一切

发生了什么?

'new'调用clean'clean'do'rm',它删除所有扩展名为'.o''new'调用'make'的输出文件。 'make'看到没有'.o'文件,所以它继续前进,并再次创build所有'.o'。

祝你好运

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

 nmake /A 

重build所有

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

但是,如果目标不是虚假目标,但是由于某种原因(例如当使用__TIME__预处理macros),您只需要重新构build目标,则应该使用此处的答案中所述的FORCEscheme。

按照米勒的recursion考虑有害,你应该避免调用$(MAKE) ! 在这种情况下,它是无害的,因为这不是一个真正的makefile,只是一个包装脚本,这也可能是在Shell中编写的。 但是你说你在更深的recursion层次上继续这样做,所以你可能遇到了这个令人大开眼界的文章中显示的问题。

当然,用GNU做起来很麻烦。 即使他们意识到这个问题,也是他们logging的做事方式。

OTOH, makepp是为解决这个问题而创build的。 您可以在每个目录级别上编写您的makefile,但是它们都可以被整合到一个完整的项目视图中。

但是传统的makefile是recursion的编写的。 所以有一个解决方法,其中$(MAKE)什么都不做,只是将子请求传回主makepp进程。 只有当你在子部件之间做了冗余或者更糟糕的事情时,你必须要求 – --traditional-recursive-make (这当然会破坏makepp的这个优点)。 我不知道你的其他makefiles,但如果他们是干净的书面,与makepp必要的重build应该自动发生,而不需要任何黑客在这里build议的其他人。

这已经被提到,但是我认为我可以添加到使用touch

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

源文件timstamp是用来“知道”一个文件已经改变,并且需要重新编译的东西

例如:如果项目是一个c ++项目,那么请touch *.cpp ,然后再次运行make ,并且应该重新编译整个项目。

在我的Linux系统上(Centos 6.2),在声明目标.PHONY和在FORCE上创build一个假依赖关系时,实际上创build了一个匹配目标的文件是有很大区别的。 当文件必须每次都重新生成时,它需要文件上的伪依赖性FORCE和假的依赖性的.PHONY。

错误:

 date > $@ 

对:

 FORCE date > $@ FORCE: .PHONY: FORCE