调用其他Makefile的Makefile始终过期

调用其他Makefile的Makefile始终过期,makefile,Makefile,我已经看过了很多关于递归生成文件的文章。要么我做错了什么,要么我想要的功能缺失了。使用典型的makefile,我可以使用-q检查它是否过时,例如: make -q || echo "out of date" 但是,设置强制make处理依赖makefile的机制会导致根makefile始终过期。下面是一个工作示例: #./Makefile all: myfile myfile: dir cp dir/myfile . .PHONY: dir dir: $(MAKE) -C d

我已经看过了很多关于递归生成文件的文章。要么我做错了什么,要么我想要的功能缺失了。使用典型的makefile,我可以使用
-q
检查它是否过时,例如:

make -q || echo "out of date"
但是,设置强制make处理依赖makefile的机制会导致根makefile始终过期。下面是一个工作示例:

#./Makefile
all: myfile

myfile: dir
    cp dir/myfile .

.PHONY: dir
dir:
    $(MAKE) -C dir/

#./dir/Makefile
all: myfile

myfile:
    touch myfile

#testing...
>>> make
make -C dir/
make[1]: Entering directory `dir'
touch myfile
make[1]: Leaving directory `dir'
cp dir/myfile .
>>> make
make -C dir/
make[1]: Entering directory `dir'
make[1]: Nothing to be done for `all'.
make[1]: Leaving directory `dir'
cp dir/myfile . #<-- this shouldn't be necessary
>>> make -q || echo "out of date"
make -C dir/
out of date
#/Makefile
全部:我的文件
myfile:dir
cp dir/myfile。
冒牌货:迪尔
目录:
$(MAKE)-C目录/
#/dir/Makefile
全部:我的文件
我的文件:
触摸我的文件
#测试。。。
>>>制造
make-C目录/
make[1]:输入目录'dir'
触摸我的文件
make[1]:离开目录'dir'
cp dir/myfile。
>>>制造
make-C目录/
make[1]:输入目录'dir'
make[1]:对“所有人”都不做任何事情。
make[1]:离开目录'dir'

cp dir/myfile# 不,没有办法。make的递归调用只是make在shell中调用的另一个命令:该命令的唯一可用结果是退出代码。如果我们能够始终确保调用的命令是make命令,并且我们使用了
-q
标志,那么我们可以假设如果它以0退出,那么什么也没有做。但是make并没有假设这些事情


您需要将makefile重写为非递归的,以获得所需的行为。

可能有一种黑客方法。
您可以调用
$(MAKE)-q…&&从makefile内部触摸某物
,并将
某物
文件作为外部makefile中某些规则的必要文件。

@Dacav给了我明确调用make的想法。虽然不使用临时文件,但可以使用shell填充的变量动态设置目标依赖项。我不确定下面的方法是否是一个好的解决方案,因为即使在不使用
-q
调用
make
时,它也会递归调用
make-q
来填充
旧的孩子。此外,对于子makefiles,这种情况也将不必要地再次发生(假设有多个递归级别)

测试

>>> make -q || echo out of date
make -C dir/
make: *** [dir/] Error 1 #huh??? whatever. still works, returning out of date
out of date
>>> make
make -C dir/
make[1]: Entering directory `dir'
touch myfile
make[1]: Leaving directory `dir'
cp dir/myfile .
>>> make
make: Nothing to be done for `all'.
>>> make -q || echo out of date
>>> #nothing. success :D
>>> make -q || echo out of date
make -C dir/
make: *** [dir/] Error 1 #huh??? whatever. still works, returning out of date
out of date
>>> make
make -C dir/
make[1]: Entering directory `dir'
touch myfile
make[1]: Leaving directory `dir'
cp dir/myfile .
>>> make
make: Nothing to be done for `all'.
>>> make -q || echo out of date
>>> #nothing. success :D