GNU сделать копию многих файлов в одном месте - PullRequest
3 голосов
/ 21 июля 2010

Этот вопрос по духу аналогичен вопросу 2543127 .

У меня есть make-файл GNU со списком заголовочных файлов.Каждый файл заголовка может быть расположен в отдельном каталоге, например,

HEADERS = $(wildcard *.h) $(wildcard foo/*.h) $(wildcard bar/*.h)

, и я хочу, чтобы make-файл копировал все заголовки во включаемый каталог

INCDIR = ../include

и когда фиктивная цельНапример, вызывается ALL, он будет соответствующим образом обновлять заголовочные файлы в каталоге include, то есть

.PHONY: ALL
ALL : $(addprefix $(INCDIR)/,$(notdir $(HEADERS)))

Очевидно, я мог бы довольно легко выполнить то, что хочу, если бы знал, какие были списки каталогов.Если бы я это сделал, то я мог бы написать некоторые правила (что-то вроде) (например, не совсем корректно, но вы получили ошибку):

$(addprefix $(INCDIR)/,$(notdir $(filter foo/%.h,$(HEADERS)))) : %.h : foo/%.h
     @cp -f $< $@

$(addprefix $(INCDIR)/,$(notdir $(filter bar/%.h,$(HEADERS)))) : %.h : bar/%.h
     @cp -f $< $@

$(addprefix $(INCDIR)/,$(notdir $(filter-out bar/%.h,$(filter-out foo/%.h,$(HEADERS))))) : %.h : %.h
     @cp -f $< $@

При таком подходе есть две проблемы: (1) он становится утомительнымпо мере увеличения количества каталогов и (2) я пишу это в make-файле include, который не знает каталогов, все, что он знает, - это переменные INCDIR и HEADERS;он не знает напрямую каталоги foo /, bar / и ./, кроме как через $ (sort $ (dir $ (HEADERS))) *

Вопрос: Как мне написать правило для достижения желаемого эффектапри условии наличия только переменных INCDIR и HEADERS.

Ответы [ 2 ]

8 голосов
/ 28 июля 2010

Это должно сделать это:

HFILES = $(notdir $(HEADERS))
DIRS = $(dir $(HEADERS))

TARGETS = $(addprefix $(INCDIR)/, $(HFILES))

all: $(TARGETS)

$(INCDIR)/%.h: %.h
  cp $< $@

vpath %.h $(DIRS)
1 голос
/ 21 июля 2010

OK.Ответ довольно "легкий", хотя он требует использования некоторых GNU Make, которые я ранее не использовал.Мое решение создает подпрограмму, которая требует 2 аргумента: (1) имя файла (sans directory) и (2) имя каталога, в котором он находился.«Подпрограмма» является шаблоном для правила.Когда кто-то оценивает вызов подпрограммы, он инициирует другие правила, как если бы он написал это явно.

define COPY_HEADER
$$(INCDIR)/$(2) : $(1)$(2)
     @cp -f $$< $$@
endef

Затем он оценивает эту подпрограмму для каждого заголовочного файла и передает в часть каталога и файлчасть каждого заголовочного файла.

$(foreach file,$(HEADERS),$(eval $(call COPY_HEADER,$(dir $(file)),$(notdir $(file)))))
...