Can inline Makefile functions be nested?
I am trying to do some string manipulation in a Makefile using string functions that make suggestions. I want to do two conversions on my lines, I have a variable that lists the source files similar to:
C_SRCS += \
./src/foo.c \
./src/bar.c \
...
I want to take this string and convert it to a new variable containing all object files. The objects will be stored in a different directory and the obvious one will have an extension .o
instead of .c
. Effectively, they must change:
./src/<file>.c
to
./artifacts/src/<file>.o
I can do it with two rules like:
OBJS1 := $(C_SRCS:%.c=%.o)
OBJS = $(subst ./,./artifacts/,$(OBJS1))
which will work fine, but I was hoping to combine these two rules and remove the intermediate variable. I tried:
OBJS = $($(subst ./,./artifacts/,$(C_SRCS)):%.c=%.o)
and what's just left OBJS
empty, I thought maybe it would be better if I used two of the same function types, so I tried:
OBJS = $(subst %.c,%.o,$(subst ./,./artifacts/,$(C_SRCS)))
and executed only the nested rule, but OBJS
it was set./artifacts/src/foo.c ./artifacts/src/bar.c ...
I started reading some Make docs, but I can't find anything about nesting string functions. Is it possible to inline string functions in Make files? If so, what am I doing wrong here?
source to share
Yes, you can insert string functions.
You cannot use shorthand notation :X=Y
for the result of a function.
So when you combine OBJS1 := $(C_SRCS:%.c=%.o)
and OBJS = $(subst ./,./artifacts/,$(OBJS1))
, you haven't done it right (or in the obvious way), you have done something else. You wrote OBJS = $($(subst ./,./artifacts/,$(C_SRCS)):%.c=%.o)
when explicit (and correct) nesting would be OBJS = $(subst ./,./artifacts/,$(C_SRCS:%.c=%.o))
. (It may have been a typo, I'm not sure).
Abbreviation :X=Y
is shorthand for patsubst
(automatically %
prefixed transcript), not subst
, so your string OBJS = $(subst %.c,%.o,$(subst ./,./artifacts/,$(C_SRCS)))
doesn't work (note that $(C_SRCS:.c=.o)
will happen in more places than just the end of values).
See working versions below.
C_SRCS += \
./src/foo.c \
./src/bar.c
pv = $(warning $1: $($1))
$(call pv,C_SRCS)
$(warning RAW: $(subst ./,./artifacts/,$(C_SRCS:%.c=%.o)))
OBJS = $(patsubst %.c,%.o,$(subst ./,./artifacts/,$(C_SRCS)))
$(call pv,OBJS)
source to share