Skip to content

Commit

Permalink
Try #1050:
Browse files Browse the repository at this point in the history
  • Loading branch information
iohk-bors[bot] committed Feb 22, 2021
2 parents 27a5268 + aebc1ae commit f09cddf
Show file tree
Hide file tree
Showing 14 changed files with 157 additions and 20 deletions.
21 changes: 16 additions & 5 deletions builder/comp-builder.nix
@@ -1,4 +1,4 @@
{ pkgs, stdenv, buildPackages, ghc, lib, gobject-introspection ? null, haskellLib, makeConfigFiles, haddockBuilder, ghcForComponent, hsPkgs, compiler, runCommand, libffi, gmp, zlib, ncurses, numactl, nodejs }:
{ pkgs, stdenv, buildPackages, ghc, lib, gobject-introspection ? null, haskellLib, makeConfigFiles, haddockBuilder, ghcForComponent, hsPkgs, compiler, runCommand, libffi, gmp, zlib, ncurses, numactl, nodejs }@defaults:
lib.makeOverridable (
let self =
{ componentId
Expand Down Expand Up @@ -77,6 +77,16 @@ let self =
}@drvArgs:

let
# Ignore attempts to include DWARF info when it is not possible
enableDWARF = drvArgs.enableDWARF or false
&& stdenv.hostPlatform.isLinux
&& !haskellLib.isCrossHost
&& !stdenv.hostPlatform.isMusl
&& builtins.compareVersions defaults.ghc.version "8.10.2" >= 0;

ghc = if enableDWARF then defaults.ghc.dwarf else defaults.ghc;
setup = if enableDWARF then drvArgs.setup.dwarf else drvArgs.setup;

# TODO fix cabal wildcard support so hpack wildcards can be mapped to cabal wildcards
canCleanSource = !(cabal-generator == "hpack" && !(package.cleanHpack or false));
# In order to support relative references to other packages we need to use
Expand Down Expand Up @@ -109,7 +119,7 @@ let

configFiles = makeConfigFiles {
inherit (package) identifier;
inherit component fullName flags needsProfiling;
inherit component fullName flags needsProfiling enableDWARF;
};

enableFeature = enable: feature:
Expand Down Expand Up @@ -178,7 +188,7 @@ let
++ (ghc.extraConfigureFlags or [])
++ lib.optional enableDebugRTS "--ghc-option=-debug"
++ lib.optional enableTSanRTS "--ghc-option=-tsan"
++ lib.optional enableDWARF "--ghc-option=-g"
++ lib.optional enableDWARF "--ghc-option=-g3"
++ lib.optionals useLLVM [
"--ghc-option=-fPIC" "--gcc-option=-fPIC"
]
Expand All @@ -195,7 +205,7 @@ let
# work in the nix-shell. See ../doc/removing-with-package-wrapper.md.
shellWrappers = ghcForComponent {
componentName = fullName;
inherit configFiles;
inherit configFiles enableDWARF;
};

# In order to let shell hooks make package-specific things like Hoogle databases
Expand Down Expand Up @@ -280,10 +290,11 @@ let
config = component;
srcSubDir = cleanSrc.subDir;
srcSubDirPath = cleanSrc.root + cleanSrc.subDir;
inherit configFiles executableToolDepends exeName;
inherit configFiles executableToolDepends exeName enableDWARF;
exePath = drv + "/bin/${exeName}";
env = shellWrappers;
profiled = self (drvArgs // { enableLibraryProfiling = true; });
dwarf = self (drvArgs // { enableDWARF = true; });
} // lib.optionalAttrs (haskellLib.isLibrary componentId) ({
inherit haddock;
inherit (haddock) haddockDir; # This is null if `doHaddock = false`
Expand Down
5 changes: 4 additions & 1 deletion builder/ghc-for-component-wrapper.nix
Expand Up @@ -7,14 +7,17 @@
# database.

{ lib, stdenv, ghc, runCommand, lndir, makeWrapper, haskellLib
}:
}@defaults:

{ componentName # Full derivation name of the component
, configFiles # The component's "config" derivation
, postInstall ? ""
, enableDWARF
}:

let
ghc = if enableDWARF then defaults.ghc.dwarf else defaults.ghc;

inherit (configFiles) targetPrefix ghcCommand ghcCommandCaps packageCfgDir;
libDir = "$out/${configFiles.libDir}";
docDir = "$out/share/doc/ghc/html";
Expand Down
1 change: 1 addition & 0 deletions builder/haddock-builder.nix
Expand Up @@ -54,6 +54,7 @@ let
shellWrappers = ghcForComponent {
componentName = fullName;
configFiles = docsConfigFiles;
inherit (componentDrv) enableDWARF;
};

drv = stdenv.mkDerivation (commonAttrs // {
Expand Down
11 changes: 7 additions & 4 deletions builder/make-config-files.nix
@@ -1,8 +1,10 @@
{ stdenv, lib, haskellLib, ghc, nonReinstallablePkgs, runCommand, writeText, writeScript }:
{ stdenv, lib, haskellLib, ghc, nonReinstallablePkgs, runCommand, writeText, writeScript }@defaults:

{ identifier, component, fullName, flags ? {}, needsProfiling ? false, chooseDrv ? drv: drv }:
{ identifier, component, fullName, flags ? {}, needsProfiling ? false, enableDWARF ? false, chooseDrv ? drv: drv }:

let
ghc = if enableDWARF then defaults.ghc.dwarf else defaults.ghc;

flagsAndConfig = field: xs: lib.optionalString (xs != []) ''
echo ${lib.concatStringsSep " " (map (x: "--${field}=${x}") xs)} >> $out/configure-flags
echo "${field}: ${lib.concatStringsSep " " xs}" >> $out/cabal.config
Expand Down Expand Up @@ -47,9 +49,10 @@ let
# TODO investigate why this is needed
# TODO find out why p ? configFiles helps (for instance for `R1909.aarch64-unknown-linux-gnu.tests.cabal-22.run.x86_64-linux`)
libDeps = map chooseDrv (
(if needsProfiling then (x: map (p: p.profiled or p) x) else x: x)
(if enableDWARF then (x: map (p: p.dwarf or p) x) else x: x)
((if needsProfiling then (x: map (p: p.profiled or p) x) else x: x)
(lib.filter (p: (p ? configFiles) && p.configFiles.targetPrefix == ghc.targetPrefix)
(map getLibComponent component.depends))
(map getLibComponent component.depends)))
);
cfgFiles =
let xs = map
Expand Down
10 changes: 6 additions & 4 deletions builder/setup-builder.nix
@@ -1,12 +1,13 @@
{ pkgs, stdenv, lib, buildPackages, haskellLib, ghc, nonReinstallablePkgs, hsPkgs, makeSetupConfigFiles, pkgconfig }:

{ component, package, name, src, flags ? {}, revision ? null, patches ? [], defaultSetupSrc
let self =
{ component, package, name, src, enableDWARF ? false, flags ? {}, revision ? null, patches ? [], defaultSetupSrc
, preUnpack ? component.preUnpack, postUnpack ? component.postUnpack
, prePatch ? null, postPatch ? null
, preBuild ? component.preBuild , postBuild ? component.postBuild
, preInstall ? component.preInstall , postInstall ? component.postInstall
, cleanSrc ? haskellLib.cleanCabalComponent package component "setup" src
}:
}@drvArgs:

let
cleanSrc' = haskellLib.rootAndSubDir cleanSrc;
Expand All @@ -17,7 +18,7 @@ let

configFiles = makeSetupConfigFiles {
inherit (package) identifier;
inherit fullName flags component;
inherit fullName flags component enableDWARF;
};
hooks = haskellLib.optionalHooks {
inherit
Expand Down Expand Up @@ -50,6 +51,7 @@ let
srcSubDirPath = cleanSrc'.root + cleanSrc'.subDir;
cleanSrc = cleanSrc';
inherit configFiles;
dwarf = self (drvArgs // { enableDWARF = true; });
};

meta = {
Expand Down Expand Up @@ -94,4 +96,4 @@ let
// (lib.optionalAttrs (patches != []) { patches = map (p: if builtins.isFunction p then p { inherit (package.identifier) version; inherit revision; } else p) patches; })
// hooks
);
in drv
in drv; in self
2 changes: 2 additions & 0 deletions builder/shell-for.nix
Expand Up @@ -16,6 +16,7 @@
, exactDeps ? false
, tools ? {}
, packageSetupDeps ? true
, enableDWARF ? false
, ... } @ args:

let
Expand Down Expand Up @@ -93,6 +94,7 @@ let
postInstall = lib.optionalString withHoogle' ''
ln -s ${hoogleIndex}/bin/hoogle $out/bin
'';
inherit enableDWARF;
};

