Scheintod
Scheintod

Reputation: 8115

gnu make recreating directory structure in target

I'd like to use GNUmake to do image compression and some preparations for my websites.

I have a structure like

src
    www.site1.org
        images
            foo.jpg
            bar.png
        css
            style.scss
    www.site2.org
        images
            baz.svg
        css
            design.scss

I want be able to recreate this structure in target directory while using some other tools to optimize/compile the sources like e.g. convert --strip src/www.site1.org/images/foo.jpg target/www.site1.org/images/foo.jpg

I can find all my jpegs using something like SRC:=$(shell find . -name '*.jpg') and even create a variable holding all the targets with TARGETS=$(SRC:src=target).

But now I don't find a way of writing a rule for which would (naively) look like:

$(TARGET): $(SRC)
    convert --strip $< $@

I've searched the internet for quiet some time now but didn't find anything appropriate.

Upvotes: 1

Views: 50

Answers (1)

Renaud Pacalet
Renaud Pacalet

Reputation: 29177

You could use:

SRC     := $(shell find src -name '*.jpg')
TARGETS = $(patsubst src/%,target/%,$(SRC))

all: $(TARGETS)

$(TARGETS): target/%: src/%
    convert --strip $< $@

which basically says: for each word in TARGETS, match it against the target/% pattern (and record the % sub-expression), consider that its single dependency is src/% and apply the recipe. This is a GNU make feature, documented in section 4.12 Static Pattern Rules of the manual.

By the way, $(SRC:src=target) does not do what you think because the pattern matches only at the end of each word of $(SRC). So, foo_src would be substituted with foo_target but src/foo would be left unmodified. patsubst is a more powerful substitution function.

Upvotes: 1

Related Questions