* Use a more robust method of creating the top level object directory.

Use getmakevar to expand MAKEOBJDIRPREFIX or MAKEOBJDIR, or (if
  neither of those variables is set) use a non-recursive "make obj" in
  the top level source directory.

* Do not let TOP_objdir default to ${TOP}.  It's now set only by the
  -M or -O command line options, or after using getmakevar to expand
  MAKEOBJDIRPREFIX or MAKEOBJDIR.

* Make try_set_TOOLDIR handle MAKEOBJDIRPERFIX passed from the
  environment.  It runs too early to use getmakevar, so it will not work
  if the value contains embedded '${...}' variable references.

* Use '$TOOLDIR' (with a literal '$') instead of 'nonexistent' in
  a message when rebuilding make when TOOLDIR is not yet known.
This commit is contained in:
apb 2009-09-27 18:08:24 +00:00
parent a95848c094
commit 828252228e
3 changed files with 155 additions and 90 deletions

View File

@ -117,14 +117,19 @@ CONFIGURATION
usefully be set inside a Makefile, including mk.conf or
${MAKECONF}.
MAKEOBJDIRPREFIX Top level directory of the object directory tree. If
specified, must be an absolute path. If this is
defined, ${MAKEOBJDIRPREFIX}/${.CURDIR} is used as the
.OBJDIR for the current directory. The current direc-
tory may be read only. MAKEOBJDIRPREFIX can be pro-
vided only in the environment or via the -M flag of
build.sh; it cannot usefully be set inside a Makefile,
including mk.conf or ${MAKECONF}.
MAKEOBJDIRPREFIX Top level directory of the object directory tree. The
value is subjected to variable expansion by make(1).
build.sh will create the ${MAKEOBJDIRPREFIX} directory
if necessary, but if make(1) is used without build.sh,
then rules in <bsd.obj.mk> will abort the build if the
${MAKEOBJDIRPREFIX} directory does not exist. If the
value is defined and valid, then ${MAKEOBJDIRPRE-
FIX}/${.CURDIR} is used as the .OBJDIR for the current
directory. The current directory may be read only.
MAKEOBJDIRPREFIX can be provided only in the environ-
ment or via the -M flag of build.sh; it cannot usefully
be set inside a Makefile, including mk.conf or
${MAKECONF}.
"make" variables
Several variables control the behavior of NetBSD builds. Unless other-
@ -754,14 +759,22 @@ BUILDING
ber of CPUs) and (2 * the number of CPUs) are recommended. Use
lower values on machines with limited memory or I/O bandwidth.
-M obj Set MAKEOBJDIRPREFIX to obj. For instance, if the source
directory is /usr/src, a setting of ``-M /usr/obj'' will place
build-time files under /usr/obj/usr/src/bin,
/usr/obj/usr/src/lib, /usr/obj/usr/src/usr.bin, and so forth.
If a relative path is specified, it will be converted to an
absolute path before being used. Unsets MAKEOBJDIR. See ``-O
-M obj Set MAKEOBJDIRPREFIX to obj. Unsets MAKEOBJDIR. See ``-O
-obj'' for more information.
For instance, if the source directory is /usr/src, a setting of
``-M /usr/obj'' will place build-time files under
/usr/obj/usr/src/bin, /usr/obj/usr/src/lib,
/usr/obj/usr/src/usr.bin, and so forth.
If a relative path is specified, it will be converted to an
absolute path before being used. build.sh imposes the restric-
tion that the argument to the -M option must not begin with a
``$'' (dollar sign) character; otherwise it would be too diffi-
cult to determine whether the value is an absolute or a rela-
tive path. If the directory does not already exist, build.sh
will create it.
-m mach Set the value of MACHINE to mach, except in some special cases
listed below. This will also override any value of
MACHINE_ARCH in the process environment with a value deduced
@ -796,11 +809,18 @@ BUILDING
-n''.
-O obj Create an appropriate transform macro for MAKEOBJDIR that will
place the built object files under obj. For instance, a set-
ting of ``-O /usr/obj'' will place build-time files under
/usr/obj/bin, /usr/obj/lib, /usr/obj/usr.bin, and so forth. If
a relative path is specified, it will be converted to an abso-
lute path before being used. Unsets MAKEOBJDIRPREFIX.
place the built object files under obj. Unsets
MAKEOBJDIRPREFIX.
For instance, a setting of ``-O /usr/obj'' will place build-
time files under /usr/obj/bin, /usr/obj/lib, /usr/obj/usr.bin,
and so forth.
If a relative path is specified, it will be converted to an
absolute path before being used. build.sh imposes the restric-
tion that the argument to the -O option must not contain a
``$'' (dollar sign) character. If the directory does not
already exist, build.sh will create it.
In normal use, exactly one of the -M or -O options should be
specified. If neither -M nor -O is specified, then a default

