I have been using strange rules like this for a long time, but suddenly they are breaking on a new environment.
Is there a robust way to do this?
all: test.1.out
test.%.out: %/test*.out
/bin/cp -f $< $@
On my box (ubuntu):
alishan:~/Dropbox/make_insanity> make --version
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE.
This program built for x86_64-pc-linux-gnu
alishan:~/Dropbox/make_insanity> make
/bin/cp -f 1/test.out test.1.out
No problem with this kind of code on other people's Macs, ubuntu machines, ubuntu virtual machines. Don't know all their make versions, but it seems like OK code.
On my mageia server in the same directory after clearing.
[dushoff@yushan make_insanity]$ make --version
GNU Make 3.82
Built for x86_64-mageia-linux-gnu
Copyright (C) 2010 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
[dushoff@yushan make_insanity]$ make
make: *** No rule to make target `test.1.out', needed by `all'. Stop.
[dushoff@yushan make_insanity]$
Changing either the %
or *
to appropriate text "fixes" the problem, but of course does not produce the desired generality.
I'm not absolutely sure but I think you want
test.<name>.out
to be made from
<name>/test.out
(if it exists). If that's right, you can do it robustly by reverse-engineering the name of the prerequisite for each target from the name of the target, e.g.
targs := test.1.out test.a.out
define src_of =
$(patsubst .%,%,$(suffix $(basename $(1))))/$(basename $(basename $(1)))$(suffix $(1))
endef
all: $(targs)
test.%.out: $(call src_of,test.%.out)
cp -f $< $@
clean:
rm -f *.*.out
It's a bit of a mouthful, admittedly.
So if we pre-arrange a demo where the prerequisites exist:
$ ls -LR
.:
1 a Makefile
./1:
test.out
./a:
test.out
$ make
cp -f 1/test.out test.1.out
cp -f a/test.out test.a.out
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