| # Copyright 1999-2014 Gentoo Foundation |
| # Distributed under the terms of the GNU General Public License v2 |
| # $Header: /var/cvsroot/gentoo-x86/eclass/flag-o-matic.eclass,v 1.205 2015/05/06 07:04:53 vapier Exp $ |
| |
| # @ECLASS: flag-o-matic.eclass |
| # @MAINTAINER: |
| # toolchain@gentoo.org |
| # @BLURB: common functions to manipulate and query toolchain flags |
| # @DESCRIPTION: |
| # This eclass contains a suite of functions to help developers sanely |
| # and safely manage toolchain flags in their builds. |
| |
| if [[ -z ${_FLAG_O_MATIC_ECLASS} ]]; then |
| _FLAG_O_MATIC_ECLASS=1 |
| |
| inherit eutils toolchain-funcs multilib |
| |
| # Return all the flag variables that our high level funcs operate on. |
| all-flag-vars() { |
| echo {C,CPP,CXX,CCAS,F,FC,LD}FLAGS |
| } |
| |
| # {C,CPP,CXX,CCAS,F,FC,LD}FLAGS that we allow in strip-flags |
| # Note: shell globs and character lists are allowed |
| setup-allowed-flags() { |
| ALLOWED_FLAGS="-pipe" |
| ALLOWED_FLAGS+=" -O -O1 -O2 -Os -Og -mcpu -march -mtune" |
| ALLOWED_FLAGS+=" -fstack-protector* -fsanitize=*" |
| ALLOWED_FLAGS+=" -fbounds-checking -fno-strict-overflow" |
| ALLOWED_FLAGS+=" -fno-PIE -fno-pie -nopie -fno-unit-at-a-time" |
| ALLOWED_FLAGS+=" -g -g[0-9] -ggdb -ggdb[0-9] -gdwarf-* gstabs -gstabs+" |
| ALLOWED_FLAGS+=" -fno-ident -fpermissive -frecord-gcc-switches" |
| ALLOWED_FLAGS+=" -fdiagnostics*" |
| ALLOWED_FLAGS+=" -W* -w" |
| |
| # allow a bunch of flags that negate features / control ABI |
| ALLOWED_FLAGS+=" -fno-stack-protector* -fabi-version=* \ |
| -fno-strict-aliasing -fno-bounds-checking -fstrict-overflow \ |
| -fno-omit-frame-pointer -fno-builtin*" |
| ALLOWED_FLAGS+=" -mregparm -mno-app-regs -mapp-regs -mno-mmx -mno-sse \ |
| -mno-sse2 -mno-sse3 -mno-ssse3 -mno-sse4 -mno-sse4.1 -mno-sse4.2 \ |
| -mno-avx -mno-aes -mno-pclmul -mno-sse4a -mno-3dnow -mno-popcnt \ |
| -mno-abm -mips1 -mips2 -mips3 -mips4 -mips32 -mips64 -mips16 -mplt \ |
| -msoft-float -mno-soft-float -mhard-float -mno-hard-float -mfpu \ |
| -mieee -mieee-with-inexact -mschedule -mfloat-gprs -mspe -mno-spe \ |
| -mtls-direct-seg-refs -mno-tls-direct-seg-refs -mflat -mno-flat \ |
| -mno-faster-structs -mfaster-structs -m32 -m64 -mx32 -mabi \ |
| -mlittle-endian -mbig-endian -EL -EB -fPIC -mlive-g0 -mcmodel \ |
| -mstack-bias -mno-stack-bias -msecure-plt -m*-toc -mfloat-abi \ |
| -mfix-r10000 -mno-fix-r10000 -D* -U*" |
| |
| # 4.5 |
| ALLOWED_FLAGS+=" -mno-fma4 -mno-movbe -mno-xop -mno-lwp" |
| # 4.6 |
| ALLOWED_FLAGS+=" -mno-fsgsbase -mno-rdrnd -mno-f16c -mno-bmi -mno-tbm" |
| # 4.7 |
| ALLOWED_FLAGS+=" -mno-avx2 -mno-bmi2 -mno-fma -mno-lzcnt" |
| # 4.8 |
| ALLOWED_FLAGS+=" -mno-fxsr -mno-rtm -mno-xsave -mno-xsaveopt" |
| # 4.9 |
| ALLOWED_FLAGS+=" -mno-avx512cd -mno-avx512er -mno-avx512f -mno-avx512pf -mno-sha" |
| |
| # CPPFLAGS and LDFLAGS |
| ALLOWED_FLAGS+=" -I* -L* -R* -Wl,*" |
| |
| export ALLOWED_FLAGS |
| return 0 |
| } |
| |
| # inverted filters for hardened compiler. This is trying to unpick |
| # the hardened compiler defaults. |
| _filter-hardened() { |
| local f |
| for f in "$@" ; do |
| case "${f}" in |
| # Ideally we should only concern ourselves with PIE flags, |
| # not -fPIC or -fpic, but too many places filter -fPIC without |
| # thinking about -fPIE. |
| -fPIC|-fpic|-fPIE|-fpie|-Wl,pie|-pie) |
| gcc-specs-pie || continue |
| is-flagq -nopie || append-flags -nopie;; |
| -fstack-protector) |
| gcc-specs-ssp || continue |
| is-flagq -fno-stack-protector || append-flags $(test-flags -fno-stack-protector);; |
| -fstack-protector-all) |
| gcc-specs-ssp-to-all || continue |
| is-flagq -fno-stack-protector-all || append-flags $(test-flags -fno-stack-protector-all);; |
| -fno-strict-overflow) |
| gcc-specs-nostrict || continue |
| is-flagq -fstrict-overflow || append-flags $(test-flags -fstrict-overflow);; |
| esac |
| done |
| } |
| |
| # Remove occurrences of strings from variable given in $1 |
| # Strings removed are matched as globs, so for example |
| # '-O*' would remove -O1, -O2 etc. |
| _filter-var() { |
| local f x var=$1 new=() |
| shift |
| |
| for f in ${!var} ; do |
| for x in "$@" ; do |
| # Note this should work with globs like -O* |
| [[ ${f} == ${x} ]] && continue 2 |
| done |
| new+=( "${f}" ) |
| done |
| eval export ${var}=\""${new[*]}"\" |
| } |
| |
| # @FUNCTION: filter-flags |
| # @USAGE: <flags> |
| # @DESCRIPTION: |
| # Remove particular <flags> from {C,CPP,CXX,CCAS,F,FC,LD}FLAGS. Accepts shell globs. |
| filter-flags() { |
| _filter-hardened "$@" |
| local v |
| for v in $(all-flag-vars) ; do |
| _filter-var ${v} "$@" |
| done |
| return 0 |
| } |
| |
| # @FUNCTION: filter-lfs-flags |
| # @DESCRIPTION: |
| # Remove flags that enable Large File Support. |
| filter-lfs-flags() { |
| [[ $# -ne 0 ]] && die "filter-lfs-flags takes no arguments" |
| # http://www.gnu.org/s/libc/manual/html_node/Feature-Test-Macros.html |
| # _LARGEFILE_SOURCE: enable support for new LFS funcs (ftello/etc...) |
| # _LARGEFILE64_SOURCE: enable support for 64bit variants (off64_t/fseeko64/etc...) |
| # _FILE_OFFSET_BITS: default to 64bit variants (off_t is defined as off64_t) |
| filter-flags -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE |
| } |
| |
| # @FUNCTION: filter-ldflags |
| # @USAGE: <flags> |
| # @DESCRIPTION: |
| # Remove particular <flags> from LDFLAGS. Accepts shell globs. |
| filter-ldflags() { |
| _filter-var LDFLAGS "$@" |
| return 0 |
| } |
| |
| # @FUNCTION: append-cppflags |
| # @USAGE: <flags> |
| # @DESCRIPTION: |
| # Add extra <flags> to the current CPPFLAGS. |
| append-cppflags() { |
| [[ $# -eq 0 ]] && return 0 |
| export CPPFLAGS+=" $*" |
| return 0 |
| } |
| |
| # @FUNCTION: append-cflags |
| # @USAGE: <flags> |
| # @DESCRIPTION: |
| # Add extra <flags> to the current CFLAGS. If a flag might not be supported |
| # with different compilers (or versions), then use test-flags-CC like so: |
| # @CODE |
| # append-cflags $(test-flags-CC -funky-flag) |
| # @CODE |
| append-cflags() { |
| [[ $# -eq 0 ]] && return 0 |
| # Do not do automatic flag testing ourselves. #417047 |
| export CFLAGS+=" $*" |
| return 0 |
| } |
| |
| # @FUNCTION: append-cxxflags |
| # @USAGE: <flags> |
| # @DESCRIPTION: |
| # Add extra <flags> to the current CXXFLAGS. If a flag might not be supported |
| # with different compilers (or versions), then use test-flags-CXX like so: |
| # @CODE |
| # append-cxxflags $(test-flags-CXX -funky-flag) |
| # @CODE |
| append-cxxflags() { |
| [[ $# -eq 0 ]] && return 0 |
| # Do not do automatic flag testing ourselves. #417047 |
| export CXXFLAGS+=" $*" |
| return 0 |
| } |
| |
| # @FUNCTION: append-fflags |
| # @USAGE: <flags> |
| # @DESCRIPTION: |
| # Add extra <flags> to the current {F,FC}FLAGS. If a flag might not be supported |
| # with different compilers (or versions), then use test-flags-F77 like so: |
| # @CODE |
| # append-fflags $(test-flags-F77 -funky-flag) |
| # @CODE |
| append-fflags() { |
| [[ $# -eq 0 ]] && return 0 |
| # Do not do automatic flag testing ourselves. #417047 |
| export FFLAGS+=" $*" |
| export FCFLAGS+=" $*" |
| return 0 |
| } |
| |
| # @FUNCTION: append-lfs-flags |
| # @DESCRIPTION: |
| # Add flags that enable Large File Support. |
| append-lfs-flags() { |
| [[ $# -ne 0 ]] && die "append-lfs-flags takes no arguments" |
| # see comments in filter-lfs-flags func for meaning of these |
| append-cppflags -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE |
| } |
| |
| # @FUNCTION: append-ldflags |
| # @USAGE: <flags> |
| # @DESCRIPTION: |
| # Add extra <flags> to the current LDFLAGS. |
| append-ldflags() { |
| [[ $# -eq 0 ]] && return 0 |
| local flag |
| for flag in "$@"; do |
| [[ ${flag} == -l* ]] && \ |
| eqawarn "Appending a library link instruction (${flag}); libraries to link to should not be passed through LDFLAGS" |
| done |
| |
| export LDFLAGS="${LDFLAGS} $*" |
| return 0 |
| } |
| |
| # @FUNCTION: append-flags |
| # @USAGE: <flags> |
| # @DESCRIPTION: |
| # Add extra <flags> to your current {C,CXX,F,FC}FLAGS. |
| append-flags() { |
| [[ $# -eq 0 ]] && return 0 |
| case " $* " in |
| *' '-[DIU]*) eqawarn 'please use append-cppflags for preprocessor flags' ;; |
| *' '-L*|\ |
| *' '-Wl,*) eqawarn 'please use append-ldflags for linker flags' ;; |
| esac |
| append-cflags "$@" |
| append-cxxflags "$@" |
| append-fflags "$@" |
| return 0 |
| } |
| |
| # @FUNCTION: replace-flags |
| # @USAGE: <old> <new> |
| # @DESCRIPTION: |
| # Replace the <old> flag with <new>. Accepts shell globs for <old>. |
| replace-flags() { |
| [[ $# != 2 ]] && die "Usage: replace-flags <old flag> <new flag>" |
| |
| local f var new |
| for var in $(all-flag-vars) ; do |
| # Looping over the flags instead of using a global |
| # substitution ensures that we're working with flag atoms. |
| # Otherwise globs like -O* have the potential to wipe out the |
| # list of flags. |
| new=() |
| for f in ${!var} ; do |
| # Note this should work with globs like -O* |
| [[ ${f} == ${1} ]] && f=${2} |
| new+=( "${f}" ) |
| done |
| eval export ${var}=\""${new[*]}"\" |
| done |
| |
| return 0 |
| } |
| |
| # @FUNCTION: replace-cpu-flags |
| # @USAGE: <old> <new> |
| # @DESCRIPTION: |
| # Replace cpu flags (like -march/-mcpu/-mtune) that select the <old> cpu |
| # with flags that select the <new> cpu. Accepts shell globs for <old>. |
| replace-cpu-flags() { |
| local newcpu="$#" ; newcpu="${!newcpu}" |
| while [ $# -gt 1 ] ; do |
| # quote to make sure that no globbing is done (particularly on |
| # ${oldcpu}) prior to calling replace-flags |
| replace-flags "-march=${1}" "-march=${newcpu}" |
| replace-flags "-mcpu=${1}" "-mcpu=${newcpu}" |
| replace-flags "-mtune=${1}" "-mtune=${newcpu}" |
| shift |
| done |
| return 0 |
| } |
| |
| _is_flagq() { |
| local x var |
| eval var=\""\${$1[*]}"\" |
| for x in ${var} ; do |
| [[ ${x} == $2 ]] && return 0 |
| done |
| return 1 |
| } |
| |
| # @FUNCTION: is-flagq |
| # @USAGE: <flag> |
| # @DESCRIPTION: |
| # Returns shell true if <flag> is in {C,CXX,F,FC}FLAGS, else returns shell false. Accepts shell globs. |
| is-flagq() { |
| [[ -n $2 ]] && die "Usage: is-flag <flag>" |
| |
| local var |
| for var in $(all-flag-vars) ; do |
| _is_flagq ${var} "$1" && return 0 |
| done |
| return 1 |
| } |
| |
| # @FUNCTION: is-flag |
| # @USAGE: <flag> |
| # @DESCRIPTION: |
| # Echo's "true" if flag is set in {C,CXX,F,FC}FLAGS. Accepts shell globs. |
| is-flag() { |
| is-flagq "$@" && echo true |
| } |
| |
| # @FUNCTION: is-ldflagq |
| # @USAGE: <flag> |
| # @DESCRIPTION: |
| # Returns shell true if <flag> is in LDFLAGS, else returns shell false. Accepts shell globs. |
| is-ldflagq() { |
| [[ -n $2 ]] && die "Usage: is-ldflag <flag>" |
| _is_flagq LDFLAGS $1 |
| } |
| |
| # @FUNCTION: is-ldflag |
| # @USAGE: <flag> |
| # @DESCRIPTION: |
| # Echo's "true" if flag is set in LDFLAGS. Accepts shell globs. |
| is-ldflag() { |
| is-ldflagq "$@" && echo true |
| } |
| |
| # @FUNCTION: filter-mfpmath |
| # @USAGE: <math types> |
| # @DESCRIPTION: |
| # Remove specified math types from the fpmath flag. For example, if the user |
| # has -mfpmath=sse,386, running `filter-mfpmath sse` will leave the user with |
| # -mfpmath=386. |
| filter-mfpmath() { |
| local orig_mfpmath new_math prune_math |
| |
| # save the original -mfpmath flag |
| orig_mfpmath=$(get-flag -mfpmath) |
| # get the value of the current -mfpmath flag |
| new_math=$(get-flag mfpmath) |
| # convert "both" to something we can filter |
| new_math=${new_math/both/387,sse} |
| new_math=" ${new_math//[,+]/ } " |
| # figure out which math values are to be removed |
| prune_math="" |
| for prune_math in "$@" ; do |
| new_math=${new_math/ ${prune_math} / } |
| done |
| new_math=$(echo ${new_math}) |
| new_math=${new_math// /,} |
| |
| if [[ -z ${new_math} ]] ; then |
| # if we're removing all user specified math values are |
| # slated for removal, then we just filter the flag |
| filter-flags ${orig_mfpmath} |
| else |
| # if we only want to filter some of the user specified |
| # math values, then we replace the current flag |
| replace-flags ${orig_mfpmath} -mfpmath=${new_math} |
| fi |
| return 0 |
| } |
| |
| # @FUNCTION: strip-flags |
| # @DESCRIPTION: |
| # Strip *FLAGS of everything except known good/safe flags. This runs over all |
| # flags returned by all_flag_vars(). |
| strip-flags() { |
| local x y var |
| |
| setup-allowed-flags |
| |
| set -f # disable pathname expansion |
| |
| for var in $(all-flag-vars) ; do |
| local new=() |
| |
| for x in ${!var} ; do |
| local flag=${x%%=*} |
| for y in ${ALLOWED_FLAGS} ; do |
| if [[ -z ${flag%%${y}} ]] ; then |
| new+=( "${x}" ) |
| break |
| fi |
| done |
| done |
| |
| # In case we filtered out all optimization flags fallback to -O2 |
| if _is_flagq ${var} "-O*" && ! _is_flagq new "-O*" ; then |
| new+=( -O2 ) |
| fi |
| |
| if [[ ${!var} != "${new[*]}" ]] ; then |
| einfo "strip-flags: ${var}: changed '${!var}' to '${new[*]}'" |
| fi |
| eval export ${var}=\""${new[*]}"\" |
| done |
| |
| set +f # re-enable pathname expansion |
| |
| return 0 |
| } |
| |
| test-flag-PROG() { |
| local comp=$1 |
| local lang=$2 |
| local flag=$3 |
| |
| [[ -z ${comp} || -z ${flag} ]] && return 1 |
| |
| local cmdline=( |
| $(tc-get${comp}) |
| # Clang will warn about unknown gcc flags but exit 0. |
| # Need -Werror to force it to exit non-zero. |
| -Werror |
| # Use -c so we can test the assembler as well. |
| -c -o /dev/null |
| ) |
| if "${cmdline[@]}" -x${lang} - </dev/null >/dev/null 2>&1 ; then |
| "${cmdline[@]}" "${flag}" -x${lang} - </dev/null >/dev/null 2>&1 |
| else |
| "${cmdline[@]}" "${flag}" -c -o /dev/null /dev/null >/dev/null 2>&1 |
| fi |
| } |
| |
| # @FUNCTION: test-flag-CC |
| # @USAGE: <flag> |
| # @DESCRIPTION: |
| # Returns shell true if <flag> is supported by the C compiler, else returns shell false. |
| test-flag-CC() { test-flag-PROG "CC" c "$1"; } |
| |
| # @FUNCTION: test-flag-CXX |
| # @USAGE: <flag> |
| # @DESCRIPTION: |
| # Returns shell true if <flag> is supported by the C++ compiler, else returns shell false. |
| test-flag-CXX() { test-flag-PROG "CXX" c++ "$1"; } |
| |
| # @FUNCTION: test-flag-F77 |
| # @USAGE: <flag> |
| # @DESCRIPTION: |
| # Returns shell true if <flag> is supported by the Fortran 77 compiler, else returns shell false. |
| test-flag-F77() { test-flag-PROG "F77" f77 "$1"; } |
| |
| # @FUNCTION: test-flag-FC |
| # @USAGE: <flag> |
| # @DESCRIPTION: |
| # Returns shell true if <flag> is supported by the Fortran 90 compiler, else returns shell false. |
| test-flag-FC() { test-flag-PROG "FC" f95 "$1"; } |
| |
| test-flags-PROG() { |
| local comp=$1 |
| local flags=() |
| local x |
| |
| shift |
| |
| [[ -z ${comp} ]] && return 1 |
| |
| for x ; do |
| test-flag-${comp} "${x}" && flags+=( "${x}" ) |
| done |
| |
| echo "${flags[*]}" |
| |
| # Just bail if we dont have any flags |
| [[ ${#flags[@]} -gt 0 ]] |
| } |
| |
| # @FUNCTION: test-flags-CC |
| # @USAGE: <flags> |
| # @DESCRIPTION: |
| # Returns shell true if <flags> are supported by the C compiler, else returns shell false. |
| test-flags-CC() { test-flags-PROG "CC" "$@"; } |
| |
| # @FUNCTION: test-flags-CXX |
| # @USAGE: <flags> |
| # @DESCRIPTION: |
| # Returns shell true if <flags> are supported by the C++ compiler, else returns shell false. |
| test-flags-CXX() { test-flags-PROG "CXX" "$@"; } |
| |
| # @FUNCTION: test-flags-F77 |
| # @USAGE: <flags> |
| # @DESCRIPTION: |
| # Returns shell true if <flags> are supported by the Fortran 77 compiler, else returns shell false. |
| test-flags-F77() { test-flags-PROG "F77" "$@"; } |
| |
| # @FUNCTION: test-flags-FC |
| # @USAGE: <flags> |
| # @DESCRIPTION: |
| # Returns shell true if <flags> are supported by the Fortran 90 compiler, else returns shell false. |
| test-flags-FC() { test-flags-PROG "FC" "$@"; } |
| |
| # @FUNCTION: test-flags |
| # @USAGE: <flags> |
| # @DESCRIPTION: |
| # Short-hand that should hopefully work for both C and C++ compiler, but |
| # its really only present due to the append-flags() abomination. |
| test-flags() { test-flags-CC "$@"; } |
| |
| # @FUNCTION: test_version_info |
| # @USAGE: <version> |
| # @DESCRIPTION: |
| # Returns shell true if the current C compiler version matches <version>, else returns shell false. |
| # Accepts shell globs. |
| test_version_info() { |
| if [[ $($(tc-getCC) --version 2>&1) == *$1* ]]; then |
| return 0 |
| else |
| return 1 |
| fi |
| } |
| |
| # @FUNCTION: strip-unsupported-flags |
| # @DESCRIPTION: |
| # Strip {C,CXX,F,FC}FLAGS of any flags not supported by the active toolchain. |
| strip-unsupported-flags() { |
| export CFLAGS=$(test-flags-CC ${CFLAGS}) |
| export CXXFLAGS=$(test-flags-CXX ${CXXFLAGS}) |
| export FFLAGS=$(test-flags-F77 ${FFLAGS}) |
| export FCFLAGS=$(test-flags-FC ${FCFLAGS}) |
| } |
| |
| # @FUNCTION: get-flag |
| # @USAGE: <flag> |
| # @DESCRIPTION: |
| # Find and echo the value for a particular flag. Accepts shell globs. |
| get-flag() { |
| local f var findflag="$1" |
| |
| # this code looks a little flaky but seems to work for |
| # everything we want ... |
| # for example, if CFLAGS="-march=i686": |
| # `get-flag -march` == "-march=i686" |
| # `get-flag march` == "i686" |
| for var in $(all-flag-vars) ; do |
| for f in ${!var} ; do |
| if [ "${f/${findflag}}" != "${f}" ] ; then |
| printf "%s\n" "${f/-${findflag}=}" |
| return 0 |
| fi |
| done |
| done |
| return 1 |
| } |
| |
| # @FUNCTION: has_m64 |
| # @DESCRIPTION: |
| # This doesn't test if the flag is accepted, it tests if the flag actually |
| # WORKS. Non-multilib gcc will take both -m32 and -m64. If the flag works |
| # return code is 0, else the return code is 1. |
| has_m64() { |
| eqawarn "${FUNCNAME}: don't use this anymore" |
| |
| # this doesnt test if the flag is accepted, it tests if the flag |
| # actually -WORKS-. non-multilib gcc will take both -m32 and -m64! |
| # please dont replace this function with test_flag in some future |
| # clean-up! |
| |
| local temp="$(emktemp)" |
| echo "int main() { return(0); }" > "${temp}".c |
| MY_CC=$(tc-getCC) |
| ${MY_CC/ .*/} -m64 -o "$(emktemp)" "${temp}".c > /dev/null 2>&1 |
| local ret=$? |
| rm -f "${temp}".c |
| [[ ${ret} != 1 ]] && return 0 |
| return 1 |
| } |
| |
| has_m32() { |
| die "${FUNCNAME}: don't use this anymore" |
| } |
| |
| # @FUNCTION: replace-sparc64-flags |
| # @DESCRIPTION: |
| # Sets mcpu to v8 and uses the original value as mtune if none specified. |
| replace-sparc64-flags() { |
| local SPARC64_CPUS="ultrasparc3 ultrasparc v9" |
| |
| if [ "${CFLAGS/mtune}" != "${CFLAGS}" ]; then |
| for x in ${SPARC64_CPUS}; do |
| CFLAGS="${CFLAGS/-mcpu=${x}/-mcpu=v8}" |
| done |
| else |
| for x in ${SPARC64_CPUS}; do |
| CFLAGS="${CFLAGS/-mcpu=${x}/-mcpu=v8 -mtune=${x}}" |
| done |
| fi |
| |
| if [ "${CXXFLAGS/mtune}" != "${CXXFLAGS}" ]; then |
| for x in ${SPARC64_CPUS}; do |
| CXXFLAGS="${CXXFLAGS/-mcpu=${x}/-mcpu=v8}" |
| done |
| else |
| for x in ${SPARC64_CPUS}; do |
| CXXFLAGS="${CXXFLAGS/-mcpu=${x}/-mcpu=v8 -mtune=${x}}" |
| done |
| fi |
| |
| export CFLAGS CXXFLAGS |
| } |
| |
| # @FUNCTION: append-libs |
| # @USAGE: <libs> |
| # @DESCRIPTION: |
| # Add extra <libs> to the current LIBS. All arguments should be prefixed with |
| # either -l or -L. For compatibility, if arguments are not prefixed as |
| # options, they are given a -l prefix automatically. |
| append-libs() { |
| [[ $# -eq 0 ]] && return 0 |
| local flag |
| for flag in "$@"; do |
| if [[ -z "${flag// }" ]]; then |
| eqawarn "Appending an empty argument to LIBS is invalid! Skipping." |
| continue |
| fi |
| case $flag in |
| -[lL]*) |
| export LIBS="${LIBS} ${flag}" |
| ;; |
| -*) |
| eqawarn "Appending non-library to LIBS (${flag}); Other linker flags should be passed via LDFLAGS" |
| export LIBS="${LIBS} ${flag}" |
| ;; |
| *) |
| export LIBS="${LIBS} -l${flag}" |
| esac |
| done |
| |
| return 0 |
| } |
| |
| # @FUNCTION: raw-ldflags |
| # @USAGE: [flags] |
| # @DESCRIPTION: |
| # Turn C style ldflags (-Wl,-foo) into straight ldflags - the results |
| # are suitable for passing directly to 'ld'; note LDFLAGS is usually passed |
| # to gcc where it needs the '-Wl,'. |
| # |
| # If no flags are specified, then default to ${LDFLAGS}. |
| raw-ldflags() { |
| local x input="$@" |
| [[ -z ${input} ]] && input=${LDFLAGS} |
| set -- |
| for x in ${input} ; do |
| case ${x} in |
| -Wl,*) |
| x=${x#-Wl,} |
| set -- "$@" ${x//,/ } |
| ;; |
| *) # Assume it's a compiler driver flag, so throw it away #441808 |
| ;; |
| esac |
| done |
| echo "$@" |
| } |
| |
| # @FUNCTION: no-as-needed |
| # @RETURN: Flag to disable asneeded behavior for use with append-ldflags. |
| no-as-needed() { |
| case $($(tc-getLD) -v 2>&1 </dev/null) in |
| *GNU*) # GNU ld |
| echo "-Wl,--no-as-needed" ;; |
| esac |
| } |
| |
| fi |