[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Get a target's prerequisites from an external script?

From: Paul Smith
Subject: Re: Get a target's prerequisites from an external script?
Date: Fri, 15 Jul 2022 17:07:51 -0400
User-agent: Evolution 3.44.3 (by

On Fri, 2022-07-15 at 20:25 +0100, Sean Hammond wrote:
>     requirements/%.txt: requirements/$(shell grep --color=never
> '^[[:blank:]]*-r\|^[[:blank:]]*-c' requirements/ | sed
> 's/^[[:blank:]]*\(-r\|-c\)[[:blank:]]*//')

Unless you're sure that the shell generates only one single filename
every time, it can't be correct to just prefix it with "requirements/"
like this, even if the shell function did work as you wanted.  That
would prepend "requirements/" only to the first word in the output:

  BAR = one two three
  FOO = foo/$(BAR)

gives "foo/one two three"; it doesn't give "foo/one foo/two foo/three".

> But it doesn't work:
>     grep: No such file or directory
> It seems that make didn't expand the % within the $(shell ...)
> command.

Correct.  See How make Reads a Makefile[1] from the documentation. 
Here you will see that the prerequisites section of a rule is expanded
(all variables and functions are resolved) as make reads in the
makefile, right after this line exists.  That happens long, long before
make uses this pattern rule to try to build the target, and discovers
what the value of the % pattern should be.

There are multiple ways to work around this.  One way is to use
secondary expansion[2], which would mean doing something like this:

  REQS = $(addprefix requirements/,$(shell grep ... requirements/$*.in | sed 


  requirements/%.txt: $$(REQS)

Note I just used a separate function for simplicity and readability:
you could inline the value as you did before but you have escape ALL
the "$" with "$$".

Also if you use a separate variable, ensure you use "=" above NOT ":=",
which would break everything.


reply via email to

[Prev in Thread] Current Thread [Next in Thread]