about summary refs log tree commit diff
path: root/pkgs/build-support/bintools-wrapper
diff options
context:
space:
mode:
authorSergei Trofimovich <slyich@gmail.com>2022-07-18 13:11:48 +0100
committerSergei Trofimovich <slyich@gmail.com>2022-07-23 18:40:07 +0100
commit34636efceda7a89d6f0bb66d63e422fd1f215da3 (patch)
tree23a1b23a6d7c97d3c4e5db2e0b45e3ded947bd9f /pkgs/build-support/bintools-wrapper
parentdab3ae9d8be645366d2dc9634cc172983885f9fc (diff)
gcc: pass --with-build-sysroot=/ for gcc builds
Without this change cross-built gcc fails to detect stack protector style:

    $ nix log -f pkgs/stdenv/linux/make-bootstrap-tools-cross.nix powerpc64le.bootGCC | fgrep __stack_chk_fail
    checking __stack_chk_fail in target C library... no
    checking __stack_chk_fail in target C library... no

It happens because gcc treats search paths differently:

    https://gcc.gnu.org/git/?p=gcc.git;a=blob;f=gcc/configure.ac;h=446747311a6aec3c810ad6aa4190f7bd383b94f7;hb=HEAD#l2458

     if test x$host != x$target || test "x$TARGET_SYSTEM_ROOT" != x ||
        test x$build != x$host || test "x$with_build_sysroot" != x; then
       ...
       if test "x$with_build_sysroot" != "x"; then
         target_header_dir="${with_build_sysroot}${native_system_header_dir}"
       elif test "x$with_sysroot" = x; then
         target_header_dir="${test_exec_prefix}/${target_noncanonical}/sys-include"
       elif test "x$with_sysroot" = xyes; then
         target_header_dir="${test_exec_prefix}/${target_noncanonical}/sys-root${native_system_header_dir}"
       else
         target_header_dir="${with_sysroot}${native_system_header_dir}"
       fi
     else
       target_header_dir=${native_system_header_dir}
     fi

By passing --with-build-sysroot=/ we trick cross-case to use
`target_header_dir="${with_sysroot}${native_system_header_dir}"`
which makes it equivalent to non-cross
`target_header_dir="${with_build_sysroot}${native_system_header_dir}"`

Tested the following setups:
- cross-compiler without libc headers (powerpc64le-static)
- cross-compiler with libc headers (powerpc64le-debug)
- cross-build compiler with libc headers (powerpc64le bootstrapTools)

Before the change only 2 of 3 compilers detected libc headers.
After the change all 3 compilers detected libc headers.

For darwin we silently ignore '-syslibroot //' argument as it does not
introduce impurities.

While at it dropped mingw special case for no-libc build. Before the change
we passed both '--without-headers --with-native-system-headers-dir' for
no-libc gcc-static builds. This tricked darwin builds to find sys/sdt.h
and fail inhibid_libc builds. Now all targets avoid passing native headers
for gcc-static builds.

While at it fixed correct headers passing to
--with-native-system-headers-dir= in host != target case: we were passing
host's headers where intention was to pass target's headers.
Noticed the mismatch as a build failure on pkgsCross.powernv.stdenv.cc
on darwin where `sys/sdt.h` is present in host's headers (libSystem)
but not target's headers (`glibc`).

Co-authored-by: Adam Joseph <54836058+amjoseph-nixpkgs@users.noreply.github.com>
Diffstat (limited to 'pkgs/build-support/bintools-wrapper')
-rw-r--r--pkgs/build-support/bintools-wrapper/ld-wrapper.sh5
1 files changed, 5 insertions, 0 deletions
diff --git a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh
index f8bddabbc6871..86a7416022010 100644
--- a/pkgs/build-support/bintools-wrapper/ld-wrapper.sh
+++ b/pkgs/build-support/bintools-wrapper/ld-wrapper.sh
@@ -50,6 +50,11 @@ if [[ "${NIX_ENFORCE_PURITY:-}" = 1 && -n "${NIX_STORE:-}"
             n+=1; skip "$p2"
         elif [ "$p" = -dynamic-linker ] && badPath "$p2"; then
             n+=1; skip "$p2"
+        elif [ "$p" = -syslibroot ] && [ $p2 == // ]; then
+            # When gcc is built on darwin --with-build-sysroot=/
+            # produces '-syslibroot //' linker flag. It's a no-op,
+            # which does not introduce impurities.
+            n+=1; skip "$p2"
         elif [ "${p:0:1}" = / ] && badPath "$p"; then
             # We cannot skip this; barf.
             echo "impure path \`$p' used in link" >&2