如何强制makefile重建目标

时间:2009-05-03 05:00:49

标签: linux makefile

我有一个构建然后调用另一个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

15 个答案:

答案 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