setup_pkgmgr(): Make the 'build' use flag passed in
[catalyst.git] / targets / support / chroot-functions.sh
index 8114ee90ccd18b59e2640d35b8ea482e73e41b90..ee820edebfe36916d67e33e277e989fe80987e89 100755 (executable)
@@ -1,3 +1,7 @@
+#!/bin/bash
+
+# Set the profile
+eselect profile set ${clst_target_profile}
 
 # Trap these signals and kill ourselves if recieved
 # Force ourselves to die if any of these signals are recieved
@@ -12,17 +16,6 @@ trap "echo SIGKILL signal recieved killing $0 with pid $$;kill -9 $$" SIGKILL
 #      * user types ctrl-c
 #      * kernel recognizes this and generates SIGINT signal
 trap "echo SIGINT signal recieved killing $0 with pid $$;kill -9 $$" SIGINT
-check_portage_version(){
-       portage_version=`/usr/lib/portage/bin/portageq best_version / sys-apps/portage \
-               | cut -d/ -f2 | cut -d- -f2,3`
-       if [ -n ${portage_version} -a `echo ${portage_version} | cut -d- -f1 | cut -d. -f3` -lt '51' ]
-       then
-               echo "ERROR: Your portage version is too low in your seed stage.  Portage version"
-               echo "2.0.51 or greater is required."
-               exit 1
-       fi
-}
 
 check_genkernel_version(){
        if [ -x /usr/bin/genkernel ]
@@ -45,84 +38,201 @@ check_genkernel_version(){
        fi
 }
 
-setup_myfeatures(){
+get_libdir() {
+       ABI=$(portageq envvar ABI)
+       DEFAULT_ABI=$(portageq envvar DEFAULT_ABI)
+       LIBDIR_default=$(portageq envvar LIBDIR_default)
+
+       local abi
+       if [ $# -gt 0 ]
+       then
+               abi=${1}
+       elif [ -n "${ABI}" ]
+       then
+               abi=${ABI}
+       elif [ -n "${DEFAULT_ABI}" ]
+       then
+               abi=${DEFAULT_ABI}
+       else
+               abi="default"
+       fi
+
+       local var="LIBDIR_${abi}"
+       var=$(portageq envvar ${var})
+       echo ${var}
+}
 
+setup_myfeatures(){
+       setup_myemergeopts
+       export FEATURES="-news clean-logs"
        if [ -n "${clst_CCACHE}" ]
        then
                export clst_myfeatures="${clst_myfeatures} ccache"
-               #if [ "${clst_AUTORESUME}" = "1" -a -e /tmp/.clst_ccache ]
-               #then
-               #       echo "CCACHE Autoresume point found not emerging ccache"
-               #else
-                       emerge --oneshot --nodeps -b -k ccache || exit 1
-               #       touch /tmp/.clst_ccache
-               #fi
+               clst_root_path=/ run_merge --oneshot --noreplace dev-util/ccache || exit 1
        fi
 
        if [ -n "${clst_DISTCC}" ]
        then
                export clst_myfeatures="${clst_myfeatures} distcc"
                export DISTCC_HOSTS="${clst_distcc_hosts}"
-               #if [ "${clst_AUTORESUME}" = "1" -a -e /tmp/.clst_distcc ]
-               #then
-               #       echo "DISTCC Autoresume point found not emerging distcc"
-               #else
-                       USE="-gtk -gnome" emerge --oneshot --nodeps -b -k distcc || exit 1
-                       #touch /tmp/.clst_distcc
-               #fi
+               [ -e /etc/portage/make.conf ] && \
+                       echo 'USE="${USE} -avahi -gtk -gnome"' >> /etc/portage/make.conf
+               # We install distcc to / on stage1, then use --noreplace, so we need to
+               # have some way to check if we need to reinstall distcc without being
+               # able to rely on USE, so we check for the distcc user and force a
+               # reinstall if it isn't found.
+               if [ "$(getent passwd distcc | cut -d: -f1)" != "distcc" ]
+               then
+                       clst_root_path=/ run_merge --oneshot sys-devel/distcc || exit 1
+               else
+                       clst_root_path=/ run_merge --oneshot --noreplace sys-devel/distcc || exit 1
+               fi
+               sed -i '/USE="${USE} -avahi -gtk -gnome"/d' /etc/portage/make.conf
                mkdir -p /etc/distcc
                echo "${clst_distcc_hosts}" > /etc/distcc/hosts
+
+               # This sets up automatic cross-distcc-fu according to
+               # http://www.gentoo.org/doc/en/cross-compiling-distcc.xml
+               CHOST=$(portageq envvar CHOST)
+               LIBDIR=$(get_libdir)
+               cd /usr/${LIBDIR}/distcc/bin
+               rm cc gcc g++ c++ 2>/dev/null
+               echo -e '#!/bin/bash\nexec /usr/'${LIBDIR}'/distcc/bin/'${CHOST}'-g${0:$[-2]} "$@"' > ${CHOST}-wrapper
+               chmod a+x /usr/${LIBDIR}/distcc/bin/${CHOST}-wrapper
+               for i in cc gcc g++ c++; do ln -s ${CHOST}-wrapper ${i}; done
+       fi
+
+       if [ -n "${clst_ICECREAM}" ]
+       then
+               clst_root_path=/ run_merge --oneshot --noreplace sys-devel/icecream || exit 1
+
+               # This sets up automatic cross-icecc-fu according to
+               # http://gentoo-wiki.com/HOWTO_Setup_An_ICECREAM_Compile_Cluster#Icecream_and_cross-compiling
+               CHOST=$(portageq envvar CHOST)
+               LIBDIR=$(get_libdir)
+               cd /usr/${LIBDIR}/icecc/bin
+               rm cc gcc g++ c++ 2>/dev/null
+               echo -e '#!/bin/bash\nexec /usr/'${LIBDIR}'/icecc/bin/'${CHOST}'-g${0:$[-2]} "$@"' > ${CHOST}-wrapper
+               chmod a+x ${CHOST}-wrapper
+               for i in cc gcc g++ c++; do ln -s ${CHOST}-wrapper ${i}; done
+               export PATH="/usr/lib/icecc/bin:${PATH}"
+               export PREROOTPATH="/usr/lib/icecc/bin"
        fi
+       export FEATURES="${clst_myfeatures} -news"
 }
 
 setup_myemergeopts(){
-       if [ -n "${clst_PKGCACHE}" ]
+       if [ -n "${clst_VERBOSE}" ]
+       then
+               clst_myemergeopts="--verbose"
+       else
+               clst_myemergeopts="--quiet"
+               bootstrap_opts="${bootstrap_opts} -q"
+       fi
+       if [ -n "${clst_FETCH}" ]
+       then
+               export bootstrap_opts="${bootstrap_opts} -f"
+               export clst_myemergeopts="${clst_myemergeopts} -f"
+       # if we have PKGCACHE, and either update_seed is empty or 'no', make and use binpkgs
+       elif [ -n "${clst_PKGCACHE}" ] && [ -z "${clst_update_seed}" -o "${clst_update_seed}" = "no" ]
        then
-               export clst_myemergeopts="--usepkg --buildpkg --newuse"
-               export bootstrap_opts="-r"
+               export clst_myemergeopts="${clst_myemergeopts} --usepkg --buildpkg --newuse"
+               export bootstrap_opts="${bootstrap_opts} -r"
        fi
 }
 
-
-setup_portage(){
-       # portage needs to be merged manually with USE="build" set to avoid frying our
-       # make.conf. emerge system could merge it otherwise.
-       if [ "${clst_AUTORESUME}" = "1" -a -e /tmp/.clst_portage ]
+setup_binutils(){
+       if [ -x /usr/bin/binutils-config ]
        then
-               echo "Portage Autoresume point found not emerging portage"
-       else
-               USE="build" emerge --oneshot --nodeps portage
-               touch /tmp/.clst_portage || exit 1
+               my_binutils=$( cd /etc/env.d/binutils; ls ${clst_CHOST}-* | head -n 1 )
+               if [ -z "${my_binutils}" ]
+               then
+                       my_binutils=1
+               fi
+               binutils-config ${my_binutils}; update_env_settings
        fi
 }
 
 setup_gcc(){
        if [ -x /usr/bin/gcc-config ]
        then
-               mythang=$( cd /etc/env.d/gcc; ls ${clst_CHOST}-* | head -n 1 )
-               if [ -z "${mythang}" ]
+               my_gcc=$( cd /etc/env.d/gcc; ls ${clst_CHOST}-* | head -n 1 )
+               if [ -z "${my_gcc}" ]
                then
-                       mythang=1
+                       my_gcc=1
                fi
-               gcc-config ${mythang}; update_env_settings
+               gcc-config ${my_gcc}; update_env_settings
        fi
 }
 
-setup_binutils(){
-       if [ -x /usr/bin/binutils-config ]
+setup_pkgmgr(){
+       # We need to merge our package manager with USE="build" set in case it is
+       # portage to avoid frying our /etc/portage/make.conf file.  Otherwise, we could
+       # just let emerge @system could merge it.
+       # Use --update or portage might just waste time/cycles and reinstall the same version.
+       if [ -n "$1" ];then
+               echo "Adding USE='${USE} $1' to make.conf for portage build"
+               [ -e /etc/portage/make.conf ] && echo 'USE="${USE} $1"' >> /etc/portage/make.conf
+               run_merge --oneshot --update sys-apps/portage
+               sed -i '/USE="${USE} $1"/d' /etc/portage/make.conf
+       else
+               echo "Updating portage with USE='${USE}'"
+               run_merge --oneshot --update sys-apps/portage
+       fi
+}
+
+cleanup_distcc() {
+       LIBDIR=$(get_libdir)
+       rm -rf /etc/distcc/hosts
+       for i in cc gcc c++ g++; do
+               rm -f /usr/${LIBDIR}/distcc/bin/${i}
+               ln -s /usr/bin/distcc /usr/${LIBDIR}/distcc/bin/${i}
+       done
+       rm -f /usr/${LIBDIR}/distcc/bin/*-wrapper
+}
+
+cleanup_icecream() {
+       LIBDIR=$(get_libdir)
+       for i in cc gcc c++ g++; do
+               rm -f /usr/${LIBDIR}/icecc/bin/${i}
+               ln -s /usr/bin/icecc /usr/${LIBDIR}/icecc/bin/${i}
+       done
+       rm -f /usr/${LIBDIR}/icecc/bin/*-wrapper
+}
+
+cleanup_stages() {
+       make_destpath
+       if [ -n "${clst_DISTCC}" ]
        then
-               mythang=$( cd /etc/env.d/binutils; ls ${clst_CHOST}-* | head -n 1 )
-               if [ -z "${mythang}" ]
-               then
-                       mythang=1
-               fi
-               binutils-config ${mythang}; update_env_settings
+               cleanup_distcc
+       fi
+       if [ -n "${clst_ICECREAM}" ]
+       then
+               cleanup_icecream
        fi
+       case ${clst_target} in
+               stage3|system)
+                       run_merge --depclean --with-bdeps=y
+                       ;;
+               *)
+                       echo "Skipping depclean operation for ${clst_target}"
+                       ;;
+       esac
+       case ${clst_target} in
+               stage1|stage2|stage3|system)
+                       rm -f /var/lib/portage/world
+                       touch /var/lib/portage/world
+                       ;;
+               *)
+                       echo "Skipping removal of world file for ${clst_target}"
+                       ;;
+       esac
+
+       rm -f /var/log/emerge.log /var/log/portage/elog/*
 }
 
 update_env_settings(){
-       /usr/sbin/env-update
+       [ -x /usr/sbin/env-update ] && /usr/sbin/env-update
        source /etc/profile
        [ -f /tmp/envscript ] && source /tmp/envscript
 }
@@ -133,28 +243,35 @@ die() {
 }
 
 make_destpath() {
-       if  [ "${1}" = "" ]
+       # ROOT is / by default, so remove any ROOT= settings from make.conf
+       sed -i '/ROOT=/d' /etc/portage/make.conf
+       export ROOT=/
+       if [ "${1}" != "/" -a -n "${1}" ]
        then
-               export ROOT=/
-       else
+               echo "ROOT=\"${1}\"" >> /etc/portage/make.conf
                export ROOT=${1}
-               if [ ! -d ${ROOT} ]
-               then
-                       install -d ${ROOT}
-               fi
+       fi
+       if [ ! -d ${ROOT} ]
+       then
+               install -d ${ROOT}
        fi
 }
 
-run_emerge() {
-
+run_merge() {
        # Sets up the ROOT= parameter
        # with no options ROOT=/
        make_destpath ${clst_root_path}
-       
+
+       export EMERGE_WARNING_DELAY=0
+       export CLEAN_DELAY=0
+       export EBEEP_IGNORE=0
+       export EPAUSE_IGNORE=0
+       export CONFIG_PROTECT="-*"
+
        if [ -n "${clst_VERBOSE}" ]
        then
-               echo "ROOT=${ROOT} emerge ${clst_myemergeopts} -vpt $@" || exit 1
-               emerge ${clst_myemergeopts} -vpt $@ || exit 3
+               echo "ROOT=${ROOT} emerge ${clst_myemergeopts} -pt $@" || exit 1
+               emerge ${clst_myemergeopts} -pt $@ || exit 3
                echo "Press any key within 15 seconds to pause the build..."
                read -s -t 15 -n 1
                if [ $? -eq 0 ]
@@ -166,23 +283,60 @@ run_emerge() {
 
        echo "emerge ${clst_myemergeopts} $@" || exit 1
 
-       if [ -n "${clst_FETCH}" ]
+       emerge ${clst_myemergeopts} $@ || exit 1
+}
+
+show_debug() {
+       if [ "${clst_DEBUG}" = "1" ]
        then
-               export bootstrap_opts="-f"
-               emerge ${clst_myemergeopts} -f $@ || exit 1
+               unset PACKAGES
+               echo "DEBUG:"
+               echo "Profile/target info:"
+               echo "Profile inheritance:"
+               python -c 'import portage; print(portage.settings.profiles)'
+               echo
+               # TODO: make this work on non-portage
+               emerge --info
+               # TODO: grab our entire env
+               # <zmedico> to get see the ebuild env you can do something like:
+               # `set > /tmp/env_dump.${EBUILD_PHASE}` inside /etc/portage/bashrc
+               # XXX: Also, portageq does *not* source profile.bashrc at any time.
+               echo
+               echo "BOOTSTRAP_USE:            $(portageq envvar BOOTSTRAP_USE)"
+               echo
+               echo "USE (profile):         $(portageq envvar USE)"
+               echo "FEATURES (profile):    $(portageq envvar FEATURES)"
+               echo
+               echo "ARCH:                  $(portageq envvar ARCH)"
+               echo "CHOST:                 $(portageq envvar CHOST)"
+               echo "CFLAGS:                $(portageq envvar CFLAGS)"
+               echo
+               echo "These should be blank on non-multilib profiles."
+               echo "ABI:                   $(portageq envvar ABI)"
+               echo "DEFAULT_ABI:           $(portageq envvar DEFAULT_ABI)"
+               echo "KERNEL_ABI:            $(portageq envvar KERNEL_ABI)"
+               echo "LIBDIR:                $(get_libdir)"
+               echo "MULTILIB_ABIS:         $(portageq envvar MULTILIB_ABIS)"
+               echo "PROFILE_ARCH:          $(portageq envvar PROFILE_ARCH)"
+               echo
        fi
+}
 
-       emerge ${clst_myemergeopts} $@ || exit 1
+run_default_funcs() {
+       if [ "${RUN_DEFAULT_FUNCS}" != "no" ]
+       then
+               update_env_settings
+               setup_myfeatures
+               show_debug
+       fi
 }
 
 # Functions
 # Copy libs of a executable in the chroot
 function copy_libs() {
-
        # Check if it's a dynamix exec
-
        ldd ${1} > /dev/null 2>&1 || return
-       
+
        for lib in `ldd ${1} | awk '{ print $3 }'`
        do
                echo ${lib}
@@ -191,7 +345,9 @@ function copy_libs() {
                        if [ ! -e ${clst_root_path}/${lib} ]
                        then
                                copy_file ${lib}
-                               [ -e "${clst_root_path}/${lib}" ] && strip -R .comment -R .note ${clst_root_path}/${lib} || echo "WARNING : Cannot strip lib ${clst_root_path}/${lib} !"
+                               [ -e "${clst_root_path}/${lib}" ] && \
+                               strip -R .comment -R .note ${clst_root_path}/${lib} \
+                               || echo "WARNING : Cannot strip lib ${clst_root_path}/${lib} !"
                        fi
                else
                        echo "WARNING : Some library was not found for ${lib} !"
@@ -200,30 +356,34 @@ function copy_libs() {
 }
 
 function copy_symlink() {
-
        STACK=${2}
        [ "${STACK}" = "" ] && STACK=16 || STACK=$((${STACK} - 1 ))
 
-       if [ ${STACK} -le 0 ] 
+       if [ ${STACK} -le 0 ]
        then
                echo "WARNING : ${TARGET} : too many levels of symbolic links !"
                return
        fi
 
-       [ ! -e ${clst_root_path}/`dirname ${1}` ] && mkdir -p ${clst_root_path}/`dirname ${1}`
-       [ ! -e ${clst_root_path}/${1} ] && cp -vfdp ${1} ${clst_root_path}/${1}
-       
-       TARGET=`readlink -f ${1}`
+       [ ! -e ${clst_root_path}/`dirname ${1}` ] && \
+               mkdir -p ${clst_root_path}/`dirname ${1}`
+       [ ! -e ${clst_root_path}/${1} ] && \
+               cp -vfdp ${1} ${clst_root_path}/${1}
+
+       if [[ -n $(type -p realpath) ]]; then
+               TARGET=`realpath ${1}`
+       else
+               TARGET=`readlink -f ${1}`
+       fi
        if [ -h ${TARGET} ]
        then
                copy_symlink ${TARGET} ${STACK}
        else
                copy_file ${TARGET}
        fi
-       }               
+}
 
 function copy_file() {
-
        f="${1}"
 
        if [ ! -e "${f}" ]
@@ -232,8 +392,10 @@ function copy_file() {
                continue
        fi
 
-       [ ! -e ${clst_root_path}/`dirname ${f}` ] && mkdir -p ${clst_root_path}/`dirname ${f}`
-       [ ! -e ${clst_root_path}/${f} ] && cp -vfdp ${f} ${clst_root_path}/${f}
+       [ ! -e ${clst_root_path}/`dirname ${f}` ] && \
+               mkdir -p ${clst_root_path}/`dirname ${f}`
+       [ ! -e ${clst_root_path}/${f} ] && \
+               cp -vfdp ${f} ${clst_root_path}/${f}
        if [ -x ${f} -a ! -h ${f} ]
        then
                copy_libs ${f}
@@ -243,3 +405,20 @@ function copy_file() {
                copy_symlink ${f}
        fi
 }
+
+create_handbook_icon() {
+       # This function creates a local icon to the Gentoo Handbook
+       echo "[Desktop Entry]
+Encoding=UTF-8
+Version=1.0
+Type=Link
+URL=file:///mnt/cdrom/docs/handbook/html/index.html
+Terminal=false
+Name=Gentoo Linux Handbook
+GenericName=Gentoo Linux Handbook
+Comment=This is a link to the local copy of the Gentoo Linux Handbook.
+Icon=text-editor" > /usr/share/applications/gentoo-handbook.desktop
+}
+
+# We do this everywhere, so why not put it in this script
+run_default_funcs