【问题标题】:How to pattern-match multiple targets with their prerequisities?如何将多个目标与其先决条件进行模式匹配?
【发布时间】:2021-03-23 08:23:15
【问题描述】:

我从 makefile 开始,我对模式的工作原理有点困惑。我有多个不同的目标,每个目标都有一个名称匹配的先决条件。我想在顶部有一个变量存储目标和先决条件的所有“词干”,然后只为所有这些添加前缀/后缀和一个通用配方。到目前为止,我已经尝试过:

names = stem1 stem2 stem3

all: $(names:%=dir/prefix_%.txt) $(names:%=dir/another_%.txt)

$(names:%=dir/prefix_%.txt): $(names:%=sourcedir/yetanother_%.xlsx)
    echo $@
    echo prerequisite_with_the_same_stem_as_current_target

尽管这会一一生成所有目标,但每个目标的先决条件都会全部列出,而不仅仅是与目标的当前%(names) 匹配的先决条件。我需要它匹配的原因是因为我随后将当前目标及其单个先决条件提供给脚本,然后该脚本生成目标。如何将每个先决条件与其一个目标进行模式匹配?

【问题讨论】:

    标签: makefile gnu-make


    【解决方案1】:

    您对make 如何处理列表的误解。如果你有一个变量:

    names = stem1 stem2 stem3
    

    然后make 将其作为列表处理但每次命名此变量时都会一次实例化整个列表内容它不会对列表内容进行一对一的操作,因为这将接近于无法控制,具体取决于具体情况。相反,它采用简单的文本替换,因此您的行

    all: $(names:%=dir/prefix_%.txt) $(names:%=dir/another_%.txt)
    

    被非常简单地解析和变量替换成一个字符串:

    all: dir/prefix_stem1.txt dir/prefix_stem2.txt dir/prefix_stem3.txt ...etc...
    

    迭代列表处理只发生在$(names:%=dir/prefix_%.txt) 内,以此类推,而行本身,在变量替换之后,只是输入到第二个解析步骤的文本。

    按照你的规则:

    $(names:%=dir/prefix_%.txt): $(names:%=sourcedir/yetanother_%.xlsx)
    

    扩展到

    dir/prefix_stem1.txt dir/prefix_stem2.txt dir/prefix_stem3.txt: sourcedir/yetanother_stem1.xlsx sourcedir/yetanother_stem2.xlsx sourcedir/yetanother_stem3.xlsx
    

    这是三个规则的简写:

    dir/prefix_stem1.txt: sourcedir/yetanother_stem1.xlsx sourcedir/yetanother_stem2.xlsx sourcedir/yetanother_stem3.xlsx
    dir/prefix_stem2.txt: sourcedir/yetanother_stem1.xlsx sourcedir/yetanother_stem2.xlsx sourcedir/yetanother_stem3.xlsx
    dir/prefix_stem3.txt: sourcedir/yetanother_stem1.xlsx sourcedir/yetanother_stem2.xlsx sourcedir/yetanother_stem3.xlsx
    

    没有别的。显然你告诉 make 每个目标都依赖于所有的先决条件。

    稍作调整和Static Pattern Rules,您就可以实现您的目标:

    MY_TARGETS :=  $(names:%=dir/prefix_%.txt) # create full target names
    
    $(MY_TARGETS) : dir/prefix_%.txt : sourcedir/yetanother_%.xslx
    

    【讨论】:

    • 这行得通,非常感谢! make 中的常见格式是否有大写变量?
    • 嗯..我不知道。我从手册中选择了这种风格。再说一次,在我的库 gmtt 中,我做相反的事情,主要是希望将库名称与用户名分开。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-25
    • 2020-07-12
    • 2019-01-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多