about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBernardo Meurer <bernardo@meurer.org>2022-07-28 00:30:49 -0700
committerGitHub <noreply@github.com>2022-07-28 00:30:49 -0700
commit88c63ca65a30eb83bd2a00d183a9f11819be43ad (patch)
tree28deb0ec736374e6a61478ede77500b1537eb751
parent0049ace2ece4a4555c5582c3b5a74a548cfb60e9 (diff)
parenteece5d0dc0bbd7eaab1f09e608f89449f745003b (diff)
Merge pull request #182513 from trofi/strip-for-host-and-target
gcc: enable stripping for cross-compilers
-rw-r--r--doc/stdenv/stdenv.chapter.md8
-rw-r--r--pkgs/build-support/setup-hooks/strip.sh42
-rw-r--r--pkgs/development/compilers/gcc/10/default.nix16
-rw-r--r--pkgs/development/compilers/gcc/11/default.nix16
-rw-r--r--pkgs/development/compilers/gcc/12/default.nix16
-rw-r--r--pkgs/development/compilers/gcc/4.8/default.nix16
-rw-r--r--pkgs/development/compilers/gcc/4.9/default.nix16
-rw-r--r--pkgs/development/compilers/gcc/6/default.nix16
-rw-r--r--pkgs/development/compilers/gcc/7/default.nix16
-rw-r--r--pkgs/development/compilers/gcc/8/default.nix16
-rw-r--r--pkgs/development/compilers/gcc/9/default.nix16
-rw-r--r--pkgs/development/compilers/gcc/builder.sh5
-rw-r--r--pkgs/development/compilers/gcc/common/strip-attributes.nix53
-rw-r--r--pkgs/top-level/all-packages.nix6
14 files changed, 151 insertions, 107 deletions
diff --git a/doc/stdenv/stdenv.chapter.md b/doc/stdenv/stdenv.chapter.md
index ebfda97ba77ae..da30807beead7 100644
--- a/doc/stdenv/stdenv.chapter.md
+++ b/doc/stdenv/stdenv.chapter.md
@@ -731,6 +731,10 @@ If set, files in `$out/sbin` are not moved to `$out/bin`. By default, they are.
 
 List of directories to search for libraries and executables from which *all* symbols should be stripped. By default, it’s empty. Stripping all symbols is risky, since it may remove not just debug symbols but also ELF information necessary for normal execution.
 
+##### `stripAllListTarget` {#var-stdenv-stripAllListTarget}
+
+Like `stripAllList`, but only applies to packages’ target platform. By default, it’s empty. Useful when supporting cross compilation.
+
 ##### `stripAllFlags` {#var-stdenv-stripAllFlags}
 
 Flags passed to the `strip` command applied to the files in the directories listed in `stripAllList`. Defaults to `-s` (i.e. `--strip-all`).
@@ -739,6 +743,10 @@ Flags passed to the `strip` command applied to the files in the directories list
 
 List of directories to search for libraries and executables from which only debugging-related symbols should be stripped. It defaults to `lib lib32 lib64 libexec bin sbin`.
 
+##### `stripDebugListTarget` {#var-stdenv-stripDebugListTarget}
+
+Like `stripDebugList`, but only applies to packages’ target platform. By default, it’s empty. Useful when supporting cross compilation.
+
 ##### `stripDebugFlags` {#var-stdenv-stripDebugFlags}
 
 Flags passed to the `strip` command applied to the files in the directories listed in `stripDebugList`. Defaults to `-S` (i.e. `--strip-debug`).
