makefile - 子生成文件和向上传递变量

标签 makefile gnu-make

我有一个项目,它涉及带有子 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/

相关文章:

c++ - 奇怪的 GDAL 编译错误

为类创建文件夹的 Java makefile

makefile - 无法使用 nmake 将重定向符号 (>>) 写入文本文件

c++ - 如何在makefile中添加.c、.cc和.so文件来创建另一个.so?

linux - 详解mkmakefile生成的Makefile(Linux内核、buildroot、busybox)

c++ - GNU 使 : How to add an option in front of every entry of a list

HeadFirst C 中的 C Makefile 练习

c - Makefile:通配符和 patsubst 不会更改文件源名称

c++ - 使不更新可执行文件

gnu-make - 如何在多核 Linux 机器上使用 GNU make --max-load?