1109998Smarkm# SPDX-License-Identifier: BSD-2-Clause
2280304Sjkim#
3280304Sjkim# $Id: sys.dirdeps.mk,v 1.15 2024/04/18 17:18:31 sjg Exp $
4280304Sjkim#
5109998Smarkm#	@(#) Copyright (c) 2012-2023, Simon J. Gerraty
6109998Smarkm#
7109998Smarkm#	This file is provided in the hope that it will
8109998Smarkm#	be of use.  There is absolutely NO WARRANTY.
9109998Smarkm#	Permission to copy, redistribute or otherwise
10109998Smarkm#	use this file is hereby granted provided that
11109998Smarkm#	the above copyright notice and this notice are
12109998Smarkm#	left intact.
13109998Smarkm#
14280304Sjkim#	Please send copies of changes and bug-fixes to:
15109998Smarkm#	sjg@crufty.net
16109998Smarkm#
17109998Smarkm
18109998Smarkm# Originally DIRDEPS_BUILD and META_MODE were the same thing.
19109998Smarkm# So, much of this was done in *meta.sys.mk and local*mk
20109998Smarkm# but properly belongs here.
21109998Smarkm
22109998Smarkm# Include from [local.]sys.mk - if doing DIRDEPS_BUILD
23109998Smarkm# we should not be here otherwise
24109998SmarkmMK_DIRDEPS_BUILD ?= yes
25109998Smarkm# these are all implied
26109998SmarkmMK_AUTO_OBJ ?= yes
27109998SmarkmMK_META_MODE ?= yes
28109998SmarkmMK_STAGING ?= yes
29109998Smarkm
30109998Smarkm_PARSEDIR ?= ${.PARSEDIR:tA}
31109998Smarkm
32109998Smarkm.-include <local.sys.dirdeps.env.mk>
33109998Smarkm
34109998Smarkm.if ${.MAKE.LEVEL} == 0
35109998Smarkm# make sure dirdeps target exists and do it first
36109998Smarkm# init.mk will set .MAIN to 'dirdeps' if appropriate
37109998Smarkm# as will dirdeps-targets.mk for top-level builds.
38109998Smarkm# This allows a Makefile to have more control.
39109998Smarkmdirdeps:
40109998Smarkm.NOPATH: dirdeps
41109998Smarkmall: dirdeps .WAIT
42109998Smarkm.endif
43109998Smarkm
44109998Smarkm.if empty(SRCTOP)
45109998Smarkm# fallback assumes share/mk!
46109998SmarkmSRCTOP := ${SB_SRC:U${.PARSEDIR:tA:H:H}}
47109998Smarkm.export SRCTOP
48109998Smarkm.endif
49109998Smarkm
50109998Smarkm# fake SB if not using mk wrapper
51109998Smarkm# SB documented at http://www.crufty.net/sjg/docs/sb-tools.htm
52109998Smarkm.if !defined(SB)
53109998SmarkmSB := ${SRCTOP:H}
54109998Smarkm.export SB
55109998Smarkm.endif
56109998Smarkm
57109998Smarkm.if empty(OBJROOT)
58109998SmarkmOBJROOT := ${SB_OBJROOT:U${MAKEOBJDIRPREFIX:U${SB}/obj}/}
59109998Smarkm.export OBJROOT
60109998Smarkm.endif
61109998Smarkm# we expect OBJROOT to end with / (- can work too)
62109998Smarkm.if ${OBJROOT:M*[/-]} == ""
63109998SmarkmOBJROOT := ${OBJROOT}/
64109998Smarkm.endif
65109998Smarkm
66109998Smarkm.if empty(STAGE_ROOT)
67109998SmarkmSTAGE_ROOT ?= ${OBJROOT}stage
68109998Smarkm.export STAGE_ROOT
69280304Sjkim.endif
70280304Sjkim
71# We should be included before meta.sys.mk
72# If TARGET_SPEC_VARS is other than just MACHINE
73# it should be set by now.
74# TARGET_SPEC must not contain any '.'s.
75TARGET_SPEC_VARS ?= MACHINE
76
77.if ${TARGET_SPEC:Uno:M*,*} != ""
78# deal with TARGET_SPEC from env
79_tspec := ${TARGET_SPEC:S/,/ /g}
80.for i in ${TARGET_SPEC_VARS:${M_RANGE:Urange}}
81${TARGET_SPEC_VARS:[$i]} := ${_tspec:[$i]}
82.endfor
83# We need to stop that TARGET_SPEC affecting any submakes
84TARGET_SPEC=
85# so export but do not track
86.export-env TARGET_SPEC
87.export ${TARGET_SPEC_VARS}
88.for v in ${TARGET_SPEC_VARS:O:u}
89.if empty($v)
90.undef $v
91.endif
92.endfor
93.endif
94
95# Now make sure we know what TARGET_SPEC is
96# as we may need it to find Makefile.depend*
97.if ${MACHINE:Mhost*} != ""
98# host is special
99TARGET_SPEC = ${MACHINE}
100.else
101TARGET_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts,}
102.endif
103
104.if ${TARGET_SPEC_VARS:[#]} > 1
105TARGET_SPEC_VARSr := ${TARGET_SPEC_VARS:[-1..1]}
106# alternatives might be
107# TARGET_OBJ_SPEC = ${TARGET_SPEC_VARSr:@v@${$v:U}@:ts/}
108# TARGET_OBJ_SPEC = ${TARGET_SPEC_VARS:@v@${$v:U}@:ts/}
109TARGET_OBJ_SPEC ?= ${TARGET_SPEC_VARS:@v@${$v:U}@:ts.}
110.else
111TARGET_OBJ_SPEC ?= ${MACHINE}
112.endif
113
114MAKE_PRINT_VAR_ON_ERROR += ${TARGET_SPEC_VARS}
115
116.if !defined(MACHINE0)
117# it can be handy to know which MACHINE kicked off the build
118# for example, if using Makefild.depend for multiple machines,
119# allowing only MACHINE0 to update can keep things simple.
120MACHINE0 := ${MACHINE}
121.export MACHINE0
122.endif
123
124MACHINE_OBJ.host = ${HOST_TARGET}
125MACHINE_OBJ.host32 = ${HOST_TARGET32}
126MACHINE_OBJ.${MACHINE} ?= ${TARGET_OBJ_SPEC}
127MACHINE_OBJDIR = ${MACHINE_OBJ.${MACHINE}}
128
129# we likely want to override env for OBJTOP
130.if ${MACHINE} == "host"
131OBJTOP = ${HOST_OBJTOP}
132.elif ${MACHINE} == "host32"
133OBJTOP = ${HOST_OBJTOP32}
134.else
135OBJTOP = ${OBJROOT}${MACHINE_OBJDIR}
136.endif
137.if ${.MAKE.LEVEL} > 0
138# should not change from level 1 onwards
139# this only matters for cases like bmake/unit-tests
140# where we do ${MAKE} -r
141.export OBJTOP
142.endif
143
144.if ${MAKEOBJDIR:U:M*/*} == ""
145# we do not use MAKEOBJDIRPREFIX
146# though we may have used it above to initialize OBJROOT
147.undef MAKEOBJDIRPREFIX
148# this is what we expected in env
149MAKEOBJDIR = $${.CURDIR:S,^$${SRCTOP},$${OBJTOP},}
150# export that but do not track
151.export-env MAKEOBJDIR
152# this what we need here
153MAKEOBJDIR = ${.CURDIR:S,${SRCTOP},${OBJTOP},}
154.endif
155
156STAGE_MACHINE ?= ${MACHINE_OBJDIR}
157STAGE_OBJTOP ?= ${STAGE_ROOT}/${STAGE_MACHINE}
158STAGE_COMMON_OBJTOP ?= ${STAGE_ROOT}/common
159STAGE_HOST_OBJTOP ?= ${STAGE_ROOT}/${HOST_TARGET}
160STAGE_HOST_OBJTOP32 ?= ${STAGE_ROOT}/${HOST_TARGET32}
161
162STAGE_INCLUDEDIR ?= ${STAGE_OBJTOP}${INCLUDEDIR:U/usr/include}
163STAGE_LIBDIR ?= ${STAGE_OBJTOP}${LIBDIR:U/lib}
164
165TIME_STAMP_FMT ?= @ %s [%Y-%m-%d %T] ${:U}
166DATE_TIME_STAMP ?= `date '+${TIME_STAMP_FMT}'`
167TIME_STAMP ?= ${TIME_STAMP_FMT:localtime}
168
169.if ${MK_TIME_STAMPS:Uyes} == "yes"
170TRACER = ${TIME_STAMP}
171ECHO_DIR = echo ${TIME_STAMP}
172ECHO_TRACE = echo ${TIME_STAMP}
173.endif
174
175.if ${.CURDIR} == ${SRCTOP}
176RELDIR= .
177RELTOP= .
178.elif ${.CURDIR:M${SRCTOP}/*}
179RELDIR:= ${.CURDIR:S,${SRCTOP}/,,}
180.else
181RELDIR:= ${.OBJDIR:S,${OBJTOP}/,,}
182.endif
183RELTOP?= ${RELDIR:C,[^/]+,..,g}
184RELOBJTOP?= ${RELTOP}
185RELSRCTOP?= ${RELTOP}
186
187# this does all the smarts of setting .MAKE.DEPENDFILE
188.-include <sys.dependfile.mk>
189
190.-include <local.sys.dirdeps.mk>
191
192# check if we got anything sane
193.if ${.MAKE.DEPENDFILE} == ".depend"
194.undef .MAKE.DEPENDFILE
195.endif
196# just in case
197.MAKE.DEPENDFILE ?= Makefile.depend
198
199# Makefile.depend* often refer to DEP_MACHINE etc,
200# we need defaults for both first include in a leaf dir
201# and when level > 0
202# so ensure DEP_* for TARGET_SPEC_VARS and RELDIR are set
203.for V in ${TARGET_SPEC_VARS} RELDIR
204DEP_$V ?= ${$V}
205.endfor
206