1# SPDX-License-Identifier: BSD-2-Clause
2#
3#	$Id: subdir.mk,v 1.24 2024/04/10 01:47:23 sjg Exp $
4#
5#	@(#) Copyright (c) 2002-2024, Simon J. Gerraty
6#
7#	This file is provided in the hope that it will
8#	be of use.  There is absolutely NO WARRANTY.
9#	Permission to copy, redistribute or otherwise
10#	use this file is hereby granted provided that
11#	the above copyright notice and this notice are
12#	left intact.
13#
14#	Please send copies of changes and bug-fixes to:
15#	sjg@crufty.net
16
17#	if SUBDIR=@auto replace that with each subdir that has
18#	a [Mm]akefile.
19#
20#	Unless SUBDIR_MUST_EXIST is defined, missing subdirs
21#	are ignored (to allow for sparse checkout).
22#
23#	If you use _SUBDIRUSE for a target you may need to add it to
24#	SUBDIR_TARGETS.
25
26# should be set properly in sys.mk
27_this ?= ${.PARSEFILE:S,bsd.,,}
28
29.if !target(__${_this}__)
30__${_this}__: .NOTMAIN
31
32.if defined(SUBDIR)
33
34.if ${.MAKE.LEVEL} == 0 && ${MK_DIRDEPS_BUILD:Uno} == "yes"
35.include <meta.subdir.mk>
36# keep everyone happy
37_SUBDIRUSE:
38.elif !commands(_SUBDIRUSE) && !defined(NO_SUBDIR) && !defined(NOSUBDIR)
39.-include <local.subdir.mk>
40.if !target(.MAIN)
41.MAIN: all
42.endif
43
44ECHO_DIR ?= echo
45.ifdef SUBDIR_MUST_EXIST
46MISSING_DIR=echo "Missing ===> ${.CURDIR}/$$_dir"; exit 1
47.else
48MISSING_DIR=echo "Skipping ===> ${.CURDIR}/$$_dir"; exit 0
49.endif
50
51# the actual implementation
52# our target should be of the form ${_target}-${_dir}
53_SUBDIR_USE: .USE
54	@Exists() { test -f $$1; }; \
55	_dir=${.TARGET:C/^.*-//} \
56	_target=${.TARGET:C/-.*//:S/real//:S/.depend/depend/}; \
57	if ! Exists ${.CURDIR}/$$_dir/[mM]akefile; then \
58		${MISSING_DIR}; \
59	fi; \
60	if test X"${_THISDIR_}" = X""; then \
61		_nextdir_="$$_dir"; \
62	else \
63		_nextdir_="$${_THISDIR_}/$$_dir"; \
64	fi; \
65	${ECHO_DIR} "===> $${_nextdir_} ($$_target)"; \
66	(cd ${.CURDIR}/$$_dir && \
67		${.MAKE} _THISDIR_="$${_nextdir_}" $$_target)
68
69.if !target(install)
70.if !target(beforeinstall)
71beforeinstall:
72.endif
73.if !target(afterinstall)
74afterinstall:
75.endif
76install: maninstall
77maninstall: afterinstall
78afterinstall: realinstall
79realinstall: beforeinstall _SUBDIRUSE
80.endif
81
82# the interface from others
83# this may require additions to SUBDIR_TAREGTS
84_SUBDIRUSE: .USE subdir-${.TARGET:C/-.*//:S/real//:S/.depend/depend/}
85
86SUBDIR_TARGETS += \
87	all \
88	clean \
89	cleandir \
90	includes \
91	install \
92	depend \
93	lint \
94	obj \
95	tags \
96	etags
97
98.if ${SUBDIR} == "@auto"
99SUBDIR = ${echo ${.CURDIR}/*/[Mm]akefile:L:sh:H:T:O:N\*}
100.endif
101
102__subdirs =
103.for d in ${SUBDIR}
104.if $d != ".WAIT" && exists(${.CURDIR}/$d.${MACHINE})
105__subdirs += $d.${MACHINE}
106.else
107__subdirs += $d
108.endif
109.endfor
110
111.for t in ${SUBDIR_TARGETS:O:u}
112__subdir_$t =
113.for d in ${__subdirs}
114.if $d == ".WAIT"
115__subdir_$t += $d
116.elif !commands($t-$d)
117$t-$d: .PHONY .MAKE _SUBDIR_USE
118__subdir_$t += $t-$d
119.endif
120.endfor
121subdir-$t: .PHONY ${__subdir_$t}
122$t: subdir-$t
123.endfor
124
125.else
126_SUBDIRUSE:
127.endif				# SUBDIR
128
129.include <own.mk>
130.if make(destroy*)
131.include <obj.mk>
132.endif
133.endif
134# make sure this exists
135all:
136
137.endif
138