diff options
author | matoro <matoro@users.noreply.github.com> | 2022-07-10 18:41:17 -0400 |
---|---|---|
committer | Sam James <sam@gentoo.org> | 2022-07-20 23:35:14 +0000 |
commit | 29cf769f4de6550851e74829c2011c2e23554cc7 (patch) | |
tree | f114b67792eed5d051d0649430223521fa60a7f3 /eclass/flag-o-matic.eclass | |
parent | dev-dotnet/dotnet-sdk-bin: fix location of the workloads file (diff) | |
download | gentoo-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.eclass | 145 |
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 |