xref: /freebsd/share/mk/src.sys.obj.mk (revision ca987d4641cdcd7f27e153db17c5bf064934faf5)
1# $FreeBSD$
2#
3# Early setup of MAKEOBJDIR
4#
5# Default format is: /usr/obj/usr/src/[${TARGET}.${TARGET_ARCH}/]bin/sh
6#  MAKEOBJDIRPREFIX is	/usr/obj
7#  OBJROOT is		/usr/obj/usr/src/
8#  OBJTOP is		/usr/obj/usr/src/[${TARGET}.${TARGET_ARCH}/]
9#  MAKEOBJDIR is	/usr/obj/usr/src/[${TARGET}.${TARGET_ARCH}/]bin/sh
10#
11#  MAKEOBJDIRPREFIX will override the default pattern above and internally
12#  set MAKEOBJDIR.  If OBJROOT is set then MAKEOBJDIRPREFIX is rooted inside
13#  of there.
14#
15#  If MK_UNIFIED_OBJDIR is no then OBJROOT will always match OBJTOP.
16#
17#  If .MAKE.LEVEL == 0 then the TARGET.TARGET_ARCH is potentially added on.
18#  If .MAKE.LEVEL >  0 and MAKEOBJDIRPREFIX is set then it will not get
19#  TARGET.TARGET_ARCH added in as it assumes that MAKEOBJDIRPREFIX is
20#  nested in the existing OBJTOP with TARGET.TARGET_ARCH in it.
21#
22
23_default_makeobjdirprefix?=	/usr/obj
24_default_makeobjdir=	$${.CURDIR:S,^$${SRCTOP},$${OBJTOP},}
25
26.include <bsd.mkopt.mk>
27
28.if ${.MAKE.LEVEL} == 0 || empty(OBJROOT)
29.if ${MK_UNIFIED_OBJDIR} == "no" && ${MK_DIRDEPS_BUILD} == "no"
30# Fall back to historical behavior.
31# We always want to set a default MAKEOBJDIRPREFIX...
32MAKEOBJDIRPREFIX?=	${_default_makeobjdirprefix}
33# but don't enforce TARGET.TARGET_ARCH unless we're at the top-level directory.
34.if ${.CURDIR} == ${SRCTOP} && \
35    !(defined(TARGET) && defined(TARGET_ARCH) && \
36    ${MACHINE} == ${TARGET} && ${MACHINE_ARCH} == ${TARGET_ARCH} && \
37    !defined(CROSS_BUILD_TESTING))
38MAKEOBJDIRPREFIX:=	${MAKEOBJDIRPREFIX}${TARGET:D/${TARGET}.${TARGET_ARCH}}
39.endif
40.endif	# ${MK_UNIFIED_OBJDIR} == "no"
41
42.if !empty(MAKEOBJDIRPREFIX)
43# put things approximately where they want
44OBJROOT:=	${MAKEOBJDIRPREFIX}${SRCTOP}/
45MAKEOBJDIRPREFIX=
46# export but do not track
47.export-env MAKEOBJDIRPREFIX
48.endif
49.if empty(MAKEOBJDIR)
50# OBJTOP set below
51MAKEOBJDIR=	${_default_makeobjdir}
52# export but do not track
53.export-env MAKEOBJDIR
54# Expand for our own use
55MAKEOBJDIR:=	${MAKEOBJDIR}
56.endif
57# SB documented at http://www.crufty.net/sjg/docs/sb-tools.htm
58.if !empty(SB)
59SB_OBJROOT?=	${SB}/obj/
60# this is what we use below
61OBJROOT?=	${SB_OBJROOT}
62.endif
63OBJROOT?=	${_default_makeobjdirprefix}${SRCTOP}/
64.if ${OBJROOT:M*/} != ""
65OBJROOT:=	${OBJROOT:H:tA}/
66.else
67OBJROOT:=	${OBJROOT:H:tA}/${OBJROOT:T}
68.endif
69# Must export since OBJDIR will dynamically be based on it
70.export OBJROOT SRCTOP
71.endif
72
73.if ${MK_DIRDEPS_BUILD} == "no"
74.if empty(OBJTOP)
75# SRCTOP == OBJROOT only happens with clever MAKEOBJDIRPREFIX=/.  Don't
76# append TARGET.TARGET_ARCH for that case since the user wants to build
77# in the source tree.
78.if ${MK_UNIFIED_OBJDIR} == "yes" && ${SRCTOP} != ${OBJROOT:tA}
79.if defined(TARGET) && defined(TARGET_ARCH)
80OBJTOP:=	${OBJROOT}${TARGET}.${TARGET_ARCH}
81.elif defined(TARGET) && ${.CURDIR} == ${SRCTOP}
82# Not enough information, just use basic OBJDIR.  This can happen with some
83# 'make universe' targets or if TARGET is not being used as expected.
84OBJTOP:=	${OBJROOT:H}
85.else
86OBJTOP:=	${OBJROOT}${MACHINE}.${MACHINE_ARCH}
87.endif
88.else
89# TARGET.TARGET_ARCH handled in OBJROOT already.
90OBJTOP:=	${OBJROOT:H}
91.endif	# ${MK_UNIFIED_OBJDIR} == "yes"
92.endif	# empty(OBJTOP)
93
94# Fixup OBJROOT/OBJTOP if using MAKEOBJDIRPREFIX.
95# This intenionally comes after adding TARGET.TARGET_ARCH so that is truncated
96# away for nested objdirs.  This logic also will not trigger if the OBJROOT
97# block above unsets MAKEOBJDIRPREFIX.
98.if !empty(MAKEOBJDIRPREFIX)
99OBJTOP:=	${MAKEOBJDIRPREFIX}${SRCTOP}
100OBJROOT:=	${OBJTOP}/
101.endif
102
103# Wait to validate MAKEOBJDIR until OBJTOP is set.
104.if defined(MAKEOBJDIR)
105.if ${MAKEOBJDIR:M/*} == ""
106.error Cannot use MAKEOBJDIR=${MAKEOBJDIR}${.newline}Unset MAKEOBJDIR to get default:  MAKEOBJDIR='${_default_makeobjdir}'
107.endif
108.endif
109
110# __objdir is the expected .OBJDIR we want to use and that auto.obj.mk will
111# try to create.
112.if !empty(MAKEOBJDIRPREFIX)
113.if ${.CURDIR:M${MAKEOBJDIRPREFIX}/*} != ""
114# we are already in obj tree!
115__objdir=	${.CURDIR}
116.else
117__objdir:=	${MAKEOBJDIRPREFIX}${.CURDIR}
118.endif
119.elif !empty(MAKEOBJDIR)
120__objdir:=	${MAKEOBJDIR}
121.endif
122
123# Try to enable MK_AUTO_OBJ by default if we can write to the __objdir.  Only
124# do this if AUTO_OBJ is not disabled by the user, and this is the first make
125# ran.
126.if ${.MAKE.LEVEL} == 0 && \
127    ${MK_AUTO_OBJ} == "no" && empty(.MAKEOVERRIDES:MMK_AUTO_OBJ) && \
128    !defined(WITHOUT_AUTO_OBJ) && !make(showconfig) && !make(print-dir) && \
129    !defined(NO_OBJ)
130# Find the last existing directory component and check if we can write to it.
131# If the last component is a symlink then recurse on the new path.
132CheckAutoObj= \
133DirIsCreatable() { \
134	[ -w "$${1}" ] && return 0; \
135	d="$${1}"; \
136	IFS=/; \
137	set -- $${d}; \
138	unset dir; \
139	while [ $$\# -gt 0 ]; do \
140		d="$${1}"; \
141		shift; \
142		if [ ! -d "$${dir}$${d}/" ]; then \
143			if [ -L "$${dir}$${d}" ]; then \
144				dir="$$(readlink "$${dir}$${d}")/"; \
145				for d in "$${@}"; do \
146					dir="$${dir}$${d}/"; \
147				done; \
148				ret=0; \
149				DirIsCreatable "$${dir%/}" || ret=$$?; \
150				return $${ret}; \
151			else \
152				break; \
153			fi; \
154		fi; \
155		dir="$${dir}$${d}/"; \
156	done; \
157	[ -w "$${dir}" ]; \
158}; \
159CheckAutoObj() { \
160	if DirIsCreatable "$${1}"; then \
161		echo yes; \
162	else \
163		echo no; \
164	fi; \
165}
166.if !empty(__objdir)
167.if ${.CURDIR} == ${__objdir}
168__objdir_writable?= yes
169.else
170__objdir_writable!= \
171	${CheckAutoObj}; CheckAutoObj "${__objdir}" || echo no
172.endif
173.endif
174__objdir_writable?= no
175# Export the decision to sub-makes.
176MK_AUTO_OBJ:=	${__objdir_writable}
177.export MK_AUTO_OBJ
178.elif make(showconfig)
179# Need to export for showconfig internally running make -dg1.  It is enabled
180# in sys.mk by default.
181.export MK_AUTO_OBJ
182.endif	# ${MK_AUTO_OBJ} == "no" && ...
183
184# Assign this directory as .OBJDIR if possible.
185#
186# The expected OBJDIR already exists, set it as .OBJDIR.
187.if !empty(__objdir) && exists(${__objdir})
188.OBJDIR: ${__objdir}
189# Special case to work around bmake bug.  If the top-level .OBJDIR does not yet
190# exist and MAKEOBJDIR is passed into environment and yield a blank value,
191# bmake will incorrectly set .OBJDIR=${SRCTOP}/ rather than the expected
192# ${SRCTOP} to match ${.CURDIR}.
193.elif ${MAKE_VERSION} <= 20170720 && \
194    ${.CURDIR} == ${SRCTOP} && ${.OBJDIR} == ${SRCTOP}/
195.OBJDIR: ${.CURDIR}
196.else
197# The OBJDIR we wanted does not yet exist, ensure we default to safe .CURDIR
198# in case make started with a bogus MAKEOBJDIR, that expanded before OBJTOP
199# was set, that happened to match some unexpected directory.  Either
200# auto.obj.mk or bsd.obj.mk will create the directory and fix .OBJDIR later.
201.OBJDIR: ${.CURDIR}
202.endif
203
204# Ensure .OBJDIR=.CURDIR cases have a proper OBJTOP and .OBJDIR
205.if defined(NO_OBJ) || ${__objdir_writable:Uunknown} == "no" || \
206    ${__objdir} == ${.CURDIR}
207OBJTOP=		${SRCTOP}
208OBJROOT=	${SRCTOP}/
209# Compare only to avoid an unneeded chdir(2), :tA purposely left out.
210.if ${.OBJDIR} != ${.CURDIR}
211.OBJDIR:	${.CURDIR}
212.endif
213.endif	# defined(NO_OBJ)
214
215.endif	# ${MK_DIRDEPS_BUILD} == "no"
216