hoogleIndex = let
Expand Down
7 changes: 6 additions & 1 deletion compiler/ghc/configured-src.nix
Expand Up @@ -9,6 +9,7 @@
, useLLVM, llvmPackages
, targetCC
, enableIntegerSimple, targetGmp
, enableDWARF, elfutils
, ncurses, targetLibffi, libiconv
, disableLargeAddressSpace
, buildMK
Expand Down Expand Up @@ -112,7 +113,11 @@ stdenv.mkDerivation (rec {
"CFLAGS=-fuse-ld=gold"
"CONF_GCC_LINKER_OPTS_STAGE1=-fuse-ld=gold"
"CONF_GCC_LINKER_OPTS_STAGE2=-fuse-ld=gold"
] ;
] ++ lib.optionals enableDWARF [
"--enable-dwarf-unwind"
"--with-libdw-includes=${lib.getDev elfutils}/include"
"--with-libdw-libraries=${lib.getLib elfutils}/lib"
];

outputs = [ "out" ];
phases = [ "unpackPhase" "patchPhase" ]
Expand Down
20 changes: 17 additions & 3 deletions compiler/ghc/default.nix
Expand Up @@ -3,11 +3,12 @@
# haskell.nix ships its own version of the ghc expression as it needs more
# control over the expression to isolate it against varying <nixpkgs> and
# allow us to customize it to the way haskell.nix works.
let self =
{ stdenv, lib, haskell-nix, targetPackages

# build-tools
, bootPkgs
, autoconf, automake, coreutils, fetchurl, fetchpatch, perl, python3, m4, sphinx, numactl
, autoconf, automake, coreutils, fetchurl, fetchpatch, perl, python3, m4, sphinx, numactl, elfutils
, autoreconfHook
, bash

Expand Down Expand Up @@ -37,6 +38,8 @@

, enableLibraryProfiling ? true

, enableDWARF ? false

, # Whether to build terminfo. Musl fails to build terminfo as ncurses seems to be linked to glibc
enableTerminfo ? !stdenv.targetPlatform.isWindows && !stdenv.targetPlatform.isMusl

Expand All @@ -59,7 +62,7 @@

# extra values we want to have available as passthru values.
, extra-passthru ? {}
}:
}@args:

