-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
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
haskell.compiler.ghc*: fix cross-built native GHC #243619
Changes from all commits
c3ab42d
ebf5462
80b2ffd
bc44d9a
f0653bb
b0379b4
b41be4b
8f422a5
1801e27
640b562
d64620d
4e0921f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -1,8 +1,8 @@ | ||||||
{ lib, stdenv, pkgsBuildTarget, pkgsHostTarget, targetPackages | ||||||
{ lib, stdenv, pkgsBuildTarget, pkgsHostTarget, buildPackages, targetPackages | ||||||
|
||||||
# build-tools | ||||||
, bootPkgs | ||||||
, autoconf, automake, coreutils, fetchpatch, fetchurl, perl, python3, m4, sphinx | ||||||
, autoreconfHook, autoconf, automake, coreutils, fetchpatch, fetchurl, perl, python3, m4, sphinx | ||||||
, xattr, autoSignDarwinBinariesHook | ||||||
, bash | ||||||
|
||||||
|
@@ -44,25 +44,35 @@ | |||||
|
||||||
, # Whether to build sphinx documentation. | ||||||
enableDocs ? ( | ||||||
# Docs disabled if we are building on musl because it's a large task to keep | ||||||
# all `sphinx` dependencies building in this environment. | ||||||
!stdenv.buildPlatform.isMusl | ||||||
# Docs disabled if we are building on musl or cross-building because it's a | ||||||
# large task to keep all `sphinx` dependencies building in this environment. | ||||||
(stdenv.buildPlatform == stdenv.hostPlatform && stdenv.targetPlatform == stdenv.hostPlatform) | ||||||
&& !stdenv.buildPlatform.isMusl | ||||||
) | ||||||
|
||||||
, enableHaddockProgram ? | ||||||
# Disabled for cross; see note [HADDOCK_DOCS]. | ||||||
(stdenv.targetPlatform == stdenv.hostPlatform) | ||||||
(stdenv.buildPlatform == stdenv.hostPlatform && stdenv.targetPlatform == stdenv.hostPlatform) | ||||||
|
||||||
, # 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/ | ||||||
disableLargeAddressSpace ? stdenv.targetPlatform.isiOS | ||||||
|
||||||
, # Whether to build an unregisterised version of GHC. | ||||||
# GHC will normally auto-detect whether it can do a registered build, but this | ||||||
# option will force it to do an unregistered build when set to true. | ||||||
# See https://gitlab.haskell.org/ghc/ghc/-/wikis/building/unregisterised | ||||||
enableUnregisterised ? false | ||||||
}: | ||||||
|
||||||
assert !enableIntegerSimple -> gmp != null; | ||||||
|
||||||
# Cross cannot currently build the `haddock` program for silly reasons, | ||||||
# see note [HADDOCK_DOCS]. | ||||||
assert (stdenv.targetPlatform != stdenv.hostPlatform) -> !enableHaddockProgram; | ||||||
assert (stdenv.buildPlatform != stdenv.hostPlatform || stdenv.targetPlatform != stdenv.hostPlatform) -> !enableHaddockProgram; | ||||||
|
||||||
# GHC does not support building when all 3 platforms are different. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nixpkgs doesn't either (but I guess we can keep the comment in case it does at some point in the future). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Noted, though I agree about the future-proofing (for both the comment and the asserts). |
||||||
assert stdenv.buildPlatform == stdenv.hostPlatform || stdenv.hostPlatform == stdenv.targetPlatform; | ||||||
|
||||||
let | ||||||
inherit (stdenv) buildPlatform hostPlatform targetPlatform; | ||||||
|
@@ -129,7 +139,9 @@ let | |||||
pkgsBuildTarget.targetPackages.stdenv.cc | ||||||
] ++ lib.optional useLLVM buildTargetLlvmPackages.llvm; | ||||||
|
||||||
buildCC = buildPackages.stdenv.cc; | ||||||
targetCC = builtins.head toolsForTarget; | ||||||
installCC = pkgsHostTarget.targetPackages.stdenv.cc; | ||||||
|
||||||
# Sometimes we have to dispatch between the bintools wrapper and the unwrapped | ||||||
# derivation for certain tools depending on the platform. | ||||||
|
@@ -161,14 +173,11 @@ let | |||||
(lib.optionalString enableIntegerSimple "-integer-simple") | ||||||
]; | ||||||
|
||||||
in | ||||||
targetLibffi = if hostPlatform != targetPlatform | ||||||
then targetPackages.libffi | ||||||
else pkgsHostTarget.libffi; | ||||||
|
||||||
# C compiler, bintools and LLVM are used at build time, but will also leak into | ||||||
# the resulting GHC's settings file and used at runtime. This means that we are | ||||||
# currently only able to build GHC if hostPlatform == buildPlatform. | ||||||
assert targetCC == pkgsHostTarget.targetPackages.stdenv.cc; | ||||||
assert buildTargetLlvmPackages.llvm == llvmPackages.llvm; | ||||||
assert stdenv.targetPlatform.isDarwin -> buildTargetLlvmPackages.clang == llvmPackages.clang; | ||||||
in | ||||||
|
||||||
stdenv.mkDerivation (rec { | ||||||
version = "8.10.7"; | ||||||
|
@@ -223,6 +232,12 @@ stdenv.mkDerivation (rec { | |||||
stripLen = 3; | ||||||
extraPrefix = "libraries/Cabal/Cabal/"; | ||||||
}) | ||||||
|
||||||
# We need to be able to set AR_STAGE0 and LD_STAGE0 when cross-compiling | ||||||
(fetchpatch { | ||||||
url = "https://gitlab.haskell.org/ghc/ghc/-/commit/8f7dd5710b80906ea7a3e15b7bb56a883a49fed8.patch"; | ||||||
hash = "sha256-C636Nq2U8YOG/av7XQmG3L1rU0bmC9/7m7Hty5pm5+s="; | ||||||
}) | ||||||
sternenseemann marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
] ++ lib.optionals stdenv.isDarwin [ | ||||||
# Make Block.h compile with c++ compilers. Remove with the next release | ||||||
(fetchpatch { | ||||||
|
@@ -241,6 +256,9 @@ stdenv.mkDerivation (rec { | |||||
|
||||||
postPatch = "patchShebangs ."; | ||||||
|
||||||
# GHC is unable to build a cross-compiler without this set. | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you be more specific why this is needed? I'm guessing the build->build CC needs to be exposed as There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Unfortunately I have no idea myself. I figured out it was needed by diffing the environment variables between |
||||||
"NIX_CC_WRAPPER_TARGET_HOST_${buildCC.suffixSalt}" = 1; | ||||||
|
||||||
# GHC is a bit confused on its cross terminology. | ||||||
# TODO(@sternenseemann): investigate coreutils dependencies and pass absolute paths | ||||||
preConfigure = '' | ||||||
|
@@ -269,6 +287,9 @@ stdenv.mkDerivation (rec { | |||||
# LLVM backend on Darwin needs clang: https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/codegens.html#llvm-code-generator-fllvm | ||||||
export CLANG="${buildTargetLlvmPackages.clang}/bin/${buildTargetLlvmPackages.clang.targetPrefix}clang" | ||||||
'' + '' | ||||||
export CC_STAGE0="${buildCC}/bin/${buildCC.targetPrefix}cc" | ||||||
export LD_STAGE0="${buildCC.bintools}/bin/${buildCC.bintools.targetPrefix}ld" | ||||||
export AR_STAGE0="${buildCC.bintools.bintools}/bin/${buildCC.bintools.targetPrefix}ar" | ||||||
|
||||||
echo -n "${buildMK}" > mk/build.mk | ||||||
sed -i -e 's|-isysroot /Developer/SDKs/MacOSX10.5.sdk||' configure | ||||||
|
@@ -299,18 +320,22 @@ stdenv.mkDerivation (rec { | |||||
done | ||||||
''; | ||||||
|
||||||
# Although it is usually correct to pass --host, we don't do that here because | ||||||
# GHC's usage of build, host, and target is non-standard. | ||||||
# See https://gitlab.haskell.org/ghc/ghc/-/wikis/building/cross-compiling | ||||||
# TODO(@Ericson2314): Always pass "--target" and always prefix. | ||||||
configurePlatforms = [ "build" "host" ] | ||||||
++ lib.optional (targetPlatform != hostPlatform) "target"; | ||||||
configurePlatforms = [ "build" ] | ||||||
++ lib.optional (buildPlatform != hostPlatform || targetPlatform != hostPlatform) "target"; | ||||||
|
||||||
# `--with` flags for libraries needed for RTS linker | ||||||
configureFlags = [ | ||||||
"--datadir=$doc/share/doc/ghc" | ||||||
"--with-curses-includes=${ncurses.dev}/include" "--with-curses-libraries=${ncurses.out}/lib" | ||||||
"--with-curses-includes=${buildPackages.ncurses.dev}/include" | ||||||
"--with-curses-libraries=${buildPackages.ncurses.out}/lib" | ||||||
] ++ lib.optionals (libffi != null) [ | ||||||
"--with-system-libffi" | ||||||
"--with-ffi-includes=${targetPackages.libffi.dev}/include" | ||||||
"--with-ffi-libraries=${targetPackages.libffi.out}/lib" | ||||||
"--with-ffi-includes=${targetLibffi.dev}/include" | ||||||
"--with-ffi-libraries=${targetLibffi.out}/lib" | ||||||
] ++ lib.optionals (targetPlatform == hostPlatform && !enableIntegerSimple) [ | ||||||
"--with-gmp-includes=${targetPackages.gmp.dev}/include" | ||||||
"--with-gmp-libraries=${targetPackages.gmp.out}/lib" | ||||||
|
@@ -325,6 +350,8 @@ stdenv.mkDerivation (rec { | |||||
"CONF_GCC_LINKER_OPTS_STAGE2=-fuse-ld=gold" | ||||||
] ++ lib.optionals (disableLargeAddressSpace) [ | ||||||
"--disable-large-address-space" | ||||||
] ++ lib.optionals enableUnregisterised [ | ||||||
"--enable-unregisterised" | ||||||
]; | ||||||
|
||||||
# Make sure we never relax`$PATH` and hooks support for compatibility. | ||||||
|
@@ -334,7 +361,7 @@ stdenv.mkDerivation (rec { | |||||
dontAddExtraLibs = true; | ||||||
|
||||||
nativeBuildInputs = [ | ||||||
perl autoconf automake m4 python3 | ||||||
perl autoreconfHook autoconf automake m4 python3 | ||||||
ghc bootPkgs.alex bootPkgs.happy bootPkgs.hscolour | ||||||
] ++ lib.optionals (stdenv.isDarwin && stdenv.isAarch64) [ | ||||||
autoSignDarwinBinariesHook | ||||||
|
@@ -372,6 +399,14 @@ stdenv.mkDerivation (rec { | |||||
requiredSystemFeatures = [ "big-parallel" ]; | ||||||
|
||||||
postInstall = '' | ||||||
# Make the installed GHC use the host platform's tools. | ||||||
sed -i $out/lib/${targetPrefix}${passthru.haskellCompilerName}/settings \ | ||||||
-e "s!$CC!${installCC}/bin/${installCC.targetPrefix}cc!g" \ | ||||||
-e "s!$CXX!${installCC}/bin/${installCC.targetPrefix}c++!g" \ | ||||||
-e "s!$LD!${installCC.bintools}/bin/${installCC.bintools.targetPrefix}ld${lib.optionalString useLdGold ".gold"}!g" \ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here technically a separate useGold condition makes sense, but I don't think bintools can in practice differ between |
||||||
-e "s!$AR!${installCC.bintools.bintools}/bin/${installCC.bintools.targetPrefix}ar!g" \ | ||||||
-e "s!$RANLIB!${installCC.bintools.bintools}/bin/${installCC.bintools.targetPrefix}ranlib!g" | ||||||
|
||||||
# Install the bash completion file. | ||||||
install -D -m 444 utils/completion/ghc.bash $out/share/bash-completion/completions/${targetPrefix}ghc | ||||||
''; | ||||||
|
@@ -397,7 +432,8 @@ stdenv.mkDerivation (rec { | |||||
guibou | ||||||
] ++ lib.teams.haskell.members; | ||||||
timeout = 24 * 3600; | ||||||
inherit (ghc.meta) license platforms; | ||||||
platforms = lib.platforms.all; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This change is right, but means we need to find a new mechanism to implement this: #240348. Not sure how that should look tbh, there is not a lot of prior art on detecting if something can be boostrapped in nixpkgs… There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ideally, I think we'd want a way of recursively checking that the entire closure supports the build platform and isn't marked broken. I'm not aware of an existing function to check that. Perhaps it'd be easier to give users the option to override If we still want to automatically choose whether to use it or not, how about this?
It's not general enough to be usable on everything in Nixpkgs, but it should at the very least prevent a regression here. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
You can't do that in nixpkgs. This is the PR which adds that capability: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
As long as this is being changed, let's switch to the non-deprecated form... There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there documentation about this? |
||||||
inherit (ghc.meta) license; | ||||||
}; | ||||||
|
||||||
} // lib.optionalAttrs targetPlatform.useAndroidPrebuilt { | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you split out "add
autoreconfHook
" as a separate commit? That's a no-brainer, easy to approve.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The latest
haskell-updates
has dropped 8.8.4, so I don't think there will be much reason to do this once I've rebased. After rebasing, all the commit will do is addautoreconfHook
and a patch forconfigure.ac
.