Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to copy a directory in a Makefile?

Tags:

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.

like image 237
Grumbel Avatar asked Jun 23 '10 10:06

Grumbel


People also ask

How do I copy a directory in Linux?

In order to copy a directory on Linux, you have to execute the “cp” command with the “-R” option for recursive and specify the source and destination directories to be copied.

Can Makefile target be a directory?

Yes, a Makefile can have a directory as target. Your problem could be that the cd doesn't do what you want: it does cd and the git clone is carried out in the original directory (the one you cd ed from, not the one you cd ed to). This is because for every command in the Makefile an extra shell is created.

What is cp in Makefile?

cp copies files (or, optionally, directories). The copy is completely independent of the original. You can either copy one file to another, or copy arbitrarily many files to a destination directory.

How do I copy and move a directory in Linux?

Use cp followed by the file you want to copy and the destination where you want it moved. That, of course, assumes that your file is in the same directory you're working out of. You can specify both. You also have the option of renaming your file while copying it.


1 Answers

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)) 
like image 173
liori Avatar answered Oct 11 '22 13:10

liori