toolchain.eclass: port to EAPI=7
[gentoo.git] / eclass / toolchain.eclass
1 # Copyright 1999-2019 Gentoo Authors
2 # Distributed under the terms of the GNU General Public License v2
3
4 # Maintainer: Toolchain Ninjas <toolchain@gentoo.org>
5 # @SUPPORTED_EAPIS: 5 6 7
6
7 DESCRIPTION="The GNU Compiler Collection"
8 HOMEPAGE="https://gcc.gnu.org/"
9 RESTRICT="strip" # cross-compilers need controlled stripping
10
11 inherit eutils fixheadtails flag-o-matic gnuconfig libtool multilib pax-utils toolchain-funcs prefix
12
13 if [[ ${PV} == *_pre9999* ]] ; then
14         EGIT_REPO_URI="git://gcc.gnu.org/git/gcc.git"
15         # naming style:
16         # gcc-4.7.1_pre9999 -> gcc-4_7-branch
17         #  Note that the micro version is required or lots of stuff will break.
18         #  To checkout master set gcc_LIVE_BRANCH="master" in the ebuild before
19         #  inheriting this eclass.
20         EGIT_BRANCH="${PN}-${PV%.?_pre9999}-branch"
21         EGIT_BRANCH=${EGIT_BRANCH//./_}
22         inherit git-2
23 fi
24
25 FEATURES=${FEATURES/multilib-strict/}
26
27 case ${EAPI:-0} in
28         0|1|2|3|4*) die "Need to upgrade to at least EAPI=5" ;;
29         5*|6) inherit eapi7-ver ;;
30         7) ;;
31         *) die "I don't speak EAPI ${EAPI}." ;;
32 esac
33 EXPORT_FUNCTIONS pkg_pretend pkg_setup src_unpack src_prepare src_configure \
34         src_compile src_test src_install pkg_postinst pkg_postrm
35
36 #---->> globals <<----
37
38 export CTARGET=${CTARGET:-${CHOST}}
39 if [[ ${CTARGET} = ${CHOST} ]] ; then
40         if [[ ${CATEGORY} == cross-* ]] ; then
41                 export CTARGET=${CATEGORY#cross-}
42         fi
43 fi
44 : ${TARGET_ABI:=${ABI}}
45 : ${TARGET_MULTILIB_ABIS:=${MULTILIB_ABIS}}
46 : ${TARGET_DEFAULT_ABI:=${DEFAULT_ABI}}
47
48 is_crosscompile() {
49         [[ ${CHOST} != ${CTARGET} ]]
50 }
51
52 # General purpose version check.  Without a second arg matches up to minor version (x.x.x)
53 tc_version_is_at_least() {
54         ver_test "${2:-${GCC_RELEASE_VER}}" -ge "$1"
55 }
56
57 # General purpose version range check
58 # Note that it matches up to but NOT including the second version
59 tc_version_is_between() {
60         tc_version_is_at_least "${1}" && ! tc_version_is_at_least "${2}"
61 }
62
63 GCC_PV=${TOOLCHAIN_GCC_PV:-${PV}}
64 GCC_PVR=${GCC_PV}
65 [[ ${PR} != "r0" ]] && GCC_PVR=${GCC_PVR}-${PR}
66 GCC_RELEASE_VER=$(ver_cut 1-3 ${GCC_PV})
67 GCC_BRANCH_VER=$(ver_cut 1-2 ${GCC_PV})
68 GCCMAJOR=$(ver_cut 1 ${GCC_PV})
69 GCCMINOR=$(ver_cut 2 ${GCC_PV})
70 GCCMICRO=$(ver_cut 3 ${GCC_PV})
71
72 # According to gcc/c-cppbuiltin.c, GCC_CONFIG_VER MUST match this regex.
73 # ([^0-9]*-)?[0-9]+[.][0-9]+([.][0-9]+)?([- ].*)?
74 GCC_CONFIG_VER=${GCC_CONFIG_VER:-$(ver_rs 3 '-' ${GCC_PV})}
75
76 # Pre-release support
77 if [[ ${GCC_PV} == *_pre* ]] ; then
78         PRERELEASE=${GCC_PV/_pre/-}
79 elif [[ ${GCC_PV} == *_alpha* ]] ; then
80         SNAPSHOT=${GCC_BRANCH_VER}-${GCC_PV##*_alpha}
81 elif [[ ${GCC_PV} == *_beta* ]] ; then
82         SNAPSHOT=${GCC_BRANCH_VER}-${GCC_PV##*_beta}
83 elif [[ ${GCC_PV} == *_rc* ]] ; then
84         SNAPSHOT=${GCC_PV%_rc*}-RC-${GCC_PV##*_rc}
85 fi
86
87 if [[ ${SNAPSHOT} == [56789].0-* ]] ; then
88         # The gcc-5+ releases have dropped the .0 for some reason.
89         SNAPSHOT=${SNAPSHOT/.0}
90 fi
91
92 PREFIX=${TOOLCHAIN_PREFIX:-${EPREFIX}/usr}
93
94 if tc_version_is_at_least 3.4.0 ; then
95         LIBPATH=${TOOLCHAIN_LIBPATH:-${PREFIX}/lib/gcc/${CTARGET}/${GCC_CONFIG_VER}}
96 else
97         LIBPATH=${TOOLCHAIN_LIBPATH:-${PREFIX}/lib/gcc-lib/${CTARGET}/${GCC_CONFIG_VER}}
98 fi
99 INCLUDEPATH=${TOOLCHAIN_INCLUDEPATH:-${LIBPATH}/include}
100
101 if is_crosscompile ; then
102         BINPATH=${TOOLCHAIN_BINPATH:-${PREFIX}/${CHOST}/${CTARGET}/gcc-bin/${GCC_CONFIG_VER}}
103         HOSTLIBPATH=${PREFIX}/${CHOST}/${CTARGET}/lib/${GCC_CONFIG_VER}
104 else
105         BINPATH=${TOOLCHAIN_BINPATH:-${PREFIX}/${CTARGET}/gcc-bin/${GCC_CONFIG_VER}}
106 fi
107
108 DATAPATH=${TOOLCHAIN_DATAPATH:-${PREFIX}/share/gcc-data/${CTARGET}/${GCC_CONFIG_VER}}
109
110 # Dont install in /usr/include/g++-v3/, but in gcc internal directory.
111 # We will handle /usr/include/g++-v3/ with gcc-config ...
112 STDCXX_INCDIR=${TOOLCHAIN_STDCXX_INCDIR:-${LIBPATH}/include/g++-v${GCC_BRANCH_VER/\.*/}}
113
114 #---->> LICENSE+SLOT+IUSE logic <<----
115
116 if tc_version_is_at_least 4.6 ; then
117         LICENSE="GPL-3+ LGPL-3+ || ( GPL-3+ libgcc libstdc++ gcc-runtime-library-exception-3.1 ) FDL-1.3+"
118 elif tc_version_is_at_least 4.4 ; then
119         LICENSE="GPL-3+ LGPL-3+ || ( GPL-3+ libgcc libstdc++ gcc-runtime-library-exception-3.1 ) FDL-1.2+"
120 elif tc_version_is_at_least 4.3 ; then
121         LICENSE="GPL-3+ LGPL-3+ || ( GPL-3+ libgcc libstdc++ ) FDL-1.2+"
122 elif tc_version_is_at_least 4.2 ; then
123         LICENSE="GPL-3+ LGPL-2.1+ || ( GPL-3+ libgcc libstdc++ ) FDL-1.2+"
124 elif tc_version_is_at_least 3.3 ; then
125         LICENSE="GPL-2+ LGPL-2.1+ FDL-1.2+"
126 else
127         LICENSE="GPL-2+ LGPL-2.1+ FDL-1.1+"
128 fi
129
130 if tc_version_is_at_least 8.3; then
131         GCC_EBUILD_TEST_FLAG='test'
132 else
133         # Don't force USE regression-test->test change on every
134         # gcc ebuild just yet. Let's do the change when >=gcc-8.3
135         # is commonly used as a main compiler.
136         GCC_EBUILD_TEST_FLAG='regression-test'
137 fi
138 IUSE="${GCC_EBUILD_TEST_FLAG} vanilla +nls"
139
140 TC_FEATURES=()
141
142 tc_has_feature() {
143         has "$1" "${TC_FEATURES[@]}"
144 }
145
146 if [[ ${PN} != "kgcc64" && ${PN} != gcc-* ]] ; then
147         IUSE+=" altivec debug +cxx +fortran +nptl" TC_FEATURES+=(fortran nptl)
148         [[ -n ${PIE_VER} ]] && IUSE+=" nopie"
149         [[ -n ${HTB_VER} ]] && IUSE+=" boundschecking"
150         [[ -n ${D_VER}   ]] && IUSE+=" d"
151         [[ -n ${SPECS_VER} ]] && IUSE+=" nossp"
152         tc_version_is_at_least 3 && IUSE+=" doc hardened multilib objc"
153         tc_version_is_between 3 7 && IUSE+=" awt gcj" TC_FEATURES+=(gcj)
154         tc_version_is_at_least 3.3 && IUSE+=" pgo"
155         tc_version_is_at_least 4.0 &&
156                 IUSE+=" objc-gc" TC_FEATURES+=(objc-gc)
157         tc_version_is_between 4.0 4.9 && IUSE+=" mudflap"
158         tc_version_is_at_least 4.1 && IUSE+=" libssp objc++"
159         tc_version_is_at_least 4.2 && IUSE+=" +openmp"
160         tc_version_is_at_least 4.3 && IUSE+=" fixed-point"
161         tc_version_is_at_least 4.7 && IUSE+=" go"
162         # Note: while <=gcc-4.7 also supported graphite, it required forked ppl
163         # versions which we dropped.  Since graphite was also experimental in
164         # the older versions, we don't want to bother supporting it.  #448024
165         tc_version_is_at_least 4.8 &&
166                 IUSE+=" graphite +sanitize" TC_FEATURES+=(graphite)
167         tc_version_is_between 4.9 8 && IUSE+=" cilk"
168         tc_version_is_at_least 4.9 && IUSE+=" +vtv"
169         tc_version_is_at_least 5.0 && IUSE+=" jit"
170         tc_version_is_between 5.0 9 && IUSE+=" mpx"
171         tc_version_is_at_least 6.0 && IUSE+=" +pie +ssp +pch"
172         # systemtap is a gentoo-specific switch: bug #654748
173         tc_version_is_at_least 8.0 &&
174                 IUSE+=" systemtap" TC_FEATURES+=(systemtap)
175         tc_version_is_at_least 9.0 && IUSE+=" d"
176         tc_version_is_at_least 9.1 && IUSE+=" lto"
177 fi
178
179 SLOT="${GCC_CONFIG_VER}"
180
181 #---->> DEPEND <<----
182
183 RDEPEND="sys-libs/zlib
184         nls? ( virtual/libintl )"
185
186 tc_version_is_at_least 3 && RDEPEND+=" virtual/libiconv"
187
188 if tc_version_is_at_least 4 ; then
189         GMP_MPFR_DEPS=">=dev-libs/gmp-4.3.2:0= >=dev-libs/mpfr-2.4.2:0="
190         if tc_version_is_at_least 4.3 ; then
191                 RDEPEND+=" ${GMP_MPFR_DEPS}"
192         elif tc_has_feature fortran ; then
193                 RDEPEND+=" fortran? ( ${GMP_MPFR_DEPS} )"
194         fi
195 fi
196
197 tc_version_is_at_least 4.5 && RDEPEND+=" >=dev-libs/mpc-0.8.1:0="
198
199 if tc_has_feature objc-gc ; then
200         if tc_version_is_at_least 7 ; then
201                 RDEPEND+=" objc-gc? ( >=dev-libs/boehm-gc-7.4.2 )"
202         fi
203 fi
204
205 if tc_has_feature graphite ; then
206         if tc_version_is_at_least 5.0 ; then
207                 RDEPEND+=" graphite? ( >=dev-libs/isl-0.14:0= )"
208         elif tc_version_is_at_least 4.8 ; then
209                 RDEPEND+="
210                         graphite? (
211                                 >=dev-libs/cloog-0.18.0:0=
212                                 >=dev-libs/isl-0.11.1:0=
213                         )"
214         fi
215 fi
216
217 DEPEND="${RDEPEND}
218         >=sys-devel/bison-1.875
219         >=sys-devel/flex-2.5.4
220         nls? ( sys-devel/gettext )
221         ${GCC_EBUILD_TEST_FLAG}? (
222                 >=dev-util/dejagnu-1.4.4
223                 >=sys-devel/autogen-5.5.4
224         )"
225
226 if tc_has_feature gcj ; then
227         GCJ_DEPS=">=media-libs/libart_lgpl-2.1"
228         GCJ_GTK_DEPS="
229                 x11-base/xorg-proto
230                 x11-libs/libXt
231                 x11-libs/libX11
232                 x11-libs/libXtst
233                 =x11-libs/gtk+-2*
234                 virtual/pkgconfig
235         "
236         tc_version_is_at_least 3.4 && GCJ_GTK_DEPS+=" x11-libs/pango"
237         tc_version_is_at_least 4.2 && GCJ_DEPS+=" app-arch/zip app-arch/unzip"
238         DEPEND+=" gcj? ( awt? ( ${GCJ_GTK_DEPS} ) ${GCJ_DEPS} )"
239 fi
240
241 if tc_has_feature systemtap ; then
242         # gcc needs sys/sdt.h headers on target
243         DEPEND+=" systemtap? ( dev-util/systemtap )"
244 fi
245
246 PDEPEND=">=sys-devel/gcc-config-1.7"
247
248 #---->> S + SRC_URI essentials <<----
249
250 # Set the source directory depending on whether we're using
251 # a prerelease, snapshot, or release tarball.
252 S=$(
253         if [[ -n ${PRERELEASE} ]] ; then
254                 echo ${WORKDIR}/gcc-${PRERELEASE}
255         elif [[ -n ${SNAPSHOT} ]] ; then
256                 echo ${WORKDIR}/gcc-${SNAPSHOT}
257         else
258                 echo ${WORKDIR}/gcc-${GCC_RELEASE_VER}
259         fi
260 )
261
262 gentoo_urls() {
263         local devspace="HTTP~vapier/dist/URI HTTP~rhill/dist/URI
264         HTTP~zorry/patches/gcc/URI HTTP~blueness/dist/URI
265         HTTP~tamiko/distfiles/URI HTTP~slyfox/distfiles/URI"
266         devspace=${devspace//HTTP/https:\/\/dev.gentoo.org\/}
267         echo mirror://gentoo/$1 ${devspace//URI/$1}
268 }
269
270 # This function handles the basics of setting the SRC_URI for a gcc ebuild.
271 # To use, set SRC_URI with:
272 #
273 #       SRC_URI="$(get_gcc_src_uri)"
274 #
275 # Other than the variables normally set by portage, this function's behavior
276 # can be altered by setting the following:
277 #
278 #       SNAPSHOT
279 #                       If set, this variable signals that we should be using a snapshot of
280 #                       gcc. It is expected to be in the format "YYYY-MM-DD". Note that if
281 #                       the ebuild has a _pre suffix, this variable is ignored and the
282 #                       prerelease tarball is used instead.
283 #
284 #       PATCH_VER
285 #       PATCH_GCC_VER
286 #                       This should be set to the version of the gentoo patch tarball.
287 #                       The resulting filename of this tarball will be:
288 #                       gcc-${PATCH_GCC_VER:-${GCC_RELEASE_VER}}-patches-${PATCH_VER}.tar.bz2
289 #
290 #       PIE_VER
291 #       PIE_GCC_VER
292 #                       These variables control patching in various updates for the logic
293 #                       controlling Position Independant Executables. PIE_VER is expected
294 #                       to be the version of this patch, and PIE_GCC_VER the gcc version of
295 #                       the patch:
296 #                       An example:
297 #                                       PIE_VER="8.7.6.5"
298 #                                       PIE_GCC_VER="3.4.0"
299 #                       The resulting filename of this tarball will be:
300 #                       gcc-${PIE_GCC_VER:-${GCC_RELEASE_VER}}-piepatches-v${PIE_VER}.tar.bz2
301 #
302 #       SPECS_VER
303 #       SPECS_GCC_VER
304 #                       This is for the minispecs files included in the hardened gcc-4.x
305 #                       The specs files for hardenedno*, vanilla and for building the "specs" file.
306 #                       SPECS_VER is expected to be the version of this patch, SPECS_GCC_VER
307 #                       the gcc version of the patch.
308 #                       An example:
309 #                                       SPECS_VER="8.7.6.5"
310 #                                       SPECS_GCC_VER="3.4.0"
311 #                       The resulting filename of this tarball will be:
312 #                       gcc-${SPECS_GCC_VER:-${GCC_RELEASE_VER}}-specs-${SPECS_VER}.tar.bz2
313 #
314 #       HTB_VER
315 #       HTB_GCC_VER
316 #                       These variables control whether or not an ebuild supports Herman
317 #                       ten Brugge's bounds-checking patches. If you want to use a patch
318 #                       for an older gcc version with a new gcc, make sure you set
319 #                       HTB_GCC_VER to that version of gcc.
320 #
321 #       CYGWINPORTS_GITREV
322 #                       If set, this variable signals that we should apply additional patches
323 #                       maintained by upstream Cygwin developers at github/cygwinports/gcc,
324 #                       using the specified git commit id there.  The list of patches to
325 #                       apply is extracted from gcc.cygport, maintained there as well.
326 #                       This is done for compilers running on Cygwin, not for cross compilers
327 #                       with a Cygwin target.
328 get_gcc_src_uri() {
329         export PATCH_GCC_VER=${PATCH_GCC_VER:-${GCC_RELEASE_VER}}
330         export UCLIBC_GCC_VER=${UCLIBC_GCC_VER:-${PATCH_GCC_VER}}
331         export PIE_GCC_VER=${PIE_GCC_VER:-${GCC_RELEASE_VER}}
332         export HTB_GCC_VER=${HTB_GCC_VER:-${GCC_RELEASE_VER}}
333         export SPECS_GCC_VER=${SPECS_GCC_VER:-${GCC_RELEASE_VER}}
334
335         # Set where to download gcc itself depending on whether we're using a
336         # prerelease, snapshot, or release tarball.
337         if [[ ${PV} == *9999* ]] ; then
338                 # Nothing to do w/git snapshots.
339                 :
340         elif [[ -n ${PRERELEASE} ]] ; then
341                 GCC_SRC_URI="ftp://gcc.gnu.org/pub/gcc/prerelease-${PRERELEASE}/gcc-${PRERELEASE}.tar.bz2"
342         elif [[ -n ${SNAPSHOT} ]] ; then
343                 if tc_version_is_between 5.5 6 || tc_version_is_between 6.4 7 || tc_version_is_at_least 7.2 ; then
344                         GCC_SRC_URI="ftp://gcc.gnu.org/pub/gcc/snapshots/${SNAPSHOT}/gcc-${SNAPSHOT}.tar.xz"
345                 else
346                         GCC_SRC_URI="ftp://gcc.gnu.org/pub/gcc/snapshots/${SNAPSHOT}/gcc-${SNAPSHOT}.tar.bz2"
347                 fi
348         else
349                 if tc_version_is_between 5.5 6 || tc_version_is_between 6.4 7 || tc_version_is_at_least 7.2 ; then
350                         GCC_SRC_URI="mirror://gnu/gcc/gcc-${GCC_PV}/gcc-${GCC_RELEASE_VER}.tar.xz"
351                 else
352                         GCC_SRC_URI="mirror://gnu/gcc/gcc-${GCC_PV}/gcc-${GCC_RELEASE_VER}.tar.bz2"
353                 fi
354         fi
355
356         [[ -n ${UCLIBC_VER} ]] && \
357                 GCC_SRC_URI+=" $(gentoo_urls gcc-${UCLIBC_GCC_VER}-uclibc-patches-${UCLIBC_VER}.tar.bz2)"
358         [[ -n ${PATCH_VER} ]] && \
359                 GCC_SRC_URI+=" $(gentoo_urls gcc-${PATCH_GCC_VER}-patches-${PATCH_VER}.tar.bz2)"
360
361         # strawberry pie, Cappuccino and a Gauloises (it's a good thing)
362         [[ -n ${PIE_VER} ]] && \
363                 PIE_CORE=${PIE_CORE:-gcc-${PIE_GCC_VER}-piepatches-v${PIE_VER}.tar.bz2} && \
364                 GCC_SRC_URI+=" $(gentoo_urls ${PIE_CORE})"
365
366         # gcc minispec for the hardened gcc 4 compiler
367         [[ -n ${SPECS_VER} ]] && \
368                 GCC_SRC_URI+=" $(gentoo_urls gcc-${SPECS_GCC_VER}-specs-${SPECS_VER}.tar.bz2)"
369
370         # gcc bounds checking patch
371         if [[ -n ${HTB_VER} ]] ; then
372                 local HTBFILE="bounds-checking-gcc-${HTB_GCC_VER}-${HTB_VER}.patch.bz2"
373                 GCC_SRC_URI+="
374                         boundschecking? (
375                                 mirror://sourceforge/boundschecking/${HTBFILE}
376                                 $(gentoo_urls ${HTBFILE})
377                         )"
378         fi
379
380         [[ -n ${D_VER} ]] && \
381                 GCC_SRC_URI+=" d? ( mirror://sourceforge/dgcc/gdc-${D_VER}-src.tar.bz2 )"
382
383         if tc_has_feature gcj ; then
384                 if tc_version_is_at_least 4.5 ; then
385                         GCC_SRC_URI+=" gcj? ( ftp://sourceware.org/pub/java/ecj-4.5.jar )"
386                 elif tc_version_is_at_least 4.3 ; then
387                         GCC_SRC_URI+=" gcj? ( ftp://sourceware.org/pub/java/ecj-4.3.jar )"
388                 fi
389         fi
390
391         # Cygwin patches from https://github.com/cygwinports/gcc
392         [[ -n ${CYGWINPORTS_GITREV} ]] && \
393                 GCC_SRC_URI+=" elibc_Cygwin? ( https://github.com/cygwinports/gcc/archive/${CYGWINPORTS_GITREV}.tar.gz
394                         -> gcc-cygwinports-${CYGWINPORTS_GITREV}.tar.gz )"
395
396         echo "${GCC_SRC_URI}"
397 }
398
399 SRC_URI=$(get_gcc_src_uri)
400
401 #---->> pkg_pretend <<----
402
403 toolchain_pkg_pretend() {
404         if [[ -n ${PRERELEASE}${SNAPSHOT} || ${PV} == *9999* ]] &&
405            [[ -z ${I_PROMISE_TO_SUPPLY_PATCHES_WITH_BUGS} ]] ; then
406                 die "Please \`export I_PROMISE_TO_SUPPLY_PATCHES_WITH_BUGS=1\` or define it" \
407                         "in your make.conf if you want to use this version."
408         fi
409
410         if ! use_if_iuse cxx ; then
411                 use_if_iuse go && ewarn 'Go requires a C++ compiler, disabled due to USE="-cxx"'
412                 use_if_iuse objc++ && ewarn 'Obj-C++ requires a C++ compiler, disabled due to USE="-cxx"'
413                 use_if_iuse gcj && ewarn 'GCJ requires a C++ compiler, disabled due to USE="-cxx"'
414         fi
415
416         want_minispecs
417 }
418
419 #---->> pkg_setup <<----
420
421 toolchain_pkg_setup() {
422         # we dont want to use the installed compiler's specs to build gcc
423         unset GCC_SPECS
424         unset LANGUAGES #265283
425 }
426
427 #---->> src_unpack <<----
428
429 toolchain_src_unpack() {
430         if [[ ${PV} == *9999* ]]; then
431                 git-2_src_unpack
432         else
433                 gcc_quick_unpack
434         fi
435 }
436
437 gcc_quick_unpack() {
438         pushd "${WORKDIR}" > /dev/null
439         export PATCH_GCC_VER=${PATCH_GCC_VER:-${GCC_RELEASE_VER}}
440         export UCLIBC_GCC_VER=${UCLIBC_GCC_VER:-${PATCH_GCC_VER}}
441         export PIE_GCC_VER=${PIE_GCC_VER:-${GCC_RELEASE_VER}}
442         export HTB_GCC_VER=${HTB_GCC_VER:-${GCC_RELEASE_VER}}
443         export SPECS_GCC_VER=${SPECS_GCC_VER:-${GCC_RELEASE_VER}}
444
445         # Injection point for more tarballs. dev-lang/gnat-gpl uses
446         # 'GCC_A_FAKEIT' to specify it's own source and binary tarballs.
447         if [[ -n ${GCC_A_FAKEIT} ]] ; then
448                 unpack ${GCC_A_FAKEIT}
449         elif [[ -n ${PRERELEASE} ]] ; then
450                 unpack gcc-${PRERELEASE}.tar.bz2
451         elif [[ -n ${SNAPSHOT} ]] ; then
452                 if tc_version_is_between 5.5 6 || tc_version_is_between 6.4 7 || tc_version_is_at_least 7.2 ; then
453                         unpack gcc-${SNAPSHOT}.tar.xz
454                 else
455                         unpack gcc-${SNAPSHOT}.tar.bz2
456                 fi
457         elif [[ ${PV} != *9999* ]] ; then
458                 if tc_version_is_between 5.5 6 || tc_version_is_between 6.4 7 || tc_version_is_at_least 7.2 ; then
459                         unpack gcc-${GCC_RELEASE_VER}.tar.xz
460                 else
461                         unpack gcc-${GCC_RELEASE_VER}.tar.bz2
462                 fi
463         fi
464
465         if [[ -n ${D_VER} ]] && use d ; then
466                 pushd "${S}"/gcc > /dev/null
467                 unpack gdc-${D_VER}-src.tar.bz2
468                 cd ..
469                 ebegin "Adding support for the D language"
470                 ./gcc/d/setup-gcc.sh >& "${T}"/dgcc.log
471                 if ! eend $? ; then
472                         eerror "The D GCC package failed to apply"
473                         eerror "Please include this log file when posting a bug report:"
474                         eerror "  ${T}/dgcc.log"
475                         die "failed to include the D language"
476                 fi
477                 popd > /dev/null
478         fi
479
480         [[ -n ${PATCH_VER} ]] && \
481                 unpack gcc-${PATCH_GCC_VER}-patches-${PATCH_VER}.tar.bz2
482
483         [[ -n ${UCLIBC_VER} ]] && \
484                 unpack gcc-${UCLIBC_GCC_VER}-uclibc-patches-${UCLIBC_VER}.tar.bz2
485
486         if want_pie ; then
487                 if [[ -n ${PIE_CORE} ]] ; then
488                         unpack ${PIE_CORE}
489                 else
490                         unpack gcc-${PIE_GCC_VER}-piepatches-v${PIE_VER}.tar.bz2
491                 fi
492                 [[ -n ${SPECS_VER} ]] && \
493                         unpack gcc-${SPECS_GCC_VER}-specs-${SPECS_VER}.tar.bz2
494         fi
495
496         use_if_iuse boundschecking && unpack "bounds-checking-gcc-${HTB_GCC_VER}-${HTB_VER}.patch.bz2"
497
498         [[ -n ${CYGWINPORTS_GITREV} ]] && use elibc_Cygwin && unpack "gcc-cygwinports-${CYGWINPORTS_GITREV}.tar.gz"
499
500         popd > /dev/null
501 }
502
503 #---->> src_prepare <<----
504
505 # 'epatch' is not available in EAPI=7. Abstract away patchset application
506 # until we eventually get all gcc ebuilds on EAPI=7 or later.
507 tc_apply_patches() {
508         [[ ${#@} -lt 2 ]] && die "usage: tc_apply_patches <message> <patches...>"
509
510         einfo "$1"; shift
511
512         case ${EAPI:-0} in
513                 # Note: even for EAPI=6 we used 'epatch' semantics. To avoid
514                 # breaking existing ebuilds use 'eapply' only in EAPI=7 or later.
515                 5*|6) epatch "$@" ;;
516                 7) eapply "$@" ;;
517                 *) die "Update apply_patches() for ${EAPI}." ;;
518         esac
519 }
520
521 toolchain_src_prepare() {
522         export BRANDING_GCC_PKGVERSION="Gentoo ${GCC_PVR}"
523         cd "${S}"
524
525         do_gcc_gentoo_patches
526         do_gcc_HTB_patches
527         do_gcc_PIE_patches
528         do_gcc_CYGWINPORTS_patches
529
530         case ${EAPI:-0} in
531                 5*) epatch_user;;
532                 6|7) eapply_user ;;
533                 *) die "Update toolchain_src_prepare() for ${EAPI}." ;;
534         esac
535
536         if ( tc_version_is_at_least 4.8.2 || use_if_iuse hardened ) && ! use vanilla ; then
537                 make_gcc_hard
538         fi
539
540         # install the libstdc++ python into the right location
541         # http://gcc.gnu.org/PR51368
542         if tc_version_is_between 4.5 4.7 ; then
543                 sed -i \
544                         '/^pythondir =/s:=.*:= $(datadir)/python:' \
545                         "${S}"/libstdc++-v3/python/Makefile.in || die
546         fi
547
548         # make sure the pkg config files install into multilib dirs.
549         # since we configure with just one --libdir, we can't use that
550         # (as gcc itself takes care of building multilibs).  #435728
551         find "${S}" -name Makefile.in \
552                 -exec sed -i '/^pkgconfigdir/s:=.*:=$(toolexeclibdir)/pkgconfig:' {} +
553
554         # No idea when this first started being fixed, but let's go with 4.3.x for now
555         if ! tc_version_is_at_least 4.3 ; then
556                 fix_files=""
557                 for x in contrib/test_summary libstdc++-v3/scripts/check_survey.in ; do
558                         [[ -e ${x} ]] && fix_files="${fix_files} ${x}"
559                 done
560                 ht_fix_file ${fix_files} */configure *.sh */Makefile.in
561         fi
562
563         setup_multilib_osdirnames
564         gcc_version_patch
565
566         if tc_version_is_at_least 4.1 ; then
567                 if [[ -n ${SNAPSHOT} || -n ${PRERELEASE} ]] ; then
568                         # BASE-VER must be a three-digit version number
569                         # followed by an optional -pre string
570                         #   eg. 4.5.1, 4.6.2-pre20120213, 4.7.0-pre9999
571                         # If BASE-VER differs from ${PV/_/-} then libraries get installed in
572                         # the wrong directory.
573                         echo ${PV/_/-} > "${S}"/gcc/BASE-VER
574                 fi
575         fi
576
577         # >= gcc-4.3 doesn't bundle ecj.jar, so copy it
578         if tc_version_is_at_least 4.3 && use_if_iuse gcj ; then
579                 if tc_version_is_at_least 4.5 ; then
580                         einfo "Copying ecj-4.5.jar"
581                         cp -pPR "${DISTDIR}/ecj-4.5.jar" "${S}/ecj.jar" || die
582                 else
583                         einfo "Copying ecj-4.3.jar"
584                         cp -pPR "${DISTDIR}/ecj-4.3.jar" "${S}/ecj.jar" || die
585                 fi
586         fi
587
588         # disable --as-needed from being compiled into gcc specs
589         # natively when using a gcc version < 3.4.4
590         # http://gcc.gnu.org/PR14992
591         if ! tc_version_is_at_least 3.4.4 ; then
592                 sed -i -e s/HAVE_LD_AS_NEEDED/USE_LD_AS_NEEDED/g "${S}"/gcc/config.in
593         fi
594
595         # In gcc 3.3.x and 3.4.x, rename the java bins to gcc-specific names
596         # in line with gcc-4.
597         if tc_version_is_between 3.3 4.0 ; then
598                 do_gcc_rename_java_bins
599         fi
600
601         # Prevent libffi from being installed
602         if tc_version_is_between 3.0 4.8 ; then
603                 sed -i -e 's/\(install.*:\) install-.*recursive/\1/' "${S}"/libffi/Makefile.in || die
604                 sed -i -e 's/\(install-data-am:\).*/\1/' "${S}"/libffi/include/Makefile.in || die
605         fi
606
607         # Fixup libtool to correctly generate .la files with portage
608         elibtoolize --portage --shallow --no-uclibc
609
610         gnuconfig_update
611
612         # update configure files
613         local f
614         einfo "Fixing misc issues in configure files"
615         for f in $(grep -l 'autoconf version 2.13' $(find "${S}" -name configure)) ; do
616                 ebegin "  Updating ${f/${S}\/} [LANG]"
617                 patch "${f}" "${FILESDIR}"/gcc-configure-LANG.patch >& "${T}"/configure-patch.log \
618                         || eerror "Please file a bug about this"
619                 eend $?
620         done
621         sed -i 's|A-Za-z0-9|[:alnum:]|g' "${S}"/gcc/*.awk #215828
622
623         # Prevent new texinfo from breaking old versions (see #198182, #464008)
624         if tc_version_is_at_least 4.1; then
625                 tc_apply_patches "Remove texinfo (bug #198182, bug ##464008)" "${FILESDIR}"/gcc-configure-texinfo.patch
626         fi
627
628         if [[ -x contrib/gcc_update ]] ; then
629                 einfo "Touching generated files"
630                 ./contrib/gcc_update --touch | \
631                         while read f ; do
632                                 einfo "  ${f%%...}"
633                         done
634         fi
635 }
636
637 do_gcc_gentoo_patches() {
638         if ! use vanilla ; then
639                 if [[ -n ${PATCH_VER} ]] ; then
640                         tc_apply_patches "Applying Gentoo patches ..." "${WORKDIR}"/patch/*.patch
641                         BRANDING_GCC_PKGVERSION="${BRANDING_GCC_PKGVERSION} p${PATCH_VER}"
642                 fi
643                 if [[ -n ${UCLIBC_VER} ]] ; then
644                         tc_apply_patches "Applying uClibc patches ..." "${WORKDIR}"/uclibc/*.patch
645                 fi
646         fi
647 }
648
649 do_gcc_HTB_patches() {
650         use_if_iuse boundschecking || return 0
651
652         # modify the bounds checking patch with a regression patch
653         tc_apply_patches "Bounds checking patch" "${WORKDIR}/bounds-checking-gcc-${HTB_GCC_VER}-${HTB_VER}.patch"
654         BRANDING_GCC_PKGVERSION="${BRANDING_GCC_PKGVERSION}, HTB-${HTB_GCC_VER}-${HTB_VER}"
655 }
656
657 do_gcc_PIE_patches() {
658         want_pie || return 0
659         use vanilla && return 0
660
661         tc_apply_patches "Applying pie patches ..." "${WORKDIR}"/piepatch/*.patch
662
663         BRANDING_GCC_PKGVERSION="${BRANDING_GCC_PKGVERSION}, pie-${PIE_VER}"
664 }
665
666 do_gcc_CYGWINPORTS_patches() {
667         [[ -n ${CYGWINPORTS_GITREV} ]] || return 0
668         use elibc_Cygwin || return 0
669
670         local p d="${WORKDIR}/gcc-${CYGWINPORTS_GITREV}"
671         # readarray -t is available since bash-4.4 only, #690686
672         local patches=( $(sed -e '1,/PATCH_URI="/d;/"/,$d' < "${d}"/gcc.cygport) )
673         tc_apply_patches "Applying cygwin port patches ..." ${patches[*]}
674 }
675
676 # configure to build with the hardened GCC specs as the default
677 make_gcc_hard() {
678
679         local gcc_hard_flags=""
680
681         # If we use gcc-6 or newer with pie enable to compile older gcc we need to pass -no-pie
682         # to stage1; bug 618908
683         if ! tc_version_is_at_least 6.0 && [[ $(gcc-major-version) -ge 6 ]] ; then
684                 einfo "Disabling PIE in stage1 (only) ..."
685                 sed -i -e "/^STAGE1_LDFLAGS/ s/$/ -no-pie/" "${S}"/Makefile.in || die
686         fi
687
688         # Gcc >= 6.X we can use configurations options to turn pie/ssp on as default
689         if tc_version_is_at_least 6.0 ; then
690                 if use_if_iuse pie ; then
691                         einfo "Updating gcc to use automatic PIE building ..."
692                 fi
693                 if use_if_iuse ssp ; then
694                         einfo "Updating gcc to use automatic SSP building ..."
695                 fi
696                 if use_if_iuse hardened ; then
697                         # Will add some optimatizion as default.
698                         gcc_hard_flags+=" -DEXTRA_OPTIONS"
699                         # rebrand to make bug reports easier
700                         BRANDING_GCC_PKGVERSION=${BRANDING_GCC_PKGVERSION/Gentoo/Gentoo Hardened}
701                 fi
702         else
703                 if use_if_iuse hardened ; then
704                         # rebrand to make bug reports easier
705                         BRANDING_GCC_PKGVERSION=${BRANDING_GCC_PKGVERSION/Gentoo/Gentoo Hardened}
706                         if hardened_gcc_works ; then
707                                 einfo "Updating gcc to use automatic PIE + SSP building ..."
708                                 gcc_hard_flags+=" -DEFAULT_PIE_SSP"
709                         elif hardened_gcc_works pie ; then
710                                 einfo "Updating gcc to use automatic PIE building ..."
711                                 ewarn "SSP has not been enabled by default"
712                                 gcc_hard_flags+=" -DEFAULT_PIE"
713                         elif hardened_gcc_works ssp ; then
714                                 einfo "Updating gcc to use automatic SSP building ..."
715                                 ewarn "PIE has not been enabled by default"
716                                 gcc_hard_flags+=" -DEFAULT_SSP"
717                         else
718                                 # do nothing if hardened isn't supported, but don't die either
719                                 ewarn "hardened is not supported for this arch in this gcc version"
720                                 return 0
721                         fi
722                 else
723                         if hardened_gcc_works ssp ; then
724                                 einfo "Updating gcc to use automatic SSP building ..."
725                                 gcc_hard_flags+=" -DEFAULT_SSP"
726                         fi
727                 fi
728         fi
729
730         # we want to be able to control the pie patch logic via something other
731         # than ALL_CFLAGS...
732         sed -e '/^ALL_CFLAGS/iHARD_CFLAGS = ' \
733                 -e 's|^ALL_CFLAGS = |ALL_CFLAGS = $(HARD_CFLAGS) |' \
734                 -i "${S}"/gcc/Makefile.in
735         # Need to add HARD_CFLAGS to ALL_CXXFLAGS on >= 4.7
736         if tc_version_is_at_least 4.7 ; then
737                 sed -e '/^ALL_CXXFLAGS/iHARD_CFLAGS = ' \
738                         -e 's|^ALL_CXXFLAGS = |ALL_CXXFLAGS = $(HARD_CFLAGS) |' \
739                         -i "${S}"/gcc/Makefile.in
740         fi
741
742         sed -i \
743                 -e "/^HARD_CFLAGS = /s|=|= ${gcc_hard_flags} |" \
744                 "${S}"/gcc/Makefile.in || die
745
746 }
747
748 # This is a historical wart.  The original Gentoo/amd64 port used:
749 #    lib32 - 32bit binaries (x86)
750 #    lib64 - 64bit binaries (x86_64)
751 #    lib   - "native" binaries (a symlink to lib64)
752 # Most other distros use the logic (including mainline gcc):
753 #    lib   - 32bit binaries (x86)
754 #    lib64 - 64bit binaries (x86_64)
755 # Over time, Gentoo is migrating to the latter form.
756 #
757 # Unfortunately, due to distros picking the lib32 behavior, newer gcc
758 # versions will dynamically detect whether to use lib or lib32 for its
759 # 32bit multilib.  So, to keep the automagic from getting things wrong
760 # while people are transitioning from the old style to the new style,
761 # we always set the MULTILIB_OSDIRNAMES var for relevant targets.
762 setup_multilib_osdirnames() {
763         is_multilib || return 0
764
765         local config
766         local libdirs="../lib64 ../lib32"
767
768         # this only makes sense for some Linux targets
769         case ${CTARGET} in
770         x86_64*-linux*)    config="i386" ;;
771         powerpc64*-linux*) config="rs6000" ;;
772         sparc64*-linux*)   config="sparc" ;;
773         s390x*-linux*)     config="s390" ;;
774         *)                     return 0 ;;
775         esac
776         config+="/t-linux64"
777
778         local sed_args=()
779         if tc_version_is_at_least 4.6 ; then
780                 sed_args+=( -e 's:$[(]call if_multiarch[^)]*[)]::g' )
781         fi
782         if [[ ${SYMLINK_LIB} == "yes" ]] ; then
783                 einfo "updating multilib directories to be: ${libdirs}"
784                 if tc_version_is_at_least 4.6.4 || tc_version_is_at_least 4.7 ; then
785                         sed_args+=( -e '/^MULTILIB_OSDIRNAMES.*lib32/s:[$][(]if.*):../lib32:' )
786                 else
787                         sed_args+=( -e "/^MULTILIB_OSDIRNAMES/s:=.*:= ${libdirs}:" )
788                 fi
789         else
790                 einfo "using upstream multilib; disabling lib32 autodetection"
791                 sed_args+=( -r -e 's:[$][(]if.*,(.*)[)]:\1:' )
792         fi
793         sed -i "${sed_args[@]}" "${S}"/gcc/config/${config} || die
794 }
795
796 gcc_version_patch() {
797         # gcc-4.3+ has configure flags (whoo!)
798         tc_version_is_at_least 4.3 && return 0
799
800         local version_string=${GCC_CONFIG_VER}
801
802         einfo "patching gcc version: ${version_string} (${BRANDING_GCC_PKGVERSION})"
803
804         local gcc_sed=( -e 's:gcc\.gnu\.org/bugs\.html:bugs\.gentoo\.org/:' )
805         if grep -qs VERSUFFIX "${S}"/gcc/version.c ; then
806                 gcc_sed+=( -e "/VERSUFFIX \"\"/s:\"\":\" (${BRANDING_GCC_PKGVERSION})\":" )
807         else
808                 version_string="${version_string} (${BRANDING_GCC_PKGVERSION})"
809                 gcc_sed+=( -e "/const char version_string\[\] = /s:= \".*\":= \"${version_string}\":" )
810         fi
811         sed -i "${gcc_sed[@]}" "${S}"/gcc/version.c || die
812 }
813
814 do_gcc_rename_java_bins() {
815         # bug #139918 - conflict between gcc and java-config-2 for ownership of
816         # /usr/bin/rmi{c,registry}.      Done with mv & sed rather than a patch
817         # because patches would be large (thanks to the rename of man files),
818         # and it's clear from the sed invocations that all that changes is the
819         # rmi{c,registry} names to grmi{c,registry} names.
820         # Kevin F. Quinn 2006-07-12
821         einfo "Renaming jdk executables rmic and rmiregistry to grmic and grmiregistry."
822         # 1) Move the man files if present (missing prior to gcc-3.4)
823         for manfile in rmic rmiregistry ; do
824                 [[ -f ${S}/gcc/doc/${manfile}.1 ]] || continue
825                 mv "${S}"/gcc/doc/${manfile}.1 "${S}"/gcc/doc/g${manfile}.1
826         done
827         # 2) Fixup references in the docs if present (mission prior to gcc-3.4)
828         for jfile in gcc/doc/gcj.info gcc/doc/grmic.1 gcc/doc/grmiregistry.1 gcc/java/gcj.texi ; do
829                 [[ -f ${S}/${jfile} ]] || continue
830                 sed -i -e 's:rmiregistry:grmiregistry:g' "${S}"/${jfile} ||
831                         die "Failed to fixup file ${jfile} for rename to grmiregistry"
832                 sed -i -e 's:rmic:grmic:g' "${S}"/${jfile} ||
833                         die "Failed to fixup file ${jfile} for rename to grmic"
834         done
835         # 3) Fixup Makefiles to build the changed executable names
836         #        These are present in all 3.x versions, and are the important bit
837         #        to get gcc to build with the new names.
838         for jfile in libjava/Makefile.am libjava/Makefile.in gcc/java/Make-lang.in ; do
839                 sed -i -e 's:rmiregistry:grmiregistry:g' "${S}"/${jfile} ||
840                         die "Failed to fixup file ${jfile} for rename to grmiregistry"
841                 # Careful with rmic on these files; it's also the name of a directory
842                 # which should be left unchanged.  Replace occurrences of 'rmic$',
843                 # 'rmic_' and 'rmic '.
844                 sed -i -e 's:rmic\([$_ ]\):grmic\1:g' "${S}"/${jfile} ||
845                         die "Failed to fixup file ${jfile} for rename to grmic"
846         done
847 }
848
849 #---->> src_configure <<----
850
851 toolchain_src_configure() {
852         downgrade_arch_flags
853         gcc_do_filter_flags
854
855         einfo "CFLAGS=\"${CFLAGS}\""
856         einfo "CXXFLAGS=\"${CXXFLAGS}\""
857         einfo "LDFLAGS=\"${LDFLAGS}\""
858
859         # Force internal zip based jar script to avoid random
860         # issues with 3rd party jar implementations.  #384291
861         export JAR=no
862
863         # For hardened gcc 4.3 piepatchset to build the hardened specs
864         # file (build.specs) to use when building gcc.
865         if ! tc_version_is_at_least 4.4 && want_minispecs ; then
866                 setup_minispecs_gcc_build_specs
867         fi
868
869         local confgcc=( --host=${CHOST} )
870
871         if is_crosscompile || tc-is-cross-compiler ; then
872                 # Straight from the GCC install doc:
873                 # "GCC has code to correctly determine the correct value for target
874                 # for nearly all native systems. Therefore, we highly recommend you
875                 # not provide a configure target when configuring a native compiler."
876                 confgcc+=( --target=${CTARGET} )
877         fi
878         [[ -n ${CBUILD} ]] && confgcc+=( --build=${CBUILD} )
879
880         confgcc+=(
881                 --prefix="${PREFIX}"
882                 --bindir="${BINPATH}"
883                 --includedir="${INCLUDEPATH}"
884                 --datadir="${DATAPATH}"
885                 --mandir="${DATAPATH}/man"
886                 --infodir="${DATAPATH}/info"
887                 --with-gxx-include-dir="${STDCXX_INCDIR}"
888         )
889
890         # Stick the python scripts in their own slotted directory (bug #279252)
891         #
892         #  --with-python-dir=DIR
893         #  Specifies where to install the Python modules used for aot-compile. DIR
894         #  should not include the prefix used in installation. For example, if the
895         #  Python modules are to be installed in /usr/lib/python2.5/site-packages,
896         #  then --with-python-dir=/lib/python2.5/site-packages should be passed.
897         #
898         # This should translate into "/share/gcc-data/${CTARGET}/${GCC_CONFIG_VER}/python"
899         if tc_version_is_at_least 4.4 ; then
900                 confgcc+=( --with-python-dir=${DATAPATH/$PREFIX/}/python )
901         fi
902
903         ### language options
904
905         local GCC_LANG="c"
906         is_cxx && GCC_LANG+=",c++"
907         is_d   && GCC_LANG+=",d"
908         is_gcj && GCC_LANG+=",java"
909         is_go  && GCC_LANG+=",go"
910         is_jit && GCC_LANG+=",jit"
911         if is_objc || is_objcxx ; then
912                 GCC_LANG+=",objc"
913                 if tc_version_is_at_least 4 ; then
914                         use objc-gc && confgcc+=( --enable-objc-gc )
915                 fi
916                 is_objcxx && GCC_LANG+=",obj-c++"
917         fi
918
919         # fortran support just got sillier! the lang value can be f77 for
920         # fortran77, f95 for fortran95, or just plain old fortran for the
921         # currently supported standard depending on gcc version.
922         is_fortran && GCC_LANG+=",fortran"
923         is_f77 && GCC_LANG+=",f77"
924         is_f95 && GCC_LANG+=",f95"
925
926         # We do NOT want 'ADA support' in here!
927         # is_ada && GCC_LANG+=",ada"
928
929         confgcc+=( --enable-languages=${GCC_LANG} )
930
931         ### general options
932
933         confgcc+=(
934                 --enable-obsolete
935                 --enable-secureplt
936                 --disable-werror
937                 --with-system-zlib
938         )
939
940         if use nls ; then
941                 confgcc+=( --enable-nls --without-included-gettext )
942         else
943                 confgcc+=( --disable-nls )
944         fi
945
946         tc_version_is_at_least 3.4 || confgcc+=( --disable-libunwind-exceptions )
947
948         # Use the default ("release") checking because upstream usually neglects
949         # to test "disabled" so it has a history of breaking. #317217
950         if tc_version_is_at_least 3.4 && in_iuse debug ; then
951                 # The "release" keyword is new to 4.0. #551636
952                 local off=$(tc_version_is_at_least 4.0 && echo release || echo no)
953                 confgcc+=( --enable-checking="${GCC_CHECKS_LIST:-$(usex debug yes ${off})}" )
954         fi
955
956         # Branding
957         tc_version_is_at_least 4.3 && confgcc+=(
958                 --with-bugurl=https://bugs.gentoo.org/
959                 --with-pkgversion="${BRANDING_GCC_PKGVERSION}"
960         )
961
962         # If we want hardened support with the newer piepatchset for >=gcc 4.4
963         if tc_version_is_at_least 4.4 && want_minispecs && in_iuse hardened ; then
964                 confgcc+=( $(use_enable hardened esp) )
965         fi
966
967         # allow gcc to search for clock funcs in the main C lib.
968         # if it can't find them, then tough cookies -- we aren't
969         # going to link in -lrt to all C++ apps.  #411681
970         if tc_version_is_at_least 4.4 && is_cxx ; then
971                 confgcc+=( --enable-libstdcxx-time )
972         fi
973
974         # Build compiler using LTO
975         if tc_version_is_at_least 9.1 && use_if_iuse lto ; then
976                 confgcc+=( --with-build-config=bootstrap-lto )
977         fi
978
979         # Support to disable pch when building libstdcxx
980         if tc_version_is_at_least 6.0 && ! use_if_iuse pch ; then
981                 confgcc+=( --disable-libstdcxx-pch )
982         fi
983
984         # The jit language requires this.
985         is_jit && confgcc+=( --enable-host-shared )
986
987         # # Turn on the -Wl,--build-id flag by default for ELF targets. #525942
988         # # This helps with locating debug files.
989         # case ${CTARGET} in
990         # *-linux-*|*-elf|*-eabi)
991         #       tc_version_is_at_least 4.5 && confgcc+=(
992         #               --enable-linker-build-id
993         #       )
994         #       ;;
995         # esac
996
997         # newer gcc versions like to bootstrap themselves with C++,
998         # so we need to manually disable it ourselves
999         if tc_version_is_between 4.7 4.8 && ! is_cxx ; then
1000                 confgcc+=( --disable-build-with-cxx --disable-build-poststage1-with-cxx )
1001         fi
1002
1003         ### Cross-compiler options
1004         if is_crosscompile ; then
1005                 # Enable build warnings by default with cross-compilers when system
1006                 # paths are included (e.g. via -I flags).
1007                 confgcc+=( --enable-poison-system-directories )
1008
1009                 # When building a stage1 cross-compiler (just C compiler), we have to
1010                 # disable a bunch of features or gcc goes boom
1011                 local needed_libc=""
1012                 case ${CTARGET} in
1013                 *-linux)                 needed_libc=no-fucking-clue;;
1014                 *-dietlibc)              needed_libc=dietlibc;;
1015                 *-elf|*-eabi)
1016                         needed_libc=newlib
1017                         # Bare-metal targets don't have access to clock_gettime()
1018                         # arm-none-eabi example: bug #589672
1019                         # But we explicitly do --enable-libstdcxx-time above.
1020                         # Undoing it here.
1021                         confgcc+=( --disable-libstdcxx-time )
1022                         ;;
1023                 *-freebsd*)              needed_libc=freebsd-lib;;
1024                 *-gnu*)                  needed_libc=glibc;;
1025                 *-klibc)                 needed_libc=klibc;;
1026                 *-musl*)                 needed_libc=musl;;
1027                 *-uclibc*)
1028                         if ! echo '#include <features.h>' | \
1029                            $(tc-getCPP ${CTARGET}) -E -dD - 2>/dev/null | \
1030                            grep -q __HAVE_SHARED__
1031                         then #291870
1032                                 confgcc+=( --disable-shared )
1033                         fi
1034                         needed_libc=uclibc-ng
1035                         ;;
1036                 *-cygwin)                needed_libc=cygwin;;
1037                 x86_64-*-mingw*|\
1038                 *-w64-mingw*)    needed_libc=mingw64-runtime;;
1039                 mingw*|*-mingw*) needed_libc=mingw-runtime;;
1040                 avr)                     confgcc+=( --enable-shared --disable-threads );;
1041                 esac
1042                 if [[ -n ${needed_libc} ]] ; then
1043                         local confgcc_no_libc=( --disable-shared )
1044                         tc_version_is_at_least 4.8 && confgcc_no_libc+=( --disable-libatomic )
1045                         if ! has_version ${CATEGORY}/${needed_libc} ; then
1046                                 confgcc+=(
1047                                         "${confgcc_no_libc[@]}"
1048                                         --disable-threads
1049                                         --without-headers
1050                                 )
1051                         elif has_version "${CATEGORY}/${needed_libc}[headers-only(-)]" ; then
1052                                 confgcc+=(
1053                                         "${confgcc_no_libc[@]}"
1054                                         --with-sysroot="${PREFIX}"/${CTARGET}
1055                                 )
1056                         else
1057                                 confgcc+=( --with-sysroot="${PREFIX}"/${CTARGET} )
1058                         fi
1059                 fi
1060
1061                 tc_version_is_at_least 4.2 && confgcc+=( --disable-bootstrap )
1062         else
1063                 if tc-is-static-only ; then
1064                         confgcc+=( --disable-shared )
1065                 else
1066                         confgcc+=( --enable-shared )
1067                 fi
1068                 case ${CHOST} in
1069                 mingw*|*-mingw*)
1070                         confgcc+=( --enable-threads=win32 ) ;;
1071                 *)
1072                         confgcc+=( --enable-threads=posix ) ;;
1073                 esac
1074         fi
1075
1076         # __cxa_atexit is "essential for fully standards-compliant handling of
1077         # destructors", but apparently requires glibc.
1078         case ${CTARGET} in
1079         *-uclibc*)
1080                 if tc_has_feature nptl ; then
1081                         confgcc+=(
1082                                 --disable-__cxa_atexit
1083                                 $(use_enable nptl tls)
1084                         )
1085                 fi
1086                 tc_version_is_between 3.3 3.4 && confgcc+=( --enable-sjlj-exceptions )
1087                 if tc_version_is_between 3.4 4.3 ; then
1088                         confgcc+=( --enable-clocale=uclibc )
1089                 fi
1090                 ;;
1091         *-elf|*-eabi)
1092                 confgcc+=( --with-newlib )
1093                 ;;
1094         *-musl*)
1095                 confgcc+=( --enable-__cxa_atexit )
1096                 ;;
1097         *-gnu*)
1098                 confgcc+=(
1099                         --enable-__cxa_atexit
1100                         --enable-clocale=gnu
1101                 )
1102                 ;;
1103         *-freebsd*)
1104                 confgcc+=( --enable-__cxa_atexit )
1105                 ;;
1106         *-solaris*)
1107                 confgcc+=( --enable-__cxa_atexit )
1108                 ;;
1109         esac
1110
1111         ### arch options
1112
1113         gcc-multilib-configure
1114
1115         # ppc altivec support
1116         in_iuse altivec && confgcc+=( $(use_enable altivec) )
1117
1118         # gcc has fixed-point arithmetic support in 4.3 for mips targets that can
1119         # significantly increase compile time by several hours.  This will allow
1120         # users to control this feature in the event they need the support.
1121         tc_version_is_at_least 4.3 && in_iuse fixed-point && confgcc+=( $(use_enable fixed-point) )
1122
1123         case $(tc-is-softfloat) in
1124         yes)    confgcc+=( --with-float=soft ) ;;
1125         softfp) confgcc+=( --with-float=softfp ) ;;
1126         *)
1127                 # If they've explicitly opt-ed in, do hardfloat,
1128                 # otherwise let the gcc default kick in.
1129                 case ${CTARGET//_/-} in
1130                 *-hardfloat-*|*eabihf) confgcc+=( --with-float=hard ) ;;
1131                 esac
1132         esac
1133
1134         local with_abi_map=()
1135         case $(tc-arch) in
1136         arm)    #264534 #414395
1137                 local a arm_arch=${CTARGET%%-*}
1138                 # Remove trailing endian variations first: eb el be bl b l
1139                 for a in e{b,l} {b,l}e b l ; do
1140                         if [[ ${arm_arch} == *${a} ]] ; then
1141                                 arm_arch=${arm_arch%${a}}
1142                                 break
1143                         fi
1144                 done
1145                 # Convert armv7{a,r,m} to armv7-{a,r,m}
1146                 [[ ${arm_arch} == armv7? ]] && arm_arch=${arm_arch/7/7-}
1147                 # See if this is a valid --with-arch flag
1148                 if (srcdir=${S}/gcc target=${CTARGET} with_arch=${arm_arch};
1149                     . "${srcdir}"/config.gcc) &>/dev/null
1150                 then
1151                         confgcc+=( --with-arch=${arm_arch} )
1152                 fi
1153
1154                 # Make default mode thumb for microcontroller classes #418209
1155                 [[ ${arm_arch} == *-m ]] && confgcc+=( --with-mode=thumb )
1156
1157                 # Enable hardvfp
1158                 if [[ $(tc-is-softfloat) == "no" ]] && \
1159                    [[ ${CTARGET} == armv[67]* ]] && \
1160                    tc_version_is_at_least 4.5
1161                 then
1162                         # Follow the new arm hardfp distro standard by default
1163                         confgcc+=( --with-float=hard )
1164                         case ${CTARGET} in
1165                         armv6*) confgcc+=( --with-fpu=vfp ) ;;
1166                         armv7*) confgcc+=( --with-fpu=vfpv3-d16 ) ;;
1167                         esac
1168                 fi
1169                 ;;
1170         mips)
1171                 # Add --with-abi flags to set default ABI
1172                 confgcc+=( --with-abi=$(gcc-abi-map ${TARGET_DEFAULT_ABI}) )
1173                 ;;
1174         amd64)
1175                 # drop the older/ABI checks once this get's merged into some
1176                 # version of gcc upstream
1177                 if tc_version_is_at_least 4.8 && has x32 $(get_all_abis TARGET) ; then
1178                         confgcc+=( --with-abi=$(gcc-abi-map ${TARGET_DEFAULT_ABI}) )
1179                 fi
1180                 ;;
1181         x86)
1182                 # Default arch for x86 is normally i386, lets give it a bump
1183                 # since glibc will do so based on CTARGET anyways
1184                 confgcc+=( --with-arch=${CTARGET%%-*} )
1185                 ;;
1186         hppa)
1187                 # Enable sjlj exceptions for backward compatibility on hppa
1188                 [[ ${GCCMAJOR} == "3" ]] && confgcc+=( --enable-sjlj-exceptions )
1189                 ;;
1190         ppc)
1191                 # Set up defaults based on current CFLAGS
1192                 is-flagq -mfloat-gprs=double && confgcc+=( --enable-e500-double )
1193                 [[ ${CTARGET//_/-} == *-e500v2-* ]] && confgcc+=( --enable-e500-double )
1194                 ;;
1195         riscv)
1196                 # Add --with-abi flags to set default ABI
1197                 confgcc+=( --with-abi=$(gcc-abi-map ${TARGET_DEFAULT_ABI}) )
1198                 ;;
1199         esac
1200
1201         # if the target can do biarch (-m32/-m64), enable it.  overhead should
1202         # be small, and should simplify building of 64bit kernels in a 32bit
1203         # userland by not needing sys-devel/kgcc64.  #349405
1204         case $(tc-arch) in
1205         ppc|ppc64) tc_version_is_at_least 3.4 && confgcc+=( --enable-targets=all ) ;;
1206         sparc)     tc_version_is_at_least 4.4 && confgcc+=( --enable-targets=all ) ;;
1207         amd64|x86) tc_version_is_at_least 4.3 && confgcc+=( --enable-targets=all ) ;;
1208         esac
1209
1210         # On Darwin we need libdir to be set in order to get correct install names
1211         # for things like libobjc-gnu, libgcj and libfortran.  If we enable it on
1212         # non-Darwin we screw up the behaviour this eclass relies on.  We in
1213         # particular need this over --libdir for bug #255315.
1214         [[ ${CTARGET} == *-darwin* ]] && \
1215                 confgcc+=( --enable-version-specific-runtime-libs )
1216
1217         ### library options
1218
1219         if tc_version_is_between 3.0 7.0 ; then
1220                 if is_gcj ; then
1221                         confgcc+=( --disable-gjdoc )
1222                         use awt && confgcc+=( --enable-java-awt=gtk )
1223                 else
1224                         confgcc+=( --disable-libgcj )
1225                 fi
1226         fi
1227
1228         if tc_version_is_at_least 4.2 ; then
1229                 if in_iuse openmp ; then
1230                         # Make sure target has pthreads support. #326757 #335883
1231                         # There shouldn't be a chicken & egg problem here as openmp won't
1232                         # build without a C library, and you can't build that w/out
1233                         # already having a compiler ...
1234                         if ! is_crosscompile || \
1235                            $(tc-getCPP ${CTARGET}) -E - <<<"#include <pthread.h>" >& /dev/null
1236                         then
1237                                 confgcc+=( $(use_enable openmp libgomp) )
1238                         else
1239                                 # Force disable as the configure script can be dumb #359855
1240                                 confgcc+=( --disable-libgomp )
1241                         fi
1242                 else
1243                         # For gcc variants where we don't want openmp (e.g. kgcc)
1244                         confgcc+=( --disable-libgomp )
1245                 fi
1246         fi
1247
1248         if tc_version_is_at_least 4.0 ; then
1249                 if in_iuse mudflap ; then
1250                         confgcc+=( $(use_enable mudflap libmudflap) )
1251                 else
1252                         confgcc+=( --disable-libmudflap )
1253                 fi
1254
1255                 if use_if_iuse libssp ; then
1256                         confgcc+=( --enable-libssp )
1257                 else
1258                         if hardened_gcc_is_stable ssp; then
1259                                 export gcc_cv_libc_provides_ssp=yes
1260                         fi
1261                         if use_if_iuse ssp; then
1262                                 # On some targets USE="ssp -libssp" is an invalid
1263                                 # configuration as target libc does not provide
1264                                 # stack_chk_* functions. Do not disable libssp there.
1265                                 case ${CTARGET} in
1266                                         mingw*|*-mingw*) ewarn "Not disabling libssp" ;;
1267                                         *) confgcc+=( --disable-libssp ) ;;
1268                                 esac
1269                         else
1270                                 confgcc+=( --disable-libssp )
1271                         fi
1272                 fi
1273         fi
1274
1275         if in_iuse cilk ; then
1276                 confgcc+=( $(use_enable cilk libcilkrts) )
1277         fi
1278
1279         if in_iuse mpx ; then
1280                 confgcc+=( $(use_enable mpx libmpx) )
1281         fi
1282
1283         if in_iuse systemtap ; then
1284                 confgcc+=( $(use_enable systemtap) )
1285         fi
1286
1287         if in_iuse vtv ; then
1288                 confgcc+=(
1289                         $(use_enable vtv vtable-verify)
1290                         # See Note [implicitly enabled flags]
1291                         $(usex vtv '' --disable-libvtv)
1292                 )
1293         fi
1294
1295         # newer gcc's come with libquadmath, but only fortran uses
1296         # it, so auto punt it when we don't care
1297         if tc_version_is_at_least 4.6 && ! is_fortran ; then
1298                 confgcc+=( --disable-libquadmath )
1299         fi
1300
1301         if tc_version_is_at_least 4.6 ; then
1302                 confgcc+=( --enable-lto )
1303         elif tc_version_is_at_least 4.5 ; then
1304                 confgcc+=( --disable-lto )
1305         fi
1306
1307         # graphite was added in 4.4 but we only support it in 4.8+ due to external
1308         # library issues.  #448024
1309         if tc_version_is_at_least 5.0 && in_iuse graphite ; then
1310                 confgcc+=( $(use_with graphite isl) )
1311                 use graphite && confgcc+=( --disable-isl-version-check )
1312         elif tc_version_is_at_least 4.8 && in_iuse graphite ; then
1313                 confgcc+=( $(use_with graphite cloog) )
1314                 use graphite && confgcc+=( --disable-isl-version-check )
1315         elif tc_version_is_at_least 4.4 ; then
1316                 confgcc+=( --without-{cloog,ppl} )
1317         fi
1318
1319         if tc_version_is_at_least 4.8 && in_iuse sanitize ; then
1320                 # See Note [implicitly enabled flags]
1321                 confgcc+=( $(usex sanitize '' --disable-libsanitizer) )
1322         fi
1323
1324         if tc_version_is_at_least 6.0 && in_iuse pie ; then
1325                 confgcc+=( $(use_enable pie default-pie) )
1326         fi
1327
1328         if tc_version_is_at_least 6.0 && in_iuse ssp ; then
1329                 confgcc+=(
1330                         # This defaults to -fstack-protector-strong.
1331                         $(use_enable ssp default-ssp)
1332                 )
1333         fi
1334
1335         # Disable gcc info regeneration -- it ships with generated info pages
1336         # already.  Our custom version/urls/etc... trigger it.  #464008
1337         export gcc_cv_prog_makeinfo_modern=no
1338
1339         # Do not let the X detection get in our way.  We know things can be found
1340         # via system paths, so no need to hardcode things that'll break multilib.
1341         # Older gcc versions will detect ac_x_libraries=/usr/lib64 which ends up
1342         # killing the 32bit builds which want /usr/lib.
1343         export ac_cv_have_x='have_x=yes ac_x_includes= ac_x_libraries='
1344
1345         confgcc+=( "$@" ${EXTRA_ECONF} )
1346
1347         # Nothing wrong with a good dose of verbosity
1348         echo
1349         einfo "PREFIX:          ${PREFIX}"
1350         einfo "BINPATH:         ${BINPATH}"
1351         einfo "LIBPATH:         ${LIBPATH}"
1352         einfo "DATAPATH:        ${DATAPATH}"
1353         einfo "STDCXX_INCDIR:   ${STDCXX_INCDIR}"
1354         echo
1355         einfo "Languages:       ${GCC_LANG}"
1356         echo
1357         einfo "Configuring GCC with: ${confgcc[@]//--/\n\t--}"
1358         echo
1359
1360         # Build in a separate build tree
1361         mkdir -p "${WORKDIR}"/build
1362         pushd "${WORKDIR}"/build > /dev/null
1363
1364         # and now to do the actual configuration
1365         addwrite /dev/zero
1366         echo "${S}"/configure "${confgcc[@]}"
1367         # Older gcc versions did not detect bash and re-exec itself, so force the
1368         # use of bash.  Newer ones will auto-detect, but this is not harmful.
1369         CONFIG_SHELL="${EPREFIX}/bin/bash" \
1370         bash "${S}"/configure "${confgcc[@]}" || die "failed to run configure"
1371
1372         # return to whatever directory we were in before
1373         popd > /dev/null
1374 }
1375
1376 # Replace -m flags unsupported by the version being built with the best
1377 # available equivalent
1378 downgrade_arch_flags() {
1379         local arch bver i isa myarch mytune rep ver
1380
1381         bver=${1:-${GCC_BRANCH_VER}}
1382         [[ $(gcc-version) < ${bver} ]] && return 0
1383         [[ $(tc-arch) != amd64 && $(tc-arch) != x86 ]] && return 0
1384
1385         myarch=$(get-flag march)
1386         mytune=$(get-flag mtune)
1387
1388         # If -march=native isn't supported we have to tease out the actual arch
1389         if [[ ${myarch} == native || ${mytune} == native ]] ; then
1390                 if [[ ${bver} < 4.2 ]] ; then
1391                         arch=$($(tc-getCC) -march=native -v -E -P - </dev/null 2>&1 \
1392                                 | sed -rn "/cc1.*-march/s:.*-march=([^ ']*).*:\1:p")
1393                         replace-cpu-flags native ${arch}
1394                 fi
1395         fi
1396
1397         # Handle special -mtune flags
1398         [[ ${mytune} == intel && ${bver} < 4.9 ]] && replace-cpu-flags intel generic
1399         [[ ${mytune} == generic && ${bver} < 4.2 ]] && filter-flags '-mtune=*'
1400         [[ ${mytune} == x86-64 ]] && filter-flags '-mtune=*'
1401         [[ ${bver} < 3.4 ]] && filter-flags '-mtune=*'
1402
1403         # "added" "arch" "replacement"
1404         local archlist=(
1405                 4.9 bdver4 bdver3
1406                 4.9 bonnell atom
1407                 4.9 broadwell core-avx2
1408                 4.9 haswell core-avx2
1409                 4.9 ivybridge core-avx-i
1410                 4.9 nehalem corei7
1411                 4.9 sandybridge corei7-avx
1412                 4.9 silvermont corei7
1413                 4.9 westmere corei7
1414                 4.8 bdver3 bdver2
1415                 4.8 btver2 btver1
1416                 4.7 bdver2 bdver1
1417                 4.7 core-avx2 core-avx-i
1418                 4.6 bdver1 amdfam10
1419                 4.6 btver1 amdfam10
1420                 4.6 core-avx-i core2
1421                 4.6 corei7 core2
1422                 4.6 corei7-avx core2
1423                 4.5 atom core2
1424                 4.3 amdfam10 k8
1425                 4.3 athlon64-sse3 k8
1426                 4.3 barcelona k8
1427                 4.3 core2 nocona
1428                 4.3 geode k6-2 # gcc.gnu.org/PR41989#c22
1429                 4.3 k8-sse3 k8
1430                 4.3 opteron-sse3 k8
1431                 3.4 athlon-fx x86-64
1432                 3.4 athlon64 x86-64
1433                 3.4 c3-2 c3
1434                 3.4 k8 x86-64
1435                 3.4 opteron x86-64
1436                 3.4 pentium-m pentium3
1437                 3.4 pentium3m pentium3
1438                 3.4 pentium4m pentium4
1439         )
1440
1441         for ((i = 0; i < ${#archlist[@]}; i += 3)) ; do
1442                 myarch=$(get-flag march)
1443                 mytune=$(get-flag mtune)
1444
1445                 ver=${archlist[i]}
1446                 arch=${archlist[i + 1]}
1447                 rep=${archlist[i + 2]}
1448
1449                 [[ ${myarch} != ${arch} && ${mytune} != ${arch} ]] && continue
1450
1451                 if [[ ${ver} > ${bver} ]] ; then
1452                         einfo "Replacing ${myarch} (added in gcc ${ver}) with ${rep}..."
1453                         [[ ${myarch} == ${arch} ]] && replace-cpu-flags ${myarch} ${rep}
1454                         [[ ${mytune} == ${arch} ]] && replace-cpu-flags ${mytune} ${rep}
1455                         continue
1456                 else
1457                         break
1458                 fi
1459         done
1460
1461         # we only check -mno* here since -m* get removed by strip-flags later on
1462         local isalist=(
1463                 4.9 -mno-sha
1464                 4.9 -mno-avx512pf
1465                 4.9 -mno-avx512f
1466                 4.9 -mno-avx512er
1467                 4.9 -mno-avx512cd
1468                 4.8 -mno-xsaveopt
1469                 4.8 -mno-xsave
1470                 4.8 -mno-rtm
1471                 4.8 -mno-fxsr
1472                 4.7 -mno-lzcnt
1473                 4.7 -mno-bmi2
1474                 4.7 -mno-avx2
1475                 4.6 -mno-tbm
1476                 4.6 -mno-rdrnd
1477                 4.6 -mno-fsgsbase
1478                 4.6 -mno-f16c
1479                 4.6 -mno-bmi
1480                 4.5 -mno-xop
1481                 4.5 -mno-movbe
1482                 4.5 -mno-lwp
1483                 4.5 -mno-fma4
1484                 4.4 -mno-pclmul
1485                 4.4 -mno-fma
1486                 4.4 -mno-avx
1487                 4.4 -mno-aes
1488                 4.3 -mno-ssse3
1489                 4.3 -mno-sse4a
1490                 4.3 -mno-sse4
1491                 4.3 -mno-sse4.2
1492                 4.3 -mno-sse4.1
1493                 4.3 -mno-popcnt
1494                 4.3 -mno-abm
1495         )
1496
1497         for ((i = 0; i < ${#isalist[@]}; i += 2)) ; do
1498                 ver=${isalist[i]}
1499                 isa=${isalist[i + 1]}
1500                 [[ ${ver} > ${bver} ]] && filter-flags ${isa} ${isa/-m/-mno-}
1501         done
1502 }
1503
1504 gcc_do_filter_flags() {
1505         strip-flags
1506         replace-flags -O? -O2
1507
1508         # dont want to funk ourselves
1509         filter-flags '-mabi*' -m31 -m32 -m64
1510
1511         filter-flags -frecord-gcc-switches # 490738
1512         filter-flags -mno-rtm -mno-htm # 506202
1513
1514         if tc_version_is_between 3.2 3.4 ; then
1515                 # XXX: this is so outdated it's barely useful, but it don't hurt...
1516                 replace-cpu-flags G3 750
1517                 replace-cpu-flags G4 7400
1518                 replace-cpu-flags G5 7400
1519
1520                 # XXX: should add a sed or something to query all supported flags
1521                 #      from the gcc source and trim everything else ...
1522                 filter-flags -f{no-,}unit-at-a-time -f{no-,}web -mno-tls-direct-seg-refs
1523                 filter-flags -f{no-,}stack-protector{,-all}
1524                 filter-flags -fvisibility-inlines-hidden -fvisibility=hidden
1525                 # and warning options
1526                 filter-flags -Wextra -Wstack-protector
1527         fi
1528         if ! tc_version_is_at_least 4.1 ; then
1529                 filter-flags -fdiagnostics-show-option
1530                 filter-flags -Wstack-protector
1531         fi
1532
1533         if tc_version_is_at_least 3.4 ; then
1534                 case $(tc-arch) in
1535                         amd64|x86)
1536                                 filter-flags '-mcpu=*'
1537
1538                                 tc_version_is_between 4.4 4.5 && append-flags -mno-avx # 357287
1539
1540                                 if tc_version_is_between 4.6 4.7 ; then
1541                                         # https://bugs.gentoo.org/411333
1542                                         # https://bugs.gentoo.org/466454
1543                                         replace-cpu-flags c3-2 pentium2 pentium3 pentium3m pentium-m i686
1544                                 fi
1545                                 ;;
1546                         alpha)
1547                                 # https://bugs.gentoo.org/454426
1548                                 append-ldflags -Wl,--no-relax
1549                                 ;;
1550                         sparc)
1551                                 # temporary workaround for random ICEs reproduced by multiple users
1552                                 # https://bugs.gentoo.org/457062
1553                                 tc_version_is_between 4.6 4.8 && MAKEOPTS+=" -j1"
1554                                 ;;
1555                         *-macos)
1556                                 # http://gcc.gnu.org/PR25127
1557                                 tc_version_is_between 4.0 4.2 && \
1558                                         filter-flags '-mcpu=*' '-march=*' '-mtune=*'
1559                                 ;;
1560                 esac
1561         fi
1562
1563         strip-unsupported-flags
1564
1565         # these are set here so we have something sane at configure time
1566         if is_crosscompile ; then
1567                 # Set this to something sane for both native and target
1568                 CFLAGS="-O2 -pipe"
1569                 FFLAGS=${CFLAGS}
1570                 FCFLAGS=${CFLAGS}
1571
1572                 # "hppa2.0-unknown-linux-gnu" -> hppa2_0_unknown_linux_gnu
1573                 local VAR="CFLAGS_"${CTARGET//[-.]/_}
1574                 CXXFLAGS=${!VAR-${CFLAGS}}
1575         fi
1576
1577         export GCJFLAGS=${GCJFLAGS:-${CFLAGS}}
1578 }
1579
1580 setup_minispecs_gcc_build_specs() {
1581         # Setup the "build.specs" file for gcc 4.3 to use when building.
1582         if hardened_gcc_works pie ; then
1583                 cat "${WORKDIR}"/specs/pie.specs >> "${WORKDIR}"/build.specs
1584         fi
1585         if hardened_gcc_works ssp ; then
1586                 for s in ssp sspall ; do
1587                         cat "${WORKDIR}"/specs/${s}.specs >> "${WORKDIR}"/build.specs
1588                 done
1589         fi
1590         for s in nostrict znow ; do
1591                 cat "${WORKDIR}"/specs/${s}.specs >> "${WORKDIR}"/build.specs
1592         done
1593         export GCC_SPECS="${WORKDIR}"/build.specs
1594 }
1595
1596 gcc-multilib-configure() {
1597         if ! is_multilib ; then
1598                 confgcc+=( --disable-multilib )
1599                 # Fun times: if we are building for a target that has multiple
1600                 # possible ABI formats, and the user has told us to pick one
1601                 # that isn't the default, then not specifying it via the list
1602                 # below will break that on us.
1603         else
1604                 confgcc+=( --enable-multilib )
1605         fi
1606
1607         # translate our notion of multilibs into gcc's
1608         local abi list
1609         for abi in $(get_all_abis TARGET) ; do
1610                 local l=$(gcc-abi-map ${abi})
1611                 [[ -n ${l} ]] && list+=",${l}"
1612         done
1613         if [[ -n ${list} ]] ; then
1614                 case ${CTARGET} in
1615                 x86_64*)
1616                         tc_version_is_at_least 4.8 && confgcc+=( --with-multilib-list=${list:1} )
1617                         ;;
1618                 esac
1619         fi
1620 }
1621
1622 gcc-abi-map() {
1623         # Convert the ABI name we use in Gentoo to what gcc uses
1624         local map=()
1625         case ${CTARGET} in
1626         mips*)   map=("o32 32" "n32 n32" "n64 64") ;;
1627         riscv*)  map=("lp64d lp64d" "lp64 lp64") ;;
1628         x86_64*) map=("amd64 m64" "x86 m32" "x32 mx32") ;;
1629         esac
1630
1631         local m
1632         for m in "${map[@]}" ; do
1633                 l=( ${m} )
1634                 [[ $1 == ${l[0]} ]] && echo ${l[1]} && break
1635         done
1636 }
1637
1638 #----> src_compile <----
1639
1640 toolchain_src_compile() {
1641         touch "${S}"/gcc/c-gperf.h
1642
1643         # Do not make manpages if we do not have perl ...
1644         [[ ! -x /usr/bin/perl ]] \
1645                 && find "${WORKDIR}"/build -name '*.[17]' -exec touch {} +
1646
1647         # Older gcc versions did not detect bash and re-exec itself, so force the
1648         # use of bash.  Newer ones will auto-detect, but this is not harmful.
1649         # This needs to be set for compile as well, as it's used in libtool
1650         # generation, which will break install otherwise (at least in 3.3.6): #664486
1651         CONFIG_SHELL="${EPREFIX}/bin/bash" \
1652         gcc_do_make ${GCC_MAKE_TARGET}
1653 }
1654
1655 gcc_do_make() {
1656         # This function accepts one optional argument, the make target to be used.
1657         # If omitted, gcc_do_make will try to guess whether it should use all,
1658         # or bootstrap-lean depending on CTARGET and arch.
1659         # An example of how to use this function:
1660         #
1661         #       gcc_do_make all-target-libstdc++-v3
1662
1663         [[ -n ${1} ]] && GCC_MAKE_TARGET=${1}
1664
1665         # default target
1666         if is_crosscompile || tc-is-cross-compiler ; then
1667                 # 3 stage bootstrapping doesnt quite work when you cant run the
1668                 # resulting binaries natively ^^;
1669                 GCC_MAKE_TARGET=${GCC_MAKE_TARGET-all}
1670         else
1671                 if tc_version_is_at_least 3.3 && use_if_iuse pgo; then
1672                         GCC_MAKE_TARGET=${GCC_MAKE_TARGET-profiledbootstrap}
1673                 else
1674                         GCC_MAKE_TARGET=${GCC_MAKE_TARGET-bootstrap-lean}
1675                 fi
1676         fi
1677
1678         # Older versions of GCC could not do profiledbootstrap in parallel due to
1679         # collisions with profiling info.
1680         # boundschecking also seems to introduce parallel build issues.
1681         if [[ ${GCC_MAKE_TARGET} == "profiledbootstrap" ]] || use_if_iuse boundschecking ; then
1682                 ! tc_version_is_at_least 4.6 && export MAKEOPTS="${MAKEOPTS} -j1"
1683         fi
1684
1685         if [[ ${GCC_MAKE_TARGET} == "all" ]] ; then
1686                 STAGE1_CFLAGS=${STAGE1_CFLAGS-"${CFLAGS}"}
1687         elif [[ $(gcc-version) == "3.4" && ${GCC_BRANCH_VER} == "3.4" ]] && gcc-specs-ssp ; then
1688                 # See bug #79852
1689                 STAGE1_CFLAGS=${STAGE1_CFLAGS-"-O2"}
1690         fi
1691
1692         if is_crosscompile; then
1693                 # In 3.4, BOOT_CFLAGS is never used on a crosscompile...
1694                 # but I'll leave this in anyways as someone might have had
1695                 # some reason for putting it in here... --eradicator
1696                 BOOT_CFLAGS=${BOOT_CFLAGS-"-O2"}
1697         else
1698                 # we only want to use the system's CFLAGS if not building a
1699                 # cross-compiler.
1700                 BOOT_CFLAGS=${BOOT_CFLAGS-"$(get_abi_CFLAGS ${TARGET_DEFAULT_ABI}) ${CFLAGS}"}
1701         fi
1702
1703         einfo "Compiling ${PN} (${GCC_MAKE_TARGET})..."
1704
1705         pushd "${WORKDIR}"/build >/dev/null
1706
1707         emake \
1708                 LDFLAGS="${LDFLAGS}" \
1709                 STAGE1_CFLAGS="${STAGE1_CFLAGS}" \
1710                 LIBPATH="${LIBPATH}" \
1711                 BOOT_CFLAGS="${BOOT_CFLAGS}" \
1712                 ${GCC_MAKE_TARGET} \
1713                 || die "emake failed with ${GCC_MAKE_TARGET}"
1714
1715         if ! is_crosscompile && use_if_iuse cxx && use_if_iuse doc ; then
1716                 if type -p doxygen > /dev/null ; then
1717                         if tc_version_is_at_least 4.3 ; then
1718                                 cd "${CTARGET}"/libstdc++-v3/doc
1719                                 emake doc-man-doxygen || ewarn "failed to make docs"
1720                         elif tc_version_is_at_least 3.0 ; then
1721                                 cd "${CTARGET}"/libstdc++-v3
1722                                 emake doxygen-man || ewarn "failed to make docs"
1723                         fi
1724                         # Clean bogus manpages.  #113902
1725                         find -name '*_build_*' -delete
1726                         # Blow away generated directory references.  Newer versions of gcc
1727                         # have gotten better at this, but not perfect.  This is easier than
1728                         # backporting all of the various doxygen patches.  #486754
1729                         find -name '*_.3' -exec grep -l ' Directory Reference ' {} + | \
1730                                 xargs rm -f
1731                 else
1732                         ewarn "Skipping libstdc++ manpage generation since you don't have doxygen installed"
1733                 fi
1734         fi
1735
1736         popd >/dev/null
1737 }
1738
1739 #---->> src_test <<----
1740
1741 toolchain_src_test() {
1742         if use ${GCC_EBUILD_TEST_FLAG} ; then
1743                 cd "${WORKDIR}"/build
1744                 # enable verbose test run and result logging
1745                 emake -k check RUNTESTFLAGS='-a -v'
1746         fi
1747 }
1748
1749 #---->> src_install <<----
1750
1751 toolchain_src_install() {
1752         cd "${WORKDIR}"/build
1753
1754         # Do allow symlinks in private gcc include dir as this can break the build
1755         find gcc/include*/ -type l -delete
1756
1757         # Copy over the info pages.  We disabled their generation earlier, but the
1758         # build system only expects to install out of the build dir, not the source.  #464008
1759         mkdir -p gcc/doc
1760         local x=
1761         for x in "${S}"/gcc/doc/*.info* ; do
1762                 if [[ -f ${x} ]] ; then
1763                         cp "${x}" gcc/doc/ || die
1764                 fi
1765         done
1766
1767         # We remove the generated fixincludes, as they can cause things to break
1768         # (ncurses, openssl, etc).  We do not prevent them from being built, as
1769         # in the following commit which we revert:
1770         # https://sources.gentoo.org/cgi-bin/viewvc.cgi/gentoo-x86/eclass/toolchain.eclass?r1=1.647&r2=1.648
1771         # This is because bsd userland needs fixedincludes to build gcc, while
1772         # linux does not.  Both can dispose of them afterwards.
1773         while read x ; do
1774                 grep -q 'It has been auto-edited by fixincludes from' "${x}" \
1775                         && rm -f "${x}"
1776         done < <(find gcc/include*/ -name '*.h')
1777
1778         # Do the 'make install' from the build directory
1779         S="${WORKDIR}"/build emake -j1 DESTDIR="${D}" install || die
1780
1781         # Punt some tools which are really only useful while building gcc
1782         find "${ED}" -name install-tools -prune -type d -exec rm -rf "{}" \;
1783         # This one comes with binutils
1784         find "${ED}" -name libiberty.a -delete
1785
1786         # Move the libraries to the proper location
1787         gcc_movelibs
1788
1789         # Basic sanity check
1790         if ! is_crosscompile ; then
1791                 local EXEEXT
1792                 eval $(grep ^EXEEXT= "${WORKDIR}"/build/gcc/config.log)
1793                 [[ -r ${D}${BINPATH}/gcc${EXEEXT} ]] || die "gcc not found in ${ED}"
1794         fi
1795
1796         dodir /etc/env.d/gcc
1797         create_gcc_env_entry
1798         create_revdep_rebuild_entry
1799
1800         # Setup the gcc_env_entry for hardened gcc 4 with minispecs
1801         want_minispecs && copy_minispecs_gcc_specs
1802
1803         # Make sure we dont have stuff lying around that
1804         # can nuke multiple versions of gcc
1805         gcc_slot_java
1806
1807         dodir /usr/bin
1808         cd "${D}"${BINPATH}
1809         # Ugh: we really need to auto-detect this list.
1810         #      It's constantly out of date.
1811         for x in cpp gcc g++ c++ gcov g77 gcj gcjh gfortran gccgo ; do
1812                 # For some reason, g77 gets made instead of ${CTARGET}-g77...
1813                 # this should take care of that
1814                 if [[ -f ${x} ]] ; then
1815                         # In case they're hardlinks, clear out the target first
1816                         # otherwise the mv below will complain.
1817                         rm -f ${CTARGET}-${x}
1818                         mv ${x} ${CTARGET}-${x}
1819                 fi
1820
1821                 if [[ -f ${CTARGET}-${x} ]] ; then
1822                         if ! is_crosscompile ; then
1823                                 ln -sf ${CTARGET}-${x} ${x}
1824                                 dosym ${BINPATH#${EPREFIX}}/${CTARGET}-${x} \
1825                                         /usr/bin/${x}-${GCC_CONFIG_VER}
1826                         fi
1827                         # Create versioned symlinks
1828                         dosym ${BINPATH#${EPREFIX}}/${CTARGET}-${x} \
1829                                 /usr/bin/${CTARGET}-${x}-${GCC_CONFIG_VER}
1830                 fi
1831
1832                 if [[ -f ${CTARGET}-${x}-${GCC_CONFIG_VER} ]] ; then
1833                         rm -f ${CTARGET}-${x}-${GCC_CONFIG_VER}
1834                         ln -sf ${CTARGET}-${x} ${CTARGET}-${x}-${GCC_CONFIG_VER}
1835                 fi
1836         done
1837
1838         # When gcc builds a crosscompiler it does not install unprefixed tools.
1839         # When cross-building gcc does install native tools.
1840         if ! is_crosscompile; then
1841                 # Rename the main go binaries as we don't want to clobber dev-lang/go
1842                 # when gcc-config runs. #567806
1843                 if tc_version_is_at_least 5 && is_go ; then
1844                         for x in go gofmt; do
1845                                 mv ${x} ${x}-${GCCMAJOR} || die
1846                         done
1847                 fi
1848         fi
1849
1850         # TODO: implement stripping (we use RESTRICT=strip)
1851         # As gcc installs object files both build against ${CHOST} and ${CTARGET}
1852         # we will ned to run stripping using different tools:
1853         # Using ${CHOST} tools:
1854         #  - "${D}${BINPATH}"
1855         #  - (for is_crosscompile) "${D}${HOSTLIBPATH}"
1856         #  - "${D}${PREFIX}/libexec/gcc/${CTARGET}/${GCC_CONFIG_VER}"
1857         # Using ${CTARGET} tools:
1858         #  - "${D}${LIBPATH}"
1859
1860         cd "${S}"
1861         if is_crosscompile; then
1862                 rm -rf "${ED}"/usr/share/{man,info}
1863                 rm -rf "${D}"${DATAPATH}/{man,info}
1864         else
1865                 if tc_version_is_at_least 3.0 ; then
1866                         local cxx_mandir=$(find "${WORKDIR}/build/${CTARGET}/libstdc++-v3" -name man)
1867                         if [[ -d ${cxx_mandir} ]] ; then
1868                                 cp -r "${cxx_mandir}"/man? "${D}${DATAPATH}"/man/
1869                         fi
1870                 fi
1871         fi
1872
1873         # portage regenerates 'dir' files on it's own: bug #672408
1874         # Drop 'dir' files to avoid collisions.
1875         if [[ -f "${D}${DATAPATH}"/info/dir ]]; then
1876                 einfo "Deleting '${D}${DATAPATH}/info/dir'"
1877                 rm "${D}${DATAPATH}"/info/dir || die
1878         fi
1879
1880         # prune empty dirs left behind
1881         find "${ED}" -depth -type d -delete 2>/dev/null
1882
1883         # install testsuite results
1884         if use ${GCC_EBUILD_TEST_FLAG}; then
1885                 docinto testsuite
1886                 find "${WORKDIR}"/build -type f -name "*.sum" -exec dodoc {} +
1887                 find "${WORKDIR}"/build -type f -path "*/testsuite/*.log" -exec dodoc {} +
1888         fi
1889
1890         # Rather install the script, else portage with changing $FILESDIR
1891         # between binary and source package borks things ....
1892         if ! is_crosscompile && [[ ${PN} != "kgcc64" ]] ; then
1893                 insinto "${DATAPATH#${EPREFIX}}"
1894                 newins "$(prefixify_ro "${FILESDIR}"/awk/fixlafiles.awk-no_gcc_la)" fixlafiles.awk || die
1895                 exeinto "${DATAPATH#${EPREFIX}}"
1896                 doexe "$(prefixify_ro "${FILESDIR}"/fix_libtool_files.sh)" || die
1897                 doexe "${FILESDIR}"/c{89,99} || die
1898         fi
1899
1900         # libstdc++.la: Delete as it doesn't add anything useful: g++ itself
1901         # handles linkage correctly in the dynamic & static case.  It also just
1902         # causes us pain: any C++ progs/libs linking with libtool will gain a
1903         # reference to the full libstdc++.la file which is gcc version specific.
1904         # libstdc++fs.la: It doesn't link against anything useful.
1905         # libsupc++.la: This has no dependencies.
1906         # libcc1.la: There is no static library, only dynamic.
1907         # libcc1plugin.la: Same as above, and it's loaded via dlopen.
1908         # libcp1plugin.la: Same as above, and it's loaded via dlopen.
1909         # libgomp.la: gcc itself handles linkage (libgomp.spec).
1910         # libgomp-plugin-*.la: Same as above, and it's an internal plugin only
1911         # loaded via dlopen.
1912         # libgfortran.la: gfortran itself handles linkage correctly in the
1913         # dynamic & static case (libgfortran.spec). #573302
1914         # libgfortranbegin.la: Same as above, and it's an internal lib.
1915         # libmpx.la: gcc itself handles linkage correctly (libmpx.spec).
1916         # libmpxwrappers.la: See above.
1917         # libitm.la: gcc itself handles linkage correctly (libitm.spec).
1918         # libvtv.la: gcc itself handles linkage correctly.
1919         # lib*san.la: Sanitizer linkage is handled internally by gcc, and they
1920         # do not support static linking. #487550 #546700
1921         find "${D}${LIBPATH}" \
1922                 '(' \
1923                         -name libstdc++.la -o \
1924                         -name libstdc++fs.la -o \
1925                         -name libsupc++.la -o \
1926                         -name libcc1.la -o \
1927                         -name libcc1plugin.la -o \
1928                         -name libcp1plugin.la -o \
1929                         -name 'libgomp.la' -o \
1930                         -name 'libgomp-plugin-*.la' -o \
1931                         -name libgfortran.la -o \
1932                         -name libgfortranbegin.la -o \
1933                         -name libmpx.la -o \
1934                         -name libmpxwrappers.la -o \
1935                         -name libitm.la -o \
1936                         -name libvtv.la -o \
1937                         -name 'lib*san.la' \
1938                 ')' -type f -delete
1939
1940         # Use gid of 0 because some stupid ports don't have
1941         # the group 'root' set to gid 0.  Send to /dev/null
1942         # for people who are testing as non-root.
1943         chown -R root:0 "${D}${LIBPATH}" 2>/dev/null
1944
1945         # Installing gdb pretty-printers into gdb-specific location.
1946         local py gdbdir=/usr/share/gdb/auto-load${LIBPATH}
1947         pushd "${D}${LIBPATH}" >/dev/null
1948         for py in $(find . -name '*-gdb.py') ; do
1949                 local multidir=${py%/*}
1950                 insinto "${gdbdir}/${multidir}"
1951                 sed -i "/^libdir =/s:=.*:= '${LIBPATH}/${multidir}':" "${py}" || die #348128
1952                 doins "${py}" || die
1953                 rm "${py}" || die
1954         done
1955         popd >/dev/null
1956
1957         # Don't scan .gox files for executable stacks - false positives
1958         export QA_EXECSTACK="usr/lib*/go/*/*.gox"
1959         export QA_WX_LOAD="usr/lib*/go/*/*.gox"
1960
1961         # Disable RANDMMAP so PCH works. #301299
1962         if tc_version_is_at_least 4.3 ; then
1963                 pax-mark -r "${D}${PREFIX}/libexec/gcc/${CTARGET}/${GCC_CONFIG_VER}/cc1"
1964                 pax-mark -r "${D}${PREFIX}/libexec/gcc/${CTARGET}/${GCC_CONFIG_VER}/cc1plus"
1965         fi
1966
1967         # Disable MPROTECT so java works. #574808
1968         if is_gcj ; then
1969                 pax-mark -m "${D}${PREFIX}/libexec/gcc/${CTARGET}/${GCC_CONFIG_VER}/ecj1"
1970                 pax-mark -m "${D}${PREFIX}/${CTARGET}/gcc-bin/${GCC_CONFIG_VER}/gij"
1971         fi
1972 }
1973
1974 # Move around the libs to the right location.  For some reason,
1975 # when installing gcc, it dumps internal libraries into /usr/lib
1976 # instead of the private gcc lib path
1977 gcc_movelibs() {
1978         # older versions of gcc did not support --print-multi-os-directory
1979         tc_version_is_at_least 3.2 || return 0
1980
1981         # For non-target libs which are for CHOST and not CTARGET, we want to
1982         # move them to the compiler-specific CHOST internal dir.  This is stuff
1983         # that you want to link against when building tools rather than building
1984         # code to run on the target.
1985         if tc_version_is_at_least 5 && is_crosscompile ; then
1986                 dodir "${HOSTLIBPATH#${EPREFIX}}"
1987                 mv "${ED}"/usr/$(get_libdir)/libcc1* "${D}${HOSTLIBPATH}" || die
1988         fi
1989
1990         # For all the libs that are built for CTARGET, move them into the
1991         # compiler-specific CTARGET internal dir.
1992         local x multiarg removedirs=""
1993         for multiarg in $($(XGCC) -print-multi-lib) ; do
1994                 multiarg=${multiarg#*;}
1995                 multiarg=${multiarg//@/ -}
1996
1997                 local OS_MULTIDIR=$($(XGCC) ${multiarg} --print-multi-os-directory)
1998                 local MULTIDIR=$($(XGCC) ${multiarg} --print-multi-directory)
1999                 local TODIR="${D}${LIBPATH}"/${MULTIDIR}
2000                 local FROMDIR=
2001
2002                 [[ -d ${TODIR} ]] || mkdir -p ${TODIR}
2003
2004                 for FROMDIR in \
2005                         "${LIBPATH}"/${OS_MULTIDIR} \
2006                         "${LIBPATH}"/../${MULTIDIR} \
2007                         "${PREFIX}"/lib/${OS_MULTIDIR} \
2008                         "${PREFIX}"/${CTARGET}/lib/${OS_MULTIDIR}
2009                 do
2010                         removedirs="${removedirs} ${FROMDIR}"
2011                         FROMDIR=${D}${FROMDIR}
2012                         if [[ ${FROMDIR} != "${TODIR}" && -d ${FROMDIR} ]] ; then
2013                                 local files=$(find "${FROMDIR}" -maxdepth 1 ! -type d 2>/dev/null)
2014                                 if [[ -n ${files} ]] ; then
2015                                         mv ${files} "${TODIR}" || die
2016                                 fi
2017                         fi
2018                 done
2019                 fix_libtool_libdir_paths "${LIBPATH}/${MULTIDIR}"
2020
2021                 # SLOT up libgcj.pc if it's available (and let gcc-config worry about links)
2022                 FROMDIR="${PREFIX}/lib/${OS_MULTIDIR}"
2023                 for x in "${D}${FROMDIR}"/pkgconfig/libgcj*.pc ; do
2024                         [[ -f ${x} ]] || continue
2025                         sed -i "/^libdir=/s:=.*:=${LIBPATH}/${MULTIDIR}:" "${x}" || die
2026                         mv "${x}" "${D}${FROMDIR}"/pkgconfig/libgcj-${GCC_PV}.pc || die
2027                 done
2028         done
2029
2030         # We remove directories separately to avoid this case:
2031         #       mv SRC/lib/../lib/*.o DEST
2032         #       rmdir SRC/lib/../lib/
2033         #       mv SRC/lib/../lib32/*.o DEST  # Bork
2034         for FROMDIR in ${removedirs} ; do
2035                 rmdir "${D}"${FROMDIR} >& /dev/null
2036         done
2037         find -depth "${ED}" -type d -exec rmdir {} + >& /dev/null
2038 }
2039
2040 # make sure the libtool archives have libdir set to where they actually
2041 # -are-, and not where they -used- to be.  also, any dependencies we have
2042 # on our own .la files need to be updated.
2043 fix_libtool_libdir_paths() {
2044         local libpath="$1"
2045
2046         pushd "${D}" >/dev/null
2047
2048         pushd "./${libpath}" >/dev/null
2049         local dir="${PWD#${D%/}}"
2050         local allarchives=$(echo *.la)
2051         allarchives="\(${allarchives// /\\|}\)"
2052         popd >/dev/null
2053
2054         # The libdir might not have any .la files. #548782
2055         find "./${dir}" -maxdepth 1 -name '*.la' \
2056                 -exec sed -i -e "/^libdir=/s:=.*:='${dir}':" {} + || die
2057         # Would be nice to combine these, but -maxdepth can not be specified
2058         # on sub-expressions.
2059         find "./${PREFIX}"/lib* -maxdepth 3 -name '*.la' \
2060                 -exec sed -i -e "/^dependency_libs=/s:/[^ ]*/${allarchives}:${libpath}/\1:g" {} + || die
2061         find "./${dir}/" -maxdepth 1 -name '*.la' \
2062                 -exec sed -i -e "/^dependency_libs=/s:/[^ ]*/${allarchives}:${libpath}/\1:g" {} + || die
2063
2064         popd >/dev/null
2065 }
2066
2067 create_gcc_env_entry() {
2068         dodir /etc/env.d/gcc
2069         local gcc_envd_base="/etc/env.d/gcc/${CTARGET}-${GCC_CONFIG_VER}"
2070
2071         local gcc_specs_file
2072         local gcc_envd_file="${ED}${gcc_envd_base}"
2073         if [[ -z $1 ]] ; then
2074                 # I'm leaving the following commented out to remind me that it
2075                 # was an insanely -bad- idea. Stuff broke. GCC_SPECS isnt unset
2076                 # on chroot or in non-toolchain.eclass gcc ebuilds!
2077                 #gcc_specs_file="${LIBPATH}/specs"
2078                 gcc_specs_file=""
2079         else
2080                 gcc_envd_file+="-$1"
2081                 gcc_specs_file="${LIBPATH}/$1.specs"
2082         fi
2083
2084         # We want to list the default ABI's LIBPATH first so libtool
2085         # searches that directory first.  This is a temporary
2086         # workaround for libtool being stupid and using .la's from
2087         # conflicting ABIs by using the first one in the search path
2088         local ldpaths mosdirs
2089         if tc_version_is_at_least 3.2 ; then
2090                 local mdir mosdir abi ldpath
2091                 for abi in $(get_all_abis TARGET) ; do
2092                         mdir=$($(XGCC) $(get_abi_CFLAGS ${abi}) --print-multi-directory)
2093                         ldpath=${LIBPATH}
2094                         [[ ${mdir} != "." ]] && ldpath+="/${mdir}"
2095                         ldpaths="${ldpath}${ldpaths:+:${ldpaths}}"
2096
2097                         mosdir=$($(XGCC) $(get_abi_CFLAGS ${abi}) -print-multi-os-directory)
2098                         mosdirs="${mosdir}${mosdirs:+:${mosdirs}}"
2099                 done
2100         else
2101                 # Older gcc's didn't do multilib, so logic is simple.
2102                 ldpaths=${LIBPATH}
2103         fi
2104
2105         cat <<-EOF > ${gcc_envd_file}
2106         GCC_PATH="${BINPATH}"
2107         LDPATH="${ldpaths}"
2108         MANPATH="${DATAPATH}/man"
2109         INFOPATH="${DATAPATH}/info"
2110         STDCXX_INCDIR="${STDCXX_INCDIR##*/}"
2111         CTARGET="${CTARGET}"
2112         GCC_SPECS="${gcc_specs_file}"
2113         MULTIOSDIRS="${mosdirs}"
2114         EOF
2115 }
2116
2117 create_revdep_rebuild_entry() {
2118         local revdep_rebuild_base="/etc/revdep-rebuild/05cross-${CTARGET}-${GCC_CONFIG_VER}"
2119         local revdep_rebuild_file="${ED}${revdep_rebuild_base}"
2120
2121         is_crosscompile || return 0
2122
2123         dodir /etc/revdep-rebuild
2124         cat <<-EOF > "${revdep_rebuild_file}"
2125         # Generated by ${CATEGORY}/${PF}
2126         # Ignore libraries built for ${CTARGET}, https://bugs.gentoo.org/692844.
2127         SEARCH_DIRS_MASK="${LIBPATH}"
2128         EOF
2129 }
2130
2131 copy_minispecs_gcc_specs() {
2132         # on gcc 6 we don't need minispecs
2133         if tc_version_is_at_least 6.0 ; then
2134                 return 0
2135         fi
2136
2137         # setup the hardenedno* specs files and the vanilla specs file.
2138         if hardened_gcc_works ; then
2139                 create_gcc_env_entry hardenednopiessp
2140         fi
2141         if hardened_gcc_works pie ; then
2142                 create_gcc_env_entry hardenednopie
2143         fi
2144         if hardened_gcc_works ssp ; then
2145                 create_gcc_env_entry hardenednossp
2146         fi
2147         create_gcc_env_entry vanilla
2148         insinto ${LIBPATH#${EPREFIX}}
2149         doins "${WORKDIR}"/specs/*.specs || die "failed to install specs"
2150         # Build system specs file which, if it exists, must be a complete set of
2151         # specs as it completely and unconditionally overrides the builtin specs.
2152         if ! tc_version_is_at_least 4.4 ; then
2153                 $(XGCC) -dumpspecs > "${WORKDIR}"/specs/specs
2154                 cat "${WORKDIR}"/build.specs >> "${WORKDIR}"/specs/specs
2155                 doins "${WORKDIR}"/specs/specs || die "failed to install the specs file"
2156         fi
2157 }
2158
2159 gcc_slot_java() {
2160         local x
2161
2162         # Move Java headers to compiler-specific dir
2163         for x in "${D}${PREFIX}"/include/gc*.h "${D}${PREFIX}"/include/j*.h ; do
2164                 [[ -f ${x} ]] && mv -f "${x}" "${D}${LIBPATH}"/include/
2165         done
2166         for x in gcj gnu java javax org ; do
2167                 if [[ -d ${D}${PREFIX}/include/${x} ]] ; then
2168                         dodir /${LIBPATH#${EPREFIX}}/include/${x}
2169                         mv -f "${D}${PREFIX}"/include/${x}/* "${D}${LIBPATH}"/include/${x}/
2170                         rm -rf "${D}${PREFIX}"/include/${x}
2171                 fi
2172         done
2173
2174         if [[ -d ${D}${PREFIX}/lib/security ]] || [[ -d ${D}${PREFIX}/$(get_libdir)/security ]] ; then
2175                 dodir /${LIBPATH#${EPREFIX}}/security
2176                 mv -f "${D}${PREFIX}"/lib*/security/* "${D}${LIBPATH}"/security
2177                 rm -rf "${D}${PREFIX}"/lib*/security
2178         fi
2179
2180         # Move random gcj files to compiler-specific directories
2181         for x in libgcj.spec logging.properties ; do
2182                 x="${D}${PREFIX}/lib/${x}"
2183                 [[ -f ${x} ]] && mv -f "${x}" "${D}${LIBPATH}"/
2184         done
2185
2186         # Rename jar because it could clash with Kaffe's jar if this gcc is
2187         # primary compiler (aka don't have the -<version> extension)
2188         cd "${D}${BINPATH}"
2189         [[ -f jar ]] && mv -f jar gcj-jar
2190 }
2191
2192 #---->> pkg_post* <<----
2193
2194 toolchain_pkg_postinst() {
2195         do_gcc_config
2196         if [[ ! ${ROOT%/} && -f ${EPREFIX}/usr/share/eselect/modules/compiler-shadow.eselect ]] ; then
2197                 eselect compiler-shadow update all
2198         fi
2199
2200         if ! is_crosscompile && [[ ${PN} != "kgcc64" ]] ; then
2201                 echo
2202                 ewarn "If you have issues with packages unable to locate libstdc++.la,"
2203                 ewarn "then try running 'fix_libtool_files.sh' on the old gcc versions."
2204                 echo
2205                 ewarn "You might want to review the GCC upgrade guide when moving between"
2206                 ewarn "major versions (like 4.2 to 4.3):"
2207                 ewarn "https://wiki.gentoo.org/wiki/Upgrading_GCC"
2208                 echo
2209
2210                 # Clean up old paths
2211                 rm -f "${EROOT%/}"/*/rcscripts/awk/fixlafiles.awk "${EROOT%/}"/sbin/fix_libtool_files.sh
2212                 rmdir "${EROOT%/}"/*/rcscripts{/awk,} 2>/dev/null
2213
2214                 mkdir -p "${EROOT%/}"/usr/{share/gcc-data,sbin,bin}
2215                 # DATAPATH has EPREFIX already, use ROOT with it
2216                 cp "${ROOT%/}${DATAPATH}"/fixlafiles.awk "${EROOT%/}"/usr/share/gcc-data/ || die
2217                 cp "${ROOT%/}${DATAPATH}"/fix_libtool_files.sh "${EROOT%/}"/usr/sbin/ || die
2218
2219                 # Since these aren't critical files and portage sucks with
2220                 # handling of binpkgs, don't require these to be found
2221                 cp "${ROOT%/}${DATAPATH}"/c{89,99} "${EROOT%/}"/usr/bin/ 2>/dev/null
2222         fi
2223
2224         if use ${GCC_EBUILD_TEST_FLAG} ; then
2225                 elog "Testsuite results have been installed into /usr/share/doc/${PF}/testsuite"
2226                 echo
2227         fi
2228
2229         if [[ -n ${PRERELEASE}${SNAPSHOT} ]] ; then
2230                 einfo "This GCC ebuild is provided for your convenience, and the use"
2231                 einfo "of this compiler is not supported by the Gentoo Developers."
2232                 einfo "Please report bugs to upstream at http://gcc.gnu.org/bugzilla/"
2233         fi
2234 }
2235
2236 toolchain_pkg_postrm() {
2237         do_gcc_config
2238         if [[ ! ${ROOT%/} && -f ${EPREFIX}/usr/share/eselect/modules/compiler-shadow.eselect ]] ; then
2239                 eselect compiler-shadow clean all
2240         fi
2241
2242         # to make our lives easier (and saner), we do the fix_libtool stuff here.
2243         # rather than checking SLOT's and trying in upgrade paths, we just see if
2244         # the common libstdc++.la exists in the ${LIBPATH} of the gcc that we are
2245         # unmerging.  if it does, that means this was a simple re-emerge.
2246
2247         # clean up the cruft left behind by cross-compilers
2248         if is_crosscompile ; then
2249                 if [[ -z $(ls "${EROOT%/}"/etc/env.d/gcc/${CTARGET}* 2>/dev/null) ]] ; then
2250                         einfo "Removing last cross-compiler instance. Deleting dangling symlinks."
2251                         rm -f "${EROOT%/}"/etc/env.d/gcc/config-${CTARGET}
2252                         rm -f "${EROOT%/}"/etc/env.d/??gcc-${CTARGET}
2253                         rm -f "${EROOT%/}"/usr/bin/${CTARGET}-{gcc,{g,c}++}{,32,64}
2254                 fi
2255                 return 0
2256         fi
2257
2258         # ROOT isnt handled by the script
2259         [[ ${ROOT%/} ]] && return 0
2260
2261         if [[ ! -e ${LIBPATH}/libstdc++.so ]] ; then
2262                 einfo "Running 'fix_libtool_files.sh ${GCC_RELEASE_VER}'"
2263                 fix_libtool_files.sh ${GCC_RELEASE_VER}
2264         fi
2265
2266         return 0
2267 }
2268
2269 do_gcc_config() {
2270         if ! should_we_gcc_config ; then
2271                 gcc-config --use-old --force
2272                 return 0
2273         fi
2274
2275         local current_gcc_config target
2276
2277         current_gcc_config=$(gcc-config -c ${CTARGET} 2>/dev/null)
2278         if [[ -n ${current_gcc_config} ]] ; then
2279                 local current_specs use_specs
2280                 # figure out which specs-specific config is active
2281                 current_specs=$(gcc-config -S ${current_gcc_config} | awk '{print $3}')
2282                 [[ -n ${current_specs} ]] && use_specs=-${current_specs}
2283
2284                 if [[ -n ${use_specs} ]] && \
2285                    [[ ! -e ${EROOT%/}/etc/env.d/gcc/${CTARGET}-${GCC_CONFIG_VER}${use_specs} ]]
2286                 then
2287                         ewarn "The currently selected specs-specific gcc config,"
2288                         ewarn "${current_specs}, doesn't exist anymore. This is usually"
2289                         ewarn "due to enabling/disabling hardened or switching to a version"
2290                         ewarn "of gcc that doesnt create multiple specs files. The default"
2291                         ewarn "config will be used, and the previous preference forgotten."
2292                         use_specs=""
2293                 fi
2294
2295                 target="${CTARGET}-${GCC_CONFIG_VER}${use_specs}"
2296         else
2297                 # The curent target is invalid.  Attempt to switch to a valid one.
2298                 # Blindly pick the latest version.  #529608
2299                 # TODO: Should update gcc-config to accept `-l ${CTARGET}` rather than
2300                 # doing a partial grep like this.
2301                 target=$(gcc-config -l 2>/dev/null | grep " ${CTARGET}-[0-9]" | tail -1 | awk '{print $2}')
2302         fi
2303
2304         gcc-config "${target}"
2305 }
2306
2307 should_we_gcc_config() {
2308         # if the current config is invalid, we definitely want a new one
2309         # Note: due to bash quirkiness, the following must not be 1 line
2310         local curr_config
2311         curr_config=$(gcc-config -c ${CTARGET} 2>&1) || return 0
2312
2313         # if the previously selected config has the same major.minor (branch) as
2314         # the version we are installing, then it will probably be uninstalled
2315         # for being in the same SLOT, make sure we run gcc-config.
2316         local curr_config_ver=$(gcc-config -S ${curr_config} | awk '{print $2}')
2317
2318         local curr_branch_ver=$(ver_cut 1-2 ${curr_config_ver})
2319
2320         if [[ ${curr_branch_ver} == ${GCC_BRANCH_VER} ]] ; then
2321                 return 0
2322         else
2323                 # if we're installing a genuinely different compiler version,
2324                 # we should probably tell the user -how- to switch to the new
2325                 # gcc version, since we're not going to do it for him/her.
2326                 # We don't want to switch from say gcc-3.3 to gcc-3.4 right in
2327                 # the middle of an emerge operation (like an 'emerge -e world'
2328                 # which could install multiple gcc versions).
2329                 # Only warn if we're installing a pkg as we might be called from
2330                 # the pkg_{pre,post}rm steps.  #446830
2331                 if [[ ${EBUILD_PHASE} == *"inst" ]] ; then
2332                         einfo "The current gcc config appears valid, so it will not be"
2333                         einfo "automatically switched for you.  If you would like to"
2334                         einfo "switch to the newly installed gcc version, do the"
2335                         einfo "following:"
2336                         echo
2337                         einfo "gcc-config ${CTARGET}-${GCC_CONFIG_VER}"
2338                         einfo "source /etc/profile"
2339                         echo
2340                 fi
2341                 return 1
2342         fi
2343 }
2344
2345 #---->> support and misc functions <<----
2346
2347 # This is to make sure we don't accidentally try to enable support for a
2348 # language that doesnt exist. GCC 3.4 supports f77, while 4.0 supports f95, etc.
2349 #
2350 # Also add a hook so special ebuilds (kgcc64) can control which languages
2351 # exactly get enabled
2352 gcc-lang-supported() {
2353         grep ^language=\"${1}\" "${S}"/gcc/*/config-lang.in > /dev/null || return 1
2354         [[ -z ${TOOLCHAIN_ALLOWED_LANGS} ]] && return 0
2355         has $1 ${TOOLCHAIN_ALLOWED_LANGS}
2356 }
2357
2358 is_ada() {
2359         gcc-lang-supported ada || return 1
2360         use_if_iuse ada
2361 }
2362
2363 is_cxx() {
2364         gcc-lang-supported 'c++' || return 1
2365         use_if_iuse cxx
2366 }
2367
2368 is_d() {
2369         gcc-lang-supported d || return 1
2370         use_if_iuse d
2371 }
2372
2373 is_f77() {
2374         gcc-lang-supported f77 || return 1
2375         use_if_iuse fortran
2376 }
2377
2378 is_f95() {
2379         gcc-lang-supported f95 || return 1
2380         use_if_iuse fortran
2381 }
2382
2383 is_fortran() {
2384         gcc-lang-supported fortran || return 1
2385         use_if_iuse fortran
2386 }
2387
2388 is_gcj() {
2389         gcc-lang-supported java || return 1
2390         use_if_iuse cxx && use_if_iuse gcj
2391 }
2392
2393 is_go() {
2394         gcc-lang-supported go || return 1
2395         use_if_iuse cxx && use_if_iuse go
2396 }
2397
2398 is_jit() {
2399         gcc-lang-supported jit || return 1
2400         # cross-compiler does not really support jit as it has
2401         # to generate code for a target. On target like avr
2402         # libgcclit.so can't link at all: bug #594572
2403         is_crosscompile && return 1
2404         use_if_iuse jit
2405 }
2406
2407 is_multilib() {
2408         tc_version_is_at_least 3 || return 1
2409         use_if_iuse multilib
2410 }
2411
2412 is_objc() {
2413         gcc-lang-supported objc || return 1
2414         use_if_iuse objc
2415 }
2416
2417 is_objcxx() {
2418         gcc-lang-supported 'obj-c++' || return 1
2419         use_if_iuse cxx && use_if_iuse objc++
2420 }
2421
2422 # Grab a variable from the build system (taken from linux-info.eclass)
2423 get_make_var() {
2424         local var=$1 makefile=${2:-${WORKDIR}/build/Makefile}
2425         echo -e "e:\\n\\t@echo \$(${var})\\ninclude ${makefile}" | \
2426                 r=${makefile%/*} emake --no-print-directory -s -f - 2>/dev/null
2427 }
2428
2429 XGCC() { get_make_var GCC_FOR_TARGET ; }
2430
2431 # The gentoo piessp patches allow for 3 configurations:
2432 # 1) PIE+SSP by default
2433 # 2) PIE by default
2434 # 3) SSP by default
2435 hardened_gcc_works() {
2436         if [[ $1 == "pie" ]] ; then
2437                 # $gcc_cv_ld_pie is unreliable as it simply take the output of
2438                 # `ld --help | grep -- -pie`, that reports the option in all cases, also if
2439                 # the loader doesn't actually load the resulting executables.
2440                 # To avoid breakage, blacklist FreeBSD here at least
2441                 [[ ${CTARGET} == *-freebsd* ]] && return 1
2442
2443                 want_pie || return 1
2444                 use_if_iuse nopie && return 1
2445                 hardened_gcc_is_stable pie
2446                 return $?
2447         elif [[ $1 == "ssp" ]] ; then
2448                 [[ -n ${SPECS_VER} ]] || return 1
2449                 use_if_iuse nossp && return 1
2450                 hardened_gcc_is_stable ssp
2451                 return $?
2452         else
2453                 # laziness ;)
2454                 hardened_gcc_works pie || return 1
2455                 hardened_gcc_works ssp || return 1
2456                 return 0
2457         fi
2458 }
2459
2460 hardened_gcc_is_stable() {
2461         local tocheck
2462         if [[ $1 == "pie" ]] ; then
2463                 if [[ ${CTARGET} == *-uclibc* ]] ; then
2464                         tocheck=${PIE_UCLIBC_STABLE}
2465                 else
2466                         tocheck=${PIE_GLIBC_STABLE}
2467                 fi
2468         elif [[ $1 == "ssp" ]] ; then
2469                 if [[ ${CTARGET} == *-uclibc* ]] ; then
2470                         tocheck=${SSP_UCLIBC_STABLE}
2471                 elif  [[ ${CTARGET} == *-gnu* ]] ; then
2472                         tocheck=${SSP_STABLE}
2473                 fi
2474         else
2475                 die "hardened_gcc_stable needs to be called with pie or ssp"
2476         fi
2477
2478         has $(tc-arch) ${tocheck} && return 0
2479         return 1
2480 }
2481
2482 want_minispecs() {
2483         # on gcc 6 we don't need minispecs
2484         if tc_version_is_at_least 6.0 ; then
2485                 return 0
2486         fi
2487         if tc_version_is_at_least 4.3.2 && use_if_iuse hardened ; then
2488                 if ! want_pie ; then
2489                         ewarn "PIE_VER or SPECS_VER is not defined in the GCC ebuild."
2490                 elif use vanilla ; then
2491                         ewarn "You will not get hardened features if you have the vanilla USE-flag."
2492                 elif use_if_iuse nopie && use_if_iuse nossp ; then
2493                         ewarn "You will not get hardened features if you have the nopie and nossp USE-flag."
2494                 elif ! hardened_gcc_works ; then
2495                         ewarn "Your $(tc-arch) arch is not supported."
2496                 else
2497                         return 0
2498                 fi
2499                 ewarn "Hope you know what you are doing. Hardened will not work."
2500                 return 0
2501         fi
2502         return 1
2503 }
2504
2505 want_pie() {
2506         ! use_if_iuse hardened && [[ -n ${PIE_VER} ]] && use_if_iuse nopie && return 1
2507         [[ -n ${PIE_VER} ]] && [[ -n ${SPECS_VER} ]] && return 0
2508         tc_version_is_at_least 4.3.2 && return 1
2509         [[ -z ${PIE_VER} ]] && return 1
2510         use_if_iuse nopie || return 0
2511         return 1
2512 }
2513
2514 has toolchain_death_notice ${EBUILD_DEATH_HOOKS} || EBUILD_DEATH_HOOKS+=" toolchain_death_notice"
2515 toolchain_death_notice() {
2516         if [[ -e "${WORKDIR}"/build ]] ; then
2517                 pushd "${WORKDIR}"/build >/dev/null
2518                 (echo '' | $(tc-getCC ${CTARGET}) ${CFLAGS} -v -E - 2>&1) > gccinfo.log
2519                 [[ -e "${T}"/build.log ]] && cp "${T}"/build.log .
2520                 tar jcf "${WORKDIR}"/gcc-build-logs.tar.bz2 \
2521                         gccinfo.log build.log $(find -name config.log)
2522                 rm gccinfo.log build.log
2523                 eerror
2524                 eerror "Please include ${WORKDIR}/gcc-build-logs.tar.bz2 in your bug report."
2525                 eerror
2526                 popd >/dev/null
2527         fi
2528 }
2529
2530 # Note [implicitly enabled flags]
2531 # -------------------------------
2532 # Usually configure-based packages handle explicit feature requests
2533 # like
2534 #     ./configure --enable-foo
2535 # as explicit request to check for support of 'foo' and bail out at
2536 # configure time.
2537 #
2538 # GCC does not follow this pattern and instead overrides autodetection
2539 # of the feature and enables it unconditionally.
2540 # See bugs:
2541 #    https://gcc.gnu.org/PR85663 (libsanitizer on mips)
2542 #    https://bugs.gentoo.org/661252 (libvtv on powerpc64)
2543 #
2544 # Thus safer way to enable/disable the feature is to rely on implicit
2545 # enabled-by-default state:
2546 #    econf $(usex foo '' --disable-foo)