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

发布于 2024-09-11 11:49:12 字数 1142 浏览 6 评论 0原文

这个问题在本质上与问题2543127类似。

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

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

我想让 makefile 将所有头文件复制到包含目录中

INCDIR = ../include

,并且当调用虚拟目标(例如 ALL)时,它将相应地更新包含目录中的头文件,即,

.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 include 中编写此内容,它不知道目录,它只知道变量 INCDIR 和 HEADERS;除了通过 $(sort $(dir $(HEADERS))) 之外,它不直接知道目录 foo/、bar/ 和 ./

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

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 
lt; $@

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

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

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

听,心雨的声音 2024-09-18 11:49:12

这应该可以做到:

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

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

all: $(TARGETS)

$(INCDIR)/%.h: %.h
  cp 
lt; $@

vpath %.h $(DIRS)

This should do it:

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

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

all: $(TARGETS)

$(INCDIR)/%.h: %.h
  cp 
lt; $@

vpath %.h $(DIRS)
旧瑾黎汐 2024-09-18 11:49:12

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

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

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

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

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)))))
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文