From d10cc0e184c927394d18bba756c0db85bd5880fb Mon Sep 17 00:00:00 2001 From: geos_one Date: Sat, 17 Nov 2007 18:52:32 +0000 Subject: [PATCH] llvm git-svn-id: https://svn.disconnected-by-peer.at/svn/linamh/trunk/linamh@308 6952d904-891a-0410-993b-d76249ca496b --- eclass/toolchain-funcs.eclass | 411 ++++ eclass/toolchain-gcc.eclass | 2385 +++++++++++++++++++++++ eclass/toolchain-llvm.eclass | 2608 +++----------------------- sys-devel/llvm/Manifest | 9 + sys-devel/llvm/files/digest-llvm-2.1 | 6 + sys-devel/llvm/llvm-2.1.ebuild | 8 + 6 files changed, 3098 insertions(+), 2329 deletions(-) create mode 100644 eclass/toolchain-funcs.eclass create mode 100644 eclass/toolchain-gcc.eclass create mode 100644 sys-devel/llvm/Manifest create mode 100644 sys-devel/llvm/files/digest-llvm-2.1 create mode 100644 sys-devel/llvm/llvm-2.1.ebuild diff --git a/eclass/toolchain-funcs.eclass b/eclass/toolchain-funcs.eclass new file mode 100644 index 00000000..aaf82c9d --- /dev/null +++ b/eclass/toolchain-funcs.eclass @@ -0,0 +1,411 @@ +# Copyright 1999-2007 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/eclass/toolchain-funcs.eclass,v 1.74 2007/08/17 10:14:13 vapier Exp $ + +# @ECLASS: toolchain-funcs.eclass +# @MAINTAINER: +# Toolchain Ninjas +# @BLURB: functions to query common info about the toolchain +# @DESCRIPTION: +# The toolchain-funcs aims to provide a complete suite of functions +# for gleaning useful information about the toolchain and to simplify +# ugly things like cross-compiling and multilib. All of this is done +# in such a way that you can rely on the function always returning +# something sane. + +___ECLASS_RECUR_TOOLCHAIN_FUNCS="yes" +[[ -z ${___ECLASS_RECUR_MULTILIB} ]] && inherit multilib + +DESCRIPTION="Based on the ${ECLASS} eclass" + +tc-getPROG() { + local var=$1 + local prog=$2 + + if [[ -n ${!var} ]] ; then + echo "${!var}" + return 0 + fi + + local search= + [[ -n $3 ]] && search=$(type -p "$3-${prog}") + [[ -z ${search} && -n ${CHOST} ]] && search=$(type -p "${CHOST}-${prog}") + [[ -n ${search} ]] && prog=${search##*/} + + export ${var}=${prog} + echo "${!var}" +} + +# @FUNCTION: tc-getAR +# @USAGE: [toolchain prefix] +# @RETURN: name of the archiver +tc-getAR() { tc-getPROG AR ar "$@"; } +# @FUNCTION: tc-getAS +# @USAGE: [toolchain prefix] +# @RETURN: name of the assembler +tc-getAS() { tc-getPROG AS as "$@"; } +# @FUNCTION: tc-getCC +# @USAGE: [toolchain prefix] +# @RETURN: name of the C compiler +tc-getCC() { tc-getPROG CC gcc "$@"; } +# @FUNCTION: tc-getCPP +# @USAGE: [toolchain prefix] +# @RETURN: name of the C preprocessor +tc-getCPP() { tc-getPROG CPP cpp "$@"; } +# @FUNCTION: tc-getCXX +# @USAGE: [toolchain prefix] +# @RETURN: name of the C++ compiler +tc-getCXX() { tc-getPROG CXX g++ "$@"; } +# @FUNCTION: tc-getLD +# @USAGE: [toolchain prefix] +# @RETURN: name of the linker +tc-getLD() { tc-getPROG LD ld "$@"; } +# @FUNCTION: tc-getSTRIP +# @USAGE: [toolchain prefix] +# @RETURN: name of the strip program +tc-getSTRIP() { tc-getPROG STRIP strip "$@"; } +# @FUNCTION: tc-getNM +# @USAGE: [toolchain prefix] +# @RETURN: name of the symbol/object thingy +tc-getNM() { tc-getPROG NM nm "$@"; } +# @FUNCTION: tc-getRANLIB +# @USAGE: [toolchain prefix] +# @RETURN: name of the archiver indexer +tc-getRANLIB() { tc-getPROG RANLIB ranlib "$@"; } +# @FUNCTION: tc-getF77 +# @USAGE: [toolchain prefix] +# @RETURN: name of the Fortran 77 compiler +tc-getF77() { tc-getPROG F77 f77 "$@"; } +# @FUNCTION: tc-getF90 +# @USAGE: [toolchain prefix] +# @RETURN: name of the Fortran 90 compiler +tc-getF90() { tc-getPROG F90 gfortran "$@"; } +# @FUNCTION: tc-getFORTRAN +# @USAGE: [toolchain prefix] +# @RETURN: name of the Fortran compiler +tc-getFORTRAN() { tc-getPROG FORTRAN gfortran "$@"; } +# @FUNCTION: tc-getGCJ +# @USAGE: [toolchain prefix] +# @RETURN: name of the java compiler +tc-getGCJ() { tc-getPROG GCJ gcj "$@"; } + +# @FUNCTION: tc-getBUILD_CC +# @USAGE: [toolchain prefix] +# @RETURN: name of the C compiler for building binaries to run on the build machine +tc-getBUILD_CC() { + local v + for v in CC_FOR_BUILD BUILD_CC HOSTCC ; do + if [[ -n ${!v} ]] ; then + export BUILD_CC=${!v} + echo "${!v}" + return 0 + fi + done + + local search= + if [[ -n ${CBUILD} ]] ; then + search=$(type -p ${CBUILD}-gcc) + search=${search##*/} + fi + search=${search:-gcc} + + export BUILD_CC=${search} + echo "${search}" +} + +# @FUNCTION: tc-export +# @USAGE: +# @DESCRIPTION: +# Quick way to export a bunch of compiler vars at once. +tc-export() { + local var + for var in "$@" ; do + eval tc-get${var} > /dev/null + done +} + +# @FUNCTION: tc-is-cross-compiler +# @RETURN: Shell true if we are using a cross-compiler, shell false otherwise +tc-is-cross-compiler() { + return $([[ ${CBUILD:-${CHOST}} != ${CHOST} ]]) +} + +# @FUNCTION: tc-is-softfloat +# @DESCRIPTION: +# See if this toolchain is a softfloat based one. +# @CODE +# The possible return values: +# - only: the target is always softfloat (never had fpu) +# - yes: the target should support softfloat +# - no: the target should support hardfloat +# @CODE +# This allows us to react differently where packages accept +# softfloat flags in the case where support is optional, but +# rejects softfloat flags where the target always lacks an fpu. +tc-is-softfloat() { + case ${CTARGET} in + bfin*|h8300*) + echo "only" ;; + *) + [[ ${CTARGET//_/-} == *-softfloat-* ]] \ + && echo "yes" \ + || echo "no" + ;; + esac +} + +# Parse information from CBUILD/CHOST/CTARGET rather than +# use external variables from the profile. +tc-ninja_magic_to_arch() { +ninj() { [[ ${type} == "kern" ]] && echo $1 || echo $2 ; } + + local type=$1 + local host=$2 + [[ -z ${host} ]] && host=${CTARGET:-${CHOST}} + + case ${host} in + alpha*) echo alpha;; + arm*) echo arm;; + avr*) ninj avr32 avr;; + bfin*) ninj blackfin bfin;; + cris*) echo cris;; + hppa*) ninj parisc hppa;; + i?86*) ninj i386 x86;; + ia64*) echo ia64;; + m68*) echo m68k;; + mips*) echo mips;; + nios2*) echo nios2;; + nios*) echo nios;; + powerpc*) + # Starting with linux-2.6.15, the 'ppc' and 'ppc64' trees + # have been unified into simply 'powerpc', but until 2.6.16, + # ppc32 is still using ARCH="ppc" as default + if [[ $(KV_to_int ${KV}) -ge $(KV_to_int 2.6.16) ]] && [[ ${type} == "kern" ]] ; then + echo powerpc + elif [[ $(KV_to_int ${KV}) -eq $(KV_to_int 2.6.15) ]] && [[ ${type} == "kern" ]] ; then + if [[ ${host} == powerpc64* ]] || [[ ${PROFILE_ARCH} == "ppc64" ]] ; then + echo powerpc + else + echo ppc + fi + elif [[ ${host} == powerpc64* ]] ; then + echo ppc64 + elif [[ ${PROFILE_ARCH} == "ppc64" ]] ; then + ninj ppc64 ppc + else + echo ppc + fi + ;; + s390*) echo s390;; + sh64*) ninj sh64 sh;; + sh*) echo sh;; + sparc64*) ninj sparc64 sparc;; + sparc*) [[ ${PROFILE_ARCH} == "sparc64" ]] \ + && ninj sparc64 sparc \ + || echo sparc + ;; + vax*) echo vax;; + x86_64*) ninj x86_64 amd64;; + + # since our usage of tc-arch is largely concerned with + # normalizing inputs for testing ${CTARGET}, let's filter + # other cross targets (mingw and such) into the unknown. + *) echo unknown;; + esac +} +# @FUNCTION: tc-arch-kernel +# @USAGE: [toolchain prefix] +# @RETURN: name of the kernel arch according to the compiler target +tc-arch-kernel() { + tc-ninja_magic_to_arch kern "$@" +} +# @FUNCTION: tc-arch +# @USAGE: [toolchain prefix] +# @RETURN: name of the portage arch according to the compiler target +tc-arch() { + tc-ninja_magic_to_arch portage "$@" +} + +tc-endian() { + local host=$1 + [[ -z ${host} ]] && host=${CTARGET:-${CHOST}} + host=${host%%-*} + + case ${host} in + alpha*) echo big;; + arm*b*) echo big;; + arm*) echo little;; + cris*) echo little;; + hppa*) echo big;; + i?86*) echo little;; + ia64*) echo little;; + m68*) echo big;; + mips*l*) echo little;; + mips*) echo big;; + powerpc*) echo big;; + s390*) echo big;; + sh*b*) echo big;; + sh*) echo little;; + sparc*) echo big;; + x86_64*) echo little;; + *) echo wtf;; + esac +} + +# @FUNCTION: gcc-fullversion +# @RETURN: compiler version (major.minor.micro: [3.4.6]) +gcc-fullversion() { + $(tc-getCC "$@") -dumpversion +} +# @FUNCTION: gcc-version +# @RETURN: compiler version (major.minor: [3.4].6) +gcc-version() { + gcc-fullversion "$@" | cut -f1,2 -d. +} +# @FUNCTION: gcc-major-version +# @RETURN: major compiler version (major: [3].4.6) +gcc-major-version() { + gcc-version "$@" | cut -f1 -d. +} +# @FUNCTION: gcc-minor-version +# @RETURN: minor compiler version (minor: 3.[4].6) +gcc-minor-version() { + gcc-version "$@" | cut -f2 -d. +} +# @FUNCTION: gcc-micro-version +# @RETURN: micro compiler version (micro: 3.4.[6]) +gcc-micro-version() { + gcc-fullversion "$@" | cut -f3 -d. | cut -f1 -d- +} + +# Returns the installation directory - internal toolchain +# function for use by _gcc-specs-exists (for flag-o-matic). +_gcc-install-dir() { + echo "$($(tc-getCC) -print-search-dirs 2> /dev/null |\ + awk '$1=="install:" {print $2}')" +} +# Returns true if the indicated specs file exists - internal toolchain +# function for use by flag-o-matic. +_gcc-specs-exists() { + [[ -f $(_gcc-install-dir)/$1 ]] +} + +# Returns requested gcc specs directive unprocessed - for used by +# gcc-specs-directive() +# Note; later specs normally overwrite earlier ones; however if a later +# spec starts with '+' then it appends. +# gcc -dumpspecs is parsed first, followed by files listed by "gcc -v" +# as "Reading ", in order. Strictly speaking, if there's a +# $(gcc_install_dir)/specs, the built-in specs aren't read, however by +# the same token anything from 'gcc -dumpspecs' is overridden by +# the contents of $(gcc_install_dir)/specs so the result is the +# same either way. +_gcc-specs-directive_raw() { + local cc=$(tc-getCC) + local specfiles=$(LC_ALL=C ${cc} -v 2>&1 | awk '$1=="Reading" {print $NF}') + ${cc} -dumpspecs 2> /dev/null | cat - ${specfiles} | awk -v directive=$1 \ +'BEGIN { pspec=""; spec=""; outside=1 } +$1=="*"directive":" { pspec=spec; spec=""; outside=0; next } + outside || NF==0 || ( substr($1,1,1)=="*" && substr($1,length($1),1)==":" ) { outside=1; next } + spec=="" && substr($0,1,1)=="+" { spec=pspec " " substr($0,2); next } + { spec=spec $0 } +END { print spec }' + return 0 +} + +# Return the requested gcc specs directive, with all included +# specs expanded. +# Note, it does not check for inclusion loops, which cause it +# to never finish - but such loops are invalid for gcc and we're +# assuming gcc is operational. +gcc-specs-directive() { + local directive subdname subdirective + directive="$(_gcc-specs-directive_raw $1)" + while [[ ${directive} == *%\(*\)* ]]; do + subdname=${directive/*%\(} + subdname=${subdname/\)*} + subdirective="$(_gcc-specs-directive_raw ${subdname})" + directive="${directive//\%(${subdname})/${subdirective}}" + done + echo "${directive}" + return 0 +} + +# Returns true if gcc sets relro +gcc-specs-relro() { + local directive + directive=$(gcc-specs-directive link_command) + return $([[ ${directive/\{!norelro:} != ${directive} ]]) +} +# Returns true if gcc sets now +gcc-specs-now() { + local directive + directive=$(gcc-specs-directive link_command) + return $([[ ${directive/\{!nonow:} != ${directive} ]]) +} +# Returns true if gcc builds PIEs +gcc-specs-pie() { + local directive + directive=$(gcc-specs-directive cc1) + return $([[ ${directive/\{!nopie:} != ${directive} ]]) +} +# Returns true if gcc builds with the stack protector +gcc-specs-ssp() { + local directive + directive=$(gcc-specs-directive cc1) + return $([[ ${directive/\{!fno-stack-protector:} != ${directive} ]]) +} +# Returns true if gcc upgrades fstack-protector to fstack-protector-all +gcc-specs-ssp-to-all() { + local directive + directive=$(gcc-specs-directive cc1) + return $([[ ${directive/\{!fno-stack-protector-all:} != ${directive} ]]) +} + + +# @FUNCTION: gen_usr_ldscript +# @USAGE: +# @DESCRIPTION: +# This function generate linker scripts in /usr/lib for dynamic +# libs in /lib. This is to fix linking problems when you have +# the .so in /lib, and the .a in /usr/lib. What happens is that +# in some cases when linking dynamic, the .a in /usr/lib is used +# instead of the .so in /lib due to gcc/libtool tweaking ld's +# library search path. This causes many builds to fail. +# See bug #4411 for more info. +# +# Note that you should in general use the unversioned name of +# the library (libfoo.so), as ldconfig should usually update it +# correctly to point to the latest version of the library present. +gen_usr_ldscript() { + local lib libdir=$(get_libdir) output_format="" + # Just make sure it exists + dodir /usr/${libdir} + + # OUTPUT_FORMAT gives hints to the linker as to what binary format + # is referenced ... makes multilib saner + output_format=$($(tc-getCC) ${CFLAGS} ${LDFLAGS} -Wl,--verbose 2>&1 | sed -n 's/^OUTPUT_FORMAT("\([^"]*\)",.*/\1/p') + [[ -n ${output_format} ]] && output_format="OUTPUT_FORMAT ( ${output_format} )" + + for lib in "$@" ; do + if [[ ${USERLAND} == "Darwin" ]] ; then + ewarn "Not creating fake dynamic library for $lib on Darwin;" + ewarn "making a symlink instead." + dosym "/${libdir}/${lib}" "/usr/${libdir}/${lib}" + else + cat > "${D}/usr/${libdir}/${lib}" <<-END_LDSCRIPT + /* GNU ld script + Since Gentoo has critical dynamic libraries + in /lib, and the static versions in /usr/lib, + we need to have a "fake" dynamic lib in /usr/lib, + otherwise we run into linking problems. + + See bug http://bugs.gentoo.org/4411 for more info. + */ + ${output_format} + GROUP ( /${libdir}/${lib} ) + END_LDSCRIPT + fi + fperms a+x "/usr/${libdir}/${lib}" || die "could not change perms on ${lib}" + done +} diff --git a/eclass/toolchain-gcc.eclass b/eclass/toolchain-gcc.eclass new file mode 100644 index 00000000..755b2728 --- /dev/null +++ b/eclass/toolchain-gcc.eclass @@ -0,0 +1,2385 @@ +# Copyright 1999-2007 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/eclass/toolchain.eclass,v 1.342 2007/11/12 19:33:00 vapier Exp $ +# +# Maintainer: Toolchain Ninjas + +HOMEPAGE="http://gcc.gnu.org/" +LICENSE="GPL-2 LGPL-2.1" +RESTRICT="strip" # cross-compilers need controlled stripping + +#---->> eclass stuff <<---- +inherit eutils versionator libtool toolchain-funcs flag-o-matic gnuconfig multilib fixheadtails + +EXPORT_FUNCTIONS pkg_setup src_unpack src_compile src_test pkg_preinst src_install pkg_postinst pkg_prerm pkg_postrm +DESCRIPTION="Based on the ${ECLASS} eclass" + +FEATURES=${FEATURES/multilib-strict/} + +toolchain_pkg_setup() { + gcc_pkg_setup +} +toolchain_src_unpack() { + gcc_src_unpack +} +toolchain_src_compile() { + gcc_src_compile +} +toolchain_src_test() { + gcc_src_test +} +toolchain_pkg_preinst() { + ${ETYPE}_pkg_preinst +} +toolchain_src_install() { + ${ETYPE}_src_install +} +toolchain_pkg_postinst() { + ${ETYPE}_pkg_postinst +} +toolchain_pkg_prerm() { + ${ETYPE}_pkg_prerm +} +toolchain_pkg_postrm() { + ${ETYPE}_pkg_postrm +} +#----<< eclass stuff >>---- + + +#---->> globals <<---- +export CTARGET=${CTARGET:-${CHOST}} +if [[ ${CTARGET} = ${CHOST} ]] ; then + if [[ ${CATEGORY/cross-} != ${CATEGORY} ]] ; then + export CTARGET=${CATEGORY/cross-} + fi +fi +is_crosscompile() { + [[ ${CHOST} != ${CTARGET} ]] +} + +tc_version_is_at_least() { version_is_at_least "$1" "${2:-${GCC_PV}}" ; } + + +GCC_PV=${TOOLCHAIN_GCC_PV:-${PV}} +GCC_PVR=${GCC_PV} +[[ ${PR} != "r0" ]] && GCC_PVR=${GCC_PVR}-${PR} +GCC_RELEASE_VER=$(get_version_component_range 1-3 ${GCC_PV}) +GCC_BRANCH_VER=$(get_version_component_range 1-2 ${GCC_PV}) +GCCMAJOR=$(get_version_component_range 1 ${GCC_PV}) +GCCMINOR=$(get_version_component_range 2 ${GCC_PV}) +GCCMICRO=$(get_version_component_range 3 ${GCC_PV}) +[[ ${BRANCH_UPDATE-notset} == "notset" ]] && BRANCH_UPDATE=$(get_version_component_range 4 ${GCC_PV}) + +# According to gcc/c-cppbuiltin.c, GCC_CONFIG_VER MUST match this regex. +# ([^0-9]*-)?[0-9]+[.][0-9]+([.][0-9]+)?([- ].*)? +GCC_CONFIG_VER=${GCC_CONFIG_VER:-$(replace_version_separator 3 '-' ${GCC_PV})} + +# Pre-release support +if [[ ${GCC_PV} != ${GCC_PV/_pre/-} ]] ; then + PRERELEASE=${GCC_PV/_pre/-} +fi +# make _alpha and _beta ebuilds automatically use a snapshot +if [[ ${GCC_PV} != ${GCC_PV/_alpha/} ]] ; then + SNAPSHOT=${GCC_BRANCH_VER}-${GCC_PV##*_alpha} +elif [[ ${GCC_PV} != ${GCC_PV/_beta/} ]] ; then + SNAPSHOT=${GCC_BRANCH_VER}-${GCC_PV##*_beta} +fi +export GCC_FILESDIR=${GCC_FILESDIR:-${FILESDIR}} + +if [[ ${ETYPE} == "gcc-library" ]] ; then + GCC_VAR_TYPE=${GCC_VAR_TYPE:-non-versioned} + GCC_LIB_COMPAT_ONLY=${GCC_LIB_COMPAT_ONLY:-true} + GCC_TARGET_NO_MULTILIB=${GCC_TARGET_NO_MULTILIB:-true} +else + GCC_VAR_TYPE=${GCC_VAR_TYPE:-versioned} + GCC_LIB_COMPAT_ONLY="false" + GCC_TARGET_NO_MULTILIB=${GCC_TARGET_NO_MULTILIB:-false} +fi + +PREFIX=${TOOLCHAIN_PREFIX:-/usr} + +if [[ ${GCC_VAR_TYPE} == "versioned" ]] ; then + if tc_version_is_at_least 3.4.0 ; then + LIBPATH=${TOOLCHAIN_LIBPATH:-${PREFIX}/lib/gcc/${CTARGET}/${GCC_CONFIG_VER}} + else + LIBPATH=${TOOLCHAIN_LIBPATH:-${PREFIX}/lib/gcc-lib/${CTARGET}/${GCC_CONFIG_VER}} + fi + INCLUDEPATH=${TOOLCHAIN_INCLUDEPATH:-${LIBPATH}/include} + if is_crosscompile ; then + BINPATH=${TOOLCHAIN_BINPATH:-${PREFIX}/${CHOST}/${CTARGET}/gcc-bin/${GCC_CONFIG_VER}} + else + BINPATH=${TOOLCHAIN_BINPATH:-${PREFIX}/${CTARGET}/gcc-bin/${GCC_CONFIG_VER}} + fi + DATAPATH=${TOOLCHAIN_DATAPATH:-${PREFIX}/share/gcc-data/${CTARGET}/${GCC_CONFIG_VER}} + # Dont install in /usr/include/g++-v3/, but in gcc internal directory. + # We will handle /usr/include/g++-v3/ with gcc-config ... + STDCXX_INCDIR=${TOOLCHAIN_STDCXX_INCDIR:-${LIBPATH}/include/g++-v${GCC_BRANCH_VER/\.*/}} +elif [[ ${GCC_VAR_TYPE} == "non-versioned" ]] ; then + # using non-versioned directories to install gcc, like what is currently + # done for ppc64 and 3.3.3_pre, is a BAD IDEA. DO NOT do it!! However... + # setting up variables for non-versioned directories might be useful for + # specific gcc targets, like libffi. Note that we dont override the value + # returned by get_libdir here. + LIBPATH=${TOOLCHAIN_LIBPATH:-${PREFIX}/$(get_libdir)} + INCLUDEPATH=${TOOLCHAIN_INCLUDEPATH:-${PREFIX}/include} + BINPATH=${TOOLCHAIN_BINPATH:-${PREFIX}/bin} + DATAPATH=${TOOLCHAIN_DATAPATH:-${PREFIX}/share} + STDCXX_INCDIR=${TOOLCHAIN_STDCXX_INCDIR:-${PREFIX}/include/g++-v3} +fi + +#----<< globals >>---- + + +#---->> SLOT+IUSE logic <<---- +if [[ ${ETYPE} == "gcc-library" ]] ; then + IUSE="nls build test" + SLOT="${CTARGET}-${SO_VERSION_SLOT:-5}" +else + IUSE="multislot test" + + if [[ ${PN} != "kgcc64" && ${PN} != gcc-* ]] ; then + IUSE="${IUSE} altivec build fortran nls nocxx" + [[ -n ${PIE_VER} ]] && IUSE="${IUSE} nopie" + [[ -n ${PP_VER} ]] && IUSE="${IUSE} nossp" + [[ -n ${HTB_VER} ]] && IUSE="${IUSE} boundschecking" + [[ -n ${D_VER} ]] && IUSE="${IUSE} d" + + if version_is_at_least 3 ; then + IUSE="${IUSE} bootstrap doc gcj gtk hardened multilib objc vanilla" + + # gcc-{nios2,bfin} don't accept these + if [[ ${PN} == "gcc" ]] ; then + IUSE="${IUSE} ip28 ip32r10k n32 n64" + fi + + tc_version_is_at_least "4.0" && IUSE="${IUSE} objc-gc mudflap" + tc_version_is_at_least "4.1" && IUSE="${IUSE} objc++" + tc_version_is_at_least "4.2" && IUSE="${IUSE} openmp" + fi + fi + + # Support upgrade paths here or people get pissed + if use multislot ; then + SLOT="${CTARGET}-${GCC_CONFIG_VER}" + elif is_crosscompile; then + SLOT="${CTARGET}-${GCC_BRANCH_VER}" + else + SLOT="${GCC_BRANCH_VER}" + fi +fi +#----<< SLOT+IUSE logic >>---- + + +#---->> S + SRC_URI essentials <<---- + +# This function sets the source directory depending on whether we're using +# a prerelease, snapshot, or release tarball. To use it, just set S with: +# +# S="$(gcc_get_s_dir)" +# +# Travis Tilley (03 Sep 2004) +# +gcc_get_s_dir() { + local GCC_S + if [[ -n ${PRERELEASE} ]] ; then + GCC_S=${WORKDIR}/gcc-${PRERELEASE} + elif [[ -n ${SNAPSHOT} ]] ; then + GCC_S=${WORKDIR}/gcc-${SNAPSHOT} + else + GCC_S=${WORKDIR}/gcc-${GCC_RELEASE_VER} + fi + echo "${GCC_S}" +} + +# This function handles the basics of setting the SRC_URI for a gcc ebuild. +# To use, set SRC_URI with: +# +# SRC_URI="$(get_gcc_src_uri)" +# +# Other than the variables normally set by portage, this function's behavior +# can be altered by setting the following: +# +# SNAPSHOT +# If set, this variable signals that we should be using a snapshot +# of gcc from ftp://sources.redhat.com/pub/gcc/snapshots/. It is +# expected to be in the format "YYYY-MM-DD". Note that if the ebuild +# has a _pre suffix, this variable is ignored and the prerelease +# tarball is used instead. +# +# BRANCH_UPDATE +# If set, this variable signals that we should be using the main +# release tarball (determined by ebuild version) and applying a +# CVS branch update patch against it. The location of this branch +# update patch is assumed to be in ${GENTOO_TOOLCHAIN_BASE_URI}. +# Just like with SNAPSHOT, this variable is ignored if the ebuild +# has a _pre suffix. +# +# PATCH_VER +# PATCH_GCC_VER +# This should be set to the version of the gentoo patch tarball. +# The resulting filename of this tarball will be: +# gcc-${PATCH_GCC_VER:-${GCC_RELEASE_VER}}-patches-${PATCH_VER}.tar.bz2 +# +# PIE_VER +# PIE_GCC_VER +# obsoleted: PIE_CORE +# These variables control patching in various updates for the logic +# controlling Position Independant Executables. PIE_VER is expected +# to be the version of this patch, PIE_GCC_VER the gcc version of +# the patch, and PIE_CORE (obsoleted) the actual filename of the patch. +# An example: +# PIE_VER="8.7.6.5" +# PIE_GCC_VER="3.4.0" +# The resulting filename of this tarball will be: +# gcc-${PIE_GCC_VER:-${GCC_RELEASE_VER}}-piepatches-v${PIE_VER}.tar.bz2 +# old syntax (do not define PIE_CORE anymore): +# PIE_CORE="gcc-3.4.0-piepatches-v${PIE_VER}.tar.bz2" +# +# PP_VER +# PP_GCC_VER +# obsoleted: PP_FVER +# These variables control patching in stack smashing protection +# support. They both control the version of ProPolice to download. +# +# PP_VER / PP_GCC_VER +# Used to roll our own custom tarballs of ssp. +# PP_FVER / PP_VER +# Used for mirroring ssp straight from IBM. +# PP_VER sets the version of the directory in which to find the +# patch, and PP_FVER sets the version of the patch itself. For +# example: +# PP_VER="3_4" +# PP_FVER="${PP_VER//_/.}-2" +# would download gcc3_4/protector-3.4-2.tar.gz +# +# HTB_VER +# HTB_GCC_VER +# These variables control whether or not an ebuild supports Herman +# ten Brugge's bounds-checking patches. If you want to use a patch +# for an older gcc version with a new gcc, make sure you set +# HTB_GCC_VER to that version of gcc. +# +# MAN_VER +# The version of gcc for which we will download manpages. This will +# default to ${GCC_RELEASE_VER}, but we may not want to pre-generate man pages +# for prerelease test ebuilds for example. This allows you to +# continue using pre-generated manpages from the last stable release. +# If set to "none", this will prevent the downloading of manpages, +# which is useful for individual library targets. +# +gentoo_urls() { + local devspace="HTTP~lv/GCC/URI HTTP~eradicator/gcc/URI HTTP~vapier/dist/URI + HTTP~halcy0n/patches/URI" + devspace=${devspace//HTTP/http:\/\/dev.gentoo.org\/} + echo mirror://gentoo/$1 ${devspace//URI/$1} +} +get_gcc_src_uri() { + export PATCH_GCC_VER=${PATCH_GCC_VER:-${GCC_RELEASE_VER}} + export UCLIBC_GCC_VER=${UCLIBC_GCC_VER:-${PATCH_GCC_VER}} + export PIE_GCC_VER=${PIE_GCC_VER:-${GCC_RELEASE_VER}} + export PP_GCC_VER=${PP_GCC_VER:-${GCC_RELEASE_VER}} + export HTB_GCC_VER=${HTB_GCC_VER:-${GCC_RELEASE_VER}} + + [[ -n ${PIE_VER} ]] && \ + PIE_CORE=${PIE_CORE:-gcc-${PIE_GCC_VER}-piepatches-v${PIE_VER}.tar.bz2} + + # Set where to download gcc itself depending on whether we're using a + # prerelease, snapshot, or release tarball. + if [[ -n ${PRERELEASE} ]] ; then + GCC_SRC_URI="ftp://gcc.gnu.org/pub/gcc/prerelease-${PRERELEASE}/gcc-${PRERELEASE}.tar.bz2" + elif [[ -n ${SNAPSHOT} ]] ; then + GCC_SRC_URI="ftp://sources.redhat.com/pub/gcc/snapshots/${SNAPSHOT}/gcc-${SNAPSHOT}.tar.bz2" + else + GCC_SRC_URI="mirror://gnu/gcc/gcc-${GCC_PV}/gcc-${GCC_RELEASE_VER}.tar.bz2" + # we want all branch updates to be against the main release + [[ -n ${BRANCH_UPDATE} ]] && \ + GCC_SRC_URI="${GCC_SRC_URI} $(gentoo_urls gcc-${GCC_RELEASE_VER}-branch-update-${BRANCH_UPDATE}.patch.bz2)" + fi + + # propolice aka stack smashing protection + if [[ -n ${PP_VER} ]] ; then + if [[ -n ${PP_FVER} ]] ; then + GCC_SRC_URI="${GCC_SRC_URI} + !nossp? ( + http://www.research.ibm.com/trl/projects/security/ssp/gcc${PP_VER}/protector-${PP_FVER}.tar.gz + $(gentoo_urls protector-${PP_FVER}.tar.gz) + )" + else + GCC_SRC_URI="${GCC_SRC_URI} $(gentoo_urls gcc-${PP_GCC_VER}-ssp-${PP_VER}.tar.bz2)" + fi + fi + + # uclibc lovin + [[ -n ${UCLIBC_VER} ]] && \ + GCC_SRC_URI="${GCC_SRC_URI} $(gentoo_urls gcc-${UCLIBC_GCC_VER}-uclibc-patches-${UCLIBC_VER}.tar.bz2)" + + # PERL cannot be present at bootstrap, and is used to build the man pages. + # So... lets include some pre-generated ones, shall we? + [[ -n ${MAN_VER} ]] && \ + GCC_SRC_URI="${GCC_SRC_URI} $(gentoo_urls gcc-${MAN_VER}-manpages.tar.bz2)" + + # various gentoo patches + [[ -n ${PATCH_VER} ]] && \ + GCC_SRC_URI="${GCC_SRC_URI} $(gentoo_urls gcc-${PATCH_GCC_VER}-patches-${PATCH_VER}.tar.bz2)" + + # strawberry pie, Cappuccino and a Gauloises (it's a good thing) + [[ -n ${PIE_VER} ]] && \ + GCC_SRC_URI="${GCC_SRC_URI} !nopie? ( $(gentoo_urls ${PIE_CORE}) )" + + # gcc bounds checking patch + if [[ -n ${HTB_VER} ]] ; then + local HTBFILE="bounds-checking-gcc-${HTB_GCC_VER}-${HTB_VER}.patch.bz2" + GCC_SRC_URI="${GCC_SRC_URI} + boundschecking? ( + mirror://sourceforge/boundschecking/${HTBFILE} + $(gentoo_urls ${HTBFILE}) + )" + fi + + # support for the D language + [[ -n ${D_VER} ]] && \ + GCC_SRC_URI="${GCC_SRC_URI} d? ( mirror://sourceforge/dgcc/gdc-${D_VER}-src.tar.bz2 )" + + echo "${GCC_SRC_URI}" +} +S=$(gcc_get_s_dir) +SRC_URI=$(get_gcc_src_uri) +#---->> S + SRC_URI essentials >>---- + + +#---->> support checks <<---- + +# Grab a variable from the build system (taken from linux-info.eclass) +get_make_var() { + local var=$1 makefile=${2:-${WORKDIR}/build/Makefile} + echo -e "e:\\n\\t@echo \$(${var})\\ninclude ${makefile}" | \ + r=${makefile%/*} emake --no-print-directory -s -f - 2>/dev/null +} +XGCC() { get_make_var GCC_FOR_TARGET ; } + +# The gentoo piessp patches allow for 3 configurations: +# 1) PIE+SSP by default +# 2) PIE by default +# 3) SSP by default +hardened_gcc_works() { + if [[ $1 == "pie" ]] ; then + # $gcc_cv_ld_pie is unreliable as it simply take the output of + # `ld --help | grep -- -pie`, that reports the option in all cases, also if + # the loader doesn't actually load the resulting executables. + # To avoid breakage, blacklist FreeBSD here at least + [[ ${CTARGET} == *-freebsd* ]] && return 1 + + want_pie || return 1 + hardened_gcc_is_stable pie && return 0 + if has ~$(tc-arch) ${ACCEPT_KEYWORDS} ; then + hardened_gcc_check_unsupported pie && return 1 + ewarn "Allowing pie-by-default for an unstable arch ($(tc-arch))" + return 0 + fi + return 1 + elif [[ $1 == "ssp" ]] ; then + [[ -z ${PP_VER} ]] && return 1 + hardened_gcc_is_stable ssp && return 0 + if has ~$(tc-arch) ${ACCEPT_KEYWORDS} ; then + hardened_gcc_check_unsupported ssp && return 1 + ewarn "Allowing ssp-by-default for an unstable arch ($(tc-arch))" + return 0 + fi + return 1 + else + # laziness ;) + hardened_gcc_works pie || return 1 + hardened_gcc_works ssp || return 1 + return 0 + fi +} + +hardened_gcc_is_stable() { + if [[ $1 == "pie" ]] ; then + # HARDENED_* variables are deprecated and here for compatibility + local tocheck="${HARDENED_PIE_WORKS} ${HARDENED_GCC_WORKS}" + if [[ ${CTARGET} == *-uclibc* ]] ; then + tocheck="${tocheck} ${PIE_UCLIBC_STABLE}" + else + tocheck="${tocheck} ${PIE_GLIBC_STABLE}" + fi + elif [[ $1 == "ssp" ]] ; then + # ditto + local tocheck="${HARDENED_SSP_WORKS} ${HARDENED_GCC_WORKS}" + if [[ ${CTARGET} == *-uclibc* ]] ; then + tocheck="${tocheck} ${SSP_UCLIBC_STABLE}" + else + tocheck="${tocheck} ${SSP_STABLE}" + fi + else + die "hardened_gcc_stable needs to be called with pie or ssp" + fi + + hasq $(tc-arch) ${tocheck} && return 0 + return 1 +} + +hardened_gcc_check_unsupported() { + local tocheck="" + # if a variable is unset, we assume that all archs are unsupported. since + # this function is never called if hardened_gcc_is_stable returns true, + # this shouldn't cause problems... however, allowing this logic to work + # even with the variables unset will break older ebuilds that dont use them. + if [[ $1 == "pie" ]] ; then + if [[ ${CTARGET} == *-uclibc* ]] ; then + [[ -z ${PIE_UCLIBC_UNSUPPORTED} ]] && return 0 + tocheck="${tocheck} ${PIE_UCLIBC_UNSUPPORTED}" + else + [[ -z ${PIE_GLIBC_UNSUPPORTED} ]] && return 0 + tocheck="${tocheck} ${PIE_GLIBC_UNSUPPORTED}" + fi + elif [[ $1 == "ssp" ]] ; then + if [[ ${CTARGET} == *-uclibc* ]] ; then + [[ -z ${SSP_UCLIBC_UNSUPPORTED} ]] && return 0 + tocheck="${tocheck} ${SSP_UCLIBC_UNSUPPORTED}" + else + [[ -z ${SSP_UNSUPPORTED} ]] && return 0 + tocheck="${tocheck} ${SSP_UNSUPPORTED}" + fi + else + die "hardened_gcc_check_unsupported needs to be called with pie or ssp" + fi + + hasq $(tc-arch) ${tocheck} && return 0 + return 1 +} + +has_libssp() { + [[ -e /$(get_libdir)/libssp.so ]] && return 0 + return 1 +} + +want_libssp() { + [[ ${GCC_LIBSSP_SUPPORT} == "true" ]] || return 1 + has_libssp || return 1 + [[ -n ${PP_VER} ]] || return 1 + return 0 +} + +_want_stuff() { + local var=$1 flag=$2 + [[ -z ${!var} ]] && return 1 + use ${flag} && return 0 + return 1 +} +want_boundschecking() { _want_stuff HTB_VER boundschecking ; } +want_pie() { _want_stuff PIE_VER !nopie ; } +want_ssp() { _want_stuff PP_VER !nossp ; } + +want_split_specs() { + [[ ${SPLIT_SPECS} == "true" ]] && want_pie +} + +# This function checks whether or not glibc has the support required to build +# Position Independant Executables with gcc. +glibc_have_pie() { + if [[ ! -f ${ROOT}/usr/$(get_libdir)/Scrt1.o ]] ; then + echo + ewarn "Your glibc does not have support for pie, the file Scrt1.o is missing" + ewarn "Please update your glibc to a proper version or disable hardened" + echo + return 1 + fi +} + +# This function determines whether or not libc has been patched with stack +# smashing protection support. +libc_has_ssp() { + [[ ${ROOT} != "/" ]] && return 0 + + # lib hacks taken from sandbox configure + echo 'int main(){}' > "${T}"/libctest.c + LC_ALL=C gcc "${T}"/libctest.c -lc -o libctest -Wl,-verbose &> "${T}"/libctest.log || return 1 + local libc_file=$(awk '/attempt to open/ { if (($4 ~ /\/libc\.so/) && ($5 == "succeeded")) LIBC = $4; }; END {print LIBC}' "${T}"/libctest.log) + + [[ -z ${libc_file} ]] && die "Unable to find a libc !?" + + # Check for gcc-4.x style ssp support + if [[ -n $(readelf -s "${libc_file}" 2>/dev/null | \ + grep 'FUNC.*GLOBAL.*__stack_chk_fail') ]] + then + return 0 + else + # Check for gcc-3.x style ssp support + if [[ -n $(readelf -s "${libc_file}" 2>/dev/null | \ + grep 'OBJECT.*GLOBAL.*__guard') ]] && \ + [[ -n $(readelf -s "${libc_file}" 2>/dev/null | \ + grep 'FUNC.*GLOBAL.*__stack_smash_handler') ]] + then + return 0 + elif is_crosscompile ; then + die "'${libc_file}' was detected w/out ssp, that sucks (a lot)" + else + return 1 + fi + fi +} + +# This is to make sure we don't accidentally try to enable support for a +# language that doesnt exist. GCC 3.4 supports f77, while 4.0 supports f95, etc. +# +# Also add a hook so special ebuilds (kgcc64) can control which languages +# exactly get enabled +gcc-lang-supported() { + grep ^language=\"${1}\" "${S}"/gcc/*/config-lang.in > /dev/null || return 1 + [[ -z ${TOOLCHAIN_ALLOWED_LANGS} ]] && return 0 + has $1 ${TOOLCHAIN_ALLOWED_LANGS} +} + +#----<< support checks >>---- + +#---->> specs + env.d logic <<---- + +# defaults to enable for all hardened toolchains +gcc_common_hard="-DEFAULT_RELRO -DEFAULT_BIND_NOW" + +# configure to build with the hardened GCC specs as the default +make_gcc_hard() { + if hardened_gcc_works ; then + einfo "Updating gcc to use automatic PIE + SSP building ..." + sed -e "s|^HARD_CFLAGS = |HARD_CFLAGS = -DEFAULT_PIE_SSP ${gcc_common_hard} |" \ + -i "${S}"/gcc/Makefile.in || die "Failed to update gcc!" + elif hardened_gcc_works pie ; then + einfo "Updating gcc to use automatic PIE building ..." + ewarn "SSP has not been enabled by default" + sed -e "s|^HARD_CFLAGS = |HARD_CFLAGS = -DEFAULT_PIE ${gcc_common_hard} |" \ + -i "${S}"/gcc/Makefile.in || die "Failed to update gcc!" + elif hardened_gcc_works ssp ; then + einfo "Updating gcc to use automatic SSP building ..." + ewarn "PIE has not been enabled by default" + sed -e "s|^HARD_CFLAGS = |HARD_CFLAGS = -DEFAULT_SSP ${gcc_common_hard} |" \ + -i "${S}"/gcc/Makefile.in || die "Failed to update gcc!" + else + # do nothing if hardened isnt supported, but dont die either + ewarn "hardened is not supported for this arch in this gcc version" + ebeep + return 0 + fi + + # rebrand to make bug reports easier + release_version="${release_version/Gentoo/Gentoo Hardened}" +} + +# now we generate different spec files so that the user can select a compiler +# that enforces certain features in gcc itself and so we don't have to worry +# about a certain package ignoring CFLAGS/LDFLAGS +_create_specs_file() { + # Usage: _create_specs_file + local uflag=$1 name=$2 flags=${*:3} + ebegin "Creating a ${name} gcc specs file" + pushd "${WORKDIR}"/build/gcc > /dev/null + if [[ -z ${uflag} ]] || use ${uflag} ; then + # backup the compiler first + cp Makefile Makefile.orig + sed -i -e '/^HARD_CFLAGS/s:=.*:='"${flags}"':' Makefile + mv xgcc xgcc.foo + mv gcc.o gcc.o.foo + emake -s xgcc + $(XGCC) -dumpspecs > "${WORKDIR}"/build/${name}.specs + # restore everything to normal + mv gcc.o.foo gcc.o + mv xgcc.foo xgcc + mv Makefile.orig Makefile + else + $(XGCC) -dumpspecs > "${WORKDIR}"/build/${name}.specs + fi + popd > /dev/null + eend $([[ -s ${WORKDIR}/build/${name}.specs ]] ; echo $?) +} +create_vanilla_specs_file() { _create_specs_file hardened vanilla ; } +create_hardened_specs_file() { _create_specs_file !hardened hardened ${gcc_common_hard} -DEFAULT_PIE_SSP ; } +create_hardenednossp_specs_file() { _create_specs_file "" hardenednossp ${gcc_common_hard} -DEFAULT_PIE ; } +create_hardenednopie_specs_file() { _create_specs_file "" hardenednopie ${gcc_common_hard} -DEFAULT_SSP ; } +create_hardenednopiessp_specs_file() { _create_specs_file "" hardenednopiessp ${gcc_common_hard} ; } + +split_out_specs_files() { + local s spec_list="hardenednopiessp vanilla" + if hardened_gcc_works ; then + spec_list="${spec_list} hardened hardenednossp hardenednopie" + elif hardened_gcc_works pie ; then + spec_list="${spec_list} hardenednossp" + elif hardened_gcc_works ssp ; then + spec_list="${spec_list} hardenednopie" + fi + for s in ${spec_list} ; do + create_${s}_specs_file || return 1 + done +} + +create_gcc_env_entry() { + dodir /etc/env.d/gcc + local gcc_envd_base="/etc/env.d/gcc/${CTARGET}-${GCC_CONFIG_VER}" + + if [[ -z $1 ]] ; then + gcc_envd_file="${D}${gcc_envd_base}" + # I'm leaving the following commented out to remind me that it + # was an insanely -bad- idea. Stuff broke. GCC_SPECS isnt unset + # on chroot or in non-toolchain.eclass gcc ebuilds! + #gcc_specs_file="${LIBPATH}/specs" + gcc_specs_file="" + else + gcc_envd_file="${D}${gcc_envd_base}-$1" + gcc_specs_file="${LIBPATH}/$1.specs" + fi + + # phase PATH/ROOTPATH out ... + echo "PATH=\"${BINPATH}\"" > ${gcc_envd_file} + echo "ROOTPATH=\"${BINPATH}\"" >> ${gcc_envd_file} + echo "GCC_PATH=\"${BINPATH}\"" >> ${gcc_envd_file} + + if use multilib && ! has_multilib_profile; then + LDPATH="${LIBPATH}" + for path in 32 64 ; do + [[ -d ${LIBPATH}/${path} ]] && LDPATH="${LDPATH}:${LIBPATH}/${path}" + done + else + local MULTIDIR + LDPATH="${LIBPATH}" + + # We want to list the default ABI's LIBPATH first so libtool + # searches that directory first. This is a temporary + # workaround for libtool being stupid and using .la's from + # conflicting ABIs by using the first one in the search path + + local abi=${DEFAULT_ABI} + local MULTIDIR=$($(XGCC) $(get_abi_CFLAGS ${abi}) --print-multi-directory) + if [[ ${MULTIDIR} == "." ]] ; then + LDPATH=${LIBPATH} + else + LDPATH=${LIBPATH}/${MULTIDIR} + fi + + for abi in $(get_all_abis) ; do + [[ ${abi} == ${DEFAULT_ABI} ]] && continue + + MULTIDIR=$($(XGCC) $(get_abi_CFLAGS ${abi}) --print-multi-directory) + if [[ ${MULTIDIR} == "." ]] ; then + LDPATH=${LDPATH}:${LIBPATH} + else + LDPATH=${LDPATH}:${LIBPATH}/${MULTIDIR} + fi + done + fi + + echo "LDPATH=\"${LDPATH}\"" >> ${gcc_envd_file} + echo "MANPATH=\"${DATAPATH}/man\"" >> ${gcc_envd_file} + echo "INFOPATH=\"${DATAPATH}/info\"" >> ${gcc_envd_file} + echo "STDCXX_INCDIR=\"${STDCXX_INCDIR##*/}\"" >> ${gcc_envd_file} + + is_crosscompile && echo "CTARGET=${CTARGET}" >> ${gcc_envd_file} + + # Set which specs file to use + [[ -n ${gcc_specs_file} ]] && echo "GCC_SPECS=\"${gcc_specs_file}\"" >> ${gcc_envd_file} +} + +add_profile_eselect_conf() { + local compiler_config_file=$1 + local abi=$2 + local specs=$3 + local gcc_specs_file + local var + + if [[ -z ${specs} ]] ; then + # I'm leaving the following commented out to remind me that it + # was an insanely -bad- idea. Stuff broke. GCC_SPECS isnt unset + # on chroot or in non-toolchain.eclass gcc ebuilds! + #gcc_specs_file="${LIBPATH}/specs" + gcc_specs_file="" + + if use hardened ; then + specs="hardened" + else + specs="vanilla" + fi + else + gcc_specs_file="${LIBPATH}/${specs}.specs" + fi + + echo >> ${compiler_config_file} + if ! is_multilib ; then + echo "[${specs}]" >> ${compiler_config_file} + echo " ctarget=${CTARGET}" >> ${compiler_config_file} + else + echo "[${abi}-${specs}]" >> ${compiler_config_file} + var="CTARGET_${abi}" + if [[ -n ${!var} ]] ; then + echo " ctarget=${!var}" >> ${compiler_config_file} + else + var="CHOST_${abi}" + if [[ -n ${!var} ]] ; then + echo " ctarget=${!var}" >> ${compiler_config_file} + else + echo " ctarget=${CTARGET}" >> ${compiler_config_file} + fi + fi + fi + + local MULTIDIR=$($(XGCC) $(get_abi_CFLAGS ${abi}) --print-multi-directory) + local LDPATH=${LIBPATH} + if [[ ${MULTIDIR} != "." ]] ; then + LDPATH="${LIBPATH}/${MULTIDIR}" + fi + + echo " ldpath=${LDPATH}" >> ${compiler_config_file} + + if [[ -n ${gcc_specs_file} ]] ; then + echo " specs=${gcc_specs_file}" >> ${compiler_config_file} + fi + + var="CFLAGS_${abi}" + if [[ -n ${!var} ]] ; then + echo " cflags=${!var}" >> ${compiler_config_file} + fi +} + +create_eselect_conf() { + local config_dir="/etc/eselect/compiler" + local compiler_config_file="${D}/${config_dir}/${CTARGET}-${GCC_CONFIG_VER}.conf" + local abi + + dodir ${config_dir} + + echo "[global]" > ${compiler_config_file} + echo " version=${CTARGET}-${GCC_CONFIG_VER}" >> ${compiler_config_file} + echo " binpath=${BINPATH}" >> ${compiler_config_file} + echo " manpath=${DATAPATH}/man" >> ${compiler_config_file} + echo " infopath=${DATAPATH}/info" >> ${compiler_config_file} + echo " alias_cc=gcc" >> ${compiler_config_file} + echo " stdcxx_incdir=${STDCXX_INCDIR##*/}" >> ${compiler_config_file} + echo " bin_prefix=${CTARGET}" >> ${compiler_config_file} + + # Per spyderous, it is best not to alias the fortran compilers + #if [[ -x "${D}/${BINPATH}/${CTARGET}-g77" ]] ; then + # echo " alias_gfortran=g77" >> ${compiler_config_file} + #elif [[ -x "${D}/${BINPATH}/${CTARGET}-gfortran" ]] ; then + # echo " alias_g77=gfortran" >> ${compiler_config_file} + #fi + + for abi in $(get_all_abis) ; do + add_profile_eselect_conf "${compiler_config_file}" "${abi}" + + if want_split_specs ; then + if use hardened ; then + add_profile_eselect_conf "${compiler_config_file}" "${abi}" vanilla + elif hardened_gcc_works ; then + add_profile_eselect_conf "${compiler_config_file}" "${abi}" hardened + fi + + if hardened_gcc_works || hardened_gcc_works pie ; then + add_profile_eselect_conf "${compiler_config_file}" "${abi}" hardenednossp + fi + + if hardened_gcc_works || hardened_gcc_works ssp ; then + add_profile_eselect_conf "${compiler_config_file}" "${abi}" hardenednopie + fi + + add_profile_eselect_conf "${compiler_config_file}" "${abi}" hardenednopiessp + fi + done +} + +#----<< specs + env.d logic >>---- + +#---->> pkg_* <<---- +gcc_pkg_setup() { + [[ -z ${ETYPE} ]] && die "Your ebuild needs to set the ETYPE variable" + + if [[ ( $(tc-arch) == "amd64" || $(tc-arch) == "ppc64" ) && ( ${LD_PRELOAD} == "/lib/libsandbox.so" || ${LD_PRELOAD} == "/usr/lib/libsandbox.so" ) ]] && is_multilib ; then + eerror "Sandbox in your installed portage does not support compilation." + eerror "of a multilib gcc. Please set FEATURES=-sandbox and try again." + eerror "After you have a multilib gcc, re-emerge portage to have a working sandbox." + die "No 32bit sandbox. Retry with FEATURES=-sandbox." + fi + + if [[ ${ETYPE} == "gcc-compiler" ]] ; then + case $(tc-arch) in + mips) + # Must compile for mips64-linux target if we want n32/n64 support + case "${CTARGET}" in + mips64*) ;; + *) + if use n32 || use n64; then + eerror "n32/n64 can only be used when target host is mips64*-*-linux-*"; + die "Invalid USE flags for CTARGET ($CTARGET)"; + fi + ;; + esac + + #cannot have both n32 & n64 without multilib + if use n32 && use n64 && ! is_multilib; then + eerror "Please enable multilib if you want to use both n32 & n64"; + die "Invalid USE flag combination"; + fi + ;; + esac + + # Setup variables which would normally be in the profile + if is_crosscompile ; then + multilib_env ${CTARGET} + if ! use multilib ; then + MULTILIB_ABIS=${DEFAULT_ABI} + fi + fi + + # we dont want to use the installed compiler's specs to build gcc! + unset GCC_SPECS + fi + + want_libssp && libc_has_ssp && \ + die "libssp cannot be used with a glibc that has been patched to provide ssp symbols" +} + +gcc-compiler_pkg_preinst() { + : +} + +gcc-compiler_pkg_postinst() { + export LD_LIBRARY_PATH=${LIBPATH}:${LD_LIBRARY_PATH} + + if has_version 'app-admin/eselect-compiler' ; then + do_eselect_compiler + else + do_gcc_config + fi + + if ! is_crosscompile ; then + echo + ewarn "If you have issues with packages unable to locate libstdc++.la," + ewarn "then try running 'fix_libtool_files.sh' on the old gcc versions." + echo + fi + + # If our gcc-config version doesn't like '-' in it's version string, + # tell our users that gcc-config will yell at them, but it's all good. + if ! has_version '>=sys-devel/gcc-config-1.3.10-r1' && [[ ${GCC_CONFIG_VER/-/} != ${GCC_CONFIG_VER} ]] ; then + ewarn "Your version of gcc-config will issue about having an invalid profile" + ewarn "when switching to this profile. It is safe to ignore this warning," + ewarn "and this problem has been corrected in >=sys-devel/gcc-config-1.3.10-r1." + fi + + if ! is_crosscompile && ! use multislot && [[ ${GCCMAJOR}.${GCCMINOR} == 3.4 ]] ; then + echo + ewarn "You should make sure to rebuild all your C++ packages when" + ewarn "upgrading between different versions of gcc. For example," + ewarn "when moving to gcc-3.4 from gcc-3.3, emerge gentoolkit and run:" + ewarn " # revdep-rebuild --library libstdc++.so.5" + echo + ewarn "For more information on the steps to take when upgrading " + ewarn "from gcc-3.3 please refer to: " + ewarn "http://www.gentoo.org/doc/en/gcc-upgrading.xml" + echo + fi + + if ! is_crosscompile ; then + # hack to prevent collisions between SLOT + [[ ! -d ${ROOT}/lib/rcscripts/awk ]] \ + && mkdir -p "${ROOT}"/lib/rcscripts/awk + [[ ! -d ${ROOT}/sbin ]] \ + && mkdir -p "${ROOT}"/sbin + cp "${ROOT}/${DATAPATH}"/fixlafiles.awk "${ROOT}"/lib/rcscripts/awk/ || die "installing fixlafiles.awk" + cp "${ROOT}/${DATAPATH}"/fix_libtool_files.sh "${ROOT}"/sbin/ || die "installing fix_libtool_files.sh" + + [[ ! -d ${ROOT}/usr/bin ]] \ + && mkdir -p "${ROOT}"/usr/bin + # Since these aren't critical files and portage sucks with + # handling of binpkgs, don't require these to be found + for x in "${ROOT}/${DATAPATH}"/c{89,99} ; do + if [[ -e ${x} ]]; then + cp ${x} "${ROOT}"/usr/bin/ || die "installing c89/c99" + fi + done + fi +} + +gcc-compiler_pkg_prerm() { + # Don't let these files be uninstalled #87647 + touch -c "${ROOT}"/sbin/fix_libtool_files.sh \ + "${ROOT}"/lib/rcscripts/awk/fixlafiles.awk +} + +gcc-compiler_pkg_postrm() { + # to make our lives easier (and saner), we do the fix_libtool stuff here. + # rather than checking SLOT's and trying in upgrade paths, we just see if + # the common libstdc++.la exists in the ${LIBPATH} of the gcc that we are + # unmerging. if it does, that means this was a simple re-emerge. + + # clean up the cruft left behind by cross-compilers + if is_crosscompile ; then + if [[ -z $(ls "${ROOT}"/etc/env.d/gcc/${CTARGET}* 2>/dev/null) ]] ; then + rm -f "${ROOT}"/etc/env.d/gcc/config-${CTARGET} + rm -f "${ROOT}"/etc/env.d/??gcc-${CTARGET} + rm -f "${ROOT}"/usr/bin/${CTARGET}-{gcc,{g,c}++}{,32,64} + fi + return 0 + fi + + # ROOT isnt handled by the script + [[ ${ROOT} != "/" ]] && return 0 + + if [[ ! -e ${LIBPATH}/libstdc++.so ]] ; then + einfo "Running 'fix_libtool_files.sh ${GCC_RELEASE_VER}'" + /sbin/fix_libtool_files.sh ${GCC_RELEASE_VER} + if [[ -n ${BRANCH_UPDATE} ]] ; then + einfo "Running 'fix_libtool_files.sh ${GCC_RELEASE_VER}-${BRANCH_UPDATE}'" + /sbin/fix_libtool_files.sh ${GCC_RELEASE_VER}-${BRANCH_UPDATE} + fi + fi + + return 0 +} + +#---->> 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: +# +# 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 + want_pie && use hardened && glibc_have_pie + + if use hardened ; then + einfo "updating configuration to build hardened GCC" + make_gcc_hard || die "failed to make gcc hard" + fi +} +gcc-library_src_unpack() { + : +} +guess_patch_type_in_dir() { + [[ -n $(ls "$1"/*.bz2 2>/dev/null) ]] \ + && EPATCH_SUFFIX="patch.bz2" \ + || EPATCH_SUFFIX="patch" +} +do_gcc_rename_java_bins() { + # bug #139918 - conflict between gcc and java-config-2 for ownership of + # /usr/bin/rmi{c,registry}. Done with mv & sed rather than a patch + # because patches would be large (thanks to the rename of man files), + # and it's clear from the sed invocations that all that changes is the + # rmi{c,registry} names to grmi{c,registry} names. + # Kevin F. Quinn 2006-07-12 + einfo "Renaming jdk executables rmic and rmiregistry to grmic and grmiregistry." + # 1) Move the man files if present (missing prior to gcc-3.4) + for manfile in rmic rmiregistry; do + [[ -f ${S}/gcc/doc/${manfile}.1 ]] || continue + mv ${S}/gcc/doc/${manfile}.1 ${S}/gcc/doc/g${manfile}.1 + done + # 2) Fixup references in the docs if present (mission prior to gcc-3.4) + for jfile in gcc/doc/gcj.info gcc/doc/grmic.1 gcc/doc/grmiregistry.1 gcc/java/gcj.texi; do + [[ -f ${S}/${jfile} ]] || continue + sed -i -e 's:rmiregistry:grmiregistry:g' ${S}/${jfile} || + die "Failed to fixup file ${jfile} for rename to grmiregistry" + sed -i -e 's:rmic:grmic:g' ${S}/${jfile} || + die "Failed to fixup file ${jfile} for rename to grmic" + done + # 3) Fixup Makefiles to build the changed executable names + # These are present in all 3.x versions, and are the important bit + # to get gcc to build with the new names. + for jfile in libjava/Makefile.am libjava/Makefile.in gcc/java/Make-lang.in; do + sed -i -e 's:rmiregistry:grmiregistry:g' ${S}/${jfile} || + die "Failed to fixup file ${jfile} for rename to grmiregistry" + # Careful with rmic on these files; it's also the name of a directory + # which should be left unchanged. Replace occurrences of 'rmic$', + # 'rmic_' and 'rmic '. + sed -i -e 's:rmic\([$_ ]\):grmic\1:g' ${S}/${jfile} || + die "Failed to fixup file ${jfile} for rename to grmic" + done +} +gcc_src_unpack() { + local release_version="Gentoo ${GCC_PVR}" + + [[ -z ${UCLIBC_VER} ]] && [[ ${CTARGET} == *-uclibc* ]] && die "Sorry, this version does not support uClibc" + + gcc_quick_unpack + exclude_gcc_patches + + cd "${S}" + + if ! use vanilla ; then + if [[ -n ${PATCH_VER} ]] ; then + guess_patch_type_in_dir "${WORKDIR}"/patch + EPATCH_MULTI_MSG="Applying Gentoo patches ..." \ + epatch "${WORKDIR}"/patch + release_version="${release_version} p${PATCH_VER}" + fi + if [[ -n ${UCLIBC_VER} ]] ; then + guess_patch_type_in_dir "${WORKDIR}"/uclibc + EPATCH_MULTI_MSG="Applying uClibc patches ..." \ + epatch "${WORKDIR}"/uclibc + fi + fi + do_gcc_HTB_patches + do_gcc_SSP_patches + do_gcc_PIE_patches + + ${ETYPE}_src_unpack || die "failed to ${ETYPE}_src_unpack" + + # protoize don't build on FreeBSD, skip it + if ! is_crosscompile && ! use elibc_FreeBSD ; then + # enable protoize / unprotoize + sed -i -e '/^LANGUAGES =/s:$: proto:' "${S}"/gcc/Makefile.in + fi + + fix_files="" + for x in contrib/test_summary libstdc++-v3/scripts/check_survey.in ; do + [[ -e ${x} ]] && fix_files="${fix_files} ${x}" + done + ht_fix_file ${fix_files} */configure *.sh */Makefile.in + + if ! is_crosscompile && is_multilib && \ + [[ ( $(tc-arch) == "amd64" || $(tc-arch) == "ppc64" ) && -z ${SKIP_MULTILIB_HACK} ]] ; then + disgusting_gcc_multilib_HACK || die "multilib hack failed" + fi + + local version_string=${GCC_CONFIG_VER} + + # Backwards support... add the BRANCH_UPDATE for 3.3.5-r1 and 3.4.3-r1 + # which set it directly rather than using ${GCC_PV} + if [[ ${GCC_PVR} == "3.3.5-r1" || ${GCC_PVR} = "3.4.3-r1" ]] ; then + version_string="${version_string} ${BRANCH_UPDATE}" + fi + + einfo "patching gcc version: ${version_string} (${release_version})" + gcc_version_patch "${version_string}" "${release_version}" + + if [[ ${GCCMAJOR}.${GCCMINOR} > 4.0 ]] ; then + if [[ -n ${SNAPSHOT} || -n ${PRERELEASE} ]] ; then + echo ${PV/_/-} > "${S}"/gcc/BASE-VER + echo "" > "${S}"/gcc/DATESTAMP + fi + fi + + # Misdesign in libstdc++ (Redhat) + if [[ ${GCCMAJOR} -ge 3 ]] && [[ -e ${S}/libstdc++-v3/config/cpu/i486/atomicity.h ]] ; then + cp -pPR "${S}"/libstdc++-v3/config/cpu/i{4,3}86/atomicity.h + fi + + # disable --as-needed from being compiled into gcc specs + # natively when using a gcc version < 3.4.4 + # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14992 + if [[ ${GCCMAJOR} < 3 ]] || \ + [[ ${GCCMAJOR}.${GCCMINOR} < 3.4 ]] || \ + [[ ${GCCMAJOR}.${GCCMINOR}.${GCCMICRO} < 3.4.4 ]] + then + sed -i -e s/HAVE_LD_AS_NEEDED/USE_LD_AS_NEEDED/g "${S}"/gcc/config.in + fi + + # In gcc 3.3.x and 3.4.x, rename the java bins to gcc-specific names + # in line with gcc-4. + if [[ ${GCCMAJOR} == 3 ]] && + [[ ${GCCMINOR} -ge 3 ]] + then + do_gcc_rename_java_bins + fi + + # Fixup libtool to correctly generate .la files with portage + cd "${S}" + elibtoolize --portage --shallow --no-uclibc + + gnuconfig_update + + # update configure files + local f + einfo "Fixing misc issues in configure files" + [[ ${GCCMAJOR} -ge 4 ]] && epatch "${GCC_FILESDIR}"/gcc-configure-texinfo.patch + for f in $(grep -l 'autoconf version 2.13' $(find "${S}" -name configure)) ; do + ebegin " Updating ${f/${S}\/} [LANG]" + patch "${f}" "${GCC_FILESDIR}"/gcc-configure-LANG.patch >& "${T}"/configure-patch.log \ + || eerror "Please file a bug about this" + eend $? + done + + if [[ -x contrib/gcc_update ]] ; then + einfo "Touching generated files" + ./contrib/gcc_update --touch | \ + while read f ; do + einfo " ${f%%...}" + done + fi + + disable_multilib_libjava || die "failed to disable multilib java" +} + +gcc-library-configure() { + # multilib support + [[ ${GCC_TARGET_NO_MULTILIB} == "true" ]] \ + && confgcc="${confgcc} --disable-multilib" \ + || confgcc="${confgcc} --enable-multilib" +} + +gcc-compiler-configure() { + # multilib support + if is_multilib ; then + confgcc="${confgcc} --enable-multilib" + elif [[ ${CTARGET} == *-linux* ]] ; then + confgcc="${confgcc} --disable-multilib" + fi + + if tc_version_is_at_least "4.0" ; then + if has mudflap ${IUSE} ; then + confgcc="${confgcc} $(use_enable mudflap libmudflap)" + else + confgcc="${confgcc} --disable-libmudflap" + fi + + if want_libssp ; then + confgcc="${confgcc} --enable-libssp" + else + export gcc_cv_libc_provides_ssp=yes + confgcc="${confgcc} --disable-libssp" + fi + 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 ! is_gcj ; then + confgcc="${confgcc} --disable-libgcj" + elif use gtk ; then + confgcc="${confgcc} --enable-java-awt=gtk" + fi + + case $(tc-arch) in + # Add --with-abi flags to set default MIPS ABI + mips) + local mips_abi="" + use n64 && mips_abi="--with-abi=64" + use n32 && mips_abi="--with-abi=n32" + [[ -n ${mips_abi} ]] && confgcc="${confgcc} ${mips_abi}" + ;; + # Default arch for x86 is normally i386, lets give it a bump + # since glibc will do so based on CTARGET anyways + x86) + confgcc="${confgcc} --with-arch=${CTARGET%%-*}" + ;; + # Enable sjlj exceptions for backward compatibility on hppa + hppa) + [[ ${GCC_PV:0:1} == "3" ]] && \ + confgcc="${confgcc} --enable-sjlj-exceptions" + ;; + esac + + GCC_LANG="c" + is_cxx && GCC_LANG="${GCC_LANG},c++" + is_d && GCC_LANG="${GCC_LANG},d" + is_gcj && GCC_LANG="${GCC_LANG},java" + if is_objc || is_objcxx ; then + GCC_LANG="${GCC_LANG},objc" + use objc-gc && confgcc="${confgcc} --enable-objc-gc" + is_objcxx && GCC_LANG="${GCC_LANG},obj-c++" + fi + + # fortran support just got sillier! the lang value can be f77 for + # fortran77, f95 for fortran95, or just plain old fortran for the + # currently supported standard depending on gcc version. + is_fortran && GCC_LANG="${GCC_LANG},fortran" + is_f77 && GCC_LANG="${GCC_LANG},f77" + is_f95 && GCC_LANG="${GCC_LANG},f95" + + # We do NOT want 'ADA support' in here! + # is_ada && GCC_LANG="${GCC_LANG},ada" + + einfo "configuring for GCC_LANG: ${GCC_LANG}" +} + +# Other than the variables described for gcc_setup_variables, the following +# will alter tha behavior of gcc_do_configure: +# +# CTARGET +# CBUILD +# Enable building for a target that differs from CHOST +# +# GCC_TARGET_NO_MULTILIB +# Disable multilib. Useful when building single library targets. +# +# GCC_LANG +# Enable support for ${GCC_LANG} languages. defaults to just "c" +# +# Travis Tilley (04 Sep 2004) +# +gcc_do_configure() { + local confgcc + + # Set configuration based on path variables + confgcc="${confgcc} \ + --prefix=${PREFIX} \ + --bindir=${BINPATH} \ + --includedir=${INCLUDEPATH} \ + --datadir=${DATAPATH} \ + --mandir=${DATAPATH}/man \ + --infodir=${DATAPATH}/info \ + --with-gxx-include-dir=${STDCXX_INCDIR}" + + # All our cross-compile logic goes here ! woo ! + confgcc="${confgcc} --host=${CHOST}" + if is_crosscompile || tc-is-cross-compiler ; then + # Straight from the GCC install doc: + # "GCC has code to correctly determine the correct value for target + # for nearly all native systems. Therefore, we highly recommend you + # not provide a configure target when configuring a native compiler." + confgcc="${confgcc} --target=${CTARGET}" + fi + [[ -n ${CBUILD} ]] && confgcc="${confgcc} --build=${CBUILD}" + + # ppc altivec support + confgcc="${confgcc} $(use_enable altivec)" + + [[ $(tc-is-softfloat) == "yes" ]] && confgcc="${confgcc} --with-float=soft" + + # Native Language Support + if use nls && ! use build ; then + confgcc="${confgcc} --enable-nls --without-included-gettext" + else + confgcc="${confgcc} --disable-nls" + fi + + # reasonably sane globals (hopefully) + # --disable-libunwind-exceptions needed till unwind sections get fixed. see ps.m for details + confgcc="${confgcc} \ + --with-system-zlib \ + --disable-checking \ + --disable-werror \ + --enable-secureplt \ + --disable-libunwind-exceptions" + + # etype specific configuration + einfo "running ${ETYPE}-configure" + ${ETYPE}-configure || die + + # if not specified, assume we are building for a target that only + # requires C support + GCC_LANG=${GCC_LANG:-c} + confgcc="${confgcc} --enable-languages=${GCC_LANG}" + + if is_crosscompile ; then + # When building a stage1 cross-compiler (just C compiler), we have to + # disable a bunch of features or gcc goes boom + local needed_libc="" + case ${CTARGET} in + *-linux) needed_libc=no-fucking-clue;; + *-dietlibc) needed_libc=dietlibc;; + *-elf) needed_libc=newlib;; + *-freebsd*) needed_libc=freebsd-lib;; + *-gnu*) needed_libc=glibc;; + *-klibc) needed_libc=klibc;; + *-uclibc*) needed_libc=uclibc;; + mingw*|*-mingw*) needed_libc=mingw-runtime;; + avr) confgcc="${confgcc} --enable-shared --disable-threads";; + esac + if [[ -n ${needed_libc} ]] ; then + if ! has_version ${CATEGORY}/${needed_libc} ; then + confgcc="${confgcc} --disable-shared --disable-threads --without-headers" + elif built_with_use --hidden --missing false ${CATEGORY}/${needed_libc} crosscompile_opts_headers-only ; then + confgcc="${confgcc} --disable-shared --with-sysroot=${PREFIX}/${CTARGET}" + else + confgcc="${confgcc} --with-sysroot=${PREFIX}/${CTARGET}" + fi + fi + + if [[ ${GCCMAJOR}.${GCCMINOR} > 4.1 ]] ; then + confgcc="${confgcc} --disable-bootstrap --disable-libgomp" + fi + elif [[ ${CHOST} != mingw* ]] && [[ ${CHOST} != *-mingw* ]] ; then + confgcc="${confgcc} --enable-shared --enable-threads=posix" + fi + [[ ${CTARGET} == *-elf ]] && confgcc="${confgcc} --with-newlib" + # __cxa_atexit is "essential for fully standards-compliant handling of + # destructors", but apparently requires glibc. + # --enable-sjlj-exceptions : currently the unwind stuff seems to work + # for statically linked apps but not dynamic + # so use setjmp/longjmp exceptions by default + if [[ ${CTARGET} == *-uclibc* ]] ; then + confgcc="${confgcc} --disable-__cxa_atexit --enable-target-optspace" + [[ ${GCCMAJOR}.${GCCMINOR} == 3.3 ]] && \ + confgcc="${confgcc} --enable-sjlj-exceptions" + elif [[ ${CTARGET} == *-gnu* ]] ; then + confgcc="${confgcc} --enable-__cxa_atexit" + elif [[ ${CTARGET} == *-freebsd* ]]; then + confgcc="${confgcc} --enable-__cxa_atexit" + fi + [[ ${CTARGET} == *-gnu* ]] && confgcc="${confgcc} --enable-clocale=gnu" + [[ ${CTARGET} == *-uclibc* ]] && [[ ${GCCMAJOR}.${GCCMINOR} > 3.3 ]] \ + && confgcc="${confgcc} --enable-clocale=uclibc" + + # Nothing wrong with a good dose of verbosity + echo + einfo "PREFIX: ${PREFIX}" + einfo "BINPATH: ${BINPATH}" + einfo "LIBPATH: ${LIBPATH}" + einfo "DATAPATH: ${DATAPATH}" + einfo "STDCXX_INCDIR: ${STDCXX_INCDIR}" + echo + einfo "Configuring GCC with: ${confgcc//--/\n\t--} ${@} ${EXTRA_ECONF}" + echo + + # Build in a separate build tree + mkdir -p "${WORKDIR}"/build + pushd "${WORKDIR}"/build > /dev/null + + # and now to do the actual configuration + addwrite /dev/zero + "${S}"/configure ${confgcc} $@ ${EXTRA_ECONF} \ + || die "failed to run configure" + + # return to whatever directory we were in before + popd > /dev/null +} + +# This function accepts one optional argument, the make target to be used. +# If ommitted, gcc_do_make will try to guess whether it should use all, +# profiledbootstrap, or bootstrap-lean depending on CTARGET and arch. An +# example of how to use this function: +# +# gcc_do_make all-target-libstdc++-v3 +# +# In addition to the target to be used, the following variables alter the +# behavior of this function: +# +# LDFLAGS +# Flags to pass to ld +# +# STAGE1_CFLAGS +# CFLAGS to use during stage1 of a gcc bootstrap +# +# BOOT_CFLAGS +# CFLAGS to use during stages 2+3 of a gcc bootstrap. +# +# Travis Tilley (04 Sep 2004) +# +gcc_do_make() { + # Fix for libtool-portage.patch + local OLDS=${S} + S=${WORKDIR}/build + + # Set make target to $1 if passed + [[ -n $1 ]] && GCC_MAKE_TARGET=$1 + # default target + if is_crosscompile || tc-is-cross-compiler ; then + # 3 stage bootstrapping doesnt quite work when you cant run the + # resulting binaries natively ^^; + GCC_MAKE_TARGET=${GCC_MAKE_TARGET-all} + elif [[ $(tc-arch) == "x86" || $(tc-arch) == "amd64" || $(tc-arch) == "ppc64" ]] \ + && [[ ${GCCMAJOR}.${GCCMINOR} > 3.3 ]] + then + GCC_MAKE_TARGET=${GCC_MAKE_TARGET-profiledbootstrap} + else + GCC_MAKE_TARGET=${GCC_MAKE_TARGET-bootstrap-lean} + fi + + # the gcc docs state that parallel make isnt supported for the + # profiledbootstrap target, as collisions in profile collecting may occur. + [[ ${GCC_MAKE_TARGET} == "profiledbootstrap" ]] && export MAKEOPTS="${MAKEOPTS} -j1" + + # boundschecking seems to introduce parallel build issues + want_boundschecking && export MAKEOPTS="${MAKEOPTS} -j1" + + if [[ ${GCC_MAKE_TARGET} == "all" ]] ; then + STAGE1_CFLAGS=${STAGE1_CFLAGS-"${CFLAGS}"} + elif [[ $(gcc-version) == "3.4" && ${GCC_BRANCH_VER} == "3.4" ]] && gcc-specs-ssp ; then + # See bug #79852 + STAGE1_CFLAGS=${STAGE1_CFLAGS-"-O2"} + else + STAGE1_CFLAGS=${STAGE1_CFLAGS-"-O"} + fi + + if is_crosscompile; then + # In 3.4, BOOT_CFLAGS is never used on a crosscompile... + # but I'll leave this in anyways as someone might have had + # some reason for putting it in here... --eradicator + BOOT_CFLAGS=${BOOT_CFLAGS-"-O2"} + else + # we only want to use the system's CFLAGS if not building a + # cross-compiler. + BOOT_CFLAGS=${BOOT_CFLAGS-"$(get_abi_CFLAGS) ${CFLAGS}"} + fi + + pushd "${WORKDIR}"/build + einfo "Running make LDFLAGS=\"${LDFLAGS}\" STAGE1_CFLAGS=\"${STAGE1_CFLAGS}\" LIBPATH=\"${LIBPATH}\" BOOT_CFLAGS=\"${BOOT_CFLAGS}\" ${GCC_MAKE_TARGET}" + + emake \ + LDFLAGS="${LDFLAGS}" \ + STAGE1_CFLAGS="${STAGE1_CFLAGS}" \ + LIBPATH="${LIBPATH}" \ + BOOT_CFLAGS="${BOOT_CFLAGS}" \ + ${GCC_MAKE_TARGET} \ + || die "emake failed with ${GCC_MAKE_TARGET}" + + if ! use build && ! is_crosscompile && ! use nocxx && use doc ; then + if type -p doxygen > /dev/null ; then + cd "${CTARGET}"/libstdc++-v3 + make doxygen-man || ewarn "failed to make docs" + else + ewarn "Skipping libstdc++ manpage generation since you don't have doxygen installed" + fi + fi + + popd +} + +# This function will add ${GCC_CONFIG_VER} to the names of all shared libraries in the +# directory specified to avoid filename collisions between multiple slotted +# non-versioned gcc targets. If no directory is specified, it is assumed that +# you want -all- shared objects to have ${GCC_CONFIG_VER} added. Example +# +# add_version_to_shared ${D}/usr/$(get_libdir) +# +# Travis Tilley (05 Sep 2004) +# +add_version_to_shared() { + local sharedlib sharedlibdir + [[ -z $1 ]] \ + && sharedlibdir=${D} \ + || sharedlibdir=$1 + + for sharedlib in $(find ${sharedlibdir} -name *.so.*) ; do + if [[ ! -L ${sharedlib} ]] ; then + einfo "Renaming `basename "${sharedlib}"` to `basename "${sharedlib/.so*/}-${GCC_CONFIG_VER}.so.${sharedlib/*.so./}"`" + mv "${sharedlib}" "${sharedlib/.so*/}-${GCC_CONFIG_VER}.so.${sharedlib/*.so./}" \ + || die + pushd `dirname "${sharedlib}"` > /dev/null || die + ln -sf "`basename "${sharedlib/.so*/}-${GCC_CONFIG_VER}.so.${sharedlib/*.so./}"`" \ + "`basename "${sharedlib}"`" || die + popd > /dev/null || die + fi + done +} + +# This is mostly a stub function to be overwritten in an ebuild +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 + + # ... sure, why not? + strip-unsupported-flags + + # dont want to funk ourselves + filter-flags '-mabi*' -m31 -m32 -m64 + + case ${GCC_BRANCH_VER} in + 3.2|3.3) + case $(tc-arch) in + x86) filter-flags '-mtune=*';; + amd64) filter-flags '-mtune=*' + replace-cpu-flags k8 athlon64 opteron i686;; + esac + ;; + 3.4|4.*) + case $(tc-arch) in + x86|amd64) filter-flags '-mcpu=*';; + esac + ;; + esac + + # Compile problems with these (bug #6641 among others)... + #filter-flags "-fno-exceptions -fomit-frame-pointer -fforce-addr" + + # CFLAGS logic (verified with 3.4.3): + # CFLAGS: + # This conflicts when creating a crosscompiler, so set to a sane + # default in this case: + # used in ./configure and elsewhere for the native compiler + # used by gcc when creating libiberty.a + # used by xgcc when creating libstdc++ (and probably others)! + # this behavior should be removed... + # + # CXXFLAGS: + # used by xgcc when creating libstdc++ + # + # STAGE1_CFLAGS (not used in creating a crosscompile gcc): + # used by ${CHOST}-gcc for building stage1 compiler + # + # BOOT_CFLAGS (not used in creating a crosscompile gcc): + # used by xgcc for building stage2/3 compiler + + if is_crosscompile ; then + # Set this to something sane for both native and target + CFLAGS="-O2 -pipe" + + local VAR="CFLAGS_"${CTARGET//-/_} + CXXFLAGS=${!VAR} + fi + + export GCJFLAGS=${GCJFLAGS:-${CFLAGS}} +} + +gcc_src_compile() { + gcc_do_filter_flags + einfo "CFLAGS=\"${CFLAGS}\"" + einfo "CXXFLAGS=\"${CXXFLAGS}\"" + + # Build in a separate build tree + mkdir -p "${WORKDIR}"/build + pushd "${WORKDIR}"/build > /dev/null + + # Install our pre generated manpages if we do not have perl ... + [[ ! -x /usr/bin/perl ]] && [[ -n ${MAN_VER} ]] && \ + unpack gcc-${MAN_VER}-manpages.tar.bz2 + + einfo "Configuring ${PN} ..." + gcc_do_configure + + touch "${S}"/gcc/c-gperf.h + + # Do not make manpages if we do not have perl ... + [[ ! -x /usr/bin/perl ]] \ + && find "${WORKDIR}"/build -name '*.[17]' | xargs touch + + einfo "Compiling ${PN} ..." + gcc_do_make ${GCC_MAKE_TARGET} + + # Do not create multiple specs files for PIE+SSP if boundschecking is in + # USE, as we disable PIE+SSP when it is. + if [[ ${ETYPE} == "gcc-compiler" ]] && want_split_specs ; then + split_out_specs_files || die "failed to split out specs" + fi + + popd > /dev/null +} + +gcc_src_test() { + cd "${WORKDIR}"/build + make check || ewarn "check failed and that sucks :(" +} + +gcc-library_src_install() { + einfo "Installing ${PN} ..." + # Do the 'make install' from the build directory + cd "${WORKDIR}"/build + S=${WORKDIR}/build \ + make DESTDIR="${D}" \ + prefix=${PREFIX} \ + bindir=${BINPATH} \ + includedir=${LIBPATH}/include \ + datadir=${DATAPATH} \ + mandir=${DATAPATH}/man \ + infodir=${DATAPATH}/info \ + LIBPATH="${LIBPATH}" \ + ${GCC_INSTALL_TARGET} || die + + if [[ ${GCC_LIB_COMPAT_ONLY} == "true" ]] ; then + rm -rf "${D}"${INCLUDEPATH} + rm -rf "${D}"${DATAPATH} + pushd "${D}"${LIBPATH}/ + rm *.a *.la *.so + popd + fi + + if [[ -n ${GCC_LIB_USE_SUBDIR} ]] ; then + mkdir -p "${WORKDIR}"/${GCC_LIB_USE_SUBDIR}/ + mv "${D}"${LIBPATH}/* "${WORKDIR}"/${GCC_LIB_USE_SUBDIR}/ + mv "${WORKDIR}"/${GCC_LIB_USE_SUBDIR}/ "${D}"${LIBPATH} + + dodir /etc/env.d + echo "LDPATH=\"${LIBPATH}/${GCC_LIB_USE_SUBDIR}/\"" >> "${D}"/etc/env.d/99${PN} + fi + + if [[ ${GCC_VAR_TYPE} == "non-versioned" ]] ; then + # if we're not using versioned directories, we need to use versioned + # filenames. + add_version_to_shared + fi +} + +gcc-compiler_src_install() { + local x= + + # Do allow symlinks in ${PREFIX}/lib/gcc-lib/${CHOST}/${GCC_CONFIG_VER}/include as + # this can break the build. + for x in "${WORKDIR}"/build/gcc/include/* ; do + [[ -L ${x} ]] && rm -f "${x}" + 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 + grep -q 'It has been auto-edited by fixincludes from' "${x}" \ + && rm -f "${x}" + done + einfo "Installing GCC..." + # Do the 'make install' from the build directory + cd "${WORKDIR}"/build + S=${WORKDIR}/build \ + make DESTDIR="${D}" install || die + # Punt some tools which are really only useful while building gcc + find "${D}" -name install-tools -type d -exec rm -rf "{}" \; + # This one comes with binutils + find "${D}" -name libiberty.a -exec rm -f "{}" \; + + # Move the libraries to the proper location + gcc_movelibs + + # Basic sanity check + if ! is_crosscompile ; then + local EXEEXT + eval $(grep ^EXEEXT= "${WORKDIR}"/build/gcc/config.log) + [[ -r ${D}${BINPATH}/gcc${EXEEXT} ]] || die "gcc not found in ${D}" + fi + + 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 + create_gcc_env_entry hardenednopiessp + + insinto ${LIBPATH} + doins "${WORKDIR}"/build/*.specs || die "failed to install specs" + fi + + # 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}"${BINPATH} + [[ -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 + dodir /usr/bin + cd "${D}"${BINPATH} + for x in cpp gcc g++ c++ g77 gcj gcjh gfortran ; do + # For some reason, g77 gets made instead of ${CTARGET}-g77... + # this should take care of that + [[ -f ${x} ]] && mv ${x} ${CTARGET}-${x} + + if [[ -f ${CTARGET}-${x} ]] && ! is_crosscompile ; then + ln -sf ${CTARGET}-${x} ${x} + + # Create version-ed symlinks + dosym ${BINPATH}/${CTARGET}-${x} \ + /usr/bin/${CTARGET}-${x}-${GCC_CONFIG_VER} + dosym ${BINPATH}/${CTARGET}-${x} \ + /usr/bin/${x}-${GCC_CONFIG_VER} + fi + + if [[ -f ${CTARGET}-${x}-${GCC_CONFIG_VER} ]] ; then + rm -f ${CTARGET}-${x}-${GCC_CONFIG_VER} + ln -sf ${CTARGET}-${x} ${CTARGET}-${x}-${GCC_CONFIG_VER} + 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 is_objc && ! is_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 + + # Now do the fun stripping stuff + env RESTRICT="" CHOST=${CHOST} prepstrip "${D}${BINPATH}" + env RESTRICT="" CHOST=${CTARGET} prepstrip "${D}${LIBPATH}" + # gcc used to install helper binaries in lib/ but then moved to libexec/ + [[ -d ${D}${PREFIX}/libexec/gcc ]] && \ + env RESTRICT="" CHOST=${CHOST} prepstrip "${D}${PREFIX}/libexec/gcc/${CTARGET}/${GCC_CONFIG_VER}" + + cd "${S}" + if use build || is_crosscompile; then + rm -rf "${D}"/usr/share/{man,info} + rm -rf "${D}"${DATAPATH}/{man,info} + else + local cxx_mandir=${WORKDIR}/build/${CTARGET}/libstdc++-v3/docs/doxygen/man + if [[ -d ${cxx_mandir} ]] ; then + # clean bogus manpages #113902 + find "${cxx_mandir}" -name '*_build_*' -exec rm {} \; + cp -r "${cxx_mandir}"/man? "${D}/${DATAPATH}"/man/ + fi + has noinfo ${FEATURES} \ + && rm -r "${D}/${DATAPATH}"/info \ + || prepinfo "${DATAPATH}" + has noman ${FEATURES} \ + && rm -r "${D}/${DATAPATH}"/man \ + || prepman "${DATAPATH}" + fi + # prune empty dirs left behind + find "${D}" -type d | xargs rmdir >& /dev/null + + # Rather install the script, else portage with changing $FILESDIR + # between binary and source package borks things .... + if ! is_crosscompile ; then + insinto "${DATAPATH}" + if tc_version_is_at_least 4.0 ; then + newins "${GCC_FILESDIR}"/awk/fixlafiles.awk-no_gcc_la fixlafiles.awk || die + find "${D}/${LIBPATH}" -name libstdc++.la -type f -exec rm "{}" \; + else + doins "${GCC_FILESDIR}"/awk/fixlafiles.awk || die + fi + exeinto "${DATAPATH}" + doexe "${GCC_FILESDIR}"/fix_libtool_files.sh || die + doexe "${GCC_FILESDIR}"/c{89,99} || die + fi + + # use gid of 0 because some stupid ports don't have + # the group 'root' set to gid 0 + chown -R root:0 "${D}"${LIBPATH} + + # Create config files for eselect-compiler + create_eselect_conf +} + +# Move around the libs to the right location. For some reason, +# when installing gcc, it dumps internal libraries into /usr/lib +# instead of the private gcc lib path +gcc_movelibs() { + # older versions of gcc did not support --print-multi-os-directory + tc_version_is_at_least 3.0 || return 0 + + local multiarg removedirs="" + for multiarg in $($(XGCC) -print-multi-lib) ; do + multiarg=${multiarg#*;} + multiarg=${multiarg//@/ -} + + local OS_MULTIDIR=$($(XGCC) ${multiarg} --print-multi-os-directory) + local MULTIDIR=$($(XGCC) ${multiarg} --print-multi-directory) + local TODIR=${D}${LIBPATH}/${MULTIDIR} + local FROMDIR= + + [[ -d ${TODIR} ]] || mkdir -p ${TODIR} + + for FROMDIR in \ + ${LIBPATH}/${OS_MULTIDIR} \ + ${LIBPATH}/../${MULTIDIR} \ + ${PREFIX}/lib/${OS_MULTIDIR} \ + ${PREFIX}/${CTARGET}/lib/${OS_MULTIDIR} \ + ${PREFIX}/lib/${MULTIDIR} + do + removedirs="${removedirs} ${FROMDIR}" + FROMDIR=${D}${FROMDIR} + if [[ ${FROMDIR} != "${TODIR}" && -d ${FROMDIR} ]] ; then + local files=$(find "${FROMDIR}" -maxdepth 1 ! -type d 2>/dev/null) + if [[ -n ${files} ]] ; then + mv ${files} "${TODIR}" + fi + fi + done + done + + # We remove directories separately to avoid this case: + # mv SRC/lib/../lib/*.o DEST + # rmdir SRC/lib/../lib/ + # mv SRC/lib/../lib32/*.o DEST # Bork + for FROMDIR in ${removedirs} ; do + rmdir "${D}"${FROMDIR} >& /dev/null + done + find "${D}" -type d | xargs rmdir >& /dev/null + + # 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_* >>---- + +#---->> unorganized crap in need of refactoring follows + +# 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 PATCH_GCC_VER=${PATCH_GCC_VER:-${GCC_RELEASE_VER}} + export UCLIBC_GCC_VER=${UCLIBC_GCC_VER:-${PATCH_GCC_VER}} + export PIE_GCC_VER=${PIE_GCC_VER:-${GCC_RELEASE_VER}} + export PP_GCC_VER=${PP_GCC_VER:-${GCC_RELEASE_VER}} + export HTB_GCC_VER=${HTB_GCC_VER:-${GCC_RELEASE_VER}} + + if [[ -n ${GCC_A_FAKEIT} ]] ; then + unpack ${GCC_A_FAKEIT} + elif [[ -n ${PRERELEASE} ]] ; then + unpack gcc-${PRERELEASE}.tar.bz2 + elif [[ -n ${SNAPSHOT} ]] ; then + unpack gcc-${SNAPSHOT}.tar.bz2 + else + unpack gcc-${GCC_RELEASE_VER}.tar.bz2 + # We want branch updates to be against a release tarball + if [[ -n ${BRANCH_UPDATE} ]] ; then + pushd "${S}" > /dev/null + epatch ${DISTDIR}/gcc-${GCC_RELEASE_VER}-branch-update-${BRANCH_UPDATE}.patch.bz2 + popd > /dev/null + fi + fi + + if [[ -n ${D_VER} ]] && use d ; then + pushd "${S}"/gcc > /dev/null + unpack gdc-${D_VER}-src.tar.bz2 + cd .. + ebegin "Adding support for the D language" + ./gcc/d/setup-gcc.sh >& "${T}"/dgcc.log + if ! eend $? ; then + eerror "The D gcc package failed to apply" + eerror "Please include this log file when posting a bug report:" + eerror " ${T}/dgcc.log" + die "failed to include the D language" + fi + popd > /dev/null + fi + + [[ -n ${PATCH_VER} ]] && \ + unpack gcc-${PATCH_GCC_VER}-patches-${PATCH_VER}.tar.bz2 + + [[ -n ${UCLIBC_VER} ]] && \ + unpack gcc-${UCLIBC_GCC_VER}-uclibc-patches-${UCLIBC_VER}.tar.bz2 + + if want_ssp ; then + if [[ -n ${PP_FVER} ]] ; then + # The gcc 3.4 propolice versions are meant to be unpacked to ${S} + pushd "${S}" > /dev/null + unpack protector-${PP_FVER}.tar.gz + popd > /dev/null + else + unpack gcc-${PP_GCC_VER}-ssp-${PP_VER}.tar.bz2 + fi + fi + + if want_pie ; then + if [[ -n ${PIE_CORE} ]] ; then + unpack ${PIE_CORE} + else + unpack gcc-${PIE_GCC_VER}-piepatches-v${PIE_VER}.tar.bz2 + fi + fi + + want_boundschecking && \ + unpack "bounds-checking-gcc-${HTB_GCC_VER}-${HTB_VER}.patch.bz2" + + 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 +} + +# Try to apply some stub patches so that gcc won't error out when +# passed parameters like -fstack-protector but no ssp is found +do_gcc_stub() { + local v stub_patch="" + for v in ${GCC_RELEASE_VER} ${GCC_BRANCH_VER} ; do + stub_patch=${GCC_FILESDIR}/stubs/gcc-${v}-$1-stub.patch + if [[ -e ${stub_patch} ]] && ! use vanilla ; then + EPATCH_SINGLE_MSG="Applying stub patch for $1 ..." \ + epatch "${stub_patch}" + return 0 + fi + done +} + +do_gcc_HTB_patches() { + if ! want_boundschecking || \ + (want_ssp && [[ ${HTB_EXCLUSIVE} == "true" ]]) + then + do_gcc_stub htb + return 0 + fi + + # modify the bounds checking patch with a regression patch + epatch "${WORKDIR}/bounds-checking-gcc-${HTB_GCC_VER}-${HTB_VER}.patch" + release_version="${release_version}, HTB-${HTB_GCC_VER}-${HTB_VER}" +} + +# patch in ProPolice Stack Smashing protection +do_gcc_SSP_patches() { + # PARISC has no love ... it's our stack :( + if [[ $(tc-arch) == "hppa" ]] || \ + ! want_ssp || \ + (want_boundschecking && [[ ${HTB_EXCLUSIVE} == "true" ]]) + then + do_gcc_stub ssp + return 0 + fi + + local ssppatch + local sspdocs + + if [[ -n ${PP_FVER} ]] ; then + # Etoh keeps changing where files are and what the patch is named + if tc_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 tc_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 tc_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" + fi + else + # Just start packaging the damn thing ourselves + mv "${WORKDIR}"/ssp/protector.{c,h} "${S}"/gcc/ + ssppatch=${WORKDIR}/ssp/gcc-${PP_GCC_VER}-ssp.patch + # allow boundschecking and ssp to get along + (want_boundschecking && [[ -e ${WORKDIR}/ssp/htb-ssp.patch ]]) \ + && patch -s "${ssppatch}" "${WORKDIR}"/ssp/htb-ssp.patch + fi + + [[ -z ${ssppatch} ]] && die "Sorry, SSP is not supported in this version" + epatch ${ssppatch} + + if [[ ${PN} == "gcc" && ${sspdocs} == "no" ]] ; then + epatch "${GCC_FILESDIR}"/pro-police-docs.patch + fi + + # Don't build crtbegin/end with ssp + sed -e 's|^CRTSTUFF_CFLAGS = |CRTSTUFF_CFLAGS = -fno-stack-protector |'\ + -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 use build && tc_version_is_at_least 3.4.0 ; then + if gcc -dumpspecs | grep -q "fno-stack-protector:" ; then + epatch "${GCC_FILESDIR}"/3.4.0/gcc-3.4.0-cc1-no-stack-protector.patch + fi + fi + + release_version="${release_version}, ssp-${PP_FVER:-${PP_GCC_VER}-${PP_VER}}" + if want_libssp ; then + update_gcc_for_libssp + else + update_gcc_for_libc_ssp + fi + + # Don't build libgcc with ssp + sed -e 's|^\(LIBGCC2_CFLAGS.*\)$|\1 -fno-stack-protector|' \ + -i gcc/Makefile.in || die "Failed to update gcc!" +} + +# 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() { + if ! want_pie || \ + (want_boundschecking && [[ ${HTB_EXCLUSIVE} == "true" ]]) + then + return 0 + fi + + want_boundschecking \ + && rm -f "${WORKDIR}"/piepatch/*/*-boundschecking-no.patch* \ + || rm -f "${WORKDIR}"/piepatch/*/*-boundschecking-yes.patch* + + use vanilla && rm -f "${WORKDIR}"/piepatch/*/*uclibc* + + guess_patch_type_in_dir "${WORKDIR}"/piepatch/upstream + + # corrects startfile/endfile selection and shared/static/pie flag usage + EPATCH_MULTI_MSG="Applying upstream pie patches ..." \ + epatch "${WORKDIR}"/piepatch/upstream + # adds non-default pie support (rs6000) + EPATCH_MULTI_MSG="Applying non-default pie patches ..." \ + epatch "${WORKDIR}"/piepatch/nondef + # adds default pie support (rs6000 too) if DEFAULT_PIE[_SSP] is defined + EPATCH_MULTI_MSG="Applying default pie patches ..." \ + epatch "${WORKDIR}"/piepatch/def + + # 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 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 definitely want a new one + # Note: due to bash quirkiness, the following must not be 1 line + local curr_config + curr_config=$(env -i ROOT="${ROOT}" gcc-config -c ${CTARGET} 2>&1) || return 0 + + # if the previously selected config has the same major.minor (branch) as + # the version we are installing, then it will probably be uninstalled + # for being in the same SLOT, make sure we run gcc-config. + local curr_config_ver=$(env -i ROOT="${ROOT}" gcc-config -S ${curr_config} | awk '{print $2}') + + local curr_branch_ver=$(get_version_component_range 1-2 ${curr_config_ver}) + + # If we're using multislot, just run gcc-config if we're installing + # to the same profile as the current one. + use multislot && return $([[ ${curr_config_ver} == ${GCC_CONFIG_VER} ]]) + + if [[ ${curr_branch_ver} == ${GCC_BRANCH_VER} ]] ; 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. + # We don't want to switch from say gcc-3.3 to gcc-3.4 right in + # the middle of an emerge operation (like an 'emerge -e world' + # which could install multiple gcc versions). + 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}-${GCC_CONFIG_VER}" + einfo "source /etc/profile" + echo + ebeep + return 1 + fi +} + +do_gcc_config() { + if ! should_we_gcc_config ; then + env -i ROOT="${ROOT}" gcc-config --use-old --force + return 0 + fi + + local current_gcc_config="" current_specs="" use_specs="" + + # We grep out any possible errors + current_gcc_config=$(env -i ROOT="${ROOT}" gcc-config -c ${CTARGET} | grep -v '^ ') + if [[ -n ${current_gcc_config} ]] ; then + # figure out which specs-specific config is active + current_specs=$(gcc-config -S ${current_gcc_config} | awk '{print $3}') + [[ -n ${current_specs} ]] && use_specs=-${current_specs} + fi + if [[ -n ${use_specs} ]] && \ + [[ ! -e ${ROOT}/etc/env.d/gcc/${CTARGET}-${GCC_CONFIG_VER}${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 + use_specs="" + fi + + gcc-config ${CTARGET}-${GCC_CONFIG_VER}${use_specs} +} + +should_we_eselect_compiler() { + # 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 definitely want a new one + # Note: due to bash quirkiness, the following must not be 1 line + local curr_config + curr_config=$(env -i eselect compiler show ${CTARGET} 2>&1) || return 0 + [[ -z ${curr_config} || ${curr_config} == "(none)" ]] && return 0 + + # if the previously selected config has the same major.minor (branch) as + # the version we are installing, then it will probably be uninstalled + # for being in the same SLOT, make sure we run gcc-config. + local curr_config_ver=$(echo ${curr_config} | cut -f1 -d/ | awk -F - '{ print $5 }') + local curr_branch_ver=$(get_version_component_range 1-2 ${curr_config_ver}) + + # If we're using multislot, just run gcc-config if we're installing + # to the same profile as the current one. + use multislot && return $([[ ${curr_config_ver} == ${GCC_CONFIG_VER} ]]) + + if [[ ${curr_branch_ver} == ${GCC_BRANCH_VER} ]] ; 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. + # We don't want to switch from say gcc-3.3 to gcc-3.4 right in + # the middle of an emerge operation (like an 'emerge -e world' + # which could install multiple gcc versions). + 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 "eselect compiler set " + echo + ebeep + return 1 + fi +} + +do_eselect_compiler() { + if ! should_we_eselect_compiler; then + eselect compiler update + return 0 + fi + + for abi in $(get_all_abis) ; do + local ctarget=$(get_abi_CHOST ${abi}) + local current_specs=$(env -i eselect compiler show ${ctarget} | cut -f2 -d/) + + if [[ -n ${current_specs} && ${current_specs} != "(none)" ]] && eselect compiler set ${CTARGET}-${GCC_CONFIG_VER}/${current_specs} &> /dev/null; then + einfo "The following compiler profile has been activated based on your previous profile:" + einfo "${CTARGET}-${GCC_CONFIG_VER}/${current_specs}" + else + # We couldn't choose based on the old specs, so fall back on vanilla/hardened based on USE + + local spec + if use hardened ; then + spec="hardened" + else + spec="vanilla" + fi + + local profile + local isset=0 + for profile in "${current_specs%-*}-${spec}" "${abi}-${spec}" "${spec}" ; do + if eselect compiler set ${CTARGET}-${GCC_CONFIG_VER}/${profile} &> /dev/null ; then + ewarn "The newly installed version of gcc does not have a profile that matches the name of your" + ewarn "currently selected profile for ${ctarget}, so we have enabled the following instead:" + ewarn "${CTARGET}-${GCC_CONFIG_VER}/${profile}" + ewarn "If this is incorrect, please use 'eselect compiler set' to" + ewarn "select another profile." + + isset=1 + break + fi + done + + if [[ ${isset} == 0 ]] ; then + eerror "We were not able to automatically set the current compiler for ${ctarget}" + eerror "to your newly emerged gcc. Please use 'eselect compiler set'" + eerror "to select your compiler." + fi + fi + done +} + +# 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" + + if grep -qs VERSUFFIX "${S}"/gcc/version.c ; then + sed -i -e "s~VERSUFFIX \"\"~VERSUFFIX \" ($2)\"~" \ + "${S}"/gcc/version.c || die "failed to update VERSUFFIX with Gentoo branding" + else + version_string="$1 ($2)" + sed -i -e "s~\(const char version_string\[\] = \"\).*\(\".*\)~\1$version_string\2~" \ + "${S}"/gcc/version.c || die "failed to update version.c with Gentoo branding." + fi + sed -i -e 's~gcc\.gnu\.org\/bugs\.html~bugs\.gentoo\.org\/~' \ + "${S}"/gcc/version.c || die "Failed to change the bug 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 config + local libdirs + if has_multilib_profile ; then + case $(tc-arch) in + amd64) + config="i386/t-linux64" + libdirs="../$(get_abi_LIBDIR amd64) ../$(get_abi_LIBDIR x86)" \ + ;; + ppc64) + config="rs6000/t-linux64" + libdirs="../$(get_abi_LIBDIR ppc64) ../$(get_abi_LIBDIR ppc)" \ + ;; + esac + else + die "Your profile is no longer supported by portage." + fi + + einfo "updating multilib directories to be: ${libdirs}" + sed -i -e "s:^MULTILIB_OSDIRNAMES.*:MULTILIB_OSDIRNAMES = ${libdirs}:" "${S}"/gcc/config/${config} +} + +disable_multilib_libjava() { + if is_gcj ; then + # 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 + fi +} + +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 +} + +is_multilib() { + [[ ${GCCMAJOR} < 3 ]] && return 1 + case ${CTARGET} in + mips64*|powerpc64*|s390x*|sparc64*|x86_64*) + has_multilib_profile || use multilib ;; + *) false ;; + esac +} + +is_cxx() { + gcc-lang-supported 'c++' || return 1 + use build && return 1 + ! use nocxx +} + +is_d() { + gcc-lang-supported d || return 1 + use build && return 1 + use d +} + +is_f77() { + gcc-lang-supported f77 || return 1 + use build && return 1 + use fortran +} + +is_f95() { + gcc-lang-supported f95 || return 1 + use build && return 1 + use fortran +} + +is_fortran() { + gcc-lang-supported fortran || return 1 + use build && return 1 + use fortran +} + +is_gcj() { + gcc-lang-supported java || return 1 + use build && return 1 + use gcj +} + +is_objc() { + gcc-lang-supported objc || return 1 + use build && return 1 + use objc +} + +is_objcxx() { + gcc-lang-supported 'obj-c++' || return 1 + use build && return 1 + use objc++ +} + +is_ada() { + gcc-lang-supported ada || return 1 + use build && return 1 + use ada +} diff --git a/eclass/toolchain-llvm.eclass b/eclass/toolchain-llvm.eclass index ed04799d..852837bd 100644 --- a/eclass/toolchain-llvm.eclass +++ b/eclass/toolchain-llvm.eclass @@ -1,2384 +1,334 @@ # Copyright 1999-2007 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 -# $Header: /var/cvsroot/gentoo-x86/eclass/toolchain.eclass,v 1.339 2007/07/20 04:59:51 vapier Exp $ +# $Header: $ # # Maintainer: Toolchain Ninjas +# +# We install llvm into CTARGET-VERSION specific directories. This lets +# us easily merge multiple versions for multiple targets (if we wish) and +# then switch the versions on the fly (with `binutils-config`). +# +# llvm-9999 -> live svn +# llvm-9999_preYYMMDD -> nightly snapshot date YYMMDD +# llvm-# -> normal release -HOMEPAGE="http://gcc.gnu.org/" -LICENSE="GPL-2 LGPL-2.1" -RESTRICT="strip" # cross-compilers need controlled stripping +extra_eclass="" +if [[ -n ${LLVM_TYPE} ]] ; then + LTYPE=${LLVM_TYPE} +else + case ${PV} in + 9999) LTYPE="svn";; + 9999_pre*) LTYPE="snap";; + *) LTYPE="rel";; + esac +fi -#---->> eclass stuff <<---- -inherit eutils versionator libtool toolchain-funcs flag-o-matic gnuconfig multilib fixheadtails +if [[ ${LTYPE} == "svn" ]] ; then + extra_eclass="subversion" + ESVN_REPO_URI="http://llvm.org/svn/llvm-project/llvm/trunk/llvm" + LVER="svn" +elif [[ ${LTYPE} == "snap" ]] ; then + LVER=${PV/9999_pre} +elif [[ ${LTYPE} == "rel" ]] ; then + LVER=${PV} +else + LVER=${LLVM_VER} +fi -EXPORT_FUNCTIONS pkg_setup src_unpack src_compile src_test pkg_preinst src_install pkg_postinst pkg_prerm pkg_postrm -DESCRIPTION="Based on the ${ECLASS} eclass" +inherit eutils libtool autotools flag-o-matic gnuconfig multilib ${extra_eclass} +EXPORT_FUNCTIONS src_unpack src_compile src_test src_install pkg_postinst pkg_postrm -FEATURES=${FEATURES/multilib-strict/} - -toolchain_pkg_setup() { - gcc_pkg_setup -} -toolchain_src_unpack() { - gcc_src_unpack -} -toolchain_src_compile() { - gcc_src_compile -} -toolchain_src_test() { - gcc_src_test -} -toolchain_pkg_preinst() { - ${ETYPE}_pkg_preinst -} -toolchain_src_install() { - ${ETYPE}_src_install -} -toolchain_pkg_postinst() { - ${ETYPE}_pkg_postinst -} -toolchain_pkg_prerm() { - ${ETYPE}_pkg_prerm -} -toolchain_pkg_postrm() { - ${ETYPE}_pkg_postrm -} -#----<< eclass stuff >>---- - - -#---->> globals <<---- export CTARGET=${CTARGET:-${CHOST}} -if [[ ${CTARGET} = ${CHOST} ]] ; then +if [[ ${CTARGET} == ${CHOST} ]] ; then if [[ ${CATEGORY/cross-} != ${CATEGORY} ]] ; then export CTARGET=${CATEGORY/cross-} fi fi -is_crosscompile() { - [[ ${CHOST} != ${CTARGET} ]] +is_cross() { [[ ${CHOST} != ${CTARGET} ]] ; } + +DESCRIPTION="Low Level Virtual Machine" +HOMEPAGE="http://llvm.org/" + +case ${LTYPE} in + svn) SRC_URI="";; + snap) SRC_URI="ftp://gcc.gnu.org/pub/llvm/snapshots/llvm-${LVER}.tar.bz2";; + rel) + SRC_URI="http://llvm.org/releases/${PV}/llvm-${PV}.tar.gz" +esac +add_src_uri() { + [[ -z $2 ]] && return + local a=$1 + set -- http://ftp.mars.arge.at/pub/ + SRC_URI="${SRC_URI} ${@/%//${a}}" } +add_src_uri llvm-${PV}-patches-${PATCHVER}.tar.bz2 ${PATCHVER} +add_src_uri llvm-${PV}-uclibc-patches-${UCLIBC_PATCHVER}.tar.bz2 ${UCLIBC_PATCHVER} -tc_version_is_at_least() { version_is_at_least "$1" "${2:-${GCC_PV}}" ; } - - -GCC_PV=${TOOLCHAIN_GCC_PV:-${PV}} -GCC_PVR=${GCC_PV} -[[ ${PR} != "r0" ]] && GCC_PVR=${GCC_PVR}-${PR} -GCC_RELEASE_VER=$(get_version_component_range 1-3 ${GCC_PV}) -GCC_BRANCH_VER=$(get_version_component_range 1-2 ${GCC_PV}) -GCCMAJOR=$(get_version_component_range 1 ${GCC_PV}) -GCCMINOR=$(get_version_component_range 2 ${GCC_PV}) -GCCMICRO=$(get_version_component_range 3 ${GCC_PV}) -[[ ${BRANCH_UPDATE-notset} == "notset" ]] && BRANCH_UPDATE=$(get_version_component_range 4 ${GCC_PV}) - -# According to gcc/c-cppbuiltin.c, GCC_CONFIG_VER MUST match this regex. -# ([^0-9]*-)?[0-9]+[.][0-9]+([.][0-9]+)?([- ].*)? -GCC_CONFIG_VER=${GCC_CONFIG_VER:-$(replace_version_separator 3 '-' ${GCC_PV})} - -# Pre-release support -if [[ ${GCC_PV} != ${GCC_PV/_pre/-} ]] ; then - PRERELEASE=${GCC_PV/_pre/-} -fi -# make _alpha and _beta ebuilds automatically use a snapshot -if [[ ${GCC_PV} != ${GCC_PV/_alpha/} ]] ; then - SNAPSHOT=${GCC_BRANCH_VER}-${GCC_PV##*_alpha} -elif [[ ${GCC_PV} != ${GCC_PV/_beta/} ]] ; then - SNAPSHOT=${GCC_BRANCH_VER}-${GCC_PV##*_beta} -fi -export GCC_FILESDIR=${GCC_FILESDIR:-${FILESDIR}} - -if [[ ${ETYPE} == "gcc-library" ]] ; then - GCC_VAR_TYPE=${GCC_VAR_TYPE:-non-versioned} - GCC_LIB_COMPAT_ONLY=${GCC_LIB_COMPAT_ONLY:-true} - GCC_TARGET_NO_MULTILIB=${GCC_TARGET_NO_MULTILIB:-true} +LICENSE="|| ( LLVM )" +IUSE="multitarget multislot test vanilla" +if use multislot ; then + SLOT="${CTARGET}-${LVER}" +elif is_cross ; then + SLOT="${CTARGET}" else - GCC_VAR_TYPE=${GCC_VAR_TYPE:-versioned} - GCC_LIB_COMPAT_ONLY="false" - GCC_TARGET_NO_MULTILIB=${GCC_TARGET_NO_MULTILIB:-false} + SLOT="0" fi -PREFIX=${TOOLCHAIN_PREFIX:-/usr} - -if [[ ${GCC_VAR_TYPE} == "versioned" ]] ; then - if tc_version_is_at_least 3.4.0 ; then - LIBPATH=${TOOLCHAIN_LIBPATH:-${PREFIX}/lib/gcc/${CTARGET}/${GCC_CONFIG_VER}} - else - LIBPATH=${TOOLCHAIN_LIBPATH:-${PREFIX}/lib/gcc-lib/${CTARGET}/${GCC_CONFIG_VER}} - fi - INCLUDEPATH=${TOOLCHAIN_INCLUDEPATH:-${LIBPATH}/include} - if is_crosscompile ; then - BINPATH=${TOOLCHAIN_BINPATH:-${PREFIX}/${CHOST}/${CTARGET}/gcc-bin/${GCC_CONFIG_VER}} - else - BINPATH=${TOOLCHAIN_BINPATH:-${PREFIX}/${CTARGET}/gcc-bin/${GCC_CONFIG_VER}} - fi - DATAPATH=${TOOLCHAIN_DATAPATH:-${PREFIX}/share/gcc-data/${CTARGET}/${GCC_CONFIG_VER}} - # Dont install in /usr/include/g++-v3/, but in gcc internal directory. - # We will handle /usr/include/g++-v3/ with gcc-config ... - STDCXX_INCDIR=${TOOLCHAIN_STDCXX_INCDIR:-${LIBPATH}/include/g++-v${GCC_BRANCH_VER/\.*/}} -elif [[ ${GCC_VAR_TYPE} == "non-versioned" ]] ; then - # using non-versioned directories to install gcc, like what is currently - # done for ppc64 and 3.3.3_pre, is a BAD IDEA. DO NOT do it!! However... - # setting up variables for non-versioned directories might be useful for - # specific gcc targets, like libffi. Note that we dont override the value - # returned by get_libdir here. - LIBPATH=${TOOLCHAIN_LIBPATH:-${PREFIX}/$(get_libdir)} - INCLUDEPATH=${TOOLCHAIN_INCLUDEPATH:-${PREFIX}/include} - BINPATH=${TOOLCHAIN_BINPATH:-${PREFIX}/bin} - DATAPATH=${TOOLCHAIN_DATAPATH:-${PREFIX}/share} - STDCXX_INCDIR=${TOOLCHAIN_STDCXX_INCDIR:-${PREFIX}/include/g++-v3} -fi - -#----<< globals >>---- - - -#---->> SLOT+IUSE logic <<---- -if [[ ${ETYPE} == "gcc-library" ]] ; then - IUSE="nls build test" - SLOT="${CTARGET}-${SO_VERSION_SLOT:-5}" +if is_cross ; then + RDEPEND=">=sys-devel/binutils-config-1.9" else - IUSE="multislot test" - - if [[ ${PN} != "kgcc64" && ${PN} != gcc-* ]] ; then - IUSE="${IUSE} altivec build fortran nls nocxx" - [[ -n ${PIE_VER} ]] && IUSE="${IUSE} nopie" - [[ -n ${PP_VER} ]] && IUSE="${IUSE} nossp" - [[ -n ${HTB_VER} ]] && IUSE="${IUSE} boundschecking" - [[ -n ${D_VER} ]] && IUSE="${IUSE} d" - - if version_is_at_least 3 ; then - IUSE="${IUSE} bootstrap doc gcj gtk hardened multilib objc vanilla" - - # gcc-{nios2,bfin} don't accept these - if [[ ${PN} == "gcc" ]] ; then - IUSE="${IUSE} ip28 ip32r10k n32 n64" - fi - - tc_version_is_at_least "4.0" && IUSE="${IUSE} objc-gc mudflap" - tc_version_is_at_least "4.1" && IUSE="${IUSE} objc++" - tc_version_is_at_least "4.2" && IUSE="${IUSE} openmp" - fi - fi - - # Support upgrade paths here or people get pissed - if use multislot ; then - SLOT="${CTARGET}-${GCC_CONFIG_VER}" - elif is_crosscompile; then - SLOT="${CTARGET}-${GCC_BRANCH_VER}" - else - SLOT="${GCC_BRANCH_VER}" - fi + RDEPEND=">=sys-devel/binutils-config-1.8-r6" fi -#----<< SLOT+IUSE logic >>---- +DEPEND="${RDEPEND} + test? ( dev-util/dejagnu ) + nls? ( sys-devel/gettext )" +S=${WORKDIR}/llvm +[[ ${LVER} != "svn" ]] && S=${S}-${LVER} -#---->> S + SRC_URI essentials <<---- +LIBPATH=/usr/$(get_libdir)/llvm/${CTARGET}/${LVER} +INCPATH=${LIBPATH}/include +DATAPATH=/usr/share/llvm-data/${CTARGET}/${LVER} +MY_BUILDDIR=${WORKDIR}/build +if is_cross ; then + BINPATH=/usr/${CHOST}/${CTARGET}/binutils-bin/${LVER} +else + BINPATH=/usr/${CTARGET}/binutils-bin/${LVER} +fi -# This function sets the source directory depending on whether we're using -# a prerelease, snapshot, or release tarball. To use it, just set S with: -# -# S="$(gcc_get_s_dir)" -# -# Travis Tilley (03 Sep 2004) -# -gcc_get_s_dir() { - local GCC_S - if [[ -n ${PRERELEASE} ]] ; then - GCC_S=${WORKDIR}/gcc-${PRERELEASE} - elif [[ -n ${SNAPSHOT} ]] ; then - GCC_S=${WORKDIR}/gcc-${SNAPSHOT} - else - GCC_S=${WORKDIR}/gcc-${GCC_RELEASE_VER} - fi - echo "${GCC_S}" +tc-llvm_unpack() { + unpack ${A} + mkdir -p "${MY_BUILDDIR}" + [[ -d ${WORKDIR}/patch ]] && mkdir "${WORKDIR}"/patch/skip } -# This function handles the basics of setting the SRC_URI for a gcc ebuild. -# To use, set SRC_URI with: -# -# SRC_URI="$(get_gcc_src_uri)" -# -# Other than the variables normally set by portage, this function's behavior -# can be altered by setting the following: -# -# SNAPSHOT -# If set, this variable signals that we should be using a snapshot -# of gcc from ftp://sources.redhat.com/pub/gcc/snapshots/. It is -# expected to be in the format "YYYY-MM-DD". Note that if the ebuild -# has a _pre suffix, this variable is ignored and the prerelease -# tarball is used instead. -# -# BRANCH_UPDATE -# If set, this variable signals that we should be using the main -# release tarball (determined by ebuild version) and applying a -# CVS branch update patch against it. The location of this branch -# update patch is assumed to be in ${GENTOO_TOOLCHAIN_BASE_URI}. -# Just like with SNAPSHOT, this variable is ignored if the ebuild -# has a _pre suffix. -# -# PATCH_VER -# PATCH_GCC_VER -# This should be set to the version of the gentoo patch tarball. -# The resulting filename of this tarball will be: -# gcc-${PATCH_GCC_VER:-${GCC_RELEASE_VER}}-patches-${PATCH_VER}.tar.bz2 -# -# PIE_VER -# PIE_GCC_VER -# obsoleted: PIE_CORE -# These variables control patching in various updates for the logic -# controlling Position Independant Executables. PIE_VER is expected -# to be the version of this patch, PIE_GCC_VER the gcc version of -# the patch, and PIE_CORE (obsoleted) the actual filename of the patch. -# An example: -# PIE_VER="8.7.6.5" -# PIE_GCC_VER="3.4.0" -# The resulting filename of this tarball will be: -# gcc-${PIE_GCC_VER:-${GCC_RELEASE_VER}}-piepatches-v${PIE_VER}.tar.bz2 -# old syntax (do not define PIE_CORE anymore): -# PIE_CORE="gcc-3.4.0-piepatches-v${PIE_VER}.tar.bz2" -# -# PP_VER -# PP_GCC_VER -# obsoleted: PP_FVER -# These variables control patching in stack smashing protection -# support. They both control the version of ProPolice to download. -# -# PP_VER / PP_GCC_VER -# Used to roll our own custom tarballs of ssp. -# PP_FVER / PP_VER -# Used for mirroring ssp straight from IBM. -# PP_VER sets the version of the directory in which to find the -# patch, and PP_FVER sets the version of the patch itself. For -# example: -# PP_VER="3_4" -# PP_FVER="${PP_VER//_/.}-2" -# would download gcc3_4/protector-3.4-2.tar.gz -# -# HTB_VER -# HTB_GCC_VER -# These variables control whether or not an ebuild supports Herman -# ten Brugge's bounds-checking patches. If you want to use a patch -# for an older gcc version with a new gcc, make sure you set -# HTB_GCC_VER to that version of gcc. -# -# MAN_VER -# The version of gcc for which we will download manpages. This will -# default to ${GCC_RELEASE_VER}, but we may not want to pre-generate man pages -# for prerelease test ebuilds for example. This allows you to -# continue using pre-generated manpages from the last stable release. -# If set to "none", this will prevent the downloading of manpages, -# which is useful for individual library targets. -# -gentoo_urls() { - local devspace="HTTP~lv/GCC/URI HTTP~eradicator/gcc/URI HTTP~vapier/dist/URI - HTTP~halcy0n/patches/URI" - devspace=${devspace//HTTP/http:\/\/dev.gentoo.org\/} - echo mirror://gentoo/$1 ${devspace//URI/$1} -} -get_gcc_src_uri() { - export PATCH_GCC_VER=${PATCH_GCC_VER:-${GCC_RELEASE_VER}} - export UCLIBC_GCC_VER=${UCLIBC_GCC_VER:-${PATCH_GCC_VER}} - export PIE_GCC_VER=${PIE_GCC_VER:-${GCC_RELEASE_VER}} - export PP_GCC_VER=${PP_GCC_VER:-${GCC_RELEASE_VER}} - export HTB_GCC_VER=${HTB_GCC_VER:-${GCC_RELEASE_VER}} - - [[ -n ${PIE_VER} ]] && \ - PIE_CORE=${PIE_CORE:-gcc-${PIE_GCC_VER}-piepatches-v${PIE_VER}.tar.bz2} - - # Set where to download gcc itself depending on whether we're using a - # prerelease, snapshot, or release tarball. - if [[ -n ${PRERELEASE} ]] ; then - GCC_SRC_URI="ftp://gcc.gnu.org/pub/gcc/prerelease-${PRERELEASE}/gcc-${PRERELEASE}.tar.bz2" - elif [[ -n ${SNAPSHOT} ]] ; then - GCC_SRC_URI="ftp://sources.redhat.com/pub/gcc/snapshots/${SNAPSHOT}/gcc-${SNAPSHOT}.tar.bz2" - else - GCC_SRC_URI="mirror://gnu/gcc/gcc-${GCC_PV}/gcc-${GCC_RELEASE_VER}.tar.bz2" - # we want all branch updates to be against the main release - [[ -n ${BRANCH_UPDATE} ]] && \ - GCC_SRC_URI="${GCC_SRC_URI} $(gentoo_urls gcc-${GCC_RELEASE_VER}-branch-update-${BRANCH_UPDATE}.patch.bz2)" - fi - - # propolice aka stack smashing protection - if [[ -n ${PP_VER} ]] ; then - if [[ -n ${PP_FVER} ]] ; then - GCC_SRC_URI="${GCC_SRC_URI} - !nossp? ( - http://www.research.ibm.com/trl/projects/security/ssp/gcc${PP_VER}/protector-${PP_FVER}.tar.gz - $(gentoo_urls protector-${PP_FVER}.tar.gz) - )" - else - GCC_SRC_URI="${GCC_SRC_URI} $(gentoo_urls gcc-${PP_GCC_VER}-ssp-${PP_VER}.tar.bz2)" - fi - fi - - # uclibc lovin - [[ -n ${UCLIBC_VER} ]] && \ - GCC_SRC_URI="${GCC_SRC_URI} $(gentoo_urls gcc-${UCLIBC_GCC_VER}-uclibc-patches-${UCLIBC_VER}.tar.bz2)" - - # PERL cannot be present at bootstrap, and is used to build the man pages. - # So... lets include some pre-generated ones, shall we? - [[ -n ${MAN_VER} ]] && \ - GCC_SRC_URI="${GCC_SRC_URI} $(gentoo_urls gcc-${MAN_VER}-manpages.tar.bz2)" - - # various gentoo patches - [[ -n ${PATCH_VER} ]] && \ - GCC_SRC_URI="${GCC_SRC_URI} $(gentoo_urls gcc-${PATCH_GCC_VER}-patches-${PATCH_VER}.tar.bz2)" - - # strawberry pie, Cappuccino and a Gauloises (it's a good thing) - [[ -n ${PIE_VER} ]] && \ - GCC_SRC_URI="${GCC_SRC_URI} !nopie? ( $(gentoo_urls ${PIE_CORE}) )" - - # gcc bounds checking patch - if [[ -n ${HTB_VER} ]] ; then - local HTBFILE="bounds-checking-gcc-${HTB_GCC_VER}-${HTB_VER}.patch.bz2" - GCC_SRC_URI="${GCC_SRC_URI} - boundschecking? ( - mirror://sourceforge/boundschecking/${HTBFILE} - $(gentoo_urls ${HTBFILE}) - )" - fi - - # support for the D language - [[ -n ${D_VER} ]] && \ - GCC_SRC_URI="${GCC_SRC_URI} d? ( mirror://sourceforge/dgcc/gdc-${D_VER}-src.tar.bz2 )" - - echo "${GCC_SRC_URI}" -} -S=$(gcc_get_s_dir) -SRC_URI=$(get_gcc_src_uri) -#---->> S + SRC_URI essentials >>---- - - -#---->> support checks <<---- - -# Grab a variable from the build system (taken from linux-info.eclass) -get_make_var() { - local var=$1 makefile=${2:-${WORKDIR}/build/Makefile} - echo -e "e:\\n\\t@echo \$(${var})\\ninclude ${makefile}" | \ - r=${makefile%/*} emake --no-print-directory -s -f - 2>/dev/null -} -XGCC() { get_make_var GCC_FOR_TARGET ; } - -# The gentoo piessp patches allow for 3 configurations: -# 1) PIE+SSP by default -# 2) PIE by default -# 3) SSP by default -hardened_gcc_works() { - if [[ $1 == "pie" ]] ; then - # $gcc_cv_ld_pie is unreliable as it simply take the output of - # `ld --help | grep -- -pie`, that reports the option in all cases, also if - # the loader doesn't actually load the resulting executables. - # To avoid breakage, blacklist FreeBSD here at least - [[ ${CTARGET} == *-freebsd* ]] && return 1 - - want_pie || return 1 - hardened_gcc_is_stable pie && return 0 - if has ~$(tc-arch) ${ACCEPT_KEYWORDS} ; then - hardened_gcc_check_unsupported pie && return 1 - ewarn "Allowing pie-by-default for an unstable arch ($(tc-arch))" - return 0 - fi - return 1 - elif [[ $1 == "ssp" ]] ; then - [[ -z ${PP_VER} ]] && return 1 - hardened_gcc_is_stable ssp && return 0 - if has ~$(tc-arch) ${ACCEPT_KEYWORDS} ; then - hardened_gcc_check_unsupported ssp && return 1 - ewarn "Allowing ssp-by-default for an unstable arch ($(tc-arch))" - return 0 - fi - return 1 - else - # laziness ;) - hardened_gcc_works pie || return 1 - hardened_gcc_works ssp || return 1 - return 0 - fi -} - -hardened_gcc_is_stable() { - if [[ $1 == "pie" ]] ; then - # HARDENED_* variables are deprecated and here for compatibility - local tocheck="${HARDENED_PIE_WORKS} ${HARDENED_GCC_WORKS}" - if [[ ${CTARGET} == *-uclibc* ]] ; then - tocheck="${tocheck} ${PIE_UCLIBC_STABLE}" - else - tocheck="${tocheck} ${PIE_GLIBC_STABLE}" - fi - elif [[ $1 == "ssp" ]] ; then - # ditto - local tocheck="${HARDENED_SSP_WORKS} ${HARDENED_GCC_WORKS}" - if [[ ${CTARGET} == *-uclibc* ]] ; then - tocheck="${tocheck} ${SSP_UCLIBC_STABLE}" - else - tocheck="${tocheck} ${SSP_STABLE}" - fi - else - die "hardened_gcc_stable needs to be called with pie or ssp" - fi - - hasq $(tc-arch) ${tocheck} && return 0 - return 1 -} - -hardened_gcc_check_unsupported() { - local tocheck="" - # if a variable is unset, we assume that all archs are unsupported. since - # this function is never called if hardened_gcc_is_stable returns true, - # this shouldn't cause problems... however, allowing this logic to work - # even with the variables unset will break older ebuilds that dont use them. - if [[ $1 == "pie" ]] ; then - if [[ ${CTARGET} == *-uclibc* ]] ; then - [[ -z ${PIE_UCLIBC_UNSUPPORTED} ]] && return 0 - tocheck="${tocheck} ${PIE_UCLIBC_UNSUPPORTED}" - else - [[ -z ${PIE_GLIBC_UNSUPPORTED} ]] && return 0 - tocheck="${tocheck} ${PIE_GLIBC_UNSUPPORTED}" - fi - elif [[ $1 == "ssp" ]] ; then - if [[ ${CTARGET} == *-uclibc* ]] ; then - [[ -z ${SSP_UCLIBC_UNSUPPORTED} ]] && return 0 - tocheck="${tocheck} ${SSP_UCLIBC_UNSUPPORTED}" - else - [[ -z ${SSP_UNSUPPORTED} ]] && return 0 - tocheck="${tocheck} ${SSP_UNSUPPORTED}" - fi - else - die "hardened_gcc_check_unsupported needs to be called with pie or ssp" - fi - - hasq $(tc-arch) ${tocheck} && return 0 - return 1 -} - -has_libssp() { - [[ -e /$(get_libdir)/libssp.so ]] && return 0 - return 1 -} - -want_libssp() { - [[ ${GCC_LIBSSP_SUPPORT} == "true" ]] || return 1 - has_libssp || return 1 - [[ -n ${PP_VER} ]] || return 1 - return 0 -} - -_want_stuff() { - local var=$1 flag=$2 - [[ -z ${!var} ]] && return 1 - use ${flag} && return 0 - return 1 -} -want_boundschecking() { _want_stuff HTB_VER boundschecking ; } -want_pie() { _want_stuff PIE_VER !nopie ; } -want_ssp() { _want_stuff PP_VER !nossp ; } - -want_split_specs() { - [[ ${SPLIT_SPECS} == "true" ]] && want_pie -} - -# This function checks whether or not glibc has the support required to build -# Position Independant Executables with gcc. -glibc_have_pie() { - if [[ ! -f ${ROOT}/usr/$(get_libdir)/Scrt1.o ]] ; then - echo - ewarn "Your glibc does not have support for pie, the file Scrt1.o is missing" - ewarn "Please update your glibc to a proper version or disable hardened" - echo - return 1 - fi -} - -# This function determines whether or not libc has been patched with stack -# smashing protection support. -libc_has_ssp() { - [[ ${ROOT} != "/" ]] && return 0 - - # lib hacks taken from sandbox configure - echo 'int main(){}' > "${T}"/libctest.c - LC_ALL=C gcc "${T}"/libctest.c -lc -o libctest -Wl,-verbose &> "${T}"/libctest.log || return 1 - local libc_file=$(awk '/attempt to open/ { if (($4 ~ /\/libc\.so/) && ($5 == "succeeded")) LIBC = $4; }; END {print LIBC}' "${T}"/libctest.log) - - [[ -z ${libc_file} ]] && die "Unable to find a libc !?" - - # Check for gcc-4.x style ssp support - if [[ -n $(readelf -s "${libc_file}" 2>/dev/null | \ - grep 'FUNC.*GLOBAL.*__stack_chk_fail') ]] - then - return 0 - else - # Check for gcc-3.x style ssp support - if [[ -n $(readelf -s "${libc_file}" 2>/dev/null | \ - grep 'OBJECT.*GLOBAL.*__guard') ]] && \ - [[ -n $(readelf -s "${libc_file}" 2>/dev/null | \ - grep 'FUNC.*GLOBAL.*__stack_smash_handler') ]] - then - return 0 - elif is_crosscompile ; then - die "'${libc_file}' was detected w/out ssp, that sucks (a lot)" - else - return 1 - fi - fi -} - -# This is to make sure we don't accidentally try to enable support for a -# language that doesnt exist. GCC 3.4 supports f77, while 4.0 supports f95, etc. -# -# Also add a hook so special ebuilds (kgcc64) can control which languages -# exactly get enabled -gcc-lang-supported() { - grep ^language=\"${1}\" "${S}"/gcc/*/config-lang.in > /dev/null || return 1 - [[ -z ${TOOLCHAIN_ALLOWED_LANGS} ]] && return 0 - has $1 ${TOOLCHAIN_ALLOWED_LANGS} -} - -#----<< support checks >>---- - -#---->> specs + env.d logic <<---- - -# defaults to enable for all hardened toolchains -gcc_common_hard="-DEFAULT_RELRO -DEFAULT_BIND_NOW" - -# configure to build with the hardened GCC specs as the default -make_gcc_hard() { - if hardened_gcc_works ; then - einfo "Updating gcc to use automatic PIE + SSP building ..." - sed -e "s|^HARD_CFLAGS = |HARD_CFLAGS = -DEFAULT_PIE_SSP ${gcc_common_hard} |" \ - -i "${S}"/gcc/Makefile.in || die "Failed to update gcc!" - elif hardened_gcc_works pie ; then - einfo "Updating gcc to use automatic PIE building ..." - ewarn "SSP has not been enabled by default" - sed -e "s|^HARD_CFLAGS = |HARD_CFLAGS = -DEFAULT_PIE ${gcc_common_hard} |" \ - -i "${S}"/gcc/Makefile.in || die "Failed to update gcc!" - elif hardened_gcc_works ssp ; then - einfo "Updating gcc to use automatic SSP building ..." - ewarn "PIE has not been enabled by default" - sed -e "s|^HARD_CFLAGS = |HARD_CFLAGS = -DEFAULT_SSP ${gcc_common_hard} |" \ - -i "${S}"/gcc/Makefile.in || die "Failed to update gcc!" - else - # do nothing if hardened isnt supported, but dont die either - ewarn "hardened is not supported for this arch in this gcc version" - ebeep - return 0 - fi - - # rebrand to make bug reports easier - release_version="${release_version/Gentoo/Gentoo Hardened}" -} - -# now we generate different spec files so that the user can select a compiler -# that enforces certain features in gcc itself and so we don't have to worry -# about a certain package ignoring CFLAGS/LDFLAGS -_create_specs_file() { - # Usage: _create_specs_file - local uflag=$1 name=$2 flags=${*:3} - ebegin "Creating a ${name} gcc specs file" - pushd "${WORKDIR}"/build/gcc > /dev/null - if [[ -z ${uflag} ]] || use ${uflag} ; then - # backup the compiler first - cp Makefile Makefile.orig - sed -i -e '/^HARD_CFLAGS/s:=.*:='"${flags}"':' Makefile - mv xgcc xgcc.foo - mv gcc.o gcc.o.foo - emake -s xgcc - $(XGCC) -dumpspecs > "${WORKDIR}"/build/${name}.specs - # restore everything to normal - mv gcc.o.foo gcc.o - mv xgcc.foo xgcc - mv Makefile.orig Makefile - else - $(XGCC) -dumpspecs > "${WORKDIR}"/build/${name}.specs - fi - popd > /dev/null - eend $([[ -s ${WORKDIR}/build/${name}.specs ]] ; echo $?) -} -create_vanilla_specs_file() { _create_specs_file hardened vanilla ; } -create_hardened_specs_file() { _create_specs_file !hardened hardened ${gcc_common_hard} -DEFAULT_PIE_SSP ; } -create_hardenednossp_specs_file() { _create_specs_file "" hardenednossp ${gcc_common_hard} -DEFAULT_PIE ; } -create_hardenednopie_specs_file() { _create_specs_file "" hardenednopie ${gcc_common_hard} -DEFAULT_SSP ; } -create_hardenednopiessp_specs_file() { _create_specs_file "" hardenednopiessp ${gcc_common_hard} ; } - -split_out_specs_files() { - local s spec_list="hardenednopiessp vanilla" - if hardened_gcc_works ; then - spec_list="${spec_list} hardened hardenednossp hardenednopie" - elif hardened_gcc_works pie ; then - spec_list="${spec_list} hardenednossp" - elif hardened_gcc_works ssp ; then - spec_list="${spec_list} hardenednopie" - fi - for s in ${spec_list} ; do - create_${s}_specs_file || return 1 - done -} - -create_gcc_env_entry() { - dodir /etc/env.d/gcc - local gcc_envd_base="/etc/env.d/gcc/${CTARGET}-${GCC_CONFIG_VER}" - - if [[ -z $1 ]] ; then - gcc_envd_file="${D}${gcc_envd_base}" - # I'm leaving the following commented out to remind me that it - # was an insanely -bad- idea. Stuff broke. GCC_SPECS isnt unset - # on chroot or in non-toolchain.eclass gcc ebuilds! - #gcc_specs_file="${LIBPATH}/specs" - gcc_specs_file="" - else - gcc_envd_file="${D}${gcc_envd_base}-$1" - gcc_specs_file="${LIBPATH}/$1.specs" - fi - - # phase PATH/ROOTPATH out ... - echo "PATH=\"${BINPATH}\"" > ${gcc_envd_file} - echo "ROOTPATH=\"${BINPATH}\"" >> ${gcc_envd_file} - echo "GCC_PATH=\"${BINPATH}\"" >> ${gcc_envd_file} - - if use multilib && ! has_multilib_profile; then - LDPATH="${LIBPATH}" - for path in 32 64 ; do - [[ -d ${LIBPATH}/${path} ]] && LDPATH="${LDPATH}:${LIBPATH}/${path}" - done - else - local MULTIDIR - LDPATH="${LIBPATH}" - - # We want to list the default ABI's LIBPATH first so libtool - # searches that directory first. This is a temporary - # workaround for libtool being stupid and using .la's from - # conflicting ABIs by using the first one in the search path - - local abi=${DEFAULT_ABI} - local MULTIDIR=$($(XGCC) $(get_abi_CFLAGS ${abi}) --print-multi-directory) - if [[ ${MULTIDIR} == "." ]] ; then - LDPATH=${LIBPATH} - else - LDPATH=${LIBPATH}/${MULTIDIR} - fi - - for abi in $(get_all_abis) ; do - [[ ${abi} == ${DEFAULT_ABI} ]] && continue - - MULTIDIR=$($(XGCC) $(get_abi_CFLAGS ${abi}) --print-multi-directory) - if [[ ${MULTIDIR} == "." ]] ; then - LDPATH=${LDPATH}:${LIBPATH} - else - LDPATH=${LDPATH}:${LIBPATH}/${MULTIDIR} - fi - done - fi - - echo "LDPATH=\"${LDPATH}\"" >> ${gcc_envd_file} - echo "MANPATH=\"${DATAPATH}/man\"" >> ${gcc_envd_file} - echo "INFOPATH=\"${DATAPATH}/info\"" >> ${gcc_envd_file} - echo "STDCXX_INCDIR=\"${STDCXX_INCDIR##*/}\"" >> ${gcc_envd_file} - - is_crosscompile && echo "CTARGET=${CTARGET}" >> ${gcc_envd_file} - - # Set which specs file to use - [[ -n ${gcc_specs_file} ]] && echo "GCC_SPECS=\"${gcc_specs_file}\"" >> ${gcc_envd_file} -} - -add_profile_eselect_conf() { - local compiler_config_file=$1 - local abi=$2 - local specs=$3 - local gcc_specs_file - local var - - if [[ -z ${specs} ]] ; then - # I'm leaving the following commented out to remind me that it - # was an insanely -bad- idea. Stuff broke. GCC_SPECS isnt unset - # on chroot or in non-toolchain.eclass gcc ebuilds! - #gcc_specs_file="${LIBPATH}/specs" - gcc_specs_file="" - - if use hardened ; then - specs="hardened" - else - specs="vanilla" - fi - else - gcc_specs_file="${LIBPATH}/${specs}.specs" - fi - - echo >> ${compiler_config_file} - if ! is_multilib ; then - echo "[${specs}]" >> ${compiler_config_file} - echo " ctarget=${CTARGET}" >> ${compiler_config_file} - else - echo "[${abi}-${specs}]" >> ${compiler_config_file} - var="CTARGET_${abi}" - if [[ -n ${!var} ]] ; then - echo " ctarget=${!var}" >> ${compiler_config_file} - else - var="CHOST_${abi}" - if [[ -n ${!var} ]] ; then - echo " ctarget=${!var}" >> ${compiler_config_file} - else - echo " ctarget=${CTARGET}" >> ${compiler_config_file} - fi - fi - fi - - local MULTIDIR=$($(XGCC) $(get_abi_CFLAGS ${abi}) --print-multi-directory) - local LDPATH=${LIBPATH} - if [[ ${MULTIDIR} != "." ]] ; then - LDPATH="${LIBPATH}/${MULTIDIR}" - fi - - echo " ldpath=${LDPATH}" >> ${compiler_config_file} - - if [[ -n ${gcc_specs_file} ]] ; then - echo " specs=${gcc_specs_file}" >> ${compiler_config_file} - fi - - var="CFLAGS_${abi}" - if [[ -n ${!var} ]] ; then - echo " cflags=${!var}" >> ${compiler_config_file} - fi -} - -create_eselect_conf() { - local config_dir="/etc/eselect/compiler" - local compiler_config_file="${D}/${config_dir}/${CTARGET}-${GCC_CONFIG_VER}.conf" - local abi - - dodir ${config_dir} - - echo "[global]" > ${compiler_config_file} - echo " version=${CTARGET}-${GCC_CONFIG_VER}" >> ${compiler_config_file} - echo " binpath=${BINPATH}" >> ${compiler_config_file} - echo " manpath=${DATAPATH}/man" >> ${compiler_config_file} - echo " infopath=${DATAPATH}/info" >> ${compiler_config_file} - echo " alias_cc=gcc" >> ${compiler_config_file} - echo " stdcxx_incdir=${STDCXX_INCDIR##*/}" >> ${compiler_config_file} - echo " bin_prefix=${CTARGET}" >> ${compiler_config_file} - - # Per spyderous, it is best not to alias the fortran compilers - #if [[ -x "${D}/${BINPATH}/${CTARGET}-g77" ]] ; then - # echo " alias_gfortran=g77" >> ${compiler_config_file} - #elif [[ -x "${D}/${BINPATH}/${CTARGET}-gfortran" ]] ; then - # echo " alias_g77=gfortran" >> ${compiler_config_file} - #fi - - for abi in $(get_all_abis) ; do - add_profile_eselect_conf "${compiler_config_file}" "${abi}" - - if want_split_specs ; then - if use hardened ; then - add_profile_eselect_conf "${compiler_config_file}" "${abi}" vanilla - elif hardened_gcc_works ; then - add_profile_eselect_conf "${compiler_config_file}" "${abi}" hardened - fi - - if hardened_gcc_works || hardened_gcc_works pie ; then - add_profile_eselect_conf "${compiler_config_file}" "${abi}" hardenednossp - fi - - if hardened_gcc_works || hardened_gcc_works ssp ; then - add_profile_eselect_conf "${compiler_config_file}" "${abi}" hardenednopie - fi - - add_profile_eselect_conf "${compiler_config_file}" "${abi}" hardenednopiessp - fi - done -} - -#----<< specs + env.d logic >>---- - -#---->> pkg_* <<---- -gcc_pkg_setup() { - [[ -z ${ETYPE} ]] && die "Your ebuild needs to set the ETYPE variable" - - if [[ ( $(tc-arch) == "amd64" || $(tc-arch) == "ppc64" ) && ( ${LD_PRELOAD} == "/lib/libsandbox.so" || ${LD_PRELOAD} == "/usr/lib/libsandbox.so" ) ]] && is_multilib ; then - eerror "Sandbox in your installed portage does not support compilation." - eerror "of a multilib gcc. Please set FEATURES=-sandbox and try again." - eerror "After you have a multilib gcc, re-emerge portage to have a working sandbox." - die "No 32bit sandbox. Retry with FEATURES=-sandbox." - fi - - if [[ ${ETYPE} == "gcc-compiler" ]] ; then - case $(tc-arch) in - mips) - # Must compile for mips64-linux target if we want n32/n64 support - case "${CTARGET}" in - mips64*) ;; - *) - if use n32 || use n64; then - eerror "n32/n64 can only be used when target host is mips64*-*-linux-*"; - die "Invalid USE flags for CTARGET ($CTARGET)"; - fi - ;; - esac - - #cannot have both n32 & n64 without multilib - if use n32 && use n64 && ! is_multilib; then - eerror "Please enable multilib if you want to use both n32 & n64"; - die "Invalid USE flag combination"; - fi - ;; - esac - - # Setup variables which would normally be in the profile - if is_crosscompile ; then - multilib_env ${CTARGET} - if ! use multilib ; then - MULTILIB_ABIS=${DEFAULT_ABI} - fi - fi - - # we dont want to use the installed compiler's specs to build gcc! - unset GCC_SPECS - fi - - want_libssp && libc_has_ssp && \ - die "libssp cannot be used with a glibc that has been patched to provide ssp symbols" -} - -gcc-compiler_pkg_preinst() { - : -} - -gcc-compiler_pkg_postinst() { - export LD_LIBRARY_PATH=${LIBPATH}:${LD_LIBRARY_PATH} - - if has_version 'app-admin/eselect-compiler' ; then - do_eselect_compiler - else - do_gcc_config - fi - - if ! is_crosscompile ; then - echo - ewarn "If you have issues with packages unable to locate libstdc++.la," - ewarn "then try running 'fix_libtool_files.sh' on the old gcc versions." - echo - fi - - # If our gcc-config version doesn't like '-' in it's version string, - # tell our users that gcc-config will yell at them, but it's all good. - if ! has_version '>=sys-devel/gcc-config-1.3.10-r1' && [[ ${GCC_CONFIG_VER/-/} != ${GCC_CONFIG_VER} ]] ; then - ewarn "Your version of gcc-config will issue about having an invalid profile" - ewarn "when switching to this profile. It is safe to ignore this warning," - ewarn "and this problem has been corrected in >=sys-devel/gcc-config-1.3.10-r1." - fi - - if ! is_crosscompile && ! use multislot && [[ ${GCCMAJOR}.${GCCMINOR} == 3.4 ]] ; then - echo - ewarn "You should make sure to rebuild all your C++ packages when" - ewarn "upgrading between different versions of gcc. For example," - ewarn "when moving to gcc-3.4 from gcc-3.3, emerge gentoolkit and run:" - ewarn " # revdep-rebuild --library libstdc++.so.5" - echo - ewarn "For more information on the steps to take when upgrading " - ewarn "from gcc-3.3 please refer to: " - ewarn "http://www.gentoo.org/doc/en/gcc-upgrading.xml" - echo - fi - - if ! is_crosscompile ; then - # hack to prevent collisions between SLOT - [[ ! -d ${ROOT}/lib/rcscripts/awk ]] \ - && mkdir -p "${ROOT}"/lib/rcscripts/awk - [[ ! -d ${ROOT}/sbin ]] \ - && mkdir -p "${ROOT}"/sbin - cp "${ROOT}/${DATAPATH}"/fixlafiles.awk "${ROOT}"/lib/rcscripts/awk/ || die "installing fixlafiles.awk" - cp "${ROOT}/${DATAPATH}"/fix_libtool_files.sh "${ROOT}"/sbin/ || die "installing fix_libtool_files.sh" - - [[ ! -d ${ROOT}/usr/bin ]] \ - && mkdir -p "${ROOT}"/usr/bin - # Since these aren't critical files and portage sucks with - # handling of binpkgs, don't require these to be found - for x in "${ROOT}/${DATAPATH}"/c{89,99} ; do - if [[ -e ${x} ]]; then - cp ${x} "${ROOT}"/usr/bin/ || die "installing c89/c99" - fi - done - fi -} - -gcc-compiler_pkg_prerm() { - # Don't let these files be uninstalled #87647 - touch -c "${ROOT}"/sbin/fix_libtool_files.sh \ - "${ROOT}"/lib/rcscripts/awk/fixlafiles.awk -} - -gcc-compiler_pkg_postrm() { - # to make our lives easier (and saner), we do the fix_libtool stuff here. - # rather than checking SLOT's and trying in upgrade paths, we just see if - # the common libstdc++.la exists in the ${LIBPATH} of the gcc that we are - # unmerging. if it does, that means this was a simple re-emerge. - - # clean up the cruft left behind by cross-compilers - if is_crosscompile ; then - if [[ -z $(ls "${ROOT}"/etc/env.d/gcc/${CTARGET}* 2>/dev/null) ]] ; then - rm -f "${ROOT}"/etc/env.d/gcc/config-${CTARGET} - rm -f "${ROOT}"/etc/env.d/??gcc-${CTARGET} - rm -f "${ROOT}"/usr/bin/${CTARGET}-{gcc,{g,c}++}{,32,64} - fi - return 0 - fi - - # ROOT isnt handled by the script - [[ ${ROOT} != "/" ]] && return 0 - - if [[ ! -e ${LIBPATH}/libstdc++.so ]] ; then - einfo "Running 'fix_libtool_files.sh ${GCC_RELEASE_VER}'" - /sbin/fix_libtool_files.sh ${GCC_RELEASE_VER} - if [[ -n ${BRANCH_UPDATE} ]] ; then - einfo "Running 'fix_libtool_files.sh ${GCC_RELEASE_VER}-${BRANCH_UPDATE}'" - /sbin/fix_libtool_files.sh ${GCC_RELEASE_VER}-${BRANCH_UPDATE} - fi - fi - - return 0 -} - -#---->> 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: -# -# 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 - want_pie && use hardened && glibc_have_pie - - if use hardened ; then - einfo "updating configuration to build hardened GCC" - make_gcc_hard || die "failed to make gcc hard" - fi -} -gcc-library_src_unpack() { - : -} -guess_patch_type_in_dir() { - [[ -n $(ls "$1"/*.bz2 2>/dev/null) ]] \ - && EPATCH_SUFFIX="patch.bz2" \ - || EPATCH_SUFFIX="patch" -} -do_gcc_rename_java_bins() { - # bug #139918 - conflict between gcc and java-config-2 for ownership of - # /usr/bin/rmi{c,registry}. Done with mv & sed rather than a patch - # because patches would be large (thanks to the rename of man files), - # and it's clear from the sed invocations that all that changes is the - # rmi{c,registry} names to grmi{c,registry} names. - # Kevin F. Quinn 2006-07-12 - einfo "Renaming jdk executables rmic and rmiregistry to grmic and grmiregistry." - # 1) Move the man files if present (missing prior to gcc-3.4) - for manfile in rmic rmiregistry; do - [[ -f ${S}/gcc/doc/${manfile}.1 ]] || continue - mv ${S}/gcc/doc/${manfile}.1 ${S}/gcc/doc/g${manfile}.1 - done - # 2) Fixup references in the docs if present (mission prior to gcc-3.4) - for jfile in gcc/doc/gcj.info gcc/doc/grmic.1 gcc/doc/grmiregistry.1 gcc/java/gcj.texi; do - [[ -f ${S}/${jfile} ]] || continue - sed -i -e 's:rmiregistry:grmiregistry:g' ${S}/${jfile} || - die "Failed to fixup file ${jfile} for rename to grmiregistry" - sed -i -e 's:rmic:grmic:g' ${S}/${jfile} || - die "Failed to fixup file ${jfile} for rename to grmic" - done - # 3) Fixup Makefiles to build the changed executable names - # These are present in all 3.x versions, and are the important bit - # to get gcc to build with the new names. - for jfile in libjava/Makefile.am libjava/Makefile.in gcc/java/Make-lang.in; do - sed -i -e 's:rmiregistry:grmiregistry:g' ${S}/${jfile} || - die "Failed to fixup file ${jfile} for rename to grmiregistry" - # Careful with rmic on these files; it's also the name of a directory - # which should be left unchanged. Replace occurrences of 'rmic$', - # 'rmic_' and 'rmic '. - sed -i -e 's:rmic\([$_ ]\):grmic\1:g' ${S}/${jfile} || - die "Failed to fixup file ${jfile} for rename to grmic" - done -} -gcc_src_unpack() { - local release_version="Gentoo ${GCC_PVR}" - - [[ -z ${UCLIBC_VER} ]] && [[ ${CTARGET} == *-uclibc* ]] && die "Sorry, this version does not support uClibc" - - gcc_quick_unpack - exclude_gcc_patches - +tc-llvm_apply_patches() { cd "${S}" if ! use vanilla ; then - if [[ -n ${PATCH_VER} ]] ; then - guess_patch_type_in_dir "${WORKDIR}"/patch - EPATCH_MULTI_MSG="Applying Gentoo patches ..." \ - epatch "${WORKDIR}"/patch - release_version="${release_version} p${PATCH_VER}" + if [[ -n ${PATCHVER} ]] ; then + EPATCH_SOURCE=${WORKDIR}/patch + [[ -n $(ls "${EPATCH_SOURCE}"/*.bz2 2>/dev/null) ]] \ + && EPATCH_SUFFIX="patch.bz2" \ + || EPATCH_SUFFIX="patch" + epatch fi - if [[ -n ${UCLIBC_VER} ]] ; then - guess_patch_type_in_dir "${WORKDIR}"/uclibc - EPATCH_MULTI_MSG="Applying uClibc patches ..." \ - epatch "${WORKDIR}"/uclibc - fi - fi - do_gcc_HTB_patches - do_gcc_SSP_patches - do_gcc_PIE_patches - - ${ETYPE}_src_unpack || die "failed to ${ETYPE}_src_unpack" - - # protoize don't build on FreeBSD, skip it - if ! is_crosscompile && ! use elibc_FreeBSD ; then - # enable protoize / unprotoize - sed -i -e '/^LANGUAGES =/s:$: proto:' "${S}"/gcc/Makefile.in - fi - - fix_files="" - for x in contrib/test_summary libstdc++-v3/scripts/check_survey.in ; do - [[ -e ${x} ]] && fix_files="${fix_files} ${x}" - done - ht_fix_file ${fix_files} */configure *.sh */Makefile.in - - if ! is_crosscompile && is_multilib && \ - [[ ( $(tc-arch) == "amd64" || $(tc-arch) == "ppc64" ) && -z ${SKIP_MULTILIB_HACK} ]] ; then - disgusting_gcc_multilib_HACK || die "multilib hack failed" - fi - - local version_string=${GCC_CONFIG_VER} - - # Backwards support... add the BRANCH_UPDATE for 3.3.5-r1 and 3.4.3-r1 - # which set it directly rather than using ${GCC_PV} - if [[ ${GCC_PVR} == "3.3.5-r1" || ${GCC_PVR} = "3.4.3-r1" ]] ; then - version_string="${version_string} ${BRANCH_UPDATE}" - fi - - einfo "patching gcc version: ${version_string} (${release_version})" - gcc_version_patch "${version_string}" "${release_version}" - - if [[ ${GCCMAJOR}.${GCCMINOR} > 4.0 ]] ; then - if [[ -n ${SNAPSHOT} || -n ${PRERELEASE} ]] ; then - echo ${PV/_/-} > "${S}"/gcc/BASE-VER - echo "" > "${S}"/gcc/DATESTAMP - fi - fi - - # Misdesign in libstdc++ (Redhat) - if [[ ${GCCMAJOR} -ge 3 ]] && [[ -e ${S}/libstdc++-v3/config/cpu/i486/atomicity.h ]] ; then - cp -pPR "${S}"/libstdc++-v3/config/cpu/i{4,3}86/atomicity.h - fi - - # disable --as-needed from being compiled into gcc specs - # natively when using a gcc version < 3.4.4 - # http://gcc.gnu.org/bugzilla/show_bug.cgi?id=14992 - if [[ ${GCCMAJOR} < 3 ]] || \ - [[ ${GCCMAJOR}.${GCCMINOR} < 3.4 ]] || \ - [[ ${GCCMAJOR}.${GCCMINOR}.${GCCMICRO} < 3.4.4 ]] - then - sed -i -e s/HAVE_LD_AS_NEEDED/USE_LD_AS_NEEDED/g "${S}"/gcc/config.in - fi - - # In gcc 3.3.x and 3.4.x, rename the java bins to gcc-specific names - # in line with gcc-4. - if [[ ${GCCMAJOR} == 3 ]] && - [[ ${GCCMINOR} -ge 3 ]] - then - do_gcc_rename_java_bins - fi - - # Fixup libtool to correctly generate .la files with portage - cd "${S}" - elibtoolize --portage --shallow --no-uclibc - - gnuconfig_update - - # update configure files - local f - einfo "Fixing misc issues in configure files" - for f in $(grep -l 'autoconf version 2.13' $(find "${S}" -name configure)) ; do - ebegin " Updating ${f/${S}\/}" - patch "${f}" "${GCC_FILESDIR}"/gcc-configure-LANG.patch >& "${T}"/configure-patch.log \ - || eerror "Please file a bug about this" - eend $? - done - - if [[ -x contrib/gcc_update ]] ; then - einfo "Touching generated files" - ./contrib/gcc_update --touch | \ - while read f ; do - einfo " ${f%%...}" - done - fi - - disable_multilib_libjava || die "failed to disable multilib java" -} - -gcc-library-configure() { - # multilib support - [[ ${GCC_TARGET_NO_MULTILIB} == "true" ]] \ - && confgcc="${confgcc} --disable-multilib" \ - || confgcc="${confgcc} --enable-multilib" -} - -gcc-compiler-configure() { - # multilib support - if is_multilib ; then - confgcc="${confgcc} --enable-multilib" - elif [[ ${CTARGET} == *-linux* ]] ; then - confgcc="${confgcc} --disable-multilib" - fi - - if tc_version_is_at_least "4.0" ; then - if has mudflap ${IUSE} ; then - confgcc="${confgcc} $(use_enable mudflap libmudflap)" - else - confgcc="${confgcc} --disable-libmudflap" - fi - - if want_libssp ; then - confgcc="${confgcc} --enable-libssp" - else - export gcc_cv_libc_provides_ssp=yes - confgcc="${confgcc} --disable-libssp" - fi - 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 ! is_gcj ; then - confgcc="${confgcc} --disable-libgcj" - elif use gtk ; then - confgcc="${confgcc} --enable-java-awt=gtk" - fi - - case $(tc-arch) in - # Add --with-abi flags to set default MIPS ABI - mips) - local mips_abi="" - use n64 && mips_abi="--with-abi=64" - use n32 && mips_abi="--with-abi=n32" - [[ -n ${mips_abi} ]] && confgcc="${confgcc} ${mips_abi}" - ;; - # Default arch for x86 is normally i386, lets give it a bump - # since glibc will do so based on CTARGET anyways - x86) - confgcc="${confgcc} --with-arch=${CTARGET%%-*}" - ;; - # Enable sjlj exceptions for backward compatibility on hppa - hppa) - [[ ${GCC_PV:0:1} == "3" ]] && \ - confgcc="${confgcc} --enable-sjlj-exceptions" - ;; - esac - - GCC_LANG="c" - is_cxx && GCC_LANG="${GCC_LANG},c++" - is_d && GCC_LANG="${GCC_LANG},d" - is_gcj && GCC_LANG="${GCC_LANG},java" - if is_objc || is_objcxx ; then - GCC_LANG="${GCC_LANG},objc" - use objc-gc && confgcc="${confgcc} --enable-objc-gc" - is_objcxx && GCC_LANG="${GCC_LANG},obj-c++" - fi - - # fortran support just got sillier! the lang value can be f77 for - # fortran77, f95 for fortran95, or just plain old fortran for the - # currently supported standard depending on gcc version. - is_fortran && GCC_LANG="${GCC_LANG},fortran" - is_f77 && GCC_LANG="${GCC_LANG},f77" - is_f95 && GCC_LANG="${GCC_LANG},f95" - - # We do NOT want 'ADA support' in here! - # is_ada && GCC_LANG="${GCC_LANG},ada" - - einfo "configuring for GCC_LANG: ${GCC_LANG}" -} - -# Other than the variables described for gcc_setup_variables, the following -# will alter tha behavior of gcc_do_configure: -# -# CTARGET -# CBUILD -# Enable building for a target that differs from CHOST -# -# GCC_TARGET_NO_MULTILIB -# Disable multilib. Useful when building single library targets. -# -# GCC_LANG -# Enable support for ${GCC_LANG} languages. defaults to just "c" -# -# Travis Tilley (04 Sep 2004) -# -gcc_do_configure() { - local confgcc - - # Set configuration based on path variables - confgcc="${confgcc} \ - --prefix=${PREFIX} \ - --bindir=${BINPATH} \ - --includedir=${INCLUDEPATH} \ - --datadir=${DATAPATH} \ - --mandir=${DATAPATH}/man \ - --infodir=${DATAPATH}/info \ - --with-gxx-include-dir=${STDCXX_INCDIR}" - - # All our cross-compile logic goes here ! woo ! - confgcc="${confgcc} --host=${CHOST}" - if is_crosscompile || tc-is-cross-compiler ; then - # Straight from the GCC install doc: - # "GCC has code to correctly determine the correct value for target - # for nearly all native systems. Therefore, we highly recommend you - # not provide a configure target when configuring a native compiler." - confgcc="${confgcc} --target=${CTARGET}" - fi - [[ -n ${CBUILD} ]] && confgcc="${confgcc} --build=${CBUILD}" - - # ppc altivec support - confgcc="${confgcc} $(use_enable altivec)" - - [[ $(tc-is-softfloat) == "yes" ]] && confgcc="${confgcc} --with-float=soft" - - # Native Language Support - if use nls && ! use build ; then - confgcc="${confgcc} --enable-nls --without-included-gettext" - else - confgcc="${confgcc} --disable-nls" - fi - - # reasonably sane globals (hopefully) - # --disable-libunwind-exceptions needed till unwind sections get fixed. see ps.m for details - confgcc="${confgcc} \ - --with-system-zlib \ - --disable-checking \ - --disable-werror \ - --enable-secureplt \ - --disable-libunwind-exceptions" - - # etype specific configuration - einfo "running ${ETYPE}-configure" - ${ETYPE}-configure || die - - # if not specified, assume we are building for a target that only - # requires C support - GCC_LANG=${GCC_LANG:-c} - confgcc="${confgcc} --enable-languages=${GCC_LANG}" - - if is_crosscompile ; then - # When building a stage1 cross-compiler (just C compiler), we have to - # disable a bunch of features or gcc goes boom - local needed_libc="" - case ${CTARGET} in - *-linux) needed_libc=no-fucking-clue;; - *-dietlibc) needed_libc=dietlibc;; - *-elf) needed_libc=newlib;; - *-freebsd*) needed_libc=freebsd-lib;; - *-gnu*) needed_libc=glibc;; - *-klibc) needed_libc=klibc;; - *-uclibc*) needed_libc=uclibc;; - mingw*|*-mingw*) needed_libc=mingw-runtime;; - avr) confgcc="${confgcc} --enable-shared --disable-threads";; - esac - if [[ -n ${needed_libc} ]] ; then - if ! has_version ${CATEGORY}/${needed_libc} ; then - confgcc="${confgcc} --disable-shared --disable-threads --without-headers" - elif built_with_use --hidden --missing false ${CATEGORY}/${needed_libc} crosscompile_opts_headers-only ; then - confgcc="${confgcc} --disable-shared --with-sysroot=${PREFIX}/${CTARGET}" - else - confgcc="${confgcc} --with-sysroot=${PREFIX}/${CTARGET}" + local check base=${PORTAGE_CONFIGROOT}/etc/portage/patches + for check in {${CATEGORY}/${PF},${CATEGORY}/${P},${CATEGORY}/${PN}}; do + EPATCH_SOURCE=${base}/${CTARGET}/${check} + [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${CHOST}/${check} + [[ -r ${EPATCH_SOURCE} ]] || EPATCH_SOURCE=${base}/${check} + if [[ -d ${EPATCH_SOURCE} ]] ; then + EPATCH_SUFFIX="patch" + EPATCH_FORCE="yes" \ + EPATCH_MULTI_MSG="Applying user patches from ${EPATCH_SOURCE} ..." \ + epatch + break fi - fi - - if [[ ${GCCMAJOR}.${GCCMINOR} > 4.1 ]] ; then - confgcc="${confgcc} --disable-bootstrap --disable-libgomp" - fi - elif [[ ${CHOST} != mingw* ]] && [[ ${CHOST} != *-mingw* ]] ; then - confgcc="${confgcc} --enable-shared --enable-threads=posix" + done fi - [[ ${CTARGET} == *-elf ]] && confgcc="${confgcc} --with-newlib" - # __cxa_atexit is "essential for fully standards-compliant handling of - # destructors", but apparently requires glibc. - # --enable-sjlj-exceptions : currently the unwind stuff seems to work - # for statically linked apps but not dynamic - # so use setjmp/longjmp exceptions by default - if [[ ${CTARGET} == *-uclibc* ]] ; then - confgcc="${confgcc} --disable-__cxa_atexit --enable-target-optspace" - [[ ${GCCMAJOR}.${GCCMINOR} == 3.3 ]] && \ - confgcc="${confgcc} --enable-sjlj-exceptions" - elif [[ ${CTARGET} == *-gnu* ]] ; then - confgcc="${confgcc} --enable-__cxa_atexit" - elif [[ ${CTARGET} == *-freebsd* ]]; then - confgcc="${confgcc} --enable-__cxa_atexit" - fi - [[ ${CTARGET} == *-gnu* ]] && confgcc="${confgcc} --enable-clocale=gnu" - [[ ${CTARGET} == *-uclibc* ]] && [[ ${GCCMAJOR}.${GCCMINOR} > 3.3 ]] \ - && confgcc="${confgcc} --enable-clocale=uclibc" - # Nothing wrong with a good dose of verbosity - echo - einfo "PREFIX: ${PREFIX}" - einfo "BINPATH: ${BINPATH}" - einfo "LIBPATH: ${LIBPATH}" - einfo "DATAPATH: ${DATAPATH}" - einfo "STDCXX_INCDIR: ${STDCXX_INCDIR}" - echo - einfo "Configuring GCC with: ${confgcc//--/\n\t--} ${@} ${EXTRA_ECONF}" - echo + # Run misc portage update scripts + cd autoconf + gnuconfig_update + aclocal --force -I m4 || die "aclocal failed" + autoconf --force --warnings=all -o ../configure configure.ac || die "autoconf failed" + cd .. + autoheader --warnings=all -I autoconf -I autoconf/m4 autoconf/configure.ac || die "autoheader failed" + + rm -rf projects/sample - # Build in a separate build tree - mkdir -p "${WORKDIR}"/build - pushd "${WORKDIR}"/build > /dev/null +# cd projects/sample/autoconf +# gnuconfig_update +# aclocal -I ../../../autoconf/m4 || die "aclocal failed" +# autoconf --warnings=all -o ../configure configure.ac || die "autoconf failed" +# cd ../../.. - # and now to do the actual configuration - addwrite /dev/zero - "${S}"/configure ${confgcc} $@ ${EXTRA_ECONF} \ - || die "failed to run configure" - - # return to whatever directory we were in before - popd > /dev/null } -# This function accepts one optional argument, the make target to be used. -# If ommitted, gcc_do_make will try to guess whether it should use all, -# profiledbootstrap, or bootstrap-lean depending on CTARGET and arch. An -# example of how to use this function: -# -# gcc_do_make all-target-libstdc++-v3 -# -# In addition to the target to be used, the following variables alter the -# behavior of this function: -# -# LDFLAGS -# Flags to pass to ld -# -# STAGE1_CFLAGS -# CFLAGS to use during stage1 of a gcc bootstrap -# -# BOOT_CFLAGS -# CFLAGS to use during stages 2+3 of a gcc bootstrap. -# -# Travis Tilley (04 Sep 2004) -# -gcc_do_make() { - # Fix for libtool-portage.patch - local OLDS=${S} - S=${WORKDIR}/build +toolchain-llvm_src_unpack() { + is_cross && [[ $(binutils-config -V) != binutils-config-1.9* ]] \ + && die "You need to upgrade your binutils-config to 1.9 or newer" - # Set make target to $1 if passed - [[ -n $1 ]] && GCC_MAKE_TARGET=$1 - # default target - if is_crosscompile || tc-is-cross-compiler ; then - # 3 stage bootstrapping doesnt quite work when you cant run the - # resulting binaries natively ^^; - GCC_MAKE_TARGET=${GCC_MAKE_TARGET-all} - elif [[ $(tc-arch) == "x86" || $(tc-arch) == "amd64" || $(tc-arch) == "ppc64" ]] \ - && [[ ${GCCMAJOR}.${GCCMINOR} > 3.3 ]] - then - GCC_MAKE_TARGET=${GCC_MAKE_TARGET-profiledbootstrap} - else - GCC_MAKE_TARGET=${GCC_MAKE_TARGET-bootstrap-lean} - fi - - # the gcc docs state that parallel make isnt supported for the - # profiledbootstrap target, as collisions in profile collecting may occur. - [[ ${GCC_MAKE_TARGET} == "profiledbootstrap" ]] && export MAKEOPTS="${MAKEOPTS} -j1" - - # boundschecking seems to introduce parallel build issues - want_boundschecking && export MAKEOPTS="${MAKEOPTS} -j1" - - if [[ ${GCC_MAKE_TARGET} == "all" ]] ; then - STAGE1_CFLAGS=${STAGE1_CFLAGS-"${CFLAGS}"} - elif [[ $(gcc-version) == "3.4" && ${GCC_BRANCH_VER} == "3.4" ]] && gcc-specs-ssp ; then - # See bug #79852 - STAGE1_CFLAGS=${STAGE1_CFLAGS-"-O2"} - else - STAGE1_CFLAGS=${STAGE1_CFLAGS-"-O"} - fi - - if is_crosscompile; then - # In 3.4, BOOT_CFLAGS is never used on a crosscompile... - # but I'll leave this in anyways as someone might have had - # some reason for putting it in here... --eradicator - BOOT_CFLAGS=${BOOT_CFLAGS-"-O2"} - else - # we only want to use the system's CFLAGS if not building a - # cross-compiler. - BOOT_CFLAGS=${BOOT_CFLAGS-"$(get_abi_CFLAGS) ${CFLAGS}"} - fi - - pushd "${WORKDIR}"/build - einfo "Running make LDFLAGS=\"${LDFLAGS}\" STAGE1_CFLAGS=\"${STAGE1_CFLAGS}\" LIBPATH=\"${LIBPATH}\" BOOT_CFLAGS=\"${BOOT_CFLAGS}\" ${GCC_MAKE_TARGET}" - - emake \ - LDFLAGS="${LDFLAGS}" \ - STAGE1_CFLAGS="${STAGE1_CFLAGS}" \ - LIBPATH="${LIBPATH}" \ - BOOT_CFLAGS="${BOOT_CFLAGS}" \ - ${GCC_MAKE_TARGET} \ - || die "emake failed with ${GCC_MAKE_TARGET}" - - if ! use build && ! is_crosscompile && ! use nocxx && use doc ; then - if type -p doxygen > /dev/null ; then - cd "${CTARGET}"/libstdc++-v3 - make doxygen-man || ewarn "failed to make docs" - else - ewarn "Skipping libstdc++ manpage generation since you don't have doxygen installed" - fi - fi - - popd + tc-llvm_unpack + tc-llvm_apply_patches } -# This function will add ${GCC_CONFIG_VER} to the names of all shared libraries in the -# directory specified to avoid filename collisions between multiple slotted -# non-versioned gcc targets. If no directory is specified, it is assumed that -# you want -all- shared objects to have ${GCC_CONFIG_VER} added. Example -# -# add_version_to_shared ${D}/usr/$(get_libdir) -# -# Travis Tilley (05 Sep 2004) -# -add_version_to_shared() { - local sharedlib sharedlibdir - [[ -z $1 ]] \ - && sharedlibdir=${D} \ - || sharedlibdir=$1 +toolchain-llvm_src_compile() { + # prevent makeinfo from running in releases. it may not always be + # installed, and older llvm may fail with newer texinfo. + # besides, we never patch the doc files anyways, so regenerating + # in the first place is useless. #193364 +# find . '(' -name '*.info' -o -name '*.texi' ')' -print0 | xargs -0 touch -r . - for sharedlib in $(find ${sharedlibdir} -name *.so.*) ; do - if [[ ! -L ${sharedlib} ]] ; then - einfo "Renaming `basename "${sharedlib}"` to `basename "${sharedlib/.so*/}-${GCC_CONFIG_VER}.so.${sharedlib/*.so./}"`" - mv "${sharedlib}" "${sharedlib/.so*/}-${GCC_CONFIG_VER}.so.${sharedlib/*.so./}" \ - || die - pushd `dirname "${sharedlib}"` > /dev/null || die - ln -sf "`basename "${sharedlib/.so*/}-${GCC_CONFIG_VER}.so.${sharedlib/*.so./}"`" \ - "`basename "${sharedlib}"`" || die - popd > /dev/null || die - fi - done -} + # make sure we filter $LINGUAS so that only ones that + # actually work make it through #42033 +# strip-linguas -u */po -# This is mostly a stub function to be overwritten in an ebuild -gcc_do_filter_flags() { + # keep things sane 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 + local x + echo + for x in CATEGORY CBUILD CHOST CTARGET CFLAGS LDFLAGS ; do + einfo "$(printf '%10s' ${x}:) ${!x}" + done + echo - # ... sure, why not? - strip-unsupported-flags + cd "${MY_BUILDDIR}" + local myconf="" +# use nls \ +# && myconf="${myconf} --without-included-gettext" \ +# || myconf="${myconf} --disable-nls" + use multitarget && myconf="${myconf} --enable-targets=all" + [[ -n ${CBUILD} ]] && myconf="${myconf} --build=${CBUILD}" +# is_cross && myconf="${myconf} --with-sysroot=/usr/${CTARGET}" + myconf="--prefix=/usr \ + --sysconfdir=${LIBPATH}/llvm \ + --host=${CHOST} \ + --target=${CTARGET} \ + --datadir=${DATAPATH} \ + --infodir=${DATAPATH}/info \ + --mandir=${DATAPATH}/man \ + --docdir=${DATAPATH}/doc \ + --bindir=${BINPATH} \ + --libdir=${LIBPATH} \ + --libexecdir=${LIBPATH} \ + --includedir=${INCPATH} \ + --enable-assertions \ + --enable-shared \ + --enable-optimized \ + ${myconf} ${EXTRA_ECONF}" + echo ./configure ${myconf} + "${S}"/configure ${myconf} || die "configure failed" - # dont want to funk ourselves - filter-flags '-mabi*' -m31 -m32 -m64 + emake all || die "emake failed" - case ${GCC_BRANCH_VER} in - 3.2|3.3) - case $(tc-arch) in - x86) filter-flags '-mtune=*';; - amd64) filter-flags '-mtune=*' - replace-cpu-flags k8 athlon64 opteron i686;; - esac - ;; - 3.4|4.*) - case $(tc-arch) in - x86|amd64) filter-flags '-mcpu=*';; - esac - ;; + # only build info pages if we user wants them, and if + # we have makeinfo (may not exist when we bootstrap) +# if ! has noinfo ${FEATURES} ; then +# if type -p makeinfo > /dev/null ; then +# make info || die "make info failed" +# fi +# fi + # we nuke the manpages when we're left with junk + # (like when we bootstrap, no perl -> no manpages) +# find . -name '*.1' -a -size 0 | xargs rm -f + +} + +toolchain-llvm_src_test() { + cd "${MY_BUILDDIR}" + make check || die "check failed :(" +} + +toolchain-llvm_src_install() { + local x d + + cd "${MY_BUILDDIR}" + emake DESTDIR="${D}" install || die + rm -rf "${D}"/${LIBPATH}/bin + + # Newer versions of llvm get fancy with ${LIBPATH} #171905 + cd "${D}"/${LIBPATH} + for d in ../* ; do + [[ ${d} == ../${LVER} ]] && continue + mv ${d}/* . || die + rmdir ${d} || die + done + + # move llvm-config /usr/bin + "${D}"/${BINPATH}/llvm-config "${D}"/usr/bin + + # create compatibility Links + cd "${D}"/${BINPATH} + for x in llvm-* ; do + ln -sf ${x} ${x/llvm-/} + done + + # Now we collect everything intp the proper SLOT-ed dirs + # When something is built to cross-compile, it installs into + # /usr/$CHOST/ by default ... we have to 'fix' that :) + if is_cross ; then + cd "${D}"/${BINPATH} + for x in * ; do + mv ${x} ${x/${CTARGET}-} + done + + if [[ -d ${D}/usr/${CHOST}/${CTARGET} ]] ; then + mv "${D}"/usr/${CHOST}/${CTARGET}/include "${D}"/${INCPATH} + mv "${D}"/usr/${CHOST}/${CTARGET}/lib/* "${D}"/${LIBPATH}/ + rm -r "${D}"/usr/${CHOST}/{include,lib} + fi + fi + insinto ${INCPATH} + if [[ -d ${D}/${LIBPATH}/lib ]] ; then + mv "${D}"/${LIBPATH}/lib/* "${D}"/${LIBPATH}/ + rm -r "${D}"/${LIBPATH}/lib + fi + + # Now, some llvm are tricky and actually provide + # for multiple TARGETS. Really, we're talking just + # 32bit/64bit support (like mips/ppc/sparc). Here + # we want to tell binutils-config that it's cool if + # it generates multiple sets of binutil symlinks. + # e.g. sparc gets {sparc,sparc64}-unknown-linux-gnu + local targ=${CTARGET/-*} src="" dst="" + local FAKE_TARGETS=${CTARGET} + case ${targ} in + mips*) src="mips" dst="mips64";; + powerpc*) src="powerpc" dst="powerpc64";; + s390*) src="s390" dst="s390x";; + sparc*) src="sparc" dst="sparc64";; esac + case ${targ} in + mips64*|powerpc64*|s390x*|sparc64*) targ=${src} src=${dst} dst=${targ};; + esac + [[ -n ${src}${dst} ]] && FAKE_TARGETS="${FAKE_TARGETS} ${CTARGET/${src}/${dst}}" - # Compile problems with these (bug #6641 among others)... - #filter-flags "-fno-exceptions -fomit-frame-pointer -fforce-addr" - - # CFLAGS logic (verified with 3.4.3): - # CFLAGS: - # This conflicts when creating a crosscompiler, so set to a sane - # default in this case: - # used in ./configure and elsewhere for the native compiler - # used by gcc when creating libiberty.a - # used by xgcc when creating libstdc++ (and probably others)! - # this behavior should be removed... - # - # CXXFLAGS: - # used by xgcc when creating libstdc++ - # - # STAGE1_CFLAGS (not used in creating a crosscompile gcc): - # used by ${CHOST}-gcc for building stage1 compiler - # - # BOOT_CFLAGS (not used in creating a crosscompile gcc): - # used by xgcc for building stage2/3 compiler - - if is_crosscompile ; then - # Set this to something sane for both native and target - CFLAGS="-O2 -pipe" - - local VAR="CFLAGS_"${CTARGET//-/_} - CXXFLAGS=${!VAR} - fi - - export GCJFLAGS=${GCJFLAGS:-${CFLAGS}} -} - -gcc_src_compile() { - gcc_do_filter_flags - einfo "CFLAGS=\"${CFLAGS}\"" - einfo "CXXFLAGS=\"${CXXFLAGS}\"" - - # Build in a separate build tree - mkdir -p "${WORKDIR}"/build - pushd "${WORKDIR}"/build > /dev/null - - # Install our pre generated manpages if we do not have perl ... - [[ ! -x /usr/bin/perl ]] && [[ -n ${MAN_VER} ]] && \ - unpack gcc-${MAN_VER}-manpages.tar.bz2 - - einfo "Configuring ${PN} ..." - gcc_do_configure - - touch "${S}"/gcc/c-gperf.h - - # Do not make manpages if we do not have perl ... - [[ ! -x /usr/bin/perl ]] \ - && find "${WORKDIR}"/build -name '*.[17]' | xargs touch - - einfo "Compiling ${PN} ..." - gcc_do_make ${GCC_MAKE_TARGET} - - # Do not create multiple specs files for PIE+SSP if boundschecking is in - # USE, as we disable PIE+SSP when it is. - if [[ ${ETYPE} == "gcc-compiler" ]] && want_split_specs ; then - split_out_specs_files || die "failed to split out specs" - fi - - popd > /dev/null -} - -gcc_src_test() { - cd "${WORKDIR}"/build - make check || ewarn "check failed and that sucks :(" -} - -gcc-library_src_install() { - einfo "Installing ${PN} ..." - # Do the 'make install' from the build directory - cd "${WORKDIR}"/build - S=${WORKDIR}/build \ - make DESTDIR="${D}" \ - prefix=${PREFIX} \ - bindir=${BINPATH} \ - includedir=${LIBPATH}/include \ - datadir=${DATAPATH} \ - mandir=${DATAPATH}/man \ - infodir=${DATAPATH}/info \ - LIBPATH="${LIBPATH}" \ - ${GCC_INSTALL_TARGET} || die - - if [[ ${GCC_LIB_COMPAT_ONLY} == "true" ]] ; then - rm -rf "${D}"${INCLUDEPATH} - rm -rf "${D}"${DATAPATH} - pushd "${D}"${LIBPATH}/ - rm *.a *.la *.so - popd - fi - - if [[ -n ${GCC_LIB_USE_SUBDIR} ]] ; then - mkdir -p "${WORKDIR}"/${GCC_LIB_USE_SUBDIR}/ - mv "${D}"${LIBPATH}/* "${WORKDIR}"/${GCC_LIB_USE_SUBDIR}/ - mv "${WORKDIR}"/${GCC_LIB_USE_SUBDIR}/ "${D}"${LIBPATH} - - dodir /etc/env.d - echo "LDPATH=\"${LIBPATH}/${GCC_LIB_USE_SUBDIR}/\"" >> "${D}"/etc/env.d/99${PN} - fi - - if [[ ${GCC_VAR_TYPE} == "non-versioned" ]] ; then - # if we're not using versioned directories, we need to use versioned - # filenames. - add_version_to_shared - fi -} - -gcc-compiler_src_install() { - local x= - - # Do allow symlinks in ${PREFIX}/lib/gcc-lib/${CHOST}/${GCC_CONFIG_VER}/include as - # this can break the build. - for x in "${WORKDIR}"/build/gcc/include/* ; do - [[ -L ${x} ]] && rm -f "${x}" - 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 - grep -q 'It has been auto-edited by fixincludes from' "${x}" \ - && rm -f "${x}" - done - einfo "Installing GCC..." - # Do the 'make install' from the build directory - cd "${WORKDIR}"/build - S=${WORKDIR}/build \ - make DESTDIR="${D}" install || die - # Punt some tools which are really only useful while building gcc - find "${D}" -name install-tools -type d -exec rm -rf "{}" \; - # This one comes with binutils - find "${D}" -name libiberty.a -exec rm -f "{}" \; - - # Move the libraries to the proper location - gcc_movelibs - - # Basic sanity check - if ! is_crosscompile ; then - local EXEEXT - eval $(grep ^EXEEXT= "${WORKDIR}"/build/gcc/config.log) - [[ -r ${D}${BINPATH}/gcc${EXEEXT} ]] || die "gcc not found in ${D}" - fi - - 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 - create_gcc_env_entry hardenednopiessp - - insinto ${LIBPATH} - doins "${WORKDIR}"/build/*.specs || die "failed to install specs" - fi - - # 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}"${BINPATH} - [[ -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 - dodir /usr/bin - cd "${D}"${BINPATH} - for x in cpp gcc g++ c++ g77 gcj gcjh gfortran ; do - # For some reason, g77 gets made instead of ${CTARGET}-g77... - # this should take care of that - [[ -f ${x} ]] && mv ${x} ${CTARGET}-${x} - - if [[ -f ${CTARGET}-${x} ]] && ! is_crosscompile ; then - ln -sf ${CTARGET}-${x} ${x} - - # Create version-ed symlinks - dosym ${BINPATH}/${CTARGET}-${x} \ - /usr/bin/${CTARGET}-${x}-${GCC_CONFIG_VER} - dosym ${BINPATH}/${CTARGET}-${x} \ - /usr/bin/${x}-${GCC_CONFIG_VER} - fi - - if [[ -f ${CTARGET}-${x}-${GCC_CONFIG_VER} ]] ; then - rm -f ${CTARGET}-${x}-${GCC_CONFIG_VER} - ln -sf ${CTARGET}-${x} ${CTARGET}-${x}-${GCC_CONFIG_VER} - 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 is_objc && ! is_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 - - # Now do the fun stripping stuff - env RESTRICT="" CHOST=${CHOST} prepstrip "${D}${BINPATH}" - env RESTRICT="" CHOST=${CTARGET} prepstrip "${D}${LIBPATH}" - # gcc used to install helper binaries in lib/ but then moved to libexec/ - [[ -d ${D}${PREFIX}/libexec/gcc ]] && \ - env RESTRICT="" CHOST=${CHOST} prepstrip "${D}${PREFIX}/libexec/gcc/${CTARGET}/${GCC_CONFIG_VER}" - + # Generate an env.d entry for this llvm cd "${S}" - if use build || is_crosscompile; then - rm -rf "${D}"/usr/share/{man,info} - rm -rf "${D}"${DATAPATH}/{man,info} - else - local cxx_mandir=${WORKDIR}/build/${CTARGET}/libstdc++-v3/docs/doxygen/man - if [[ -d ${cxx_mandir} ]] ; then - # clean bogus manpages #113902 - find "${cxx_mandir}" -name '*_build_*' -exec rm {} \; - cp -r "${cxx_mandir}"/man? "${D}/${DATAPATH}"/man/ - fi - has noinfo ${FEATURES} \ - && rm -r "${D}/${DATAPATH}"/info \ - || prepinfo "${DATAPATH}" - has noman ${FEATURES} \ - && rm -r "${D}/${DATAPATH}"/man \ - || prepman "${DATAPATH}" - fi - # prune empty dirs left behind + insinto /etc/env.d/binutils + cat <<-EOF > env.d + TARGET="${CTARGET}" + VER="${LVER}" + LIBPATH="${LIBPATH}" + FAKE_TARGETS="${FAKE_TARGETS}" + EOF + newins env.d ${CTARGET}-${LVER} + + # Punt all the fun stuff if user doesn't want it :) + has noinfo ${FEATURES} && rm -r "${D}"/${DATAPATH}/info + has noman ${FEATURES} && rm -r "${D}"/${DATAPATH}/man + # Trim all empty dirs find "${D}" -type d | xargs rmdir >& /dev/null +} - # Rather install the script, else portage with changing $FILESDIR - # between binary and source package borks things .... - if ! is_crosscompile ; then - insinto "${DATAPATH}" - if tc_version_is_at_least 4.0 ; then - newins "${GCC_FILESDIR}"/awk/fixlafiles.awk-no_gcc_la fixlafiles.awk || die - find "${D}/${LIBPATH}" -name libstdc++.la -type f -exec rm "{}" \; +toolchain-llvm_pkg_postinst() { + # Make sure this ${CTARGET} has a binutils version selected + [[ -e ${ROOT}/etc/env.d/binutils/config-${CTARGET} ]] && return 0 + binutils-config ${CTARGET}-${LVER} +} + +toolchain-llvm_pkg_postrm() { + local current_profile=$(binutils-config -c ${CTARGET}) + + # If no other versions exist, then uninstall for this + # target ... otherwise, switch to the newest version + # Note: only do this if this version is unmerged. We + # rerun binutils-config if this is a remerge, as + # we want the mtimes on the symlinks updated (if + # it is the same as the current selected profile) + if [[ ! -e ${BINPATH}/ld ]] && [[ ${current_profile} == ${CTARGET}-${LVER} ]] ; then + local choice=$(binutils-config -l | grep ${CTARGET} | awk '{print $2}') + choice=${choice//$'\n'/ } + choice=${choice/* } + if [[ -z ${choice} ]] ; then + env -i binutils-config -u ${CTARGET} else - doins "${GCC_FILESDIR}"/awk/fixlafiles.awk || die + binutils-config ${choice} fi - exeinto "${DATAPATH}" - doexe "${GCC_FILESDIR}"/fix_libtool_files.sh || die - doexe "${GCC_FILESDIR}"/c{89,99} || die - fi - - # use gid of 0 because some stupid ports don't have - # the group 'root' set to gid 0 - chown -R root:0 "${D}"${LIBPATH} - - # Create config files for eselect-compiler - create_eselect_conf -} - -# Move around the libs to the right location. For some reason, -# when installing gcc, it dumps internal libraries into /usr/lib -# instead of the private gcc lib path -gcc_movelibs() { - # older versions of gcc did not support --print-multi-os-directory - tc_version_is_at_least 3.0 || return 0 - - local multiarg removedirs="" - for multiarg in $($(XGCC) -print-multi-lib) ; do - multiarg=${multiarg#*;} - multiarg=${multiarg//@/ -} - - local OS_MULTIDIR=$($(XGCC) ${multiarg} --print-multi-os-directory) - local MULTIDIR=$($(XGCC) ${multiarg} --print-multi-directory) - local TODIR=${D}${LIBPATH}/${MULTIDIR} - local FROMDIR= - - [[ -d ${TODIR} ]] || mkdir -p ${TODIR} - - for FROMDIR in \ - ${LIBPATH}/${OS_MULTIDIR} \ - ${LIBPATH}/../${MULTIDIR} \ - ${PREFIX}/lib/${OS_MULTIDIR} \ - ${PREFIX}/${CTARGET}/lib/${OS_MULTIDIR} \ - ${PREFIX}/lib/${MULTIDIR} - do - removedirs="${removedirs} ${FROMDIR}" - FROMDIR=${D}${FROMDIR} - if [[ ${FROMDIR} != "${TODIR}" && -d ${FROMDIR} ]] ; then - local files=$(find "${FROMDIR}" -maxdepth 1 ! -type d 2>/dev/null) - if [[ -n ${files} ]] ; then - mv ${files} "${TODIR}" - fi - fi - done - done - - # We remove directories separately to avoid this case: - # mv SRC/lib/../lib/*.o DEST - # rmdir SRC/lib/../lib/ - # mv SRC/lib/../lib32/*.o DEST # Bork - for FROMDIR in ${removedirs} ; do - rmdir "${D}"${FROMDIR} >& /dev/null - done - find "${D}" -type d | xargs rmdir >& /dev/null - - # 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_* >>---- - -#---->> unorganized crap in need of refactoring follows - -# 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 PATCH_GCC_VER=${PATCH_GCC_VER:-${GCC_RELEASE_VER}} - export UCLIBC_GCC_VER=${UCLIBC_GCC_VER:-${PATCH_GCC_VER}} - export PIE_GCC_VER=${PIE_GCC_VER:-${GCC_RELEASE_VER}} - export PP_GCC_VER=${PP_GCC_VER:-${GCC_RELEASE_VER}} - export HTB_GCC_VER=${HTB_GCC_VER:-${GCC_RELEASE_VER}} - - if [[ -n ${GCC_A_FAKEIT} ]] ; then - unpack ${GCC_A_FAKEIT} - elif [[ -n ${PRERELEASE} ]] ; then - unpack gcc-${PRERELEASE}.tar.bz2 - elif [[ -n ${SNAPSHOT} ]] ; then - unpack gcc-${SNAPSHOT}.tar.bz2 - else - unpack gcc-${GCC_RELEASE_VER}.tar.bz2 - # We want branch updates to be against a release tarball - if [[ -n ${BRANCH_UPDATE} ]] ; then - pushd "${S}" > /dev/null - epatch ${DISTDIR}/gcc-${GCC_RELEASE_VER}-branch-update-${BRANCH_UPDATE}.patch.bz2 - popd > /dev/null - fi - fi - - if [[ -n ${D_VER} ]] && use d ; then - pushd "${S}"/gcc > /dev/null - unpack gdc-${D_VER}-src.tar.bz2 - cd .. - ebegin "Adding support for the D language" - ./gcc/d/setup-gcc.sh >& "${T}"/dgcc.log - if ! eend $? ; then - eerror "The D gcc package failed to apply" - eerror "Please include this log file when posting a bug report:" - eerror " ${T}/dgcc.log" - die "failed to include the D language" - fi - popd > /dev/null - fi - - [[ -n ${PATCH_VER} ]] && \ - unpack gcc-${PATCH_GCC_VER}-patches-${PATCH_VER}.tar.bz2 - - [[ -n ${UCLIBC_VER} ]] && \ - unpack gcc-${UCLIBC_GCC_VER}-uclibc-patches-${UCLIBC_VER}.tar.bz2 - - if want_ssp ; then - if [[ -n ${PP_FVER} ]] ; then - # The gcc 3.4 propolice versions are meant to be unpacked to ${S} - pushd "${S}" > /dev/null - unpack protector-${PP_FVER}.tar.gz - popd > /dev/null - else - unpack gcc-${PP_GCC_VER}-ssp-${PP_VER}.tar.bz2 - fi - fi - - if want_pie ; then - if [[ -n ${PIE_CORE} ]] ; then - unpack ${PIE_CORE} - else - unpack gcc-${PIE_GCC_VER}-piepatches-v${PIE_VER}.tar.bz2 - fi - fi - - want_boundschecking && \ - unpack "bounds-checking-gcc-${HTB_GCC_VER}-${HTB_VER}.patch.bz2" - - 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 -} - -# Try to apply some stub patches so that gcc won't error out when -# passed parameters like -fstack-protector but no ssp is found -do_gcc_stub() { - local v stub_patch="" - for v in ${GCC_RELEASE_VER} ${GCC_BRANCH_VER} ; do - stub_patch=${GCC_FILESDIR}/stubs/gcc-${v}-$1-stub.patch - if [[ -e ${stub_patch} ]] && ! use vanilla ; then - EPATCH_SINGLE_MSG="Applying stub patch for $1 ..." \ - epatch "${stub_patch}" - return 0 - fi - done -} - -do_gcc_HTB_patches() { - if ! want_boundschecking || \ - (want_ssp && [[ ${HTB_EXCLUSIVE} == "true" ]]) - then - do_gcc_stub htb - return 0 - fi - - # modify the bounds checking patch with a regression patch - epatch "${WORKDIR}/bounds-checking-gcc-${HTB_GCC_VER}-${HTB_VER}.patch" - release_version="${release_version}, HTB-${HTB_GCC_VER}-${HTB_VER}" -} - -# patch in ProPolice Stack Smashing protection -do_gcc_SSP_patches() { - # PARISC has no love ... it's our stack :( - if [[ $(tc-arch) == "hppa" ]] || \ - ! want_ssp || \ - (want_boundschecking && [[ ${HTB_EXCLUSIVE} == "true" ]]) - then - do_gcc_stub ssp - return 0 - fi - - local ssppatch - local sspdocs - - if [[ -n ${PP_FVER} ]] ; then - # Etoh keeps changing where files are and what the patch is named - if tc_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 tc_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 tc_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" - fi - else - # Just start packaging the damn thing ourselves - mv "${WORKDIR}"/ssp/protector.{c,h} "${S}"/gcc/ - ssppatch=${WORKDIR}/ssp/gcc-${PP_GCC_VER}-ssp.patch - # allow boundschecking and ssp to get along - (want_boundschecking && [[ -e ${WORKDIR}/ssp/htb-ssp.patch ]]) \ - && patch -s "${ssppatch}" "${WORKDIR}"/ssp/htb-ssp.patch - fi - - [[ -z ${ssppatch} ]] && die "Sorry, SSP is not supported in this version" - epatch ${ssppatch} - - if [[ ${PN} == "gcc" && ${sspdocs} == "no" ]] ; then - epatch "${GCC_FILESDIR}"/pro-police-docs.patch - fi - - # Don't build crtbegin/end with ssp - sed -e 's|^CRTSTUFF_CFLAGS = |CRTSTUFF_CFLAGS = -fno-stack-protector |'\ - -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 use build && tc_version_is_at_least 3.4.0 ; then - if gcc -dumpspecs | grep -q "fno-stack-protector:" ; then - epatch "${GCC_FILESDIR}"/3.4.0/gcc-3.4.0-cc1-no-stack-protector.patch - fi - fi - - release_version="${release_version}, ssp-${PP_FVER:-${PP_GCC_VER}-${PP_VER}}" - if want_libssp ; then - update_gcc_for_libssp - else - update_gcc_for_libc_ssp - fi - - # Don't build libgcc with ssp - sed -e 's|^\(LIBGCC2_CFLAGS.*\)$|\1 -fno-stack-protector|' \ - -i gcc/Makefile.in || die "Failed to update gcc!" -} - -# 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!" + elif [[ $(CHOST=${CTARGET} binutils-config -c) == ${CTARGET}-${LVER} ]] ; then + binutils-config ${CTARGET}-${LVER} 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() { - if ! want_pie || \ - (want_boundschecking && [[ ${HTB_EXCLUSIVE} == "true" ]]) - then - return 0 - fi - - want_boundschecking \ - && rm -f "${WORKDIR}"/piepatch/*/*-boundschecking-no.patch* \ - || rm -f "${WORKDIR}"/piepatch/*/*-boundschecking-yes.patch* - - use vanilla && rm -f "${WORKDIR}"/piepatch/*/*uclibc* - - guess_patch_type_in_dir "${WORKDIR}"/piepatch/upstream - - # corrects startfile/endfile selection and shared/static/pie flag usage - EPATCH_MULTI_MSG="Applying upstream pie patches ..." \ - epatch "${WORKDIR}"/piepatch/upstream - # adds non-default pie support (rs6000) - EPATCH_MULTI_MSG="Applying non-default pie patches ..." \ - epatch "${WORKDIR}"/piepatch/nondef - # adds default pie support (rs6000 too) if DEFAULT_PIE[_SSP] is defined - EPATCH_MULTI_MSG="Applying default pie patches ..." \ - epatch "${WORKDIR}"/piepatch/def - - # 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 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 definitely want a new one - # Note: due to bash quirkiness, the following must not be 1 line - local curr_config - curr_config=$(env -i ROOT="${ROOT}" gcc-config -c ${CTARGET} 2>&1) || return 0 - - # if the previously selected config has the same major.minor (branch) as - # the version we are installing, then it will probably be uninstalled - # for being in the same SLOT, make sure we run gcc-config. - local curr_config_ver=$(env -i ROOT="${ROOT}" gcc-config -S ${curr_config} | awk '{print $2}') - - local curr_branch_ver=$(get_version_component_range 1-2 ${curr_config_ver}) - - # If we're using multislot, just run gcc-config if we're installing - # to the same profile as the current one. - use multislot && return $([[ ${curr_config_ver} == ${GCC_CONFIG_VER} ]]) - - if [[ ${curr_branch_ver} == ${GCC_BRANCH_VER} ]] ; 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. - # We don't want to switch from say gcc-3.3 to gcc-3.4 right in - # the middle of an emerge operation (like an 'emerge -e world' - # which could install multiple gcc versions). - 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}-${GCC_CONFIG_VER}" - einfo "source /etc/profile" - echo - ebeep - return 1 - fi -} - -do_gcc_config() { - if ! should_we_gcc_config ; then - env -i ROOT="${ROOT}" gcc-config --use-old --force - return 0 - fi - - local current_gcc_config="" current_specs="" use_specs="" - - # We grep out any possible errors - current_gcc_config=$(env -i ROOT="${ROOT}" gcc-config -c ${CTARGET} | grep -v '^ ') - if [[ -n ${current_gcc_config} ]] ; then - # figure out which specs-specific config is active - current_specs=$(gcc-config -S ${current_gcc_config} | awk '{print $3}') - [[ -n ${current_specs} ]] && use_specs=-${current_specs} - fi - if [[ -n ${use_specs} ]] && \ - [[ ! -e ${ROOT}/etc/env.d/gcc/${CTARGET}-${GCC_CONFIG_VER}${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 - use_specs="" - fi - - gcc-config ${CTARGET}-${GCC_CONFIG_VER}${use_specs} -} - -should_we_eselect_compiler() { - # 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 definitely want a new one - # Note: due to bash quirkiness, the following must not be 1 line - local curr_config - curr_config=$(env -i eselect compiler show ${CTARGET} 2>&1) || return 0 - [[ -z ${curr_config} || ${curr_config} == "(none)" ]] && return 0 - - # if the previously selected config has the same major.minor (branch) as - # the version we are installing, then it will probably be uninstalled - # for being in the same SLOT, make sure we run gcc-config. - local curr_config_ver=$(echo ${curr_config} | cut -f1 -d/ | awk -F - '{ print $5 }') - local curr_branch_ver=$(get_version_component_range 1-2 ${curr_config_ver}) - - # If we're using multislot, just run gcc-config if we're installing - # to the same profile as the current one. - use multislot && return $([[ ${curr_config_ver} == ${GCC_CONFIG_VER} ]]) - - if [[ ${curr_branch_ver} == ${GCC_BRANCH_VER} ]] ; 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. - # We don't want to switch from say gcc-3.3 to gcc-3.4 right in - # the middle of an emerge operation (like an 'emerge -e world' - # which could install multiple gcc versions). - 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 "eselect compiler set " - echo - ebeep - return 1 - fi -} - -do_eselect_compiler() { - if ! should_we_eselect_compiler; then - eselect compiler update - return 0 - fi - - for abi in $(get_all_abis) ; do - local ctarget=$(get_abi_CHOST ${abi}) - local current_specs=$(env -i eselect compiler show ${ctarget} | cut -f2 -d/) - - if [[ -n ${current_specs} && ${current_specs} != "(none)" ]] && eselect compiler set ${CTARGET}-${GCC_CONFIG_VER}/${current_specs} &> /dev/null; then - einfo "The following compiler profile has been activated based on your previous profile:" - einfo "${CTARGET}-${GCC_CONFIG_VER}/${current_specs}" - else - # We couldn't choose based on the old specs, so fall back on vanilla/hardened based on USE - - local spec - if use hardened ; then - spec="hardened" - else - spec="vanilla" - fi - - local profile - local isset=0 - for profile in "${current_specs%-*}-${spec}" "${abi}-${spec}" "${spec}" ; do - if eselect compiler set ${CTARGET}-${GCC_CONFIG_VER}/${profile} &> /dev/null ; then - ewarn "The newly installed version of gcc does not have a profile that matches the name of your" - ewarn "currently selected profile for ${ctarget}, so we have enabled the following instead:" - ewarn "${CTARGET}-${GCC_CONFIG_VER}/${profile}" - ewarn "If this is incorrect, please use 'eselect compiler set' to" - ewarn "select another profile." - - isset=1 - break - fi - done - - if [[ ${isset} == 0 ]] ; then - eerror "We were not able to automatically set the current compiler for ${ctarget}" - eerror "to your newly emerged gcc. Please use 'eselect compiler set'" - eerror "to select your compiler." - fi - fi - done -} - -# 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" - - if grep -qs VERSUFFIX "${S}"/gcc/version.c ; then - sed -i -e "s~VERSUFFIX \"\"~VERSUFFIX \" ($2)\"~" \ - "${S}"/gcc/version.c || die "failed to update VERSUFFIX with Gentoo branding" - else - version_string="$1 ($2)" - sed -i -e "s~\(const char version_string\[\] = \"\).*\(\".*\)~\1$version_string\2~" \ - "${S}"/gcc/version.c || die "failed to update version.c with Gentoo branding." - fi - sed -i -e 's~gcc\.gnu\.org\/bugs\.html~bugs\.gentoo\.org\/~' \ - "${S}"/gcc/version.c || die "Failed to change the bug 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 config - local libdirs - if has_multilib_profile ; then - case $(tc-arch) in - amd64) - config="i386/t-linux64" - libdirs="../$(get_abi_LIBDIR amd64) ../$(get_abi_LIBDIR x86)" \ - ;; - ppc64) - config="rs6000/t-linux64" - libdirs="../$(get_abi_LIBDIR ppc64) ../$(get_abi_LIBDIR ppc)" \ - ;; - esac - else - die "Your profile is no longer supported by portage." - fi - - einfo "updating multilib directories to be: ${libdirs}" - sed -i -e "s:^MULTILIB_OSDIRNAMES.*:MULTILIB_OSDIRNAMES = ${libdirs}:" "${S}"/gcc/config/${config} -} - -disable_multilib_libjava() { - if is_gcj ; then - # 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 - fi -} - -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 -} - -is_multilib() { - [[ ${GCCMAJOR} < 3 ]] && return 1 - case ${CTARGET} in - mips64*|powerpc64*|s390x*|sparc64*|x86_64*) - has_multilib_profile || use multilib ;; - *) false ;; - esac -} - -is_cxx() { - gcc-lang-supported 'c++' || return 1 - use build && return 1 - ! use nocxx -} - -is_d() { - gcc-lang-supported d || return 1 - use build && return 1 - use d -} - -is_f77() { - gcc-lang-supported f77 || return 1 - use build && return 1 - use fortran -} - -is_f95() { - gcc-lang-supported f95 || return 1 - use build && return 1 - use fortran -} - -is_fortran() { - gcc-lang-supported fortran || return 1 - use build && return 1 - use fortran -} - -is_gcj() { - gcc-lang-supported java || return 1 - use build && return 1 - use gcj -} - -is_objc() { - gcc-lang-supported objc || return 1 - use build && return 1 - use objc -} - -is_objcxx() { - gcc-lang-supported 'obj-c++' || return 1 - use build && return 1 - use objc++ -} - -is_ada() { - gcc-lang-supported ada || return 1 - use build && return 1 - use ada -} diff --git a/sys-devel/llvm/Manifest b/sys-devel/llvm/Manifest new file mode 100644 index 00000000..2396ae77 --- /dev/null +++ b/sys-devel/llvm/Manifest @@ -0,0 +1,9 @@ +DIST llvm-2.1-patches-1.0.tar.bz2 1573 RMD160 d96dc943b009841b9d83b409ea8680ac172693b7 SHA1 d223775c1a09d653a8d911e862d3b5eb78dd8e5e SHA256 3bee0bfe07291a3e133eb43fcd8e245c3c7605122d9b68ef8b09f071ff1f059f +DIST llvm-2.1.tar.gz 5062241 RMD160 df28ee93be79b8d436deb7c0e1cff1c21e1328be SHA1 e57081e1bc7c2cb168859f534c08b579276c3398 SHA256 8cabd422f249ada736d864fc8a1f4d14aabefacb6f860c9beefbc53f93e0f96c +EBUILD llvm-2.1.ebuild 176 RMD160 9f7b33bdedc3eca0ce04a61c5c82ef8b331aef6a SHA1 8c52175a0cf89471c3a9d27a118898b4d15ba90b SHA256 77abaacb58f0eab70168cf6636e0578ae078e80051739cbf606f0a3424d91acf +MD5 df4cb1f76ce0ffa0f2f327492e78dcf6 llvm-2.1.ebuild 176 +RMD160 9f7b33bdedc3eca0ce04a61c5c82ef8b331aef6a llvm-2.1.ebuild 176 +SHA256 77abaacb58f0eab70168cf6636e0578ae078e80051739cbf606f0a3424d91acf llvm-2.1.ebuild 176 +MD5 67e5687abc2e18ffcdf0c6e0d781de10 files/digest-llvm-2.1 488 +RMD160 07969f3cb2e375afe8f6ba62c66f38837f44ba4e files/digest-llvm-2.1 488 +SHA256 02c18aea4c9ce3944e51a1b1497a9e88dd50431b76a31289344cb686f839281d files/digest-llvm-2.1 488 diff --git a/sys-devel/llvm/files/digest-llvm-2.1 b/sys-devel/llvm/files/digest-llvm-2.1 new file mode 100644 index 00000000..ce45dea8 --- /dev/null +++ b/sys-devel/llvm/files/digest-llvm-2.1 @@ -0,0 +1,6 @@ +MD5 1d9935665e12aa49545a95847a44bde3 llvm-2.1-patches-1.0.tar.bz2 1573 +RMD160 d96dc943b009841b9d83b409ea8680ac172693b7 llvm-2.1-patches-1.0.tar.bz2 1573 +SHA256 3bee0bfe07291a3e133eb43fcd8e245c3c7605122d9b68ef8b09f071ff1f059f llvm-2.1-patches-1.0.tar.bz2 1573 +MD5 b930e7213b37acc934d0d163cf13af18 llvm-2.1.tar.gz 5062241 +RMD160 df28ee93be79b8d436deb7c0e1cff1c21e1328be llvm-2.1.tar.gz 5062241 +SHA256 8cabd422f249ada736d864fc8a1f4d14aabefacb6f860c9beefbc53f93e0f96c llvm-2.1.tar.gz 5062241 diff --git a/sys-devel/llvm/llvm-2.1.ebuild b/sys-devel/llvm/llvm-2.1.ebuild new file mode 100644 index 00000000..ba7bafe4 --- /dev/null +++ b/sys-devel/llvm/llvm-2.1.ebuild @@ -0,0 +1,8 @@ +# Copyright 1999-2007 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: $ + +PATCHVER="1.0" +inherit toolchain-llvm + +KEYWORDS="~x86"