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>
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -111,8 +111,30 @@ let
|
||||
"--with-mpc=${libmpc}"
|
||||
]
|
||||
++ lib.optional (libelf != null) "--with-libelf=${libelf}"
|
||||
++ lib.optional (!(crossMingw && crossStageStatic))
|
||||
"--with-native-system-header-dir=${lib.getDev stdenv.cc.libc}/include"
|
||||
++ lib.optionals (!crossStageStatic) [
|
||||
(if libcCross == null
|
||||
then "--with-native-system-header-dir=${lib.getDev stdenv.cc.libc}/include"
|
||||
else "--with-native-system-header-dir=${lib.getDev libcCross}${libcCross.incdir or "/include"}")
|
||||
# gcc builds for cross-compilers (build != host) or cross-built
|
||||
# gcc (host != target) always apply the offset prefix to disentangle
|
||||
# target headers from build or host headers:
|
||||
# ${with_build_sysroot}${native_system_header_dir}
|
||||
# or ${test_exec_prefix}/${target_noncanonical}/sys-include
|
||||
# or ${with_sysroot}${native_system_header_dir}
|
||||
# While native build (build == host == target) uses passed headers
|
||||
# path as is:
|
||||
# ${native_system_header_dir}
|
||||
#
|
||||
# Nixpkgs uses flat directory structure for both native and cross
|
||||
# cases. As a result libc headers don't get found for cross case
|
||||
# and many modern features get disabled (libssp is used instead of
|
||||
# target-specific implementations and similar). More details at:
|
||||
# https://github.com/NixOS/nixpkgs/pull/181802#issuecomment-1186822355
|
||||
#
|
||||
# We pick "/" path to effectively avoid sysroot offset and make it work
|
||||
# as a native case.
|
||||
"--with-build-sysroot=/"
|
||||
]
|
||||
|
||||
# Basic configuration
|
||||
++ [
|
||||
|
||||
Reference in New Issue
Block a user