xref: /illumos-gate/usr/src/tools/scripts/bldenv (revision 4125432b52bd46f8b4129eae0625c71e159f0077)
1#!/usr/bin/ksh93
2#
3# CDDL HEADER START
4#
5# The contents of this file are subject to the terms of the
6# Common Development and Distribution License (the "License").
7# You may not use this file except in compliance with the License.
8#
9# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10# or http://www.opensolaris.org/os/licensing.
11# See the License for the specific language governing permissions
12# and limitations under the License.
13#
14# When distributing Covered Code, include this CDDL HEADER in each
15# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16# If applicable, add the following below this CDDL HEADER, with the
17# fields enclosed by brackets "[]" replaced with your own identifying
18# information: Portions Copyright [yyyy] [name of copyright owner]
19#
20# CDDL HEADER END
21#
22
23#
24# Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
25# Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
26# Copyright 2014 Garrett D'Amore <garrett@damore.org>
27# Copyright 2020 Joyent, Inc.
28# Copyright 2020 Oxide Computer Company
29# Copyright 2024 Bill Sommerfeld <sommerfeld@hamachi.org>
30#
31# Uses supplied "env" file, based on /opt/onbld/etc/env, to set shell variables
32# before spawning a shell for doing a release-style builds interactively
33# and incrementally.
34#
35
36function fatal_error
37{
38	print -u2 "${progname}: $*"
39	exit 1
40}
41
42function usage
43{
44    OPTIND=0
45    getopts -a "${progname}" "${USAGE}" OPT '-?'
46    exit 2
47}
48
49typeset -r USAGE=$'+
50[-?\n@(#)\$Id: bldenv (OS/Net) 2008-04-06 \$\n]
51[-author?OS/Net community <tools-discuss@opensolaris.org>]
52[+NAME?bldenv - spawn shell for interactive incremental OS-Net
53    consolidation builds]
54[+DESCRIPTION?bldenv is a useful companion to the nightly(1) script for
55    doing interactive and incremental builds in a workspace
56    already built with nightly(1). bldenv spawns a shell set up
57    with the same environment variables taken from an env_file,
58    as prepared for use with nightly(1).]
59[+?In addition to running a shell for interactive use, bldenv
60    can optionally run a single command in the given environment,
61    in the vein of sh -c or su -c. This is useful for
62    scripting, when an interactive shell would not be. If the
63    command is composed of multiple shell words or contains
64    other shell metacharacters, it must be quoted appropriately.]
65[+?bldenv is particularly useful for testing Makefile targets
66    like clobber, install and _msg, which otherwise require digging
67    through large build logs to figure out what is being
68    done.]
69[+?By default, bldenv will invoke the shell specified in
70    $SHELL. If $SHELL is not set or is invalid, csh will be
71    used.]
72[c?force the use of csh, regardless of the  value  of $SHELL.]
73[f?invoke csh with the -f (fast-start) option. This option is valid
74    only if $SHELL is unset or if it points to csh.]
75[d?set up environment for doing DEBUG builds. The default is non-DEBUG,
76    unless the -F flag is specified in the nightly file.]
77[t?set up environment to use the tools in usr/src/tools (this is the
78    default, use +t to use the tools from /opt/onbld)]
79
80<env_file> [command]
81
82[+EXAMPLES]{
83    [+?Example 1: Interactive use]{
84        [+?Use bldenv to spawn a shell to perform  a  DEBUG  build  and
85            testing of the  Makefile  targets  clobber and install for
86            usr/src/cmd/true.]
87        [+\n% rlogin wopr-2 -l gk
88{root::wopr-2::49} bldenv -d /export0/jg/on10-se.env
89Build type   is  DEBUG
90RELEASE      is  5.10
91VERSION      is  wopr-2::on10-se::11/01/2001
92RELEASE_DATE is  May 2004
93The top-level `setup\' target is available to build headers
94and tools.
95Using /usr/bin/tcsh as shell.
96{root::wopr-2::49}
97{root::wopr-2::49} cd $SRC/cmd/true
98{root::wopr-2::50} make
99{root::wopr-2::51} make clobber
100/usr/bin/rm -f true true.po
101{root::wopr-2::52} make
102/usr/bin/rm -f true
103cat true.sh > true
104chmod +x true
105{root::wopr-2::53} make install
106install -s -m 0555 -u root -g bin -f /export0/jg/on10-se/proto/root_sparc/usr/bin true
107`install\' is up to date.]
108    }
109    [+?Example 2: Non-interactive use]{
110        [+?Invoke bldenv to create SUNWonbld with a single command:]
111        [+\nexample% bldenv onnv_06 \'cd $SRC/tools && make pkg\']
112        }
113}
114[+SEE ALSO?\bnightly\b(1)]
115'
116
117# main
118builtin basename
119
120# boolean flags (true/false)
121typeset flags=(
122	typeset c=false
123	typeset f=false
124	typeset d=false
125	typeset O=false
126	typeset o=false
127	typeset t=true
128	typeset s=(
129		typeset e=false
130		typeset h=false
131		typeset d=false
132		typeset o=false
133	)
134	typeset d_set=false
135	typeset DF_build=false
136)
137
138typeset progname="$(basename -- "${0}")"
139
140OPTIND=1
141
142while getopts -a "${progname}" "${USAGE}" OPT ; do
143    case ${OPT} in
144	  c)	flags.c=true  ;;
145	  +c)	flags.c=false ;;
146	  f)	flags.f=true  ;;
147	  +f)	flags.f=false ;;
148	  d)	flags.d=true ; flags.d_set=true ;;
149	  +d)	flags.d=false ; flags.d_set=true ;;
150	  t)	flags.t=true  ;;
151	  +t)	flags.t=false ;;
152	  \?)	usage ;;
153    esac
154done
155shift $((OPTIND-1))
156
157# test that the path to the environment-setting file was given
158if (( $# < 1 )) ; then
159	usage
160fi
161
162# force locale to C
163export \
164	LANG=C \
165	LC_ALL=C \
166	LC_COLLATE=C \
167	LC_CTYPE=C \
168	LC_MESSAGES=C \
169	LC_MONETARY=C \
170	LC_NUMERIC=C \
171	LC_TIME=C
172
173# clear environment variables we know to be bad for the build
174unset \
175	LD_OPTIONS \
176	LD_LIBRARY_PATH \
177	LD_AUDIT \
178	LD_BIND_NOW \
179	LD_BREADTH \
180	LD_CONFIG \
181	LD_DEBUG \
182	LD_FLAGS \
183	LD_LIBRARY_PATH_64 \
184	LD_NOVERSION \
185	LD_ORIGIN \
186	LD_LOADFLTR \
187	LD_NOAUXFLTR \
188	LD_NOCONFIG \
189	LD_NODIRCONFIG \
190	LD_NOOBJALTER \
191	LD_PRELOAD \
192	LD_PROFILE \
193	CONFIG \
194	GROUP \
195	OWNER \
196	REMOTE \
197	ENV \
198	ARCH \
199	CLASSPATH
200
201# set variables we want environment file to be able to override
202MAKEFLAGS=e
203
204#
205# Setup environment variables
206#
207if [[ -f /etc/nightly.conf ]]; then
208	source /etc/nightly.conf
209fi
210
211if [[ -f "$1" ]]; then
212	if [[ "$1" == */* ]]; then
213		source "$1"
214	else
215		source "./$1"
216	fi
217else
218	if [[ -f "/opt/onbld/env/$1" ]]; then
219		source "/opt/onbld/env/$1"
220	else
221		printf \
222		    'Cannot find env file as either %s or /opt/onbld/env/%s\n' \
223		    "$1" "$1"
224		exit 1
225	fi
226fi
227shift
228
229# Check if we have sufficient data to continue...
230[[ -v CODEMGR_WS ]] || fatal_error "Error: Variable CODEMGR_WS not set."
231[[ -d "${CODEMGR_WS}" ]] || fatal_error "Error: ${CODEMGR_WS} is not a directory."
232[[ -f "${CODEMGR_WS}/usr/src/Makefile" ]] || fatal_error "Error: ${CODEMGR_WS}/usr/src/Makefile not found."
233
234# must match the getopts in nightly
235OPTIND=1
236NIGHTLY_OPTIONS="-${NIGHTLY_OPTIONS#-}"
237while getopts '+0ABCDdFfGIilMmNnpRrtUuwW' FLAG $NIGHTLY_OPTIONS
238do
239	case "$FLAG" in
240	  t)	flags.t=true  ;;
241	  +t)	flags.t=false ;;
242	  F)	flags.DF_build=true ;;
243	  *)	;;
244	esac
245done
246
247# DEBUG is a little bit complicated.  First, bldenv -d/+d over-rides
248# the env file.  Otherwise, we'll default to DEBUG iff we are *not*
249# building non-DEBUG bits at all.
250if [ "${flags.d_set}" != "true" ] && "${flags.DF_build}"; then
251	flags.d=true
252fi
253
254POUND_SIGN="#"
255basews=$(basename -- "$CODEMGR_WS")
256# have we set RELEASE_DATE in our env file?
257if [ -z "$RELEASE_DATE" ]; then
258	RELEASE_DATE=$(LC_ALL=C date +"%B %Y")
259fi
260now=$(LC_ALL=C date +%Y-%b-%d)
261DEV_CM_TAIL="development build: $LOGNAME $now [$basews]"
262
263#
264# We export POUND_SIGN, RELEASE_DATE and DEV_CM_TAIL to speed up the build
265# process by avoiding repeated shell invocations to evaluate Makefile.master
266# definitions.
267#
268export POUND_SIGN RELEASE_DATE DEV_CM_TAIL
269
270print 'Build type   is  \c'
271if ${flags.d} ; then
272	print 'DEBUG'
273	SUFFIX=""
274	unset RELEASE_BUILD
275	unset EXTRA_OPTIONS
276	unset EXTRA_CFLAGS
277
278	if [ -n "$DEBUG_CONSOLE_COLOR" ]; then
279		export DEFAULT_CONSOLE_COLOR="$DEBUG_CONSOLE_COLOR"
280	fi
281else
282	# default is a non-DEBUG build
283	print 'non-DEBUG'
284	SUFFIX="-nd"
285	export RELEASE_BUILD=
286	unset EXTRA_OPTIONS
287	unset EXTRA_CFLAGS
288
289	if [ -n "$RELEASE_CONSOLE_COLOR" ]; then
290		export DEFAULT_CONSOLE_COLOR="$RELEASE_CONSOLE_COLOR"
291	fi
292fi
293
294# update build-type variables
295PKGARCHIVE="${PKGARCHIVE}${SUFFIX}"
296
297#	Set PATH for a build
298PATH="/opt/onbld/bin:/opt/onbld/bin/${MACH}:/opt/SUNWspro/bin:/usr/ccs/bin:/usr/bin:/usr/sbin:/usr/ucb:/usr/etc:/usr/openwin/bin:/usr/sfw/bin:/opt/sfw/bin:."
299if [[ "${SUNWSPRO}" != "" ]]; then
300	export PATH="${SUNWSPRO}/bin:$PATH"
301fi
302
303if [[ -n "${MAKE}" ]]; then
304	if [[ -x "${MAKE}" ]]; then
305		export PATH="$(dirname -- "${MAKE}"):$PATH"
306	else
307		print "\$MAKE (${MAKE}) is not a valid executible"
308		exit 1
309	fi
310fi
311
312TOOLS="${SRC}/tools"
313TOOLS_PROTO="${TOOLS}/proto/root_${MACH}-nd" ; export TOOLS_PROTO
314
315if "${flags.t}" ; then
316	export ONBLD_TOOLS="${ONBLD_TOOLS:=${TOOLS_PROTO}/opt/onbld}"
317
318	export STABS="${TOOLS_PROTO}/opt/onbld/bin/${MACH}/stabs"
319	export CTFSTABS="${TOOLS_PROTO}/opt/onbld/bin/${MACH}/ctfstabs"
320	export GENOFFSETS="${TOOLS_PROTO}/opt/onbld/bin/genoffsets"
321
322	export CTFCONVERT="${TOOLS_PROTO}/opt/onbld/bin/${MACH}/ctfconvert"
323	export CTFMERGE="${TOOLS_PROTO}/opt/onbld/bin/${MACH}/ctfmerge"
324	export NDRGEN="${TOOLS_PROTO}/opt/onbld/bin/${MACH}/ndrgen"
325
326	PATH="${TOOLS_PROTO}/opt/onbld/bin/${MACH}:${PATH}"
327	PATH="${TOOLS_PROTO}/opt/onbld/bin:${PATH}"
328	export PATH
329fi
330
331export DMAKE_MODE=${DMAKE_MODE:-parallel}
332
333#
334# Work around folks who have historically used GCC_ROOT and convert it to
335# GNUC_ROOT. We leave GCC_ROOT in the environment for now (though this could
336# mess up the case where multiple different gcc versions are being used to
337# shadow).
338#
339if [[ -n "${GCC_ROOT}" ]]; then
340	export GNUC_ROOT=${GCC_ROOT}
341fi
342
343DEF_STRIPFLAG="-s"
344
345TMPDIR="/tmp"
346
347export \
348	PATH TMPDIR \
349	POUND_SIGN \
350	DEF_STRIPFLAG \
351	RELEASE_DATE
352unset \
353	CFLAGS \
354	LD_LIBRARY_PATH
355
356# a la ws
357ENVLDLIBS1=
358ENVLDLIBS2=
359ENVLDLIBS3=
360ENVCPPFLAGS1=
361ENVCPPFLAGS2=
362ENVCPPFLAGS3=
363ENVCPPFLAGS4=
364PARENT_ROOT=
365PARENT_TOOLS_ROOT=
366
367if [[ "$MULTI_PROTO" != "yes" && "$MULTI_PROTO" != "no" ]]; then
368	printf \
369	    'WARNING: invalid value for MULTI_PROTO (%s); setting to "no".\n' \
370	    "$MULTI_PROTO"
371	export MULTI_PROTO="no"
372fi
373
374[[ "$MULTI_PROTO" == "yes" ]] && export ROOT="${ROOT}${SUFFIX}"
375
376ENVLDLIBS1="-L$ROOT/lib -L$ROOT/usr/lib"
377ENVCPPFLAGS1="-I$ROOT/usr/include"
378
379# Per usr/src/cmd/make/bin/main.cc, MAKEFLAGS could be in one of two styles.
380# If '-' or '=' is present, it is a new-style MAKEFLAGS which could be
381# pasted into the command line as-is.
382# Otherwise it is old-style (just a list of flag letters with no -)
383# make always converts MAKEFLAGS to new-style in the environment of
384# the processes it spawns
385
386case $MAKEFLAGS in
387	*-* | *=*)
388		print "New-style MAKEFLAGS detected; no change made"
389		print ""
390		;;
391	*e*)
392		;;
393	*)
394		MAKEFLAGS="${MAKEFLAGS}e"
395		print "MAKEFLAGS is now '${MAKEFLAGS}'"
396		print ""
397		;;
398esac
399
400export \
401        ENVLDLIBS1 \
402        ENVLDLIBS2 \
403        ENVLDLIBS3 \
404	ENVCPPFLAGS1 \
405        ENVCPPFLAGS2 \
406        ENVCPPFLAGS3 \
407	ENVCPPFLAGS4 \
408        MAKEFLAGS \
409        PARENT_ROOT \
410        PARENT_TOOLS_ROOT
411
412if [[ -z "$VERSION" ]]; then
413	export VERSION=$(git -C "${CODEMGR_WS}" describe --long --all --dirty |
414		cut -d/ -f2-)
415fi
416
417printf 'RELEASE      is %s\n'   "$RELEASE"
418printf 'VERSION      is %s\n'   "$VERSION"
419printf 'RELEASE_DATE is %s\n\n' "$RELEASE_DATE"
420
421if [[ -f "$SRC/Makefile" ]] && egrep -s '^setup:' "$SRC/Makefile" ; then
422	print "The top-level 'setup' target is available \c"
423	print "to build headers and tools."
424	print ""
425
426elif "${flags.t}" ; then
427	printf \
428	    'The tools can be (re)built with the install target in %s.\n\n' \
429	    "${TOOLS}"
430fi
431
432#
433# place ourselves in a new task, respecting BUILD_PROJECT if set.
434#
435/usr/bin/newtask -c $$ ${BUILD_PROJECT:+-p$BUILD_PROJECT}
436
437if [[ "${flags.c}" == "false" && -x "$SHELL" && \
438    "$(basename -- "${SHELL}")" != "csh" ]]; then
439	# $SHELL is set, and it's not csh.
440
441	if "${flags.f}" ; then
442		print 'WARNING: -f is ignored when $SHELL is not csh'
443	fi
444
445	printf 'Using %s as shell.\n' "$SHELL"
446	exec "$SHELL" ${@:+-c "$@"}
447
448elif "${flags.f}" ; then
449	print 'Using csh -f as shell.'
450	exec csh -f ${@:+-c "$@"}
451
452else
453	print 'Using csh as shell.'
454	exec csh ${@:+-c "$@"}
455fi
456
457# not reached
458