summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatoro <matoro@users.noreply.github.com>2022-07-10 18:41:17 -0400
committerSam James <sam@gentoo.org>2022-07-20 23:35:14 +0000
commit29cf769f4de6550851e74829c2011c2e23554cc7 (patch)
treef114b67792eed5d051d0649430223521fa60a7f3 /eclass/flag-o-matic.eclass
parentdev-dotnet/dotnet-sdk-bin: fix location of the workloads file (diff)
downloadgentoo-29cf769f4de6550851e74829c2011c2e23554cc7.tar.gz
gentoo-29cf769f4de6550851e74829c2011c2e23554cc7.tar.bz2
gentoo-29cf769f4de6550851e74829c2011c2e23554cc7.zip
flag-o-matic.eclass: implement append-atomic-flags
My take on implementing bug 820101 as conservatively as possible. This will append -latomic only when absolutely necessary (even though it's probably not required to be that conservative due to our use of --as-needed). This will take flags into account when testing as well. For example, if you compile with -march=i386, this would require linking libatomic even if the same toolchain with a higher -march level would not require it. So rebuilding the same package with the same flags may change whether -latomic is linked at build time if the CFLAGS change. Another instance might be switching from GCC to clang - the former requires explicitly linking -latomic, while the latter does not even HAVE libatomic (see bug 820095) as all atomic intrinsics are built-in internally. This function would safely detect this and not append -latomic. There is an optional parameter [bytes]. You can use this if you want to be specific about what size atomic support is required. For example, there are several platforms like MIPS where the 32-bit version has 1-, 2-, and 4-byte atomics builtin but requires libatomic linkage for 8-byte atomics. If your program only requires, say, 4-byte atomics, you can use append-atomic-flags 4 and this will then not attempt to link libatomic on 32-bit MIPS. I tested using this to solve bug 688574 on 32-bit SPARC. Bug: https://bugs.gentoo.org/688574 Bug: https://bugs.gentoo.org/820095 Closes: https://bugs.gentoo.org/820101 Closes: https://github.com/gentoo/gentoo/pull/26334 Signed-off-by: Sam James <sam@gentoo.org>
Diffstat (limited to 'eclass/flag-o-matic.eclass')
-rw-r--r--eclass/flag-o-matic.eclass145
1 files changed, 145 insertions, 0 deletions
diff --git a/eclass/flag-o-matic.eclass b/eclass/flag-o-matic.eclass
index 0dd2c1191273..503f23a141a1 100644
--- a/eclass/flag-o-matic.eclass
+++ b/eclass/flag-o-matic.eclass
@@ -875,4 +875,149 @@ 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