0

我很难想出一个生成文件规则来拥有几个可执行文件,每个可执行文件都依赖于其各自的源文件。有一个共同的库,每个程序都有一个源文件: 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我错过了什么?

4

2 回答 2

3

只是为了完整性:你可以用普通的旧静态模式规则做你想做的事,只要你可以匹配所有${TARGETS}与 make's (noddy) 模式匹配。

${TARGETS}: %: %.C lib.a
    g++ ${CFLAGS} $< -o $@ lib.a

lib.a: ...
    ar ...

比 ? 更具可读性,也许更兼容.SECONDEXPANSION

于 2013-04-04T10:22:37.140 回答
2

首先,我假设 fio.a 是一个错字(你可能是指 lib.a)。

其次,我认为棘手的部分是您的 ${@:%=%.c} 先决条件。AFAIK,$@ 不能以这种方式使用。

我认为您可以使用 .SECONDEPANSION 获得您正在寻找的行为。

尝试:

.SECONDEXPANSION:
${TARGETS} : lib.a $$(patsubst %,%.c,$$@)

可能有一种老式的替换方法可以做到这一点,但我发现 patsubst 行比 ${@:%=%.c} 更具可读性。

(我应该补充一点,这适用于 Gnu make 3.82. YMMV 与旧版本的 Gnu make 或 [heaven forbid] 非 Gnu 版本的 make)。

于 2013-04-03T20:42:31.207 回答