xref: /freebsd/share/mk/sys.dirdeps.mk (revision e2afbc45258f2fa4bdcf126e959ac660e76fc802)
1# $Id: sys.dirdeps.mk,v 1.16 2025/08/09 22:42:24 sjg Exp $
2#
3#	@(#) Copyright (c) 2012-2023, Simon J. Gerraty
4#
5#	SPDX-License-Identifier: BSD-2-Clause
6#
7#	Please send copies of changes and bug-fixes to:
8#	sjg@crufty.net
9#
10
11# Originally DIRDEPS_BUILD and META_MODE were the same thing.
12# So, much of this was done in *meta.sys.mk and local*mk
13# but properly belongs here.
14
15# Include from [local.]sys.mk - if doing DIRDEPS_BUILD
16# we should not be here otherwise
17MK_DIRDEPS_BUILD ?= yes
18# these are all implied
19MK_AUTO_OBJ ?= yes
20MK_META_MODE ?= yes
21MK_STAGING ?= yes
22
23_PARSEDIR ?= ${.PARSEDIR:tA}
24
25.-include <local.sys.dirdeps.env.mk>
26
27.if ${.MAKE.LEVEL} == 0
28# make sure dirdeps target exists and do it first
29# init.mk will set .MAIN to 'dirdeps' if appropriate
30# as will dirdeps-targets.mk for top-level builds.
31# This allows a Makefile to have more control.
32dirdeps:
33.NOPATH: dirdeps
34all: dirdeps .WAIT
35.endif
36
37.if empty(SRCTOP)
38# fallback assumes share/mk!
39SRCTOP := ${SB_SRC:U${.PARSEDIR:tA:H:H}}
40.export SRCTOP
41.endif
42
43# fake SB if not using mk wrapper
44# SB documented at http://www.crufty.net/sjg/docs/sb-tools.htm
45.if !defined(SB)
46SB := ${SRCTOP:H}
47.export SB
48.endif
49
50.if empty(OBJROOT)
51OBJROOT := ${SB_OBJROOT:U${MAKEOBJDIRPREFIX:U${SB}/obj}/}
52.export OBJROOT
53.endif
54# we expect OBJROOT to end with / (- can work too)
55.if ${OBJROOT:M*[/-]} == ""
56OBJROOT := ${OBJROOT}/
57.endif
58
59.if empty(STAGE_ROOT)
60STAGE_ROOT ?= ${OBJROOT}stage
61.export STAGE_ROOT
62.endif
63
64# We should be included before meta.sys.mk
65# If TARGET_SPEC_VARS is other than just MACHINE
66# it should be set by now.
67# TARGET_SPEC must not contain any '.'s.
68TARGET_SPEC_VARS ?= MACHINE
69
70.if ${TARGET_SPEC:Uno:M*,*} != ""
71# deal with TARGET_SPEC from env
72_tspec := ${TARGET_SPEC:S/,/ /g}
73.for i in ${TARGET_SPEC_VARS:${M_RANGE:Urange}}
74${TARGET_SPEC_VARS:[$i]} := ${_tspec:[$i]}
75.endfor
76# We need to stop that TARGET_SPEC affecting any submakes
77TARGET_SPEC=
78# so export but do not track
79.export-env TARGET_SPEC
80.export ${TARGET_SPEC_VARS}
81.for v in ${TARGET_SPEC_VARS:O:u}
82.if empty($v)
83.undef $v
84.endif
85.endfor
86.endif
87
88# Now make sure we know what TARGET_SPEC is
89# as we may need it to find Makefile.depend*
90.if ${MACHINE:Mhost*} != ""
91# host is special
92TARGET_SPEC = ${MACHINE}
93.else
94TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,}
95.endif
96
97.if ${TARGET_SPEC_VARS:[#]} > 1
98TARGET_SPEC_VARSr := ${TARGET_SPEC_VARS:[-1..1]}
99# alternatives might be
100# TARGET_OBJ_SPEC = ${TARGET_SPEC_VARSr:@v@${$v:U}@:ts/}
101# TARGET_OBJ_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts/}
102TARGET_OBJ_SPEC ?= ${TARGET_SPEC_VARS:@v@${$v:U}@:ts.}
103.else
104TARGET_OBJ_SPEC ?= ${MACHINE}
105.endif
106
107MAKE_PRINT_VAR_ON_ERROR += ${TARGET_SPEC_VARS}
108
109.if !defined(MACHINE0)
110# it can be handy to know which MACHINE kicked off the build
111# for example, if using Makefild.depend for multiple machines,
112# allowing only MACHINE0 to update can keep things simple.
113MACHINE0 := ${MACHINE}
114.export MACHINE0
115.endif
116
117MACHINE_OBJ.host = ${HOST_TARGET}
118MACHINE_OBJ.host32 = ${HOST_TARGET32}
119MACHINE_OBJ.${MACHINE} ?= ${TARGET_OBJ_SPEC}
120MACHINE_OBJDIR = ${MACHINE_OBJ.${MACHINE}}
121
122# we likely want to override env for OBJTOP
123.if ${MACHINE} == "host"
124OBJTOP = ${HOST_OBJTOP}
125.elif ${MACHINE} == "host32"
126OBJTOP = ${HOST_OBJTOP32}
127.else
128OBJTOP = ${OBJROOT}${MACHINE_OBJDIR}
129.endif
130.if ${.MAKE.LEVEL} > 0
131# should not change from level 1 onwards
132# this only matters for cases like bmake/unit-tests
133# where we do ${MAKE} -r
134.export OBJTOP
135.endif
136
137.if ${MAKEOBJDIR:U:M*/*} == ""
138# we do not use MAKEOBJDIRPREFIX
139# though we may have used it above to initialize OBJROOT
140.undef MAKEOBJDIRPREFIX
141# this is what we expected in env
142MAKEOBJDIR = $${.CURDIR:S,^$${SRCTOP},$${OBJTOP},}
143# export that but do not track
144.export-env MAKEOBJDIR
145# this what we need here
146MAKEOBJDIR = ${.CURDIR:S,${SRCTOP},${OBJTOP},}
147.endif
148
149STAGE_MACHINE ?= ${MACHINE_OBJDIR}
150STAGE_OBJTOP ?= ${STAGE_ROOT}/${STAGE_MACHINE}
151STAGE_COMMON_OBJTOP ?= ${STAGE_ROOT}/common
152STAGE_HOST_OBJTOP ?= ${STAGE_ROOT}/${HOST_TARGET}
153STAGE_HOST_OBJTOP32 ?= ${STAGE_ROOT}/${HOST_TARGET32}
154
155STAGE_INCLUDEDIR ?= ${STAGE_OBJTOP}${INCLUDEDIR:U/usr/include}
156STAGE_LIBDIR ?= ${STAGE_OBJTOP}${LIBDIR:U/lib}
157
158TIME_STAMP_FMT ?= @ %s [%Y-%m-%d %T] ${:U}
159DATE_TIME_STAMP ?= `date '+${TIME_STAMP_FMT}'`
160TIME_STAMP ?= ${TIME_STAMP_FMT:localtime}
161
162.if ${MK_TIME_STAMPS:Uyes} == "yes"
163TRACER = ${TIME_STAMP}
164ECHO_DIR = echo ${TIME_STAMP}
165ECHO_TRACE = echo ${TIME_STAMP}
166.endif
167
168.if ${.CURDIR} == ${SRCTOP}
169RELDIR= .
170RELTOP= .
171.elif ${.CURDIR:M${SRCTOP}/*}
172RELDIR:= ${.CURDIR:S,${SRCTOP}/,,}
173.else
174RELDIR:= ${.OBJDIR:S,${OBJTOP}/,,}
175.endif
176RELTOP?= ${RELDIR:C,[^/]+,..,g}
177RELOBJTOP?= ${RELTOP}
178RELSRCTOP?= ${RELTOP}
179
180# this does all the smarts of setting .MAKE.DEPENDFILE
181.-include <sys.dependfile.mk>
182
183.-include <local.sys.dirdeps.mk>
184
185# check if we got anything sane
186.if ${.MAKE.DEPENDFILE} == ".depend"
187.undef .MAKE.DEPENDFILE
188.endif
189# just in case
190.MAKE.DEPENDFILE ?= Makefile.depend
191
192# Makefile.depend* often refer to DEP_MACHINE etc,
193# we need defaults for both first include in a leaf dir
194# and when level > 0
195# so ensure DEP_* for TARGET_SPEC_VARS and RELDIR are set
196.for V in ${TARGET_SPEC_VARS} RELDIR
197DEP_$V ?= ${$V}
198.endfor
199