blob: 3e71900bcb9ec11b11d374e7eeb26c215660709a [file] [log] [blame]
Manoj Gupta7888b882019-09-18 10:57:50 -07001# Copyright 2002-2019 Gentoo Authors
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -07002# Distributed under the terms of the GNU General Public License v2
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -07003
4# @ECLASS: toolchain-funcs.eclass
5# @MAINTAINER:
6# Toolchain Ninjas <toolchain@gentoo.org>
7# @BLURB: functions to query common info about the toolchain
8# @DESCRIPTION:
9# The toolchain-funcs aims to provide a complete suite of functions
10# for gleaning useful information about the toolchain and to simplify
11# ugly things like cross-compiling and multilib. All of this is done
12# in such a way that you can rely on the function always returning
13# something sane.
14
Yunlian Jiang5fe56222016-04-15 14:33:59 -070015if [[ -z ${_TOOLCHAIN_FUNCS_ECLASS} ]]; then
16_TOOLCHAIN_FUNCS_ECLASS=1
Mike Frysinger13d24b12012-05-22 14:21:36 -040017
Ben Chanc3c0e812018-08-01 11:29:21 -070018inherit multilib flag-o-matic
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -070019
Mike Frysinger13d24b12012-05-22 14:21:36 -040020# tc-getPROG <VAR [search vars]> <default> [tuple]
21_tc-getPROG() {
22 local tuple=$1
23 local v var vars=$2
Yunlian Jiang5ace3942017-04-14 09:54:49 -070024 local prog=( $3 )
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -070025
Mike Frysinger13d24b12012-05-22 14:21:36 -040026 var=${vars%% *}
27 for v in ${vars} ; do
28 if [[ -n ${!v} ]] ; then
29 export ${var}="${!v}"
30 echo "${!v}"
31 return 0
32 fi
33 done
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -070034
35 local search=
Yunlian Jiang5ace3942017-04-14 09:54:49 -070036 [[ -n $4 ]] && search=$(type -p $4-${prog[0]})
37 [[ -z ${search} && -n ${!tuple} ]] && search=$(type -p ${!tuple}-${prog[0]})
38 [[ -n ${search} ]] && prog[0]=${search##*/}
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -070039
Yunlian Jiang5ace3942017-04-14 09:54:49 -070040 export ${var}="${prog[*]}"
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -070041 echo "${!var}"
42}
Yunlian Jiang9fc23462018-04-23 15:15:09 -070043tc-getBUILD_PROG() {
44 local vars="BUILD_$1 $1_FOR_BUILD HOST$1"
45 # respect host vars if not cross-compiling
46 # https://bugs.gentoo.org/630282
47 tc-is-cross-compiler || vars+=" $1"
48 _tc-getPROG CBUILD "${vars}" "${@:2}"
49}
Mike Frysinger13d24b12012-05-22 14:21:36 -040050tc-getPROG() { _tc-getPROG CHOST "$@"; }
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -070051
52# @FUNCTION: tc-getAR
53# @USAGE: [toolchain prefix]
54# @RETURN: name of the archiver
55tc-getAR() { tc-getPROG AR ar "$@"; }
56# @FUNCTION: tc-getAS
57# @USAGE: [toolchain prefix]
58# @RETURN: name of the assembler
59tc-getAS() { tc-getPROG AS as "$@"; }
60# @FUNCTION: tc-getCC
61# @USAGE: [toolchain prefix]
62# @RETURN: name of the C compiler
63tc-getCC() { tc-getPROG CC gcc "$@"; }
64# @FUNCTION: tc-getCPP
65# @USAGE: [toolchain prefix]
66# @RETURN: name of the C preprocessor
Yunlian Jiang5ace3942017-04-14 09:54:49 -070067tc-getCPP() { tc-getPROG CPP "${CC:-gcc} -E" "$@"; }
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -070068# @FUNCTION: tc-getCXX
69# @USAGE: [toolchain prefix]
70# @RETURN: name of the C++ compiler
71tc-getCXX() { tc-getPROG CXX g++ "$@"; }
72# @FUNCTION: tc-getLD
73# @USAGE: [toolchain prefix]
74# @RETURN: name of the linker
75tc-getLD() { tc-getPROG LD ld "$@"; }
Manoj Guptaf45846e2020-06-30 10:36:15 -070076# @FUNCTION: tc-getSTRINGS
77# @USAGE: [toolchain prefix]
78# @RETURN: name of the strings program
79tc-getSTRINGS() { tc-getPROG STRINGS strings "$@"; }
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -070080# @FUNCTION: tc-getSTRIP
81# @USAGE: [toolchain prefix]
82# @RETURN: name of the strip program
83tc-getSTRIP() { tc-getPROG STRIP strip "$@"; }
84# @FUNCTION: tc-getNM
85# @USAGE: [toolchain prefix]
86# @RETURN: name of the symbol/object thingy
87tc-getNM() { tc-getPROG NM nm "$@"; }
88# @FUNCTION: tc-getRANLIB
89# @USAGE: [toolchain prefix]
Manoj Guptaf45846e2020-06-30 10:36:15 -070090# @RETURN: name of the archive indexer
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -070091tc-getRANLIB() { tc-getPROG RANLIB ranlib "$@"; }
Manoj Guptaf45846e2020-06-30 10:36:15 -070092# @FUNCTION: tc-getREADELF
93# @USAGE: [toolchain prefix]
94# @RETURN: name of the ELF reader
95tc-getREADELF() { tc-getPROG READELF readelf "$@"; }
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -070096# @FUNCTION: tc-getOBJCOPY
97# @USAGE: [toolchain prefix]
98# @RETURN: name of the object copier
99tc-getOBJCOPY() { tc-getPROG OBJCOPY objcopy "$@"; }
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700100# @FUNCTION: tc-getOBJDUMP
101# @USAGE: [toolchain prefix]
102# @RETURN: name of the object dumper
103tc-getOBJDUMP() { tc-getPROG OBJDUMP objdump "$@"; }
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700104# @FUNCTION: tc-getF77
105# @USAGE: [toolchain prefix]
106# @RETURN: name of the Fortran 77 compiler
Mike Frysinger13d24b12012-05-22 14:21:36 -0400107tc-getF77() { tc-getPROG F77 gfortran "$@"; }
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700108# @FUNCTION: tc-getFC
109# @USAGE: [toolchain prefix]
110# @RETURN: name of the Fortran 90 compiler
111tc-getFC() { tc-getPROG FC gfortran "$@"; }
112# @FUNCTION: tc-getGCJ
113# @USAGE: [toolchain prefix]
114# @RETURN: name of the java compiler
115tc-getGCJ() { tc-getPROG GCJ gcj "$@"; }
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700116# @FUNCTION: tc-getGO
117# @USAGE: [toolchain prefix]
118# @RETURN: name of the Go compiler
119tc-getGO() { tc-getPROG GO go "$@"; }
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700120# @FUNCTION: tc-getPKG_CONFIG
121# @USAGE: [toolchain prefix]
122# @RETURN: name of the pkg-config tool
123tc-getPKG_CONFIG() { tc-getPROG PKG_CONFIG pkg-config "$@"; }
Mike Frysinger13d24b12012-05-22 14:21:36 -0400124# @FUNCTION: tc-getRC
125# @USAGE: [toolchain prefix]
126# @RETURN: name of the Windows resource compiler
127tc-getRC() { tc-getPROG RC windres "$@"; }
128# @FUNCTION: tc-getDLLWRAP
129# @USAGE: [toolchain prefix]
130# @RETURN: name of the Windows dllwrap utility
131tc-getDLLWRAP() { tc-getPROG DLLWRAP dllwrap "$@"; }
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700132
Mike Frysinger13d24b12012-05-22 14:21:36 -0400133# @FUNCTION: tc-getBUILD_AR
134# @USAGE: [toolchain prefix]
135# @RETURN: name of the archiver for building binaries to run on the build machine
136tc-getBUILD_AR() { tc-getBUILD_PROG AR ar "$@"; }
137# @FUNCTION: tc-getBUILD_AS
138# @USAGE: [toolchain prefix]
139# @RETURN: name of the assembler for building binaries to run on the build machine
140tc-getBUILD_AS() { tc-getBUILD_PROG AS as "$@"; }
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700141# @FUNCTION: tc-getBUILD_CC
142# @USAGE: [toolchain prefix]
143# @RETURN: name of the C compiler for building binaries to run on the build machine
Mike Frysinger13d24b12012-05-22 14:21:36 -0400144tc-getBUILD_CC() { tc-getBUILD_PROG CC gcc "$@"; }
145# @FUNCTION: tc-getBUILD_CPP
146# @USAGE: [toolchain prefix]
147# @RETURN: name of the C preprocessor for building binaries to run on the build machine
Yunlian Jiang5ace3942017-04-14 09:54:49 -0700148tc-getBUILD_CPP() { tc-getBUILD_PROG CPP "$(tc-getBUILD_CC) -E" "$@"; }
Mike Frysinger13d24b12012-05-22 14:21:36 -0400149# @FUNCTION: tc-getBUILD_CXX
150# @USAGE: [toolchain prefix]
151# @RETURN: name of the C++ compiler for building binaries to run on the build machine
152tc-getBUILD_CXX() { tc-getBUILD_PROG CXX g++ "$@"; }
153# @FUNCTION: tc-getBUILD_LD
154# @USAGE: [toolchain prefix]
155# @RETURN: name of the linker for building binaries to run on the build machine
156tc-getBUILD_LD() { tc-getBUILD_PROG LD ld "$@"; }
Manoj Guptaf45846e2020-06-30 10:36:15 -0700157# @FUNCTION: tc-getBUILD_STRINGS
158# @USAGE: [toolchain prefix]
159# @RETURN: name of the strings program for building binaries to run on the build machine
160tc-getBUILD_STRINGS() { tc-getBUILD_PROG STRINGS strings "$@"; }
Mike Frysinger13d24b12012-05-22 14:21:36 -0400161# @FUNCTION: tc-getBUILD_STRIP
162# @USAGE: [toolchain prefix]
163# @RETURN: name of the strip program for building binaries to run on the build machine
164tc-getBUILD_STRIP() { tc-getBUILD_PROG STRIP strip "$@"; }
165# @FUNCTION: tc-getBUILD_NM
166# @USAGE: [toolchain prefix]
167# @RETURN: name of the symbol/object thingy for building binaries to run on the build machine
168tc-getBUILD_NM() { tc-getBUILD_PROG NM nm "$@"; }
169# @FUNCTION: tc-getBUILD_RANLIB
170# @USAGE: [toolchain prefix]
Manoj Guptaf45846e2020-06-30 10:36:15 -0700171# @RETURN: name of the archive indexer for building binaries to run on the build machine
Mike Frysinger13d24b12012-05-22 14:21:36 -0400172tc-getBUILD_RANLIB() { tc-getBUILD_PROG RANLIB ranlib "$@"; }
Manoj Guptaf45846e2020-06-30 10:36:15 -0700173# @FUNCTION: tc-getBUILD_READELF
174# @USAGE: [toolchain prefix]
175# @RETURN: name of the ELF reader for building binaries to run on the build machine
176tc-getBUILD_READELF() { tc-getBUILD_PROG READELF readelf "$@"; }
Mike Frysinger13d24b12012-05-22 14:21:36 -0400177# @FUNCTION: tc-getBUILD_OBJCOPY
178# @USAGE: [toolchain prefix]
179# @RETURN: name of the object copier for building binaries to run on the build machine
180tc-getBUILD_OBJCOPY() { tc-getBUILD_PROG OBJCOPY objcopy "$@"; }
181# @FUNCTION: tc-getBUILD_PKG_CONFIG
182# @USAGE: [toolchain prefix]
183# @RETURN: name of the pkg-config tool for building binaries to run on the build machine
184tc-getBUILD_PKG_CONFIG() { tc-getBUILD_PROG PKG_CONFIG pkg-config "$@"; }
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700185
Manoj Gupta7888b882019-09-18 10:57:50 -0700186# @FUNCTION: tc-getTARGET_CPP
187# @USAGE: [toolchain prefix]
188# @RETURN: name of the C preprocessor for the toolchain being built (or used)
189tc-getTARGET_CPP() {
190 if [[ -n ${CTARGET} ]]; then
191 _tc-getPROG CTARGET TARGET_CPP "gcc -E" "$@"
192 else
193 tc-getCPP "$@"
194 fi
195}
196
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700197# @FUNCTION: tc-export
198# @USAGE: <list of toolchain variables>
199# @DESCRIPTION:
200# Quick way to export a bunch of compiler vars at once.
201tc-export() {
202 local var
203 for var in "$@" ; do
Yunlian Jiang5ace3942017-04-14 09:54:49 -0700204 [[ $(type -t "tc-get${var}") != "function" ]] && die "tc-export: invalid export variable '${var}'"
205 "tc-get${var}" > /dev/null
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700206 done
207}
208
209# @FUNCTION: tc-is-cross-compiler
210# @RETURN: Shell true if we are using a cross-compiler, shell false otherwise
211tc-is-cross-compiler() {
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700212 [[ ${CBUILD:-${CHOST}} != ${CHOST} ]]
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700213}
214
Manoj Gupta7888b882019-09-18 10:57:50 -0700215# @FUNCTION: tc-cpp-is-true
216# @USAGE: <condition> [cpp flags]
217# @RETURN: Shell true if the condition is true, shell false otherwise.
218# @DESCRIPTION:
219# Evaluate the given condition using the C preprocessor for CTARGET, if
220# defined, or CHOST. Additional arguments are passed through to the cpp
221# command. A typical condition would be in the form defined(__FOO__).
222tc-cpp-is-true() {
223 local CONDITION=${1}
224 shift
225
Manoj Guptaf45846e2020-06-30 10:36:15 -0700226 $(tc-getTARGET_CPP) "${@}" -P - <<-EOF >/dev/null 2>&1
227 #if ${CONDITION}
228 true
229 #else
230 #error false
231 #endif
232 EOF
Manoj Gupta7888b882019-09-18 10:57:50 -0700233}
234
235# @FUNCTION: tc-detect-is-softfloat
236# @RETURN: Shell true if detection was possible, shell false otherwise
237# @DESCRIPTION:
238# Detect whether the CTARGET (or CHOST) toolchain is a softfloat based
239# one by examining the toolchain's output, if possible. Outputs a value
240# alike tc-is-softfloat if detection was possible.
241tc-detect-is-softfloat() {
242 # If fetching CPP falls back to the default (gcc -E) then fail
243 # detection as this may not be the correct toolchain.
244 [[ $(tc-getTARGET_CPP) == "gcc -E" ]] && return 1
245
246 case ${CTARGET:-${CHOST}} in
247 # Avoid autodetection for bare-metal targets. bug #666896
248 *-newlib|*-elf|*-eabi)
249 return 1 ;;
250
251 # arm-unknown-linux-gnueabi is ambiguous. We used to treat it as
252 # hardfloat but we now treat it as softfloat like most everyone
253 # else. Check existing toolchains to respect existing systems.
254 arm*)
255 if tc-cpp-is-true "defined(__ARM_PCS_VFP)"; then
256 echo "no"
257 else
258 # Confusingly __SOFTFP__ is defined only when
259 # -mfloat-abi is soft, not softfp.
260 if tc-cpp-is-true "defined(__SOFTFP__)"; then
261 echo "yes"
262 else
263 echo "softfp"
264 fi
265 fi
266
267 return 0 ;;
268 *)
269 return 1 ;;
270 esac
271}
272
273# @FUNCTION: tc-tuple-is-softfloat
274# @RETURN: See tc-is-softfloat for the possible values.
275# @DESCRIPTION:
276# Determine whether the CTARGET (or CHOST) toolchain is a softfloat
277# based one solely from the tuple.
278tc-tuple-is-softfloat() {
279 local CTARGET=${CTARGET:-${CHOST}}
280 case ${CTARGET//_/-} in
281 bfin*|h8300*)
282 echo "only" ;;
283 *-softfloat-*)
284 echo "yes" ;;
285 *-softfp-*)
286 echo "softfp" ;;
287 arm*-hardfloat-*|arm*eabihf)
288 echo "no" ;;
289 # bare-metal targets have their defaults. bug #666896
290 *-newlib|*-elf|*-eabi)
291 echo "no" ;;
292 arm*)
293 echo "yes" ;;
294 *)
295 echo "no" ;;
296 esac
297}
298
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700299# @FUNCTION: tc-is-softfloat
300# @DESCRIPTION:
301# See if this toolchain is a softfloat based one.
302# @CODE
303# The possible return values:
Mike Frysinger1c599582013-01-27 23:38:22 -0500304# - only: the target is always softfloat (never had fpu)
305# - yes: the target should support softfloat
306# - softfp: (arm specific) the target should use hardfloat insns, but softfloat calling convention
307# - no: the target doesn't support softfloat
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700308# @CODE
309# This allows us to react differently where packages accept
310# softfloat flags in the case where support is optional, but
311# rejects softfloat flags where the target always lacks an fpu.
312tc-is-softfloat() {
Manoj Gupta7888b882019-09-18 10:57:50 -0700313 tc-detect-is-softfloat || tc-tuple-is-softfloat
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700314}
315
316# @FUNCTION: tc-is-static-only
317# @DESCRIPTION:
318# Return shell true if the target does not support shared libs, shell false
319# otherwise.
320tc-is-static-only() {
321 local host=${CTARGET:-${CHOST}}
322
323 # *MiNT doesn't have shared libraries, only platform so far
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700324 [[ ${host} == *-mint* ]]
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700325}
326
Yunlian Jiang5ace3942017-04-14 09:54:49 -0700327# @FUNCTION: tc-stack-grows-down
328# @DESCRIPTION:
329# Return shell true if the stack grows down. This is the default behavior
330# for the vast majority of systems out there and usually projects shouldn't
331# care about such internal details.
332tc-stack-grows-down() {
333 # List the few that grow up.
334 case ${ARCH} in
335 hppa|metag) return 1 ;;
336 esac
337
338 # Assume all others grow down.
339 return 0
340}
341
Mike Frysinger1c599582013-01-27 23:38:22 -0500342# @FUNCTION: tc-export_build_env
343# @USAGE: [compiler variables]
344# @DESCRIPTION:
345# Export common build related compiler settings.
346tc-export_build_env() {
347 tc-export "$@"
Raul E Rangelb8215262018-05-01 12:40:30 -0600348 if tc-is-cross-compiler; then
349 # Some build envs will initialize vars like:
350 # : ${BUILD_LDFLAGS:-${LDFLAGS}}
351 # So make sure all variables are non-empty. #526734
352 : ${BUILD_CFLAGS:=-O1 -pipe}
353 : ${BUILD_CXXFLAGS:=-O1 -pipe}
354 : ${BUILD_CPPFLAGS:= }
355 : ${BUILD_LDFLAGS:= }
356 else
357 # https://bugs.gentoo.org/654424
Manoj Gupta7888b882019-09-18 10:57:50 -0700358 : ${BUILD_CFLAGS:=${CFLAGS}}
359 : ${BUILD_CXXFLAGS:=${CXXFLAGS}}
360 : ${BUILD_CPPFLAGS:=${CPPFLAGS}}
361 : ${BUILD_LDFLAGS:=${LDFLAGS}}
Raul E Rangelb8215262018-05-01 12:40:30 -0600362 fi
Mike Frysinger1c599582013-01-27 23:38:22 -0500363 export BUILD_{C,CXX,CPP,LD}FLAGS
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700364
365 # Some packages use XXX_FOR_BUILD.
366 local v
367 for v in BUILD_{C,CXX,CPP,LD}FLAGS ; do
368 export ${v#BUILD_}_FOR_BUILD="${!v}"
369 done
Mike Frysinger1c599582013-01-27 23:38:22 -0500370}
371
Mike Frysinger13d24b12012-05-22 14:21:36 -0400372# @FUNCTION: tc-env_build
373# @USAGE: <command> [command args]
374# @INTERNAL
375# @DESCRIPTION:
376# Setup the compile environment to the build tools and then execute the
377# specified command. We use tc-getBUILD_XX here so that we work with
378# all of the semi-[non-]standard env vars like $BUILD_CC which often
379# the target build system does not check.
380tc-env_build() {
Mike Frysinger1c599582013-01-27 23:38:22 -0500381 tc-export_build_env
382 CFLAGS=${BUILD_CFLAGS} \
383 CXXFLAGS=${BUILD_CXXFLAGS} \
Mike Frysinger13d24b12012-05-22 14:21:36 -0400384 CPPFLAGS=${BUILD_CPPFLAGS} \
385 LDFLAGS=${BUILD_LDFLAGS} \
386 AR=$(tc-getBUILD_AR) \
387 AS=$(tc-getBUILD_AS) \
388 CC=$(tc-getBUILD_CC) \
389 CPP=$(tc-getBUILD_CPP) \
390 CXX=$(tc-getBUILD_CXX) \
391 LD=$(tc-getBUILD_LD) \
392 NM=$(tc-getBUILD_NM) \
393 PKG_CONFIG=$(tc-getBUILD_PKG_CONFIG) \
394 RANLIB=$(tc-getBUILD_RANLIB) \
Manoj Guptaf45846e2020-06-30 10:36:15 -0700395 READELF=$(tc-getBUILD_READELF) \
Mike Frysinger13d24b12012-05-22 14:21:36 -0400396 "$@"
397}
398
399# @FUNCTION: econf_build
400# @USAGE: [econf flags]
401# @DESCRIPTION:
402# Sometimes we need to locally build up some tools to run on CBUILD because
403# the package has helper utils which are compiled+executed when compiling.
404# This won't work when cross-compiling as the CHOST is set to a target which
405# we cannot natively execute.
406#
407# For example, the python package will build up a local python binary using
408# a portable build system (configure+make), but then use that binary to run
409# local python scripts to build up other components of the overall python.
410# We cannot rely on the python binary in $PATH as that often times will be
411# a different version, or not even installed in the first place. Instead,
412# we compile the code in a different directory to run on CBUILD, and then
413# use that binary when compiling the main package to run on CHOST.
414#
415# For example, with newer EAPIs, you'd do something like:
416# @CODE
417# src_configure() {
418# ECONF_SOURCE=${S}
419# if tc-is-cross-compiler ; then
420# mkdir "${WORKDIR}"/${CBUILD}
421# pushd "${WORKDIR}"/${CBUILD} >/dev/null
422# econf_build --disable-some-unused-stuff
423# popd >/dev/null
424# fi
425# ... normal build paths ...
426# }
427# src_compile() {
428# if tc-is-cross-compiler ; then
429# pushd "${WORKDIR}"/${CBUILD} >/dev/null
430# emake one-or-two-build-tools
431# ln/mv build-tools to normal build paths in ${S}/
432# popd >/dev/null
433# fi
434# ... normal build paths ...
435# }
436# @CODE
437econf_build() {
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700438 local CBUILD=${CBUILD:-${CHOST}}
439 tc-env_build econf --build=${CBUILD} --host=${CBUILD} "$@"
440}
441
442# @FUNCTION: tc-ld-is-gold
443# @USAGE: [toolchain prefix]
444# @DESCRIPTION:
445# Return true if the current linker is set to gold.
446tc-ld-is-gold() {
447 local out
448
449 # First check the linker directly.
450 out=$($(tc-getLD "$@") --version 2>&1)
451 if [[ ${out} == *"GNU gold"* ]] ; then
452 return 0
453 fi
454
455 # Then see if they're selecting gold via compiler flags.
456 # Note: We're assuming they're using LDFLAGS to hold the
457 # options and not CFLAGS/CXXFLAGS.
458 local base="${T}/test-tc-gold"
459 cat <<-EOF > "${base}.c"
460 int main() { return 0; }
461 EOF
462 out=$($(tc-getCC "$@") ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} -Wl,--version "${base}.c" -o "${base}" 2>&1)
463 rm -f "${base}"*
464 if [[ ${out} == *"GNU gold"* ]] ; then
465 return 0
466 fi
467
468 # No gold here!
469 return 1
470}
471
Manoj Gupta94ae3262019-09-10 14:11:46 -0700472# @FUNCTION: tc-ld-is-lld
473# @USAGE: [toolchain prefix]
474# @DESCRIPTION:
475# Return true if the current linker is set to lld.
476tc-ld-is-lld() {
477 local out
478
479 # First check the linker directly.
480 out=$($(tc-getLD "$@") --version 2>&1)
481 if [[ ${out} == *"LLD"* ]] ; then
482 return 0
483 fi
484
485 # Then see if they're selecting lld via compiler flags.
486 # Note: We're assuming they're using LDFLAGS to hold the
487 # options and not CFLAGS/CXXFLAGS.
488 local base="${T}/test-tc-lld"
489 cat <<-EOF > "${base}.c"
490 int main() { return 0; }
491 EOF
492 out=$($(tc-getCC "$@") ${CFLAGS} ${CPPFLAGS} ${LDFLAGS} -Wl,--version "${base}.c" -o "${base}" 2>&1)
493 rm -f "${base}"*
494 if [[ ${out} == *"LLD"* ]] ; then
495 return 0
496 fi
497
498 # No lld here!
499 return 1
500}
501
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700502# @FUNCTION: tc-ld-disable-gold
503# @USAGE: [toolchain prefix]
504# @DESCRIPTION:
505# If the gold linker is currently selected, configure the compilation
506# settings so that we use the older bfd linker instead.
507tc-ld-disable-gold() {
508 if ! tc-ld-is-gold "$@" ; then
509 # They aren't using gold, so nothing to do!
510 return
511 fi
512
513 ewarn "Forcing usage of the BFD linker instead of GOLD"
514
515 # Set up LD to point directly to bfd if it's available.
516 # We need to extract the first word in case there are flags appended
517 # to its value (like multilib). #545218
518 local ld=$(tc-getLD "$@")
519 local bfd_ld="${ld%% *}.bfd"
520 local path_ld=$(which "${bfd_ld}" 2>/dev/null)
521 [[ -e ${path_ld} ]] && export LD=${bfd_ld}
522
Rahul Chaudhryed0ea942018-05-04 14:13:05 -0700523 # Set up LDFLAGS to select gold based on the gcc / clang version.
524 local fallback="true"
525 if tc-is-gcc; then
526 local major=$(gcc-major-version "$@")
527 local minor=$(gcc-minor-version "$@")
528 if [[ ${major} -gt 4 ]] || [[ ${major} -eq 4 && ${minor} -ge 8 ]]; then
529 # gcc-4.8+ supports -fuse-ld directly.
530 export LDFLAGS="${LDFLAGS} -fuse-ld=bfd"
531 fallback="false"
532 fi
533 elif tc-is-clang; then
534 local major=$(clang-major-version "$@")
535 local minor=$(clang-minor-version "$@")
536 if [[ ${major} -gt 3 ]] || [[ ${major} -eq 3 && ${minor} -ge 5 ]]; then
537 # clang-3.5+ supports -fuse-ld directly.
538 export LDFLAGS="${LDFLAGS} -fuse-ld=bfd"
539 fallback="false"
540 fi
541 fi
542 if [[ ${fallback} == "true" ]] ; then
543 # <=gcc-4.7 and <=clang-3.4 require some coercion.
544 # Only works if bfd exists.
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700545 if [[ -e ${path_ld} ]] ; then
546 local d="${T}/bfd-linker"
547 mkdir -p "${d}"
548 ln -sf "${path_ld}" "${d}"/ld
549 export LDFLAGS="${LDFLAGS} -B${d}"
550 else
551 die "unable to locate a BFD linker to bypass gold"
552 fi
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700553 fi
Mike Frysinger13d24b12012-05-22 14:21:36 -0400554}
555
556# @FUNCTION: tc-has-openmp
557# @USAGE: [toolchain prefix]
558# @DESCRIPTION:
559# See if the toolchain supports OpenMP.
560tc-has-openmp() {
561 local base="${T}/test-tc-openmp"
562 cat <<-EOF > "${base}.c"
563 #include <omp.h>
564 int main() {
565 int nthreads, tid, ret = 0;
566 #pragma omp parallel private(nthreads, tid)
567 {
568 tid = omp_get_thread_num();
569 nthreads = omp_get_num_threads(); ret += tid + nthreads;
570 }
571 return ret;
572 }
573 EOF
574 $(tc-getCC "$@") -fopenmp "${base}.c" -o "${base}" >&/dev/null
575 local ret=$?
576 rm -f "${base}"*
577 return ${ret}
578}
579
Yunlian Jiang5ace3942017-04-14 09:54:49 -0700580# @FUNCTION: tc-check-openmp
581# @DESCRIPTION:
582# Test for OpenMP support with the current compiler and error out with
583# a clear error message, telling the user how to rectify the missing
584# OpenMP support that has been requested by the ebuild. Using this function
585# to test for OpenMP support should be preferred over tc-has-openmp and
586# printing a custom message, as it presents a uniform interface to the user.
587tc-check-openmp() {
588 if ! tc-has-openmp; then
589 eerror "Your current compiler does not support OpenMP!"
590
591 if tc-is-gcc; then
592 eerror "Enable OpenMP support by building sys-devel/gcc with USE=\"openmp\"."
593 elif tc-is-clang; then
594 eerror "OpenMP support in sys-devel/clang is provided by sys-libs/libomp."
595 fi
596
597 die "Active compiler does not have required support for OpenMP"
598 fi
599}
600
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700601# @FUNCTION: tc-has-tls
602# @USAGE: [-s|-c|-l] [toolchain prefix]
603# @DESCRIPTION:
604# See if the toolchain supports thread local storage (TLS). Use -s to test the
605# compiler, -c to also test the assembler, and -l to also test the C library
606# (the default).
607tc-has-tls() {
608 local base="${T}/test-tc-tls"
609 cat <<-EOF > "${base}.c"
610 int foo(int *i) {
611 static __thread int j = 0;
612 return *i ? j : *i;
613 }
614 EOF
615 local flags
616 case $1 in
617 -s) flags="-S";;
618 -c) flags="-c";;
619 -l) ;;
620 -*) die "Usage: tc-has-tls [-c|-l] [toolchain prefix]";;
621 esac
622 : ${flags:=-fPIC -shared -Wl,-z,defs}
623 [[ $1 == -* ]] && shift
624 $(tc-getCC "$@") ${flags} "${base}.c" -o "${base}" >&/dev/null
625 local ret=$?
626 rm -f "${base}"*
627 return ${ret}
628}
629
630
631# Parse information from CBUILD/CHOST/CTARGET rather than
632# use external variables from the profile.
633tc-ninja_magic_to_arch() {
634ninj() { [[ ${type} == "kern" ]] && echo $1 || echo $2 ; }
635
636 local type=$1
637 local host=$2
638 [[ -z ${host} ]] && host=${CTARGET:-${CHOST}}
639
640 case ${host} in
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700641 aarch64*) echo arm64;;
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700642 alpha*) echo alpha;;
643 arm*) echo arm;;
644 avr*) ninj avr32 avr;;
645 bfin*) ninj blackfin bfin;;
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700646 c6x*) echo c6x;;
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700647 cris*) echo cris;;
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700648 frv*) echo frv;;
649 hexagon*) echo hexagon;;
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700650 hppa*) ninj parisc hppa;;
651 i?86*)
652 # Starting with linux-2.6.24, the 'x86_64' and 'i386'
653 # trees have been unified into 'x86'.
654 # FreeBSD still uses i386
Yunlian Jiang5ace3942017-04-14 09:54:49 -0700655 if [[ ${type} == "kern" && ${host} == *freebsd* ]] ; then
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700656 echo i386
657 else
658 echo x86
659 fi
660 ;;
661 ia64*) echo ia64;;
662 m68*) echo m68k;;
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700663 metag*) echo metag;;
664 microblaze*) echo microblaze;;
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700665 mips*) echo mips;;
666 nios2*) echo nios2;;
667 nios*) echo nios;;
Yunlian Jiang5ace3942017-04-14 09:54:49 -0700668 or1k|or32*) echo openrisc;;
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700669 powerpc*)
Mike Frysinger13d24b12012-05-22 14:21:36 -0400670 # Starting with linux-2.6.15, the 'ppc' and 'ppc64' trees
671 # have been unified into simply 'powerpc', but until 2.6.16,
672 # ppc32 is still using ARCH="ppc" as default
Yunlian Jiang5ace3942017-04-14 09:54:49 -0700673 if [[ ${type} == "kern" ]] ; then
Mike Frysinger13d24b12012-05-22 14:21:36 -0400674 echo powerpc
Mike Frysinger13d24b12012-05-22 14:21:36 -0400675 elif [[ ${host} == powerpc64* ]] ; then
676 echo ppc64
Mike Frysinger13d24b12012-05-22 14:21:36 -0400677 else
678 echo ppc
679 fi
680 ;;
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700681 riscv*) echo riscv;;
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700682 s390*) echo s390;;
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700683 score*) echo score;;
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700684 sh64*) ninj sh64 sh;;
685 sh*) echo sh;;
686 sparc64*) ninj sparc64 sparc;;
687 sparc*) [[ ${PROFILE_ARCH} == "sparc64" ]] \
688 && ninj sparc64 sparc \
689 || echo sparc
690 ;;
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700691 tile*) echo tile;;
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700692 vax*) echo vax;;
Mike Frysinger13d24b12012-05-22 14:21:36 -0400693 x86_64*freebsd*) echo amd64;;
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700694 x86_64*)
695 # Starting with linux-2.6.24, the 'x86_64' and 'i386'
696 # trees have been unified into 'x86'.
Yunlian Jiang5ace3942017-04-14 09:54:49 -0700697 if [[ ${type} == "kern" ]] ; then
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700698 echo x86
699 else
Yunlian Jiang5ace3942017-04-14 09:54:49 -0700700 echo amd64
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700701 fi
702 ;;
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700703 xtensa*) echo xtensa;;
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700704
705 # since our usage of tc-arch is largely concerned with
706 # normalizing inputs for testing ${CTARGET}, let's filter
707 # other cross targets (mingw and such) into the unknown.
708 *) echo unknown;;
709 esac
710}
711# @FUNCTION: tc-arch-kernel
712# @USAGE: [toolchain prefix]
713# @RETURN: name of the kernel arch according to the compiler target
714tc-arch-kernel() {
715 tc-ninja_magic_to_arch kern "$@"
716}
717# @FUNCTION: tc-arch
718# @USAGE: [toolchain prefix]
719# @RETURN: name of the portage arch according to the compiler target
720tc-arch() {
721 tc-ninja_magic_to_arch portage "$@"
722}
723
724tc-endian() {
725 local host=$1
726 [[ -z ${host} ]] && host=${CTARGET:-${CHOST}}
727 host=${host%%-*}
728
729 case ${host} in
Mike Frysinger1c599582013-01-27 23:38:22 -0500730 aarch64*be) echo big;;
731 aarch64) echo little;;
Yunlian Jiang9fc23462018-04-23 15:15:09 -0700732 alpha*) echo little;;
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700733 arm*b*) echo big;;
734 arm*) echo little;;
735 cris*) echo little;;
736 hppa*) echo big;;
737 i?86*) echo little;;
738 ia64*) echo little;;
739 m68*) echo big;;
740 mips*l*) echo little;;
741 mips*) echo big;;
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700742 powerpc*le) echo little;;
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700743 powerpc*) echo big;;
Manoj Gupta7888b882019-09-18 10:57:50 -0700744 riscv*) echo little;;
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700745 s390*) echo big;;
746 sh*b*) echo big;;
747 sh*) echo little;;
748 sparc*) echo big;;
749 x86_64*) echo little;;
750 *) echo wtf;;
751 esac
752}
753
Yunlian Jiang5ace3942017-04-14 09:54:49 -0700754# @FUNCTION: tc-get-compiler-type
755# @RETURN: keyword identifying the compiler: gcc, clang, pathcc, unknown
756tc-get-compiler-type() {
757 local code='
758#if defined(__PATHSCALE__)
759 HAVE_PATHCC
760#elif defined(__clang__)
761 HAVE_CLANG
762#elif defined(__GNUC__)
763 HAVE_GCC
764#endif
765'
766 local res=$($(tc-getCPP "$@") -E -P - <<<"${code}")
767
768 case ${res} in
769 *HAVE_PATHCC*) echo pathcc;;
770 *HAVE_CLANG*) echo clang;;
771 *HAVE_GCC*) echo gcc;;
772 *) echo unknown;;
773 esac
774}
775
776# @FUNCTION: tc-is-gcc
777# @RETURN: Shell true if the current compiler is GCC, false otherwise.
778tc-is-gcc() {
779 [[ $(tc-get-compiler-type) == gcc ]]
780}
781
782# @FUNCTION: tc-is-clang
783# @RETURN: Shell true if the current compiler is clang, false otherwise.
784tc-is-clang() {
785 [[ $(tc-get-compiler-type) == clang ]]
786}
787
Mike Frysinger13d24b12012-05-22 14:21:36 -0400788# Internal func. The first argument is the version info to expand.
789# Query the preprocessor to improve compatibility across different
790# compilers rather than maintaining a --version flag matrix. #335943
791_gcc_fullversion() {
792 local ver="$1"; shift
Yunlian Jiang5ace3942017-04-14 09:54:49 -0700793 set -- $($(tc-getCPP "$@") -E -P - <<<"__GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__")
Mike Frysinger13d24b12012-05-22 14:21:36 -0400794 eval echo "$ver"
795}
796
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700797# @FUNCTION: gcc-fullversion
798# @RETURN: compiler version (major.minor.micro: [3.4.6])
799gcc-fullversion() {
Mike Frysinger13d24b12012-05-22 14:21:36 -0400800 _gcc_fullversion '$1.$2.$3' "$@"
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700801}
802# @FUNCTION: gcc-version
803# @RETURN: compiler version (major.minor: [3.4].6)
804gcc-version() {
Mike Frysinger13d24b12012-05-22 14:21:36 -0400805 _gcc_fullversion '$1.$2' "$@"
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700806}
807# @FUNCTION: gcc-major-version
808# @RETURN: major compiler version (major: [3].4.6)
809gcc-major-version() {
Mike Frysinger13d24b12012-05-22 14:21:36 -0400810 _gcc_fullversion '$1' "$@"
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700811}
812# @FUNCTION: gcc-minor-version
813# @RETURN: minor compiler version (minor: 3.[4].6)
814gcc-minor-version() {
Mike Frysinger13d24b12012-05-22 14:21:36 -0400815 _gcc_fullversion '$2' "$@"
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700816}
817# @FUNCTION: gcc-micro-version
818# @RETURN: micro compiler version (micro: 3.4.[6])
819gcc-micro-version() {
Mike Frysinger13d24b12012-05-22 14:21:36 -0400820 _gcc_fullversion '$3' "$@"
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700821}
822
Yunlian Jiang5ace3942017-04-14 09:54:49 -0700823# Internal func. Based on _gcc_fullversion() above.
824_clang_fullversion() {
825 local ver="$1"; shift
826 set -- $($(tc-getCPP "$@") -E -P - <<<"__clang_major__ __clang_minor__ __clang_patchlevel__")
827 eval echo "$ver"
828}
829
830# @FUNCTION: clang-fullversion
831# @RETURN: compiler version (major.minor.micro: [3.4.6])
832clang-fullversion() {
833 _clang_fullversion '$1.$2.$3' "$@"
834}
835# @FUNCTION: clang-version
836# @RETURN: compiler version (major.minor: [3.4].6)
837clang-version() {
838 _clang_fullversion '$1.$2' "$@"
839}
840# @FUNCTION: clang-major-version
841# @RETURN: major compiler version (major: [3].4.6)
842clang-major-version() {
843 _clang_fullversion '$1' "$@"
844}
845# @FUNCTION: clang-minor-version
846# @RETURN: minor compiler version (minor: 3.[4].6)
847clang-minor-version() {
848 _clang_fullversion '$2' "$@"
849}
850# @FUNCTION: clang-micro-version
851# @RETURN: micro compiler version (micro: 3.4.[6])
852clang-micro-version() {
853 _clang_fullversion '$3' "$@"
854}
855
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700856# Returns the installation directory - internal toolchain
857# function for use by _gcc-specs-exists (for flag-o-matic).
858_gcc-install-dir() {
859 echo "$(LC_ALL=C $(tc-getCC) -print-search-dirs 2> /dev/null |\
860 awk '$1=="install:" {print $2}')"
861}
862# Returns true if the indicated specs file exists - internal toolchain
863# function for use by flag-o-matic.
864_gcc-specs-exists() {
865 [[ -f $(_gcc-install-dir)/$1 ]]
866}
867
868# Returns requested gcc specs directive unprocessed - for used by
869# gcc-specs-directive()
870# Note; later specs normally overwrite earlier ones; however if a later
871# spec starts with '+' then it appends.
872# gcc -dumpspecs is parsed first, followed by files listed by "gcc -v"
873# as "Reading <file>", in order. Strictly speaking, if there's a
874# $(gcc_install_dir)/specs, the built-in specs aren't read, however by
875# the same token anything from 'gcc -dumpspecs' is overridden by
876# the contents of $(gcc_install_dir)/specs so the result is the
877# same either way.
878_gcc-specs-directive_raw() {
879 local cc=$(tc-getCC)
880 local specfiles=$(LC_ALL=C ${cc} -v 2>&1 | awk '$1=="Reading" {print $NF}')
881 ${cc} -dumpspecs 2> /dev/null | cat - ${specfiles} | awk -v directive=$1 \
882'BEGIN { pspec=""; spec=""; outside=1 }
883$1=="*"directive":" { pspec=spec; spec=""; outside=0; next }
884 outside || NF==0 || ( substr($1,1,1)=="*" && substr($1,length($1),1)==":" ) { outside=1; next }
885 spec=="" && substr($0,1,1)=="+" { spec=pspec " " substr($0,2); next }
886 { spec=spec $0 }
887END { print spec }'
888 return 0
889}
890
891# Return the requested gcc specs directive, with all included
892# specs expanded.
893# Note, it does not check for inclusion loops, which cause it
894# to never finish - but such loops are invalid for gcc and we're
895# assuming gcc is operational.
896gcc-specs-directive() {
897 local directive subdname subdirective
898 directive="$(_gcc-specs-directive_raw $1)"
899 while [[ ${directive} == *%\(*\)* ]]; do
900 subdname=${directive/*%\(}
901 subdname=${subdname/\)*}
902 subdirective="$(_gcc-specs-directive_raw ${subdname})"
903 directive="${directive//\%(${subdname})/${subdirective}}"
904 done
905 echo "${directive}"
906 return 0
907}
908
909# Returns true if gcc sets relro
910gcc-specs-relro() {
911 local directive
912 directive=$(gcc-specs-directive link_command)
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700913 [[ "${directive/\{!norelro:}" != "${directive}" ]]
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700914}
915# Returns true if gcc sets now
916gcc-specs-now() {
917 local directive
918 directive=$(gcc-specs-directive link_command)
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700919 [[ "${directive/\{!nonow:}" != "${directive}" ]]
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700920}
921# Returns true if gcc builds PIEs
922gcc-specs-pie() {
923 local directive
924 directive=$(gcc-specs-directive cc1)
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700925 [[ "${directive/\{!nopie:}" != "${directive}" ]]
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700926}
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700927# Returns true if gcc builds with the stack protector
928gcc-specs-ssp() {
929 local directive
930 directive=$(gcc-specs-directive cc1)
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700931 [[ "${directive/\{!fno-stack-protector:}" != "${directive}" ]]
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700932}
933# Returns true if gcc upgrades fstack-protector to fstack-protector-all
934gcc-specs-ssp-to-all() {
935 local directive
936 directive=$(gcc-specs-directive cc1)
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700937 [[ "${directive/\{!fno-stack-protector-all:}" != "${directive}" ]]
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700938}
939# Returns true if gcc builds with fno-strict-overflow
940gcc-specs-nostrict() {
941 local directive
942 directive=$(gcc-specs-directive cc1)
Yunlian Jiang5fe56222016-04-15 14:33:59 -0700943 [[ "${directive/\{!fstrict-overflow:}" != "${directive}" ]]
944}
945# Returns true if gcc builds with fstack-check
946gcc-specs-stack-check() {
947 local directive
948 directive=$(gcc-specs-directive cc1)
949 [[ "${directive/\{!fno-stack-check:}" != "${directive}" ]]
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700950}
951
952
Yunlian Jiang9fc23462018-04-23 15:15:09 -0700953# @FUNCTION: tc-enables-pie
954# @RETURN: Truth if the current compiler generates position-independent code (PIC) which can be linked into executables
955# @DESCRIPTION:
956# Return truth if the current compiler generates position-independent code (PIC)
957# which can be linked into executables.
958tc-enables-pie() {
Manoj Gupta7888b882019-09-18 10:57:50 -0700959 tc-cpp-is-true "defined(__PIE__)" ${CPPFLAGS} ${CFLAGS}
Yunlian Jiang9fc23462018-04-23 15:15:09 -0700960}
961
962# @FUNCTION: tc-enables-ssp
963# @RETURN: Truth if the current compiler enables stack smashing protection (SSP) on at least minimal level
964# @DESCRIPTION:
965# Return truth if the current compiler enables stack smashing protection (SSP)
966# on level corresponding to any of the following options:
967# -fstack-protector
968# -fstack-protector-strong
969# -fstack-protector-all
970tc-enables-ssp() {
Manoj Gupta7888b882019-09-18 10:57:50 -0700971 tc-cpp-is-true "defined(__SSP__) || defined(__SSP_STRONG__) || defined(__SSP_ALL__)" ${CPPFLAGS} ${CFLAGS}
Yunlian Jiang9fc23462018-04-23 15:15:09 -0700972}
973
974# @FUNCTION: tc-enables-ssp-strong
975# @RETURN: Truth if the current compiler enables stack smashing protection (SSP) on at least middle level
976# @DESCRIPTION:
977# Return truth if the current compiler enables stack smashing protection (SSP)
978# on level corresponding to any of the following options:
979# -fstack-protector-strong
980# -fstack-protector-all
981tc-enables-ssp-strong() {
Manoj Gupta7888b882019-09-18 10:57:50 -0700982 tc-cpp-is-true "defined(__SSP_STRONG__) || defined(__SSP_ALL__)" ${CPPFLAGS} ${CFLAGS}
Yunlian Jiang9fc23462018-04-23 15:15:09 -0700983}
984
985# @FUNCTION: tc-enables-ssp-all
986# @RETURN: Truth if the current compiler enables stack smashing protection (SSP) on maximal level
987# @DESCRIPTION:
988# Return truth if the current compiler enables stack smashing protection (SSP)
989# on level corresponding to any of the following options:
990# -fstack-protector-all
991tc-enables-ssp-all() {
Manoj Gupta7888b882019-09-18 10:57:50 -0700992 tc-cpp-is-true "defined(__SSP_ALL__)" ${CPPFLAGS} ${CFLAGS}
Yunlian Jiang9fc23462018-04-23 15:15:09 -0700993}
994
995
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -0700996# @FUNCTION: gen_usr_ldscript
997# @USAGE: [-a] <list of libs to create linker scripts for>
998# @DESCRIPTION:
Manoj Gupta7888b882019-09-18 10:57:50 -0700999# This function is deprecated. Use the version from
1000# usr-ldscript.eclass instead.
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -07001001gen_usr_ldscript() {
Manoj Gupta7888b882019-09-18 10:57:50 -07001002 ewarn "${FUNCNAME}: Please migrate to usr-ldscript.eclass"
1003
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -07001004 local lib libdir=$(get_libdir) output_format="" auto=false suffix=$(get_libname)
1005 [[ -z ${ED+set} ]] && local ED=${D%/}${EPREFIX}/
1006
1007 tc-is-static-only && return
1008
Yunlian Jiang5fe56222016-04-15 14:33:59 -07001009 # We only care about stuffing / for the native ABI. #479448
1010 if [[ $(type -t multilib_is_native_abi) == "function" ]] ; then
1011 multilib_is_native_abi || return 0
1012 fi
1013
Mike Frysinger1c599582013-01-27 23:38:22 -05001014 # Eventually we'd like to get rid of this func completely #417451
1015 case ${CTARGET:-${CHOST}} in
1016 *-darwin*) ;;
Yunlian Jiang5fe56222016-04-15 14:33:59 -07001017 *-android*) return 0 ;;
Mike Frysinger1c599582013-01-27 23:38:22 -05001018 *linux*|*-freebsd*|*-openbsd*|*-netbsd*)
1019 use prefix && return 0 ;;
1020 *) return 0 ;;
1021 esac
1022
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -07001023 # Just make sure it exists
1024 dodir /usr/${libdir}
1025
1026 if [[ $1 == "-a" ]] ; then
1027 auto=true
1028 shift
1029 dodir /${libdir}
1030 fi
1031
1032 # OUTPUT_FORMAT gives hints to the linker as to what binary format
1033 # is referenced ... makes multilib saner
Yunlian Jiang5fe56222016-04-15 14:33:59 -07001034 local flags=( ${CFLAGS} ${LDFLAGS} -Wl,--verbose )
1035 if $(tc-getLD) --version | grep -q 'GNU gold' ; then
1036 # If they're using gold, manually invoke the old bfd. #487696
1037 local d="${T}/bfd-linker"
1038 mkdir -p "${d}"
1039 ln -sf $(which ${CHOST}-ld.bfd) "${d}"/ld
1040 flags+=( -B"${d}" )
1041 fi
1042 output_format=$($(tc-getCC) "${flags[@]}" 2>&1 | sed -n 's/^OUTPUT_FORMAT("\([^"]*\)",.*/\1/p')
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -07001043 [[ -n ${output_format} ]] && output_format="OUTPUT_FORMAT ( ${output_format} )"
1044
1045 for lib in "$@" ; do
1046 local tlib
1047 if ${auto} ; then
1048 lib="lib${lib}${suffix}"
1049 else
1050 # Ensure /lib/${lib} exists to avoid dangling scripts/symlinks.
1051 # This especially is for AIX where $(get_libname) can return ".a",
1052 # so /lib/${lib} might be moved to /usr/lib/${lib} (by accident).
1053 [[ -r ${ED}/${libdir}/${lib} ]] || continue
1054 #TODO: better die here?
1055 fi
1056
1057 case ${CTARGET:-${CHOST}} in
1058 *-darwin*)
1059 if ${auto} ; then
1060 tlib=$(scanmacho -qF'%S#F' "${ED}"/usr/${libdir}/${lib})
1061 else
1062 tlib=$(scanmacho -qF'%S#F' "${ED}"/${libdir}/${lib})
1063 fi
1064 [[ -z ${tlib} ]] && die "unable to read install_name from ${lib}"
1065 tlib=${tlib##*/}
1066
1067 if ${auto} ; then
1068 mv "${ED}"/usr/${libdir}/${lib%${suffix}}.*${suffix#.} "${ED}"/${libdir}/ || die
1069 # some install_names are funky: they encode a version
1070 if [[ ${tlib} != ${lib%${suffix}}.*${suffix#.} ]] ; then
1071 mv "${ED}"/usr/${libdir}/${tlib%${suffix}}.*${suffix#.} "${ED}"/${libdir}/ || die
1072 fi
1073 rm -f "${ED}"/${libdir}/${lib}
1074 fi
1075
1076 # Mach-O files have an id, which is like a soname, it tells how
1077 # another object linking against this lib should reference it.
1078 # Since we moved the lib from usr/lib into lib this reference is
1079 # wrong. Hence, we update it here. We don't configure with
1080 # libdir=/lib because that messes up libtool files.
1081 # Make sure we don't lose the specific version, so just modify the
1082 # existing install_name
1083 if [[ ! -w "${ED}/${libdir}/${tlib}" ]] ; then
1084 chmod u+w "${ED}${libdir}/${tlib}" # needed to write to it
1085 local nowrite=yes
1086 fi
1087 install_name_tool \
1088 -id "${EPREFIX}"/${libdir}/${tlib} \
1089 "${ED}"/${libdir}/${tlib} || die "install_name_tool failed"
1090 [[ -n ${nowrite} ]] && chmod u-w "${ED}${libdir}/${tlib}"
1091 # Now as we don't use GNU binutils and our linker doesn't
1092 # understand linker scripts, just create a symlink.
1093 pushd "${ED}/usr/${libdir}" > /dev/null
1094 ln -snf "../../${libdir}/${tlib}" "${lib}"
1095 popd > /dev/null
1096 ;;
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -07001097 *)
1098 if ${auto} ; then
1099 tlib=$(scanelf -qF'%S#F' "${ED}"/usr/${libdir}/${lib})
1100 [[ -z ${tlib} ]] && die "unable to read SONAME from ${lib}"
1101 mv "${ED}"/usr/${libdir}/${lib}* "${ED}"/${libdir}/ || die
1102 # some SONAMEs are funky: they encode a version before the .so
1103 if [[ ${tlib} != ${lib}* ]] ; then
1104 mv "${ED}"/usr/${libdir}/${tlib}* "${ED}"/${libdir}/ || die
1105 fi
1106 rm -f "${ED}"/${libdir}/${lib}
1107 else
1108 tlib=${lib}
1109 fi
1110 cat > "${ED}/usr/${libdir}/${lib}" <<-END_LDSCRIPT
1111 /* GNU ld script
1112 Since Gentoo has critical dynamic libraries in /lib, and the static versions
1113 in /usr/lib, we need to have a "fake" dynamic lib in /usr/lib, otherwise we
1114 run into linking problems. This "fake" dynamic lib is a linker script that
1115 redirects the linker to the real lib. And yes, this works in the cross-
1116 compiling scenario as the sysroot-ed linker will prepend the real path.
1117
Yunlian Jiang5fe56222016-04-15 14:33:59 -07001118 See bug https://bugs.gentoo.org/4411 for more info.
Ahmad Sharif9e7e3de2011-08-31 12:19:10 -07001119 */
1120 ${output_format}
1121 GROUP ( ${EPREFIX}/${libdir}/${tlib} )
1122 END_LDSCRIPT
1123 ;;
1124 esac
1125 fperms a+x "/usr/${libdir}/${lib}" || die "could not change perms on ${lib}"
1126 done
1127}
Mike Frysinger13d24b12012-05-22 14:21:36 -04001128
1129#
1130# ChromiumOS extensions below here.
1131#
1132
Michael Martis0651e002018-06-27 13:03:16 +10001133# @FUNCTION: tc-get-BUILD_compiler-type
1134# @RETURN: keyword identifying the compiler for the build machine: gcc, clang, pathcc, unknown
1135tc-get-BUILD_compiler-type() {
1136 local code='
1137#if defined(__PATHSCALE__)
1138 HAVE_PATHCC
1139#elif defined(__clang__)
1140 HAVE_CLANG
1141#elif defined(__GNUC__)
1142 HAVE_GCC
1143#endif
1144'
1145 local res=$($(tc-getBUILD_CPP "$@") -E -P - <<<"${code}")
1146
1147 case ${res} in
1148 *HAVE_PATHCC*) echo pathcc;;
1149 *HAVE_CLANG*) echo clang;;
1150 *HAVE_GCC*) echo gcc;;
1151 *) echo unknown;;
1152 esac
1153}
1154
1155# @FUNCTION: tc-getDWP
1156# @USAGE: [toolchain prefix]
1157# @RETURN: name of the DWARF package builder
1158tc-getDWP() { tc-getPROG DWP dwp "$@"; }
1159
1160# @FUNCTION: tc-getGCOV
1161# @USAGE: [toolchain prefix]
1162# @RETURN: name of the test coverage program
1163tc-getGCOV() { tc-getPROG GCOV gcov "$@"; }
1164
1165# @FUNCTION: tc-getBUILD_DWP
1166# @USAGE: [toolchain prefix]
1167# @RETURN: name of the DWARF package builder to run on the build machine
1168tc-getBUILD_DWP() { tc-getBUILD_PROG DWP dwp "$@"; }
1169
1170# @FUNCTION: tc-getBUILD_GCOV
1171# @USAGE: [toolchain prefix]
1172# @RETURN: name of the test coverage program to run on the build machine
1173tc-getBUILD_GCOV() { tc-getBUILD_PROG GCOV gcov "$@"; }
1174
1175# @FUNCTION: tc-getBUILD_OBJDUMP
1176# @USAGE: [toolchain prefix]
1177# @RETURN: name of the object dumper to run on the build machine
1178tc-getBUILD_OBJDUMP() { tc-getBUILD_PROG OBJDUMP objdump "$@"; }
1179
Yunlian Jiang5ace3942017-04-14 09:54:49 -07001180# @FUNCTION: tc-getBUILD_GO
1181# @USAGE: [toolchain prefix]
1182# @RETURN: name of the Go compiler for building binaries to run on the build machine
1183tc-getBUILD_GO() { tc-getBUILD_PROG GO go "$@"; }
1184
Rahul Chaudhryab648452017-05-05 14:17:33 -07001185tc-getTARGET_PROG() {
1186 local CTARGET="${CTARGET:-${CHOST}}"
Rahul Chaudhry68a64f72017-05-23 12:29:08 -07001187 _tc-getPROG CTARGET "TARGET_$1 $1_FOR_TARGET" "${2#${CHOST}-}" "${@:3}"
Rahul Chaudhryab648452017-05-05 14:17:33 -07001188}
1189
1190# @FUNCTION: tc-getTARGET_CC
1191# @USAGE: [toolchain prefix]
1192# @RETURN: name of the C compiler for building binaries to run on the target machine
Rahul Chaudhry68a64f72017-05-23 12:29:08 -07001193tc-getTARGET_CC() { tc-getTARGET_PROG CC "$(tc-getCC)" "$@"; }
Rahul Chaudhryab648452017-05-05 14:17:33 -07001194# @FUNCTION: tc-getTARGET_CXX
1195# @USAGE: [toolchain prefix]
1196# @RETURN: name of the C++ compiler for building binaries to run on the target machine
Rahul Chaudhry68a64f72017-05-23 12:29:08 -07001197tc-getTARGET_CXX() { tc-getTARGET_PROG CXX "$(tc-getCXX)" "$@"; }
Rahul Chaudhryab648452017-05-05 14:17:33 -07001198
Mike Frysinger13d24b12012-05-22 14:21:36 -04001199# Returns true if gcc builds PIEs
1200# For ARM, readelf -h | grep Type always has REL instead of EXEC.
1201# That is why we have to read the flags one by one and check them instead
1202# of test-compiling a small program.
1203gcc-pie() {
1204 for flag in $(echo "void f(){char a[100];}" | \
1205 ${CTARGET}-gcc -v -xc -c -o /dev/null - 2>&1 | \
1206 grep cc1 | \
1207 tr " " "\n" | \
1208 tac)
1209 do
1210 if [[ $flag == "-fPIE" || $flag == "-fPIC" ]]
1211 then
1212 return 0
1213 elif [[ $flag == "-fno-PIE" || $flag == "-fno-PIC" ]]
1214 then
1215 return 1
1216 fi
1217 done
1218 return 1
1219}
1220
1221# Returns true if gcc builds with the stack protector
1222gcc-ssp() {
1223 local obj=$(mktemp)
1224 echo "void f(){char a[100];}" | ${CTARGET}-gcc -xc -c -o ${obj} -
1225 return $(${CTARGET}-readelf -sW ${obj} | grep -q stack_chk_fail)
1226}
1227
Liam McLoughlin46ea39a2012-08-01 13:42:13 -07001228# Sets up environment variables required to build with Clang
1229# This should be replaced with a sysroot wrapper ala GCC if/when
1230# we get serious about building with Clang.
1231clang-setup-env() {
1232 use clang || return 0
Yunlian Jiangb9617172016-06-22 15:10:49 -07001233 # There is no wrapper for host clang.
1234 if [[ "${CHOST}" == "x86_64-pc-linux-gnu" ]] ; then
1235 return 0
1236 fi
Liam McLoughlin46ea39a2012-08-01 13:42:13 -07001237 case ${ARCH} in
Adam Kallaic3e62f12018-05-09 16:14:35 +02001238 amd64|x86|arm|arm64)
Yunlian Jiang31d291c2013-09-06 14:44:50 -07001239 export CC="${CHOST}-clang" CXX="${CHOST}-clang++"
Liam McLoughlin46ea39a2012-08-01 13:42:13 -07001240 ;;
1241 *) die "Clang is not yet supported for ${ARCH}"
1242 esac
1243
1244 if use asan; then
Yunlian Jiang0a788eb2015-08-19 11:26:03 -07001245 local asan_flags=(
1246 -fsanitize=address
1247 -fsanitize=alignment
Yunlian Jiang7d8113c2015-10-13 16:04:49 -07001248 -fsanitize=shift
Yunlian Jiang0a788eb2015-08-19 11:26:03 -07001249 )
1250 append-flags "${asan_flags[@]}"
1251 append-ldflags "${asan_flags[@]}"
Liam McLoughlin46ea39a2012-08-01 13:42:13 -07001252 fi
1253}
1254
Mike Frysinger13d24b12012-05-22 14:21:36 -04001255fi