Por que o Eval do GNU make converte uma lista em escalar?

0

Estou tentando usar eval para definir algumas variáveis de criação, mas, implicitamente, parece converter uma lista em escalar. Eu não consigo descobrir como evitar esse comportamento. Aqui está o meu Makefile atual:

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)"

e aqui está o comportamento atual que observo:

$ 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

Minha expectativa era que tanto $ (foo_gen_objs) quanto $ (foo_man_objs) avaliassem o mesmo valor, mas eval parece tratar $$ ($ (1) _srcs) como um escalar ao invés de uma lista. Como posso consertar isso?

    
por user65369 22.12.2017 / 18:17

1 resposta

1

A solução é bem simples: você deve escapar dos $ signs das funções addprefix ():

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

Mas é mais importante entender como você pode depurar esse tipo de problema sozinho. Basicamente, você apenas tem que substituir "eval" por "info", e make irá imprimir a entrada de eval ao invés de analisá-lo.

No seu exemplo, substituindo "eval" por "info" e, em seguida, chamando 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

Como você pode ver, call () expandiu as funções addprefix () antes de eval () ser chamado. Se você corrigir seu makefile como escrevi acima, você verá:

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

Tags