Skip to content

Musl changes #700

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Jun 23, 2020
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
18 changes: 5 additions & 13 deletions builder/comp-builder.nix
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
{ stdenv, buildPackages, ghc, lib, gobject-introspection ? null, haskellLib, makeConfigFiles, ghcForComponent, hsPkgs, runCommand, libffi, gmp, zlib, ncurses, numactl, nodejs }:
let
# These are here to avoid multiple calls to override
gmpStatic = gmp.override { withStatic = true; };
zlibStatic = zlib.static;
ncursesStatic = ncurses.override { enableStatic = true; };
numactlStatic = numactl.overrideAttrs (_: { configureFlags = "--enable-static"; });
in
lib.makeOverridable (
let self =
let self =
{ componentId
, component
, package
Expand Down Expand Up @@ -40,7 +33,10 @@ let self =
, dontStrip ? component.dontStrip

, enableStatic ? component.enableStatic
, enableShared ? component.enableShared && !haskellLib.isCrossHost
, enableShared ? ghc.enableShared && component.enableShared && !haskellLib.isCrossHost
# on x86 we'll use shared libraries, even with musl m(
# ghc's internal linker seems to be broken on x86.
&& !(stdenv.hostPlatform.isMusl && !stdenv.hostPlatform.isx86)
, enableDeadCodeElimination ? component.enableDeadCodeElimination

# Options for Haddock generation
Expand Down Expand Up @@ -126,10 +122,6 @@ let
"--disable-executable-dynamic"
"--ghc-option=-optl=-pthread"
"--ghc-option=-optl=-static"
"--ghc-option=-optl=-L${gmpStatic}/lib"
"--ghc-option=-optl=-L${zlibStatic}/lib"
"--ghc-option=-optl=-L${ncursesStatic}/lib"
"--ghc-option=-optl=-L${numactlStatic}/lib"
] ++ lib.optional enableSeparateDataOutput "--datadir=$data/share/${ghc.name}"
++ lib.optional doHaddock' "--docdir=${docdir "$doc"}"
++ lib.optional (enableLibraryProfiling || enableExecutableProfiling) "--profiling-detail=${profilingDetail}"
Expand Down
11 changes: 8 additions & 3 deletions compiler/ghc/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,11 @@ let
'' + stdenv.lib.optionalString (!enableTerminfo) ''
WITH_TERMINFO=NO
''
# musl doesn't have a system-linker. Only on x86, and on x86 we need it, as
# our elf linker for x86_64 is broken.
+ stdenv.lib.optionalString (targetPlatform.isMusl && !targetPlatform.isx86) ''
compiler_CONFIGURE_OPTS += --flags=-dynamic-system-linker
''
# 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.
Expand Down Expand Up @@ -284,15 +289,15 @@ stdenv.mkDerivation (rec {
if [[ ! -f "$out/bin/${targetPrefix}ghc-pkg" ]]; then
echo "ERROR: Missing file $out/bin/${targetPrefix}ghc-pkg"
exit 0
fi
fi
if [[ ! -d "$out/lib/${targetPrefix}ghc-${version}" ]]; then
echo "ERROR: Missing directory $out/lib/${targetPrefix}ghc-${version}"
exit 0
fi
fi
if (( $(ls -1 "$out/lib/${targetPrefix}ghc-${version}" | wc -l) < 30 )); then
echo "ERROR: Expected more files in $out/lib/${targetPrefix}ghc-${version}"
exit 0
fi
fi
'';

passthru = {
Expand Down
1 change: 1 addition & 0 deletions overlays/bootstrap.nix
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ in {
# hadrian one.
++ fromUntil "8.8" "8.12" ./patches/ghc/bec76733b818b0489ffea0834ab6b1560207577c.patch
++ fromUntil "8.8" "8.12" ./patches/ghc/67738db10010fd28a8e997b5c8f83ea591b88a0e.patch
++ final.lib.optional (versionAtLeast "8.6.4" && versionLessThan "8.8") ./patches/ghc/ghc-no-system-linker.patch
;
in ({
ghc844 = final.callPackage ../compiler/ghc {
Expand Down
6 changes: 0 additions & 6 deletions overlays/hackage-quirks.nix
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,6 @@ in { haskell-nix = prev.haskell-nix // {
sha256 = "0jcpja4s4cylmg9rddyakb1p1fb4l41ffwmy0njpb1dxc5z3v618";
};
})
# Musl needs static zlib
(lib.optionalAttrs final.stdenv.hostPlatform.isMusl {
packages.pandoc.components.exes.pandoc.configureFlags = [
"--ghc-option=-optl=-L${final.zlib.static}/lib"
];
})
];
};

Expand Down
13 changes: 13 additions & 0 deletions overlays/musl.nix
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ final: prev: prev.lib.optionalAttrs prev.stdenv.hostPlatform.isMusl ({
# Prevent pkgsMusl.pkgsStatic chain
busybox-sandbox-shell = prev.busybox-sandbox-shell.override { inherit (final) busybox; };

# we don't want the static output to be split. That just
# messes with the z -> libz mapping. We can't have a conditonal
# z -> libz / z -> libz.static mapping without threading the
# package configuration in. That seems a bit overkill.
zlib = prev.zlib.override { splitStaticOutput = false; };

# and a few more packages that need their static libs explicitly enabled
gmp = prev.gmp.override { withStatic = true; };
ncurses = prev.ncurses.override { enableStatic = true; };
libsodium = prev.libsodium.overrideAttrs (_: { dontDisableStatic = true; });

numactl = prev.numactl.overrideAttrs (_: { configureFlags = "--enable-static"; });

# Fails on cross compile
nix = prev.nix.overrideAttrs (_: { doInstallCheck = false; });
} // prev.lib.optionalAttrs (prev.lib.versionAtLeast prev.lib.trivial.release "20.03") {
Expand Down
78 changes: 78 additions & 0 deletions overlays/patches/ghc/ghc-no-system-linker.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
diff --git a/compiler/ghc.cabal.in b/compiler/ghc.cabal.in
index 01628dcad1..209704d034 100644
--- a/compiler/ghc.cabal.in
+++ b/compiler/ghc.cabal.in
@@ -45,6 +45,11 @@ Flag terminfo
Default: True
Manual: True

+Flag dynamic-system-linker
+ Description: The system can load dynamic code. This is not the case for musl.
+ Default: True
+ Manual: False
+
Library
Default-Language: Haskell2010
Exposed: False
@@ -84,6 +89,9 @@ Library
CPP-Options: -DGHCI
Include-Dirs: ../rts/dist/build @FFIIncludeDir@

+ if flag(dynamic-system-linker)
+ CPP-Options: -DCAN_LOAD_DLL
+
Other-Extensions:
BangPatterns
CPP
diff --git a/compiler/ghci/Linker.hs b/compiler/ghci/Linker.hs
index 3b030be2d3..879c5c19ee 100644
--- a/compiler/ghci/Linker.hs
+++ b/compiler/ghci/Linker.hs
@@ -1295,13 +1295,13 @@ linkPackage hsc_env pkg

maybePutStr dflags
("Loading package " ++ sourcePackageIdString pkg ++ " ... ")
-
-- See comments with partOfGHCi
+#if defined(CAN_LOAD_DLL)
when (packageName pkg `notElem` partOfGHCi) $ do
loadFrameworks hsc_env platform pkg
mapM_ (load_dyn hsc_env)
(known_dlls ++ map (mkSOName platform) dlls)
-
+#endif
-- After loading all the DLLs, we can load the static objects.
-- Ordering isn't important here, because we do one final link
-- step to resolve everything.
@@ -1382,10 +1382,15 @@ locateLib hsc_env is_hs lib_dirs gcc_dirs lib
-- O(n). Loading an import library is also O(n) so in general we prefer
-- shared libraries because they are simpler and faster.
--
- = findDll user `orElse`
+ =
+#if defined(CAN_LOAD_DLL)
+ findDll user `orElse`
+#endif
tryImpLib user `orElse`
+#if defined(CAN_LOAD_DLL)
findDll gcc `orElse`
findSysDll `orElse`
+#endif
tryImpLib gcc `orElse`
findArchive `orElse`
tryGcc `orElse`
@@ -1452,7 +1457,13 @@ locateLib hsc_env is_hs lib_dirs gcc_dirs lib
full = dllpath $ search lib_so_name lib_dirs
gcc name = liftM (fmap Archive) $ search name lib_dirs
files = import_libs ++ arch_files
- in apply $ short : full : map gcc files
+ dlls = [short, full]
+ archives = map gcc files
+ in apply $
+#if defined(CAN_LOAD_DLL)
+ dlls ++
+#endif
+ archives
tryImpLib re = case os of
OSMinGW32 ->
let dirs' = if re == user then lib_dirs else gcc_dirs
25 changes: 2 additions & 23 deletions test/fully-static/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -17,32 +17,11 @@ let
src = testSrc "fully-static";
pkg-def-extras = [];
modules = [
# Musl libc fully static build
(let
staticLibs = [
zlib.static
(openssl.override { static = true; }).out
(libffi.overrideAttrs (oldAttrs: {
dontDisableStatic = true;
configureFlags = (oldAttrs.configureFlags or []) ++ [
"--enable-static"
"--disable-shared"
];
}))
] ++ optional gpl (gmp6.override { withStatic = true; });

withFullyStatic = {
configureFlags =
optionals stdenv.hostPlatform.isMusl (map (drv: "--ghc-option=-optl=-L${drv}/lib") staticLibs);
};
in {
{
# Select a non-GMP compiler, usually for software licensing reasons.
ghc.package = mkIf (stdenv.hostPlatform.isMusl && !gpl)
buildPackages.haskell-nix.compiler.integer-simple.${compiler};

# Add GHC flags and libraries for fully static build
packages.pandoc.components.exes.pandoc = withFullyStatic;
})
}
];
};
packagesGmp = (project { gpl = true; }).hsPkgs;
Expand Down