STM32F103C8T6 ARM STM32 Minimum System Development Board

October 4, 2020

libmaple -- make system

Libmaple has a complex and interesting make system. It is well enough done to be worth some study. This page will be some of my notes of features of Gnu make that are new to me and used by the maple build system.

To start with, all binary objects get sent to the "build" directory. This ends up having a tree structure that parallels the directories that hold the source code.

The game starts with Makefile, which includes the file build-targets.mk as well as other files in support/make.

Make variables

There is tricky business as to just when variables are expanded. Some variables never are (and you may as well use := to assign to those). But deciding when variables get expanded required deep knowledge. Sometimes extra dollar signs are needed to ensure things get postponed as they should. I am not clarifying all this here, just pointing out that this issue exists.

There are many ways to assign values to Make variables.
The plain "=" sets a value, but does not try to evaluate the right side.
Using ":=" does evaluate the right side immediately.
Using "::=" is the same as ":=" and exists to promote confusion (thanks to POSIX).
Using "?=" sets the value only if it is not set already.
Using "!=" runs the right side as a shell command and assigns the result.
Using "+=" appends to a variable.

odds and ends

Make will by default try to make the first target if you don't specify one. You can specify a default target via:
.DEFAULT_GOAL := borax
The following line uses a bunch of tricks.
$(foreach m,$(LIBMAPLE_MODULES),$(eval $(call LIBMAPLE_MODULE_template,$(m))))
The syntax of foreach is: $(foreach var,list,text).
It takes list and assigns each item to var, then executes text. Probably text will include a reference to var as $(var).

The use of eval is a bit tricky. I generates makefile syntax that gets added to the makefile, or something of the sort. See also "info" and "shell".

"call" actually calls a makefile subroutine. Who knew there were such things? There really aren't makefile subroutines, we just have variables, which can be defined via "define" as well as assigning to them. Call just expands the variable after setting $(1) and so on to any "arguments" The one in this case is actually named "LIBMAPLE_MODULE_template" and is defined (using the define command) as:

define LIBMAPLE_MODULE_template
dir := $(1)
include $$(dir)/rules.mk
endef
So it has a single argument (here available as $(1)) which it assigns to the make variable "dir". It then pulls in a file "rules.mk" from that directory. Presumably rules.mk makes use of the value set to dir. Values for "dir" in the maple build scheme might be "./libmaple" or "./wirish".
Feedback? Questions? Drop me a line!

Tom's Computer Info / tom@mmto.org