0

I'm trying to to use eval to define a few make variables, but implicitly it seems to convert a list into a scalar. I can't seem to figure out how to avoid this behavior. Here's my current Makefile:

foo_man_srcs := a.c b.c

define GEN_OBJS =
    $(1)_srcs := a.c b.c
    $(1)_gen_objs := $(addprefix objdir/,$$($(1)_srcs:.c=.o))
    $(1)_man_objs := $(addprefix objdir/,$(foo_man_srcs:.c=.o))
endef

$(eval $(call GEN_OBJS,foo))

all:
    echo "foo_gen_objs: $(foo_gen_objs)"
    echo "foo_man_objs: $(foo_man_objs)"

and here is the current behavior I observe:

$ make
echo "foo_gen_objs: objdir/a.o b.o"
foo_gen_objs: objdir/a.o b.o
echo "foo_man_objs: objdir/a.o objdir/b.o"
foo_man_objs: objdir/a.o objdir/b.o

My expectation was that both $(foo_gen_objs) and $(foo_man_objs) would evaluate to the same value, but instead eval seems to treat $$($(1)_srcs) as a scalar rather than as a list. How can I fix this?

1 Answer 1

1

The solution is quite simple: you should escape the $ signs of the addprefix() functions:

define GEN_OBJS =
    $(1)_srcs := a.c b.c
    $(1)_gen_objs := $$(addprefix objdir/,$$($(1)_srcs:.c=.o))
    $(1)_man_objs := $$(addprefix objdir/,$(foo_man_srcs:.c=.o))
endef

But it's more important to understand how you can debug this sort of problems by yourself. Basically, you just have to replace "eval" with "info", and make will print the input of eval instead of parsing it.

In your example, substituting "eval" with "info" and then calling make yields:

foo_srcs := a.c b.c
foo_gen_objs := objdir/$(foo_srcs:.c=.o)
foo_man_objs := objdir/a.o objdir/b.o

As you can see, call() expanded the addprefix() functions before eval() is called. If you fix your makefile as I wrote above you'll get:

foo_srcs := a.c b.c
foo_gen_objs := $(addprefix objdir/,$(foo_srcs:.c=.o))
foo_man_objs := $(addprefix objdir/,a.o b.o)

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.