assert !enableIntegerSimple -> gmp != null;

Expand Down Expand Up @@ -103,6 +106,9 @@ let
'' + lib.optionalString enableRelocatedStaticLibs ''
GhcLibHcOpts += -fPIC
GhcRtsHcOpts += -fPIC
'' + lib.optionalString enableDWARF ''
GhcLibHcOpts += -g3
GhcRtsHcOpts += -g3
'' + lib.optionalString targetPlatform.useAndroidPrebuilt ''
EXTRA_CC_OPTS += -std=gnu99
'' + lib.optionalString (!enableTerminfo) ''
Expand Down Expand Up @@ -149,6 +155,7 @@ let
useLLVM llvmPackages
targetCC
enableIntegerSimple targetGmp
enableDWARF elfutils
ncurses targetLibffi libiconv
disableLargeAddressSpace
buildMK
Expand Down Expand Up @@ -315,6 +322,12 @@ stdenv.mkDerivation (rec {

# Used to detect non haskell-nix compilers (accidental use of nixpkgs compilers can lead to unexpected errors)
isHaskellNixCompiler = true;

# The same GHC, but with debug enabled (if it can be)
dwarf = lib.makeOverridable self (args // {
enableDWARF = stdenv.targetPlatform.isLinux
&& builtins.compareVersions ghc-version "8.10.2" >= 0;
});
} // extra-passthru;

