我正在使用GNUmake从源目录生成某些Web内容的部署版本。我希望成为通过压缩工具(例如YUI压缩器)运行某些文件的规则,然后对于没有规则的任何内容,只需复制它。
例如:
# Rule with all the $(WWW_OUT_DIR)/*.* files as a prerequisite
all: $(WWW_OUT_FILES)
# Generic rule to perform compression on Javascript files.
$(WWW_OUT_DIR)/%.js: $(WWW_SRC_DIR)/%.js
$(YUI_COMP) $(YUI_COMP_OPTS) $< > $@
# Generic rule to perform compression on CSS files.
$(WWW_OUT_DIR)/%.css: $(WWW_SRC_DIR)/%.css
$(YUI_COMP) $(YUI_COMP_OPTS) $< > $@
# TDB Rule to magically handle everything else? (This doesn't work)
$(WWW_OUT_DIR)/%.%: $(WWW_SRC_DIR)/%.%
cp $< $@
如何完成最后一条规则的目标?即对于$(WWW_OUT_FILES)中不是.js或.css的所有内容,只需复制它?如果可能,我想保留对相应输入文件的依赖。
答案 0 :(得分:7)
你几乎是对的,唯一要解决的是最后一个模式规则,只需删除多余的百分号:
$(WWW_OUT_DIR)/%: $(WWW_SRC_DIR)/%
cp $< $@
另请注意,自GNU Make 3.82模式搜索算法进行了一些修改(来自Changelog):
特定于模式的变量和模式规则现在应用于 最短的第一顺序而不是定义顺序(变量 具有相同茎长的规则仍然适用于定义 订购)。这产生了通常期望的行为,其中更具体 模式是首选。
如果您使用最新版本的Make,这正是您想要的。为了使您的Makefile与其他版本的GNU Make兼容(包括3.82之前的版本),必须在其他版本之后定义规则(如原始问题中所述)。
来自here的一个很好的例子:
在版本3.82之前,当gmake在模式搜索期间发现多个匹配时,它更喜欢先前在makefile中声明的模式而不是稍后声明的模式。从3.82开始,gmake反而更喜欢导致最短茎的模式。由于行话,这听起来有点令人困惑,但我认为这实际上会使gmake更好地坚持最不惊讶的原则。这是一个例子:
all: sub/foo.x
%.x:
@echo "Prefer first match (stem is $*)."
sub/%.x:
@echo "Prefer most specific match (stem is $*)."
比较gmake 3.81和3.82的输出:
gmake 3.81
Prefer first match (stem is sub/foo).
gmake 3.82
Prefer most specific match (stem is foo).
gmake 3.82更喜欢第二种模式,因为它比第一种模式更具体。请注意,与之前版本的gmake相比,这是一个重要的向后兼容性。