简体   繁体   中英

How to use GNU make to update files in all subdirectories containing a particular file?

In my project, I have a set of sub-directories that contain package.yaml files, for eg:

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

If I run hpack A/package.yaml , the file A/A.cabal is (re-)generated. The list of such directories can change over time, so I want to use GNU make to find all immediate sub-directories containing package.yaml files and generate the corresponding .cabal files using hpack.

I tried this based on another question , but it didn't work:

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 $<

However, make update-cabal says there's nothing to be done. make test however does output the right cabal files. How can I fix this?

Cheers!

The problem is this:

%.cabal: package.yaml

There is no file package.yaml . The files are named things like A/package.yaml . That is not the same thing.

Because the prerequisite doesn't exist, make decides that this pattern rule cannot match and so it goes looking for another rule that might be able to build the target. It doesn't find any rule that can build the target, so make says there's nothing to do because all the output files already exist.

Unfortunately what you want to do is not at all easy with make, because make is most comfortable with input and output files that are tied together by the filename with extensions, or similar. And in particular, it has a really hard time with relationships where the variable part is repeated more than once (as in, A/A.cabal where the A is repeated). There's no easy way to do that in make.

You'll have to use an advanced feature such as eval to do this. Something like:

# How to build a cabal file
%.cabal:
        hpack $<

# Declare the prerequisites
$(foreach D,$(dir $(HPACK_FILES)),$(eval $D/$D.cabal: $D/package.yml))

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM