1

我有一个带有多个目标的生成文件,这些目标是通过从工作目录外部复制文件生成的。

a.tex   : $(wildcard /foo/work1/a.tex)
    cp -p $< $@

b.tex   : $(wildcard /foo/work2/b.tex)
    cp -p $< $@

我之所以使用$(wildcard)Make,是因为有时我会在无法访问/foo.

避免cp -p $< $@对每条规则重复命令的最佳方法是什么?一些选项:

  • 设置%.tex : %.tex规则。这可行,但它也适用于未明确指出的目标,因此我收到很多警告,例如make: Circular a.tex <- a.tex dependency dropped.
  • 用 定义一系列命令define。这似乎毫无意义,因为该命令只有一行。因此cp $< $@,我不会复制到每个规则,而是定义一个cp-dep序列并复制cp-dep到每个规则。
  • 将命令定义为变量,以便我可以做a.tex : $(wildcard /foo/work1/a.tex); $(CP-DEP)
  • 复制目标名称作为附加规则。a.tex b.tex : ; cp -p $< $@. 容易出错。
  • 只是复制和粘贴。笨拙但有效且易于理解。
4

3 回答 3

2

I haven't tested it, but can't you just use a pattern rule without prerequisites, and specify the prerequisite for each target on a separate line?

a.tex: $(wildcard /foo/work1/a.tex)
b.tex: $(wildcard /foo/work2/b.tex)

%.tex:
    cp -p $< $@

Btw. doesn't the wildcard function return the empty string when it doesn't find a match, so that $< is empty as well? Wouldn't that give a problem with cp?

于 2011-10-28T23:41:46.737 回答
2

我认为你copyrule是矫枉过正(而且不灵活)。如果您对@eriktous 解决方案的反对意见是将规则应用于您尚未明确定义依赖关系的目标,那么使用静态模式规则很容易解决:

a.tex: $(wildcard /foo/work1/a.tex)
b.tex: $(wildcard /foo/work2/b.tex)
blue.tex: $(wildcard /some/other/path/green.tex)

TEXES = a.tex b.tex

$(TEXES): %.tex:
    cp -p $< $@

(如果这解决了您的问题,您应该接受 eriktous 的回答——这只是它的一个变体。)

于 2011-10-30T02:36:38.997 回答
1

我最终这样做了:

COPYFILES = /foo/work1/a.tex /foo/work2/b.tex

define copyrule
$(notdir $(1)): $$(wildcard $(1))
    cp -p $$< $$@
endef
$(foreach file,$(COPYFILES),$(eval $(call copyrule,$(file))))

这种方法的优点是我可以使用最少的样板文本轻松添加新文件,并且可以轻松地将其中的规则部分复制到新的 Makefile。缺点是我不能再更改目标文件名,而且对于 makefile 经验较少的人来说,实现相当不透明。

于 2011-10-30T00:17:28.423 回答