我有一个项目,它涉及带有子 makefile 的子目录。我知道我可以使用 export 命令通过环境将变量从父 makefile 传递到子 makefile。有没有办法将变量从子生成文件传递到其调用生成文件? IE。可以反向导出工作吗?我已经尝试过但没有成功。我猜一旦 sub-make 完成它的 shell 和它的环境变量一起被销毁。是否有另一种向上传递变量的标准方法?
最佳答案
对您的问题的简短回答是:不,您不能[直接]为递归构建做您想做的事情(有关非递归构建,请参见下文)。
Make 像任何其他命令一样将子 make 过程作为配方行执行。它的 stdout/stderr 像任何其他进程一样被打印到终端。一般来说,子进程不能影响父进程的环境(显然我们不是在这里谈论环境,但同样的原则适用)——除非你有意在父进程中构建类似的东西,但你会使用IPC 机制来实现它。
我可以想象出很多方法来解决这个问题,所有这些听起来都是一件很糟糕的事情。例如,您可以写入文件并使用 include
获取它。 eval
中的指令(注意:未经测试) :
some_target:
${MAKE} ${MFLAGS} -f /path/to/makefile
some_other_target : some_target
$(eval include /path/to/new/file)
...虽然它必须在上面写的单独目标中,因为所有
$(macro statements)
在配方开始执行之前进行评估,即使宏位于配方的后面一行。gmake v4.x 有一个新功能,可以让您write out to a file直接来自 makefile 指令。文档中的一个示例:
If the command required each argument to be on a separate line of the input file, you might write your recipe like this:
program: $(OBJECTS) $(file >$@.in) $(foreach O,$^,$(file >>$@.in,$O)) $(CMD) $(CMDFLAGS) @$@.in @rm $@.in
(gnu.org)
...但你仍然需要一个
$(eval include ...)
宏在单独的配方中使用文件内容。我很怀疑使用
$(eval include ...)
在食谱中;在并行构建中,包含的文件可能会影响 make 变量,并且包含发生的时间可能与并行构建的其他目标无关。您最好为您的问题找到更自然的解决方案。我会先退后一步,问问自己“我想解决什么问题,其他人是如何解决这个问题的?”如果你没有找到试图解决这个问题的人,很有可能是因为他们没有沿着你所走的道路开始。
编辑您可以为非递归构建执行您想要的操作。例如:
# makefile1
include makefile2
my_tool: ${OBJS}
# makefile2
OBJS := some.o list.o of.o objects.o
...虽然我提醒你要非常小心。我维护的构建非常大(大约 250 个 makefile)。每个级别都包含如下语句:
include ${SOME_DIRECTORY}/*/makefile
这里的危险是你不希望人们在一棵树上依赖另一棵树的变量。有几个地方在短期内我不得不做一些你想做的事情:子生成文件附加到一个变量,然后该变量在父生成文件中使用。从长远来看,它会消失,因为它很脆弱/不安全,但目前我不得不使用它。
我建议你阅读论文Recursive Make Considered Harmful (如果该链接不起作用,只需 google the name of the paper )。
关于makefile - 子生成文件和向上传递变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31414456/