GNU使子变量中的全局变量更新

时间:2012-10-05 11:09:46

标签: recursion makefile global-variables

我需要一些项目的Makefile帮助。源目录看起来像这样。

|-- Makefile
|-- drivers
|   |-- Makefile
|   |-- tty
|       |-- Makefile
|       |-- console.c
|       |-- keyboard.c
|-- kernel
|   |-- Makefile
|   |-- kmain.c

在顶部的Makefile中,我导出了一个我希望用目标文件填充的变量OBJECTS,因此我可以在顶部的Makefile中构建并链接它们。

我想通过这样的方式更新,例如,drivers / tty / Makefile中的OBJECTS:

OBJECTS += $(CURDIR)console.o
OBJECTS += $(CURDIR)keyboard.o

但是对OBJECTS的更改并未冒泡到顶级Makefile。我一直在查看Linux源代码树中的Makefile,他们似乎在做类似的事情。但是,我无法让它发挥作用。我在这里错过了什么吗?

2 个答案:

答案 0 :(得分:1)

当您以递归方式运行make时,它会为每个后续调用打开一个新的子shell,这样您就无法使用导出返回链。一种方法是每次调用子进程以附加到对象列表文件,然后可能包含该文件。一个更好的解决方案是可能做一些事情,直接让你的主要makefile include每个这些子制作文件,而不是在它们上调用make。此方法允许使用带有OBJECTS +=语句的每个子制作文件构建OBJECTS变量。另一个额外的好处是你只运行一个make实例而不是多个submakes,这使得make可以做更好的依赖生成。看一看“递归使被认为有害”http://aegis.sourceforge.net/auug97.pdf

之前由用户Dan Molding https://stackoverflow.com/users/95706/dan-moulding发布的一个很酷的makefile构建系统真的展示了很多很酷的东西,你可以用submake文件完成,同时只有一个主makefile。 Dan的boilermake项目在这里:https://github.com/dmoulding/boilermake

答案 1 :(得分:1)

您似乎正在使用Make递归,类似

# Makefile:

export OBJECTS :=
all:
    $(MAKE) -C drivers/tty
    @echo OBJECTS is $(OBJECTS)

# drivers/tty/Makefile:

OBJECTS += $(CURDIR)console.o
all:
    whatever

这不起作用,因为每个Make都有自己的OBJECTS;子Make不能修改父Make中的变量。它是export,而不是import/exportshare(没有import/exportshare这样的东西,我只想说明一下。)

你可以通过包括其他makefile而不是调用来获得你想要的效果:

# Makefile:

OBJECTS :=
all: DRIVERS_TTY
    @echo OBJECTS is $(OBJECTS)

include drivers/tty/Makefile

# drivers/tty/Makefile:

OBJECTS += drivers/tty/console.o

DRIVERS_TTY:
    whatever

你会注意到那里有一些不愉快的位置依赖; drivers/tty/Makefile里面有“drivers / tty”,这使维护成为一种痛苦。一旦你有了这个基本的include技巧,就有办法解决这个问题。