Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
267 changes: 267 additions & 0 deletions pkgs/development/compilers/ghc/9.6.6-debian-binary.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,267 @@
{
lib,
stdenv,
fetchurl,
perl,
gcc,
ncurses5,
ncurses6,
gmp,
libiconv,
numactl,
libffi,
coreutils,
targetPackages,
}:

# Prebuilt only does native
assert stdenv.targetPlatform == stdenv.hostPlatform;

let
version = "9.6.6";

# GHC upstream doesn't release bindist tarballs for some platforms.
# We're using Debian's binary package, and patching it into a usable-in-Nixpkgs state.
ghcDebs = {
powerpc64-linux = {
variantSuffix = "";
src = {
url = "http://ftp.ports.debian.org/debian-ports/pool-ppc64/main/g/ghc/ghc_9.6.6-4_ppc64.deb";
sha256 = "722cc301b6ba70b342e5e3d9d0671440bcd749cd2f13dcccbd23c3f6a6060171";
};
exePathForLibraryCheck = null;
archSpecificLibraries = [
{
nixPackage = gmp;
fileToCheckFor = null;
}
{
nixPackage = ncurses6;
fileToCheckFor = "libtinfo.so.6";
}
{
nixPackage = numactl;
fileToCheckFor = null;
}
{
nixPackage = libffi;
fileToCheckFor = null;
}
];
};
};

debUsed =
ghcDebs.${stdenv.hostPlatform.system}
or (throw "cannot bootstrap GHC on this platform ('${stdenv.hostPlatform.system}') from Debian debs");

gmpUsed =
(builtins.head (
builtins.filter (drv: lib.hasPrefix "gmp" (drv.nixPackage.name or "")) debUsed.archSpecificLibraries
)).nixPackage;

runtimeDeps = [
targetPackages.stdenv.cc
targetPackages.stdenv.cc.bintools
coreutils # for cat
];

extraLibraryMapping = {
gmp = gmpUsed;
numa = numactl;
ffi = libffi;
};

in

