使用define生成带有eval函数的Makefile规则

时间:2014-11-02 08:29:42

标签: c linux makefile

我想在Makefile中为许多PROG生成规则

CC = gcc
LD = gcc
CFLAGS = -g
LDFLAGS = -g

PROGS = test1 test2

SRCS_test1 = test1.c
SRCS_test2 = test2.c

$(foreach prog, $(PROGS), $(eval OBJS_$(prog) = $(SRCS_$(prog):%.c=%.o)))

.PHONY: all clean

all: $(PROGS)

define PROG_template
$(1): $$(OBJS_$$(1))
    @echo ------------------
    @echo $(1)
    @echo $$(OBJS_test1) $$(OBJS_test2)
    @echo $$(OBJS_$(1))
    @echo $$^
    @echo -----------------
    $$(LD) $$(LDFLAGS) -o $$@ $$^
endef

$(foreach prog, $(PROGS), $(eval $(call PROG_template, $(prog))))

%.o: %.c
    @echo compiling $@
    $(CC) $(CFLAGS) -c -o $@ $<

clean:
    rm -f $(OBJS_test1) $(OBJS_test2) $(PROGS)

像这样的输出

------------------
test1
test1.o test2.o


-----------------
gcc -g -o test1

gcc提示没有输入文件。 我的Makefile有什么问题? 首先谢谢。 对不起,我的英语很差。

1 个答案:

答案 0 :(得分:1)

您有两个错误。第一个只是一个错字;这一行:

$(1): $$(OBJS_$$(1))

应该是:

$(1): $$(OBJS_$(1))

(请注意删除第二个$中不需要的$(1)

第二个错误更微妙:当你在make中调用函数时,你必须要小心空格。例如,当您在call的参数中留下空格时,它可以嵌入到参数中。所以这里:

$(foreach prog, $(PROGS), $(eval $(call PROG_template, $(prog))))
                                                      ^

该空格被逐字逐句用作参数的一部分,因此'$1'等同于' test1',而不仅仅是'test1'。您可以使用eval替换eval来调试info操作,以查看make看到的内容:

$(foreach prog, $(PROGS), $(info $(call PROG_template, $(prog))))

会告诉你:

 test1: $(OBJS_ test1)

注意额外的空间。

删除多余的空格并且它可以正常工作:

$(foreach prog, $(PROGS), $(eval $(call PROG_template,$(prog))))
                                                     ^^