GNU Make和模式规则

4
我将使用GNUmake从源目录生成一份Web内容的部署版本。我希望有规则可以通过压缩工具(如YUI compressor)运行某些文件,对于没有规则的任何内容,只需复制即可。
例如:
# 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的所有内容,只需复制它吗?如果可能,我想保留与相应输入文件的依赖关系。
1个回答

7

你几乎是正确的,唯一需要修复的是最后一个模式规则,只需删除冗余的百分号符号即可:

$(WWW_OUT_DIR)/%:   $(WWW_SRC_DIR)/%
    cp $< $@

请注意,从GNU Make 3.82开始,模式搜索算法已经进行了一些修改(来自更改日志):
特定于模式的变量和模式规则现在按最短词干优先顺序应用,而不是按定义顺序(具有相同词干长度的变量和规则仍按定义顺序应用)。这产生了通常所需的更具体模式优先的行为。
如果您使用最新版本的Make,则正好符合您的要求。为了使您的Makefile与其他GNU Make版本(包括早于3.82的版本)兼容,规则必须在其他规则之后定义(如原始问题中所示)。
更新: 这里提供了一个很好的例子:
在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 $*)."

Compare the output from gmake 3.81 and 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 prefers the second pattern because it is a more specific match than the first. Note that this is a significant backwards-incompatibility compared with previous versions of gmake!


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接