View Issue Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||||
ID | Project | Category | View Status | Date Submitted | Last Update | ||||
---|---|---|---|---|---|---|---|---|---|
0000566 | mercury | Bug | public | 2023-10-12 12:40 | 2023-10-16 17:01 | ||||
Reporter | wangp | ||||||||
Assigned To | wangp | ||||||||
Priority | normal | Severity | minor | Reproducibility | always | ||||
Status | resolved | Resolution | fixed | ||||||
Product Version | |||||||||
Target Version | Fixed in Version | ||||||||
Summary | 0000566: undefined variable warnings with GNU Make 4.4.0.90 | ||||||||
Description | Since GNU Make 4.4.0.90, we get warnings about undefined variables '*' and '@': /tmp/mmake.RTEA5X:64: warning: undefined variable '*' /tmp/mmake.RTEA5X:64: warning: undefined variable '@' /tmp/mmake.RTEA5X:64: warning: undefined variable '@' The problem first appears with GNU Make commit 15dfad96d77c9445d11be939a5042675e4ca8c65 "[SV 63439, SV 63452] Don't warn on undefined internal variables" https://git.savannah.gnu.org/cgit/make.git/commit/?id=15dfad96d77c9445d11be939a5042675e4ca8c65 The code that ultimately triggers these warnings is in Mmake.vars.in, from lines 374 onwards, that says: # `TARGET_<prog>FLAGS' is used to pass different flags to <prog> for # different targets. By setting MCFLAGS-foo, for example, you can add # extra values to TARGET_MCFLAGS that will used only for compiling foo.m. # # For each program <prog>, `TARGET_<prog>FLAGS' expands to # `$(<prog>FLAGS-$@)' and/or `$(<prog>FLAGS-$*)'. # $@ and $* are the builtin variables that expand to the # current target and (for pattern rules) the base name of the current target, # respectively. So $* is used for flags variables used by pattern rules, # whereas $@ is used for flags variables used by hard-coded rules, # including the ones in the generated .dep files. # # The code below uses some tricky GNU Make hacks to avoid expanding # <prog>FLAGS-$* and <prog>FLAGS-$@ if these vars are not defined, # so that we can avoid spurious warnings if the warning about # undefined variables is enabled. | ||||||||
Tags | No tags attached. | ||||||||
Attached Files |
|
Notes | |
zs (developer) 2023-10-12 12:55 |
Are you saying that the variable references that trigger bug are the ones in the *comment* you quoted? That would seem to be a serious issue in gnu make. Has this been reported to its maintainers? For us, there is an obvious workaround: put something between the $ and the @ or *, with a comment saying *why* that something is there. |
wangp (developer) 2023-10-12 13:09 |
Sorry, not in the comment, but in the code that the comment is describing: TARGET_GRADEFLAGS = \ $(maybe-base-GRADEFLAGS-$(findstring undefined,\ $(origin GRADEFLAGS-$(patsubst %_init,%,$*)))) \ $(maybe-target-GRADEFLAGS-$(findstring undefined,\ $(origin GRADEFLAGS-$(patsubst $(cs_subdir)%_init.c,%,$@)))) maybe-base-GRADEFLAGS- = $(GRADEFLAGS-$(patsubst %_init,%,$*)) maybe-base-GRADEFLAGS-undefined = maybe-target-GRADEFLAGS- = $(GRADEFLAGS-$(patsubst $(cs_subdir)%_init.c,%,$@)) maybe-target-GRADEFLAGS-undefined = etc. It could well be a bug in GNU Make. Before reporting I'd like to understand the issue properly, and construct a smaller test case. |
zs (developer) 2023-10-12 13:26 |
If you get the error for the occurrences of $* and $@ in those variable definitions, then those occurrences are being expanded at variable-definition-time. Both $* and $@ are defined with respect to a make rule, and there is no rule here. Their evaluation should be delayed until the variable being defined is actually used in a rule. If it is evaluated at any time before then, then $* and $@ are unusable in variable definitions, which I would classify as a serious regression. |
wangp (developer) 2023-10-12 15:46 |
The warnings about $@ and $* being undefined are occurring when VPATH is being evaluated, outside of any rule. The chain of references goes VPATH -> MMAKE_VPATH -> UNIX_MERCURY_EXTRA_INIT_DIRS -> MERCURY_EXTRA_INIT_DIRS -> EXTRA_INIT_DIRS -> GRADESTRING -> ALL_GRADEFLAGS -> USUAL_GRADEFLAGS -> TARGET_GRADEFLAGS -> $* and $@ |
zs (developer) 2023-10-12 16:02 |
In what context is VPATH being evaluated? The condition of of a ifeq/ifneq line? The search for a file? Because in both cases, I can see why the new warning from make would be justified. I can understand why VPATH depends on the grade; I don't see why it should depend on a grade modified by *module-specific* flags, as opposed to *program-specific* flags. |
wangp (developer) 2023-10-12 17:46 |
VPATH is evaluated once before considering any target, and this value of VPATH is used to find prerequisites of all targets (from what I gather). Here is a makefile for demonstration: VPATH = srcs.$@ \ $(shell echo Evaluating VPATH now for target [$@] >&2 ) # Put foo.c in srcs.foo foo: foo.c @echo VPATH in recipe is $(VPATH) # Put bar.c in current dir bar: bar.c @echo VPATH in recipe is $(VPATH) This is the log for `make --warn-undefined-variables -d -r foo`. foo.c cannot be found because VPATH is set to "srcs.", and *not* "srcs.foo". GNU Make 4.4.1 Built for x86_64-unknown-linux-gnu Copyright (C) 1988-2023 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <https://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. Reading makefiles... Reading makefile 'Makefile'... Makefile:1: warning: undefined variable '@' Makefile:1: warning: undefined variable '@' Evaluating VPATH now for target [] Updating makefiles.... Considering target file 'Makefile'. Looking for an implicit rule for 'Makefile'. No implicit rule found for 'Makefile'. Finished prerequisites of target file 'Makefile'. No need to remake target 'Makefile'. Updating goal targets.... Considering target file 'foo'. Considering target file 'foo.c'. File 'foo.c' does not exist. Looking for an implicit rule for 'foo.c'. No implicit rule found for 'foo.c'. Finished prerequisites of target file 'foo.c'. Must remake target 'foo.c'. make: *** No rule to make target 'foo.c', needed by 'foo'. Stop. This is the log for `make --warn-undefined-variables -d -r bar`. bar.c exists in the current directory so it is found. VPATH is evaluated again only when executing the recipe, now with $@ set to the target. GNU Make 4.4.1 Built for x86_64-unknown-linux-gnu Copyright (C) 1988-2023 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <https://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. Reading makefiles... Reading makefile 'Makefile'... Makefile:1: warning: undefined variable '@' Makefile:1: warning: undefined variable '@' Evaluating VPATH now for target [] Updating makefiles.... Considering target file 'Makefile'. Looking for an implicit rule for 'Makefile'. No implicit rule found for 'Makefile'. Finished prerequisites of target file 'Makefile'. No need to remake target 'Makefile'. Updating goal targets.... Considering target file 'bar'. File 'bar' does not exist. Considering target file 'bar.c'. Looking for an implicit rule for 'bar.c'. No implicit rule found for 'bar.c'. Finished prerequisites of target file 'bar.c'. No need to remake target 'bar.c'. Finished prerequisites of target file 'bar'. Must remake target 'bar'. Evaluating VPATH now for target [bar] Makefile:10: update target 'bar' due to: target does not exist echo VPATH in recipe is srcs.bar Putting child 0x557e7dcb1010 (bar) PID 18703 on the chain. Live child 0x557e7dcb1010 (bar) PID 18703 VPATH in recipe is srcs.bar Reaping winning child 0x557e7dcb1010 PID 18703 Removing child 0x557e7dcb1010 PID 18703 from chain. Successfully remade target file 'bar'. Directory srcs. cache invalidated (count 2 != command 4) So what mmake tries to do with VPATH (i.e. trying to take into account target-specific flags to change where to look for prerequisites) probably never actually worked. |
wangp (developer) 2023-10-16 17:01 |
Fix committed 2023-10-16 |
Issue History | |||
Date Modified | Username | Field | Change |
---|---|---|---|
2023-10-12 12:40 | wangp | New Issue | |
2023-10-12 12:43 | wangp | Summary | undefined variable warnings with GNU Make 4.4 => undefined variable warnings with GNU Make 4.4.0.90 |
2023-10-12 12:55 | zs | Note Added: 0001219 | |
2023-10-12 13:09 | wangp | Note Added: 0001220 | |
2023-10-12 13:26 | zs | Note Added: 0001221 | |
2023-10-12 15:46 | wangp | Note Added: 0001222 | |
2023-10-12 16:02 | zs | Note Added: 0001223 | |
2023-10-12 17:46 | wangp | Note Added: 0001224 | |
2023-10-16 17:01 | wangp | Assigned To | => wangp |
2023-10-16 17:01 | wangp | Status | new => resolved |
2023-10-16 17:01 | wangp | Resolution | open => fixed |
2023-10-16 17:01 | wangp | Note Added: 0001225 |