这可能有效,但我还没有测试过:
# ...
prereq: $(foreach dir ...)
program_name: $(all_objs) | prereq
$(LD) ...
它似乎在我的测试设置上工作,但我只测试了几个目录和对象。管道是order-only prerequisite,看起来可以把for循环放到一个target里面。
建议
如果你真的想要,你可以下载GNU Make 3.82 source,使用patch < function.c.patch 应用下面的补丁,然后使用make --debug=b -j32 ... 调用make 并注意Call、Evaluating 和Executing 行。
--- function.c 2010-07-13 03:20:39.000000000 +0200
+++ function.c.patched 2015-04-18 20:41:15.000000000 +0200
@@ -1371,6 +1371,8 @@
install_variable_buffer (&buf, &len);
+ DB (DB_BASIC, (_("Evaluating: %s\n"), argv[0]));
+
eval_buffer (argv[0]);
restore_variable_buffer (buf, len);
@@ -1652,6 +1654,11 @@
return o;
}
+ DB (DB_BASIC, (_("Executing shell command:")));
+ for ( char **p=command_argv; *p!=NULL; ++p )
+ DB (DB_BASIC, (_(" %s"), *p));
+ DB (DB_BASIC, (_("\n")));
+
# ifdef __EMX__
/* close some handles that are unnecessary for the child process */
CLOSE_ON_EXEC(pipedes[1]);
@@ -2311,6 +2318,12 @@
--cp;
cp[1] = '\0';
+ DB (DB_BASIC, (_("Call %s:"), fname));
+ for ( char **p=argv; *p!=NULL; ++p )
+ DB (DB_BASIC, (_(" %s"), *p));
+ DB (DB_BASIC, (_("\n")));
+
+
/* Calling nothing is a no-op */
if (*fname == '\0')
return o;
通过这种方式,您实际上可以查看 call compile_rule 是否在不应该运行的情况下运行。就我而言,输出是:
GNU Make 3.82
Built for x86_64-apple-darwin14.3.0
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Reading makefiles...
Executing shell command: find . -type d
Call compile_rule: compile_rule .
Evaluating: ./%.foo: ./%.txt
@echo build $@ from $<
Call compile_rule: compile_rule ./1
Evaluating: ./1/%.foo: ./1/%.txt
@echo build $@ from $<
Call compile_rule: compile_rule ./2
Evaluating: ./2/%.foo: ./2/%.txt
@echo build $@ from $<
Updating goal targets....
File `program' does not exist.
File `1/1.foo' does not exist.
Must remake target `1/1.foo'.
Invoking recipe from Makefile:11 to update target `1/1.foo'.
File `2/2.foo' does not exist.
Must remake target `2/2.foo'.
Invoking recipe from Makefile:11 to update target `2/2.foo'.
File `prereq' does not exist.
Must remake target `prereq'.
Successfully remade target file `prereq'.
build 1/1.foo from 1/1.txt
File `program' does not exist.
build 2/2.foo from 2/2.txt
File `program' does not exist.
Must remake target `program'.
Invoking recipe from Makefile:9 to update target `program'.
link program w/args 1/1.foo 2/2.foo