GNU Make全局变量在子Make中更新



我需要一些关于项目的Makefile的帮助。源目录如下所示。

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

在顶部Makefile中,我导出了一个变量OBJECTS,我想用对象文件填充它,这样我就可以在顶部Makefile中构建并链接它们。

我想通过这样做来更新驱动程序/ty/Makefile中的OBJECTS:

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

但是对OBJECTS的更改并没有出现在Makefile的顶部。我一直在查看Linux源代码树中的Makefile,它们似乎也在做类似的事情。然而,我无法让它发挥作用。我是不是遗漏了什么?

您似乎在递归地使用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技巧。

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

用户Dan Moulding之前在这里发布的一个很酷的makefile构建系统https://stackoverflow.com/users/95706/dan-moulding真的展示了很多你可以用submakefile做的很酷的事情,而只有一个主makefile。Dan的样板房项目在这里:https://github.com/dmoulding/boilermake

最新更新