2015-11-04 85 views
0

我有工作,看起来像这样一个makefile:的Makefile与通用中间规则

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

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

$(TARGET): $(OBJECTS) 
    gcc -o [email protected] $^ 

%.o: %.c 
    gcc $(CFLAGS) -c -o [email protected] $< 

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

用户需要改变的唯一变量是目标名称,并建立它所需的资源。需要生成的对象从源自动确定。我想扩展它以支持多个目标,每个目标都有自己的源代码列表。尽管如此,我无法获得正确的语法。这是总体思路:

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

[email protected]=$([email protected]:%.c=%.o) 

$(TARGETS): $([email protected]) 
    gcc -o [email protected] $^ 

%.o: %.c 
    gcc $(CFLAGS) -c -o [email protected] $< 

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

但我不能让对象列表正确生成。我也不确定如何编写clean规则来清除所有对象。这可能吗?

+0

没有时间更多的时刻,但像这样你需要动态地界定目标的/ etc东西写上去。与['$(eval)'](http://www.gnu.org/software/make/manual/make.html#Eval-Function)和循环(可能[Canned Recipes](http:// www。 gnu.org/software/make/manual/make.html#Canned-Recipes)或者(或可能另外)[Secondary Expansion](http://www.gnu.org/software/make/manual/make.html# Secondary-Expansion)。除非你保存了所有对象/目标的列表(或者可以再次生成),否则'clean'规则将不起作用。 –

回答

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 [email protected] $^ 

$(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): $$([email protected]) 
     gcc -o [email protected] $^ 

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

clean目标变成两种情况下:

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