diff --git a/pkgs/build-support/setup-hooks/strip.sh b/pkgs/build-support/setup-hooks/strip.sh
index 2d8e66a89fa33..80bc064ced7d3 100644
--- a/pkgs/build-support/setup-hooks/strip.sh
+++ b/pkgs/build-support/setup-hooks/strip.sh
@@ -7,38 +7,39 @@ _doStrip() {
     # to $out anyways---if it does, that's a bigger problem that a lack of
     # stripping will help catch.
     local -ra flags=(dontStripHost dontStripTarget)
-    local -ra stripCmds=(STRIP TARGET_STRIP)
+    local -ra debugDirs=(stripDebugList stripDebugListTarget)
+    local -ra allDirs=(stripAllList stripAllListTarget)
+    local -ra stripCmds=(STRIP STRIP_FOR_TARGET)
+    local -ra ranlibCmds=(RANLIB RANLIB_FOR_TARGET)
 
-    # Optimization
-    if [[ "${STRIP-}" == "${TARGET_STRIP-}" ]]; then
-        dontStripTarget+=1
-    fi
+    # Strip only host paths by default. Leave targets as is.
+    stripDebugList=${stripDebugList:-lib lib32 lib64 libexec bin sbin}
+    stripDebugListTarget=${stripDebugListTarget:-}
+    stripAllList=${stripAllList:-}
+    stripAllListTarget=${stripAllListTarget:-}
 
     local i
     for i in ${!stripCmds[@]}; do
         local -n flag="${flags[$i]}"
+        local -n debugDirList="${debugDirs[$i]}"
+        local -n allDirList="${allDirs[$i]}"
         local -n stripCmd="${stripCmds[$i]}"
+        local -n ranlibCmd="${ranlibCmds[$i]}"
 
         # `dontStrip` disables them all
         if [[ "${dontStrip-}" || "${flag-}" ]] || ! type -f "${stripCmd-}" 2>/dev/null
         then continue; fi
 
-        stripDebugList=${stripDebugList:-lib lib32 lib64 libexec bin sbin}
-        if [ -n "$stripDebugList" ]; then
-            stripDirs "$stripCmd" "$stripDebugList" "${stripDebugFlags:--S}"
-        fi
-
-        stripAllList=${stripAllList:-}
-        if [ -n "$stripAllList" ]; then
-            stripDirs "$stripCmd" "$stripAllList" "${stripAllFlags:--s}"
-        fi
+        stripDirs "$stripCmd" "$ranlibCmd" "$debugDirList" "${stripDebugFlags:--S}"
+        stripDirs "$stripCmd" "$ranlibCmd" "$allDirList" "${stripAllFlags:--s}"
     done
 }
 
 stripDirs() {
     local cmd="$1"
-    local dirs="$2"
-    local stripFlags="$3"
+    local ranlibCmd="$2"
+    local dirs="$3"
+    local stripFlags="$4"
     local dirsNew=
 
     local d
@@ -50,8 +51,13 @@ stripDirs() {
     dirs=${dirsNew}
 
     if [ -n "${dirs}" ]; then
-        header "stripping (with command $cmd and flags $stripFlags) in$dirs"
+        echo "stripping (with command $cmd and flags $stripFlags) in$dirs"
         find $dirs -type f -exec $cmd $stripFlags '{}' \; 2>/dev/null
-        stopNest
+        # 'strip' does not normally preserve archive index in .a files.
+        # This usually causes linking failures against static libs like:
+        #   ld: ...-i686-w64-mingw32-stage-final-gcc-13.0.0-lib/i686-w64-mingw32/lib/libstdc++.dll.a:
+        #     error adding symbols: archive has no index; run ranlib to add one
+        # Restore the index by running 'ranlib'.
+        find $dirs -name '*.a' -type f -exec $ranlibCmd '{}' \; 2>/dev/null
     fi
 }
diff --git a/pkgs/development/compilers/gcc/10/default.nix b/pkgs/development/compilers/gcc/10/default.nix
index aead3fa21fff2..1c223fa82f4a8 100644
--- a/pkgs/development/compilers/gcc/10/default.nix
+++ b/pkgs/development/compilers/gcc/10/default.nix
@@ -24,9 +24,6 @@
 , libcCross ? null
 , threadsCross ? null # for MinGW
 , crossStageStatic ? false
-, # Strip kills static libs of other archs (hence no cross)
-  stripped ? stdenv.hostPlatform.system == stdenv.buildPlatform.system
-          && stdenv.targetPlatform.system == stdenv.hostPlatform.system
 , gnused ? null
 , cloog # unused; just for compat with gcc4, as we override the parameter on some places
 , buildPackages
@@ -86,7 +83,7 @@ let majorVersion = "10";
 in
 
 stdenv.mkDerivation ({
-  pname = "${crossNameAddon}${name}${if stripped then "" else "-debug"}";
+  pname = "${crossNameAddon}${name}";
   inherit version;
 
   builder = ../builder.sh;
@@ -231,9 +228,11 @@ stdenv.mkDerivation ({
     (targetPlatform == hostPlatform && hostPlatform == buildPlatform)
     (if profiledCompiler then "profiledbootstrap" else "bootstrap");
 
-  dontStrip = !stripped;
-
-  installTargets = optional stripped "install-strip";
+  inherit
+    (import ../common/strip-attributes.nix { inherit stdenv; })
+    stripDebugList
+    stripDebugListTarget
+    preFixup;
 
   # https://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
   ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64";
@@ -274,8 +273,7 @@ stdenv.mkDerivation ({
   meta = {
     homepage = "https://gcc.gnu.org/";
     license = lib.licenses.gpl3Plus;  # runtime support libraries are typically LGPLv3+
-    description = "GNU Compiler Collection, version ${version}"
-      + (if stripped then "" else " (with debugging info)");
+    description = "GNU Compiler Collection, version ${version}";
 
     longDescription = ''
       The GNU Compiler Collection includes compiler front ends for C, C++,
diff --git a/pkgs/development/compilers/gcc/11/default.nix b/pkgs/development/compilers/gcc/11/default.nix
index 1522569cccce4..ca3a89af1806c 100644
--- a/pkgs/development/compilers/gcc/11/default.nix
+++ b/pkgs/development/compilers/gcc/11/default.nix
@@ -24,9 +24,6 @@
 , libcCross ? null
 , threadsCross ? null # for MinGW
 , crossStageStatic ? false
-, # Strip kills static libs of other archs (hence no cross)
-  stripped ? stdenv.hostPlatform.system == stdenv.buildPlatform.system
-          && stdenv.targetPlatform.system == stdenv.hostPlatform.system
 , gnused ? null
 , cloog # unused; just for compat with gcc4, as we override the parameter on some places
 , buildPackages
@@ -92,7 +89,7 @@ let majorVersion = "11";
 in
 
 stdenv.mkDerivation ({
-  pname = "${crossNameAddon}${name}${if stripped then "" else "-debug"}";
+  pname = "${crossNameAddon}${name}";
   inherit version;
 
   builder = ../builder.sh;
@@ -239,9 +236,11 @@ stdenv.mkDerivation ({
     (targetPlatform == hostPlatform && hostPlatform == buildPlatform)
     (if profiledCompiler then "profiledbootstrap" else "bootstrap");
 
-  dontStrip = !stripped;
-
-  installTargets = optional stripped "install-strip";
+  inherit
+    (import ../common/strip-attributes.nix { inherit stdenv; })
+    stripDebugList
+    stripDebugListTarget
+    preFixup;
 
   # https://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
   ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64";
@@ -282,8 +281,7 @@ stdenv.mkDerivation ({
   meta = {
     homepage = "https://gcc.gnu.org/";
     license = lib.licenses.gpl3Plus;  # runtime support libraries are typically LGPLv3+
-    description = "GNU Compiler Collection, version ${version}"
-      + (if stripped then "" else " (with debugging info)");
+    description = "GNU Compiler Collection, version ${version}";
 
     longDescription = ''
       The GNU Compiler Collection includes compiler front ends for C, C++,
diff --git a/pkgs/development/compilers/gcc/12/default.nix b/pkgs/development/compilers/gcc/12/default.nix
index 2279a8b5cccc0..6fdc31079a899 100644
--- a/pkgs/development/compilers/gcc/12/default.nix
+++ b/pkgs/development/compilers/gcc/12/default.nix
@@ -24,9 +24,6 @@
 , libcCross ? null
 , threadsCross ? null # for MinGW
 , crossStageStatic ? false
-, # Strip kills static libs of other archs (hence no cross)
-  stripped ? stdenv.hostPlatform.system == stdenv.buildPlatform.system
-          && stdenv.targetPlatform.system == stdenv.hostPlatform.system
 , gnused ? null
 , cloog # unused; just for compat with gcc4, as we override the parameter on some places
 , buildPackages
@@ -89,7 +86,7 @@ let majorVersion = "12";
 in
 
 stdenv.mkDerivation ({
-  pname = "${crossNameAddon}${name}${if stripped then "" else "-debug"}";
+  pname = "${crossNameAddon}${name}";
   inherit version;
 
   builder = ../builder.sh;
@@ -234,9 +231,11 @@ stdenv.mkDerivation ({
     (targetPlatform == hostPlatform && hostPlatform == buildPlatform)
     (if profiledCompiler then "profiledbootstrap" else "bootstrap");
 
-  dontStrip = !stripped;
-
-  installTargets = optional stripped "install-strip";
+  inherit
+    (import ../common/strip-attributes.nix { inherit stdenv; })
+    stripDebugList
+    stripDebugListTarget
+    preFixup;
 
   # https://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
   ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64";
@@ -277,8 +276,7 @@ stdenv.mkDerivation ({
   meta = {
     homepage = "https://gcc.gnu.org/";
     license = lib.licenses.gpl3Plus;  # runtime support libraries are typically LGPLv3+
-    description = "GNU Compiler Collection, version ${version}"
-      + (if stripped then "" else " (with debugging info)");
+    description = "GNU Compiler Collection, version ${version}";
 
     longDescription = ''
       The GNU Compiler Collection includes compiler front ends for C, C++,
diff --git a/pkgs/development/compilers/gcc/4.8/default.nix b/pkgs/development/compilers/gcc/4.8/default.nix
index 473bd39e406f2..bc93d6e135857 100644
--- a/pkgs/development/compilers/gcc/4.8/default.nix
+++ b/pkgs/development/compilers/gcc/4.8/default.nix
@@ -28,9 +28,6 @@
 , libcCross ? null
 , threadsCross ? null # for MinGW
 , crossStageStatic ? false
-, # Strip kills static libs of other archs (hence no cross)
-  stripped ? stdenv.hostPlatform == stdenv.buildPlatform
-          && stdenv.targetPlatform == stdenv.hostPlatform
 , gnused ? null
 , buildPackages
 }:
@@ -124,7 +121,7 @@ in
 assert x11Support -> (filter (x: x == null) ([ gtk2 libart_lgpl ] ++ xlibs)) == [];
 
 stdenv.mkDerivation ({
-  pname = "${crossNameAddon}${name}${if stripped then "" else "-debug"}";
+  pname = "${crossNameAddon}${name}";
   inherit version;
 
   builder = ../builder.sh;
@@ -238,12 +235,14 @@ stdenv.mkDerivation ({
     (targetPlatform == hostPlatform && hostPlatform == buildPlatform)
     (if profiledCompiler then "profiledbootstrap" else "bootstrap");
 
-  dontStrip = !stripped;
+  inherit
+    (import ../common/strip-attributes.nix { inherit stdenv; })
+    stripDebugList
+    stripDebugListTarget
+    preFixup;
 
   doCheck = false; # requires a lot of tools, causes a dependency cycle for stdenv
 
-  installTargets = optional stripped "install-strip";
-
   # https://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
   ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64";
 
@@ -297,8 +296,7 @@ stdenv.mkDerivation ({
   meta = {
     homepage = "https://gcc.gnu.org/";
     license = lib.licenses.gpl3Plus;  # runtime support libraries are typically LGPLv3+
-    description = "GNU Compiler Collection, version ${version}"
-      + (if stripped then "" else " (with debugging info)");
+    description = "GNU Compiler Collection, version ${version}";
 
     longDescription = ''
       The GNU Compiler Collection includes compiler front ends for C, C++,
diff --git a/pkgs/development/compilers/gcc/4.9/default.nix b/pkgs/development/compilers/gcc/4.9/default.nix
index 9d9dae41c453c..cc675de22549a 100644
--- a/pkgs/development/compilers/gcc/4.9/default.nix
+++ b/pkgs/development/compilers/gcc/4.9/default.nix
@@ -28,9 +28,6 @@
 , libcCross ? null
 , threadsCross ? null # for MinGW
 , crossStageStatic ? false
-, # Strip kills static libs of other archs (hence no cross)
-  stripped ? stdenv.hostPlatform == stdenv.buildPlatform
-          && stdenv.targetPlatform == stdenv.hostPlatform
 , gnused ? null
 , buildPackages
 }:
@@ -140,7 +137,7 @@ in
 assert x11Support -> (filter (x: x == null) ([ gtk2 libart_lgpl ] ++ xlibs)) == [];
 
 stdenv.mkDerivation ({
-  pname = "${crossNameAddon}${name}${if stripped then "" else "-debug"}";
+  pname = "${crossNameAddon}${name}";
   inherit version;
 
   builder = ../builder.sh;
@@ -258,12 +255,14 @@ stdenv.mkDerivation ({
     (targetPlatform == hostPlatform && hostPlatform == buildPlatform)
     (if profiledCompiler then "profiledbootstrap" else "bootstrap");
 
-  dontStrip = !stripped;
+  inherit
+    (import ../common/strip-attributes.nix { inherit stdenv; })
+    stripDebugList
+    stripDebugListTarget
+    preFixup;
 
   doCheck = false; # requires a lot of tools, causes a dependency cycle for stdenv
 
-  installTargets = optional stripped "install-strip";
-
   # https://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
   ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64";
 
@@ -316,8 +315,7 @@ stdenv.mkDerivation ({
   meta = {
     homepage = "https://gcc.gnu.org/";
     license = lib.licenses.gpl3Plus;  # runtime support libraries are typically LGPLv3+
-    description = "GNU Compiler Collection, version ${version}"
-      + (if stripped then "" else " (with debugging info)");
+    description = "GNU Compiler Collection, version ${version}";
 
     longDescription = ''
       The GNU Compiler Collection includes compiler front ends for C, C++,
diff --git a/pkgs/development/compilers/gcc/6/default.nix b/pkgs/development/compilers/gcc/6/default.nix
index a5be86ca05220..d108dc11f18c1 100644
--- a/pkgs/development/compilers/gcc/6/default.nix
+++ b/pkgs/development/compilers/gcc/6/default.nix
@@ -31,9 +31,6 @@
 , libcCross ? null
 , threadsCross ? null # for MinGW
 , crossStageStatic ? false
-, # Strip kills static libs of other archs (hence no cross)
-  stripped ? stdenv.hostPlatform.system == stdenv.buildPlatform.system
-          && stdenv.targetPlatform.system == stdenv.hostPlatform.system
 , gnused ? null
 , cloog # unused; just for compat with gcc4, as we override the parameter on some places
 , buildPackages
@@ -121,7 +118,7 @@ in
 assert x11Support -> (filter (x: x == null) ([ gtk2 libart_lgpl ] ++ xlibs)) == [];
 
 stdenv.mkDerivation ({
-  pname = "${crossNameAddon}${name}${if stripped then "" else "-debug"}";
+  pname = "${crossNameAddon}${name}";
   inherit version;
 
   builder = ../builder.sh;
@@ -270,12 +267,14 @@ stdenv.mkDerivation ({
     (targetPlatform == hostPlatform && hostPlatform == buildPlatform)
     (if profiledCompiler then "profiledbootstrap" else "bootstrap");
 
-  dontStrip = !stripped;
+  inherit
+    (import ../common/strip-attributes.nix { inherit stdenv; })
+    stripDebugList
+    stripDebugListTarget
+    preFixup;
 
   doCheck = false; # requires a lot of tools, causes a dependency cycle for stdenv
 
-  installTargets = optional stripped "install-strip";
-
   # https://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
   ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64";
 
@@ -328,8 +327,7 @@ stdenv.mkDerivation ({
   meta = {
     homepage = "https://gcc.gnu.org/";
     license = lib.licenses.gpl3Plus;  # runtime support libraries are typically LGPLv3+
-    description = "GNU Compiler Collection, version ${version}"
-      + (if stripped then "" else " (with debugging info)");
+    description = "GNU Compiler Collection, version ${version}";
 
     longDescription = ''
       The GNU Compiler Collection includes compiler front ends for C, C++,
diff --git a/pkgs/development/compilers/gcc/7/default.nix b/pkgs/development/compilers/gcc/7/default.nix
index 7a9a6938fe76e..e4e1f2038de54 100644
--- a/pkgs/development/compilers/gcc/7/default.nix
+++ b/pkgs/development/compilers/gcc/7/default.nix
@@ -21,9 +21,6 @@
 , libcCross ? null
 , threadsCross ? null # for MinGW
 , crossStageStatic ? false
-, # Strip kills static libs of other archs (hence no cross)
-  stripped ? stdenv.hostPlatform.system == stdenv.buildPlatform.system
-          && stdenv.targetPlatform.system == stdenv.hostPlatform.system
 , gnused ? null
 , cloog # unused; just for compat with gcc4, as we override the parameter on some places
 , buildPackages
@@ -94,7 +91,7 @@ let majorVersion = "7";
 in
 
 stdenv.mkDerivation ({
-  pname = "${crossNameAddon}${name}${if stripped then "" else "-debug"}";
+  pname = "${crossNameAddon}${name}";
   inherit version;
 
   builder = ../builder.sh;
@@ -237,12 +234,14 @@ stdenv.mkDerivation ({
     (targetPlatform == hostPlatform && hostPlatform == buildPlatform)
     (if profiledCompiler then "profiledbootstrap" else "bootstrap");
 
-  dontStrip = !stripped;
+  inherit
+    (import ../common/strip-attributes.nix { inherit stdenv; })
+    stripDebugList
+    stripDebugListTarget
+    preFixup;
 
   doCheck = false; # requires a lot of tools, causes a dependency cycle for stdenv
 
-  installTargets = optional stripped "install-strip";
-
   # https://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
   ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64";
 
@@ -282,8 +281,7 @@ stdenv.mkDerivation ({
   meta = {
     homepage = "https://gcc.gnu.org/";
     license = lib.licenses.gpl3Plus;  # runtime support libraries are typically LGPLv3+
-    description = "GNU Compiler Collection, version ${version}"
-      + (if stripped then "" else " (with debugging info)");
+    description = "GNU Compiler Collection, version ${version}";
 
     longDescription = ''
       The GNU Compiler Collection includes compiler front ends for C, C++,
diff --git a/pkgs/development/compilers/gcc/8/default.nix b/pkgs/development/compilers/gcc/8/default.nix
index 427244016ae19..7e94ec61c6b7e 100644
--- a/pkgs/development/compilers/gcc/8/default.nix
+++ b/pkgs/development/compilers/gcc/8/default.nix
@@ -21,9 +21,6 @@
 , libcCross ? null
 , threadsCross ? null # for MinGW
 , crossStageStatic ? false
-, # Strip kills static libs of other archs (hence no cross)
-  stripped ? stdenv.hostPlatform.system == stdenv.buildPlatform.system
-          && stdenv.targetPlatform.system == stdenv.hostPlatform.system
 , gnused ? null
 , cloog # unused; just for compat with gcc4, as we override the parameter on some places
 , buildPackages
@@ -78,7 +75,7 @@ let majorVersion = "8";
 in
 
 stdenv.mkDerivation ({
-  pname = "${crossNameAddon}${name}${if stripped then "" else "-debug"}";
+  pname = "${crossNameAddon}${name}";
   inherit version;
 
   builder = ../builder.sh;
@@ -218,9 +215,11 @@ stdenv.mkDerivation ({
     (targetPlatform == hostPlatform && hostPlatform == buildPlatform)
     (if profiledCompiler then "profiledbootstrap" else "bootstrap");
 
-  dontStrip = !stripped;
-
-  installTargets = optional stripped "install-strip";
+  inherit
+    (import ../common/strip-attributes.nix { inherit stdenv; })
+    stripDebugList
+    stripDebugListTarget
+    preFixup;
 
   # https://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
   ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64";
@@ -261,8 +260,7 @@ stdenv.mkDerivation ({
   meta = {
     homepage = "https://gcc.gnu.org/";
     license = lib.licenses.gpl3Plus;  # runtime support libraries are typically LGPLv3+
-    description = "GNU Compiler Collection, version ${version}"
-      + (if stripped then "" else " (with debugging info)");
+    description = "GNU Compiler Collection, version ${version}";
 
     longDescription = ''
       The GNU Compiler Collection includes compiler front ends for C, C++,
diff --git a/pkgs/development/compilers/gcc/9/default.nix b/pkgs/development/compilers/gcc/9/default.nix
index 6025603644522..707ead542f06b 100644
--- a/pkgs/development/compilers/gcc/9/default.nix
+++ b/pkgs/development/compilers/gcc/9/default.nix
@@ -24,9 +24,6 @@
 , libcCross ? null
 , threadsCross ? null # for MinGW
 , crossStageStatic ? false
-, # Strip kills static libs of other archs (hence no cross)
-  stripped ? stdenv.hostPlatform.system == stdenv.buildPlatform.system
-          && stdenv.targetPlatform.system == stdenv.hostPlatform.system
 , gnused ? null
 , cloog # unused; just for compat with gcc4, as we override the parameter on some places
 , buildPackages
@@ -89,7 +86,7 @@ let majorVersion = "9";
 in
 
 stdenv.mkDerivation ({
-  pname = "${crossNameAddon}${name}${if stripped then "" else "-debug"}";
+  pname = "${crossNameAddon}${name}";
   inherit version;
 
   builder = ../builder.sh;
@@ -233,9 +230,11 @@ stdenv.mkDerivation ({
     (targetPlatform == hostPlatform && hostPlatform == buildPlatform)
     (if profiledCompiler then "profiledbootstrap" else "bootstrap");
 
-  dontStrip = !stripped;
-
-  installTargets = optional stripped "install-strip";
+  inherit
+    (import ../common/strip-attributes.nix { inherit stdenv; })
+    stripDebugList
+    stripDebugListTarget
+    preFixup;
 
   # https://gcc.gnu.org/install/specific.html#x86-64-x-solaris210
   ${if hostPlatform.system == "x86_64-solaris" then "CC" else null} = "gcc -m64";
@@ -276,8 +275,7 @@ stdenv.mkDerivation ({
   meta = {
     homepage = "https://gcc.gnu.org/";
     license = lib.licenses.gpl3Plus;  # runtime support libraries are typically LGPLv3+
-    description = "GNU Compiler Collection, version ${version}"
-      + (if stripped then "" else " (with debugging info)");
+    description = "GNU Compiler Collection, version ${version}";
 
     longDescription = ''
       The GNU Compiler Collection includes compiler front ends for C, C++,
diff --git a/pkgs/development/compilers/gcc/builder.sh b/pkgs/development/compilers/gcc/builder.sh
index 187bf84068206..a9b33d9a3e4f5 100644
--- a/pkgs/development/compilers/gcc/builder.sh
+++ b/pkgs/development/compilers/gcc/builder.sh
@@ -147,11 +147,6 @@ if test "$noSysDirs" = "1"; then
     fi
 fi
 
-if [ -n "${targetConfig-}" ]; then
-    # if stripping gcc, include target directory too
-    stripDebugList="${stripDebugList-lib lib32 lib64 libexec bin sbin} $targetConfig"
-fi
-
 eval "$oldOpts"
 
 providedPreConfigure="$preConfigure";
diff --git a/pkgs/development/compilers/gcc/common/strip-attributes.nix b/pkgs/development/compilers/gcc/common/strip-attributes.nix
new file mode 100644
index 0000000000000..997c068cba623
--- /dev/null
+++ b/pkgs/development/compilers/gcc/common/strip-attributes.nix
@@ -0,0 +1,53 @@
+{ stdenv }:
+
+{
+  # Note [Cross-compiler stripping]
+  # gcc requires delicate stripping as it installs ELF files for both
+  # HOST and TARGET platforms. It requires according strip tool otherwise
+  # strip could remove sections it's not aware of.
+  # Example ARM breakage by x86_64 strip: https://bugs.gentoo.org/697428
+  #
+  # Let's recap the file layout for directories with object files for a
+  # cross-compiler (host != target):
+  # `- bin: HOST
+  #    lib/*.{a,o}: HOST
+  #      `- gcc/<TARGET>/<VERSION>/*.{a,o}: TARGET
+  #                               `- plugin/: HOST
+  #  `- lib{,32,64,x32}: symlink to lib or identical layout
+  #  `- libexec/: HOST
+  #  `- <TARGET>/: TARGET
+  #
+  # (host == target) has identical directory layout.
+
+  # The rest of stripDebugList{Host,Target} will be populated in
+  # postInstall.
+  stripDebugList = [ "bin" "libexec" ];
+  stripDebugListTarget = [ stdenv.targetPlatform.config ];
+
+  preFixup = ''
+    # Populate most delicated lib/ part of stripDebugList{,Target}
+    updateDebugListPaths() {
+      local oldOpts
+      oldOpts="$(shopt -p nullglob)" || true
+      shopt -s nullglob
+
+      pushd $out
+
+      local -ar hostFiles=(
+        lib{,32,64}/*.{a.o}
+        lib{,32,64}/gcc/${stdenv.targetPlatform.config}/*/plugin
+      )
+      local -ar targetFiles=(
+        lib{,32,64}/gcc/${stdenv.targetPlatform.config}/*/*.{a.o}
+      )
+
+      stripDebugList="$stripDebugList ''${hostFiles[*]}"
+      stripDebugListTarget="$stripDebugListTarget ''${targetFiles[*]}"
+
+      popd
+
+      eval "$oldOpts"
+    }
+    updateDebugListPaths
+  '';
+}
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index 0bb78fed352a3..2d30760722d61 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -13001,9 +13001,9 @@ with pkgs;
   clangMultiStdenv = overrideCC stdenv buildPackages.clang_multi;
   multiStdenv = if stdenv.cc.isClang then clangMultiStdenv else gccMultiStdenv;
 
-  gcc_debug = lowPrio (wrapCC (gcc.cc.override {
-    stripped = false;
-  }));
+  gcc_debug = lowPrio (wrapCC (gcc.cc.overrideAttrs (_: {
+    dontStrip = true;
+  })));
 
   gccCrossLibcStdenv = overrideCC stdenv buildPackages.gccCrossStageStatic;