Skip to content

Commit a500f39

Browse files
authored
Musl changes (#700)
This should simplify the interaction with musl quite a but. Musl specific mapping should go into the musl overlay now.
1 parent d7bf7c1 commit a500f39

File tree

7 files changed

+107
-45
lines changed

7 files changed

+107
-45
lines changed

builder/comp-builder.nix

Lines changed: 5 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,6 @@
11
{ stdenv, buildPackages, ghc, lib, gobject-introspection ? null, haskellLib, makeConfigFiles, ghcForComponent, hsPkgs, runCommand, libffi, gmp, zlib, ncurses, numactl, nodejs }:
2-
let
3-
# These are here to avoid multiple calls to override
4-
gmpStatic = gmp.override { withStatic = true; };
5-
zlibStatic = zlib.static;
6-
ncursesStatic = ncurses.override { enableStatic = true; };
7-
numactlStatic = numactl.overrideAttrs (_: { configureFlags = "--enable-static"; });
8-
in
92
lib.makeOverridable (
10-
let self =
3+
let self =
114
{ componentId
125
, component
136
, package
@@ -40,7 +33,10 @@ let self =
4033
, dontStrip ? component.dontStrip
4134

4235
, enableStatic ? component.enableStatic
43-
, enableShared ? component.enableShared && !haskellLib.isCrossHost
36+
, enableShared ? ghc.enableShared && component.enableShared && !haskellLib.isCrossHost
37+
# on x86 we'll use shared libraries, even with musl m(
38+
# ghc's internal linker seems to be broken on x86.
39+
&& !(stdenv.hostPlatform.isMusl && !stdenv.hostPlatform.isx86)
4440
, enableDeadCodeElimination ? component.enableDeadCodeElimination
4541

4642
# Options for Haddock generation
@@ -126,10 +122,6 @@ let
126122
"--disable-executable-dynamic"
127123
"--ghc-option=-optl=-pthread"
128124
"--ghc-option=-optl=-static"
129-
"--ghc-option=-optl=-L${gmpStatic}/lib"
130-
"--ghc-option=-optl=-L${zlibStatic}/lib"
131-
"--ghc-option=-optl=-L${ncursesStatic}/lib"
132-
"--ghc-option=-optl=-L${numactlStatic}/lib"
133125
] ++ lib.optional enableSeparateDataOutput "--datadir=$data/share/${ghc.name}"
134126
++ lib.optional doHaddock' "--docdir=${docdir "$doc"}"
135127
++ lib.optional (enableLibraryProfiling || enableExecutableProfiling) "--profiling-detail=${profilingDetail}"

compiler/ghc/default.nix

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,11 @@ let
107107
'' + stdenv.lib.optionalString (!enableTerminfo) ''
108108
WITH_TERMINFO=NO
109109
''
110+
# musl doesn't have a system-linker. Only on x86, and on x86 we need it, as
111+
# our elf linker for x86_64 is broken.
112+
+ stdenv.lib.optionalString (targetPlatform.isMusl && !targetPlatform.isx86) ''
113+
compiler_CONFIGURE_OPTS += --flags=-dynamic-system-linker
114+
''
110115
# While split sections are now enabled by default in ghc 8.8 for windows,
111116
# the seem to lead to `too many sections` errors when building base for
112117
# profiling.
@@ -284,15 +289,15 @@ stdenv.mkDerivation (rec {
284289
if [[ ! -f "$out/bin/${targetPrefix}ghc-pkg" ]]; then
285290
echo "ERROR: Missing file $out/bin/${targetPrefix}ghc-pkg"
286291
exit 0
287-
fi
292+
fi
288293
if [[ ! -d "$out/lib/${targetPrefix}ghc-${version}" ]]; then
289294
echo "ERROR: Missing directory $out/lib/${targetPrefix}ghc-${version}"
290295
exit 0
291-
fi
296+
fi
292297
if (( $(ls -1 "$out/lib/${targetPrefix}ghc-${version}" | wc -l) < 30 )); then
293298
echo "ERROR: Expected more files in $out/lib/${targetPrefix}ghc-${version}"
294299
exit 0
295-
fi
300+
fi
296301
'';
297302

298303
passthru = {

overlays/bootstrap.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ in {
141141
# hadrian one.
142142
++ fromUntil "8.8" "8.12" ./patches/ghc/bec76733b818b0489ffea0834ab6b1560207577c.patch
143143
++ fromUntil "8.8" "8.12" ./patches/ghc/67738db10010fd28a8e997b5c8f83ea591b88a0e.patch
144+
++ final.lib.optional (versionAtLeast "8.6.4" && versionLessThan "8.8") ./patches/ghc/ghc-no-system-linker.patch
144145
;
145146
in ({
146147
ghc844 = final.callPackage ../compiler/ghc {

overlays/hackage-quirks.nix

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -44,12 +44,6 @@ in { haskell-nix = prev.haskell-nix // {
4444
sha256 = "0jcpja4s4cylmg9rddyakb1p1fb4l41ffwmy0njpb1dxc5z3v618";
4545
};
4646
})
47-
# Musl needs static zlib
48-
(lib.optionalAttrs final.stdenv.hostPlatform.isMusl {
49-
packages.pandoc.components.exes.pandoc.configureFlags = [
50-
"--ghc-option=-optl=-L${final.zlib.static}/lib"
51-
];
52-
})
5347
];
5448
};
5549

overlays/musl.nix

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,19 @@ final: prev: prev.lib.optionalAttrs prev.stdenv.hostPlatform.isMusl ({
1111
# Prevent pkgsMusl.pkgsStatic chain
1212
busybox-sandbox-shell = prev.busybox-sandbox-shell.override { inherit (final) busybox; };
1313

14+
# we don't want the static output to be split. That just
15+
# messes with the z -> libz mapping. We can't have a conditonal
16+
# z -> libz / z -> libz.static mapping without threading the
17+
# package configuration in. That seems a bit overkill.
18+
zlib = prev.zlib.override { splitStaticOutput = false; };
19+
20+
# and a few more packages that need their static libs explicitly enabled
21+
gmp = prev.gmp.override { withStatic = true; };
22+
ncurses = prev.ncurses.override { enableStatic = true; };
23+
libsodium = prev.libsodium.overrideAttrs (_: { dontDisableStatic = true; });
24+
25+
numactl = prev.numactl.overrideAttrs (_: { configureFlags = "--enable-static"; });
26+
1427
# Fails on cross compile
1528
nix = prev.nix.overrideAttrs (_: { doInstallCheck = false; });
1629
} // prev.lib.optionalAttrs (prev.lib.versionAtLeast prev.lib.trivial.release "20.03") {
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
diff --git a/compiler/ghc.cabal.in b/compiler/ghc.cabal.in
2+
index 01628dcad1..209704d034 100644
3+
--- a/compiler/ghc.cabal.in
4+
+++ b/compiler/ghc.cabal.in
5+
@@ -45,6 +45,11 @@ Flag terminfo
6+
Default: True
7+
Manual: True
8+
9+
+Flag dynamic-system-linker
10+
+ Description: The system can load dynamic code. This is not the case for musl.
11+
+ Default: True
12+
+ Manual: False
13+
+
14+
Library
15+
Default-Language: Haskell2010
16+
Exposed: False
17+
@@ -84,6 +89,9 @@ Library
18+
CPP-Options: -DGHCI
19+
Include-Dirs: ../rts/dist/build @FFIIncludeDir@
20+
21+
+ if flag(dynamic-system-linker)
22+
+ CPP-Options: -DCAN_LOAD_DLL
23+
+
24+
Other-Extensions:
25+
BangPatterns
26+
CPP
27+
diff --git a/compiler/ghci/Linker.hs b/compiler/ghci/Linker.hs
28+
index 3b030be2d3..879c5c19ee 100644
29+
--- a/compiler/ghci/Linker.hs
30+
+++ b/compiler/ghci/Linker.hs
31+
@@ -1295,13 +1295,13 @@ linkPackage hsc_env pkg
32+
33+
maybePutStr dflags
34+
("Loading package " ++ sourcePackageIdString pkg ++ " ... ")
35+
-
36+
-- See comments with partOfGHCi
37+
+#if defined(CAN_LOAD_DLL)
38+
when (packageName pkg `notElem` partOfGHCi) $ do
39+
loadFrameworks hsc_env platform pkg
40+
mapM_ (load_dyn hsc_env)
41+
(known_dlls ++ map (mkSOName platform) dlls)
42+
-
43+
+#endif
44+
-- After loading all the DLLs, we can load the static objects.
45+
-- Ordering isn't important here, because we do one final link
46+
-- step to resolve everything.
47+
@@ -1382,10 +1382,15 @@ locateLib hsc_env is_hs lib_dirs gcc_dirs lib
48+
-- O(n). Loading an import library is also O(n) so in general we prefer
49+
-- shared libraries because they are simpler and faster.
50+
--
51+
- = findDll user `orElse`
52+
+ =
53+
+#if defined(CAN_LOAD_DLL)
54+
+ findDll user `orElse`
55+
+#endif
56+
tryImpLib user `orElse`
57+
+#if defined(CAN_LOAD_DLL)
58+
findDll gcc `orElse`
59+
findSysDll `orElse`
60+
+#endif
61+
tryImpLib gcc `orElse`
62+
findArchive `orElse`
63+
tryGcc `orElse`
64+
@@ -1452,7 +1457,13 @@ locateLib hsc_env is_hs lib_dirs gcc_dirs lib
65+
full = dllpath $ search lib_so_name lib_dirs
66+
gcc name = liftM (fmap Archive) $ search name lib_dirs
67+
files = import_libs ++ arch_files
68+
- in apply $ short : full : map gcc files
69+
+ dlls = [short, full]
70+
+ archives = map gcc files
71+
+ in apply $
72+
+#if defined(CAN_LOAD_DLL)
73+
+ dlls ++
74+
+#endif
75+
+ archives
76+
tryImpLib re = case os of
77+
OSMinGW32 ->
78+
let dirs' = if re == user then lib_dirs else gcc_dirs

test/fully-static/default.nix

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,32 +17,11 @@ let
1717
src = testSrc "fully-static";
1818
pkg-def-extras = [];
1919
modules = [
20-
# Musl libc fully static build
21-
(let
22-
staticLibs = [
23-
zlib.static
24-
(openssl.override { static = true; }).out
25-
(libffi.overrideAttrs (oldAttrs: {
26-
dontDisableStatic = true;
27-
configureFlags = (oldAttrs.configureFlags or []) ++ [
28-
"--enable-static"
29-
"--disable-shared"
30-
];
31-
}))
32-
] ++ optional gpl (gmp6.override { withStatic = true; });
33-
34-
withFullyStatic = {
35-
configureFlags =
36-
optionals stdenv.hostPlatform.isMusl (map (drv: "--ghc-option=-optl=-L${drv}/lib") staticLibs);
37-
};
38-
in {
20+
{
3921
# Select a non-GMP compiler, usually for software licensing reasons.
4022
ghc.package = mkIf (stdenv.hostPlatform.isMusl && !gpl)
4123
buildPackages.haskell-nix.compiler.integer-simple.${compiler};
42-
43-
# Add GHC flags and libraries for fully static build
44-
packages.pandoc.components.exes.pandoc = withFullyStatic;
45-
})
24+
}
4625
];
4726
};
4827
packagesGmp = (project { gpl = true; }).hsPkgs;

0 commit comments

Comments
 (0)