# 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
toolchain_pkg_setup() {
gcc_pkg_setup
}
+toolchain_pkg_preinst() {
+ ${ETYPE}-pkg_preinst
+}
+toolchain_pkg_postinst() {
+ ${ETYPE}-pkg_postinst
+}
#----<< eclass stuff >>----
DATAPATH="${DATAPATH:="${PREFIX}/share/"}"
STDCXX_INCDIR="${STDCXX_INCDIR:="${PREFIX}/include/g++-v3/"}"
fi
+
+XGCC="${WORKDIR}/build/gcc/xgcc"
#----<< globals >>----
# 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
#----<< support checks >>----
-
-
#---->> specs + env.d logic <<----
# configure to build with the hardened GCC specs as the default
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}
#----<< 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
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 <lv@gentoo.org> (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 <lv@gentoo.org> (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 <lv@gentoo.org> (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 <lv@gentoo.org> (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 <lv@gentoo.org> (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 <csm@gnu.org> for the heads up.
- # Travis Tilley <lv@gentoo.org> (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 <csm@gnu.org> for the heads up.
+ # Travis Tilley <lv@gentoo.org> (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"
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
# 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}"
# ...sure, why not?
strip-unsupported-flags
+
+ filter-flags "-mabi*"
+ filter-flags "-m32"
+ filter-flags "-m64"
+
+ export GCJFLAGS="${CFLAGS}"
}
gcc_src_compile() {
}
+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 -<version> extension)
+ cd ${D}${PREFIX}/${CTARGET}/gcc-bin/${MY_PV_FULL}
+ [ -f jar ] && mv -f jar gcj-jar
+
+ # Move <cxxabi.h> 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 <ffitarget.h>" 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 <fafhrd@gentoo.org>
+ if use objc && ! use gcj; then
+ #dosed "s:<ffitarget.h>:<libffi/ffitarget.h>: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 <lv@gentoo.org> (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 <lv@gentoo.org> (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 <lv@gentoo.org> (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 <lv@gentoo.org> (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
+}