Целевые зависимые исходные файлы в gnu make - PullRequest
1 голос
/ 07 мая 2020

Мой проект - это прошивка, которая имеет общую часть c logi, которая не зависит от устройства, и часть, зависящую от устройства. Теперь мне нужна одна (фальшивая) цель для создания устройства A и одна (фальшивая) цель для сборки устройства B. Обе цели в идеале должны создавать двоичный файл с одинаковым именем. Очевидно, что обе цели зависят от общего независимого от устройства кода и их собственных индивидуальных источников. target_A: $(COMMON_OBJ) $(A_OBJ)

Я пытался установить целевые зависимые переменные, но тот факт, что они оцениваются только в рецепте, делает невозможным создание списка зависимостей на основе общей переменной между целями.

Это не работает. Можно ли это объединить в одну цель / рецепт?

target_A: $(COMMON_OBJ) $(A_OBJ)
    <build recipe>
target_B: $(COMMON_OBJ) $(B_OBJ)
    <build recipe>

Для получения дополнительной информации: мне нравится делать Makefile достаточно простым, чтобы коллеги-инженеры могли, например, добавить еще одну цель, определить ее источники и, возможно, добавить цель или переменную в существующий список. Все это я считаю выполнимым для каждого программиста, но следует избегать написания рецептов и расширения logi c Makefiles, чтобы минимизировать вероятность ошибок, особенно для людей, не имеющих опыта работы с make.

1 Ответ

1 голос
/ 07 мая 2020

С помощью вторичного расширения , я бы сделал это так же просто, как:

$ 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
...