我有一个包含多个目标的makefile,这些目标是通过从工作目录外部复制文件生成的。
a.tex : $(wildcard /foo/work1/a.tex)
cp -p $< $@
b.tex : $(wildcard /foo/work2/b.tex)
cp -p $< $@
我使用$(wildcard)
,因为有时我在无法访问/foo
的系统上运行Make。
避免为每条规则重复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 $< $@
。容易出错。答案 0 :(得分:2)
我还没有对它进行过测试,但你不能只使用没有先决条件的模式规则,并在单独的一行上指定每个目标的先决条件吗?
a.tex: $(wildcard /foo/work1/a.tex)
b.tex: $(wildcard /foo/work2/b.tex)
%.tex:
cp -p $< $@
顺便说一下。当没有找到匹配项时,通配符函数不会返回空字符串,因此$<
也是空的吗?这不会给cp
带来问题吗?
答案 1 :(得分:2)
我认为你的copyrule
过度(并且不灵活)。如果您对@ eriktous解决方案的反对意见是它将规则应用于您尚未明确定义依赖关系的目标,那么使用static pattern rule很容易解决:
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的答案 - 这只是它的一个变种。)
答案 2 :(得分: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经验较少的人来说,实现是相当不透明的。