Re: [BUG] undefined variable used in recipe before undefine directive

Alejandro Colomar <[email protected]> Thu, 11 Sep 2025 23:00:36 +0200
Newsgroups gmane.comp.gnu.make.bugs
Message-ID <gm3ljwyqii35dxsjs3ui5p7aboofssm7czv4zawaf5wcawekjq@ml5kbzscrbyl>
Hi Paul,

On Thu, Sep 11, 2025 at 08:59:42AM -0400, Paul Smith wrote:
> On Wed, 2025-09-10 at 23:38 +0200, Alejandro Colomar wrote:
> > The reason I want to be able to undefine the variable name is to not
> > need to come up with unique names in variables used within a recipe.
> > That's why I immediately undefine it; to be able to reuse the name,
> > making sure that old values are not used accidentally.
> 
> There are lots and lots of ways to do that.  You didn't really explain
> clearly the problem you're trying to solve

Okay, what I'm trying to solve is:

I have many rules in which I use grep(1), and I have different regex
files for each of the rules (for use with 'grep -f').  The regex files
are both a prerequisite (if I change the regex file I want to re-make
the targets), and part of the recipe (I need to pass the file name to
grep(1)).

I want to call the regex file $(regexf) everywhere, to make it more
readable.  Each file only defines one rule, and in each file, I'd define
a regexf variable for its rule.  All such makefiles are included from
a main one, so I need to undefine those "local" variables to make it
work.

> so I'll just give some
> possible options:
> 
> You can use target-specific variables:
> 
>     all: foo := foo
>     all: ; echo $(foo)

Hmmm, I forgot about them.  Yup; sounds like what I want.  Almost.
It seems to not work in the pre-requisites list:

	alx@debian:~/tmp/mk$ ls
	Makefile
	alx@debian:~/tmp/mk$ cat Makefile 
	all: foo := foo

	all: %: $(foo)
		echo $(foo)
	alx@debian:~/tmp/mk$ make --warn-undefined-variables 
	Makefile:3: warning: undefined variable 'foo'
	echo foo
	foo

Are target-specific variables only available in the recipe?
I guess I can workaround that in this way:

	alx@debian:~/tmp/mk$ cat Makefile 
	foo := foo
	all: foo := $(foo)

	all: %: $(foo)
		echo $(foo)

	undefine foo
	alx@debian:~/tmp/mk$ ls
	Makefile  foo
	alx@debian:~/tmp/mk$ make --warn-undefined-variables 
	echo foo
	foo

Although it feels ugly.
Why is it that it's not available in the list of pre-requisites?

> Or you can use constructed variable names (this is POSIX-complaint
> even):
> 
>     all_foo := foo
>     all: ; echo $($@_foo)

No, it's a name I want to be the same across all targets in a rule.
Target-specific variables seems the way to go.

> > And it may also improve performance.
> > 
> > Maybe we could have something like '.IMMEDIATRECIPEEXPANSION:'.
> 
> No, I do not think that's a good idea.  I don't really even see how it
> could work.
> 
> For one thing, if you used something like this then automatic variables
> would be useless, because they will always expand to either the empty
> value or, at best, the wrong value.  Also, target-specific variables
> cannot work.  Etc.

Hmmmm, makes sense.  For some reason I wasn't thinking of automatic
variables as something in the same world as usual variables, but of
course they are.


Thanks a lot!!  It was very useful, as always!  :-)


Have a lovely night!
Alex

-- 
<https://www.alejandro-colomar.es>
Use port 80 (that is, <...:80/>).
signature.asc (application/pgp-signature, 833 B)
-----BEGIN PGP SIGNATURE-----

iQIzBAABCgAdFiEES7Jt9u9GbmlWADAi64mZXMKQwqkFAmjDOG0ACgkQ64mZXMKQ
wqnXFBAAor/4xY3Bx35PSVxI4jqNyhnvRT9iZ4bFz5/stUYVWXMFqCs+ArddZxT7
C5G0/zYBu8/l02XeNu3521f2u5Yvo29x38nVdjnJ/lYgpy3I/wM4Mvr2C67WhFmW
F49+LKj8JCygxb0KTrWBgtI1yGI8qXUqH+HcPSpeG0VAoT+Ypp0qWFi4yOZO4PBb
MYijRF+Jlv2WVr7jy5pKIP4wNZ06ntjdIUx1VVT9vTufX/EHAUOeTGpZX0lr+0pX
ExNsS9a7+dpuEyYhxB0zwTHPhlTpdstCa+jsOCES8/IT7iS+TqyAFYjW4RlEFvv9
SFUjKuljTOL4MflorJSN2rRAKJdICZlia2jC+HmxhteEZS/0siFBF0fOvI1z++mC
+dJiUZ7DhFM5cfm/91im3klmPgwVSCbun1Cqk0Ok0LGHCr3jdPtvpd4CBXaj5ktu
CYdsFUIrvwB+ccvUsRDp2wfjw1iSqsy1hG7HQHyhwagJgoD9jJij5aUVtO0u9VVt
O9WrQV1eUvGCIGHg511O9VIlSs78seI7IJRxO3BExzi58vVZRGSv7FpQojVXKUrT
dpz1RmFrVTDRfebkRzvDyeG5rXUYQNmE3fJZR4wkwarp57hJeuemTaVJ84a56tSK
Bvk6UliZRAEyuvgeR+yyeB5Dg02FNrIBMc6SvTSLO/6deGaHEBc=
=RqJW
-----END PGP SIGNATURE-----