【问题标题】:How to use GNU make to update files in all subdirectories containing a particular file?如何使用 GNU make 更新包含特定文件的所有子目录中的文件?
【发布时间】:2020-08-03 23:40:27
【问题描述】:

在我的项目中,我有一组包含package.yaml 文件的子目录,例如:

A/package.yaml
B/package.yaml
C/package.yaml

如果我运行hpack A/package.yaml,文件A/A.cabal 将(重新)生成。这些目录的列表会随着时间而改变,所以我想使用 GNU make 来查找所有包含package.yaml 文件的直接子目录,并使用 hpack 生成相应的.cabal 文件。

我根据another question 尝试过这个,但没有奏效:

HPACK_FILES := $(wildcard */package.yaml)
PKG_DIRS := $(subst /,,$(dir $(HPACK_FILES)))
CABAL_FILES := $(addsuffix .cabal,$(join $(dir $(HPACK_FILES)),$(PKG_DIRS)))

test:
    @echo $(CABAL_FILES)

update-cabal: $(CABAL_FILES)

%.cabal: package.yaml
    hpack $<

但是,make update-cabal 表示无事可做。 make test 但是确实输出了正确的 cabal 文件。我该如何解决这个问题?

干杯!

【问题讨论】:

    标签: makefile gnu-make


    【解决方案1】:

    问题是这样的:

    %.cabal: package.yaml
    

    没有文件package.yaml。这些文件被命名为A/package.yaml。那不是一回事。

    因为先决条件不存在,make 决定这个模式规则不能匹配,所以它去寻找另一个可能能够构建目标的规则。它没有找到任何可以构建目标的规则,所以 make 说没有什么可做的,因为所有的输出文件都已经存在了。

    不幸的是,你想要做的事情对 make 来说一点也不简单,因为 make 最适合输入和输出文件,这些文件通过文件名和扩展名或类似的文件名绑定在一起。特别是,对于可变部分重复多次的关系(如A/A.cabal 重复A)的关系非常困难。在 make 中没有简单的方法来做到这一点。

    您必须使用诸如eval 之类的高级功能来执行此操作。比如:

    # How to build a cabal file
    %.cabal:
            hpack $<
    
    # Declare the prerequisites
    $(foreach D,$(dir $(HPACK_FILES)),$(eval $D/$D.cabal: $D/package.yml))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-01-05
      • 1970-01-01
      • 2020-09-04
      • 2011-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-08-10
      相关资源
      最近更新 更多