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

其他回答

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

A phony target is one that is not really the name of a file; rather it is just a name for a recipe to be executed when you make an explicit request. There are two reasons to use a phony target: to avoid a conflict with a file of the same name, and to improve performance. ... A phony target should not be a prerequisite of a real target file; if it is, its recipe will be run every time make goes to update that file. As long as a phony target is never a prerequisite of a real target, the phony target recipe will be executed only when the phony target is a specified goal

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

这实际上取决于目标是什么。如果它是一个伪目标(即目标与文件无关),你应该将它声明为. phony。

然而,如果目标不是伪目标,而只是出于某种原因想要重新构建它(例如当你使用__TIME__预处理宏时),你应该使用回答中描述的FORCE方案。

一个曾经在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是最新的。这可能是因为你在执行的命令中有一个触摸释放命令;这可能是因为存在一个名为“release”的文件或目录,它没有依赖关系,所以是最新的。还有真正的原因…

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