Makefile具有通用中间规则

时间:2015-11-04 16:39:38

标签: makefile gnu-make

我有一个看起来像这样的makefile:

entity_id   revision_id     enable_value
      781          2313                0
      781          2314                1
      783          2316                1
      783          2318                0
      784          2317                0
      786          2321                1
      786          2322                1

用户需要更改的唯一变量是目标名称和构建它所需的源。需要生成的对象是从源自动确定的。我想扩展它以支持多个目标,每个目标都有自己的源列表。但是,我无法正确使用语法。这是一般的想法:

TARGET:=prog
SOURCES:=a.c b.c
CFLAGS:=-Wall -g -O2

OBJECTS:=$(SOURCES:%.c=%.o)

$(TARGET): $(OBJECTS)
    gcc -o $@ $^

%.o: %.c
    gcc $(CFLAGS) -c -o $@ $<

clean:
    rm -f $(TARGET) $(OBJECTS)

但是我无法正确生成对象列表。我也不确定如何编写TARGETS:=prog1 prog2 SOURCES_prog1:=a.c b.c SOURCES_prog2:=a.c c.c CFLAGS:=-Wall -g -O2 OBJECTS_$@=$(SOURCES_$@:%.c=%.o) $(TARGETS): $(OBJECTS_$@) gcc -o $@ $^ %.o: %.c gcc $(CFLAGS) -c -o $@ $< clean: rm -f $(TARGET) $(OBJECTS) 规则来清理所有对象。这可能吗?

1 个答案:

答案 0 :(得分:1)

我认为有两种主要方法可以做到这一点。

第一个涉及使用$(eval) function动态创建目标/先决条件映射。

TARGETS:=prog1 prog2
SOURCES_prog1:=a.c b.c
SOURCES_prog2:=a.c c.c
CFLAGS:=-Wall -g -O2

$(TARGETS):
        gcc -o $@ $^

$(foreach t,$(TARGETS),$(eval OBJECTS_$t := $(SOURCES_$t:.c=.o))$(eval $t: $(OBJECTS_$t)))

第二个涉及使用Secondary Expansion

TARGETS:=prog1 prog2
SOURCES_prog1:=a.c b.c
SOURCES_prog2:=a.c c.c
CFLAGS:=-Wall -g -O2

.SECONDEXPANSION:

$(TARGETS): $$(OBJECTS_$$@)
        gcc -o $@ $^

$(foreach t,$(TARGETS),$(eval OBJECTS_$t := $(SOURCES_$t:.c=.o)))

在任何一种情况下,clean目标都会变为:

clean:
        rm -f $(TARGETS) $(foreach t,$(TARGETS),$(OBJECTS_$t))