Notes |
|
(0001219)
|
zs
|
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. |
|
|
(0001220)
|
wangp
|
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. |
|
|
(0001221)
|
zs
|
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. |
|
|
(0001222)
|
wangp
|
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 $@ |
|
|
(0001223)
|
zs
|
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. |
|
|
(0001224)
|
wangp
|
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. |
|
|
(0001225)
|
wangp
|
2023-10-16 17:01
|
|
|