mirror of
https://github.com/ilyakooo0/haskell.nix.git
synced 2024-09-17 09:57:27 +03:00
Fix cross compilation issues for musl and aarch64 (#322)
* Enables tests for Musl and AArch64 (also rasbery pi, but leaves them disabled for now) and includes many fixes for the tests that were broken. * Makes Musl cross compiler more like native (including making `ghci` and `runghc` work) * Updates selection of enableShared * Works around missing configFiles attribute issue * Use ghc-extra-packages and compiler.nix-name to pick the right extra packages * Leaves out --cross-compile on hsc2hs for musl * Fixes haddock and hoogle for musl and disables them for other cross compilers * Adds ghc 8.8.3 * Static link components (except libraries and `all`) on musl * Use qemu for the arm cross compile `testWrapper` * Add isCrossHost and isCrossTarget functions * Fixes profiling on AArch64 * Disable split sections when compiling for windows (fixes GHC 8.8 cross compile to windows) * Disable hoogle in cross compiler shells for now
This commit is contained in:
parent
7c5c8e7691
commit
775c8cf756
@ -24,7 +24,7 @@
|
||||
, dontStrip ? component.dontStrip
|
||||
|
||||
, enableStatic ? component.enableStatic
|
||||
, enableShared ? component.enableShared && !stdenv.hostPlatform.isWindows && !stdenv.hostPlatform.useiOSPrebuilt
|
||||
, enableShared ? component.enableShared && !haskellLib.isCrossHost
|
||||
, enableDeadCodeElimination ? component.enableDeadCodeElimination
|
||||
|
||||
# Options for Haddock generation
|
||||
@ -95,11 +95,20 @@ let
|
||||
(enableFeature enableExecutableProfiling "executable-profiling")
|
||||
(enableFeature enableStatic "static")
|
||||
(enableFeature enableShared "shared")
|
||||
] ++ lib.optionals (stdenv.hostPlatform.isMusl && (haskellLib.isExecutableType componentId)) [
|
||||
# These flags will make sure the resulting executable is statically linked.
|
||||
# If it uses other libraries it may be necessary for to add more
|
||||
# `--ghc-option=-optl=-L` options to the `configurationFlags` of the
|
||||
# component.
|
||||
"--disable-executable-dynamic"
|
||||
"--ghc-option=-optl=-pthread"
|
||||
"--ghc-option=-optl=-static"
|
||||
"--ghc-option=-optl=-L${gmp.override { withStatic = true; }}/lib"
|
||||
] ++ lib.optional enableSeparateDataOutput "--datadir=$data/share/${ghc.name}"
|
||||
++ lib.optional doHaddock' "--docdir=${docdir "$doc"}"
|
||||
++ lib.optional (enableLibraryProfiling || enableExecutableProfiling) "--profiling-detail=${profilingDetail}"
|
||||
++ lib.optional stdenv.hostPlatform.isLinux (enableFeature enableDeadCodeElimination "split-sections")
|
||||
++ lib.optionals (stdenv.hostPlatform != stdenv.buildPlatform) (
|
||||
++ lib.optionals haskellLib.isCrossHost (
|
||||
map (arg: "--hsc2hs-option=" + arg) (["--cross-compile"] ++ lib.optionals (stdenv.hostPlatform.isWindows) ["--via-asm"])
|
||||
++ lib.optional (package.buildType == "Configure") "--configure-option=--host=${stdenv.hostPlatform.config}" )
|
||||
++ component.configureFlags
|
||||
@ -131,7 +140,7 @@ let
|
||||
|
||||
doHaddock' = doHaddock
|
||||
&& (haskellLib.isLibrary componentId)
|
||||
&& stdenv.hostPlatform == stdenv.buildPlatform;
|
||||
&& !haskellLib.isCrossHost;
|
||||
|
||||
exeExt = lib.optionalString stdenv.hostPlatform.isWindows ".exe";
|
||||
exeName = componentId.cname + exeExt;
|
||||
|
@ -39,10 +39,14 @@ let
|
||||
|
||||
|
||||
hoogleLocal = let
|
||||
nixpkgsHoogleLocal = import (pkgs.path + /pkgs/development/haskell-modules/hoogle.nix);
|
||||
in { packages ? [], hoogle ? pkgs.haskell-nix.haskellPackages.hoogle.components.exes.hoogle }:
|
||||
# Use the latest default nixpkgs hoogle.nix, as the 19.03 one does not work with cross compilers
|
||||
nixpkgsHoogleLocal = import ((import ../nixpkgs {}).path + /pkgs/development/haskell-modules/hoogle.nix);
|
||||
in { packages ? [], hoogle ? pkgs.buildPackages.haskell-nix.haskellPackages.hoogle.components.exes.hoogle }:
|
||||
haskellLib.weakCallPackage pkgs nixpkgsHoogleLocal {
|
||||
ghc = pkgs.haskell-nix.ghc;
|
||||
# For musl we can use haddock from the buildGHC
|
||||
ghc = if stdenv.hostPlatform.isLinux && stdenv.targetPlatform.isMusl
|
||||
then ghc.buildGHC
|
||||
else ghc;
|
||||
inherit packages hoogle;
|
||||
};
|
||||
|
||||
|
@ -15,14 +15,19 @@
|
||||
}:
|
||||
|
||||
let
|
||||
inherit (configFiles) ghcCommand ghcCommandCaps packageCfgDir;
|
||||
inherit (configFiles) targetPrefix ghcCommand ghcCommandCaps packageCfgDir;
|
||||
libDir = "$out/${configFiles.libDir}";
|
||||
docDir = "$out/share/doc/ghc/html";
|
||||
# For musl we can use haddock from the buildGHC
|
||||
haddock = if stdenv.hostPlatform.isLinux && stdenv.targetPlatform.isMusl
|
||||
then ghc.buildGHC
|
||||
else ghc;
|
||||
|
||||
in runCommand "${componentName}-${ghc.name}-env" {
|
||||
preferLocalBuild = true;
|
||||
passthru = {
|
||||
inherit (ghc) version meta;
|
||||
inherit targetPrefix;
|
||||
baseGhc = ghc;
|
||||
};
|
||||
} (
|
||||
@ -62,7 +67,7 @@ in runCommand "${componentName}-${ghc.name}-env" {
|
||||
fi
|
||||
done
|
||||
|
||||
for prg in runghc runhaskell; do
|
||||
for prg in "${targetPrefix}runghc" "${targetPrefix}runhaskell"; do
|
||||
if [[ -x "${ghc}/bin/$prg" ]]; then
|
||||
rm -f $out/bin/$prg
|
||||
makeWrapper ${ghc}/bin/$prg $out/bin/$prg \
|
||||
@ -75,9 +80,9 @@ in runCommand "${componentName}-${ghc.name}-env" {
|
||||
done
|
||||
|
||||
# Wrap haddock, if the base GHC provides it.
|
||||
if [[ -x "${ghc}/bin/haddock" ]]; then
|
||||
if [[ -x "${haddock}/bin/haddock" ]]; then
|
||||
rm -f $out/bin/haddock
|
||||
makeWrapper ${ghc}/bin/haddock $out/bin/haddock \
|
||||
makeWrapper ${haddock}/bin/haddock $out/bin/haddock \
|
||||
--add-flags '"-B$NIX_${ghcCommandCaps}_LIBDIR"' \
|
||||
--set "NIX_${ghcCommandCaps}_LIBDIR" "${libDir}"
|
||||
fi
|
||||
|
@ -66,7 +66,8 @@ let
|
||||
in { identifier, component, fullName, flags ? {} }:
|
||||
# Filters out only library packages that for this GHC target
|
||||
# TODO investigate why this is needed
|
||||
let libDeps = lib.filter (p: p.configFiles.targetPrefix == ghc.targetPrefix)
|
||||
# TODO find out why p ? configFiles helps (for instance for `R1909.aarch64-unknown-linux-gnu.tests.cabal-22.run.x86_64-linux`)
|
||||
let libDeps = lib.filter (p: (p ? configFiles) && p.configFiles.targetPrefix == ghc.targetPrefix)
|
||||
(map getLibComponent component.depends);
|
||||
cfgFiles =
|
||||
let xs = map
|
||||
|
@ -12,6 +12,8 @@
|
||||
, ... } @ args:
|
||||
|
||||
let
|
||||
# TODO find out why hoogle index creation can be made to work for cross compilers
|
||||
withHoogle' = withHoogle && !haskellLib.isCrossHost;
|
||||
selected = packages hsPkgs;
|
||||
additionalSelected = additional hsPkgs;
|
||||
selectedConfigs = map (p: p.components.all.config) selected;
|
||||
@ -53,7 +55,7 @@ let
|
||||
ghcEnv = ghcForComponent {
|
||||
inherit configFiles;
|
||||
componentName = name;
|
||||
postInstall = lib.optionalString withHoogle ''
|
||||
postInstall = lib.optionalString withHoogle' ''
|
||||
ln -s ${hoogleIndex}/bin/hoogle $out/bin
|
||||
'';
|
||||
};
|
||||
@ -79,7 +81,7 @@ in
|
||||
|
||||
buildInputs = systemInputs
|
||||
++ mkDrvArgs.buildInputs or []
|
||||
++ lib.optional withHoogle hoogleIndex;
|
||||
++ lib.optional withHoogle' hoogleIndex;
|
||||
nativeBuildInputs = [ ghcEnv ]
|
||||
++ nativeBuildInputs
|
||||
++ mkDrvArgs.nativeBuildInputs or [];
|
||||
|
@ -3,7 +3,7 @@
|
||||
# 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.
|
||||
{ stdenv, targetPackages
|
||||
{ stdenv, haskell-nix, targetPackages
|
||||
|
||||
# build-tools
|
||||
, bootPkgs
|
||||
@ -33,15 +33,24 @@
|
||||
|
||||
, # Whether to build dynamic libs for the standard library (on the target
|
||||
# platform). Static libs are always built.
|
||||
enableShared ? !stdenv.targetPlatform.isWindows && !stdenv.targetPlatform.useiOSPrebuilt
|
||||
enableShared ? !haskell-nix.haskellLib.isCrossTarget
|
||||
|
||||
, # Whetherto build terminfo.
|
||||
enableTerminfo ? !stdenv.targetPlatform.isWindows
|
||||
, # Whetherto build terminfo. Musl fails to build terminfo as ncurses seems to be linked to glibc
|
||||
enableTerminfo ? !stdenv.targetPlatform.isWindows && !stdenv.targetPlatform.isMusl
|
||||
|
||||
, # What flavour to build. An empty string indicates no
|
||||
# specific flavour and falls back to ghc default values.
|
||||
ghcFlavour ? stdenv.lib.optionalString (stdenv.targetPlatform != stdenv.hostPlatform)
|
||||
(if useLLVM then "quick-cross" else "perf-cross-ncg")
|
||||
ghcFlavour ? stdenv.lib.optionalString haskell-nix.haskellLib.isCrossTarget (
|
||||
if useLLVM
|
||||
then (
|
||||
# TODO check if the issues with qemu and Aarch32 persist. See
|
||||
# https://github.com/input-output-hk/haskell.nix/pull/411/commits/1986264683067198e7fdc1d665351622b664712e
|
||||
if stdenv.targetPlatform.isAarch32
|
||||
then "quick-cross"
|
||||
else "perf-cross"
|
||||
)
|
||||
else "perf-cross-ncg"
|
||||
)
|
||||
|
||||
, # Whether to disable the large address space allocator
|
||||
# necessary fix for iOS: https://www.reddit.com/r/haskell/comments/4ttdz1/building_an_osxi386_to_iosarm64_cross_compiler/d5qvd67/
|
||||
@ -59,9 +68,15 @@ assert !enableIntegerSimple -> gmp != null;
|
||||
|
||||
let
|
||||
inherit (stdenv) buildPlatform hostPlatform targetPlatform;
|
||||
inherit (haskell-nix.haskellLib) isCrossTarget;
|
||||
|
||||
inherit (bootPkgs) ghc;
|
||||
|
||||
# TODO check if this posible fix for segfaults works or not.
|
||||
libffiStaticEnabled = if libffi == null || !stdenv.targetPlatform.isMusl
|
||||
then libffi
|
||||
else targetPackages.libffi.overrideAttrs (old: { dontDisableStatic = true; });
|
||||
|
||||
# TODO(@Ericson2314) Make unconditional
|
||||
targetPrefix = stdenv.lib.optionalString
|
||||
(targetPlatform != hostPlatform)
|
||||
@ -75,8 +90,9 @@ let
|
||||
DYNAMIC_GHC_PROGRAMS = ${if enableShared then "YES" else "NO"}
|
||||
INTEGER_LIBRARY = ${if enableIntegerSimple then "integer-simple" else "integer-gmp"}
|
||||
'' + stdenv.lib.optionalString (targetPlatform != hostPlatform) ''
|
||||
Stage1Only = ${if targetPlatform.system == hostPlatform.system then "NO" else "YES"}
|
||||
CrossCompilePrefix = ${targetPrefix}
|
||||
'' + stdenv.lib.optionalString isCrossTarget ''
|
||||
Stage1Only = ${if targetPlatform.system == hostPlatform.system then "NO" else "YES"}
|
||||
HADDOCK_DOCS = NO
|
||||
BUILD_SPHINX_HTML = NO
|
||||
BUILD_SPHINX_PDF = NO
|
||||
@ -88,11 +104,19 @@ let
|
||||
'' + stdenv.lib.optionalString useLLVM ''
|
||||
GhcStage2HcOpts += -fast-llvm
|
||||
GhcLibHcOpts += -fast-llvm
|
||||
'' + stdenv.lib.optionalString (!enableTerminfo) ''
|
||||
WITH_TERMINFO=NO
|
||||
''
|
||||
# While split sections are now enabled by default in ghc 8.8 for windows,
|
||||
# the seem to lead to `too many sections` errors when building base for
|
||||
# profiling.
|
||||
+ stdenv.lib.optionalString targetPlatform.isWindows ''
|
||||
SplitSections = NO
|
||||
'';
|
||||
|
||||
# Splicer will pull out correct variations
|
||||
libDeps = platform: stdenv.lib.optional enableTerminfo [ ncurses ]
|
||||
++ [libffi]
|
||||
++ [libffiStaticEnabled]
|
||||
++ stdenv.lib.optional (!enableIntegerSimple) gmp
|
||||
++ stdenv.lib.optional (platform.libc != "glibc" && !targetPlatform.isWindows) libiconv;
|
||||
|
||||
@ -184,7 +208,7 @@ in let configured-src = stdenv.mkDerivation (rec {
|
||||
configureFlags = [
|
||||
"--datadir=$doc/share/doc/ghc"
|
||||
"--with-curses-includes=${ncurses.dev}/include" "--with-curses-libraries=${ncurses.out}/lib"
|
||||
] ++ stdenv.lib.optionals (libffi != null) ["--with-system-libffi" "--with-ffi-includes=${targetPackages.libffi.dev}/include" "--with-ffi-libraries=${targetPackages.libffi.out}/lib"
|
||||
] ++ stdenv.lib.optionals (libffiStaticEnabled != null) ["--with-system-libffi" "--with-ffi-includes=${libffiStaticEnabled.dev}/include" "--with-ffi-libraries=${libffiStaticEnabled.out}/lib"
|
||||
] ++ stdenv.lib.optional (!enableIntegerSimple) [
|
||||
"--with-gmp-includes=${targetPackages.gmp.dev}/include" "--with-gmp-libraries=${targetPackages.gmp.out}/lib"
|
||||
] ++ stdenv.lib.optional (targetPlatform == hostPlatform && hostPlatform.libc != "glibc" && !targetPlatform.isWindows) [
|
||||
@ -298,7 +322,12 @@ in let configured-src = stdenv.mkDerivation (rec {
|
||||
for i in "$out/bin/"*; do
|
||||
test ! -h $i || continue
|
||||
egrep --quiet '^#!' <(head -n 1 $i) || continue
|
||||
sed -i -e '2i export PATH="$PATH:${stdenv.lib.makeBinPath [ targetPackages.stdenv.cc.bintools coreutils ]}"' $i
|
||||
# The ghcprog fixup is for musl (where runhaskell script just needs to point to the correct
|
||||
# ghc program to work).
|
||||
sed -i \
|
||||
-e '2i export PATH="$PATH:${stdenv.lib.makeBinPath [ targetPackages.stdenv.cc.bintools coreutils ]}"' \
|
||||
-e 's/ghcprog="ghc-/ghcprog="${targetPrefix}ghc-/' \
|
||||
$i
|
||||
done
|
||||
'' + installDeps targetPrefix;
|
||||
|
||||
|
@ -177,4 +177,15 @@ with haskellLib;
|
||||
check = import ./check.nix {
|
||||
inherit stdenv lib haskellLib srcOnly;
|
||||
};
|
||||
|
||||
# Use `isCrossHost` to identify when we are cross compiling and
|
||||
# the code we are producing will not run on the build system
|
||||
# without an emulator.
|
||||
# In most cases we do not want to treat musl as a cross compiler.
|
||||
# For instance when building ghc we want to include ghci.
|
||||
isCrossHost = stdenv.hostPlatform != stdenv.buildPlatform
|
||||
&& !(stdenv.buildPlatform.isLinux && stdenv.hostPlatform.isMusl);
|
||||
# This is the same as isCrossHost but for use when building ghc itself
|
||||
isCrossTarget = stdenv.targetPlatform != stdenv.hostPlatform
|
||||
&& !(stdenv.hostPlatform.isLinux && stdenv.targetPlatform.isMusl);
|
||||
}
|
||||
|
@ -1,7 +1,7 @@
|
||||
{
|
||||
"url": "https://github.com/input-output-hk/nixpkgs",
|
||||
"rev": "31aa5316ca232a53667790a99e8b1e76252e065c",
|
||||
"date": "2019-11-16T23:51:02+13:00",
|
||||
"sha256": "0g0r473rdrh5vsdvr45nmfs6ibp0pqyzbw9f0iv6r0jkg6jjiykr",
|
||||
"rev": "8215f2ee01c56a764416f703c66767404a321d92",
|
||||
"date": "2020-01-25T20:38:55+13:00",
|
||||
"sha256": "0cdmpwpi19354hqvph7mnxrdbphina1vg61fk487i9559bsv545m",
|
||||
"fetchSubmodules": false
|
||||
}
|
||||
|
@ -15,10 +15,10 @@ self: super:
|
||||
inherit (pkgs) gmp;
|
||||
# iserv-proxy needs to come from the buildPackages, as it needs to run on the
|
||||
# build host.
|
||||
inherit (config.hsPkgs.buildPackages.iserv-proxy.components.exes) iserv-proxy;
|
||||
inherit (self.buildPackages.ghc-extra-packages."${config.compiler.nix-name}".iserv-proxy.components.exes) iserv-proxy;
|
||||
# remote-iserv however needs to come from the regular packages as it has to
|
||||
# run on the target host.
|
||||
inherit (config.hsPkgs.remote-iserv.components.exes) remote-iserv;
|
||||
inherit (self.ghc-extra-packages."${config.compiler.nix-name}".remote-iserv.components.exes) remote-iserv;
|
||||
# we need to use openssl.bin here, because the .dll's are in the .bin expression.
|
||||
extra-test-libs = [
|
||||
# pkgs.rocksdb
|
||||
|
@ -247,6 +247,22 @@ in {
|
||||
|
||||
ghc-patches = ghc-patches "8.8.2";
|
||||
};
|
||||
ghc883 = self.callPackage ../compiler/ghc {
|
||||
extra-passthru = { buildGHC = self.buildPackages.haskell-nix.compiler.ghc883; };
|
||||
|
||||
inherit bootPkgs sphinx installDeps;
|
||||
|
||||
buildLlvmPackages = self.buildPackages.llvmPackages_7;
|
||||
llvmPackages = self.llvmPackages_7;
|
||||
|
||||
src-spec = rec {
|
||||
version = "8.8.3";
|
||||
url = "https://downloads.haskell.org/~ghc/${version}/ghc-${version}-src.tar.xz";
|
||||
sha256 = "128g932i3wix6ic03v04nh5755vyjiidzri9iybwad72yfmc1p70";
|
||||
};
|
||||
|
||||
ghc-patches = ghc-patches "8.8.3";
|
||||
};
|
||||
} // self.lib.optionalAttrs (self.targetPlatform.isGhcjs or false)
|
||||
# This will inject `exactDeps` and `envDeps` into the ghcjs
|
||||
# compiler defined below. This is crucial to build packages
|
||||
|
@ -2,10 +2,6 @@ self: super: with super;
|
||||
# sadly we need to patch GHC a bit.
|
||||
let
|
||||
ghcPkgOverrides = {
|
||||
# Required for cross-compilation, otherwise it throws
|
||||
# Failed to load interface for ‘GHC.Integer.Type’
|
||||
# Perhaps you haven't installed the "dyn" libraries for package ‘integer-gmp-1.0.2.0’?
|
||||
enableShared = super.stdenv.buildPlatform == super.stdenv.hostPlatform;
|
||||
enableIntegerSimple = false;
|
||||
} // lib.optionalAttrs self.stdenv.hostPlatform.isAarch32 {
|
||||
enableRelocatableStaticLibs = false;
|
||||
|
@ -477,7 +477,7 @@ self: super: {
|
||||
};
|
||||
|
||||
haskellNixRoots' = ifdLevel:
|
||||
let filterSupportedGhc = self.lib.filterAttrs (n: _: n == "ghc865" || n == "ghc882");
|
||||
let filterSupportedGhc = self.lib.filterAttrs (n: _: n == "ghc865" || n == "ghc882" || n == "ghc883");
|
||||
in self.recurseIntoAttrs ({
|
||||
# Things that require no IFD to build
|
||||
inherit (self.buildPackages.haskell-nix) nix-tools source-pins;
|
||||
@ -492,6 +492,7 @@ self: super: {
|
||||
hscolour = self.buildPackages.haskell-nix.bootstrap.packages.hscolour;
|
||||
ghc865 = self.buildPackages.haskell-nix.compiler.ghc865;
|
||||
ghc882 = self.buildPackages.haskell-nix.compiler.ghc882;
|
||||
ghc883 = self.buildPackages.haskell-nix.compiler.ghc883;
|
||||
ghc-extra-projects = self.recurseIntoAttrs (builtins.mapAttrs (_: proj: withInputs proj.plan-nix)
|
||||
(filterSupportedGhc self.ghc-extra-projects));
|
||||
} // self.lib.optionalAttrs (ifdLevel > 1) {
|
||||
|
@ -53,7 +53,8 @@ let
|
||||
set -euo pipefail
|
||||
${qemu}/bin/qemu-${qemuSuffix} $@*
|
||||
'';
|
||||
testFlags = lib.optionals isLinuxCross [ "--test-wrapper ${qemuTestWrapper}/bin/test-wrapper" ];
|
||||
testWrapper = lib.optional isLinuxCross "${qemuTestWrapper}/bin/test-wrapper";
|
||||
|
||||
preCheck = lib.optionalString isLinuxCross ''
|
||||
echo "================================================================="
|
||||
echo "RUNNING TESTS for $name via qemu-${qemuSuffix}"
|
||||
@ -71,4 +72,4 @@ let
|
||||
|
||||
enableShared = lib.mkDefault (!isLinuxCross);
|
||||
|
||||
in { inherit preCheck postCheck configureFlags setupBuildFlags testFlags enableShared; }
|
||||
in { inherit preCheck postCheck configureFlags setupBuildFlags testWrapper enableShared; }
|
||||
|
@ -36,10 +36,10 @@ self: super:
|
||||
inherit (pkgs) gmp;
|
||||
# iserv-proxy needs to come from the buildPackages, as it needs to run on the
|
||||
# build host.
|
||||
inherit (self.buildPackages.ghc-extra-packages.ghc865.iserv-proxy.components.exes) iserv-proxy;
|
||||
inherit (self.buildPackages.ghc-extra-packages."${config.compiler.nix-name}".iserv-proxy.components.exes) iserv-proxy;
|
||||
# remote-iserv however needs to come from the regular packages as it has to
|
||||
# run on the target host.
|
||||
inherit (self.ghc-extra-packages.ghc865.remote-iserv.components.exes) remote-iserv;
|
||||
inherit (self.ghc-extra-packages."${config.compiler.nix-name}".remote-iserv.components.exes) remote-iserv;
|
||||
# we need to use openssl.bin here, because the .dll's are in the .bin expression.
|
||||
# extra-test-libs = [ pkgs.rocksdb pkgs.openssl.bin pkgs.libffi pkgs.gmp ];
|
||||
} // {
|
||||
|
57
release.nix
57
release.nix
@ -22,25 +22,39 @@ let
|
||||
# to `x86_64-w64-mingw32` in 19.09.
|
||||
let pinnedNixpkgs = import ./nixpkgs { inherit nixpkgs-pin; }; in
|
||||
with pinnedNixpkgs.lib;
|
||||
let inherit (systems.examples) musl64 mingwW64; in
|
||||
with (import (pinnedNixpkgs.path + "/pkgs/top-level/release-lib.nix") {
|
||||
inherit supportedSystems scrubJobs nixpkgsArgs;
|
||||
packageSet = {
|
||||
system ? builtins.currentSystem
|
||||
, crossSystem ? null
|
||||
, nixpkgsArgs ? { inherit system crossSystem; }
|
||||
, ...}@args:
|
||||
import (haskell-nix + /build.nix) (args // {
|
||||
nixpkgsArgs = nixpkgsArgs // { inherit nixpkgs-pin; };
|
||||
inherit ifdLevel;
|
||||
});
|
||||
});
|
||||
|
||||
let
|
||||
inherit (systems.examples) musl64 mingwW64 aarch64-multiplatform raspberryPi;
|
||||
packages = supportedSystems:
|
||||
with (import (pinnedNixpkgs.path + "/pkgs/top-level/release-lib.nix") {
|
||||
inherit supportedSystems scrubJobs nixpkgsArgs;
|
||||
packageSet = {
|
||||
system ? builtins.currentSystem
|
||||
, crossSystem ? null
|
||||
, nixpkgsArgs ? { inherit system crossSystem; }
|
||||
, ...}@args:
|
||||
import (haskell-nix + /build.nix) (args // {
|
||||
nixpkgsArgs = nixpkgsArgs // {
|
||||
inherit nixpkgs-pin;
|
||||
};
|
||||
inherit ifdLevel;
|
||||
});
|
||||
});
|
||||
{
|
||||
mapTestOn = mapTestOn (packagePlatforms pkgs);
|
||||
mapTestOnCross = p: mapTestOnCross p (packagePlatforms pkgs);
|
||||
};
|
||||
in
|
||||
{
|
||||
native = filterTests (mapTestOn (packagePlatforms pkgs));
|
||||
# Disabled for now. Something is wrong and this would require `allowBroken`
|
||||
# "${musl64.config}" = filterTests (mapTestOnCross musl64 (packagePlatforms pkgs));
|
||||
"${mingwW64.config}" = filterTests (mapTestOnCross mingwW64 (packagePlatforms pkgs));
|
||||
native = filterTests ((packages supportedSystems).mapTestOn);
|
||||
# Musl cross compile does not work on macOS
|
||||
"${musl64.config}" = filterTests ((packages (filter (x: x == "x86_64-linux") supportedSystems)).mapTestOnCross musl64);
|
||||
# Windows cross compilation is currently broken on macOS for nixpkgs 19.09 (works on 19.03)
|
||||
"${mingwW64.config}" = filterTests ((packages (filter
|
||||
(x: x == "x86_64-linux" || nixpkgs-pin == "release-19.03") supportedSystems)).mapTestOnCross mingwW64);
|
||||
"${aarch64-multiplatform.config}" = filterTests ((packages (filter (x: x == "x86_64-linux") supportedSystems))
|
||||
.mapTestOnCross aarch64-multiplatform);
|
||||
# "${raspberryPi.config}" = filterTests ((packages (filter (x: x == "x86_64-linux") supportedSystems))
|
||||
# .mapTestOnCross raspberryPi);
|
||||
};
|
||||
|
||||
allJobs =
|
||||
@ -57,7 +71,12 @@ in allJobs // {
|
||||
meta.description = "All jobs required to pass CI";
|
||||
constituents =
|
||||
collect isDerivation allJobs.R1903.native
|
||||
++ collect isDerivation allJobs.R1909.native;
|
||||
++ collect isDerivation allJobs.R1909.native
|
||||
# Windows cross compiling with GHC 8.8.2 is broken
|
||||
# ++ collect isDerivation allJobs.R1903.x86_64-pc-mingw32
|
||||
# ++ collect isDerivation allJobs.R1909.x86_64-w64-mingw32
|
||||
++ collect isDerivation allJobs.R1903.x86_64-unknown-linux-musl
|
||||
++ collect isDerivation allJobs.R1909.x86_64-unknown-linux-musl;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -24,11 +24,15 @@ in recurseIntoAttrs {
|
||||
printf "size of executable $exe is $size. \n" >& 2
|
||||
|
||||
# fixme: run on target platform when cross-compiled
|
||||
printf "checking whether executable rans... " >& 2
|
||||
printf "checking whether executable runs... " >& 2
|
||||
cat ${haskellLib.check packages.project.components.exes.project}
|
||||
|
||||
'' +
|
||||
# Aarch is statically linked and does not produce a .so file.
|
||||
# Musl is also statically linked, but it does make a .so file so we should check that still.
|
||||
optionalString (!stdenv.hostPlatform.isAarch32 && !stdenv.hostPlatform.isAarch64) (''
|
||||
printf "checking that executable is dynamically linked to system libraries... " >& 2
|
||||
'' + optionalString stdenv.isLinux ''
|
||||
'' + optionalString (stdenv.isLinux && !stdenv.hostPlatform.isMusl) ''
|
||||
ldd $exe | grep libgmp
|
||||
'' + optionalString stdenv.isDarwin ''
|
||||
otool -L $exe | grep "libSystem.B"
|
||||
@ -47,7 +51,7 @@ in recurseIntoAttrs {
|
||||
ldd $sofile | grep libHSghc-prim
|
||||
'' + optionalString stdenv.isDarwin ''
|
||||
otool -L $sofile | grep libHSghc-prim
|
||||
'') + ''
|
||||
'')) + ''
|
||||
touch $out
|
||||
|
||||
printf "checking whether benchmark ran... " >& 2
|
||||
|
@ -37,7 +37,10 @@ in recurseIntoAttrs {
|
||||
|
||||
# fixme: run on target platform when cross-compiled
|
||||
printf "checking whether executable runs with profiling... " >& 2
|
||||
${toString packages.cabal-simple.components.exes.cabal-simple.config.testWrapper} $exe +RTS -p -h
|
||||
# Curiosity: cross compilers prodcing profiling with `+RTS -p -h` lead to the following cryptic message:
|
||||
# cabal-simple: invalid heap profile option: -h*
|
||||
# Hence we pass `-hc`.
|
||||
${toString packages.cabal-simple.components.exes.cabal-simple.config.testWrapper} $exe +RTS -p -hc
|
||||
|
||||
touch $out
|
||||
'';
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Test a package set
|
||||
{ stdenv, util, mkCabalProjectPkgSet, cabalProject', haskellLib, gmp6, zlib, recurseIntoAttrs }:
|
||||
{ stdenv, util, mkCabalProjectPkgSet, cabalProject', haskellLib, recurseIntoAttrs }:
|
||||
|
||||
with stdenv.lib;
|
||||
|
||||
@ -9,19 +9,6 @@ let
|
||||
# Package has no exposed modules which causes
|
||||
# haddock: No input file(s)
|
||||
packages.cabal-simple.doHaddock = false;
|
||||
|
||||
# When compiling with musl ghc, build a statically linked
|
||||
# executable against static libraries.
|
||||
# Ref: https://vaibhavsagar.com/blog/2018/01/03/static-haskell-nix/
|
||||
packages.cabal-simple.components.exes.cabal-simple.configureFlags =
|
||||
optionals stdenv.hostPlatform.isMusl [
|
||||
"--disable-executable-dynamic"
|
||||
"--disable-shared"
|
||||
"--ghc-option=-optl=-pthread"
|
||||
"--ghc-option=-optl=-static"
|
||||
"--ghc-option=-optl=-L${gmp6.override { withStatic = true; }}/lib"
|
||||
# "--ghc-option=-optl=-L${zlib.static}/lib"
|
||||
];
|
||||
}
|
||||
];
|
||||
|
||||
@ -53,16 +40,20 @@ in recurseIntoAttrs {
|
||||
# fixme: run on target platform when cross-compiled
|
||||
printf "checking whether executable runs... " >& 2
|
||||
cat ${haskellLib.check packages.cabal-simple.components.exes.cabal-simple}
|
||||
'' + (if stdenv.hostPlatform.isMusl then ''
|
||||
'' + (if stdenv.hostPlatform.isMusl
|
||||
then ''
|
||||
printf "checking that executable is statically linked... " >& 2
|
||||
(ldd $exe 2>&1 || true) | grep -i "not a"
|
||||
'' else ''
|
||||
printf "checking that executable is dynamically linked to system libraries... " >& 2
|
||||
'' + optionalString stdenv.isLinux ''
|
||||
ldd $exe | grep libpthread
|
||||
'' + optionalString stdenv.isDarwin ''
|
||||
otool -L $exe |grep .dylib
|
||||
'') + ''
|
||||
''
|
||||
else
|
||||
# Skip this on aarch as we do not have an `ldd` tool
|
||||
optionalString (!stdenv.hostPlatform.isAarch32 && !stdenv.hostPlatform.isAarch64) (''
|
||||
printf "checking that executable is dynamically linked to system libraries... " >& 2
|
||||
'' + optionalString stdenv.isLinux ''
|
||||
ldd $exe | grep libpthread
|
||||
'' + optionalString stdenv.isDarwin ''
|
||||
otool -L $exe |grep .dylib
|
||||
'')) + ''
|
||||
|
||||
printf "Checking that \"all\" component has the programs... " >& 2
|
||||
all_exe="${packages.cabal-simple.components.all}/bin/cabal-simple${stdenv.hostPlatform.extensions.executable}"
|
||||
|
@ -37,12 +37,15 @@ in recurseIntoAttrs {
|
||||
printf "checking whether executable runs... " >& 2
|
||||
cat ${haskellLib.check packages.cabal-sublib.components.exes.cabal-sublib}
|
||||
|
||||
'' +
|
||||
# Musl and Aarch are statically linked..
|
||||
optionalString (!stdenv.hostPlatform.isAarch32 && !stdenv.hostPlatform.isAarch64 && !stdenv.hostPlatform.isMusl) (''
|
||||
printf "checking that executable is dynamically linked to system libraries... " >& 2
|
||||
'' + optionalString stdenv.isLinux ''
|
||||
'' + optionalString (stdenv.isLinux && !stdenv.hostPlatform.isMusl) ''
|
||||
ldd $exe | grep libgmp
|
||||
'' + optionalString stdenv.isDarwin ''
|
||||
otool -L $exe |grep .dylib
|
||||
'' + ''
|
||||
'') + ''
|
||||
|
||||
printf "Checking that \"all\" component has the programs... " >& 2
|
||||
all_exe="${packages.cabal-sublib.components.all}/bin/cabal-sublib${stdenv.hostPlatform.extensions.executable}"
|
||||
|
@ -26,7 +26,10 @@ in recurseIntoAttrs {
|
||||
# fixme: run on target platform when cross-compiled
|
||||
printf "checking whether executable ran... " >& 2
|
||||
cat ${haskellLib.check packages.exe-only.components.exes.exe-only}
|
||||
'' + (if stdenv.hostPlatform.isMusl then ''
|
||||
'' +
|
||||
# Aarch are statically linked and does not have ldd for these tests.
|
||||
optionalString (!stdenv.hostPlatform.isAarch32 && !stdenv.hostPlatform.isAarch64) (
|
||||
if stdenv.hostPlatform.isMusl then ''
|
||||
printf "checking that executable is statically linked... " >& 2
|
||||
(ldd $exe 2>&1 || true) | grep -i "not a"
|
||||
'' else ''
|
||||
|
@ -32,12 +32,7 @@ let
|
||||
|
||||
withFullyStatic = {
|
||||
configureFlags =
|
||||
optionals stdenv.hostPlatform.isMusl ([
|
||||
"--disable-executable-dynamic"
|
||||
"--disable-shared"
|
||||
"--ghc-option=-optl=-pthread"
|
||||
"--ghc-option=-optl=-static"
|
||||
] ++ map (drv: "--ghc-option=-optl=-L${drv}/lib") staticLibs);
|
||||
optionals stdenv.hostPlatform.isMusl (map (drv: "--ghc-option=-optl=-L${drv}/lib") staticLibs);
|
||||
};
|
||||
in {
|
||||
# Select a non-GMP compiler, usually for software licensing reasons.
|
||||
|
@ -15,10 +15,10 @@ let
|
||||
};
|
||||
|
||||
packages = project.hsPkgs;
|
||||
in recurseIntoAttrs (if stdenv.hostPlatform.isWindows
|
||||
in recurseIntoAttrs (if stdenv.buildPlatform != stdenv.hostPlatform
|
||||
then
|
||||
let skip = pkgs.runCommand "skip-test-setup-deps" {} ''
|
||||
echo "Skipping setup-deps test on windows as it needs the ghc lib" >& 2
|
||||
echo "Skipping setup-deps test when cross compiling as it needs the ghc lib" >& 2
|
||||
touch $out
|
||||
'';
|
||||
in {
|
||||
|
@ -14,10 +14,15 @@ let
|
||||
|
||||
env = project.hsPkgs.shellFor {};
|
||||
|
||||
in recurseIntoAttrs (if stdenv.hostPlatform.isWindows
|
||||
# Making this work for cross compilers will be dificult as setup-deps are
|
||||
# built for the build platform and the shell will be for the host platform.
|
||||
# We probably need a shell that provides both build and host ghc
|
||||
# and corrisponding package DBs and a way to use them.
|
||||
# This problem affects musl as well as the build libraries are linked to glibc.
|
||||
in recurseIntoAttrs (if stdenv.buildPlatform != stdenv.hostPlatform
|
||||
then
|
||||
let skip = runCommand "skipping-test-shell-for-setup-deps" {} ''
|
||||
echo "Skipping shell-for-setup-deps test on windows as does not work yet" >& 2
|
||||
echo "Skipping shell-for-setup-deps test on cross compilers (does not work yet)" >& 2
|
||||
touch $out
|
||||
'';
|
||||
in {
|
||||
@ -31,7 +36,7 @@ in recurseIntoAttrs (if stdenv.hostPlatform.isWindows
|
||||
};
|
||||
inherit env;
|
||||
run = stdenv.mkDerivation {
|
||||
name = "shell-for-test";
|
||||
name = "shell-for-setup-deps-test";
|
||||
|
||||
buildCommand = ''
|
||||
########################################################################
|
||||
@ -40,13 +45,14 @@ in recurseIntoAttrs (if stdenv.hostPlatform.isWindows
|
||||
cp ${./pkg/src}/*.hs .
|
||||
|
||||
printf "checking that the shell env has the dependencies...\n" >& 2
|
||||
${env.ghc}/bin/runghc conduit-test.hs
|
||||
${env.ghc}/bin/${env.ghc.targetPrefix}ghc-pkg list
|
||||
${env.ghc}/bin/${env.ghc.targetPrefix}runghc conduit-test.hs
|
||||
|
||||
touch $out
|
||||
'';
|
||||
|
||||
meta.platforms = platforms.all;
|
||||
meta.disabled = stdenv.hostPlatform.isMusl || stdenv.hostPlatform.isWindows;
|
||||
meta.disabled = stdenv.buildPlatform != stdenv.hostPlatform;
|
||||
|
||||
passthru = {
|
||||
# Used for debugging with nix repl
|
||||
|
@ -68,10 +68,10 @@ in recurseIntoAttrs (if stdenv.hostPlatform.isWindows
|
||||
cp ${./pkgb/src}/*.hs .
|
||||
|
||||
printf "checking that the shell env has the dependencies...\n" >& 2
|
||||
${env.ghc}/bin/runghc conduit-test.hs
|
||||
${env.ghc}/bin/${env.ghc.targetPrefix}runghc conduit-test.hs
|
||||
|
||||
printf "checking that the shell envDefault has the dependencies...\n" >& 2
|
||||
${envDefault.ghc}/bin/runghc conduit-test.hs
|
||||
${envDefault.ghc}/bin/${env.ghc.targetPrefix}runghc conduit-test.hs
|
||||
|
||||
touch $out
|
||||
'';
|
||||
|
@ -37,10 +37,14 @@ in recurseIntoAttrs (if stdenv.hostPlatform.isWindows
|
||||
# test snapshot ghcWithHoogle
|
||||
|
||||
printf "checking that the ghcWithPackages env has the package...\n" >& 2
|
||||
${env}/bin/ghc-pkg list | grep conduit
|
||||
${env}/bin/${env.targetPrefix}ghc-pkg list | grep conduit
|
||||
|
||||
printf "checking that the ghcWithPackages env has a hoogle index...\n" >& 2
|
||||
${env}/bin/hoogle search Conduit --count=100 | grep ConduitT
|
||||
''
|
||||
# Hoogle support is currently disabled in cross compiler shells
|
||||
+ (optionalString (!stdenv.hostPlatform.isAarch32 && !stdenv.hostPlatform.isAarch64) ''
|
||||
printf "checking that the ghcWithPackages env has a hoogle index...\n" >& 2
|
||||
${env}/bin/hoogle search Conduit --count=100 | grep ConduitT
|
||||
'') +''
|
||||
|
||||
touch $out
|
||||
'';
|
||||
|
@ -73,11 +73,11 @@ in recurseIntoAttrs {
|
||||
''
|
||||
else ''
|
||||
printf "checking that the package env has the dependencies... " >& 2
|
||||
${package.components.all.env}/bin/runghc ${./Point.hs}
|
||||
${package.components.all.env}/bin/${package.components.all.env.targetPrefix}runghc ${./Point.hs}
|
||||
echo >& 2
|
||||
|
||||
printf "checking that components.library.env has the dependencies... " >& 2
|
||||
${library.env}/bin/runghc ${./Point.hs}
|
||||
${library.env}/bin/${library.env.targetPrefix}runghc ${./Point.hs}
|
||||
echo >& 2
|
||||
'') + ''
|
||||
touch $out
|
||||
|
Loading…
Reference in New Issue
Block a user