我设置make使用递归make构建我的树。所以设置是
A/Makefile a.c
A/B/Makefile a.c
A/B/C/Makefile a.c
如果我从A级发出命令make all
,那么make将沿着树构建一切,然后再回来。每个Makefile都包含要在其下构建的文件夹列表。根目录中有一个common.inc文件,在每个Makefile中都会被读取。
这只是递归make的标准布局,并没有什么新东西。细节在许多地方给出。 here和here就是例子。
我的问题是这样的:很多次我想做make all
但是只在当前文件夹中构建东西,而不是实际沿树下行,可能是因为我想测试当前的一些变化这个文件夹。所以我最后通过注释掉下面列出所有文件夹的SUBDIRS=A B C
或者只为这个文件夹添加新的特殊目标来编辑当前文件夹的Makefile。两者都是令人讨厌的事情。
是否有任何人有一个想法或一个递归makefile的小例子,它使用一个开关来告诉它是否应该在调用时沿着树向下移动?可能有一种方法来调用make并在命令行传递一些标志,这个标志用于删除SUBDIRS=A B C .....
列表,所以它只在当前文件夹级别停止?
要清楚。我在Rules.mk中使用标准SUBDIRS,树中的每个Makefile都包含。这是部分。我很久以前就从网上复制了这个
$(SUBDIRS)::
@if test -d $@; then \
set $(EXIT_ON_ERROR); \
echo "cd $@; make $@"; \
cd $@; make $@; \
set +e; \
else \
echo "Skipping non-directory $@..."; \
fi \
$(CLICK_STOPWATCH);
endif
并在我写的每个文件夹Makefile中
SUBDIRS = A B C
include Rules.mk
all:: .......
然后我写make all
来构建。如果有一种方法可以做make all LOOP=0
,其中LOOP是某个值我传递它或选项或字符串或其他东西,然后更改上面的SUBDIRS
逻辑以检查此{{1}的值然后根据值然后执行递归make或not,然后解决问题。如果命令行中缺少默认值,则默认值为LOOP
。
但我不知道Make编程这种类型的逻辑。
答案 0 :(得分:2)
您应该使用规则的依赖关系。将源文件添加到从“根Makefile”调用的规则的依赖项中。如果这些文件是最新的,则文件夹中的递归将停止,因为规则是“最新的”,并且不会执行任何操作。 不要在子目录Makefile中为所有规则添加.PHONY,否则将调用递归规则。
使用规则的依赖关系可以是不进行递归调用的关键,但如果您修改每个文件夹中的源并且只想从根Makfile构建,则必须创建另一个规则。对于make all
,make二进制文件可能不知道您是否要构建所有项目(如果所有源都已修改)。
编辑选择
你接近答案,你可以在调用make all
时设置env var并测试值以决定是否递归调用。
CC=g++
SUBDIR=a b
all: ${SUBDIR} main.cc
${CC} main.cc
${SUBDIR}:
ifneq ($(MK_LOOP), 0)
@echo "trust the recursivity !"
${MAKE} -C $@
endif
.PHONY: ${SUBDIR}
如果没有设置MK_LOOP
var或者设置为0以外的其他值,它将不等于0,因此将调用递归的Makefile;如果设置为0,则$(SUBDIR)
规则不执行任何操作
42SH $ MK_LOOP=0 make # no recur
42SH $ make all
trust the recursivity !
42SH $ make all MK_LOOP=1 # recur by default; same as : make all
trust the recursivity !
42SH $