循环遍历 make 文件中的文件

Loop through files in make file

现在我的 make 文件中包含以下内容,用于为当前目录中的文件创建符号 link:

MY_FILE := "$(SOME_PATH)/file.txt"

ln -s $(MY_FILE)

我想对 link 一堆文件(或 none)进行某种 glob 操作。

MY_FILES :=  "$(SOME_PATH)/*.txt"
for file in files:
   ln -s $(MY_FILE)     

任何人都可以指出正确的方向吗? 谢谢!

Make 从“先决条件”创建“目标”。在您的情况下,MY_FILES 拥有创建 (link) 目标的先决条件。单个文件的规则可能如下所示:

file.txt: $(SOME_PATH)/file.txt
    ln -s $<

你想要多个文件,在这种情况下我们可以使用这个模式规则:

%.txt: $(SOME_PATH)/%.txt
    ln -s $<

您现在可以使用 make 命令创建 link:

make file.txt
make otherfile.txt

最后,我们将研究 wildcard 函数以获取所有文件,以及函数 notdir 函数以从文件名中获取 link 名称。以下规则将打印所有文本文件,并取决于 SOME_PATH link 中的所有文件到当前工作目录:

MY_FILES := $(notdir $(wildcard $(SOME_PATH)/*.txt))
cat: $(MY_FILES)
    cat $^

%.txt: $(SOME_PATH)/%.txt
    ln -s $<

下面应该做你想做的:

MY_FILES := $(wildcard $(SOME_PATH)/*.txt)
LINKS    := $(notdir $(MY_FILES))

.PHONY: links clean-links
links: $(LINKS)

$(LINKS): %: $(SOME_PATH)/%
    ln -s $<

clean-links:
    rm -f $(LINKS)

解释:

  1. 制作函数。 wildcardnotdir是两个make functions。了解 make 函数(至少是最常用的)确实有助于编写漂亮、优雅和高效的 make 文件。当然,如果文件名中有空格或特殊字符,您会遇到一些问题,因为大多数 make 函数都将空格视为分隔符。但是如果你有这样的文件和目录名,你可能应该使用 make 以外的东西。

  2. 静态模式规则:

    $(LINKS): %: $(SOME_PATH)/%
    

    是一个static pattern rule。对于 $(LINKS) 中的每个单词 foo.txt,它实例化一个单独的 make 规则:

    foo.txt: $(SOME_PATH)/foo.txt
        ln -s $(SOME_PATH)/foo.txt
    

    如果您想编写紧凑和通用的 make 文件,了解如何使用模式规则(静态或非静态)是必不可少的。

  3. 自动变量。 $< 是制造 automatic variable。在食谱(规则的命令部分)中,它扩展为第一个列出的 pre-requisite。还有许多其他自动变量,它们非常方便编写通用规则。

  4. 虚假目标。 linksclean-linksphony targets 因为它们不对应于我们要创建或更新的真实文件。它们有点像 short-hands 的动作。 make links 创建所有丢失的链接,而 make clean-links 将它们全部删除。由于 make 无法猜测这些目标不是常规文件名,我们用 .PHONY 特殊目标告诉它。