Skip to content
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*: cross-compiled ghc [iteration on alex's PR] #305392

Merged
merged 16 commits into from
Sep 8, 2024

Conversation

sternenseemann
Copy link
Member

Description of changes

Based on #243619

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
    • x86_64-darwin
    • aarch64-darwin
  • For non-Linux: Is sandboxing enabled in nix.conf? (See Nix manual)
    • sandbox = relaxed
    • sandbox = true
  • Tested, as applicable:
  • Tested compilation of all packages that depend on this change using nix-shell -p nixpkgs-review --run "nixpkgs-review rev HEAD". Note: all changes have to be committed, also see nixpkgs-review usage
  • Tested basic functionality of all binary files (usually in ./result/bin/)
  • 24.05 Release Notes (or backporting 23.05 and 23.11 Release notes)
    • (Package updates) Added a release notes entry if the change is major or breaking
    • (Module updates) Added a release notes entry if the change is significant
    • (Module addition) Added a release notes entry if adding a new NixOS module
  • Fits CONTRIBUTING.md.

Add a 👍 reaction to pull requests you find important.

@ofborg ofborg bot added the 6.topic: cross-compilation Building packages on a different sort platform than than they will be run on label Apr 19, 2024
@AlexandreTunstall
Copy link
Contributor

AlexandreTunstall commented Apr 19, 2024

I like the change to use ghc-settings-edit, but would you mind adding a comment inside the LHS file and/or the meta description to briefly explain what the script is used for?

As mentioned in this comment of the original PR, the settings file apparently still references the build platform's LLVM.
Have you had a chance to look into this issue?
I assume it just needs an extra rule to overwrite the LLVM field.

I'll test pkgsCross.riscv64 and report back in a few days.

@sternenseemann
Copy link
Member Author

but would you mind adding a comment inside the LHS file and/or the meta description to briefly explain what the script is used for?

Yes, I'll do that.

still references the the build platform's LLVM

Forgot about that, I'll look into that. This is basically the case the old asserts guarded against?

assert targetCC == pkgsHostTarget.targetPackages.stdenv.cc;
assert buildTargetLlvmPackages.llvm == llvmPackages.llvm;

@AlexandreTunstall
Copy link
Contributor

This is basically the case the old asserts guarded against?

I think so.

@AlexandreTunstall
Copy link
Contributor

I have successfully used this PR's branch to boot a native compiler and build nix-output-monitor and ShellCheck on RISC-V.

The GHC 9.4.8 cross-build still needs to be unregisterised, but through the rebuild I was able to obtain a fully functional native RISC-V compiler, so there has been no regression on that front.

Since a cross-compiled 9.4.8 can be used to boot a native 9.6.5, please feel free to update the cross sanity test to build 9.4.8 instead of 8.10.7.
I can't remember why my past testing led me to believe that only 8.10.7 was usable as a boot compiler, but it no longer seems to be an issue.

@AlexandreTunstall
Copy link
Contributor

This error is probably what led me to believe that only 8.10 and 9.0 were usable as boot compilers:

ghc.mk:141: *** The make build system requires a boot compiler older than ghc-9.2. Your boot compiler is too new and cannot be used to build ghc-9.4 with make. Either boot with ghc 9.0.2 or build with hadrian. See https://www.haskell.org/ghc/blog/20220805-make-to-hadrian.html for advice on transitioning to hadrian.. Stop.

At the time, Nixpkgs had not yet switched to 9.6.

@sternenseemann
Copy link
Member Author

Added some commentary to the ghc-settings-edit.lhs file.

@sternenseemann
Copy link
Member Author

sternenseemann commented Jun 3, 2024

Follow-up PRs:

@sternenseemann
Copy link
Member Author

@AlexandreTunstall Does enableDocs imply enableHaddock? Is that why you made the condition for the former more strict?

@sternenseemann
Copy link
Member Author

/nix/store/6pmlfcq95bswq8vwb64wzasp9pk8pnm2-ghc-9.8.2
/nix/store/fqmmy8qahfh7yhpm9v4xfddfw56w8y2a-ghc-9.8.2-doc
/nix/store/zg2lzsx6ni1s6lm0wvznf2bl1lasii9v-ghc-aarch64-unknown-linux-gnu-8.10.7-doc
/nix/store/znjbb57b6jfq1kqcg67rcw4wvv3yszn9-ghc-aarch64-unknown-linux-gnu-8.10.7
/nix/store/7cmg5rfmnr07mms8fami2qkwbbfpswpv-aarch64-unknown-linux-gnu-ghc-9.6.6-doc
/nix/store/cam5dzipi1yq3y9nfx64mwr8vm6nhlkk-aarch64-unknown-linux-gnu-ghc-9.6.6
/nix/store/8pg837wpi3k6x82i715bkj6hg072ngv8-ghc-aarch64-unknown-linux-gnu-9.4.8-doc
/nix/store/wg0mppma2z6spmj6np32kzk2xh1qlrh9-ghc-aarch64-unknown-linux-gnu-9.4.8

Successfully compile.

sternenseemann and others added 2 commits September 7, 2024 14:05
GHC's build system assumes that the C compiler, tools etc. discovered
during configure can also be used at runtime. This means that the CC,
LD, AR etc. variables given at runtime are used to populate the settings
file which GHC uses to lookup the tools it needs.

The implicit assumption of this mechanism is that the build and runtime
environment of GHC are similar enough and PATH is used to find the
tools. I. e. if we set CC=clang, we wouldn't need to worry about this as
much. We, however, pass absolute paths which is useful since it allows
GHC to work outside of stdenv (as long as e. g. no FFI is involved).

Even so, until now, we didn't really have any problems stemming from
this, as we used pkgsBuildTarget to get everything we need. The
compiler we'd want to execute would in principle need to come
from pkgsHostTarget.

1. For native compilers, all package sets are the same since
   build == host == target.
2. For cross compilers build == host, so pkgsBuildTarget
   is practically the same as pkgsHostTarget.

When cross-compiling a native compiler, build != host, so we need to
actually ensure that GHC uses different tools at runtime compared to
bootstrapping. There is currently no intended way to achieve this, so we
use a custom tool to edit the settings file. An alternative would be to
patch the build system, but this would be difficult to maintain. We
could go down this route if there's interest from upstream to provide a
proper way to specify the runtime tools.

Co-authored-by: sternenseemann <[email protected]>
@sternenseemann
Copy link
Member Author

  • Successfully (natively) compiled test programs with GHC 8.10.7, 9.4.8 cross compiled from x86_64-linux on aarch64-linux.
  • “Ordinary” Cross compilation from x86_64 to aarch64-linux with 9.6.6 still works.
  • Native 9.8.2 compiler still works.

@sternenseemann sternenseemann marked this pull request as ready for review September 7, 2024 13:18
@AlexandreTunstall
Copy link
Contributor

Does enableDocs imply enableHaddock? Is that why you made the condition for the former more strict?

It's been a while since I wrote that change, so I can't remember.
One would have to try enableDocs = true; enableHaddock = false and see, because I can't find anything in the GHC documentation that suggests that one implies the other.

@@ -146,6 +146,8 @@ let
pkgs.pkgsCross.mips64el-linux-gnuabi64.stdenv
pkgs.pkgsCross.mips64el-linux-gnuabin32.stdenv
pkgs.pkgsCross.mingwW64.stdenv
# Unlike later versions, cross-compiled 8.10.7 can reliably bootstrap a native build
pkgs.pkgsCross.riscv64.haskell.compiler.integer-simple.ghc8107
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we update this to 9.4.8 now that we know it works on aarch64 and riscv64?

(I originally used 8.10.7 because an unrelated problem prevented me from bootstrapping with a newer compiler.)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe an idea, I think we can expand the test list a bit (in release-haskell.nix), but should keep it to the essential stuff in the test.

The nice thing about 8.10.7 is of course that it can be used to start a bootstrap chain of all compilers in nixpkgs.

Also, we should be able to use gmp now if gmp can be cross compiled to riscv64.

@AlexandreTunstall
Copy link
Contributor

On the latest version of this PR, pkgsCross.riscv64.haskell.compiler.native-bignum.ghc948 builds, runs natively on my RV64GC_Zba_Zbb system, and outputs working RV64GC binaries.

@sternenseemann
Copy link
Member Author

One would have to try enableDocs = true; enableHaddock = false and see, because I can't find anything in the GHC documentation that suggests that one implies the other.

I've confirmed that it only influences the manual build which isn't problematic when cross-compiling GHC. We only need/should disable it if it is a hassle to build sphinx for the host platform (e.g. as is the case with musl).

AlexandreTunstall and others added 10 commits September 8, 2024 22:18
Propagating the supported platforms of the boot compiler doesn't make
much sense when unregistered cross-compilation is possible.
This is to ensure that Haskell users on platforms that lack official
bindists still have a convenient means of getting GHC running natively.

In my admittedly somewhat limited testing on RISC-V, GHC 8.10.7 is able
to bootstrap native builds for 9.2.8 and 9.4.5. GHC 9.2.8 and 9.4.5 are
unable to bootstrap themselves and 9.6.2 when cross-compiled.

If you're looking at this commit to see whether you can safely upgrade
the compiler used here to remove 8.10, please try cross-compiling 9.0 or
later and then booting a native GHC with it.
Hadrian started installing unlit with a targetPrefix (if applicable)
which wasn't the case with make before. Unfortunately, the logic to
generate the settings file wasn't updated, so GHC 9.6.* cross compilers
expect to find an unlit binary without a target prefix.

Upstream issue: https://gitlab.haskell.org/ghc/ghc/-/issues/23317
The build platform doesn't matter for checking which stage is our final
stage! Stage2 means host and target are sufficiently similar, Stage1
means host and target may differ.
Note that the clang command should be adapted in the future as done for
CLANG in NixOS#338782.
@sternenseemann sternenseemann merged commit 2dae227 into NixOS:haskell-updates Sep 8, 2024
22 of 26 checks passed
@sternenseemann sternenseemann deleted the ghc-cross branch September 8, 2024 21:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants