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