129
build.sh
View File

@ -1,5 +1,5 @@
#! /usr/bin/env sh
# $NetBSD: build.sh,v 1.211 2009/09/27 17:55:53 apb Exp $
# $NetBSD: build.sh,v 1.212 2009/09/27 18:08:24 apb Exp $
#
# Copyright (c) 2001-2009 The NetBSD Foundation, Inc.
# All rights reserved.
@ -255,19 +255,6 @@ initdefaults()
#
setmakeenv NETBSDSRCDIR "${TOP}"
# Determine top-level obj directory.
# Defaults to the top-level source directory.
# If $MAKEOBJDIRPREFIX is set in the environment, use it.
# We can't check $MAKEOBJDIR since that may be a make(1)
# expression that we can't evaluate at this time.
#
TOP_objdir="${TOP}"
if [ -n "${MAKEOBJDIRPREFIX}" ]; then
TOP_objdir="${MAKEOBJDIRPREFIX}${TOP}"
elif [ -n "${MAKEOBJDIR}" ]; then
warning "Can't parse \$(MAKEOBJDIR) \"$MAKEOBJDIR\" to determine top objdir"
fi
# Find the version of NetBSD
#
DISTRIBVER="$(${HOST_SH} ${TOP}/sys/conf/osrelease.sh)"
@ -696,7 +683,16 @@ parseoptions()
-M)
eval ${optargcmd}; resolvepath OPTARG
TOP_objdir="${OPTARG}${TOP}"
case "${OPTARG}" in
\$*) usage "-M argument must not begin with '$'"
;;
*\$*) # can use resolvepath, but can't set TOP_objdir
resolvepath OPTARG
;;
*) resolvepath OPTARG
TOP_objdir="${OPTARG}${TOP}"
;;
esac
unsetmakeenv MAKEOBJDIR
setmakeenv MAKEOBJDIRPREFIX "${OPTARG}"
;;
@ -725,8 +721,14 @@ parseoptions()
;;
-O)
eval ${optargcmd}; resolvepath OPTARG
TOP_objdir="${OPTARG}"
eval ${optargcmd}
case "${OPTARG}" in
*\$*) usage "-O argument must not contain '$'"
;;
*) resolvepath OPTARG
TOP_objdir="${OPTARG}"
;;
esac
unsetmakeenv MAKEOBJDIRPREFIX
setmakeenv MAKEOBJDIR "\${.CURDIR:C,^$TOP,$OPTARG,}"
;;
@ -925,7 +927,8 @@ sanitycheck()
# * If a copy of make was found above, try to use it with
# nobomb_getmakevar to find the correct value for TOOLDIR;
# * If all else fails, leave TOOLDIR unset. Our caller is expected to
# be able to cope with this.
# be able to cope with this. (For example, rebuildmake() handles it
# by building nbmake in a temporary directory.)
#
try_set_TOOLDIR()
{
@ -946,19 +949,28 @@ try_set_TOOLDIR()
#
# In the usual case (without interference from environment
# variables or /etc/mk.conf), <bsd.own.mk> should set TOOLDIR to
# "${TOP_objdir}/tooldir.${host_ostype}". However, in practice
# we might have the wrong value of TOP_objdir, so we also try
# some other possibilities.
# "${_SRC_TOP_OBJ_}/tooldir.${host_ostype}".
#
# In practice it's difficult to figure out the correct value
# for _SRC_TOP_OBJ_. In the easiest case, when the -M or -O
# options were passed to build.sh, then ${TOP_objdir} will be
# the correct value. We also try a few other possibilities, but
# we do not replicate all the logic of <bsd.obj.mk>.
#
local possible_TOP_OBJ
local possible_TOOLDIR
for possible_TOP_OBJ in "${TOP_objdir}" "${TOP}" "${TOP}/obj" \
for possible_TOP_OBJ in \
"${TOP_objdir}" \
"${MAKEOBJDIRPREFIX:+${MAKEOBJDIRPREFIX}${TOP}}" \
"${TOP}" \
"${TOP}/obj" \
"${TOP}/obj.${MACHINE}"
do
[ -n "${possible_TOP_OBJ}" ] || continue
possible_TOOLDIR="${possible_TOP_OBJ}/tooldir.${host_ostype}"
guess_make="${possible_TOOLDIR}/bin/${toolprefix}make"
if [ -x "${guess_make}" ]; then
break;
break
else
unset guess_make
fi
@ -988,8 +1000,8 @@ rebuildmake()
# binary, if TOOLDIR is pre-set or if try_set_TOOLDIR can set it.
#
try_set_TOOLDIR
make="${TOOLDIR-nonexistent}/bin/${toolprefix}make"
if [ -x "${make}" ]; then
make="${TOOLDIR:-\$TOOLDIR}/bin/${toolprefix}make"
if [ -n "$TOOLDIR" ] && [ -x "${make}" ]; then
for f in usr.bin/make/*.[ch] usr.bin/make/lst.lib/*.[ch]; do
if [ "${f}" -nt "${make}" ]; then
statusmsg "${make} outdated (older than ${f}), needs building."
@ -1051,45 +1063,39 @@ validatemakeparams()
MKUPDATE=$(getmakevar MKUPDATE)
if [ "${MKOBJDIRS}" != "no" ]; then
# Try to create the top level object directory before
# running "make obj", otherwise <bsd.own.mk> will not
# set the correct value for _SRC_TOP_OBJ_.
# Create the top-level object directory.
#
# If either -M or -O was specified, then we have the
# directory name already.
# "make obj NOSUBDIR=" can handle most cases, but it
# can't handle the case where MAKEOBJDIRPREFIX is set
# while the corresponding directory does not exist
# (rules in <bsd.obj.mk> would abort the build). We
# therefore have to handle the MAKEOBJDIRPREFIX case
# without invoking "make obj". The MAKEOBJDIR case
# could be handled either way, but we choose to handle
# it similarly to MAKEOBJDIRPREFIX.
#
# If neither -M nor -O was specified, then try to get
# the directory name from bsd.obj.mk's __usrobjdir
# variable, which is set using complex rules. This
# works only if TOP = /usr/src.
#
top_obj_dir="${TOP_objdir}"
if [ -z "${top_obj_dir}" ]; then
if [ "$TOP" = "/usr/src" ]; then
top_obj_dir="$(getmakevar __usrobjdir)"
# else __usrobjdir is not actually used
fi
if [ -n "${TOP_obj}" ]; then
# It must have been set by the "-M" or "-O"
# command line options, so there's no need to
# use getmakevar
:
elif [ -n "$MAKEOBJDIRPREFIX" ]; then
TOP_obj="$(getmakevar MAKEOBJDIRPREFIX)${TOP}"
elif [ -n "$MAKEOBJDIR" ]; then
TOP_obj="$(getmakevar MAKEOBJDIR)"
fi
if [ -n "$TOP_obj" ]; then
${runcmd} mkdir -p "${TOP_obj}" ||
bomb "Can't create top level object directory" \
"${TOP_obj}"
else
${runcmd} "${make}" -m ${TOP}/share/mk obj NOSUBDIR= ||
bomb "Can't create top level object directory" \
"using make obj"
fi
case "$top_obj_dir" in
*/*)
${runcmd} mkdir -p "${top_obj_dir}" \
|| bomb "Can't create object" \
"directory ${top_obj_dir}"
;;
*)
# We don't know what the top level object
# directory should be, so we can't create it.
# A nonexistant directory might cause an error
# when we "make obj" later, but we ignore it for
# now.
;;
esac
# make obj in tools to ensure that the objdir for the top-level
# of the source tree and for "tools" is available, in case the
# default TOOLDIR setting from <bsd.own.mk> is used, or the
# build.sh default DESTDIR and RELEASEDIR is to be used.
# make obj in tools to ensure that the objdir for "tools"
# is available.
#
${runcmd} cd tools
${runcmd} "${make}" -m ${TOP}/share/mk obj NOSUBDIR= ||
@ -1098,6 +1104,7 @@ validatemakeparams()
fi
# Find TOOLDIR, DESTDIR, RELEASEDIR, and RELEASEMACHINEDIR.
# This must be done after creating the top-level object directory.
#
TOOLDIR=$(getmakevar TOOLDIR)
statusmsg "TOOLDIR path: ${TOOLDIR}"
@ -1237,7 +1244,7 @@ createmakewrapper()
eval cat <<EOF ${makewrapout}
#! ${HOST_SH}
# Set proper variables to allow easy "make" building of a NetBSD subtree.
# Generated from: \$NetBSD: build.sh,v 1.211 2009/09/27 17:55:53 apb Exp $
# Generated from: \$NetBSD: build.sh,v 1.212 2009/09/27 18:08:24 apb Exp $
# with these arguments: ${_args}
#

