summary refs log tree commit diff
path: root/pkgs
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2015-09-17 15:24:32 +0200
committerEelco Dolstra <eelco.dolstra@logicblox.com>2015-09-17 15:56:33 +0200
commitec5b66eb4add9d494d8fb16f6899028750d317a2 (patch)
tree2e973c6d3e89612cfeba5eafac4810dc968bebf9 /pkgs
parentedee7f172098921f13466bc1d82faee423035700 (diff)
downloadnixlib-ec5b66eb4add9d494d8fb16f6899028750d317a2.tar
nixlib-ec5b66eb4add9d494d8fb16f6899028750d317a2.tar.gz
nixlib-ec5b66eb4add9d494d8fb16f6899028750d317a2.tar.bz2
nixlib-ec5b66eb4add9d494d8fb16f6899028750d317a2.tar.lz
nixlib-ec5b66eb4add9d494d8fb16f6899028750d317a2.tar.xz
nixlib-ec5b66eb4add9d494d8fb16f6899028750d317a2.tar.zst
nixlib-ec5b66eb4add9d494d8fb16f6899028750d317a2.zip
Enable separate debug info
You can now pass

  separateDebugInfo = true;

to mkDerivation. This causes debug info to be separated from ELF
binaries and stored in the "debug" output. The advantage is that it
enables installing lean binaries, while still having the ability to
make sense of core dumps, etc.
Diffstat (limited to 'pkgs')
-rw-r--r--pkgs/applications/misc/hello/ex-2/default.nix4
-rw-r--r--pkgs/build-support/setup-hooks/separate-debug-info.sh37
-rw-r--r--pkgs/stdenv/generic/default.nix34
-rw-r--r--pkgs/tools/package-management/nix/default.nix4
-rw-r--r--pkgs/top-level/all-packages.nix2
5 files changed, 65 insertions, 16 deletions
diff --git a/pkgs/applications/misc/hello/ex-2/default.nix b/pkgs/applications/misc/hello/ex-2/default.nix
index 8a31c591b29b..bb91c90e2fcf 100644
--- a/pkgs/applications/misc/hello/ex-2/default.nix
+++ b/pkgs/applications/misc/hello/ex-2/default.nix
@@ -8,7 +8,9 @@ stdenv.mkDerivation rec {
     sha256 = "0ssi1wpaf7plaswqqjwigppsg5fyh99vdlb9kzl7c9lng89ndq1i";
   };
 
-  doCheck = true;
+  doCheck = false;
+
+  separateDebugInfo = true;
 
   meta = {
     description = "A program that produces a familiar, friendly greeting";
diff --git a/pkgs/build-support/setup-hooks/separate-debug-info.sh b/pkgs/build-support/setup-hooks/separate-debug-info.sh
new file mode 100644
index 000000000000..636918992090
--- /dev/null
+++ b/pkgs/build-support/setup-hooks/separate-debug-info.sh
@@ -0,0 +1,37 @@
+export NIX_LDFLAGS+=" --build-id"
+export NIX_CFLAGS_COMPILE+=" -ggdb"
+dontStrip=1
+
+fixupOutputHooks+=(_separateDebugInfo)
+
+_separateDebugInfo() {
+    local dst="${debug:-$out}"
+    if [ "$prefix" = "$dst" ]; then return; fi
+
+    dst="$dst/lib/debug/.build-id"
+
+    # Find executables and dynamic libraries.
+    local -a files=($(find "$prefix" -type f -a \( -perm /0100 -o -name "*.so" -o -name "*.so.*" \)))
+
+    local i magic
+    for i in "${files[@]}"; do
+        # Skip non-ELF files.
+        exec 10< "$i"
+        read -n 4 -u 10 magic
+        if [[ "$magic" =~ ELF ]]; then echo FOO; fi
+        exec 10<&-
+
+        # Extract the Build ID. FIXME: there's probably a cleaner way.
+        local id="$(readelf -n "$i" | sed 's/.*Build ID: \([0-9a-f]*\).*/\1/; t; d')"
+        if [ "${#id}" != 40 ]; then
+            echo "could not find build ID of $i, skipping" >&2
+            continue
+        fi
+
+        # Extract the debug info.
+        header "separating debug info from $i (build ID $id)"
+        mkdir -p "$dst/${id:0:2}"
+        objcopy --only-keep-debug "$i" "$dst/${id:0:2}/${id:2}.debug"
+        strip --strip-debug "$i"
+    done
+}
diff --git a/pkgs/stdenv/generic/default.nix b/pkgs/stdenv/generic/default.nix
index 249e4845bc28..778b3365b478 100644
--- a/pkgs/stdenv/generic/default.nix
+++ b/pkgs/stdenv/generic/default.nix
@@ -96,6 +96,10 @@ let
     , meta ? {}
     , passthru ? {}
     , pos ? null # position used in error messages and for meta.position
+    , separateDebugInfo ? false
+    , outputs ? [ "out" ]
+    , __impureHostDeps ? []
+    , __propagatedImpureHostDeps ? []
     , ... } @ attrs:
     let
       pos' =
