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