View File

@ -1,4 +1,4 @@
.\" $NetBSD: BUILDING.mdoc,v 1.76 2009/09/27 17:28:38 apb Exp $
.\" $NetBSD: BUILDING.mdoc,v 1.77 2009/09/27 18:08:24 apb Exp $
.\"
.\" Copyright (c) 2001-2008 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -243,8 +243,21 @@ or
.
.It Sy MAKEOBJDIRPREFIX
Top level directory of the object directory tree.
If specified, must be an absolute path.
If this is defined,
The value is subjected to variable expansion by
.Xr make 1 .
.Sy build.sh
will create the
${MAKEOBJDIRPREFIX}
directory if necessary, but if
.Xr make 1
is used without
.Sy build.sh ,
then rules in
.Aq bsd.obj.mk
will abort the build if the
${MAKEOBJDIRPREFIX}
directory does not exist.
If the value is defined and valid, then
${MAKEOBJDIRPREFIX}/${.CURDIR}
is used as the
.Sy .OBJDIR
@ -1430,6 +1443,12 @@ Set
.Sy MAKEOBJDIRPREFIX
to
.Ar obj .
Unsets
.Sy MAKEOBJDIR .
See
.Dq Fl O obj
for more information.
.Pp
For instance, if the source directory is
.Pa /usr/src ,
a setting of
@ -1439,13 +1458,20 @@ will place build-time files under
.Pa /usr/obj/usr/src/lib ,
.Pa /usr/obj/usr/src/usr.bin ,
and so forth.
.Pp
If a relative path is specified, it will be converted to an
absolute path before being used.
Unsets
.Sy MAKEOBJDIR .
See
.Dq Fl O obj
for more information.
.Sy build.sh
imposes the restriction that the argument to the
.Fl M
option must not begin with a
.Dq \&$
(dollar sign)
character; otherwise it would be too difficult
to determine whether the value is an absolute or a relative path.
If the directory does not already exist,
.Sy build.sh
will create it.
.
.It Fl m Ar mach
Set the value of
@ -1509,6 +1535,9 @@ Create an appropriate transform macro for
.Sy MAKEOBJDIR
that will place the built object files under
.Ar obj .
Unsets
.Sy MAKEOBJDIRPREFIX .
.Pp
For instance, a setting of
.Dq Fl O Pa /usr/obj
will place build-time files under
@ -1516,10 +1545,19 @@ will place build-time files under
.Pa /usr/obj/lib ,
.Pa /usr/obj/usr.bin ,
and so forth.
.Pp
If a relative path is specified, it will be converted to an
absolute path before being used.
Unsets
.Sy MAKEOBJDIRPREFIX .
.Sy build.sh
imposes the restriction that the argument to the
.Fl O
option must not contain a
.Dq \&$
(dollar sign)
character.
If the directory does not already exist,
.Sy build.sh
will create it.
.Pp
In normal use, exactly one of the
.Fl M