From: Jeremy Huddleston Date: Mon, 10 Jan 2005 11:18:57 +0000 (+0000) Subject: Moved src_install, pkg_preinst, and pkg_postinst into eclass using gcc-3.3.5-r1 and... X-Git-Url: http://git.tremily.us/?a=commitdiff_plain;h=b237c90d5df465bd2183ff63af294f630fd8b922;p=gentoo.git Moved src_install, pkg_preinst, and pkg_postinst into eclass using gcc-3.3.5-r1 and gcc-3.4.3-r1 as a base. Made env.d script creation more abstract. Fixed up multilib support. Fixed some problems moving libs to incorrect destinations or not moving some libs. Fixed a few cross-compilation problems (but not all yet). Closes bug #76884. --- diff --git a/eclass/toolchain.eclass b/eclass/toolchain.eclass index b36c17c5e65d..3a676a885e5e 100644 --- a/eclass/toolchain.eclass +++ b/eclass/toolchain.eclass @@ -1,18 +1,17 @@ # Copyright 1999-2004 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/eclass/toolchain.eclass,v 1.71 2005/01/09 18:47:17 kumba Exp $ - +# $Header: /var/cvsroot/gentoo-x86/eclass/toolchain.eclass,v 1.72 2005/01/10 11:18:57 eradicator Exp $ HOMEPAGE="http://www.gnu.org/software/gcc/gcc.html" LICENSE="GPL-2 LGPL-2.1" - #---->> eclass stuff <<---- inherit eutils versionator libtool ECLASS=toolchain INHERITED="$INHERITED $ECLASS" DESCRIPTION="Based on the ${ECLASS} eclass" -EXPORT_FUNCTIONS src_unpack pkg_setup src_compile src_install +EXPORT_FUNCTIONS pkg_setup src_unpack src_compile src_install pkg_preinst pkg_postinst +FEATURES="${FEATURES/multilib-strict/}" toolchain_src_install() { ${ETYPE}-src_install @@ -26,6 +25,12 @@ toolchain_src_unpack() { toolchain_pkg_setup() { gcc_pkg_setup } +toolchain_pkg_preinst() { + ${ETYPE}-pkg_preinst +} +toolchain_pkg_postinst() { + ${ETYPE}-pkg_postinst +} #----<< eclass stuff >>---- @@ -92,6 +97,8 @@ elif [ "${GCC_VAR_TYPE}" == "non-versioned" ] ; then DATAPATH="${DATAPATH:="${PREFIX}/share/"}" STDCXX_INCDIR="${STDCXX_INCDIR:="${PREFIX}/include/g++-v3/"}" fi + +XGCC="${WORKDIR}/build/gcc/xgcc" #----<< globals >>---- @@ -407,7 +414,7 @@ glibc_have_pie() { # smashing protection support. libc_has_ssp() { local libc_prefix - use ppc64 && libc_prefix="/lib64/" + [ "${ARCH}" = "ppc64" -a -z "${ABI}" ] && libc_prefix="/lib64/" libc_prefix="${libc_prefix:="/$(get_libdir)/"}" echo 'int main(){}' > ${T}/libctest.c @@ -445,8 +452,6 @@ gcc-lang-supported() { #----<< support checks >>---- - - #---->> specs + env.d logic <<---- # configure to build with the hardened GCC specs as the default @@ -589,29 +594,24 @@ create_gcc_env_entry() { echo "PATH=\"${BINPATH}\"" > ${gcc_envd_file} echo "ROOTPATH=\"${BINPATH}\"" >> ${gcc_envd_file} - # Thanks to multilib, setting ldpath just got a little bit nuttier. - use amd64 && multilib_dirnames="32" - # we dont support this kind of amd64 multilib - #use x86 && multilib_dirnames="64" - # I'm unsure which of these is the default, so lets add both - use ppc64 && multilib_dirnames="64 32" - # same here. - use mips && multilib_dirnames="o32 32 64" - # in theory, sparc can have either as default, so add both - use sparc && multilib_dirnames="64 32" - LDPATH="${LIBPATH}" - if [ -n "${multilib_dirnames}" ] ; then - for path in ${multilib_dirnames} ; do - LDPATH="${LDPATH}:${LIBPATH}/${path}" + if [ -n "${MULTILIB_ABIS}" ]; then + local abi= + for abi in ${MULTILIB_ABIS}; do + local MULTIDIR=$(${XGCC} $(get_abi_CFLAGS ${abi}) --print-multi-directory) + [ "${MULTIDIR}" != "." -a -d "${LIBPATH}/${MULTIDIR}" ] && LDPATH="${LDPATH}:${LIBPATH}/${MULTIDIR}" + done + else + for path in 32 64 o32; do + [ -d "${LIBPATH}/${path}" ] && LDPATH="${LDPATH}:${LIBPATH}/${path}" done fi local mbits= - has_m32 && mbits="${mbits} 32" - has_m64 && mbits="${mbits} 64" - echo "GCCBITS=\"${mbits}\"" >> ${gcc_envd_file} + CC=${XGCC} has_m32 && mbits="${mbits} 32" + CC=${XGCC} has_m64 && mbits="${mbits} 64" + echo "GCCBITS=\"${mbits:1}\"" >> ${gcc_envd_file} echo "LDPATH=\"${LDPATH}\"" >> ${gcc_envd_file} echo "MANPATH=\"${DATAPATH}/man\"" >> ${gcc_envd_file} @@ -628,10 +628,7 @@ create_gcc_env_entry() { #----<< specs + env.d logic >>---- - - -#---->> unorganised crap in need of refactoring follows - +#---->> pkg_* <<---- gcc_pkg_setup() { if [ "${ETYPE}" == "gcc-compiler" ] ; then # Must compile for mips64-linux target if we want n32/n64 support @@ -659,406 +656,158 @@ gcc_pkg_setup() { die "libssp cannot be used with a glibc that has been patched to provide ssp symbols" } +gcc-compiler_pkg_preinst() { + if [ ! -f "${WORKDIR}/.chkgccversion" ] + then + mkdir -p ${WORKDIR} + chk_gcc_version + fi -# gcc_quick_unpack will unpack the gcc tarball and patches in a way that is -# consistant with the behavior of get_gcc_src_uri. The only patch it applies -# itself is the branch update if present. -# -# Travis Tilley (03 Sep 2004) -# -gcc_quick_unpack() { - pushd ${WORKDIR} > /dev/null + export LD_LIBRARY_PATH="${LIBPATH}:${LD_LIBRARY_PATH}" + ${ROOT}/sbin/ldconfig +} - if [ -n "${PRERELEASE}" ] ; then - unpack gcc-${PRERELEASE}.tar.bz2 - elif [ -n "${SNAPSHOT}" ] ; then - unpack gcc-${SNAPSHOT}.tar.bz2 - else - unpack gcc-${MAIN_BRANCH}.tar.bz2 - # We want branch updates to be against a release tarball - if [ -n "${BRANCH_UPDATE}" ] ; then - pushd ${S:="$(gcc_get_s_dir)"} > /dev/null - epatch ${DISTDIR}/gcc-${MAIN_BRANCH}-branch-update-${BRANCH_UPDATE}.patch.bz2 - popd > /dev/null - fi - fi +gcc-compiler-pkg_postinst() { + export LD_LIBRARY_PATH="${LIBPATH}:${LD_LIBRARY_PATH}" + should_we_gcc_config && do_gcc_config - if [ -n "${PATCH_VER}" ] + # Update libtool linker scripts to reference new gcc version ... + if [ "${ROOT}" = "/" ] && \ + [ -f "${WORKDIR}/.oldgccversion" -o -f "${WORKDIR}/.oldgccchost" ] then - unpack ${PN}-${PATCH_GCC_VER:=${PV}}-patches-${PATCH_VER}.tar.bz2 - fi + local OLD_GCC_VERSION= + local OLD_GCC_CHOST= - if [ -n "${PP_VER}" ] - then - # The gcc 3.4 propolice versions are meant to be unpacked to ${S} - pushd ${S:="$(gcc_get_s_dir)"} > /dev/null - unpack protector-${PP_FVER}.tar.gz - popd > /dev/null - fi + if [ -f "${WORKDIR}/.oldgccversion" ] && \ + [ -n "$(cat "${WORKDIR}/.oldgccversion")" ] + then + OLD_GCC_VERSION="$(cat "${WORKDIR}/.oldgccversion")" + else + OLD_GCC_VERSION="${MY_PV_FULL}" + fi - if [ -n "${PIE_VER}" ] - then - unpack ${PIE_CORE} - fi + if [ -f "${WORKDIR}/.oldgccchost" ] && \ + [ -n "$(cat "${WORKDIR}/.oldgccchost")" ] + then + OLD_GCC_CHOST="--oldarch $(cat "${WORKDIR}/.oldgccchost")" + fi - # pappy@gentoo.org - Fri Oct 1 23:24:39 CEST 2004 - if want_boundschecking - then - unpack "bounds-checking-${PN}-${HTB_GCC_VER:=${PV}}-${HTB_VER}.patch.bz2" + /sbin/fix_libtool_files.sh ${OLD_GCC_VERSION} ${OLD_GCC_CHOST} fi - - popd > /dev/null } -# Exclude any unwanted patches, as specified by the following variables: -# -# GENTOO_PATCH_EXCLUDE -# List of filenames, relative to ${WORKDIR}/patch/ +#---->> pkg_* <<---- + +#---->> src_* <<---- + +# generic GCC src_unpack, to be called from the ebuild's src_unpack. +# BIG NOTE regarding hardened support: ebuilds with support for hardened are +# expected to export the following variable: # -# PIEPATCH_EXCLUDE -# List of filenames, relative to ${WORKDIR}/piepatch/ +# HARDENED_GCC_WORKS +# This variable should be set to the archs on which hardened should +# be allowed. For example: HARDENED_GCC_WORKS="x86 sparc amd64" +# This allows for additional archs to be supported by hardened when +# ready. # # Travis Tilley (03 Sep 2004) # -exclude_gcc_patches() { - local i - for i in ${GENTOO_PATCH_EXCLUDE} ; do - if [ -f ${WORKDIR}/patch/${i} ] ; then - einfo "Excluding patch ${i}" - rm -f ${WORKDIR}/patch/${i} || die "failed to delete ${i}" - fi - done - for i in ${PIEPATCH_EXCLUDE} ; do - if [ -f ${WORKDIR}/piepatch/${i} ] ; then - einfo "Excluding piepatch ${i}" - rm -f ${WORKDIR}/piepatch/${i} || die "failed to delete ${i}" +gcc-compiler-src_unpack() { + # fail if using pie patches, building hardened, and glibc doesnt have + # the necessary support + [ -n "${PIE_VER}" ] && use hardened && glibc_have_pie + + if ! want_boundschecking ; then + if use hardened ; then + einfo "updating configuration to build hardened GCC" + make_gcc_hard || die "failed to make gcc hard" fi - done + fi } - -do_gcc_HTB_boundschecking_patches() { - # modify the bounds checking patch with a regression patch - epatch "${WORKDIR}/bounds-checking-${PN}-${HTB_GCC_VER:=${PV}}-${HTB_VER}.patch" - release_version="${release_version}, HTB-${HTB_VER}" +gcc-library-src_unpack() { + : } +gcc_src_unpack() { + local release_version="Gentoo Linux ${PVR}" -# patch in ProPolice Stack Smashing protection -do_gcc_SSP_patches() { - local ssppatch - local sspdocs + gcc_quick_unpack + exclude_gcc_patches - # Etoh keeps changing where files are and what the patch is named - if version_is_at_least 3.4.1 ; then - # >3.4.1 uses version in patch name, and also includes docs - ssppatch="${S}/gcc_${PP_VER}.dif" - sspdocs="yes" - elif version_is_at_least 3.4.0 ; then - # >3.4 put files where they belong and 3_4 uses old patch name - ssppatch="${S}/protector.dif" - sspdocs="no" - elif version_is_at_least 3.2.3 ; then - # earlier versions have no directory structure or docs - mv ${S}/protector.{c,h} ${S}/gcc - ssppatch="${S}/protector.dif" - sspdocs="no" - else - die "gcc version not supported by do_gcc_SSP_patches" + cd ${S:="$(gcc_get_s_dir)"} + + if [ -n "${PATCH_VER}" ] ; then + epatch ${WORKDIR}/patch fi - epatch ${ssppatch} + if ! want_boundschecking ; then + if [ "${ARCH}" != "hppa" -a "${ARCH}" != "hppa64" -a -n "${PP_VER}" ] ; then + do_gcc_SSP_patches + fi - if [ "${PN}" == "gcc" -a "${sspdocs}" == "no" ] ; then - epatch ${FILESDIR}/pro-police-docs.patch + if [ -n "${PIE_VER}" ] ; then + do_gcc_PIE_patches + fi + else + if [ -n "${HTB_VER}" ] ; then + do_gcc_HTB_boundschecking_patches + fi fi - # we apply only the needed parts of protectonly.dif - sed -e 's|^CRTSTUFF_CFLAGS = |CRTSTUFF_CFLAGS = -fno-stack-protector-all |'\ - -i gcc/Makefile.in || die "Failed to update crtstuff!" + ${ETYPE}-src_unpack || die "failed to ${ETYPE}-src_unpack" - # if gcc in a stage3 defaults to ssp, is version 3.4.0 and a stage1 is built - # the build fails building timevar.o w/: - # cc1: stack smashing attack in function ix86_split_to_parts() - if gcc -dumpspecs | grep -q "fno-stack-protector:" && version_is_at_least 3.4.0 && ! version_is_at_least 4.0.0 && [ -f ${FILESDIR}/3.4.0/gcc-3.4.0-cc1-no-stack-protector.patch ] ; then - use build && epatch ${FILESDIR}/3.4.0/gcc-3.4.0-cc1-no-stack-protector.patch + if [ "${ARCH}" = "amd64" -a -z "${SKIP_MULTILIB_HACK}" ] && use multilib; then + disgusting_gcc_multilib_HACK || die "multilib hack failed" fi - release_version="${release_version}, ssp-${PP_FVER}" - if want_libssp ; then - update_gcc_for_libssp - else - update_gcc_for_libc_ssp - fi -} + einfo "patching gcc version: ${BRANCH_UPDATE} (${release_version})" + gcc_version_patch "${BRANCH_UPDATE} (${release_version})" -# If glibc or uclibc has been patched to provide the necessary symbols itself, -# then lets use those for SSP instead of libgcc. -update_gcc_for_libc_ssp() { - if libc_has_ssp ; then - einfo "Updating gcc to use SSP from libc ..." - sed -e 's|^\(LIBGCC2_CFLAGS.*\)$|\1 -D_LIBC_PROVIDES_SSP_|' \ - -i ${S}/gcc/Makefile.in || die "Failed to update gcc!" - fi -} + # Misdesign in libstdc++ (Redhat) + cp -a ${S}/libstdc++-v3/config/cpu/i{4,3}86/atomicity.h -# a split out non-libc non-libgcc ssp requires additional spec logic changes -update_gcc_for_libssp() { - einfo "Updating gcc to use SSP from libssp..." - sed -e 's|^\(INTERNAL_CFLAGS.*\)$|\1 -D_LIBSSP_PROVIDES_SSP_|' \ - -i ${S}/gcc/Makefile.in || die "Failed to update gcc!" -} + # disable --as-needed from being compiled into gcc specs + # natively when using >=sys-devel/binutils-2.15.90.0.1 this is + # done to keep our gcc backwards compatible with binutils. + # gcc 3.4.1 cvs has patches that need back porting.. + # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14992 (May 3 2004) + sed -i -e s/HAVE_LD_AS_NEEDED/USE_LD_AS_NEEDED/g ${S}/gcc/config.in -# do various updates to PIE logic -do_gcc_PIE_patches() { - # corrects startfile/endfile selection and shared/static/pie flag usage - epatch ${WORKDIR}/piepatch/upstream - # adds non-default pie support (rs6000) - epatch ${WORKDIR}/piepatch/nondef - # adds default pie support (rs6000 too) if DEFAULT_PIE[_SSP] is defined - epatch ${WORKDIR}/piepatch/def - # disable relro/now - #use uclibc && epatch ${FILESDIR}/3.3.3/gcc-3.3.3-norelro.patch + # Fixup libtool to correctly generate .la files with portage + cd ${S} + elibtoolize --portage --shallow - # we want to be able to control the pie patch logic via something other - # than ALL_CFLAGS... - sed -e '/^ALL_CFLAGS/iHARD_CFLAGS = ' \ - -e 's|^ALL_CFLAGS = |ALL_CFLAGS = $(HARD_CFLAGS) |' \ - -i ${S}/gcc/Makefile.in + gnuconfig_update - release_version="${release_version}, pie-${PIE_VER}" + cd ${S}; ./contrib/gcc_update --touch &> /dev/null + + disable_multilib_libjava || die "failed to disable multilib java" } -should_we_gcc_config() { - # we only want to switch compilers if installing to / and we're not - # building a cross-compiler. - ! [ "${ROOT}" == "/" -a "${CHOST}" == "${CTARGET}" ] && return 1 +gcc-library-configure() { + # multilib support + if [ "${GCC_TARGET_NO_MULTILIB}" == "true" ] + then + confgcc="${confgcc} --disable-multilib" + else + confgcc="${confgcc} --enable-multilib" + fi +} - # we always want to run gcc-config if we're bootstrapping, otherwise - # we might get stuck with the c-only stage1 compiler - use bootstrap && return 0 - use build && return 0 +gcc-compiler-configure() { + # multilib support + case "${ARCH}" in + amd64|mips|sparc) + confgcc="${confgcc} $(use_enable multilib)" + ;; + esac - # if the current config is invalid, we definately want a new one - [ "$(gcc-config -L | grep -v ^\ )" == "no-config" ] && return 0 - - # if the previously selected config has the same major.minor as the - # version we are installing, then it will probably be uninstalled - # for being in the same SLOT. we cannot rely on the previous check - # to handle this, since postinst sometimes happens BEFORE the - # previous version is removed. :| - # ...skip this check if the current version is -exactly- the same - local c_gcc_conf_ver=$(gcc-config -c | awk -F - '{ print $5 }') - local c_majmin=$(get_version_component_range 1-2 ${c_gcc_conf_ver}) - if [ "${c_gcc_conf_ver}" != "${MY_PV_FULL}" ] ; then - if [ "${c_majmin}" == "${MY_PV}" ] ;then - return 0 - else - # if we're installing a genuinely different compiler version, - # we should probably tell the user -how- to switch to the new - # gcc version, since we're not going to do it for him/her. - einfo "The current gcc config appears valid, so it will not be" - einfo "automatically switched for you. If you would like to" - einfo "switch to the newly installed gcc version, do the" - einfo "following:" - echo - einfo "gcc-config ${CTARGET}-${MY_PV_FULL}" - einfo "source /etc/profile" - echo - ebeep - return 1 - fi - else - # since we are re-merging the same gcc version, it's safe to re-run - # gcc-config and update any new wrappers, etc. - return 0 - fi - - # default to -not- switching gcc configs. this is to prevent an - # annoying bug where doing an emerge world -e with multiple slotted - # compilers will compile some apps with one and others with another. - return 1 -} - -do_gcc_config() { - # the grep -v is in there to filter out informational messages >_< - local current_gcc_config="$(gcc-config -c | grep -v ^\ )" - - # figure out which specs-specific config is active. yes, this works - # even if the current config is invalid. - local current_specs="$(echo ${current_gcc_config} | awk -F - '{ print $6 }')" - [ "${current_specs}" != "" ] && local use_specs="-${current_specs}" - - - if [ -n "${use_specs}" -a ! -e ${ROOT}/etc/env.d/gcc/${CTARGET}-${MY_PV_FULL}${use_specs} ] ; then - ewarn "The currently selected specs-specific gcc config," - ewarn "${current_specs}, doesn't exist anymore. This is usually" - ewarn "due to enabling/disabling hardened or switching to a version" - ewarn "of gcc that doesnt create multiple specs files. The default" - ewarn "config will be used, and the previous preference forgotten." - ebeep - epause - fi - - - if [ -e ${ROOT}/etc/env.d/gcc/${CTARGET}-${MY_PV_FULL}${use_specs} ] ; then - # we dont want to lose the current specs setting! - gcc-config ${CTARGET}-${MY_PV_FULL}${use_specs} - else - # ...unless of course the specs-specific entry doesnt exist :) - gcc-config --use-portage-chost ${CTARGET}-${MY_PV_FULL} - fi -} - -# This function allows us to gentoo-ize gcc's version number and bugzilla -# URL without needing to use patches. -# -# Travis Tilley (02 Sep 2004) -# -gcc_version_patch() { - [ -z "$1" ] && die "no arguments to gcc_version_patch" - - sed -i -e 's~\(const char version_string\[\] = ".....\).*\(".*\)~\1 @GENTOO@\2~' ${S}/gcc/version.c || die "failed to add @GENTOO@" - sed -i -e "s:@GENTOO@:$1:g" ${S}/gcc/version.c || die "failed to patch version" - sed -i -e 's~http:\/\/gcc\.gnu\.org\/bugs\.html~http:\/\/bugs\.gentoo\.org\/~' ${S}/gcc/version.c || die "failed to update bugzilla URL" -} - -# The purpose of this DISGUSTING gcc multilib hack is to allow 64bit libs -# to live in lib instead of lib64 where they belong, with 32bit libraries -# in lib32. This hack has been around since the beginning of the amd64 port, -# and we're only now starting to fix everything that's broken. Eventually -# this should go away. -# -# Travis Tilley (03 Sep 2004) -# -disgusting_gcc_multilib_HACK() { - einfo "updating multilib directories to be: $(get_all_libdirs)" - local libdirs - for libdir in $(get_all_libdirs); do - libdirs="${libdirs} ../${libdir}" - done - sed -i -e "s:^MULTILIB_OSDIRNAMES.*:MULTILIB_OSDIRNAMES = ${libdirs}:" ${S}/gcc/config/i386/t-linux64 -} - -disable_multilib_libjava() { - # We dont want a multilib libjava, so lets use this hack taken from fedora - pushd ${S} > /dev/null - sed -i -e 's/^all: all-redirect/ifeq (\$(MULTISUBDIR),)\nall: all-redirect\nelse\nall:\n\techo Multilib libjava build disabled\nendif/' libjava/Makefile.in - sed -i -e 's/^install: install-redirect/ifeq (\$(MULTISUBDIR),)\ninstall: install-redirect\nelse\ninstall:\n\techo Multilib libjava install disabled\nendif/' libjava/Makefile.in - sed -i -e 's/^check: check-redirect/ifeq (\$(MULTISUBDIR),)\ncheck: check-redirect\nelse\ncheck:\n\techo Multilib libjava check disabled\nendif/' libjava/Makefile.in - sed -i -e 's/^all: all-recursive/ifeq (\$(MULTISUBDIR),)\nall: all-recursive\nelse\nall:\n\techo Multilib libjava build disabled\nendif/' libjava/Makefile.in - sed -i -e 's/^install: install-recursive/ifeq (\$(MULTISUBDIR),)\ninstall: install-recursive\nelse\ninstall:\n\techo Multilib libjava install disabled\nendif/' libjava/Makefile.in - sed -i -e 's/^check: check-recursive/ifeq (\$(MULTISUBDIR),)\ncheck: check-recursive\nelse\ncheck:\n\techo Multilib libjava check disabled\nendif/' libjava/Makefile.in - popd > /dev/null -} - -# generic GCC src_unpack, to be called from the ebuild's src_unpack. -# BIG NOTE regarding hardened support: ebuilds with support for hardened are -# expected to export the following variable: -# -# HARDENED_GCC_WORKS -# This variable should be set to the archs on which hardened should -# be allowed. For example: HARDENED_GCC_WORKS="x86 sparc amd64" -# This allows for additional archs to be supported by hardened when -# ready. -# -# Travis Tilley (03 Sep 2004) -# -gcc-compiler-src_unpack() { - # fail if using pie patches, building hardened, and glibc doesnt have - # the necessary support - [ -n "${PIE_VER}" ] && use hardened && glibc_have_pie - - if ! want_boundschecking ; then - if use hardened ; then - einfo "updating configuration to build hardened GCC" - make_gcc_hard || die "failed to make gcc hard" - fi - fi -} -gcc-library-src_unpack() { - : -} -gcc_src_unpack() { - local release_version="Gentoo Linux ${PVR}" - - gcc_quick_unpack - exclude_gcc_patches - - cd ${S:="$(gcc_get_s_dir)"} - - if [ -n "${PATCH_VER}" ] ; then - epatch ${WORKDIR}/patch - fi - - if ! want_boundschecking ; then - if [ "${ARCH}" != "hppa" -a "${ARCH}" != "hppa64" -a -n "${PP_VER}" ] ; then - do_gcc_SSP_patches - fi - - if [ -n "${PIE_VER}" ] ; then - do_gcc_PIE_patches - fi - else - if [ -n "${HTB_VER}" ] ; then - do_gcc_HTB_boundschecking_patches - fi - fi - - ${ETYPE}-src_unpack || die "failed to ${ETYPE}-src_unpack" - - if use amd64 && [ -z "${SKIP_MULTILIB_HACK}" ] ; then - disgusting_gcc_multilib_HACK || die "multilib hack failed" - fi - - einfo "patching gcc version: ${BRANCH_UPDATE} (${release_version})" - gcc_version_patch "${BRANCH_UPDATE} (${release_version})" - - # Misdesign in libstdc++ (Redhat) - cp -a ${S}/libstdc++-v3/config/cpu/i{4,3}86/atomicity.h - - # disable --as-needed from being compiled into gcc specs - # natively when using >=sys-devel/binutils-2.15.90.0.1 this is - # done to keep our gcc backwards compatible with binutils. - # gcc 3.4.1 cvs has patches that need back porting.. - # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14992 (May 3 2004) - sed -i -e s/HAVE_LD_AS_NEEDED/USE_LD_AS_NEEDED/g ${S}/gcc/config.in - - # Fixup libtool to correctly generate .la files with portage - cd ${S} - elibtoolize --portage --shallow - - gnuconfig_update - - cd ${S}; ./contrib/gcc_update --touch &> /dev/null - - disable_multilib_libjava || die "failed to disable multilib java" -} - -gcc-library-configure() { - # multilib support - if [ "${GCC_TARGET_NO_MULTILIB}" == "true" ] - then - confgcc="${confgcc} --disable-multilib" - else - confgcc="${confgcc} --enable-multilib" - fi -} - -gcc-compiler-configure() { - # multilib support - if use multilib && (use amd64 || use mips || use sparc) - then - confgcc="${confgcc} --enable-multilib" - else - confgcc="${confgcc} --disable-multilib" - fi - - # GTK+ is preferred over xlib in 3.4.x (xlib is unmaintained - # right now). Much thanks to for the heads up. - # Travis Tilley (11 Jul 2004) - if ! use build && use gcj && use gtk - then - confgcc="${confgcc} --enable-java-awt=gtk" - fi + # GTK+ is preferred over xlib in 3.4.x (xlib is unmaintained + # right now). Much thanks to for the heads up. + # Travis Tilley (11 Jul 2004) + if ! use build && use gcj && use gtk + then + confgcc="${confgcc} --enable-java-awt=gtk" + fi use build || use !gcj && confgcc="${confgcc} --disable-libgcj" @@ -1190,10 +939,6 @@ gcc_do_configure() { confgcc="${confgcc} --enable-shared --enable-threads=posix" fi - # default arch support - #use sparc && confgcc="${confgcc} --with-cpu=v7" - #use ppc && confgcc="${confgcc} --with-cpu=common" - # etype specific configuration einfo "running ${ETYPE}-configure" ${ETYPE}-configure || die @@ -1279,7 +1024,7 @@ gcc_do_make() { # 3 stage bootstrapping doesnt quite work when you cant run the # resulting binaries natively ^^; GCC_MAKE_TARGET="${GCC_MAKE_TARGET:=all}" - elif use x86 || use amd64 || use ppc64 ; then + elif use x86 || use amd64 || use ppc64; then GCC_MAKE_TARGET="${GCC_MAKE_TARGET:=profiledbootstrap}" else GCC_MAKE_TARGET="${GCC_MAKE_TARGET:=bootstrap-lean}" @@ -1342,6 +1087,12 @@ gcc_do_filter_flags() { # ...sure, why not? strip-unsupported-flags + + filter-flags "-mabi*" + filter-flags "-m32" + filter-flags "-m64" + + export GCJFLAGS="${CFLAGS}" } gcc_src_compile() { @@ -1421,3 +1172,622 @@ gcc-library-src_install() { } +gcc-compiler-src_install() { + local x= + + # Do allow symlinks in ${PREFIX}/lib/gcc-lib/${CHOST}/${PV}/include as + # this can break the build. + for x in ${WORKDIR}/build/gcc/include/* + do + if [ -L ${x} ] + then + rm -f ${x} + continue + fi + done + # Remove generated headers, as they can cause things to break + # (ncurses, openssl, etc). + for x in `find ${WORKDIR}/build/gcc/include/ -name '*.h'` + do + if grep -q 'It has been auto-edited by fixincludes from' ${x} + then + rm -f ${x} + fi + done + + einfo "Installing GCC..." + # Do the 'make install' from the build directory + cd ${WORKDIR}/build + S="${WORKDIR}/build" \ + make DESTDIR="${D}" install || die + + if [ "${CHOST}" == "${CTARGET}" ] ; then + [ -r ${D}${BINPATH}/gcc ] || die "gcc not found in ${D}" + fi + + dodir /lib /usr/bin + dodir /etc/env.d/gcc + create_gcc_env_entry + + if want_split_specs ; then + if use hardened ; then + create_gcc_env_entry vanilla + fi + use !hardened && hardened_gcc_works && create_gcc_env_entry hardened + if hardened_gcc_works || hardened_gcc_works pie ; then + create_gcc_env_entry hardenednossp + fi + if hardened_gcc_works || hardened_gcc_works ssp ; then + create_gcc_env_entry hardenednopie + fi + + cp ${WORKDIR}/build/*.specs ${D}/${LIBPATH} + fi + + # Move the libraries to the proper location + gcc_movelibs + + # Make sure we dont have stuff lying around that + # can nuke multiple versions of gcc + if ! use build; then + cd ${D}${LIBPATH} + + # Move Java headers to compiler-specific dir + for x in ${D}${PREFIX}/include/gc*.h ${D}${PREFIX}/include/j*.h + do + [ -f "${x}" ] && mv -f ${x} ${D}${LIBPATH}/include/ + done + for x in gcj gnu java javax org + do + if [ -d "${D}${PREFIX}/include/${x}" ] + then + dodir /${LIBPATH}/include/${x} + mv -f ${D}${PREFIX}/include/${x}/* ${D}${LIBPATH}/include/${x}/ + rm -rf ${D}${PREFIX}/include/${x} + fi + done + + if [ -d "${D}${PREFIX}/lib/security" ] + then + dodir /${LIBPATH}/security + mv -f ${D}${PREFIX}/lib/security/* ${D}${LIBPATH}/security + rm -rf ${D}${PREFIX}/lib/security + fi + + # Move libgcj.spec to compiler-specific directories + [ -f "${D}${PREFIX}/lib/libgcj.spec" ] && \ + mv -f ${D}${PREFIX}/lib/libgcj.spec ${D}${LIBPATH}/libgcj.spec + + # Rename jar because it could clash with Kaffe's jar if this gcc is + # primary compiler (aka don't have the - extension) + cd ${D}${PREFIX}/${CTARGET}/gcc-bin/${MY_PV_FULL} + [ -f jar ] && mv -f jar gcj-jar + + # Move to compiler-specific directories + [ -f "${D}${STDCXX_INCDIR}/cxxabi.h" ] && \ + mv -f ${D}${STDCXX_INCDIR}/cxxabi.h ${D}${LIBPATH}/include/ + + # These should be symlinks + cd ${D}${BINPATH} + for x in gcc g++ c++ g77 gcj + do + # For some reason, g77 gets made instead of ${CTARGET}-g77... this makes it safe + if [ -f "${x}" ] + then + mv "${x}" "${CTARGET}-${x}" + fi + + if [ "${CHOST}" == "${CTARGET}" ] && [ -f "${CTARGET}-${x}" ] + then + [ ! -f "${x}" ] && mv "${CTARGET}-${x}" "${x}" + ln -sf ${x} ${CTARGET}-${x} + fi + + if [ -f "${CTARGET}-${x}-${PV}" ] + then + rm -f ${CTARGET}-${x}-${PV} + ln -sf ${CTARGET}-${x} ${CTARGET}-${x}-${PV} + fi + done + + # I do not know if this will break gcj stuff, so I'll only do it for + # objc for now; basically "ffi.h" is the correct file to include, + # but it gets installed in .../GCCVER/include and yet it does + # "#include " which (correctly, as it's an "extra" file) + # is installed in .../GCCVER/include/libffi; the following fixes + # ffi.'s include of ffitarget.h - Armando Di Cianno + if use objc && ! use gcj; then + #dosed "s:::g" /${LIBPATH}/include/ffi.h + mv ${D}/${LIBPATH}/include/libffi/* ${D}/${LIBPATH}/include + rm -Rf ${D}/${LIBPATH}/include/libffi + fi + fi + + cd ${S} + if ! use build && [ "${CHOST}" == "${CTARGET}" ] ; then + prepman ${DATAPATH} + prepinfo ${DATAPATH} + else + rm -rf ${D}/usr/share/{man,info} + rm -rf ${D}${DATAPATH}/{man,info} + fi + + # Rather install the script, else portage with changing $FILESDIR + # between binary and source package borks things .... + if [ "${CHOST}" == "${CTARGET}" ] ; then + insinto /lib/rcscripts/awk + doins ${FILESDIR}/awk/fixlafiles.awk + exeinto /sbin + doexe ${FILESDIR}/fix_libtool_files.sh + fi + + chown -R root:root ${D}${LIBPATH} +} + +# Move around the libs to the right location. +gcc_movelibs() { + # This one comes with binutils + rm -f ${D}${PREFIX}/lib/libiberty.a + rm -f ${D}${PREFIX}/lib/*/libiberty.a + rm -f ${D}${LIBPATH}/libiberty.a + rm -f ${D}${LIBPATH}/*/libiberty.a + + if [ -n "${MULTILIB_ABIS}" ]; then + for abi in ${MULTILIB_ABIS}; do + local OS_MULTIDIR=$(${XGCC} $(get_abi_CFLAGS ${abi}) --print-multi-os-directory) + local MULTIDIR=$(${XGCC} $(get_abi_CFLAGS ${abi}) --print-multi-directory) + local TODIR=${D}/${LIBPATH}/${MULTIDIR} + local FROMDIR= + + [ -d "${TODIR}" ] || mkdir -p ${TODIR} + + FROMDIR=${D}/${LIBPATH}/${OS_MULTIDIR} + if [ "${FROMDIR}" != "${TODIR}" -a -d "${FROMDIR}" ]; then + mv ${FROMDIR}/*.a ${FROMDIR}/*.so* ${FROMDIR}/*.la ${TODIR} &> /dev/null + rmdir ${FROMDIR} &> /dev/null + fi + + FROMDIR=${D}/${LIBPATH}/../${MULTIDIR} + if [ -d "${FROMDIR}" ]; then + mv ${FROMDIR}/*.a ${FROMDIR}/*.so* ${FROMDIR}/*.la ${TODIR} &> /dev/null + rmdir ${FROMDIR} &> /dev/null + fi + + FROMDIR=${D}/${PREFIX}/lib/${OS_MULTIDIR} + if [ -d "${FROMDIR}" ]; then + mv ${FROMDIR}/*.a ${FROMDIR}/*.so* ${FROMDIR}/*.la ${TODIR} &> /dev/null + rmdir ${FROMDIR} &> /dev/null + fi + + FROMDIR=${D}/${PREFIX}/lib/${MULTIDIR} + if [ -d "${FROMDIR}" ]; then + # The only thing that ends up here is libiberty.a (which is deleted) + # Lucky for us nothing mistakenly gets placed here that we need... + # otherwise we'd have a potential conflict when OS_MULTIDIR=../lib and + # MULTIDIR=. for different ABI. If this happens, the fix is to patch + # the gcc Makefiles to behave with LIBDIR properly. + #mv ${FROMDIR}/*.a ${FROMDIR}/*.so* ${FROMDIR}/*.la ${TODIR} &> /dev/null + rmdir ${FROMDIR} &> /dev/null + fi + done + else + # No multilib or older multilib... + + # we dont want these in freaky non-versioned paths that dont ever get used + fix_freaky_non_versioned_library_paths_that_dont_ever_get_used 32 + fix_freaky_non_versioned_library_paths_that_dont_ever_get_used 64 + # and mips is just freaky in general ;p + fix_freaky_non_versioned_library_paths_that_dont_ever_get_used o32 + # and finally, the non-bitdepth-or-ABI-specific freaky path + + if [ -d ${D}/${PREFIX}/lib32 -a -d ${D}/${LIBPATH}/32 ] ; then + mv ${D}/${PREFIX}/lib32/* ${D}/${LIBPATH}/32/ + elif [ -d ${D}/${PREFIX}/lib32 -a ! -d ${D}/${LIBPATH}/32 ] ; then + mv ${D}/${PREFIX}/lib32/* ${D}/${LIBPATH}/ + fi + + if [ -d ${D}/${PREFIX}/lib64 -a -d ${D}/${LIBPATH}/64 ] ; then + mv ${D}/${PREFIX}/lib64/* ${D}/${LIBPATH}/64/ + elif [ -d ${D}/${PREFIX}/lib64 -a ! -d ${D}/${LIBPATH}/64 ] ; then + mv ${D}/${PREFIX}/lib64/* ${D}/${LIBPATH}/ + fi + + mv ${D}/${PREFIX}/lib/*.a ${D}/${PREFIX}/lib/*.so* ${D}/${PREFIX}/lib/*.la ${D}/${LIBPATH}/ + + # and sometimes crap ends up here too :| + mv ${D}/${LIBPATH}/../*.a ${D}/${LIBPATH}/../*.la ${D}/${LIBPATH}/../*so* \ + ${D}/${LIBPATH}/ + + rm -rf ${D}/${PREFIX}/lib64 + rm -rf ${D}/${PREFIX}/lib32 + rm -rf ${D}/${PREFIX}/lib/o32 + rm -rf ${D}/${PREFIX}/lib/32 + rm -rf ${D}/${PREFIX}/lib/64 + rm -rf ${D}/${LIBPATH}/../o32 + rm -rf ${D}/${LIBPATH}/../32 + rm -rf ${D}/${LIBPATH}/../64 + fi + + # make sure the libtool archives have libdir set to where they actually + # -are-, and not where they -used- to be. + fix_libtool_libdir_paths "$(find ${D}/${LIBPATH} -name *.la)" +} + +#----<< src_* >>---- + +#---->> unorganised crap in need of refactoring follows + +# This is only used by the backwards-compatible stuff above... +fix_freaky_non_versioned_library_paths_that_dont_ever_get_used() { + # first the multilib case + if [ -d ${D}/${LIBPATH}/../$1 -a -d ${D}/${LIBPATH}/$1 ] ; then + mv ${D}/${LIBPATH}/../$1/* ${D}/${LIBPATH}/$1/ + rm -rf ${D}/${LIBPATH}/../$1 + fi + if [ -d ${D}/${LIBPATH}/../lib$1 -a -d ${D}/${LIBPATH}/$1 ] ; then + mv ${D}/${LIBPATH}/../lib$1/* ${D}/${LIBPATH}/$1/ + rm -rf ${D}/${LIBPATH}/../lib$1 + fi + # and now to fix up the non-multilib case + if [ -d ${D}/${LIBPATH}/../$1 -a ! -d ${D}/${LIBPATH}/$1 ] ; then + mv ${D}/${LIBPATH}/../$1/* ${D}/${LIBPATH}/ + rm -rf ${D}/${LIBPATH}/../$1 + fi + if [ -d ${D}/${LIBPATH}/../lib$1 -a ! -d ${D}/${LIBPATH}/$1 ] ; then + mv ${D}/${LIBPATH}/../lib$1/* ${D}/${LIBPATH}/ + rm -rf ${D}/${LIBPATH}/../lib$1 + fi +} + +gcc_do_filter_flags() { + strip-flags + + # In general gcc does not like optimization, and add -O2 where + # it is safe. This is especially true for gcc 3.3 + 3.4 + replace-flags -O? -O2 + + # -mcpu is deprecated on these archs, and possibly others + if use amd64 || use x86 ; then + setting="`get-flag mcpu`" + [ ! -z "${setting}" ] && \ + replace-flags -mcpu="${setting}" -mtune="${setting}" && \ + ewarn "-mcpu is deprecated on your arch\a\a\a" && \ + epause 5 + fi + + strip-unsupported-flags + + # If we use multilib on mips, we shouldn't pass -mabi flag - it breaks + # build of non-default-abi libraries. + use mips && use multilib && filter-flags "-mabi*" + + # Compile problems with these (bug #6641 among others)... + #filter-flags "-fno-exceptions -fomit-frame-pointer -fforce-addr" + + export GCJFLAGS="${CFLAGS}" +} + +chk_gcc_version() { + mkdir -p "${WORKDIR}" + + # This next bit is for updating libtool linker scripts ... + local OLD_GCC_VERSION="`gcc -dumpversion`" + local OLD_GCC_CHOST="$(gcc -v 2>&1 | egrep '^Reading specs' |\ + sed -e 's:^.*/gcc[^/]*/\([^/]*\)/[0-9]\+.*$:\1:')" + + if [ "${OLD_GCC_VERSION}" != "${MY_PV_FULL}" ] + then + echo "${OLD_GCC_VERSION}" > "${WORKDIR}/.oldgccversion" + fi + + if [ -n "${OLD_GCC_CHOST}" ] + then + if [ "${CHOST}" = "${CTARGET}" -a "${OLD_GCC_CHOST}" != "${CHOST}" ] + then + echo "${OLD_GCC_CHOST}" > "${WORKDIR}/.oldgccchost" + fi + fi + + # Did we check the version ? + touch "${WORKDIR}/.chkgccversion" +} + +# gcc_quick_unpack will unpack the gcc tarball and patches in a way that is +# consistant with the behavior of get_gcc_src_uri. The only patch it applies +# itself is the branch update if present. +# +# Travis Tilley (03 Sep 2004) +# +gcc_quick_unpack() { + pushd ${WORKDIR} > /dev/null + + if [ -n "${PRERELEASE}" ] ; then + unpack gcc-${PRERELEASE}.tar.bz2 + elif [ -n "${SNAPSHOT}" ] ; then + unpack gcc-${SNAPSHOT}.tar.bz2 + else + unpack gcc-${MAIN_BRANCH}.tar.bz2 + # We want branch updates to be against a release tarball + if [ -n "${BRANCH_UPDATE}" ] ; then + pushd ${S:="$(gcc_get_s_dir)"} > /dev/null + epatch ${DISTDIR}/gcc-${MAIN_BRANCH}-branch-update-${BRANCH_UPDATE}.patch.bz2 + popd > /dev/null + fi + fi + + if [ -n "${PATCH_VER}" ] + then + unpack ${PN}-${PATCH_GCC_VER:=${PV}}-patches-${PATCH_VER}.tar.bz2 + fi + + if [ -n "${PP_VER}" ] + then + # The gcc 3.4 propolice versions are meant to be unpacked to ${S} + pushd ${S:="$(gcc_get_s_dir)"} > /dev/null + unpack protector-${PP_FVER}.tar.gz + popd > /dev/null + fi + + if [ -n "${PIE_VER}" ] + then + unpack ${PIE_CORE} + fi + + # pappy@gentoo.org - Fri Oct 1 23:24:39 CEST 2004 + if want_boundschecking + then + unpack "bounds-checking-${PN}-${HTB_GCC_VER:=${PV}}-${HTB_VER}.patch.bz2" + fi + + popd > /dev/null +} + +# Exclude any unwanted patches, as specified by the following variables: +# +# GENTOO_PATCH_EXCLUDE +# List of filenames, relative to ${WORKDIR}/patch/ +# +# PIEPATCH_EXCLUDE +# List of filenames, relative to ${WORKDIR}/piepatch/ +# +# Travis Tilley (03 Sep 2004) +# +exclude_gcc_patches() { + local i + for i in ${GENTOO_PATCH_EXCLUDE} ; do + if [ -f ${WORKDIR}/patch/${i} ] ; then + einfo "Excluding patch ${i}" + rm -f ${WORKDIR}/patch/${i} || die "failed to delete ${i}" + fi + done + for i in ${PIEPATCH_EXCLUDE} ; do + if [ -f ${WORKDIR}/piepatch/${i} ] ; then + einfo "Excluding piepatch ${i}" + rm -f ${WORKDIR}/piepatch/${i} || die "failed to delete ${i}" + fi + done +} + +do_gcc_HTB_boundschecking_patches() { + # modify the bounds checking patch with a regression patch + epatch "${WORKDIR}/bounds-checking-${PN}-${HTB_GCC_VER:=${PV}}-${HTB_VER}.patch" + release_version="${release_version}, HTB-${HTB_VER}" +} + +# patch in ProPolice Stack Smashing protection +do_gcc_SSP_patches() { + local ssppatch + local sspdocs + + # Etoh keeps changing where files are and what the patch is named + if version_is_at_least 3.4.1 ; then + # >3.4.1 uses version in patch name, and also includes docs + ssppatch="${S}/gcc_${PP_VER}.dif" + sspdocs="yes" + elif version_is_at_least 3.4.0 ; then + # >3.4 put files where they belong and 3_4 uses old patch name + ssppatch="${S}/protector.dif" + sspdocs="no" + elif version_is_at_least 3.2.3 ; then + # earlier versions have no directory structure or docs + mv ${S}/protector.{c,h} ${S}/gcc + ssppatch="${S}/protector.dif" + sspdocs="no" + else + die "gcc version not supported by do_gcc_SSP_patches" + fi + + epatch ${ssppatch} + + if [ "${PN}" == "gcc" -a "${sspdocs}" == "no" ] ; then + epatch ${FILESDIR}/pro-police-docs.patch + fi + + # we apply only the needed parts of protectonly.dif + sed -e 's|^CRTSTUFF_CFLAGS = |CRTSTUFF_CFLAGS = -fno-stack-protector-all |'\ + -i gcc/Makefile.in || die "Failed to update crtstuff!" + + # if gcc in a stage3 defaults to ssp, is version 3.4.0 and a stage1 is built + # the build fails building timevar.o w/: + # cc1: stack smashing attack in function ix86_split_to_parts() + if gcc -dumpspecs | grep -q "fno-stack-protector:" && version_is_at_least 3.4.0 && ! version_is_at_least 4.0.0 && [ -f ${FILESDIR}/3.4.0/gcc-3.4.0-cc1-no-stack-protector.patch ] ; then + use build && epatch ${FILESDIR}/3.4.0/gcc-3.4.0-cc1-no-stack-protector.patch + fi + + release_version="${release_version}, ssp-${PP_FVER}" + if want_libssp ; then + update_gcc_for_libssp + else + update_gcc_for_libc_ssp + fi +} + +# If glibc or uclibc has been patched to provide the necessary symbols itself, +# then lets use those for SSP instead of libgcc. +update_gcc_for_libc_ssp() { + if libc_has_ssp ; then + einfo "Updating gcc to use SSP from libc ..." + sed -e 's|^\(LIBGCC2_CFLAGS.*\)$|\1 -D_LIBC_PROVIDES_SSP_|' \ + -i ${S}/gcc/Makefile.in || die "Failed to update gcc!" + fi +} + +# a split out non-libc non-libgcc ssp requires additional spec logic changes +update_gcc_for_libssp() { + einfo "Updating gcc to use SSP from libssp..." + sed -e 's|^\(INTERNAL_CFLAGS.*\)$|\1 -D_LIBSSP_PROVIDES_SSP_|' \ + -i ${S}/gcc/Makefile.in || die "Failed to update gcc!" +} + +# do various updates to PIE logic +do_gcc_PIE_patches() { + # corrects startfile/endfile selection and shared/static/pie flag usage + epatch ${WORKDIR}/piepatch/upstream + # adds non-default pie support (rs6000) + epatch ${WORKDIR}/piepatch/nondef + # adds default pie support (rs6000 too) if DEFAULT_PIE[_SSP] is defined + epatch ${WORKDIR}/piepatch/def + # disable relro/now + #use uclibc && epatch ${FILESDIR}/3.3.3/gcc-3.3.3-norelro.patch + + # we want to be able to control the pie patch logic via something other + # than ALL_CFLAGS... + sed -e '/^ALL_CFLAGS/iHARD_CFLAGS = ' \ + -e 's|^ALL_CFLAGS = |ALL_CFLAGS = $(HARD_CFLAGS) |' \ + -i ${S}/gcc/Makefile.in + + release_version="${release_version}, pie-${PIE_VER}" +} + +should_we_gcc_config() { + # we only want to switch compilers if installing to / and we're not + # building a cross-compiler. + ! [ "${ROOT}" == "/" -a "${CHOST}" == "${CTARGET}" ] && return 1 + + # we always want to run gcc-config if we're bootstrapping, otherwise + # we might get stuck with the c-only stage1 compiler + use bootstrap && return 0 + use build && return 0 + + # if the current config is invalid, we definately want a new one + [ "$(gcc-config -L | grep -v ^\ )" == "no-config" ] && return 0 + + # if the previously selected config has the same major.minor as the + # version we are installing, then it will probably be uninstalled + # for being in the same SLOT. we cannot rely on the previous check + # to handle this, since postinst sometimes happens BEFORE the + # previous version is removed. :| + # ...skip this check if the current version is -exactly- the same + local c_gcc_conf_ver=$(gcc-config -c | awk -F - '{ print $5 }') + local c_majmin=$(get_version_component_range 1-2 ${c_gcc_conf_ver}) + if [ "${c_gcc_conf_ver}" != "${MY_PV_FULL}" ] ; then + if [ "${c_majmin}" == "${MY_PV}" ] ;then + return 0 + else + # if we're installing a genuinely different compiler version, + # we should probably tell the user -how- to switch to the new + # gcc version, since we're not going to do it for him/her. + einfo "The current gcc config appears valid, so it will not be" + einfo "automatically switched for you. If you would like to" + einfo "switch to the newly installed gcc version, do the" + einfo "following:" + echo + einfo "gcc-config ${CTARGET}-${MY_PV_FULL}" + einfo "source /etc/profile" + echo + ebeep + return 1 + fi + else + # since we are re-merging the same gcc version, it's safe to re-run + # gcc-config and update any new wrappers, etc. + return 0 + fi + + # default to -not- switching gcc configs. this is to prevent an + # annoying bug where doing an emerge world -e with multiple slotted + # compilers will compile some apps with one and others with another. + return 1 +} + +do_gcc_config() { + # the grep -v is in there to filter out informational messages >_< + local current_gcc_config="$(gcc-config -c | grep -v ^\ )" + + # figure out which specs-specific config is active. yes, this works + # even if the current config is invalid. + local current_specs="$(echo ${current_gcc_config} | awk -F - '{ print $6 }')" + [ "${current_specs}" != "" ] && local use_specs="-${current_specs}" + + + if [ -n "${use_specs}" -a ! -e ${ROOT}/etc/env.d/gcc/${CTARGET}-${MY_PV_FULL}${use_specs} ] ; then + ewarn "The currently selected specs-specific gcc config," + ewarn "${current_specs}, doesn't exist anymore. This is usually" + ewarn "due to enabling/disabling hardened or switching to a version" + ewarn "of gcc that doesnt create multiple specs files. The default" + ewarn "config will be used, and the previous preference forgotten." + ebeep + epause + fi + + + if [ -e ${ROOT}/etc/env.d/gcc/${CTARGET}-${MY_PV_FULL}${use_specs} ] ; then + # we dont want to lose the current specs setting! + gcc-config ${CTARGET}-${MY_PV_FULL}${use_specs} + else + # ...unless of course the specs-specific entry doesnt exist :) + gcc-config --use-portage-chost ${CTARGET}-${MY_PV_FULL} + fi +} + +# This function allows us to gentoo-ize gcc's version number and bugzilla +# URL without needing to use patches. +# +# Travis Tilley (02 Sep 2004) +# +gcc_version_patch() { + [ -z "$1" ] && die "no arguments to gcc_version_patch" + + sed -i -e 's~\(const char version_string\[\] = ".....\).*\(".*\)~\1 @GENTOO@\2~' ${S}/gcc/version.c || die "failed to add @GENTOO@" + sed -i -e "s:@GENTOO@:$1:g" ${S}/gcc/version.c || die "failed to patch version" + sed -i -e 's~http:\/\/gcc\.gnu\.org\/bugs\.html~http:\/\/bugs\.gentoo\.org\/~' ${S}/gcc/version.c || die "failed to update bugzilla URL" +} + +# The purpose of this DISGUSTING gcc multilib hack is to allow 64bit libs +# to live in lib instead of lib64 where they belong, with 32bit libraries +# in lib32. This hack has been around since the beginning of the amd64 port, +# and we're only now starting to fix everything that's broken. Eventually +# this should go away. +# +# Travis Tilley (03 Sep 2004) +# +disgusting_gcc_multilib_HACK() { + local libdirs + if [ -n "${MULTILIB_ABIS}" ]; then + libdirs="../$(get_abi_LIBDIR amd64) ../$(get_abi_LIBDIR x86)" + else + libdirs="../$(get_libdir) ../$(get_multilibdir)" + fi + einfo "updating multilib directories to be: ${libdirs}" + sed -i -e "s:^MULTILIB_OSDIRNAMES.*:MULTILIB_OSDIRNAMES = ${libdirs}:" ${S}/gcc/config/i386/t-linux64 +} + +disable_multilib_libjava() { + # We dont want a multilib libjava, so lets use this hack taken from fedora + pushd ${S} > /dev/null + sed -i -e 's/^all: all-redirect/ifeq (\$(MULTISUBDIR),)\nall: all-redirect\nelse\nall:\n\techo Multilib libjava build disabled\nendif/' libjava/Makefile.in + sed -i -e 's/^install: install-redirect/ifeq (\$(MULTISUBDIR),)\ninstall: install-redirect\nelse\ninstall:\n\techo Multilib libjava install disabled\nendif/' libjava/Makefile.in + sed -i -e 's/^check: check-redirect/ifeq (\$(MULTISUBDIR),)\ncheck: check-redirect\nelse\ncheck:\n\techo Multilib libjava check disabled\nendif/' libjava/Makefile.in + sed -i -e 's/^all: all-recursive/ifeq (\$(MULTISUBDIR),)\nall: all-recursive\nelse\nall:\n\techo Multilib libjava build disabled\nendif/' libjava/Makefile.in + sed -i -e 's/^install: install-recursive/ifeq (\$(MULTISUBDIR),)\ninstall: install-recursive\nelse\ninstall:\n\techo Multilib libjava install disabled\nendif/' libjava/Makefile.in + sed -i -e 's/^check: check-recursive/ifeq (\$(MULTISUBDIR),)\ncheck: check-recursive\nelse\ncheck:\n\techo Multilib libjava check disabled\nendif/' libjava/Makefile.in + popd > /dev/null +} + +fix_libtool_libdir_paths() { + local dirpath + for archive in ${*} ; do + dirpath=$(dirname ${archive} | sed -e "s:^${D}::") + sed -i ${archive} -e "s:^libdir.*:libdir=\'${dirpath}\':" + done +}