Index: ebuild.sh =================================================================== RCS file: /var/cvsroot/gentoo-src/portage/bin/ebuild.sh,v retrieving revision 1.201.2.11 diff -u -4 -p -r1.201.2.11 ebuild.sh --- ebuild.sh 2 Jan 2005 09:36:02 -0000 1.201.2.11 +++ ebuild.sh 4 Jan 2005 08:35:43 -0000 @@ -11,9 +11,23 @@ if [ ! -z "${PORTAGE_GPG_DIR}" ]; then SANDBOX_PREDICT="${SANDBOX_PREDICT}:${PORTAGE_GPG_DIR}" fi if [ "$*" != "depend" ] && [ "$*" != "clean" ] && [ "$*" != "nofetch" ]; then + # Cleanup if we were killed in the previous run... + if [ -f "${BUILDDIR}/.abi" ]; then + abi=$(cat ${BUILDDIR}/.abi) + if [ -d "${WORKDIR}" ]; then + mv ${WORKDIR} ${WORKDIR}.${abi} || die "IO Failure -- Unable to mv work work.${abi}" + fi + rm -rf ${BUILDDIR}/.abi || die "IO Failure -- Unable to 'rm .abi'" + unset abi + fi + if [ -f "${T}/environment" ]; then + # restore_env isn't set yet, so we just source it for now. + # Once this code is rearanged so the functions are defined + # before this code is executed, we can just do restore_env + # here. source "${T}/environment" &>/dev/null fi fi @@ -614,52 +628,190 @@ dyn_setup() fi pkg_setup } +# Filter which environment variables to save/restore. +select_saved_vars() { + egrep -v "^(LD_PRELOAD|SANDBOX_|PORTAGE_|DISTCC_|CCACHE_|current_vars|target_vars|var|file)" +} + +# We need to save/restore the environment for each ABI we are installing for separately +save_env() { + local file + if [ "$#" = "1" ]; then + file="${T}/environment.${1}" + else + file="${T}/environment" + fi + + local oldumask=$(umask) + umask 002 + set | select_saved_vars > ${file} || die "Unable to save environment settings." + export -p | sed 's:declare -r\{0,1\}x ::' | select_saved_vars | sed 's:^:declare -x :' >> ${file} || die "Unable to save environment settings." + chown portage:portage ${file} &>/dev/null + chmod g+w ${file} &>/dev/null + umask ${oldumask} +} + +restore_env() { + local file + if [ "$#" = "1" -a -f "${T}/environment.${1}" ]; then + file="${T}/environment.${1}" + elif [ -f "${T}/environment" ]; then + file="${T}/environment" + else + return + fi + + local current_vars=$(set | egrep '^[_A-Za-z0-9]+=' | cut -f1 -d= | select_saved_vars) + local target_vars=$(cat ${file} | egrep '^[_A-Za-z0-9]+=' | cut -f1 -d= | select_saved_vars) + + # OPTIMIZE: We should take advantage of the fact that they're both ordered lists + for var in ${current_vars}; do + if ! hasq ${var} ${target_vars}; then + # Redirect to /dev/null so we don't get spam'd about + # any read-only variables. + echo ">>> Unsetting: ${var}=${!var}" + unset ${var} &>/dev/null + fi + done + + source ${file} &>/dev/null || die "IO Failure in restore_env" +} + +set_abi() { + if [ "$#" != "1" ]; then + die "set_abi needs to be given the ABI to use." + fi + + local abi=${1} + + if [ -d "${WORKDIR}" ]; then + unset_abi + else + save_env + fi + restore_env ${abi} + + if [ -d "${WORKDIR}.${abi}" ]; then + # If it doesn't exist, then we're making it soon in dyn_unpack + mv ${WORKDIR}.${abi} ${WORKDIR} || die "IO Failure -- Failed to 'mv work.${abi} work'" + fi + + echo "${abi}" > ${BUILDDIR}/.abi || die "IO Failure -- Failed to create .abi." + echo ">>> ABI=${abi}" + + # Export variables we need for toolchain + export ABI="${abi}" + + local VAR + VAR="CFLAGS_${ABI}" + [ -n "${!VAR}" ] && eval export ${VAR} + VAR="ASFLAGS_${ABI}" + [ -n "${!VAR}" ] && eval export ${VAR} +} + +unset_abi() { + if [ -f "${BUILDDIR}/.abi" ]; then + local abi=$(cat ${BUILDDIR}/.abi) + [ ! -d "${WORKDIR}" ] && die "unset_abi: .abi present (${abi}) but workdir not present." + + save_env ${abi} + restore_env + + mv ${WORKDIR} ${WORKDIR}.${abi} || die "IO Failure -- Failed to 'mv work work.${abi}'." + rm -rf ${BUILDDIR}/.abi || die "IO Failure -- Failed to 'rm -rf .abi'." + fi +} + +get_abi_order() { + local order="" + + if ! hasq multilib-pkg ${FEATURES}; then + order="NOMULTILIB" + elif ! hasq multilib-pkg ${RESTRICT}; then + order="${DEFAULT_ABI}" + else + for x in ${MULTILIB_ABIS}; do + if [ "${x}" != "${DEFAULT_ABI}" ]; then + hasq ${x} ${ABI_DENY} || ordera="${ordera} ${x}" + fi + done + hasq ${DEFAULT_ABI} ${ABI_DENY} || order="${ordera} ${DEFAULT_ABI}" + + if [ -n "${ABI_ALLOW}" ]; then + local ordera="" + for x in ${order}; do + if hasq ${x} ${ABI_ALLOW}; then + ordera="${ordera} ${x}" + fi + done + order="${ordera}" + fi + fi + + if [ -z "${order}" ]; then + die "The ABI list is empty. Are you using a proper multilib profile? Perhaps your USE flags or MULTILIB_ABIS are too restrictive for this package." + fi + + echo ${order} +} + dyn_unpack() { trap "abort_unpack" SIGINT SIGQUIT local newstuff="no" - if [ -e "${WORKDIR}" ]; then - local x - local checkme - for x in ${AA}; do - echo ">>> Checking ${x}'s mtime..." - if [ "${DISTDIR}/${x}" -nt "${WORKDIR}" ]; then - echo ">>> ${x} has been updated; recreating WORKDIR..." + + for ABI in $(get_abi_order); do + if [ "${ABI}" = "NOMULTILIB" ]; then + unset ABI + else + set_abi ${ABI} + fi + if [ -e "${WORKDIR}" ]; then + local x + local checkme + for x in ${AA}; do + echo ">>> Checking ${x}'s mtime..." + if [ "${DISTDIR}/${x}" -nt "${WORKDIR}" ]; then + echo ">>> ${x} has been updated; recreating WORKDIR..." + newstuff="yes" + rm -rf "${WORKDIR}" + break + fi + done + if [ "${EBUILD}" -nt "${WORKDIR}" ]; then + echo ">>> ${EBUILD} has been updated; recreating WORKDIR..." + newstuff="yes" + rm -rf "${WORKDIR}" + elif [ ! -f "${BUILDDIR}/.unpacked" ]; then + echo ">>> Not marked as unpacked; recreating WORKDIR..." newstuff="yes" rm -rf "${WORKDIR}" - break fi - done - if [ "${EBUILD}" -nt "${WORKDIR}" ]; then - echo ">>> ${EBUILD} has been updated; recreating WORKDIR..." - newstuff="yes" - rm -rf "${WORKDIR}" - elif [ ! -f "${BUILDDIR}/.unpacked" ]; then - echo ">>> Not marked as unpacked; recreating WORKDIR..." - newstuff="yes" - rm -rf "${WORKDIR}" fi - fi - if [ -e "${WORKDIR}" ]; then - if [ "$newstuff" == "no" ]; then - echo ">>> WORKDIR is up-to-date, keeping..." - return 0 + if [ -e "${WORKDIR}" ]; then + if [ "${newstuff}" == "no" ]; then + echo ">>> WORKDIR is up-to-date, keeping..." + unset_abi + continue + fi fi - fi - - install -m0700 -d "${WORKDIR}" || die "Failed to create dir '${WORKDIR}'" - [ -d "$WORKDIR" ] && cd "${WORKDIR}" - echo ">>> Unpacking source..." - src_unpack + + install -m0700 -d "${WORKDIR}" || die "Failed to create dir '${WORKDIR}'" + [ -d "${WORKDIR}" ] && cd "${WORKDIR}" + echo ">>> Unpacking source..." + src_unpack + unset_abi + done + unset ABI touch "${BUILDDIR}/.unpacked" || die "IO Failure -- Failed 'touch .unpacked' in BUILDIR" echo ">>> Source unpacked." - cd "$BUILDDIR" + cd "${BUILDDIR}" trap SIGINT SIGQUIT } dyn_clean() { - if [ "$USERLAND" == "BSD" ] && type -p chflags &>/dev/null; then + if [ "${USERLAND}" == "BSD" ] && type -p chflags &>/dev/null; then chflags -R noschg,nouchg,nosappnd,nouappnd,nosunlnk,nouunlnk \ "${BUILDDIR}" fi @@ -671,13 +823,14 @@ dyn_clean() { mv "${T}/environment" "${T}/environment.keeptemp" fi if ! hasq keepwork $FEATURES; then - rm -rf "${BUILDDIR}/.compiled" + rm -rf "${BUILDDIR}/.abi" + rm -rf "${BUILDDIR}/.compiled*" rm -rf "${BUILDDIR}/.unpacked" rm -rf "${BUILDDIR}/.installed" rm -rf "${BUILDDIR}/build-info" - rm -rf "${WORKDIR}" + rm -rf "${WORKDIR}*" fi if [ -f "${BUILDDIR}/.unpacked" ]; then find "${BUILDDIR}" -type d ! -regex "^${WORKDIR}" | sort -r | tr "\n" "\0" | $XARGS -0 rmdir &>/dev/null @@ -793,15 +946,16 @@ abort_handler() { abort_compile() { abort_handler "src_compile" $1 rm -f "${BUILDDIR}/.compiled" + [ -n "${ABI}" ] && rm -f "${BUILDDIR}/.compiled.${ABI}" exit 1 } abort_unpack() { abort_handler "src_unpack" $1 rm -f "${BUILDDIR}/.unpacked" - rm -rf "${BUILDDIR}/work" + rm -rf "${BUILDDIR}/work*" exit 1 } abort_package() { @@ -824,21 +978,8 @@ abort_install() { } dyn_compile() { trap "abort_compile" SIGINT SIGQUIT - [ "${CFLAGS-unset}" != "unset" ] && export CFLAGS - [ "${CXXFLAGS-unset}" != "unset" ] && export CXXFLAGS - [ "${LIBCFLAGS-unset}" != "unset" ] && export LIBCFLAGS - [ "${LIBCXXFLAGS-unset}" != "unset" ] && export LIBCXXFLAGS - [ "${LDFLAGS-unset}" != "unset" ] && export LDFLAGS - [ "${ASFLAGS-unset}" != "unset" ] && export ASFLAGS - - [ "${CCACHE_DIR-unset}" != "unset" ] && export CCACHE_DIR - [ "${CCACHE_SIZE-unset}" != "unset" ] && export CCACHE_SIZE - - [ "${DISTCC_DIR-unset}" == "unset" ] && export DISTCC_DIR="${PORTAGE_TMPDIR}/.distcc" - [ ! -z "${DISTCC_DIR}" ] && addwrite "${DISTCC_DIR}" - if hasq noauto $FEATURES &>/dev/null && [ ! -f ${BUILDDIR}/.unpacked ]; then echo echo "!!! We apparently haven't unpacked... This is probably not what you" echo "!!! want to be doing... You are using FEATURES=noauto so I'll assume" @@ -862,27 +1003,66 @@ dyn_compile() { mkdir build-info fi cp "${EBUILD}" "build-info/${PF}.ebuild" - if [ ${BUILDDIR}/.compiled -nt "${WORKDIR}" ]; then + if [ "$(get_abi_order)" = "NOMULTILIB" -a \ + ${BUILDDIR}/.compiled -nt "${WORKDIR}" ]; then echo ">>> It appears that ${PN} is already compiled; skipping." echo ">>> (clean to force compilation)" trap SIGINT SIGQUIT return fi - if [ -d "${S}" ]; then - cd "${S}" - fi - #our custom version of libtool uses $S and $D to fix - #invalid paths in .la files - export S D - #some packages use an alternative to $S to build in, cause - #our libtool to create problematic .la files - export PWORKDIR="$WORKDIR" - src_compile + + for ABI in $(get_abi_order); do + if [ "${ABI}" = "NOMULTILIB" ]; then + unset ABI + else + set_abi ${ABI} + + if [ ${BUILDDIR}/.compiled.${ABI} -nt "${WORKDIR}" ]; then + echo ">>> It appears that ${PN} is already compiled for ABI=${ABI}; skipping." + echo ">>> (clean to force compilation)" + unset_abi + continue + fi + fi + + [ "${CFLAGS-unset}" != "unset" ] && export CFLAGS + [ "${CXXFLAGS-unset}" != "unset" ] && export CXXFLAGS + [ "${LIBCFLAGS-unset}" != "unset" ] && export LIBCFLAGS + [ "${LIBCXXFLAGS-unset}" != "unset" ] && export LIBCXXFLAGS + [ "${LDFLAGS-unset}" != "unset" ] && export LDFLAGS + [ "${ASFLAGS-unset}" != "unset" ] && export ASFLAGS + + [ "${CCACHE_DIR-unset}" != "unset" ] && export CCACHE_DIR + [ "${CCACHE_SIZE-unset}" != "unset" ] && export CCACHE_SIZE + + [ "${DISTCC_DIR-unset}" == "unset" ] && export DISTCC_DIR="${PORTAGE_TMPDIR}/.distcc" + [ ! -z "${DISTCC_DIR}" ] && addwrite "${DISTCC_DIR}" + + #our custom version of libtool uses $S and $D to fix + #invalid paths in .la files + export S D + #some packages use an alternative to $S to build in, cause + #our libtool to create problematic .la files + export PWORKDIR="${WORKDIR}" + + if [ -d "${S}" ]; then + cd "${S}" + fi + src_compile + + if [ "${ABI}" != "NOMULTILIB" ]; then + cd "${BUILDDIR}" + touch .compiled.${ABI} || die "IO Failure -- Failed to 'touch .compiled.${ABI}'" + unset_abi + fi + done + unset ABI + #|| abort_compile "fail" cd "${BUILDDIR}" - touch .compiled + touch .compiled || "IO Failure -- Failed to 'touch .compiled'" cd build-info echo "$ASFLAGS" > ASFLAGS echo "$CATEGORY" > CATEGORY @@ -913,8 +1093,12 @@ dyn_compile() { echo "$RESTRICT" > RESTRICT echo "$SLOT" > SLOT echo "$USE" > USE + if [ "$(get_abi_order)" != "NOMULTILIB" ]; then + echo "$(get_abi_order)" > MULTILIB_ABIS + fi + set > environment export -p | sed 's:declare -rx:declare -x:' >> environment bzip2 -9 environment @@ -946,18 +1130,31 @@ dyn_package() { dyn_test() { trap "abort_test" SIGINT SIGQUIT - if [ -d "${S}" ]; then - cd "${S}" - fi if hasq maketest $RESTRICT; then ewarn "Skipping make test/check due to ebuild restriction." echo ">>> Test phase [explicitly disabled]: ${CATEGORY}/${PF}" elif ! hasq maketest $FEATURES; then echo ">>> Test phase [not enabled]: ${CATEGORY}/${PF}" else - src_test + for ABI in $(get_abi_order); do + if [ "${ABI}" = "NOMULTILIB" ]; then + unset ABI + else + set_abi ${ABI} + fi + + if [ -d "${S}" ]; then + cd "${S}" + fi + src_test + + if [ "${ABI}" != "NOMULTILIB" ]; then + unset_abi + fi + done + unset ABI fi cd "${BUILDDIR}" touch .tested || die "Failed to 'touch .tested' in ${BUILDDIR}" @@ -969,20 +1166,36 @@ dyn_test() { dyn_install() { trap "abort_install" SIGINT SIGQUIT rm -rf "${BUILDDIR}/image" mkdir "${BUILDDIR}/image" - if [ -d "${S}" ]; then - cd "${S}" - fi echo echo ">>> Install ${PF} into ${D} category ${CATEGORY}" - #our custom version of libtool uses $S and $D to fix - #invalid paths in .la files - export S D - #some packages uses an alternative to $S to build in, cause - #our libtool to create problematic .la files - export PWORKDIR="$WORKDIR" - src_install + + for ABI in $(get_abi_order); do + if [ "${ABI}" = "NOMULTILIB" ]; then + unset ABI + else + set_abi ${ABI} + fi + + #our custom version of libtool uses $S and $D to fix + #invalid paths in .la files + export S D + #some packages uses an alternative to $S to build in, cause + #our libtool to create problematic .la files + export PWORKDIR="${WORKDIR}" + + if [ -d "${S}" ]; then + cd "${S}" + fi + src_install + + if [ "${ABI}" != "NOMULTILIB" ]; then + unset_abi + fi + done + unset ABI + #|| abort_install "fail" prepall cd "${D}" @@ -1813,11 +2026,8 @@ for myarg in $*; do done if [ "$myarg" != "clean" ]; then # Save current environment and touch a success file. (echo for success) - umask 002 - set | egrep -v "^SANDBOX_" > "${T}/environment" 2>/dev/null - chown portage:portage "${T}/environment" &>/dev/null - chmod g+w "${T}/environment" &>/dev/null + save_env fi exit 0