1 | # Copyright 1999-2012 Gentoo Foundation |
1 | # Copyright 1999-2015 Gentoo Foundation |
2 | # Distributed under the terms of the GNU General Public License v2 |
2 | # Distributed under the terms of the GNU General Public License v2 |
3 | # $Header: /var/cvsroot/gentoo-x86/eclass/toolchain-funcs.eclass,v 1.120 2012/12/29 05:08:54 vapier Exp $ |
3 | # $Header: /var/cvsroot/gentoo-x86/eclass/toolchain-funcs.eclass,v 1.137 2015/04/13 05:38:17 vapier Exp $ |
4 | |
4 | |
5 | # @ECLASS: toolchain-funcs.eclass |
5 | # @ECLASS: toolchain-funcs.eclass |
6 | # @MAINTAINER: |
6 | # @MAINTAINER: |
7 | # Toolchain Ninjas <toolchain@gentoo.org> |
7 | # Toolchain Ninjas <toolchain@gentoo.org> |
8 | # @BLURB: functions to query common info about the toolchain |
8 | # @BLURB: functions to query common info about the toolchain |
… | |
… | |
11 | # for gleaning useful information about the toolchain and to simplify |
11 | # for gleaning useful information about the toolchain and to simplify |
12 | # ugly things like cross-compiling and multilib. All of this is done |
12 | # ugly things like cross-compiling and multilib. All of this is done |
13 | # in such a way that you can rely on the function always returning |
13 | # in such a way that you can rely on the function always returning |
14 | # something sane. |
14 | # something sane. |
15 | |
15 | |
16 | if [[ ${___ECLASS_ONCE_TOOLCHAIN_FUNCS} != "recur -_+^+_- spank" ]] ; then |
16 | if [[ -z ${_TOOLCHAIN_FUNCS_ECLASS} ]]; then |
17 | ___ECLASS_ONCE_TOOLCHAIN_FUNCS="recur -_+^+_- spank" |
17 | _TOOLCHAIN_FUNCS_ECLASS=1 |
18 | |
18 | |
19 | inherit multilib |
19 | inherit multilib |
20 | |
20 | |
21 | # tc-getPROG <VAR [search vars]> <default> [tuple] |
21 | # tc-getPROG <VAR [search vars]> <default> [tuple] |
22 | _tc-getPROG() { |
22 | _tc-getPROG() { |
… | |
… | |
82 | tc-getRANLIB() { tc-getPROG RANLIB ranlib "$@"; } |
82 | tc-getRANLIB() { tc-getPROG RANLIB ranlib "$@"; } |
83 | # @FUNCTION: tc-getOBJCOPY |
83 | # @FUNCTION: tc-getOBJCOPY |
84 | # @USAGE: [toolchain prefix] |
84 | # @USAGE: [toolchain prefix] |
85 | # @RETURN: name of the object copier |
85 | # @RETURN: name of the object copier |
86 | tc-getOBJCOPY() { tc-getPROG OBJCOPY objcopy "$@"; } |
86 | tc-getOBJCOPY() { tc-getPROG OBJCOPY objcopy "$@"; } |
|
|
87 | # @FUNCTION: tc-getOBJDUMP |
|
|
88 | # @USAGE: [toolchain prefix] |
|
|
89 | # @RETURN: name of the object dumper |
|
|
90 | tc-getOBJDUMP() { tc-getPROG OBJDUMP objdump "$@"; } |
87 | # @FUNCTION: tc-getF77 |
91 | # @FUNCTION: tc-getF77 |
88 | # @USAGE: [toolchain prefix] |
92 | # @USAGE: [toolchain prefix] |
89 | # @RETURN: name of the Fortran 77 compiler |
93 | # @RETURN: name of the Fortran 77 compiler |
90 | tc-getF77() { tc-getPROG F77 gfortran "$@"; } |
94 | tc-getF77() { tc-getPROG F77 gfortran "$@"; } |
91 | # @FUNCTION: tc-getFC |
95 | # @FUNCTION: tc-getFC |
… | |
… | |
167 | } |
171 | } |
168 | |
172 | |
169 | # @FUNCTION: tc-is-cross-compiler |
173 | # @FUNCTION: tc-is-cross-compiler |
170 | # @RETURN: Shell true if we are using a cross-compiler, shell false otherwise |
174 | # @RETURN: Shell true if we are using a cross-compiler, shell false otherwise |
171 | tc-is-cross-compiler() { |
175 | tc-is-cross-compiler() { |
172 | return $([[ ${CBUILD:-${CHOST}} != ${CHOST} ]]) |
176 | [[ ${CBUILD:-${CHOST}} != ${CHOST} ]] |
173 | } |
177 | } |
174 | |
178 | |
175 | # @FUNCTION: tc-is-softfloat |
179 | # @FUNCTION: tc-is-softfloat |
176 | # @DESCRIPTION: |
180 | # @DESCRIPTION: |
177 | # See if this toolchain is a softfloat based one. |
181 | # See if this toolchain is a softfloat based one. |
… | |
… | |
208 | # otherwise. |
212 | # otherwise. |
209 | tc-is-static-only() { |
213 | tc-is-static-only() { |
210 | local host=${CTARGET:-${CHOST}} |
214 | local host=${CTARGET:-${CHOST}} |
211 | |
215 | |
212 | # *MiNT doesn't have shared libraries, only platform so far |
216 | # *MiNT doesn't have shared libraries, only platform so far |
213 | return $([[ ${host} == *-mint* ]]) |
217 | [[ ${host} == *-mint* ]] |
214 | } |
218 | } |
215 | |
219 | |
216 | # @FUNCTION: tc-export_build_env |
220 | # @FUNCTION: tc-export_build_env |
217 | # @USAGE: [compiler variables] |
221 | # @USAGE: [compiler variables] |
218 | # @DESCRIPTION: |
222 | # @DESCRIPTION: |
219 | # Export common build related compiler settings. |
223 | # Export common build related compiler settings. |
220 | tc-export_build_env() { |
224 | tc-export_build_env() { |
221 | tc-export "$@" |
225 | tc-export "$@" |
|
|
226 | # Some build envs will initialize vars like: |
|
|
227 | # : ${BUILD_LDFLAGS:-${LDFLAGS}} |
|
|
228 | # So make sure all variables are non-empty. #526734 |
222 | : ${BUILD_CFLAGS:=-O1 -pipe} |
229 | : ${BUILD_CFLAGS:=-O1 -pipe} |
223 | : ${BUILD_CXXFLAGS:=-O1 -pipe} |
230 | : ${BUILD_CXXFLAGS:=-O1 -pipe} |
224 | : ${BUILD_CPPFLAGS:=} |
231 | : ${BUILD_CPPFLAGS:= } |
225 | : ${BUILD_LDFLAGS:=} |
232 | : ${BUILD_LDFLAGS:= } |
226 | export BUILD_{C,CXX,CPP,LD}FLAGS |
233 | export BUILD_{C,CXX,CPP,LD}FLAGS |
|
|
234 | |
|
|
235 | # Some packages use XXX_FOR_BUILD. |
|
|
236 | local v |
|
|
237 | for v in BUILD_{C,CXX,CPP,LD}FLAGS ; do |
|
|
238 | export ${v#BUILD_}_FOR_BUILD="${!v}" |
|
|
239 | done |
227 | } |
240 | } |
228 | |
241 | |
229 | # @FUNCTION: tc-env_build |
242 | # @FUNCTION: tc-env_build |
230 | # @USAGE: <command> [command args] |
243 | # @USAGE: <command> [command args] |
231 | # @INTERNAL |
244 | # @INTERNAL |
… | |
… | |
289 | # fi |
302 | # fi |
290 | # ... normal build paths ... |
303 | # ... normal build paths ... |
291 | # } |
304 | # } |
292 | # @CODE |
305 | # @CODE |
293 | econf_build() { |
306 | econf_build() { |
|
|
307 | local CBUILD=${CBUILD:-${CHOST}} |
294 | tc-env_build econf --build=${CBUILD:-${CHOST}} "$@" |
308 | tc-env_build econf --build=${CBUILD} --host=${CBUILD} "$@" |
|
|
309 | } |
|
|
310 | |
|
|
311 | # @FUNCTION: tc-ld-is-gold |
|
|
312 | # @USAGE: [toolchain prefix] |
|
|
313 | # @DESCRIPTION: |
|
|
314 | # Return true if the current linker is set to gold. |
|
|
315 | tc-ld-is-gold() { |
|
|
316 | local out |
|
|
317 | |
|
|
318 | # First check the linker directly. |
|
|
319 | out=$($(tc-getLD "$@") --version 2>&1) |
|
|
320 | if [[ ${out} == *"GNU gold"* ]] ; then |
|
|
321 | return 0 |
|
|
322 | fi |
|
|
323 | |
|
|
324 | # Then see if they're selecting gold via compiler flags. |
|
|
325 | # Note: We're assuming they're using LDFLAGS to hold the |
|
|
326 | # options and not CFLAGS/CXXFLAGS. |
|
|
327 | local base="${T}/test-tc-gold" |
|
|
328 | cat <<-EOF > "${base}.c" |
|
|
329 | int main() { return 0; } |
|
|
330 | EOF |
|
|
331 | out=$($(tc-getCC "$@") ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} -Wl,--version "${base}.c" -o "${base}" 2>&1) |
|
|
332 | rm -f "${base}"* |
|
|
333 | if [[ ${out} == *"GNU gold"* ]] ; then |
|
|
334 | return 0 |
|
|
335 | fi |
|
|
336 | |
|
|
337 | # No gold here! |
|
|
338 | return 1 |
|
|
339 | } |
|
|
340 | |
|
|
341 | # @FUNCTION: tc-ld-disable-gold |
|
|
342 | # @USAGE: [toolchain prefix] |
|
|
343 | # @DESCRIPTION: |
|
|
344 | # If the gold linker is currently selected, configure the compilation |
|
|
345 | # settings so that we use the older bfd linker instead. |
|
|
346 | tc-ld-disable-gold() { |
|
|
347 | if ! tc-ld-is-gold "$@" ; then |
|
|
348 | # They aren't using gold, so nothing to do! |
|
|
349 | return |
|
|
350 | fi |
|
|
351 | |
|
|
352 | ewarn "Forcing usage of the BFD linker instead of GOLD" |
|
|
353 | |
|
|
354 | # Set up LD to point directly to bfd if it's available. |
|
|
355 | # We need to extract the first word in case there are flags appended |
|
|
356 | # to its value (like multilib). #545218 |
|
|
357 | local ld=$(tc-getLD "$@") |
|
|
358 | local bfd_ld="${ld%% *}.bfd" |
|
|
359 | local path_ld=$(which "${bfd_ld}" 2>/dev/null) |
|
|
360 | [[ -e ${path_ld} ]] && export LD=${bfd_ld} |
|
|
361 | |
|
|
362 | # Set up LDFLAGS to select gold based on the gcc version. |
|
|
363 | local major=$(gcc-major-version "$@") |
|
|
364 | local minor=$(gcc-minor-version "$@") |
|
|
365 | if [[ ${major} -lt 4 ]] || [[ ${major} -eq 4 && ${minor} -lt 8 ]] ; then |
|
|
366 | # <=gcc-4.7 requires some coercion. Only works if bfd exists. |
|
|
367 | if [[ -e ${path_ld} ]] ; then |
|
|
368 | local d="${T}/bfd-linker" |
|
|
369 | mkdir -p "${d}" |
|
|
370 | ln -sf "${path_ld}" "${d}"/ld |
|
|
371 | export LDFLAGS="${LDFLAGS} -B${d}" |
|
|
372 | else |
|
|
373 | die "unable to locate a BFD linker to bypass gold" |
|
|
374 | fi |
|
|
375 | else |
|
|
376 | # gcc-4.8+ supports -fuse-ld directly. |
|
|
377 | export LDFLAGS="${LDFLAGS} -fuse-ld=bfd" |
|
|
378 | fi |
295 | } |
379 | } |
296 | |
380 | |
297 | # @FUNCTION: tc-has-openmp |
381 | # @FUNCTION: tc-has-openmp |
298 | # @USAGE: [toolchain prefix] |
382 | # @USAGE: [toolchain prefix] |
299 | # @DESCRIPTION: |
383 | # @DESCRIPTION: |
… | |
… | |
360 | local KV=${KV:-${KV_FULL}} |
444 | local KV=${KV:-${KV_FULL}} |
361 | [[ ${type} == "kern" ]] && [[ -z ${KV} ]] && \ |
445 | [[ ${type} == "kern" ]] && [[ -z ${KV} ]] && \ |
362 | ewarn "QA: Kernel version could not be determined, please inherit kernel-2 or linux-info" |
446 | ewarn "QA: Kernel version could not be determined, please inherit kernel-2 or linux-info" |
363 | |
447 | |
364 | case ${host} in |
448 | case ${host} in |
365 | aarch64*) ninj arm64 arm;; |
449 | aarch64*) echo arm64;; |
366 | alpha*) echo alpha;; |
450 | alpha*) echo alpha;; |
367 | arm*) echo arm;; |
451 | arm*) echo arm;; |
368 | avr*) ninj avr32 avr;; |
452 | avr*) ninj avr32 avr;; |
369 | bfin*) ninj blackfin bfin;; |
453 | bfin*) ninj blackfin bfin;; |
|
|
454 | c6x*) echo c6x;; |
370 | cris*) echo cris;; |
455 | cris*) echo cris;; |
|
|
456 | frv*) echo frv;; |
|
|
457 | hexagon*) echo hexagon;; |
371 | hppa*) ninj parisc hppa;; |
458 | hppa*) ninj parisc hppa;; |
372 | i?86*) |
459 | i?86*) |
373 | # Starting with linux-2.6.24, the 'x86_64' and 'i386' |
460 | # Starting with linux-2.6.24, the 'x86_64' and 'i386' |
374 | # trees have been unified into 'x86'. |
461 | # trees have been unified into 'x86'. |
375 | # FreeBSD still uses i386 |
462 | # FreeBSD still uses i386 |
… | |
… | |
379 | echo x86 |
466 | echo x86 |
380 | fi |
467 | fi |
381 | ;; |
468 | ;; |
382 | ia64*) echo ia64;; |
469 | ia64*) echo ia64;; |
383 | m68*) echo m68k;; |
470 | m68*) echo m68k;; |
|
|
471 | metag*) echo metag;; |
|
|
472 | microblaze*) echo microblaze;; |
384 | mips*) echo mips;; |
473 | mips*) echo mips;; |
385 | nios2*) echo nios2;; |
474 | nios2*) echo nios2;; |
386 | nios*) echo nios;; |
475 | nios*) echo nios;; |
|
|
476 | or32*) echo openrisc;; |
387 | powerpc*) |
477 | powerpc*) |
388 | # Starting with linux-2.6.15, the 'ppc' and 'ppc64' trees |
478 | # Starting with linux-2.6.15, the 'ppc' and 'ppc64' trees |
389 | # have been unified into simply 'powerpc', but until 2.6.16, |
479 | # have been unified into simply 'powerpc', but until 2.6.16, |
390 | # ppc32 is still using ARCH="ppc" as default |
480 | # ppc32 is still using ARCH="ppc" as default |
391 | if [[ ${type} == "kern" ]] && [[ $(KV_to_int ${KV}) -ge $(KV_to_int 2.6.16) ]] ; then |
481 | if [[ ${type} == "kern" ]] && [[ $(KV_to_int ${KV}) -ge $(KV_to_int 2.6.16) ]] ; then |
… | |
… | |
402 | ninj ppc64 ppc |
492 | ninj ppc64 ppc |
403 | else |
493 | else |
404 | echo ppc |
494 | echo ppc |
405 | fi |
495 | fi |
406 | ;; |
496 | ;; |
|
|
497 | riscv*) echo riscv;; |
407 | s390*) echo s390;; |
498 | s390*) echo s390;; |
|
|
499 | score*) echo score;; |
408 | sh64*) ninj sh64 sh;; |
500 | sh64*) ninj sh64 sh;; |
409 | sh*) echo sh;; |
501 | sh*) echo sh;; |
410 | sparc64*) ninj sparc64 sparc;; |
502 | sparc64*) ninj sparc64 sparc;; |
411 | sparc*) [[ ${PROFILE_ARCH} == "sparc64" ]] \ |
503 | sparc*) [[ ${PROFILE_ARCH} == "sparc64" ]] \ |
412 | && ninj sparc64 sparc \ |
504 | && ninj sparc64 sparc \ |
413 | || echo sparc |
505 | || echo sparc |
414 | ;; |
506 | ;; |
|
|
507 | tile*) echo tile;; |
415 | vax*) echo vax;; |
508 | vax*) echo vax;; |
416 | x86_64*freebsd*) echo amd64;; |
509 | x86_64*freebsd*) echo amd64;; |
417 | x86_64*) |
510 | x86_64*) |
418 | # Starting with linux-2.6.24, the 'x86_64' and 'i386' |
511 | # Starting with linux-2.6.24, the 'x86_64' and 'i386' |
419 | # trees have been unified into 'x86'. |
512 | # trees have been unified into 'x86'. |
… | |
… | |
421 | echo x86 |
514 | echo x86 |
422 | else |
515 | else |
423 | ninj x86_64 amd64 |
516 | ninj x86_64 amd64 |
424 | fi |
517 | fi |
425 | ;; |
518 | ;; |
|
|
519 | xtensa*) echo xtensa;; |
426 | |
520 | |
427 | # since our usage of tc-arch is largely concerned with |
521 | # since our usage of tc-arch is largely concerned with |
428 | # normalizing inputs for testing ${CTARGET}, let's filter |
522 | # normalizing inputs for testing ${CTARGET}, let's filter |
429 | # other cross targets (mingw and such) into the unknown. |
523 | # other cross targets (mingw and such) into the unknown. |
430 | *) echo unknown;; |
524 | *) echo unknown;; |
… | |
… | |
459 | i?86*) echo little;; |
553 | i?86*) echo little;; |
460 | ia64*) echo little;; |
554 | ia64*) echo little;; |
461 | m68*) echo big;; |
555 | m68*) echo big;; |
462 | mips*l*) echo little;; |
556 | mips*l*) echo little;; |
463 | mips*) echo big;; |
557 | mips*) echo big;; |
|
|
558 | powerpc*le) echo little;; |
464 | powerpc*) echo big;; |
559 | powerpc*) echo big;; |
465 | s390*) echo big;; |
560 | s390*) echo big;; |
466 | sh*b*) echo big;; |
561 | sh*b*) echo big;; |
467 | sh*) echo little;; |
562 | sh*) echo little;; |
468 | sparc*) echo big;; |
563 | sparc*) echo big;; |
… | |
… | |
561 | |
656 | |
562 | # Returns true if gcc sets relro |
657 | # Returns true if gcc sets relro |
563 | gcc-specs-relro() { |
658 | gcc-specs-relro() { |
564 | local directive |
659 | local directive |
565 | directive=$(gcc-specs-directive link_command) |
660 | directive=$(gcc-specs-directive link_command) |
566 | return $([[ "${directive/\{!norelro:}" != "${directive}" ]]) |
661 | [[ "${directive/\{!norelro:}" != "${directive}" ]] |
567 | } |
662 | } |
568 | # Returns true if gcc sets now |
663 | # Returns true if gcc sets now |
569 | gcc-specs-now() { |
664 | gcc-specs-now() { |
570 | local directive |
665 | local directive |
571 | directive=$(gcc-specs-directive link_command) |
666 | directive=$(gcc-specs-directive link_command) |
572 | return $([[ "${directive/\{!nonow:}" != "${directive}" ]]) |
667 | [[ "${directive/\{!nonow:}" != "${directive}" ]] |
573 | } |
668 | } |
574 | # Returns true if gcc builds PIEs |
669 | # Returns true if gcc builds PIEs |
575 | gcc-specs-pie() { |
670 | gcc-specs-pie() { |
576 | local directive |
671 | local directive |
577 | directive=$(gcc-specs-directive cc1) |
672 | directive=$(gcc-specs-directive cc1) |
578 | return $([[ "${directive/\{!nopie:}" != "${directive}" ]]) |
673 | [[ "${directive/\{!nopie:}" != "${directive}" ]] |
579 | } |
674 | } |
580 | # Returns true if gcc builds with the stack protector |
675 | # Returns true if gcc builds with the stack protector |
581 | gcc-specs-ssp() { |
676 | gcc-specs-ssp() { |
582 | local directive |
677 | local directive |
583 | directive=$(gcc-specs-directive cc1) |
678 | directive=$(gcc-specs-directive cc1) |
584 | return $([[ "${directive/\{!fno-stack-protector:}" != "${directive}" ]]) |
679 | [[ "${directive/\{!fno-stack-protector:}" != "${directive}" ]] |
585 | } |
680 | } |
586 | # Returns true if gcc upgrades fstack-protector to fstack-protector-all |
681 | # Returns true if gcc upgrades fstack-protector to fstack-protector-all |
587 | gcc-specs-ssp-to-all() { |
682 | gcc-specs-ssp-to-all() { |
588 | local directive |
683 | local directive |
589 | directive=$(gcc-specs-directive cc1) |
684 | directive=$(gcc-specs-directive cc1) |
590 | return $([[ "${directive/\{!fno-stack-protector-all:}" != "${directive}" ]]) |
685 | [[ "${directive/\{!fno-stack-protector-all:}" != "${directive}" ]] |
591 | } |
686 | } |
592 | # Returns true if gcc builds with fno-strict-overflow |
687 | # Returns true if gcc builds with fno-strict-overflow |
593 | gcc-specs-nostrict() { |
688 | gcc-specs-nostrict() { |
594 | local directive |
689 | local directive |
595 | directive=$(gcc-specs-directive cc1) |
690 | directive=$(gcc-specs-directive cc1) |
596 | return $([[ "${directive/\{!fstrict-overflow:}" != "${directive}" ]]) |
691 | [[ "${directive/\{!fstrict-overflow:}" != "${directive}" ]] |
|
|
692 | } |
|
|
693 | # Returns true if gcc builds with fstack-check |
|
|
694 | gcc-specs-stack-check() { |
|
|
695 | local directive |
|
|
696 | directive=$(gcc-specs-directive cc1) |
|
|
697 | [[ "${directive/\{!fno-stack-check:}" != "${directive}" ]] |
597 | } |
698 | } |
598 | |
699 | |
599 | |
700 | |
600 | # @FUNCTION: gen_usr_ldscript |
701 | # @FUNCTION: gen_usr_ldscript |
601 | # @USAGE: [-a] <list of libs to create linker scripts for> |
702 | # @USAGE: [-a] <list of libs to create linker scripts for> |
… | |
… | |
634 | dodir /${libdir} |
735 | dodir /${libdir} |
635 | fi |
736 | fi |
636 | |
737 | |
637 | # OUTPUT_FORMAT gives hints to the linker as to what binary format |
738 | # OUTPUT_FORMAT gives hints to the linker as to what binary format |
638 | # is referenced ... makes multilib saner |
739 | # is referenced ... makes multilib saner |
|
|
740 | local flags=( ${CFLAGS} ${LDFLAGS} -Wl,--verbose ) |
|
|
741 | if $(tc-getLD) --version | grep -q 'GNU gold' ; then |
|
|
742 | # If they're using gold, manually invoke the old bfd. #487696 |
|
|
743 | local d="${T}/bfd-linker" |
|
|
744 | mkdir -p "${d}" |
|
|
745 | ln -sf $(which ${CHOST}-ld.bfd) "${d}"/ld |
|
|
746 | flags+=( -B"${d}" ) |
|
|
747 | fi |
639 | output_format=$($(tc-getCC) ${CFLAGS} ${LDFLAGS} -Wl,--verbose 2>&1 | sed -n 's/^OUTPUT_FORMAT("\([^"]*\)",.*/\1/p') |
748 | output_format=$($(tc-getCC) "${flags[@]}" 2>&1 | sed -n 's/^OUTPUT_FORMAT("\([^"]*\)",.*/\1/p') |
640 | [[ -n ${output_format} ]] && output_format="OUTPUT_FORMAT ( ${output_format} )" |
749 | [[ -n ${output_format} ]] && output_format="OUTPUT_FORMAT ( ${output_format} )" |
641 | |
750 | |
642 | for lib in "$@" ; do |
751 | for lib in "$@" ; do |
643 | local tlib |
752 | local tlib |
644 | if ${auto} ; then |
753 | if ${auto} ; then |