gnu make copy many files to a single location

丶灬走出姿态 提交于 2019-12-12 13:19:37

问题


This question is similar in spirit to question 2543127.

I have a gnu makefile with a list of header files. Each header file may be located in a different directory, e.g.,

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

and I want to have the makefile copy all headers to an include directory

INCDIR = ../include

and when a dummy target, e.g., ALL is invoked, it will update the header files in the include directory appropriately, i.e.,

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

Obviously, I could accomplish what I want quite easily if I knew what the lists of directories were. If I did, then I could write some rules (something) like so (not entirely correct, but you get the jist):

$(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 $< $@

There are two problems with this approach, (1) It becomes tedious as the number of directories increases and (2) I am writing this in a makefile include, which doesn't know directories, all it knows are the variables INCDIR and HEADERS; it does not directly know the directories foo/, bar/, and ./ other than through $(sort $(dir $(HEADERS)))

Question: How can I write a rule to achieve the desired effect under the constraints of only being provided the INCDIR and HEADERS variables.


回答1:


This should do it:

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

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

all: $(TARGETS)

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

vpath %.h $(DIRS)



回答2:


OK. The answer is pretty "easy", although it requires usage of some gnu make that I haven't previously used. My solution, creates a subroutine that requires 2 arguments: (1) the name of the file (sans directory) and (2) the name of the directory in which it resided. The "subroutine" is a template for a rule. When one evaluates the call to the subroutine, one initiates another rules, just as if one had written it explicitly.

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

One then evaluates this subroutine for every header file and passes in the directory part and the file part of each header file.

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


来源:https://stackoverflow.com/questions/3302546/gnu-make-copy-many-files-to-a-single-location

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!