【问题标题】:How to Loop Through a Text File in a Makefile (GNU)?如何循环通过 Makefile (GNU) 中的文本文件?
【发布时间】:2020-02-26 20:18:39
【问题描述】:

我在一个文本文件中有一个 ID 列表:pid.txt 以空格分隔。 我想为每个 ID 运行一个 python 程序。这基本上意味着我想运行以下命令:

python ./program.py id1
python ./program.py id2
python ./program.py id3
...

我正在创建一个 makefile 来做到这一点。 但我无法编写适当的代码。 我尝试了很多方法,例如:

target:
       $(foreach var,$(pid.txt),python ./program.py $(var);)

但是这些方法都不起作用。 另外,我想并行化这个。使用 -j。

【问题讨论】:

    标签: loops makefile gnu-make gnu


    【解决方案1】:

    我不会费心尝试使用 make 构造,只需调用一个简单的 shell 脚本。例如:

    target:
            for id in $$(cat pid.txt); do python ./program.py "$$id"; done
    

    根据所需的行为,您可能想要这样做:

    ...; do python ./program.py "$$id" || exit 1; done 在失败时中止。

    【讨论】:

    • 我也想使用 -j 进行并行处理。这个 for 循环会并行吗?
    • 你可以让它并行运行。如果您只执行do python ./program.py "$$id" & done,则检查退出值会稍微困难一些。如果你使用类似 gnu parallel 的东西,你会得到更多的控制。
    【解决方案2】:

    使用罐头食谱是可行的:

    ID-INPUT := $(file < pid.txt)
    
    define CREATE-PHONY-PYTHON =
    PHONY: $1
    $1:
            @echo calling Python with $1
            python ./program.py $1
    
    
    endef
    
    PHONY: all
    all: $(ID-INPUT)
    
    $(info $(foreach ID,$(ID-INPUT),$(call CREATE-PHONY-PYTHON,$(ID))))
    $(eval $(foreach ID,$(ID-INPUT),$(call CREATE-PHONY-PYTHON,$(ID))))
    

    $(info) 调用只是用于检查配方生成是否按预期工作 - 在生产时将其删除。并行化应该按预期工作,但我无法检查。 你可以看看the GNUmake table toolkit,了解make内部更复杂的配置处理。

    PS:我记得$(file &lt;) 函数仅适用于 GNUmake > 4.1

    【讨论】:

      【解决方案3】:

      使用static pattern rule

      # Use PIDS = $(shell cat pid.txt) on older versions of GNU make
      PIDS = $(file < pid.txt)
      
      # When a new pids are added, new files will be generated.
      all: pid.txt $(PIDS)
      
      # This way, you can build `make <pid>`
      # I believe, the files should be re-generated when and only when `program.py` changes
      $(PIDS): %: ./program.py
          python ./program.py "$*"
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多