# $Id: buildfunctions.sh 552 2013-04-12 22:43:06Z elkner $ # The contents of this file are subject to the terms of the # Common Development and Distribution License (the "License") # (see http://www.opensource.org/licenses/CDDL-1.0). # # Copyright (c) 2011, 2012 Jens Elkner. All rights reserved. # Use is subject to license terms. ############################################################################ # "bootstrap" stuff ############################################################################ typeset -r SCRIPT=$( cd ${ dirname $0; }; printf "$PWD/%s" ${ basename $0; } ) typeset -r HSCRIPT="${.sh.file}" [[ -z $SDIR ]] && SDIR=${SCRIPT%/*} [[ -z $SCRIPTDIR ]] && SCRIPTDIR=${HSCRIPT%/*} . $SCRIPTDIR/log.kshlib . $SCRIPTDIR/man.kshlib Man.addVar SCRIPT 'The full pathname of the script currently running. Usually \bBuild.sh\b.' Man.addVar SDIR 'If not already set, set to the directory, which contains the script currently running as well as additional files like patches, manifests etc. required to build the package.' Man.addVar HSCRIPT 'The full pathname of this helper script containing this code.' Man.addVar SCRIPTDIR 'If not already set, set to the directory, which contains common helper scripts and files used to build a package. Usually it is \a$SCRIPT_BASE/../etc\a.' Man.addVar SCRIPT_BASE 'Directory where the build script tree starts. E.g. \a~/tmp/current/build/\a.' Man.addVar ARCH 'Set to ${ uname -p; }.' ARCH=${ uname -p; } Man.addVar OSREL 'Set to ${ uname -r; }.' [[ -z $OSREL ]] && OSREL=${ uname -r; } Man.addVar LC_CTYPE 'Always initially set to \bC\b.' Man.addVar LC_MESSAGES 'Always initially set to \bC\b.' Man.addVar LC_COLLATE 'Always initially set to \bC\b.' export LC_CTYPE=C LC_MESSAGES=C LC_COLLATE=C Man.addVar LC_ALL 'Always initially unset - setting it to any value is a no-go!' unset LC_ALL #PATH=/local/usr/bin:${ print $PATH | sed -e 's,/usr/local,,g'; }} # Other vars required to be set Man.addVar TMPBUILD 'Directory, where the software gets build. \a$SCRIPTDIR\a\b/root4build\b will completely remove and create this directory, when \acmd\a \bprepare\b gets called.' Man.addVar SOURCE 'Should point to the base directory, where the source archives are stored, e.g. \a/develop/src\a.' Man.addVar BUILD 'Should point to the base directory, where the software gets built, e.g. \a/tmp\a or \a/export/scratch/$USER/build\a.' Man.addVar PROTO 'Virtual root directory, where the software built should be installed, e.g. \a$BUILD/proto\a. It gets usually completely removed when \acmd\a \bpkg\b gets executed and re-populated by e.g. make install DESTDIR=$PROTO.' Man.addVar ROOT4BUILD 'A directory, where we copy usually include and lib files required for compilation of a new package. It basically avoids linking against outdated system software by accident. It gets usually populated by calling \a$SCRIPTDIR\a\b/root4build\b.' Man.addVar PKGDIR 'Should point to the base directory, where SVR4 packages should be stored, e.g. \a/develop/lnf/$ARCH/$OSREL\a.' Man.addVar PKG_REPO 'The URL of the IPS repository, where the package should be published (only required, if option \a-p\a is in use).' Man.addVar MAKELOG 'The name of the file, where the make output of \acmd\a \bmake\b should be stored. Set it to \b/dev/null\b if you are not interested in the log.' Man.addVar INSTLOG 'The name of the file, where the install output of \acmd\a \bprep\b should be stored. Set it to \b/dev/null\b if you are not interested in the log.' # Other required vars depending on the nature of package which needs to be build Man.addVar OPAL_PREFIX 'Install directory of the Sun HPC tools. E.g. \a/opt/SUNWhpc/HPC8.2.1c/sun\a.' Man.addVar LICS 'Directory, where license files and lics.xml live. E.g. \a$SCRIPT_BASE/licenses\a.' Man.addVar JAVA_HOME 'Install directory of the default JDK to use.' Man.addVar JAVA_1_5_HOME 'Install directory of JDK 1.5.' Man.addVar JAVA_1_6_HOME 'Install directory of JDK 1.6.' Man.addVar JAVA_1_7_HOME 'Install directory of JDK 1.7.' Man.addVar ANT_HOME 'Install directory of Apache Ant build tools.' Man.addVar GF3_HOME 'Install directory of Glassfish v3.' Man.addVar DOCBOOK_XSL_HOME 'Install directory of docbook-xsl.' Man.addVar DOCBOOK_XSL_XALAN_EXTENSION 'The name of the jar file relative to \a$SCRIPTDIR\a, which contains xalan related extension for docbook-xsl.' Man.addVar DOCBOOK_XML_HOME 'The directory, which contains the DTDs for docbook-xml.' Man.addVar MAVEN_HOME 'Install directory of Apache Maven.' Man.addVar R_HOME 'Install directory of R. Required to build R modules.' # per package required vars Man.addVar VERSION 'The version of the software being built.' export VERSION Man.addVar SUNPKGS 'Space separated list of SVR4 package names. If set, \a$SCRIPTDIR\a\b/root4build\b checks, whether these packages are installed on the current system, and optionally copies modified config files to appropriate $ROOT4BUILD directories.' export SUNPKGS Man.addVar REQUIRED 'Space separated list of SVR4 package names. If set, \a$SCRIPTDIR\a\b/root4build\b checks, whether $PKGDIR contains the listed SVR4 packages and copies modified config files, libs and required binaries/scripts to appropriate $ROOT4BUILD directories.' export REQUIRED # vars set by this helper script Man.addVar PKG_VERSION 'If not set, it gets set by \bpkginfo2arch()\b to \a$VERSION\a.' Man.addVar IPS_MANIFEST 'The basename of the IPS manifest to be used for publishing the package. Default: \blnfpkg.p5m\b.' Man.addVar PKG_ARCH 'If not already set it gets set to \bsparcvis\b if $ARCH == "sparc", otherwise to \bsse3\b. See SunStudio \bcc\b(1) -xarch=... for appropriate values.' Man.addVar PKG_CPU 'If not already set it gets set to \bultrasparc3\b if $ARCH == "sparc", otherwise to \bnocona\b. See \bgcc\b(1) -march=... for appropriate values.' Man.addVar MEM_MODEL 'If not set or has a value != 32 and != 64 it gets set to \b32\b. However, it gets overwritten with \b64\b if the $PKG_ARCH denotes a 64-bit architecture instruction set.' Man.addVar ARCH_DIR 'If $MEM_MODEL == 64 it gets set to either \b/amd64\b or \b/sparcv9\b depending on whether $ARCH == "sparc" or not. Otherwise it is set to an empty string.' Man.addVar PKG_CONFIG_PATH 'The path list, where \bpkg-config\b(1) is looking for *.pc files. If $ARCH_DIR is set, corresponding pathes take precendence of 32-bit related pathes.' Man.addVar GINSTALL 'Set to a GNU compatible install command, if available.' Man.addVar STRIP 'Program used to strip. Initially set to \btrue\b to avoid stripping - not needed anymore, since HDDs are now big enough.' Man.addVar ACLOCAL_FLAGS 'Set to include $ROOT4BUILD aclocal files.' Man.addVar LD_RUN_PATH 'Set to \b$ORIGIN:$ORIGIN/../lib\b\a$ARCH_DIR\a so that the linker automatically includes this RPATH.' Man.addVar LD_LIBRARY_PATH_32 'Set to include $ROOT4BUILD and system only related pathes, to avoid linking against unwanted libs by accident.' Man.addVar LD_LIBRARY_PATH_64 'Similar as for LD_LIBRARY_PATH_32, but with 64-bit related pathes.' Man.addVar PATH 'Set to include $ROOT4BUILD related pathes first, than standard system pathes and finally to Studio and "local" directories.' Man.addVar CC 'Set to \bcc\b if not already set. If == "cc", the L_* vars below have Studio specific settings, otherwise GCC specific setting.' Man.addVar CXX 'Set to \bCC\b if not already set.' Man.addVar DEBUG 'Set to \b1\b if debug build was enabled (see option \a-D\a), to \b0\b otherwise. If != 0 \bL_\b* vars will not have special optimization flags set.' Man.addVar L_CFLAGS 'Default \bCFLAGS\b one should use, when compiling the software. For high performance apps you may add "-xbuiltin=%all". For sparc builts "-xmemalign=8s" may help to avoid coredumps of the produced binary.' Man.addVar L_CXXFLAGS 'Default \bCXXFLAGS\b one should use, when compiling C++ software. For high performance apps you may add "-noex".' Man.addVar L_LDFLAGS 'Default \bLDFLAGS\b one should use, when compiling/linking software.' Man.addVar L_CPPFLAGS 'Default \bCPPFLAGS\b one should use, when pre-processing source files.' Man.addVar X 'Stores temp. values. Might be overwritten any time.' Man.addFunc LIB '' '[+NAME?'"${SCRIPT##*/}"' - execute steps to build a SVR4 and optional an IPS package.] [+DESCRIPTION?Helper script to execute the necessary steps to build a software and package it. Change your current working directory to the appropriate package build directory (e.g. build/network/sendmail) and execute this script.] [+?\acmd\a can be a string consisting of the following digits only: \b1\b (prep), \b2\b (make), \b3\b (pkg), or one of the following strings:] { [+prep?Executes the \bdoPrepare()\b function of this script. It should create the \a$TMPBUILD\a directory, unpack and optionally patch the software source, prepare the \a$BUILDDIR/\a with all packages/dependencies required to build the software and optionally re-create/update automake/autoconf related files.] [+make?Executes the \bdoMake()\b function of this script. It should just build the software. This usually includes running configure and make.] [+pkg?Executes the \bdoPackage()\b function of this script. It should install the software into \a$PROTO/\a, create the SVR4 pkg{proto,info} files and optionally IPS manifests and finally create the SVR4 package below \a$PKGDIR/\a and optionally publish the IPS package.] } [+?If no \acmd\a is given, \b123\b is assumed.] [h:help?Print this help and exit.] [p:publish?If the current platform supports IPS packages, the IPS package gets published as well when \acmd\a \bpkg\b gets executed.] [l:list?Print a list of script relevant environment variables and their current value (i.e. when this helper script got sourced) and exit. Listing these variable is also possible anywhere in this script using the \blistVars()\b function.] [F:functions?Print a list of all functions currently defined and exit. Just invokes \btypeset +f\b builtin.] [f:Functions?Print a all functions currently defined and exit. Just invokes \btypeset -f\b builtin.] [T:trace]:[functions?A comma or whitespace separated list of functions to trace during execution.] [H:usage]:[functionName?Show the usage info for the given function, if available and exit. See also option \a-F\a.] [D:Debug?Enable debug build. See environment variable \bDEBUG\b.] \n\n[\bcmd\b] ...\n\n [+ENVIRONMENT VARIABLES?The following environment variables need to be set a priori (global scope):] {' "${ Man.varUsage SCRIPT SDIR HSCRIPT SCRIPTDIR SCRIPT_BASE ARCH OSREL LC_CTYPE LC_MESSAGES LC_COLLATE LC_ALL TMPBUILD SOURCE BUILD PROTO ROOT4BUILD PKGDIR PKG_REPO MAKELOG INSTLOG; }" ' } [+?Depending on what gets build, the following environment variables should be set (partially for convinience, only) as well (global scope):] {' "${ Man.varUsage OPAL_PREFIX LICS JAVA_HOME JAVA_1_5_HOME JAVA_1_6_HOME JAVA_1_7_HOME ANT_HOME GF3_HOME DOCBOOK_XSL_HOME DOCBOOK_XSL_XALAN_EXTENSION DOCBOOK_XML_HOME MAVEN_HOME R_HOME ; }" ' } [+?The following environment variables must be explicitly set for each single package (package scope):] {' "${ Man.varUsage VERSION SUNPKGS REQUIRED ; }" ' } [+?The following environment variables are set when this helper script gets sourced (package scope):] {' "${ Man.varUsage PKG_VERSION IPS_MANIFEST PKG_ARCH PKG_CPU MEM_MODEL ARCH_DIR PKG_CONFIG_PATH GINSTALL STRIP ACLOCAL_FLAGS LD_RUN_PATH LD_LIBRARY_PATH_32 LD_LIBRARY_PATH_64 PATH CC CXX DEBUG L_CFLAGS L_CXXFLAGS L_LDFLAGS L_CPPFLAGS X ; }" ' } ' function showUsage { typeset X FNAME if [[ $2 != LIB ]]; then getopts -a "$1" "${ print ${Man.FUNC[$2]}; }" OPT --man else getopts -a "$1" "${ print ${Man.FUNC[$2]}; }" OPT --man fi } DO_PUBLISH="" DO_LIST_VARS="" DO_LIST_FUNC="" DO_LIST_FUNC_FULL="" DO_LIST_FUNC_MAN="" DO_TRACE_FUNC="" DO_JUMP="" DEBUG=0 STYPE=MAIN [[ $SCRIPT == $HSCRIPT || -z "${Man.FUNC[$STYPE]}" ]] && STYPE=LIB while getopts "${ print ${Man.FUNC[$STYPE]}; }" OPT ; do case $OPT in h) DO_LIST_FUNC_MAN+="${SCRIPT##*/} $STYPE" ; DO_JUMP=1 ;; H) DO_LIST_FUNC_MAN+="$OPTARG $OPTARG" ; DO_JUMP=1 ;; l) DO_LIST_VARS=1; DO_JUMP=1 ;; F) DO_LIST_FUNC=1; DO_JUMP=1 ;; f) DO_LIST_FUNC_FULL=1; DO_JUMP=1 ;; T) DO_TRACE_FUNC+="${OPTARG//,/ } " ;; p) DO_PUBLISH=4 ;; D) DEBUG=1 esac done IDX=$(($OPTIND-1)) shift $IDX if [[ -z $1 && -z $DO_JUMP ]]; then DO_PREPARE=1 DO_MAKE=2 DO_PKG=3 else DO_PREPARE="" DO_MAKE="" DO_PKG="" fi while [[ -n $1 ]]; do case "$1" in +([1-3])) X="$1" Y=${X//1} [[ "$X" != "$Y" ]] && DO_PREPARE=1 X=${Y//2} [[ "$X" != "$Y" ]] && DO_MAKE=2 Y=${X//3} [[ "$X" != "$Y" ]] && DO_PKG=3 ;; prep*) DO_PREPARE=1 ;; make) DO_MAKE=2 ;; pkg) DO_PKG=3 ;; *) Log.warn "Unknown cmd \"$1\" ignored." ;; esac shift done unset IDX X Y OPT if [[ -z $DO_PREPARE && -z $DO_MAKE && -z $DO_PKG && -z $DO_JUMP ]]; then showUsage "${SCRIPT##*/}" "$STYPE" exit 1 fi NEEDVAR="" [[ -z $PROTO ]] && NEEDVAR+=" PROTO" [[ -z $SOURCE ]] && NEEDVAR+=" SOURCE" [[ -z $BUILD ]] && NEEDVAR+=" BUILD" [[ -z $PKGDIR ]] && NEEDVAR+=" PKGDIR" [[ -z $MAKELOG ]] && NEEDVAR+=" MAKELOG" [[ -z $INSTLOG ]] && NEEDVAR+=" INSTLOG" [[ -n $NEEDVAR ]] && Log.fatal "The following environment variables are not set:$NEEDVAR ." && exit 2 function clean_dst { if [[ -z $1 ]]; then Log.fatal 'Invalid function call clean_dst. Missing argument.' exit 1 else typeset _dst="$1" fi if [[ -d $_dst ]]; then rm -rf $_dst sync fi mkdir -p $_dst } function doBuild { if [[ -n $DO_PREPARE ]]; then if [[ ! -d $BUILD ]]; then Log.fatal "$BUILD directory does not exist." exit 1 fi Log.info "Preparing source ..." doPrepare else Log.info 'Skipping source setup' fi if [[ -n $DO_MAKE ]]; then if [[ ! -d $TMPBUILD ]]; then Log.fatal "$TMPBUILD does not exist." exit 1 fi Log.info "Compiling source ..." doMake else Log.info 'Skipping Make' fi if [[ -n $DO_PKG ]]; then if [[ ! -d $TMPBUILD ]]; then Log.fatal "$TMPBUILD directory does not exist." exit 1 fi Log.info "Preparing package(s) ..." doPackage else Log.info 'Skipping package make' fi } function call_pkgmk { typeset PROTOFILE=$1 Log.info "Making package $1 ..." pkgmk -o -f $PROTOFILE -d $PKGDIR 2>&1 | tee ${PROTOFILE}.log if [[ $? -ne 0 ]]; then Log.warn ' pkgmk failed. Make sure you have write permission for $PKGDIR and do a pkgmk -o -f '"$1"' -d $PKGDIR ' fi if [[ -n "$2" && -n $HAS_IPS && -n $DO_PUBLISH ]]; then [[ ! -r $TMPBUILD/$IPS_MANIFEST ]] && Log.warn "$TMPBUILD/$IPS_MANIFEST not found" && return [[ -z $PKG_REPO ]] && Log.warn 'PKG_REPO is not set!' && return Log.info "Publishing package to $PKG_REPO" pkgsend publish -d $PROTO -s $PKG_REPO $TMPBUILD/$IPS_MANIFEST fi } function gzip_man { Log.fatal 'Use gzipmans '"$1"' to zip man pages' exit 6 } # sets PKG_VERSION if not already set function pkginfo2arch { # force automounter to get the dir [[ -z $PKG_VERSION ]] && PKG_VERSION="$VERSION" ls $PKGDIR >/dev/null typeset BN for src in $SDIR/pkginfo* ; do BN=${src##*/} sed -e "/^ARCH/ s,=.*,=$ARCH," -e "/^VERSION/ s,=.*,=${PKG_VERSION}," \ $src >$TMPBUILD/${BN}.lnf done } function addRlibs { typeset VERS TR PRE PRE1 DIR T1 VERS=${ readlink -f $R_HOME; } VERS=${VERS##*/} TR="$R_LIBS_USER" while [[ -n $1 ]]; do PRE="$1" PRE1="${PRE#R.}" [[ $PRE != $PRE1 ]] && PRE="R-$PRE1" DIR="$PKGDIR/R/LNFr-$PRE/reloc/$VERS/library" if [[ ! -d $DIR ]]; then Log.warn "R library not found: $DIR" elif [[ ! -d "$DIR/$1" ]]; then Log.warn "Package error: $1 not in $DIR" else R_LIBS_USER+=":$DIR" fi shift done [[ -n $R_DEBUG ]] && Log.info "R_LIBS_USER=${#R_LIBS_USER}" if [[ ${#R_LIBS_USER} -gt 1000 ]]; then T1="$R_LIBS_USER" while [[ ${#T1} -gt 1000 ]]; do T1=${T1%:*} done R_LIBS_SITE=${R_LIBS_USER#$T1} R_LIBS_USER="$T1" export R_LIBS_SITE=${R_LIBS_SITE#:} [[ -n $R_DEBUG ]] && Log.info "R_LIBS_SITE=${#R_LIBS_SITE}" fi [[ -n $R_DEBUG ]] && Log.info "R_LIBS_USER=${#R_LIBS_USER}" export R_LIBS_USER=${R_LIBS_USER#:} } function rTestOnly { export _R_CHECK_WEAVE_VIGNETTES_=FALSE export _R_CHECK_LATEX_VIGNETTES_=FALSE export _R_CHECK_RD_XREFS_=FALSE #export _R_CHECK_FORCE_SUGGESTS_=FALSE export _R_CHECK_USE_CODETOOLS_=FALSE export _R_CHECK_RD_STYLE_=FALSE export _R_CHECK_EXECUTABLES_=FALSE export _R_CHECK_EXECUTABLES_EXCLUSIONS_=FALSE export _R_CHECK_RD_PARSE_=FALSE export _R_CHECK_DOT_INTERNAL_=FALSE export _R_CHECK_FF_CALLS_=FALSE export _R_CHECK_LICENSE_=FALSE R_CHECK_LATEX=FALSE #R_CHECK_NO_CLEAN=FALSE R_CHECK_NO_CODOC=TRUE #R_CHECK_NO_EXAMPLES=FALSE #R_CHECK_NO_INSTALL=FALSE #R_CHECK_NO_TESTS=FALSE R_CHECK_NO_VIGNETTES=TRUE } function doRcheck { typeset CKDIR PARAMS CKDIR="$1" shift addRlibs "$@" #Log.info "$R_HOME/bin/R CMD check -l $PROTO/R/library $CKDIR" #Log.info "R_LIBS_USER=$R_LIBS_USER" #Log.info "R_LIBS_SITE=$R_LIBS_SITE" PARAMS="" [[ $R_CHECK_NO_CLEAN == TRUE ]] && PARAMS+=" --no-clean" [[ $R_CHECK_NO_CODOC == TRUE ]] && PARAMS+=" --no-codoc" [[ $R_CHECK_NO_EXAMPLES == TRUE ]] && PARAM+.=" --no-examples" [[ $R_CHECK_NO_INSTALL == TRUE ]] && PARAMS+=" --no-install" [[ $R_CHECK_NO_TESTS == TRUE ]] && PARAMS+=" --no-tests" [[ $R_CHECK_NO_VIGNETTES == TRUE ]] && PARAMS+=" --no-vignettes" [[ $R_CHECK_LATEX == TRUE ]] || PARAMS+=" --no-latex" Log.info $R_HOME/bin/R CMD check $PARAMS -l $PROTO/R/library "$CKDIR" $R_HOME/bin/R CMD check $PARAMS -l $PROTO/R/library "$CKDIR" } function getDefines { typeset _LOG _OUT [[ -n $1 ]] && _LOG="$1" [[ -z $_LOG ]] && _LOG="${MAKELOG:-/tmp/mk.log}" if [[ ! -r $_LOG ]]; then Log.warn "$_LOG does not exist - nothing to search" return fi _OUT=${TMPBUILD:-/tmp/}DEFS.txt nawk -f $SCRIPTDIR/findDefs.awk $_LOG | sort -u | \ egrep -v -- '-D(FQDN|HAVE_CONFIG_H|PIC|PLUGIN_BUILD)' \ >$_OUT Log.info "Defines stored to $_OUT" } Man.addFunc addRBAC '' '[+NAME?addRBAC - add RBAC files to the given pkgproto file] [+DESCRIPTION?Adds the given RBAC files to the given \aprotomap\a file. The current OS determines the way, how the are added (S10 has no /etc/security/*.d/). The given \arbac_file\as need to have {exec|auth|prof|user}}_attr in its pathname to be able to determine, how to add them.] [f:file]:[protomap:=$TMPBUILD/prototype.lnf?Name of the file, where to add pkgproto map entries.] [p:prefix]:[basedir?The \abasedir\a to replace with @CLIENT_BASEDIR@ attr.lnf files. If no prefix is given, the file gets not modified, otherwise copied to ${TMPBUILD}/attr.lnf/$FILE to not interfere with IPS.] \n\n protofile rbac_file ... ' function addRBAC { typeset MAPFILE="${TMPBUILD}/prototype.lnf" PREFIX='' TOADD='' \ DST TYP ACT SRC X typeset -i -u NDIRS=0 while getopts -a "$0" "${ print ${Man.FUNC['addRBAC']}; }" OPT ; do case $OPT in f) if [[ -f ${OPTARG} ]]; then MAPFILE="${OPTARG}" else Log.fatal "addRBAC(): mapfile '${OPTARG}' does not exist!" exit 3 fi ;; p) PREFIX="${OPTARG}" ;; esac done X=$(( OPTIND - 1 )) shift $X (( ! $# )) && return [[ -d ${TMPBUILD}/attr.lnf ]] && rm -rf ${TMPBUILD}/attr.lnf mkdir ${TMPBUILD}/attr.lnf if [[ -d /etc/user_attr.d ]]; then # S11: just copy and do not remove. Merge is not required. for FILE in "$@" ; do TYP='e' ACT='rbac' SRC="${FILE}" case "$FILE" in *exec_attr*) (( NDIRS|=1 )) DST=/etc/security/exec_attr.d && TYP='f' if [[ -n ${PREFIX} ]]; then SRC=${TMPBUILD}/attr.lnf/${FILE##*/} gsed -e "s,::${PREFIX}/,::@CLIENT_BASEDIR@/," \ "${FILE}" >"${SRC}" ACT='rename' fi ;; *auth_attr*) (( NDIRS|=2 )) DST=/etc/security/auth_attr.d ;; *prof_attr*) (( NDIRS|=4 )) DST=/etc/security/prof_attr.d ;; *user_attr*) (( NDIRS|=8 )) DST=/etc/user_attr.d ;; *) Log.fatal "'${FILE}' doesn't match {user|exec|prof|auth}_attr" exit 3 esac TOADD+="${TYP} rbac ${DST}/${FILE##*/}=${SRC} 0644 root sys\n" done (( ${NDIRS} )) && TOADD+='d none /etc ? ? ?\n' (( ${NDIRS} & 7 )) && TOADD+='d none /etc/security ? ? ?\n' (( ${NDIRS} & 1 )) && TOADD+='d none /etc/security/exec_attr.d ? ? ?\n' (( ${NDIRS} & 2 )) && TOADD+='d none /etc/security/auth_attr.d ? ? ?\n' (( ${NDIRS} & 4 )) && TOADD+='d none /etc/security/prof_attr.d ? ? ?\n' (( ${NDIRS} & 8 )) && TOADD+='d none /etc/user_attr.d ? ? ?\n' (( ${NDIRS} & 1 )) && ! /usr/xpg4/bin/grep -q '^i i.rename=' $MAPFILE \ && TOADD+="i i.rename=${SCRIPTDIR}/i.rename\n" if (( ${NDIRS} & ~1 )); then TOADD+="i i.rbac=${SCRIPTDIR}/i.rename\n" TOADD+="i r.rbac=${SCRIPTDIR}/r.rbac\n" fi else # S10: Merge in, but do not remove. for FILE in "$@" ; do case "$FILE" in *exec_attr*) if [[ -n ${PREFIX} ]]; then gsed -e "s,::${PREFIX}/,::@CLIENT_BASEDIR@/," \ "${FILE}" >>${TMPBUILD}/attr.lnf/exec_attr else cat "${FILE}" >>${TMPBUILD}/attr.lnf/exec_attr fi (( NDIRS|=1 )) ;; *auth_attr*) cat "${FILE}" >>${TMPBUILD}/attr.lnf/auth_attr (( NDIRS|=2 )) ;; *prof_attr*) cat "${FILE}" >>${TMPBUILD}/attr.lnf/prof_attr (( NDIRS|=4 )) ;; *user_attr*) cat "${FILE}" >>${TMPBUILD}/attr.lnf/user_attr (( NDIRS|=8 )) ;; *) Log.fatal "'${FILE}' doesn't match {user|exec|prof|auth}_attr" exit 3 ;; esac done (( ${NDIRS} )) && TOADD+='d none /etc ? ? ?\n' (( ${NDIRS} & 7 )) && TOADD+='d none /etc/security ? ? ?\n' (( ${NDIRS} & 1 )) && TOADD+="e rbac /etc/security/exec_attr=${TMPBUILD}/attr.lnf/exec_attr 0644 root sys\n" (( ${NDIRS} & 2 )) && TOADD+="e rbac /etc/security/auth_attr=${TMPBUILD}/attr.lnf/auth_attr 0644 root sys\n" (( ${NDIRS} & 4 )) && TOADD+="e rbac /etc/security/prof_attr=${TMPBUILD}/attr.lnf/prof_attr 0644 root sys\n" (( ${NDIRS} & 8 )) && TOADD+="e rbac /etc/user_attr=${TMPBUILD}/attr.lnf/user_attr 0644 root sys\n" TOADD+="i i.rbac=${SCRIPTDIR}/i.rbac\n" TOADD+="i r.rbac=${SCRIPTDIR}/r.rbac\n" fi print -n "${TOADD}" >>${MAPFILE} } Man.addFunc createIPS '[+NAME?createIPS - create a complete IPS manifest ready to publish a package.] [+DESCRIPTION?A function, which combines all steps to create a valid and ready to publish IPS manifest. All produced artifacts are stored in \a$TMPBUILD/\a. The file content (lnfpkg.p5m.1) gets generated using pkgsend from \a$PROTO/\a. The metadata (lnfpkg.meta) are generated from the given arguments as well as \a$TMPBUILD\a\b/pkginfo.lnf\b. pkgmogrify gets called with ${IPS_MANIFEST}.1 and metadata to produce ${IPS_MANIFEST}.2. Than pkgdepend gets invoked to generate an IPS manifest (${IPS_MANIFEST}.3), which contains in addition all detected dependencies in debug format, which might be useful to find out, why a certain dependency has been added. After that pkgdepend is used to resolve dependencies in ${IPS_MANIFEST}.3 and to create the final IPS manifest (\a$IPS_MANIFEST\a). Finally this new IPS manifest gets copied to \a$SDIR/\a and the environment variable \bHAS_IPS\b gets set to a non-empty string.] [+?If \a$SDIR/$IPS_MANIFEST\a already exists and \a$PKGUPDATE\a is not set/empty, this function simply copies the file to \a$TMPBUILD/\a, sets the environment variable \bHAS_IPS\b and returns.] [+?This function assumes, that the current working directory is \a$TMPBUILD/\a!] [+?On Solaris < 5.11 this function sets the environment variable \bHAS_IPS\b to an empty string and returns.] [h:help?Print his help and exit.] [g:global?Package scope is global zone (optional).] [n:nonglobal?Package scope is non-global zones (optional).] [p:path]:[path?Directory name of the pkg FRMI path to use. E.g. desktop/system-monitor or library/python-2/lxml-28. The last component of the path (pkginfo:NAME with LNF prefix stripped off) gets append automatically.] [v:version]:[version:=\a$PKG_VERSION\a?Version of the packaged software. This becomes the \bcomponent\b (first) part of the IPS version info. The IPS \bbuild version\b part (2nd part, after the comma) gets set automatically to \a$OSREL\a, and the IPS \bbranch version\b (3rd part, after the dash) gets set to the SVN buildnumber suffixed with a \b.1\b] [V:humanvers]:[version?The \bpkg.human-version\b to set (a more readable version info string than just numbers). If not given, no such info gets added to the package.] [c:category]:[category?Classification of the package, e.g. "Applications/System Utilities". See http://src.iws.cs.ovgu.de/source/xref/pkg/doc/dev-guide/appendix-a.txt] [s:source]:[url?URL where the source for the packaged software might be obtained (optional).] [a:arch]:[list:=\a$ARCH\a?A comma separated list of variant.arch values (optional), e.g. "i386 sparc".] [f:force?Force the re-creation of pkg manifest even if there is a cached copy available.] ' function createIPS { if [[ ${OSREL#5.} -lt 11 ]]; then HAS_IPS="" return else HAS_IPS="true" fi Log.info 'Prepare IPS package ...' IFRMIPATH='' IVERSION='' ICATEGORY='' ISRCURL='' IARCH='' IZONE='' HVERS='' [[ -z ${PKG_VERSION} ]] && Log.warn 'PKG_VERSION is not set' && exit 1 integer FORCE=0 while getopts -a createIPS "${ print ${Man.FUNC[createIPS]}; }" OPT ; do case "$OPT" in p) IFRMIPATH="$OPTARG" ;; v) IVERSION="$OPTARG" ;; V) HVERS="$OPTARG" ;; c) ICATEGORY="$OPTARG" ;; s) ISRCURL="$OPTARG" ;; a) for X in $OPTARG ; do IARCH+="value=$X " done ;; g) IZONE+="value=global " ;; n) IZONE+="value=nonglobal " ;; h) createIPS --man ;; f) FORCE=1 ;; esac done [[ -z $IVERSION ]] && IVERSION="$PKG_VERSION" [[ -z $IVERSION ]] && Log.fatal "createIPS: VERSION (-v ...) not given" \ && exit 1 [[ -z $IFRMIPATH ]] && Log.fatal "createIPS: FRMIPATH (-p ...) not given" \ && exit 1 [[ -z $ICATEGORY ]] && Log.fatal "createIPS: CATEGORY (-c ...) not given" \ && exit 1 [[ ${ICATEGORY#org.opensolaris} == $ICATEGORY ]] && \ ICATEGORY="org.opensolaris.category.2008:$ICATEGORY" [[ -z $IARCH ]] && IARCH="value=$ARCH" cd $TMPBUILD || exit 1 [[ $FORCE != 1 && -z $PKGUPDATE && -s "$SDIR/${IPS_MANIFEST}" ]] && \ cp $SDIR/${IPS_MANIFEST} . && return typeset OLC="$LC_CTYPE" LC_CTYPE="en_US.UTF-8" typeset IINF=$TMPBUILD/pkginfo.lnf [[ ! -r $IINF ]] && Log.fatal "createIPS: $IINF not found" && exit 1 pkgsend generate $PROTO | pkgfmt >${IPS_MANIFEST}.1 IREV=${ cd $SDIR; svnversion -n } ; cd - IREV=${IREV##*:} [[ ${IREV: -1} == 'M' ]] && IREV=${IREV/%M/.1} || IREV+='.0' IPKG=${ grep ^PKG= $IINF | cut -f2 -d= ; } IDESC=${ grep ^DESC= $IINF | cut -f2 -d=; } INAME=${ grep ^NAME= $IINF | cut -f2 -d=; } ILIC=${ grep ^LICINFO= $IINF | cut -f2 -d=; } LCAT=${ grep ^CATEGORY= $IINF | cut -f2 -d=; } [[ -z $ILIC ]] && Log.warn "No LICINFO in $IINF" # IVERSION .. Software release version # OSREL .. Branch version (targeted Solaris OS) # IREV .. Build number cat >lnfpkg.meta<>lnfpkg.meta [[ -n $ISRCURL ]] && print "set name=info.source-url value=\"$ISRCURL\"" \ >>lnfpkg.meta [[ -n $IZONE ]] && print "set name=variant.opensolaris.zone $IZONE" \ >>lnfpkg.meta # cannot be used because of pkgdepend bug # [[ -n $ILIC ]] && print "license license=${ILIC}" \ # >>lnfpkg.meta pkgmogrify ${IPS_MANIFEST}.1 lnfpkg.meta | pkgfmt > ${IPS_MANIFEST}.2 [[ ! -s ${IPS_MANIFEST}.2 ]] && Log.warn "pkgmogrify failed" && exit 1 [[ -r ${IPS_MANIFEST}.bp ]] && cat ${IPS_MANIFEST}.bp >>${IPS_MANIFEST}.2 pkgdepend generate -md $PROTO ${IPS_MANIFEST}.2 | pkgfmt > ${IPS_MANIFEST}.3 [[ ! -s ${IPS_MANIFEST}.3 ]] && Log.warn "pkgdepend generate failed" && exit 1 # die scheise dauert ca. 3.5min auf ner 3GHz Kiste Log.info "Resolving IPS dependencies - this may take a while ..." pkgdepend resolve -m -s res ${IPS_MANIFEST}.3 #pkglint ${IPS_MANIFEST}.3.res if [[ -r ${IPS_MANIFEST}.3.res && -s ${IPS_MANIFEST}.3.res ]]; then Log.info "Done." mv ${IPS_MANIFEST}.3.res ${IPS_MANIFEST} && cp ${IPS_MANIFEST} $SDIR/ else Log.warn "pkgdepend resolve failed" && exit 1 fi export LC_CTYPE="$OLC" } # many configure (i.e autoconf/autmake generated) scripts are using # none-POSIX conform sed expressions which would produce unexpected results # with sed > 3.02.0 and POSIXLY_CORRECT env. var set. E.g. # # print '/usr/share/emacs/' | \ # sed -e '/.*\/share\/\(x\?emacs\)/ {s,,foobar/\1,;p;q;}' # # with POSIXLY_CORRECT (unexpected result): foobar//usr/share/emacs/ # w/o POSIXLY_CORRECT (expected result): foobar/emacs/ unset POSIXLY_CORRECT # just to make sure, that we do not get any unexpected stuff unset LD_RUN_PATH unset LD_LIBRARY_PATH [[ $MEM_MODEL != 32 && $MEM_MODEL != 64 ]] && MEM_MODEL="" # Studio if [[ -z $PKG_ARCH ]]; then # instruction sets selection if [[ $ARCH == sparc ]]; then PKG_ARCH=sparcvis else PKG_ARCH=sse3 fi fi # GCC if [[ -z $PKG_CPU ]]; then if [[ $ARCH == i386 ]]; then PKG_CPU=nocona else PKG_CPU=ultrasparc3 fi fi # yes, we let the compiler decide about timing details of code scheduling # so PKG_CPU is not used with studio compiler (as well as assumed cache type) if [[ -z $MEM_MODEL ]]; then MEM_MODEL=32 case $PKG_ARCH in v*) MEM_MODEL=64 ;; sparcfmaf) MEM_MODEL=64 ;; sparcv*) MEM_MODEL=64 ;; amd64) MEM_MODEL=64 PKG_ARCH=sse2 ;; *64) MEM_MODEL=64 ;; sse2a) MEM_MODEL=64 ;; amd64a) MEM_MODEL=64 PKG_ARCH=sse2a ;; sse3) MEM_MODEL=64 ;; esac fi PKG_CONFIG_PATH="" PKG_PATH="${ROOT4BUILD}/usr/lib /local/usr/lib /usr/lib" if [[ $MEM_MODEL == 64 ]]; then if [[ $ARCH == sparc ]]; then ARCH_DIR="/sparcv9" else ARCH_DIR="/amd64" fi # http://bugs.opensolaris.org/view_bug.do?bug_id=4829237 for P in $PKG_PATH ; do PKG_CONFIG_PATH+=":${P}$ARCH_DIR/pkgconfig" done else ARCH_DIR="" fi for P in $PKG_PATH ; do PKG_CONFIG_PATH+=":$P/pkgconfig" done PKG_CONFIG_PATH=${PKG_CONFIG_PATH:1} unset PKG_PATH GINSTALL=/usr/ucb/install if [[ ! -x $GINSTALL ]]; then GINSTALL=${ whence ginstall; } if [[ -z $GINSTALL ]]; then Log.warn "GNU compatible install not found" fi fi # HDDs are now big enough ... STRIP=true export \ PKG_CONFIG_PATH \ ACLOCAL_FLAGS="-I $ROOT4BUILD/usr/share/aclocal" \ LD_RUN_PATH='$ORIGIN:$ORIGIN/../lib'$ARCH_DIR \ LD_LIBRARY_PATH_32=$ROOT4BUILD/usr/lib:/usr/sfw/lib \ LD_LIBRARY_PATH_64=$ROOT4BUILD/usr/lib/64:/usr/sfw/lib/64 \ PATH=$ROOT4BUILD/usr/bin:$ROOT4BUILD/usr/sbin:${STUDIO_HOME}/bin:/usr/ccs/bin:/local/usr/bin:/usr/${ARCH_DIR}/bin:/usr/bin:/usr/sfw/bin:/usr/sbin:/usr/sfw/sbin:/sbin \ CC=${CC:-cc} CXX=${CXX:-CC} if [[ $CC == cc ]]; then L_CFLAGS="-fsimple=1 -xlibmil -xlibmopt -m$MEM_MODEL -xarch=$PKG_ARCH \ -xdepend -xO4 -I$ROOT4BUILD/usr/include -I/usr/sfw/include" else if [[ $PKG_CPU == ultra3i ]]; then PKG_CPU=ultrasparc3 fi L_CFLAGS="-O3 -m$MEM_MODEL -march=$PKG_CPU -I$ROOT4BUILD/usr/include" fi L_CXXFLAGS="-g $L_CFLAGS" L_LDFLAGS="-m$MEM_MODEL -L$ROOT4BUILD/usr/lib$ARCH_DIR -L/usr/sfw/lib$ARCH_DIR" L_CPPFLAGS="$L_CFLAGS $L_LDFLAGS" if [[ $CC == cc ]]; then L_CFLAGS="-g -xstrconst $L_CFLAGS" L_LDFLAGS="-zdefs -Bdirect $L_LDFLAGS" else L_CFLAGS="-g $L_CFLAGS" fi if [[ $DEBUG != 0 ]]; then Log.info "DEBUG is enabled" if [[ $CC == cc ]]; then L_CFLAGS="-g -m$MEM_MODEL -xarch=$PKG_ARCH -I$ROOT4BUILD/usr/include -I/usr/sfw/include" else L_CFLAGS="-g -m$MEM_MODEL -march=$PKG_CPU -I$ROOT4BUILD/usr/include -I/usr/sfw/include" fi L_CXXFLAGS="$L_CFLAGS" L_CPPFLAGS="$L_CFLAGS $L_LDFLAGS" fi export CC CXX IPS_MANIFEST="lnfpkg.p5m" [[ -n "$DO_TRACE_FUNC" ]] && typeset -ft $DO_TRACE_FUNC if [[ -n $DO_JUMP ]]; then [[ -n $DO_LIST_VARS ]] && Man.listVars [[ -n $DO_LIST_FUNC ]] && typeset +f [[ -n $DO_LIST_FUNC_FULL ]] && typeset -f [[ -n $DO_LIST_FUNC_MAN ]] && showUsage $DO_LIST_FUNC_MAN exit 0 fi