stdenv.mkDerivation (finalAttrs: {
inherit version;
pname = "ghc-debian-binary${debUsed.variantSuffix}";

src = fetchurl debUsed.src;

nativeBuildInputs = [ perl ];

sourceRoot = "${finalAttrs.pname}-${finalAttrs.version}";

# Custom unpack phase to handle .deb files
unpackPhase = ''
runHook preUnpack

ar x $src
tar xf data.tar.xz
mkdir -p ${finalAttrs.sourceRoot}
mv -t ${finalAttrs.sourceRoot}/ usr var

runHook postUnpack
'';

postUnpack =
# Verify our assumptions of which `libtinfo.so` (ncurses) version is used,
# so that we know when ghc debs upgrade that and we need to update the
# version used in `archSpecificLibraries`.
lib.optionalString (debUsed.exePathForLibraryCheck != null) (
lib.concatStringsSep "\n" [
''
shopt -u nullglob
echo "Checking that ghc binary exists in deb at ${debUsed.exePathForLibraryCheck}"
if ! test -e ${debUsed.exePathForLibraryCheck}; then
echo >&2 "GHC binary ${debUsed.exePathForLibraryCheck} could not be found in the deb unpack directory for arch ${stdenv.hostPlatform.system}, please check that ghcDebs correctly reflect the deb dependencies!"; exit 1;
fi
''
(lib.concatMapStringsSep "\n" (
{ fileToCheckFor, nixPackage }:
lib.optionalString (fileToCheckFor != null) ''
echo "Checking deb for ${fileToCheckFor} to ensure that is still used"
if ! readelf -d ${debUsed.exePathForLibraryCheck} | grep "${fileToCheckFor}"; then
echo >&2 "File ${fileToCheckFor} could not be found in ${debUsed.exePathForLibraryCheck} for arch ${stdenv.hostPlatform.system}, please check that ghcDebs correctly reflect the deb dependencies!"; exit 1;
fi

echo "Checking that the nix package ${nixPackage} contains ${fileToCheckFor}"
if ! test -e "${lib.getLib nixPackage}/lib/${fileToCheckFor}"; then
echo >&2 "Nix package ${nixPackage} did not contain ${fileToCheckFor} for arch ${stdenv.hostPlatform.system}, please check that ghcDebs correctly reflect the deb dependencies!"; exit 1;
fi
''
) debUsed.archSpecificLibraries)
]
)

# Linking to non-compiler libraries requires GHC to know about our non-FHS paths for those libraries
+ (lib.strings.concatMapAttrsStringSep "\n" (libName: libPackage: ''
for packageDbDir in $(find . -name package.conf.d); do
for packageDb in $(grep -l 'extra-libraries:.*${libName}' "$packageDbDir"/*.conf); do
echo "Patching include & library path for ${libName} into package DB: $packageDb"
sed -i "$packageDb" \
-e '/^[a-z-]*include-dirs/a \ ${lib.getDev libPackage}/include' \
-e '/^[a-z-]*library-dirs/a \ ${lib.getLib libPackage}/lib'
done
done
'') extraLibraryMapping)

+
# Rename needed libraries and binaries, fix interpreter
lib.optionalString stdenv.hostPlatform.isLinux ''
find . -type f -executable -exec patchelf \
--interpreter ${stdenv.cc.bintools.dynamicLinker} {} \;
'';

# Not a bindist, nothing to configure
dontConfigure = true;

# Not a bindist, it's already built
dontBuild = true;

# Install prebuilt GHC files
installPhase = ''
runHook preInstall

mkdir -p $out

cp -t $out/ -a usr/*
rm -f $out/lib/ghc/lib/package.conf.d
find var -name "package.conf.d" -type d -exec cp -a {} $out/lib/ghc/lib/ \;

runHook postInstall
'';

postInstall =
# Patch scripts to include runtime dependencies in $PATH.
''
for i in "$out/bin/"*; do
test ! -h "$i" || continue
isScript "$i" || continue
sed -i -e '2i export PATH="${lib.makeBinPath runtimeDeps}:$PATH"' "$i"
done
''

# Patch /usr paths
+ ''
for i in "$out/bin/"*; do
test ! -h "$i" || continue
isScript "$i" || continue
substituteInPlace "$i" \
--replace-fail '="/usr' '="${placeholder "out"}'
done
find "$out/lib/ghc/lib/package.conf.d" -type f -name '*.conf' \
-exec sed -i "s|/usr/|$out/|g" {} +
''

# Patch ghc settings
+ ''
substituteInPlace $out/lib/ghc/lib/settings \
--replace-fail powerpc64-linux-gnu-gcc gcc \
--replace-fail powerpc64-linux-gnu-g++ g++ \
--replace-fail powerpc64-linux-gnu-ld ld \
--replace-fail powerpc64-linux-gnu-ar ar \
--replace-fail powerpc64-linux-gnu-ranlib ranlib \
--replace-fail llc-18 llc \
--replace-fail opt-18 opt
'';

# On Linux, use patchelf to modify the executables so that they can
# find editline/gmp.
postFixup =
lib.optionalString (stdenv.hostPlatform.isLinux && !(debUsed.isStatic or false))
# Keep rpath as small as possible, running autoPatchelf makes everything segfault (maybe similar to patchelf#244).
# All Elfs are 2 directories deep from $out/lib, so pooling symlinks there makes a short rpath.
''
(cd $out/lib; ln -s ${ncurses6.out}/lib/libtinfo.so.6)
(cd $out/lib; ln -s ${lib.getLib gmpUsed}/lib/libgmp.so.10)
(cd $out/lib; ln -s ${numactl.out}/lib/libnuma.so.1)
(cd $out/lib; ln -s ${libffi.out}/lib/libffi.so.8)
for p in $(find "$out/lib" -type f -name "*\.so*"); do
(cd $out/lib; ln -s $p)
done

for p in $(find "$out/lib" -type f -executable); do
if isELF "$p"; then
echo "Patchelfing $p"
patchelf --set-rpath "\$ORIGIN:\$ORIGIN/../.." $p
fi
done
''
# Recache package db which needs to happen because
# we modify the package db
+ ''
"$out/bin/ghc-pkg" --package-db=$out/lib/ghc/lib/package.conf.d recache
'';

doInstallCheck = true;
installCheckPhase = ''
# Sanity check, can ghc create executables?
cd $TMP
mkdir test-ghc; cd test-ghc
cat > main.hs << EOF
{-# LANGUAGE TemplateHaskell #-}
module Main where
main = putStrLn \$([|"yes"|])
EOF
env -i $out/bin/ghc --make main.hs || exit 1
echo compilation ok
[ $(./main) == "yes" ]
'';

passthru = {
targetPrefix = "";
enableShared = true;

llvmPackages = null;

# Our Cabal compiler name
haskellCompilerName = "ghc-${version}";

# Normal GHC derivations expose the hadrian derivation used to build them
# here. In the case of debs we just make sure that the attribute exists,
# as it is used for checking if a GHC derivation has been built with hadrian.
hadrian = null;
};

meta = {
homepage = "http://haskell.org/ghc";
description = "Glasgow Haskell Compiler";
license = lib.licenses.bsd3;
platforms = builtins.attrNames ghcDebs;
maintainers = [ lib.maintainers.OPNA2608 ];
teams = [ lib.teams.haskell ];
};
})
47 changes: 45 additions & 2 deletions pkgs/development/haskell-modules/configuration-common.nix
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,8 @@ with haskellLib;
# Ironically, we still need to build the doctest suite.
# vector-0.13.2.0 has a doctest < 0.24 constraint
jailbreak = true;
# inspection-testing doesn't work on all archs & ABIs
doCheck = !self.inspection-testing.meta.broken;
}) super.vector;

# https://github.com/lspitzner/data-tree-print/issues/4
Expand Down Expand Up @@ -694,6 +696,12 @@ with haskellLib;
hash = "sha256-feGEuALVJ0Zl8zJPIfgEFry9eH/MxA0Aw7zlDq0PC/s=";
}) super.algebraic-graphs;

# Relies on DWARF <-> register mappings in GHC, not available for every arch & ABI
# (check dwarfReturnRegNo in compiler/GHC/CmmToAsm/Dwarf/Constants.hs, that's where ppc64 elfv1 gives up)
inspection-testing = overrideCabal (drv: {
broken = with pkgs.stdenv.hostPlatform; !(isx86 || (isPower64 && isAbiElfv2) || isAarch64);
}) super.inspection-testing;

# Too strict bounds on filepath, hpsec, tasty, tasty-quickcheck, transformers
# https://github.com/illia-shkroba/pfile/issues/3
pfile = doJailbreak super.pfile;
Expand Down Expand Up @@ -2432,6 +2440,26 @@ with haskellLib;
))
];

# Test failures on various archs
# https://github.com/kazu-yamamoto/crypton/issues/49
crypton = dontCheckIf (
pkgs.stdenv.hostPlatform.isPower64 && pkgs.stdenv.hostPlatform.isBigEndian
) super.crypton;

# Test failures on at least ppc64
# https://github.com/kazu-yamamoto/crypton-certificate/issues/25
# Likely related to the issues in crypton
# https://github.com/kazu-yamamoto/crypton/issues/49
crypton-x509-validation = dontCheckIf (
pkgs.stdenv.hostPlatform.isPower64 && pkgs.stdenv.hostPlatform.isBigEndian
) super.crypton-x509-validation;

# Likely fallout from the crypton issues
# exception: HandshakeFailed (Error_Protocol "bad PubKeyALG_Ed448 signature for ecdhparams" DecryptError)
tls = dontCheckIf (
pkgs.stdenv.hostPlatform.isPower64 && pkgs.stdenv.hostPlatform.isBigEndian
) super.tls;

# Too strict bounds on text and tls
# https://github.com/barrucadu/irc-conduit/issues/54
# Use crypton-connection instead of connection
Expand Down Expand Up @@ -2663,8 +2691,23 @@ with haskellLib;
# hashable <1.4, mmorph <1.2
composite-aeson = doJailbreak super.composite-aeson;

# Overly strict bounds on tasty-quickcheck (test suite) (< 0.11)
hashable = doJailbreak super.hashable;
hashable = lib.pipe super.hashable [
# Overly strict bounds on tasty-quickcheck (test suite) (< 0.11)
doJailbreak

# Big-endian POWER:
# Test suite xxhash-tests: RUNNING...
# xxhash
# oneshot
# w64-ref: OK (0.03s)
# +++ OK, passed 100 tests.
# w64-examples: FAIL
# tests/xxhash-tests.hs:21:
# expected: 2768807632077661767
# but got: 13521078365639231154
# https://github.com/haskell-unordered-containers/hashable/issues/323
(dontCheckIf pkgs.stdenv.hostPlatform.isBigEndian)
];

cborg = appendPatches [
# This patch changes CPP macros form gating on the version of ghc-prim to base
Expand Down
Loading
Loading