Using makefile wildcard command for file names with spaces

I have a makefile that I use to compress pictures:

src=$(wildcard Photos/*.jpg) $(wildcard Photos/*.JPG)
out=$(subst Photos,Compressed,$(src))

all : $(out)

clean:
    @rmdir -r Compressed

Compressed:
    @mkdir Compressed

Compressed/%.jpg: Photos/%.jpg Compressed
    @echo "Compressing $<"
    @convert "$<" -scale 20% "$@"

Compressed/%.JPG: Photos/%.JPG Compressed
    @echo "Compressing $<"
    @convert "$<" -scale 20% "$@"

However, when I have a picture with a space in its name, for example Piper PA-28-236 Dakota.JPG, I get this error:

make: *** No rule to make target `Compressed/Piper', needed by `all'.  Stop.

I think this is a problem in the wildcard command, but I'm not sure what to change to get it to work.

How do I modify my makefile to allow for spaces in file names?


Solution 1:

I asked on Stack Overflow and a user named perreal helped me to solve this, here is his answer.

Here is what I did to get it to work:

  1. Use src=$(shell ls Photos | sed 's/ /?/g;s/.*/Photos\/\0/') to fix the spaces problem in the wildcard command and get targets to work with spaces.

  2. This leaves a question mark in the resulting file, so use a call function to replace ? with a space in the final file: replace = echo $(1) | sed 's/?/ /g'. Call this with @convert "$<" -scale 20% "``$(call replace,$@)``" (I only used one backtick, but I don't know how to get it to display correctly).

So, here is my final Makefile:

src=$(shell ls Photos | sed 's/ /?/g;s/.*/Photos\/\0/')
out=$(subst Photos,Compressed,$(src))

replace = echo $(1) | sed 's/?/ /g'

all : $(out)

clean:
    @rmdir -r Compressed

Compressed:
    @mkdir Compressed

Compressed/%.jpg: Photos/%.jpg Compressed
    @echo "Compressing $<"
    @convert "$<" -scale 20% "`$(call replace,$@)`"

Compressed/%.JPG: Photos/%.JPG Compressed
    @echo "Compressing $<"
    @convert "$<" -scale 20% "`$(call replace,$@)`"