meta = {
Expand All @@ -328,4 +341,5 @@ stdenv.mkDerivation (rec {
dontStrip = true;
dontPatchELF = true;
noAuditTmpdir = true;
})
});
in self
4 changes: 3 additions & 1 deletion overlays/ghc.nix
Expand Up @@ -21,7 +21,9 @@ final: prev: with prev;
&& !lib.hasPrefix "ghcjs" name
&& !lib.hasSuffix "Binary" name;
overrideCompiler = compiler:
(compiler.override ghcPkgOverrides).overrideAttrs ghcDrvOverrides;
((compiler.override ghcPkgOverrides).overrideAttrs ghcDrvOverrides) // {
dwarf = overrideCompiler compiler.dwarf;
};
in
lib.recursiveUpdate prev.haskell-nix {
compiler = lib.mapAttrs (_name: overrideCompiler)
Expand Down
4 changes: 4 additions & 0 deletions test/cabal-simple-debug/Main.hs
@@ -0,0 +1,4 @@
module Main where

main :: IO ()
main = putStrLn "Hello, Haskell!"
2 changes: 2 additions & 0 deletions test/cabal-simple-debug/Setup.hs
@@ -0,0 +1,2 @@
import Distribution.Simple
main = defaultMain
37 changes: 37 additions & 0 deletions test/cabal-simple-debug/cabal-simple.cabal
@@ -0,0 +1,37 @@
cabal-version: >=1.10
-- Initial package description 'cabal-simple.cabal' generated by 'cabal
-- init'. For further documentation, see
-- http://haskell.org/cabal/users-guide/

name: cabal-simple
version: 0.1.0.0
-- synopsis:
-- description:
-- bug-reports:
license: PublicDomain
author: Rodney Lorrimar
maintainer: rodney.lorrimar@iohk.io
-- category:
build-type: Simple

library
-- exposed-modules:
-- other-modules:
-- other-extensions:
build-depends: base
, extra
, safe
, aeson
-- hs-source-dirs:
default-language: Haskell2010

executable cabal-simple
main-is: Main.hs
-- other-modules:
-- other-extensions:
build-depends: base
, cabal-simple
, extra
, optparse-applicative
-- hs-source-dirs:
default-language: Haskell2010
47 changes: 47 additions & 0 deletions test/cabal-simple-debug/default.nix
@@ -0,0 +1,47 @@
# Test a package set
{ stdenv, lib, util, cabalProject', haskellLib, recurseIntoAttrs, testSrc, compiler-nix-name, dwarfdump }:

with lib;

let
project = cabalProject' {
inherit compiler-nix-name;
src = testSrc "cabal-simple-debug";
};

packages = project.hsPkgs;

in recurseIntoAttrs {
ifdInputs = {
inherit (project) plan-nix;
};
run = stdenv.mkDerivation {
name = "cabal-simple-debug-test";

buildCommand = ''
exe="${(packages.cabal-simple.components.exes.cabal-simple.dwarf).exePath}"
size=$(command stat --format '%s' "$exe")
printf "size of executable $exe is $size. \n" >& 2
# fixme:
printf "checking whether executable included DWARF debug info... " >& 2
(${dwarfdump}/bin/dwarfdump $exe || true) | grep -c 'libraries/base/[A-Za-z0-9/]*\.hs'
(${dwarfdump}/bin/dwarfdump $exe || true) | grep -c '\/Main\.hs'
touch $out
'';

meta = {
platforms = platforms.all;
# DWARF only works on linux with GHC 8.10.2 and newer
disabled = compiler-nix-name == "ghc865" || compiler-nix-name == "ghc884"
|| !stdenv.hostPlatform.isLinux || haskellLib.isCrossHost || stdenv.hostPlatform.isMusl;
};

passthru = {
# Used for debugging with nix repl
inherit project packages;
};
};
}
6 changes: 5 additions & 1 deletion test/default.nix
@@ -1,6 +1,6 @@
{ haskellNix ? import ../default.nix { inherit checkMaterialization; }
, pkgs ? import nixpkgs nixpkgsArgs
, nixpkgs ? haskellNix.sources.nixpkgs
, nixpkgs ? haskellNix.sources.nixpkgs-unstable
, nixpkgsArgs ? haskellNix.nixpkgsArgs
, ifdLevel ? 1000
, compiler-nix-name
Expand Down Expand Up @@ -212,6 +212,10 @@ let
# githash runs git from TH code and this needs a cross compiled git exe
# to work correctly. Cross compiling git is currently brocken.
githash = haskell-nix.callPackage ./githash { inherit compiler-nix-name; testSrc = testSrcWithGitDir; };
} // lib.optionalAttrs (
stdenv.hostPlatform.isLinux && !pkgs.haskell-nix.haskellLib.isCrossHost && !stdenv.hostPlatform.isMusl
&& !(__elem compiler-nix-name ["ghc865" "ghc884"])) {
cabal-simple-debug = callTest ./cabal-simple-debug { inherit util compiler-nix-name; };
};

# This is the same as allTests, but filter out all the key/vaules from the
Expand Down

0 comments on commit f09cddf

Please sign in to comment.