[gnu.utils.bug] Lack of a feature in GNU Make 3.48

cks@WHITE.TORONTO.EDU (Chris Siebenmann) (06/01/89)

 I have a list of sources in different directories, and a list of
objects to be generated (too many and too varied to use VPATH or
vpath), and want to write a pattern-matching rule or a static pattern
rule that will make these from one template.

 In order to do this, I need to write a template that picks the
source file out of a list of files; something like

	$(objs) : %.o : $(filter \%%.c,$(srcs))

(the reason we escape the first "%" is because we want to wind up with
 a target dependency that looks like "$(filter %foo.c,$(srcs))"; we
 need the '%' in order for filter to do wildcard pattern matching).

 However, this doesn't work. $(filter...) is evauluated when the rule
is read in. So, we make another attempt:

	$(objs) : %.o : $$(filter \%%.c,$$(srcs))

and we find out '\%' is not a recognized escape (although '\ ' is)
(and that foo%.c doesn't work very well as a pattern-matcher). Even
after chanting the magic incantation

	percent=%
	$(objs) : %.o : $$(filter $$(percent)%.c,$$(srcs))

we are out of luck because GNU Make doesn't try to re-substitute
variables when it evaluates the dependencies, and correctly complains

	*** No way to make target `$(finds $(percent)foo.c,$(srcs))'.  Stop.

 Now, there are a couple of possibilities here:
a. I'm a dunce, and am missing some obvious or inobvious way of doing this
b. I'm not a dunce but this shouldn't be possible to do, or is too
   much of a hack to try and add.
c. Gee, we guess you should be able to do that.

 I have made some patches to our local copy of GNU Make that try and
bandage this problem by checking right after '%' expansion in static
pattern rules for a leading '$' and trying a variable expansion again
if there is one. I rather suspect this is the wrong thing to do (it
feels too inelegant), but I'm not enough of a GNU Make hacker to know
what the right fix is.

 As an aside, filter is a horribly inefficient function to use for
this. findstr would be perfect, except that it returns the search
string, instead of the matching token in the searched string. One could
either write a find function that returned which number word was
found, or one that returned the matching word; I chose to do the
latter, and wrote a $(finds ..) function (the speedup is quite
notable).

---
cks@white.toronto.edu		   ...!{utgpu,utzoo,watmath}!utcsri!white!cks

cks@WHITE.TORONTO.EDU (Chris Siebenmann) (06/01/89)

 In my previous message, I wrote:
...
| 	$(objs) : %.o : $$(filter \%%.c,$$(srcs))
and
| 	$(objs) : %.o : $$(filter $$(percent)%.c,$$(srcs))

 Both need a '\ ' after 'filter' in order to be pseudo-correct;
otherwise the dependcy is split up into two "file names", '$$(filter'
and '....,$$(srcs))'.

---
	"I shall clasp my hands together and bow to the corners of the world."
			Number Ten Ox, "Bridge of Birds"
Chris Siebenmann		...!utgpu!{ncrcan,ontmoh!moore}!ziebmef!cks
cks@white.toronto.edu	     or ...!utgpu!{,csri!}cks

cks@white.toronto.edu (Chris Siebenmann) (06/02/89)

I wrote, forgetting the first rule of optimization ("measure!"):
|  As an aside, filter is a horribly inefficient function to use for
| this .... I wrote a $(finds ..) function (the speedup is quite
| notable).

 Wrong wrong wrong. The speedup is small on test cases, and nonpresent
on the real makefile. filter is quite fast enough.

-- 
	"I shall clasp my hands together and bow to the corners of the world."
			Number Ten Ox, "Bridge of Birds"
Chris Siebenmann		...!utgpu!{ncrcan,ontmoh!moore}!ziebmef!cks
cks@white.toronto.edu	     or ...!utgpu!{,csri!}cks