1# This is the nix expression to build ghc. The Glasgow Haskell Compiler. It is
2# heavily inspired (and based) upon the ghc expression from nixos/nixpkgs.
3# haskell.nix ships its own version of the ghc expression as it needs more
4# control over the expression to isolate it against varying <nixpkgs> and
5# allow us to customize it to the way haskell.nix works.
6{ stdenv, haskell-nix, targetPackages
10, autoconf, automake, coreutils, fetchurl, fetchpatch, perl, python3, m4, sphinx, numactl
14, libiconv ? null, ncurses
18, # GHC can be built with system libffi or a bundled one.
21, useLLVM ? !stdenv.targetPlatform.isx86
22, # LLVM is conceptually a run-time-only dependency, but for
23 # non-x86, we need LLVM to bootstrap later stages, so it becomes a
24 # build-time dependency too.
25 buildLlvmPackages, llvmPackages
27, # If enabled, GHC will be built with the GPL-free but slower integer-simple
28 # library instead of the faster but GPLed integer-gmp library.
29 enableIntegerSimple ? !(stdenv.lib.any (stdenv.lib.meta.platformMatch stdenv.hostPlatform) gmp.meta.platforms), gmp
31, # If enabled, use -fPIC when compiling static libs.
32 enableRelocatedStaticLibs ? stdenv.targetPlatform != stdenv.hostPlatform && !stdenv.targetPlatform.isAarch32
34, # Whether to build dynamic libs for the standard library (on the target
35 # platform). Static libs are always built.
36 enableShared ? !haskell-nix.haskellLib.isCrossTarget
38, enableLibraryProfiling ? true
40, # Whether to build terminfo. Musl fails to build terminfo as ncurses seems to be linked to glibc
41 enableTerminfo ? !stdenv.targetPlatform.isWindows && !stdenv.targetPlatform.isMusl
43, # What flavour to build. An empty string indicates no
44 # specific flavour and falls back to ghc default values.
45 ghcFlavour ? stdenv.lib.optionalString haskell-nix.haskellLib.isCrossTarget (
51, # Whether to disable the large address space allocator
52 # necessary fix for iOS: https://www.reddit.com/r/haskell/comments/4ttdz1/building_an_osxi386_to_iosarm64_cross_compiler/d5qvd67/
53 disableLargeAddressSpace ? stdenv.targetPlatform.isDarwin && stdenv.targetPlatform.isAarch64
55, ghc-version ? src-spec.version
59# extra values we want to have available as passthru values.
63assert !enableIntegerSimple -> gmp != null;
66 inherit (stdenv) buildPlatform hostPlatform targetPlatform;
67 inherit (haskell-nix.haskellLib) isCrossTarget;
69 inherit (bootPkgs) ghc;
71 # TODO check if this possible fix for segfaults works or not.
73 # on native platforms targetPlatform.{libffi, gmp} do not exist; thus fall back
74 # to the non-targetPlatform version in those cases.
75 let targetLibffi = targetPackages.libffi or libffi; in
76 # we need to set `dontDisableStatic` for musl for libffi to work.
77 if stdenv.targetPlatform.isMusl
78 then targetLibffi.overrideAttrs (old: { dontDisableStatic = true; })
81 targetGmp = targetPackages.gmp or gmp;
83 # TODO(@Ericson2314) Make unconditional
84 targetPrefix = stdenv.lib.optionalString
85 (targetPlatform != hostPlatform)
86 "${targetPlatform.config}-";
89 BuildFlavour = ${ghcFlavour}
90 ifneq \"\$(BuildFlavour)\" \"\"
91 include mk/flavours/\$(BuildFlavour).mk
93 DYNAMIC_GHC_PROGRAMS = ${if enableShared then "YES" else "NO"}
94 INTEGER_LIBRARY = ${if enableIntegerSimple then "integer-simple" else "integer-gmp"}
95 '' + stdenv.lib.optionalString (targetPlatform != hostPlatform) ''
96 CrossCompilePrefix = ${targetPrefix}
97 '' + stdenv.lib.optionalString isCrossTarget ''
98 Stage1Only = ${if targetPlatform.system == hostPlatform.system then "NO" else "YES"}
100 BUILD_SPHINX_HTML = NO
101 BUILD_SPHINX_PDF = NO
102 '' + stdenv.lib.optionalString enableRelocatedStaticLibs ''
103 GhcLibHcOpts += -fPIC
104 GhcRtsHcOpts += -fPIC
105 '' + stdenv.lib.optionalString targetPlatform.useAndroidPrebuilt ''
106 EXTRA_CC_OPTS += -std=gnu99
107 '' + stdenv.lib.optionalString (!enableTerminfo) ''
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
115 # While split sections are now enabled by default in ghc 8.8 for windows,
116 # the seem to lead to `too many sections` errors when building base for
118 + stdenv.lib.optionalString targetPlatform.isWindows ''
120 '' + stdenv.lib.optionalString (!enableLibraryProfiling) ''
124 # Splicer will pull out correct variations
125 libDeps = platform: stdenv.lib.optional enableTerminfo [ ncurses ]
127 ++ stdenv.lib.optional (!enableIntegerSimple) gmp
128 ++ stdenv.lib.optional (platform.libc != "glibc" && !targetPlatform.isWindows) libiconv
129 ++ stdenv.lib.optional (platform.isLinux && !platform.isAarch32) numactl;
132 if hostPlatform == buildPlatform then
133 [ targetPackages.stdenv.cc ] ++ stdenv.lib.optional useLLVM llvmPackages.llvm
134 else assert targetPlatform == hostPlatform; # build != host == target
135 [ stdenv.cc ] ++ stdenv.lib.optional useLLVM buildLlvmPackages.llvm;
137 targetCC = builtins.head toolsForTarget;
139 configured-src = import ./configured-src.nix {
140 inherit stdenv fetchurl
141 ghc-version ghc-patches src-spec
143 targetPlatform hostPlatform
145 perl autoconf automake m4 python3 sphinx ghc bootPkgs
146 autoreconfHook toolsForTarget bash
150 enableIntegerSimple targetGmp
151 ncurses targetLibffi libiconv
152 disableLargeAddressSpace
157stdenv.mkDerivation (rec {
158 version = ghc-version;
159 name = "${targetPrefix}ghc-${version}";
161 patches = ghc-patches;
163 # for this to properly work (with inheritance of patches, postPatch, ...)
164 # this needs to be a function over the values we want to inherit and then called
165 # accordingly. Most trivial might be to just have args, and mash them into the
167 src = configured-src;
169 # configure was run by configured-src already.
170 phases = [ "unpackPhase" "buildPhase"
171 "checkPhase" "installPhase"
177 # ghc hardcodes the TOP dir during config, this breaks when
178 # splitting the configured src from the build process.
181 TOP=$(cat mk/config.mk|grep ^TOP|awk -F\ '{ print $3 }')
182 PREFIX=$(cat mk/install.mk|grep ^prefix|awk -F\ '{ print $3 }')
184 # these two are required
185 substituteInPlace mk/config.mk --replace "$TOP" "$PWD" \
186 --replace "$PREFIX" "$out"
188 substituteInPlace mk/install.mk --replace "$TOP" "$PWD" \
189 --replace "$PREFIX" "$out"
191 # these two only for convencience.
192 substituteInPlace config.log --replace "$TOP" "$PWD"\
193 --replace "$PREFIX" "$out"
194 substituteInPlace config.status --replace "$TOP" "$PWD"\
195 --replace "$PREFIX" "$out")
200 enableParallelBuilding = true;
201 postPatch = "patchShebangs .";
203 outputs = [ "out" "doc" "generated" ];
205 # Make sure we never relax`$PATH` and hooks support for compatibility.
208 # Don’t add -liconv to LDFLAGS automatically so that GHC will add it itself.
209 dontAddExtraLibs = true;
211 nativeBuildInputs = [
212 perl autoconf automake m4 python3 sphinx
213 ghc bootPkgs.alex bootPkgs.happy bootPkgs.hscolour
214 ] ++ stdenv.lib.optional (patches != []) autoreconfHook;
216 # For building runtime libs
217 depsBuildTarget = toolsForTarget;
219 buildInputs = [ perl bash ] ++ (libDeps hostPlatform);
221 propagatedBuildInputs = [ targetPackages.stdenv.cc ]
222 ++ stdenv.lib.optional useLLVM llvmPackages.llvm;
224 depsTargetTarget = map stdenv.lib.getDev (libDeps targetPlatform);
225 depsTargetTargetPropagated = map (stdenv.lib.getOutput "out") (libDeps targetPlatform);
227 # required, because otherwise all symbols from HSffi.o are stripped, and
228 # that in turn causes GHCi to abort
229 stripDebugFlags = [ "-S" ] ++ stdenv.lib.optional (!targetPlatform.isDarwin) "--keep-file-symbols";
231 # See #63511 - the only unstripped file is the debug rts which isn't meant to
233 stripDebugList = [ "lib/${name}/bin" ];
235 checkTarget = "test";
237 hardeningDisable = [ "format" ]
238 ++ stdenv.lib.optional stdenv.targetPlatform.isAarch32 "pic"
239 ++ stdenv.lib.optional stdenv.targetPlatform.isMusl "pie";
242 # Install the bash completion file.
243 install -D -m 444 utils/completion/ghc.bash $out/share/bash-completion/completions/${targetPrefix}ghc
245 # Patch scripts to include "readelf" and "cat" in $PATH.
246 for i in "$out/bin/"*; do
247 test ! -h $i || continue
248 egrep --quiet '^#!' <(head -n 1 $i) || continue
249 # The ghcprog fixup is for musl (where runhaskell script just needs to point to the correct
250 # ghc program to work).
252 -e '2i export PATH="$PATH:${stdenv.lib.makeBinPath [ targetPackages.stdenv.cc.bintools coreutils ]}"' \
253 -e 's/ghcprog="ghc-/ghcprog="${targetPrefix}ghc-/' \
257 # Save generated files for needed when building ghcjs
258 mkdir -p $generated/includes/dist-derivedconstants/header
259 cp includes/dist-derivedconstants/header/GHCConstantsHaskellExports.hs \
260 includes/dist-derivedconstants/header/GHCConstantsHaskellType.hs \
261 includes/dist-derivedconstants/header/GHCConstantsHaskellWrappers.hs \
262 $generated/includes/dist-derivedconstants/header
263 if [[ -f includes/ghcplatform.h ]]; then
264 cp includes/ghcplatform.h $generated/includes
265 elif [[ -f includes/dist-install/build/ghcplatform.h ]]; then
266 cp includes/dist-install/build/ghcplatform.h $generated/includes
268 mkdir -p $generated/compiler/stage2/build
269 cp compiler/stage2/build/Config.hs $generated/compiler/stage2/build || true
270 mkdir -p $generated/rts/build
271 cp rts/build/config.hs-incl $generated/rts/build || true
273 # Save generated files for needed when building ghc-boot
274 mkdir -p $generated/libraries/ghc-boot/dist-install/build/GHC/Platform
275 if [[ -f libraries/ghc-boot/dist-install/build/GHC/Version.hs ]]; then
276 cp libraries/ghc-boot/dist-install/build/GHC/Version.hs $generated/libraries/ghc-boot/dist-install/build/GHC/Version.hs
278 if [[ -f libraries/ghc-boot/dist-install/build/GHC/Platform/Host.hs ]]; then
279 cp libraries/ghc-boot/dist-install/build/GHC/Platform/Host.hs $generated/libraries/ghc-boot/dist-install/build/GHC/Platform/Host.hs
282 ${installDeps targetPrefix}
284 # Sanity checks for https://github.com/input-output-hk/haskell.nix/issues/660
285 if ! "$out/bin/${targetPrefix}ghc" --version; then
286 echo "ERROR: Missing file $out/bin/${targetPrefix}ghc"
289 if ! "$out/bin/${targetPrefix}ghc-pkg" --version; then
290 echo "ERROR: Missing file $out/bin/${targetPrefix}ghc-pkg"
293 if [[ ! -d "$out/lib/${targetPrefix}ghc-${version}" ]]; then
294 echo "ERROR: Missing directory $out/lib/${targetPrefix}ghc-${version}"
297 if (( $(ls -1 "$out/lib/${targetPrefix}ghc-${version}" | wc -l) < 30 )); then
298 echo "ERROR: Expected more files in $out/lib/${targetPrefix}ghc-${version}"
304 inherit bootPkgs targetPrefix;
306 inherit llvmPackages;
307 inherit enableShared;
310 # Our Cabal compiler name
311 haskellCompilerName = "ghc-${version}";
313 configured-src = configured-src;
315 # Used to detect non haskell-nix compilers (accidental use of nixpkgs compilers can lead to unexpected errors)
316 isHaskellNixCompiler = true;
320 homepage = http://haskell.org/ghc;
321 description = "The Glasgow Haskell Compiler";
323 inherit (ghc.meta) license platforms;
326} // stdenv.lib.optionalAttrs targetPlatform.useAndroidPrebuilt {
329 noAuditTmpdir = true;
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list