gnu将许多文件复制到一个位置

时间:2010-07-21 18:32:25

标签: gnu-make

这个问题与问题2543127的精神相似。

我有一个包含头文件列表的gnu makefile。每个头文件可以位于不同的目录中,例如,

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

我想让makefile将所有标题复制到include目录

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)我在makefile中写这个包含,它不知道目录,它只知道变量INCDIR和HEADERS;它不直接知道目录foo /,bar /和./,而不是通过$(sort $(dir $(HEADERS)))

问题:如何在仅提供INCDIR和HEADERS变量的约束下编写规则以达到预期效果。

2 个答案:

答案 0 :(得分:8)

这应该这样做:

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

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

all: $(TARGETS)

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

vpath %.h $(DIRS)

答案 1 :(得分:1)

行。答案非常“简单”,虽然它需要使用我以前没有使用的一些gnu make。我的解决方案,创建一个需要2个参数的子程序:(1)文件名(sans目录)和(2)它所在目录的名称。 “子程序”是规则的模板。当一个人评估对子程序的调用时,就会启动另一个规则,就像一个人明确地写了一样。

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

然后,为每个头文件评估此子例程,并传入每个头文件的目录部分和文件部分。

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