I need some help with my Makefile for a project. The source directory looks something like this.
|-- Makefile
|-- drivers
| |-- Makefile
| |-- tty
| |-- Makefile
| |-- console.c
| |-- keyboard.c
|-- kernel
| |-- Makefile
| |-- kmain.c
In the top Makefile, I have exported a variable OBJECTS that I want to populate with object files so I can build and link them together in the top Makefile.
I want to update OBJECTS in, say, drivers/tty/Makefile by doing something like this:
OBJECTS += $(CURDIR)console.o
OBJECTS += $(CURDIR)keyboard.o
But the change to OBJECTS does not bubble up to the top Makefile. I've been looking at the Makefiles in the Linux source tree, and they seem to be doing something similar. However, I can't get it to work. Am I missing something here?
You appear to be using Make recursively, something like
# Makefile:
export OBJECTS :=
all:
$(MAKE) -C drivers/tty
@echo OBJECTS is $(OBJECTS)
# drivers/tty/Makefile:
OBJECTS += $(CURDIR)console.o
all:
whatever
This doesn't work, because each Make has its own OBJECTS
; the child Make can't modify variables in the parent Make. It's export
, not import/export
or share
(there's no such thing as import/export
or share
, I'm just trying to illustrate).
You can get the effect you want by including the other makefiles instead of invoking them:
# Makefile:
OBJECTS :=
all: DRIVERS_TTY
@echo OBJECTS is $(OBJECTS)
include drivers/tty/Makefile
# drivers/tty/Makefile:
OBJECTS += drivers/tty/console.o
DRIVERS_TTY:
whatever
You'll notice there is some unpleasant location-dependency there; drivers/tty/Makefile
has "drivers/tty" spelled out inside it, which makes maintenance a pain. There are ways to fix that, once you have this basic include
trick working.
When you recursively run make it opens a new subshell for each subsequent call to make so you can't go back up the chain with your exports. One method would be for each call to a submake to append to an object list file and then possibly include that file. A better solution is to probably do something along the lines of having your main makefile include
each of these submake files directly instead of calling make on them. This method allows the OBJECTS variable to be built up using the each of the submake files with your OBJECTS +=
statements. Another added benefit is that you are running just one instance of make instead of multiple submakes which allows make to do better dependency generation. Take a look at "Recursive make considered harmful" http://aegis.sourceforge.net/auug97.pdf
One cool makefile build system that was posted up here before by user Dan Moulding https://stackoverflow.com/users/95706/dan-moulding really showed off a lot of the cool stuff you can do with submake files all while having just one master makefile. Dan's boilermake project is here: https://github.com/dmoulding/boilermake
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With