I have defined a list of files in a Makefile.
I need to copy those files, with their directory structure, to a new location.
I can't use cp --parent because the source files live in ../ (so .. will be a part of the dest path).
I've decided, then, to do one for loop that creates the dirs, then a second for loop that copies the files. The problem, however, is that I can't seem to call $(dir $$file) in the body of the for loop. I always get "./" as the result, rather than the actual dir name. If I do something like echo $(dir foo/bar), that works fine, but echo $(dir $$file) (when $$file is 'foo/bar') always returns './'.
I've tried other options like $(shell basename $$file), but that also doesn't work.
I've tried defining a function and calling it in the body of the for, but that, too, doesn't work.
Here's a quick example Makefile:
FILES := foo/faz \
bar/baz \
gah/gaz
all:
@for f in $(FILES); do \
echo $(dir $$f); \
done
I expect the output of this to be:
foo
bar
gah
but instead, I'm getting:
./
./
./
I'm open to other solutions if my method is not the best. At the end of the day, I need to be able to copy all the $(FILES) that exist in ../ (so ../foo/bar, for example) to a new dir called $(NEWDIR) (so newdir/foo/bar, for example).
This only needs to work under Linux.
f is a shell variable here. The make function dir is called on the string $f (which the shell then interprets as a variable expansion).
If you use a shell loop, you need to use the shell's constructs to extract the directory part:
@set -e; for f in $(FILES); do \
echo $$(dirname $$f); \
done
Don't forget set -e, so that if there's an error during the copy, the make rule will fail.
You can also use a foreach function in make to generate a bunch of cp commands. It makes the makefile harder to debug though.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With