我的项目是一个固件,它有一个共同的逻辑部分,它是独立于设备的,也有一个依赖于设备的部分,现在我想让一个(假的)目标来构建设备A,一个(假的)目标来构建设备B。现在我想让一个(phoney)目标来构建设备A,一个(phoney)目标来构建设备B,这两个目标最好产生相同的命名二进制文件。target_A: $(COMMON_OBJ) $(A_OBJ)
我试着设置目标依赖变量,但由于它们只在配方中被评估,因此无法基于目标之间的共享Variable创建依赖列表。
这样做是行不通的。
target_A:
DEV_SRC = foo_a.c bar_a.c
target_A: $(COMMON_OBJ) $(DEV_SRC:.c=.o)
我现在的情况是这样的: 我需要为每个目标编写相同的配方,这是我想避免的。能否将其合并为一个单一的targetrecipe?
target_A: $(COMMON_OBJ) $(A_OBJ)
<build recipe>
target_B: $(COMMON_OBJ) $(B_OBJ)
<build recipe>
对于更多的背景。我喜欢把Makefile做得足够简单,这样工程师们就可以添加另一个目标,定义它的来源,也许还可以把目标或变量添加到一个现有的列表中。所有这些我认为对于每个程序员来说都是可以做到的,但是为了尽量减少错误的可能性,尤其是对于没有使用make经验的人来说,应该避免编写配方和扩展Makefile逻辑。
在以下的帮助下 二次扩建我想让它变得简单。
$ cat Makefile
TARGETS := target_A target_B
target_A_SRC := target_A.c
target_B_SRC := target_B.c
COMMON_OBJ := common.o
$(foreach target,$(TARGETS),$(eval $(target)_OBJ := $(addsuffix .o, $(basename $($(target)_SRC)))))
.SECONDEXPANSION:
.PHONY: all
all: $(TARGETS)
.PHONY: clean
clean:
-rm -f $(TARGETS) $(foreach target,$(TARGETS),$($(target)_OBJ)) $(COMMON_OBJ)
$(TARGETS): $(COMMON_OBJ) $$($$@_OBJ)
$(LINK.o) $(OUTPUT_OPTION) $^
为了添加新的目标,只需将新的目标添加到... ... $(TARGETS)
并定义 *_SRC
变量。其余的(构建和清理)将由现有的配方来处理。
输出示例。
$ make
cc -c -o common.o common.c
cc -c -o target_A.o target_A.c
cc -o target_A common.o target_A.o
cc -c -o target_B.o target_B.c
cc -o target_B common.o target_B.o
$ make clean
rm -f target_A target_B target_A.o target_B.o common.o