summaryrefslogtreecommitdiff
path: root/eclass/flag-o-matic.eclass
diff options
context:
space:
mode:
authorV3n3RiX <venerix@koprulu.sector>2022-07-21 02:43:04 +0100
committerV3n3RiX <venerix@koprulu.sector>2022-07-21 02:43:04 +0100
commit34753f0703b775be89190c2d6a519e542387f3e8 (patch)
tree2886254a934956b13cedb995c8219e09106cc019 /eclass/flag-o-matic.eclass
parent188aafb7c559528cc9c47d6d508c322f6e33adb5 (diff)
gentoo auto-resync : 21:07:2022 - 02:43:03
Diffstat (limited to 'eclass/flag-o-matic.eclass')
-rw-r--r--eclass/flag-o-matic.eclass146
1 files changed, 146 insertions, 0 deletions
diff --git a/eclass/flag-o-matic.eclass b/eclass/flag-o-matic.eclass
index 0dd2c1191273..b0c30f81c956 100644
--- a/eclass/flag-o-matic.eclass
+++ b/eclass/flag-o-matic.eclass
@@ -875,4 +875,150 @@ no-as-needed() {
esac
}
+# @FUNCTION: _test-compile-PROG
+# @USAGE: <language> <code>
+# @INTERNAL
+# @DESCRIPTION:
+# Attempts to compile (and possibly link) the given program. The first
+# <language> parameter corresponds to the standard -x compiler argument.
+# If the program should additionally be attempted to be linked, the string
+# "+ld" should be added to the <language> parameter.
+_test-compile-PROG() {
+ local lang=$1
+ local code=$2
+ shift 2
+
+ [[ -z "${lang}" ]] && return 1
+ [[ -z "${code}" ]] && return 1
+
+ local compiler filename_in filename_out args=() libs=()
+ case "${lang}" in
+ c)
+ compiler="$(tc-getCC)"
+ filename_in="${T}/test.c"
+ filename_out="${T}/test.o"
+ args+=(${CFLAGS[@]} -xc -c)
+ ;;
+ c++)
+ compiler="$(tc-getCXX)"
+ filename_in="${T}/test.cc"
+ filename_out="${T}/test.o"
+ args+=(${CXXFLAGS[@]} -xc++ -c)
+ ;;
+ f77)
+ compiler="$(tc-getF77)"
+ filename_in="${T}/test.f"
+ filename_out="${T}/test.o"
+ args+=(${FFFLAGS[@]} -xf77 -c)
+ ;;
+ f95)
+ compiler="$(tc-getFC)"
+ filename_in="${T}/test.f90"
+ filename_out="${T}/test.o"
+ args+=(${FCFLAGS[@]} -xf95 -c)
+ ;;
+ c+ld)
+ compiler="$(tc-getCC)"
+ filename_in="${T}/test.c"
+ filename_out="${T}/test.exe"
+ args+=(${CFLAGS[@]} ${LDFLAGS[@]} -xc)
+ libs+=(${LIBS[@]})
+ ;;
+ c+++ld)
+ compiler="$(tc-getCXX)"
+ filename_in="${T}/test.cc"
+ filename_out="${T}/test.exe"
+ args+=(${CXXFLAGS[@]} ${LDFLAGS[@]} -xc++)
+ libs+=(${LIBS[@]})
+ ;;
+ f77+ld)
+ compiler="$(tc-getF77)"
+ filename_in="${T}/test.f"
+ filename_out="${T}/test.exe"
+ args+=(${FFLAGS[@]} ${LDFLAGS[@]} -xf77)
+ libs+=(${LIBS[@]})
+ ;;
+ f95+ld)
+ compiler="$(tc-getFC)"
+ filename_in="${T}/test.f90"
+ filename_out="${T}/test.exe"
+ args+=(${FCFLAGS[@]} ${LDFLAGS[@]} -xf95)
+ libs+=(${LIBS[@]})
+ ;;
+ *)
+ die "Unknown compiled language ${lang}"
+ ;;
+ esac
+
+ printf "%s\n" "${code}" > "${filename_in}" || die "Failed to create '${test_in}'"
+
+ "${compiler}" ${args[@]} "${filename_in}" -o "${filename_out}" ${libs[@]} &>/dev/null
+}
+
+# @FUNCTION: append-atomic-flags
+# @USAGE: [bytes]
+# @DESCRIPTION:
+# Attempts to detect if appending -latomic is required to use
+# a specific-sized atomic intrinsic, and if so, appends it. If the bytesize
+# is not specified, then check the four most common byte sizes (1, 2, 4, 8).
+# >=16-byte atomics are not included in this default set and must be explicitly
+# passed if required. This may require you to add a macro definition like
+# -Duint128_t=__uint128_t to your CFLAGS.
+append-atomic-flags() {
+ # this implementation is as described in bug #820101
+ local code
+
+ # first, ensure we can compile a trivial program
+ # this is because we can't distinguish if _test-compile-PROG
+ # fails because -latomic is actually needed or if we have a
+ # broken toolchain (like due to bad FLAGS)
+ read -r -d '' code <<- EOF
+ int main()
+ {
+ return 0;
+ }
+ EOF
+
+ # if toolchain is broken, just return silently. it's better to
+ # let other pieces of the build fail later down the line than to
+ # make people think that something to do with atomic support is the
+ # cause of their problems.
+ _test-compile-PROG "c+ld" "${code}" || return
+
+ local bytesizes
+ [[ "${#}" == "0" ]] && bytesizes=( "1" "2" "4" "8" ) || bytesizes="${@}"
+
+ for bytesize in ${bytesizes[@]}
+ do
+ # this sample program is informed by the great testing from the buildroot project:
+ # https://github.com/buildroot/buildroot/commit/6856e417da4f3aa77e2a814db2a89429af072f7d
+ read -r -d '' code <<- EOF
+ #include <stdint.h>
+ int main()
+ {
+ uint$((${bytesize} * 8))_t a = 0;
+ __atomic_add_fetch(&a, 3, __ATOMIC_RELAXED);
+ __atomic_compare_exchange_n(&a, &a, 2, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED);
+ return 0;
+ }
+ EOF
+
+ # do nothing if test program links fine
+ _test-compile-PROG "c+ld" "${code}" && continue
+
+ # ensure that the toolchain supports -latomic
+ test-flags-CCLD "-latomic" &>/dev/null || die "-latomic is required but not supported by $(tc-getCC)"
+
+ append-libs "-latomic"
+
+ # verify that this did indeed fix the problem
+ _test-compile-PROG "c+ld" "${code}" || \
+ die "libatomic does not include an implementation of ${bytesize}-byte atomics for this toolchain"
+
+ # if any of the required bytesizes require -latomic, no need to continue
+ # checking the others
+ return
+ done
+}
+
fi