-
-
Notifications
You must be signed in to change notification settings - Fork 13.7k
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
[WIP] mingw-w64 for haskell cross compilation with ghc. #37254
Conversation
/cc @Ericson2314 |
@@ -4,7 +4,7 @@ | |||
}: | |||
|
|||
# Prebuilt only does native | |||
assert stdenv.targetPlatform == stdenv.hostPlatform; | |||
# assert stdenv.targetPlatform == stdenv.hostPlatform; |
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.
While disabling this check, allows most of the cross compilation to succeed on macOS, I believe this is also the reason why we end up with mixed (build and target) packages in the stdenv eventually.
@@ -161,7 +175,11 @@ stdenv.mkDerivation rec { | |||
# zsh and other shells are smart about `{ghc}` but bash isn't, and doesn't | |||
# treat that as a unary `{x,y,z,..}` repetition. | |||
postInstall = '' | |||
paxmark m $out/lib/${name}/bin/${if targetPlatform != hostPlatform then "ghc" else "{ghc,haddock}"} |
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.
This change is motivated by the fact that we do not necessarily build haddock
with quick flavours. As such we fall over trying to paxmark
a file that does not exist.
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.
Sounds good-- probably can collapse this to just {ghc,haddock}
if we check for existence anyway.
"--with-strip=${stdenv.cc.bintools.targetPrefix}strip" | ||
] ++ (if isHaLVM then [] else ["--hsc2hs-options=--cross-compile"]); | ||
] ++ (if isHaLVM then [] else ["--hsc2hs-option=--cross-compile" | ||
"--hsc2hs-option=--via-asm"]); |
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.
--via-asm
is a rather recent feature in hsc2hs
that is part of ghc > 8.4
@@ -12,7 +12,7 @@ let | |||
"${targetPlatform.config}-"; | |||
in | |||
|
|||
assert targetPlatform.isDarwin; | |||
assert stdenv.isDarwin; |
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.
This could potentially also be the reason for the incorrect package set on darwin.
|
||
, version ? "8.5.20180118" | ||
, ghcRevision ? "e1d4140be4d2a1508015093b69e1ef53516e1eb6" | ||
, ghcSha256 ? "1gdcr10dd968d40qgljdwx9vfkva3yrvjm9a4nis7whaaac3ag58" | ||
, ghcFlavour ? "" |
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.
Better to do ghcFlavour ? if targetPlatform != hostPlatform then "perf-cros" else ""
c8f682e
to
de9b33e
Compare
enableShared ? (targetPlatform == hostPlatform && !targetPlatform.isWindows) | ||
|
||
, # Whetherto build terminfo. | ||
enableTerminfo ? !targetPlatform.isWindows |
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.
Does terminfo/ncurses not work on windows?
If it was failing to find ncurses headers/libs see the fix on my musl PR (remove attempt to specify where to find them).
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.
In the case of cross compiling to windows, we don't want terminfo, the GHC build system disables terminfoin that case anyway.
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.
It only disables it in some cross build "flavour"s, which we don't have to use as-is. Works for me building cross-aarch64-musl and such. Anyway sounds like you're saying windows in particular shouldn't use this, which I'll take your word for.
setupConfigureFlags+=" --extra-lib-dirs=$p/lib" | ||
fi | ||
done | ||
${nativeGhcCommand}-pkg --${packageDbFlag}="$setupPackageConfDir" recache |
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.
👍
If you're touching cctools, #37606 might have some useful bits. |
enableShared ? true | ||
# | ||
# We don't do this by default if target != host, or if we target windows. | ||
enableShared ? (targetPlatform == hostPlatform && !targetPlatform.isWindows) |
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.
I believe that the description of this option is actually quite incorrect and misleading. Setting this to true has no effect on whether ghc builds shared libraries or not. Rather, it affects the code that's used by ghci
to load compiled objects for interpretation. There's a good chance that this setting is completely ignored on Windows anyway. Could you please check whether the change you've made here is actually necessary?
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.
enable*
is about how the current package is linked. I think this does just that. That this also affects how GHCi works is just a side affect due to GHCi's fragile interpretation.
Beep boop, how's this going? |
@dtzWill this does work as-is (I've used this to build So I ended up writing Cabal2Nix, which really needs a better name. I now have hackage.nix, stackage.nix as well as some glue code in haskell.nix. This is pretty much work-in-progress. While it does allow me to build some trivial hs-hello package, it is nowhere near polished yet, and will likely see some additional changes. I believe it will provide a much better basis for cross compilation haskell packages. |
@angerman that sounds fascinating but I think your links are broken? |
# Add the setupHaskellDepends to a custom package-db, | ||
# which ghc will be provided with. | ||
|
||
for p in ${lib.escapeShellArgs setupHaskellDepends}; do |
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.
Here propagated setup dependencies are not taken into account. That is, your pkgdb will contain only immediate setup dependencies but their transitive dependencies will not be in it, so it won’t compile.
configureSetup = buildHaskellPackages.setup { setupHs = '' | ||
import Distribution.Simple | ||
main = defaultMainWithHooks autoconfUserHooks | ||
''; |
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.
inherit setupHaskellDepends
, I guess.
|
||
phases = [ "buildPhase" ]; | ||
|
||
buildInputs = [ ghc ] ++ setupHaskellDepends; |
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.
I think ghc
should go to nativeBuildInputs
.
For cross compilation, we don't need it, it's deferred to the Setup derivation. When ghc is th enativeGhc, we don't need to add it to the buildInputs either.
nixpkgs#37012 and nixpkgs#37707 introduces the setup-hooks for libiconv, which inject `-liconv` into the `NIX_LDFLAGS`. This breaks horribly on windows where the linker end up having no idea how to linke `-liconv`. The configure.ac file specifically ignores libiconv on windows.
This reverts commit 7f86470.
98cff92
to
68d2d15
Compare
Nix cc logic relies on passing /lib for each dependency as a library search path. This makes little sense for haskell packages, as their libs are nested deeply in the /lib tree. Also GHC will generate the right library serach paths on its own from the package database entries. The larger issue though is that with one search path entry for each library, and a similar one generated by GHC for each dependency will eventually overflow the command line argument limits. As such we do *not* put haskell libraries into $out anymore.
Motivation for this change
This includes all the necessary changes to nixpkgs, that allow me to cross compile haskell to
windows via mingw-w64. It is not yet sufficient to allow cross compilation of Template Haskell.
Things done
build-use-sandbox
innix.conf
on non-NixOS)nix-shell -p nox --run "nox-review wip"
./result/bin/
)