How to copy a directory in a Makefile?

Grumbel picture Grumbel · Jun 23, 2010 · Viewed 20.6k times · Source

I have a directory images/ that I want to copy to build/images/ from within a Makefile. The directory might contain multiple levels of subdirectories. What would be the most elegant way to do that? I want:

  • avoid a full directory copy on each make run (i.e. no cp -r)
  • guaranteed consistency (i.e. if a file changed in images/ it should be automatically updated in build/images/)
  • avoid to specify a rule for each image and each subdirectory in the Makefile
  • solve the issue within make, so no rsync or cp -u if possible

I am using GNU make, so GNU specific stuff is allowed.

Answer

liori picture liori · Jun 23, 2010

Well, I'd just use rsync. Any make script you will create with these constraints will just replicate its functionality, and most probably will be slower and may contain bugs. An example rule might look:

build/images:
    rsync -rupE images build/

.PHONY: build/images

(.PHONY to trigger the rule every time).

Maybe symlinks or hardlinks can be used instead?

build/images:
    ln -s ../images build/images

If you really want to avoid rsync and links, this piece re-implements them somehow (not tested, needs find, mkdir, and plain cp):

image_files:=$(shell find images -type f)
build/images/%: images/%
    mkdir -p $(@D)
    cp $< $@

build: $(patsubst %,build/%,$(image_files))