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?

+3


source to share


2 answers


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)

      

+3


source


You are doing it wrong. Just "expand the macro" and replace $(OBJS1)

with $(OBJS)

:

OBJS1 := $(C_SRCS:%.c=%.o)
OBJS = $(subst ./,./artifacts/,$(OBJS1))

      



becomes:

OBJS = $(subst ./,./artifacts/,$(C_SRCS:%.c=%.o))

      

+1


source







All Articles