Converting Strings to Uppercase in GNUmake
GNUmake doesn’t have a feature to convert Strings to uppercase. But hey, UNIX world is all easy. Just use a good shell, like bash :)
The demo use case is to pass a define to the C compiler that contains the filename stem converted to uppercase.
1 override CPPFLAGS+=-DFILE=FID_$${MODULE^^}
2
3 SHELL:=bash
4 export SHELLOPTS:=errexit:pipefail
5 sources:=$(shell find -name "*.c")
6
7 %.o: export MODULE=$*
8
9 .PHONY: all
10 all: foo
11
12 foo: foo.o $(sources:.c=.o)
13
14 .PHONY: clean
15 clean:
16 rm -f foo $(sources:.c=.o)
This simple Makefile compiles and links a binary named foo from all C source files.
The rule-specific variable MODULE
is defined for %.o
rules and contains the stem of the implicit rule match %.o: %.c
.
The variable MODULE
is exported to make it available to the bash subshells.
The variable CPPFLAGS
which is used by the shell scripts for the implicit rule %.o: %.c
contains the expression ${MODULE^^}
.
The bash shell will expand this to the value of the variable MODULE
and because of ^^
convert it to uppercase.
Btw. this Makefile is complete and will work for a lot of simple C projects.
You can also easily extend this Makefile to support an incremental build:
1 override CPPFLAGS+=-MMD -DFILE=FID_$${MODULE^^}
2
3 SHELL:=bash
4 export SHELLOPTS:=errexit:pipefail
5 sources:=$(shell find -name "*.c")
6
7 %.o: export MODULE=$*
8
9 .PHONY: all
10 all: foo
11
12 foo: foo.o $(sources:.c=.o)
13
14 -include $(sources:.c=.d)
15
16 .PHONY: clean
17 clean:
18 rm -f foo $(sources:.c=.o) $(sources:.c=.d)