xref: /freebsd/share/mk/src.sys.obj.mk (revision 70a8349311934f20fcb65e763b8ac80134446796)
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"
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_UNIFIED_OBJDIR} == "yes"
74OBJTOP:=	${OBJROOT}${TARGET:D${TARGET}.${TARGET_ARCH}:U${MACHINE}.${MACHINE_ARCH}}
75.else
76# TARGET.TARGET_ARCH handled in OBJROOT already.
77OBJTOP:=	${OBJROOT:H}
78.endif	# ${MK_UNIFIED_OBJDIR} == "yes"
79
80# Wait to validate MAKEOBJDIR until OBJTOP is set.
81.if defined(MAKEOBJDIR)
82.if ${MAKEOBJDIR:M/*} == ""
83.error Cannot use MAKEOBJDIR=${MAKEOBJDIR}${.newline}Unset MAKEOBJDIR to get default:  MAKEOBJDIR='${_default_makeobjdir}'
84.endif
85.endif
86
87# Fixup OBJROOT/OBJTOP if using MAKEOBJDIRPREFIX but leave it alone
88# for DIRDEPS_BUILD which really wants to know the absolute top at
89# all times.  This intenionally comes after adding TARGET.TARGET_ARCH
90# so that is truncated away for nested objdirs.  This logic also
91# will not trigger if the OBJROOT block above unsets MAKEOBJDIRPREFIX.
92.if !empty(MAKEOBJDIRPREFIX) && ${MK_DIRDEPS_BUILD} == "no"
93OBJTOP:=	${MAKEOBJDIRPREFIX}${SRCTOP}
94OBJROOT:=	${OBJTOP}/
95.endif
96
97# Try to enable MK_AUTO_OBJ by default if we can write to the OBJROOT.  Only
98# do this if AUTO_OBJ is not disabled by the user, not cleaning, and this
99# is the first make ran.
100.if 0 && ${.MAKE.LEVEL} == 0 && \
101    ${MK_AUTO_OBJ} == "no" && empty(.MAKEOVERRIDES:MMK_AUTO_OBJ) && \
102    !defined(WITHOUT_AUTO_OBJ) && !make(showconfig) && !make(print-dir) && \
103    !defined(NO_OBJ) && \
104    (${.TARGETS} == "" || ${.TARGETS:Nclean*:N*clean:Ndestroy*} != "")
105# Find the last existing directory component and check if we can write to it.
106# If the last component is a symlink then recurse on the new path.
107CheckAutoObj= \
108DirIsCreatable() { \
109	[ -w "$${1}" ] && return 0; \
110	d="$${1}"; \
111	IFS=/; \
112	set -- $${d}; \
113	unset dir; \
114	while [ $$\# -gt 0 ]; do \
115		d="$${1}"; \
116		shift; \
117		if [ ! -d "$${dir}$${d}/" ]; then \
118			if [ -L "$${dir}$${d}" ]; then \
119				dir="$$(readlink "$${dir}$${d}")/"; \
120				for d in "$${@}"; do \
121					dir="$${dir}$${d}/"; \
122				done; \
123				ret=0; \
124				DirIsCreatable "$${dir%/}" || ret=$$?; \
125				return $${ret}; \
126			else \
127				break; \
128			fi; \
129		fi; \
130		dir="$${dir}$${d}/"; \
131	done; \
132	[ -w "$${dir}" ]; \
133}; \
134CheckAutoObj() { \
135	if DirIsCreatable "$${1}"; then \
136		echo yes; \
137	else \
138		echo no; \
139	fi; \
140}
141.if !empty(MAKEOBJDIRPREFIX)
142WANTED_OBJDIR=	${MAKEOBJDIRPREFIX}${.CURDIR}
143.else
144WANTED_OBJDIR=	${MAKEOBJDIR}
145.endif
146OBJDIR_WRITABLE!= \
147	${CheckAutoObj}; CheckAutoObj "${WANTED_OBJDIR}" || echo no
148# Export the decision to sub-makes.
149MK_AUTO_OBJ:=	${OBJDIR_WRITABLE}
150.export MK_AUTO_OBJ
151.elif make(showconfig)
152# Need to export for showconfig internally running make -dg1.  It is enabled
153# in sys.mk by default.
154.export MK_AUTO_OBJ
155.endif	# ${MK_AUTO_OBJ} == "no" && ...
156
157# Assign this directory as .OBJDIR if possible after determining if AUTO_OBJ
158# can be enabled by default.
159.if ${MK_AUTO_OBJ} == "no"
160# The expected OBJDIR already exists, set it as .OBJDIR.
161.if !empty(MAKEOBJDIRPREFIX) && exists(${MAKEOBJDIRPREFIX}${.CURDIR})
162.OBJDIR: ${MAKEOBJDIRPREFIX}${.CURDIR}
163.elif exists(${MAKEOBJDIR})
164.OBJDIR: ${MAKEOBJDIR}
165# Special case to work around bmake bug.  If the top-level .OBJDIR does not yet
166# exist and MAKEOBJDIR is passed into environment and yield a blank value,
167# bmake will incorrectly set .OBJDIR=${SRCTOP}/ rather than the expected
168# ${SRCTOP} to match ${.CURDIR}.
169.elif ${MAKE_VERSION} <= 20170720 && \
170    ${.CURDIR} == ${SRCTOP} && ${.OBJDIR} == ${SRCTOP}/
171.OBJDIR: ${.CURDIR}
172.endif
173.endif	# ${MK_AUTO_OBJ} == "no"
174