Один из подходов, которые я нашел для работы, заключается в том, чтобы конкретно описать зависимости правила установки. Для каждого файла нам нужно построить правило, такое как:
trg_dir/my_file: my_file
install $< $@
Для этого, однако, требуется немного магии gmake:
TRG := /trg
BIN_TRG := $(TRG)/bin
ETC_TRG := $(TRG)/etc
BIN_FILES := b1 b2 b3
ETC_FILES := e1 e2 e3
INSTALLS := $(addprefix $(BIN_TRG)/,$(BIN_FILES)) \
$(addprefix $(ETC_TRG)/,$(ETC_FILES))
install: $(INSTALLS)
define install_rule
$(1)/$(2): $(2)
install $(2) $(1)/$(2)
endef
$(foreach file,$(BIN_FILES),$(eval $(call install_rule,$(BIN_DIR),$(file))))
$(foreach file,$(ETC_FILES),$(eval $(call install_rule,$(ETC_DIR),$(file))))
.PHONY: install
Я чувствую, что этот код нуждается в некотором объяснении, это также моя главная проблема с ним -
это сложнее, чем такая, казалось бы, обычная задача:
Цель install:
остается фальшивой, но теперь она будет использоваться только для проверки актуальности отдельных правил установки.
Правила генерируются с оценкой результата вызова макроопределения отдельного правила. Мы используем функцию $(foreach ...)
для итерации по каждому файлу и задаем правильные параметры при $(call ...)
install_rule
.
Я поставил вопрос и ответ здесь, хотя, похоже, уже решил его, потому что я не доволен этим решением. Любой более элегантный будет с нетерпением принят.