일부 make 변수를 정의하기 위해 eval을 사용하려고 하는데 목록을 암시적으로 스칼라로 변환하는 것 같습니다. 이 동작을 피하는 방법을 알 수 없는 것 같습니다. 이것은 내 현재 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)"
이것은 내가 관찰한 현재 동작입니다.
$ 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
내 기대는 $(foo_gen_objs)와 $(foo_man_objs)가 모두 동일한 값으로 평가될 것이라는 것이었지만 eval은 $$($(1)_srcs)를 목록이 아닌 스칼라로 처리하는 것 같습니다. 이 문제를 어떻게 해결할 수 있나요?
답변1
해결책은 매우 간단합니다. 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
하지만 더 중요한 것은 이러한 문제를 직접 디버깅하는 방법을 아는 것입니다. 기본적으로 "eval"을 "info"로 바꾸면 make는 eval의 입력을 구문 분석하는 대신 인쇄합니다.
귀하의 예에서 "eval"을 "info"로 바꾸고 make를 호출하면 다음이 생성됩니다.
foo_srcs := a.c b.c
foo_gen_objs := objdir/$(foo_srcs:.c=.o)
foo_man_objs := objdir/a.o objdir/b.o
보시다시피 call()은 eval()을 호출하기 전에 addprefix() 함수를 확장합니다. 위에 쓴 대로 makefile을 수정하면 다음과 같은 결과를 얻을 수 있습니다.
foo_srcs := a.c b.c
foo_gen_objs := $(addprefix objdir/,$(foo_srcs:.c=.o))
foo_man_objs := $(addprefix objdir/,a.o b.o)