我有一个构建然后调用另一个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 \
$(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
答案 0 :(得分:606)
要生成的-B
切换,其长格式为--always-make
,告诉make
忽略时间戳并制作指定的目标。这可能会破坏使用make的目的,但它可能就是你所需要的。
答案 1 :(得分:25)
您可以将一个或多个目标声明为phony。
伪目标是一个实际上不是文件名的目标;而是它 只是在您明确表达时要执行的配方的名称 请求。使用虚假目标有两个原因:避免使用虚假目标 与同名文件冲突,并提高性能。
...
伪目标不应该是真实目标文件的先决条件;如果 它是,它的配方将在每次make更新时运行 文件。只要虚假目标永远不是真实的先决条件 目标,虚假目标食谱将只在假的时候执行 target是指定的目标
答案 2 :(得分:15)
以前在make
的Sun手册中记录的一个技巧是使用(不存在的)目标'.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
认为发布是最新的。这可能是因为您在执行的命令中有一个touch release
命令;可能是因为存在一个名为'release'的文件或目录,并且没有依赖关系,因此是最新的。那是真正的原因......
答案 3 :(得分:13)
有人建议.PHONY绝对是正确的。 .PHONY应该用于输入和输出之间的日期比较无效的任何规则。由于您没有output: input
形式的任何目标,因此您应该使用.PHONY进行所有目标!
所有这一切,您可能应该在makefile的顶部为各种文件名定义一些变量,并定义具有输入和输出部分的真实make规则,以便您可以使用make的好处,即您将只是实际编译了copmile所必需的东西!
编辑:添加了示例。未经测试,但这就是你做的.PHONY
.PHONY: clean
clean:
$(clean)
答案 4 :(得分:4)
如果我没记错的话,'make'使用时间戳(文件修改时间)来确定目标是否是最新的。强制重新构建的常用方法是使用“touch”命令更新该时间戳。您可以尝试在makefile中调用“touch”来更新其中一个目标(可能是其中一个子makefile)的时间戳,这可能会强制Make执行该命令。
答案 5 :(得分:4)
这种简单的技术将允许makefile在不需要强制时正常工作。在 makefile 的末尾创建一个名为强制的新目标。 强制目标将触及默认目标所依赖的文件。在下面的示例中,我添加了 touch myprogram.cpp 。我还添加了对 make 的递归调用。这将导致每次键入 make force 时都会生成默认目标。
yourProgram: yourProgram.cpp
g++ -o yourProgram yourProgram.cpp
force:
touch yourProgram.cpp
make
答案 6 :(得分:3)
我尝试了这个,它对我有用
将这些行添加到Makefile
clean:
rm *.o output
new: clean
$(MAKE) #use variable $(MAKE) instead of make to get recursive make calls
保存并立即致电
make new
它将重新编译所有内容
发生了什么事?
1)'新'呼叫干净。 'clean'do'rm'删除所有扩展名为“.o”的目标文件。
2)'新'调用'make'。 'make'看到没有'.o'文件,所以它再次创建了所有'.o'。然后链接器将所有.o文件链接到一个可执行输出
祝你好运答案 7 :(得分:1)
根据米勒的Recursive Make Considered Harmful,你应该避免打电话给$(MAKE)
!在你展示的情况下,它是无害的,因为这不是一个makefile,只是一个包装脚本,可能也是用Shell编写的。但是你说你在更深的递归水平上继续这样做,所以你可能已经遇到了那篇令人大开眼界的文章所显示的问题。
当然,使用GNU会让它变得很麻烦。即使他们意识到这个问题,也是他们记录的做事方式。
OTOH,makepp被创建为此问题的解决方案。您可以在每个目录级别编写makefile,但它们都可以一起绘制到项目的完整视图中。
但传统的makefile是递归写的。所以有一种解决方法,$(MAKE)
什么也不做,只是将子请求传回主makepp进程。只有你在你的子制造之间做了多余的,或者更糟的,相互矛盾的事情,你必须要求--traditional-recursive-make
(这当然打破了makepp的这个优势)。我不知道你的其他makefile,但是如果它们写得很干净,那么makepp必须自动进行重建,而不需要其他人在这里建议任何黑客攻击。
答案 8 :(得分:1)
如果您不需要保留已成功编辑的任何输出
nmake /A
重建所有
答案 9 :(得分:0)
实际上取决于目标是什么。如果它是虚假目标(即目标与文件无关),则应将其声明为.PHONY。
但是,如果目标不是虚假目标,但您只是想因某种原因重建它(例如,当您使用__TIME__预处理宏时),则应使用此处答案中描述的FORCE方案。
答案 10 :(得分:0)
答案 11 :(得分:0)
已经提到过了,但我想我可以添加touch
如果touch
要编译所有源文件,touch
命令会将文件的时间戳更改为执行touch
命令的系统时间。
源文件timstamp是make
用于“知道”文件已更改的内容,需要重新编译
例如:如果项目是c ++项目,那么执行touch *.cpp
,然后再次运行make
,make应该重新编译整个项目。
答案 12 :(得分:0)
make clean
删除所有已编译的目标文件。
答案 13 :(得分:0)
正如abernier指出的那样,GNU make手册中有一个推荐的解决方案,它使用“伪造”目标来强制重建目标:
clean: FORCE
rm $(objects)
FORCE: ;
无论其他任何依赖项,它都将正常运行。
我已将分号从手册中添加到解决方案中,否则需要空行。
答案 14 :(得分:-1)
在我的Linux系统(Centos 6.2)上,当规则实际创建与目标匹配的文件时,声明目标.PHONY和创建对FORCE的假依赖之间存在显着差异。每次必须重新生成文件时,它都需要 虚假依赖FORCE在文件上,.PHONY用于假依赖。
错误:
date > $@
对:
FORCE
date > $@
FORCE:
.PHONY: FORCE