[BACK]Return to bsd.dep.mk CVS log [TXT][DIR] Up to [local] / src / share / mk

File: [local] / src / share / mk / bsd.dep.mk (download)

Revision 1.25, Sat Jan 8 17:05:30 2022 UTC (2 years, 4 months ago) by patrick
Branch: MAIN
CVS Tags: OPENBSD_7_5_BASE, OPENBSD_7_5, OPENBSD_7_4_BASE, OPENBSD_7_4, OPENBSD_7_3_BASE, OPENBSD_7_3, OPENBSD_7_2_BASE, OPENBSD_7_2, OPENBSD_7_1_BASE, OPENBSD_7_1, HEAD
Changes since 1.24: +2 -2 lines

Use ${.ALLSRC:M*.y} instead of ${.IMPSRC} as the input file for yacc,
to fix a bug where ${.IMPSRC} (aka $<) is used in a context where it
is not neccessarily defined by OpenBSD make.  This would sometime show
up trying to build libpcap with the following error message:

Using $< in a non-suffix rule context is a GNUmake idiom (<bsd.dep.mk>:47)

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.

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.

Committing on behalf of ehrhardt@
"I like the diff" deraadt@
ok guenther@

#	$OpenBSD: bsd.dep.mk,v 1.25 2022/01/08 17:05:30 patrick Exp $
#	$NetBSD: bsd.dep.mk,v 1.12 1995/09/27 01:15:09 christos Exp $

.if !target(depend)
depend:
	@:
.endif

# relies on DEPS defined by bsd.lib.mk and bsd.prog.mk
.if defined(DEPS) && !empty(DEPS)
# catch22: don't include potentially bogus files we are going to clean
.  if !(make(clean) || make(cleandir) || make(obj))
.    for o in ${DEPS}
       sinclude $o
.    endfor
.  endif
.endif

CFLAGS += -MD -MP
CXXFLAGS += -MD -MP

# libraries need some special love
DFLAGS += -MD -MP -MT $*.o -MT $*.po -MT $*.so -MT $*.do

.if !target(tags)
.  if defined(SRCS)
tags: ${SRCS} _SUBDIRUSE
	-cd ${.CURDIR}; ${CTAGS} -f /dev/stdout -d ${.ALLSRC:N*.h} | \
	    sed "s;\${.CURDIR}/;;" > tags
.  else
tags:
.  endif
.endif

# explicitly tag most source files
.for i in ${SRCS:N*.[hyl]:N*.sh} ${_LEXINTM} ${_YACCINTM}
# assume libraries
${i:R:S/$/.o/} ${i:R:S/$/.po/} ${i:R:S/$/.so/} ${i:R:S/$/.do/}: $i
.endfor

# give us better rules for yacc

.if ${YFLAGS:M-d}
# loop may not trigger
.  for f in ${SRCS:M*.y}	
${f:.y=.c} ${f:.y=.h}: $f
	${YACC.y} -o ${f:.y=.c} ${.ALLSRC:M*.y}
.  endfor
CLEANFILES += ${SRCS:M*.y:.y=.h}
.endif

.if defined(SRCS)
cleandir: cleandepend
cleandepend:
	rm -f ${.CURDIR}/tags
.endif

CLEANFILES += ${DEPS}

BUILDFIRST ?=
BUILDAFTER ?=
.if !empty(BUILDAFTER)
.  for i in ${BUILDFIRST} ${_LEXINTM} ${_YACCINTM}
.    if !exists($i)
${BUILDAFTER}: $i
.    endif
.  endfor
.endif
.PHONY: cleandepend