@@ -132,6 +136,13 @@ let
           throwEvalHelp "Broken" "is not supported on ‘${result.system}’"
         else true;
 
+      outputs' =
+        outputs ++
+        (if separateDebugInfo then [ "debug" ] else []);
+
+      buildInputs' = buildInputs ++
+        (if separateDebugInfo then [ ../../build-support/setup-hooks/separate-debug-info.sh ] else []);
+
     in
       assert licenseAllowed attrs;
 
@@ -140,18 +151,11 @@ let
           ["meta" "passthru" "crossAttrs" "pos"
            "__impureHostDeps" "__propagatedImpureHostDeps"])
         // (let
-          buildInputs = attrs.buildInputs or [];
-          nativeBuildInputs = attrs.nativeBuildInputs or [];
-          propagatedBuildInputs = attrs.propagatedBuildInputs or [];
-          propagatedNativeBuildInputs = attrs.propagatedNativeBuildInputs or [];
-          crossConfig = attrs.crossConfig or null;
-
-          __impureHostDeps = attrs.__impureHostDeps or [];
-          __propagatedImpureHostDeps = attrs.__propagatedImpureHostDeps or [];
-
           # TODO: remove lib.unique once nix has a list canonicalization primitive
-          computedImpureHostDeps           = lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) (extraBuildInputs ++ buildInputs ++ nativeBuildInputs));
-          computedPropagatedImpureHostDeps = lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) (propagatedBuildInputs ++ propagatedNativeBuildInputs));
+          computedImpureHostDeps =
+            lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) (extraBuildInputs ++ buildInputs ++ nativeBuildInputs));
+          computedPropagatedImpureHostDeps =
+            lib.unique (lib.concatMap (input: input.__propagatedImpureHostDeps or []) (propagatedBuildInputs ++ propagatedNativeBuildInputs));
         in
         {
           builder = attrs.realBuilder or shell;
@@ -162,10 +166,10 @@ let
           __ignoreNulls = true;
 
           # Inputs built by the cross compiler.
-          buildInputs = if crossConfig != null then buildInputs else [];
+          buildInputs = if crossConfig != null then buildInputs' else [];
           propagatedBuildInputs = if crossConfig != null then propagatedBuildInputs else [];
           # Inputs built by the usual native compiler.
-          nativeBuildInputs = nativeBuildInputs ++ (if crossConfig == null then buildInputs else []);
+          nativeBuildInputs = nativeBuildInputs ++ (if crossConfig == null then buildInputs' else []);
           propagatedNativeBuildInputs = propagatedNativeBuildInputs ++
             (if crossConfig == null then propagatedBuildInputs else []);
         } // ifDarwin {
@@ -176,7 +180,9 @@ let
             "/bin/sh"
           ];
           __propagatedImpureHostDeps = computedPropagatedImpureHostDeps ++ __propagatedImpureHostDeps;
-        }))) (
+        } // (if outputs' != [ "out" ] then {
+          outputs = outputs';
+        } else { })))) (
       {
         # The meta attribute is passed in the resulting attribute set,
         # but it's not part of the actual derivation, i.e., it's not
diff --git a/pkgs/tools/package-management/nix/default.nix b/pkgs/tools/package-management/nix/default.nix
index 7db46596eec7..8a301f912b81 100644
--- a/pkgs/tools/package-management/nix/default.nix
+++ b/pkgs/tools/package-management/nix/default.nix
@@ -41,7 +41,9 @@ let
 
     installFlags = "sysconfdir=$(out)/etc";
 
-    doInstallCheck = true;
+    doInstallCheck = false;
+
+    separateDebugInfo = true;
 
     crossAttrs = {
       postUnpack =
diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix
index e4a8fb9d46cb..486fcb8c6333 100644
--- a/pkgs/top-level/all-packages.nix
+++ b/pkgs/top-level/all-packages.nix
@@ -477,6 +477,8 @@ let
     deps = [ makeWrapper ];
   } ../build-support/setup-hooks/wrap-gapps-hook.sh;
 
+  separateDebugInfo = makeSetupHook { } ../build-support/setup-hooks/separate-debug-info.sh;
+
 
   ### TOOLS