On Fri, Dec 31, 2021 at 7:44 AM Christian Ehrhardt <ehrha...@genua.de> wrote:
> Here at genua, trying to build libpcap sometimes breaks in > libpcap with the following error message: > > | Using $< in a non-suffix rule context is a GNUmake idiom \ > | (/data/git/ehrhardt/genuos/os/mk/bsd.dep.mk:47) > > The bug is in bsd.dep.mk where ${.IMPSRC} (aka $<) is used > in a context where it is not neccessarily defined by OpenBSD make. > > Below is a diff to Use ${.ALLSRC:M*.y} instead of ${.IMPSRC} as > the input file for yacc. > > The issue is with the rule for the grammar.h file that is generated > by yacc from grammar.c. You can easily reproduce the bug with the > following steps: > - build libpcap from scratch: cd .../src/lib/libpcap && make clean all > - remove the generated grammar.h file: rm obj*/grammar.h > - build libpcap again (incremental build): make > In normal builds this does not trigger as grammar.h is implicitly > generated by the rule for grammar.c and when make checks for > dependencies it simply finds grammar.h uptodate. However, > incremental or parallel builds might decide to make grammar.h > from grammar.y. > > Now, why is this only a problem for grammar.h but not for > grammar.c? The answer to this question is burried deeply in > OpenBSD's mk files. > > The snippet in bsd.dep.mk that triggers the error is a single > rule statement that generates foo.c and foo.h from foo.y with a > call to yacc -d. The rule is generated with a loop, i.e. it is not > a prefix rule. However, a prefix rule context is required for > the use of ${.IMPSRC} aka $<. For the .c file such a prefix > rule is provided by bsd.sys.mk and this rule is in scope when > make evaluates the yacc rule. However, for .h file generation > from a .y file there is no such prefix rule defined in any of > the Makefiles. Even if it were the .h suffix is missing from > .SUFFIXES and the rule would not be considered. > > NOTE: The obvious way to fix this would be to use $f instead of > ${.IMPSRC}. However, this does not work as $f is then missing > the path prefix and yacc won't find it if an obj directory is > used. This is probably the reason for the use of ${.IMPSRC} in > the first place. > Ah, nice analysis! The suggested fix looks safe to me (can't see how a .c could have two .y direct prerequisites, so this can't be ambiguous). ok guenther@