我有一个生成文件,然后调用另一个生成文件。因为这个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

当前回答

还有人建议使用. phony,这是绝对正确的。. phony应该用于任何输入和输出之间的日期比较无效的规则。由于表单output: input没有任何目标,所以应该对所有目标都使用.PHONY !

尽管如此,您可能应该在makefile的顶部为各种文件名定义一些变量,并定义真正的make规则,这些规则同时具有输入和输出部分,这样您就可以利用make的好处,即您只编译需要复制的东西!

编辑:新增示例。未经测试,但你就是这么做的。假的

.PHONY: clean    
clean:
    $(clean)

其他回答

根据米勒的递归使认为有害,你应该避免调用$(Make)!在您所展示的情况中,它是无害的,因为这不是一个真正的makefile,只是一个包装器脚本,它也可能是用Shell编写的。但是你说你在更深层次的递归中继续这样做,所以你可能遇到了那篇令人大开眼界的文章中所显示的问题。

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

OTOH,创建makepp就是为了解决这个问题。您可以在每个目录级别上编写makefile文件,但它们都汇集到项目的完整视图中。

But legacy makefiles are written recursively. So there's a workaround where $(MAKE) does nothing but channel the subrequests back to the main makepp process. Only if you do redundant or, worse, contradictory things between your submakes, you must request --traditional-recursive-make (which of course breaks this advantage of makepp). I don't know your other makefiles, but if they're cleanly written, with makepp necessary rebuilds should happen automatically, without the need for any hacks suggested here by others.

make的-B开关,其长形式为——always-make,告诉make忽略时间戳并使指定的目标。这可能会违背使用make的目的,但它可能正是您所需要的。

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

nmake /A 

重建所有

在我的Linux系统(Centos 6.2)上,当规则确实创建了一个匹配目标的文件时,在声明目标. phony和在FORCE上创建一个伪依赖项之间有一个显著的区别。当每次都必须重新生成文件时,两者都需要 文件上的伪依赖FORCE,以及伪依赖的. phony。

错误的:

date > $@

正确的:

FORCE
    date > $@
FORCE:
    .PHONY: FORCE

它已经被提到了,但我认为我可以添加到使用触摸

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

源文件时间戳是make用来“知道”文件已更改并需要重新编译的

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