% and * together on the dependency line

I use strange rules like this a long time ago, but suddenly they break in a new environment.

Is there a reliable 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 

There is no problem with this code on other Mac computers, ubuntu machines, ubuntu virtual machines. I donโ€™t know all of my versions, but it looks like OK code.

On my mageia server in the same directory after cleaning.

 [ 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 % or * to the corresponding text "fixes" the problem, but, of course, does not create the desired generality.

+5
source share
2 answers

I'm not quite sure, but I think you want

 test.<name>.out 

of

 <name>/test.out 

(if it exists). If this is correct, you can do this by reverse engineering the name of the premise for each target on behalf of the target, for example

 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 

This is a bit of a gulp, admittedly.

So, if we pre-organize a demo version in which the prerequisites exist:

 $ ls -LR .: 1 a Makefile ./1: test.out ./a: test.out $ make cp -f 1/test.out test.1.out cp -fa/test.out test.a.out 
+1
source

You can do this using the secondary extension and the substitution function. Please note that this was never valid without this, so any code you saw should be considered broken.

 .SECONDEXPANSION: all: test.1.out test.%.out: $$(wildcard $$*/test*.out) @echo Prerequisites found: $^ 

Note the use of $* , not % to match the pattern (see automatic variables ) escaped with an extra $ , and all this will expand twice so that both sets of values โ€‹โ€‹expand.

They say that this whole layout does not look like that. You used $< , which matches only the first word of prerequisites, although if there is a wildcard, there can be many. Mike's answer will probably put you better at reorganizing your Makefile to be really reliable.

0
source

Source: https://habr.com/ru/post/1235648/


All Articles