我难以想出一个makefile规则,有几个可执行文件,每个可执行文件依赖于它各自的源文件。所有人都有一个共同的库,每个程序都有一个源文件:a.c
编译并与库链接,生成可执行文件a
等。
LIB_C_FILES = f1.c f2.c f3.c
LIB_H_FILES = f1.h f2.h f3.h
TARGETS = a b c
CFLAGS = -g -O0 -DDEBUG
.PHONY : all clean
.c.o:
g++ -c $(CFLAGS) -o $@ $<
all: $(TARGETS)
${TARGETS} : lib.a ${@:%=%.c}
g++ $(CFLAGS) ${@:=.c} -o $@ lib.a
lib.a: ${LIB_C_FILES:.c=.o} $(LIB_H_FILES)
ar r $@ $?
库部分工作正常。当可执行文件不存在时,它也可以正常工作。但是当其中一个独立源文件被修改时,它会显示make: Nothing to be done for 'all'.
我不明白让目标a
在列表中单独依赖源a.c
的正确方法。我错过了什么?
答案 0 :(得分:3)
为了完整性:只要您可以将所有${TARGETS}
与make(noddy)模式匹配匹配,就可以使用普通的旧静态模式规则执行您想要的操作。
${TARGETS}: %: %.C lib.a
g++ ${CFLAGS} $< -o $@ lib.a
lib.a: ...
ar ...
比.SECONDEXPANSION
更具可读性,可能更兼容?
答案 1 :(得分:2)
首先,我假设fio.a是一个拼写错误(你可能意味着lib.a)。
其次,我认为棘手的部分是你的$ {@:%=%。c}先决条件。 AFAIK,$ @不能以这种方式使用。
我认为您可以使用.SECONDEXPANSION获取您正在寻找的行为。
尝试:
.SECONDEXPANSION:
${TARGETS} : lib.a $$(patsubst %,%.c,$$@)
可能有一种旧式的替换方式来执行此操作,但我发现patsubst行比$ {@:%=%。c}更具可读性。
(我应该补充一点,这适用于Gnu make 3.82.YMMV与旧版本的Gnu make,或[天堂禁止]非Gnu版本的make。)