Support changing cross compiler target at runtime
Original issue:
Relevant mailing list thread: https://mail.haskell.org/pipermail/ghc-devs/2016-January/011064.html
At the moment, GHC's cross-compiling support requires you to build a cross-compiler for every target platform from scratch. (https://ghc.haskell.org/trac/ghc/wiki/CrossCompilation) There are two reasons for this:
- GHC uses a configure script to interrogate the GCC toolchain about the vagaries of cross-compilation, some parameters of which get baked into various build system scripts and header files and such. Some of this information wends its way into the final built GHC executable.
- GHC needs to build the boot libraries, using the stage 1 compiler, targeting the cross compiler.
It would be very useful to move this configuration from configure time to run time, so that a user can use GHC as a cross-compiler without having to recompile GHC. That is, we would like to (1) ensure that any information from the configure script can alternately be supplemented at runtime, (2) that users can cross-compile the boot libraries on-demand (since GHC won't ship with the ARM versions of the boot libraries), and (3) rearchitect GHC internally so that it handles knows to keep separate the interface files/package database for various cross compilation targets.
Such a change will make cross-compiling more convenient (the iOS cross-compiler currently requires GHC to be built twice, once for ARM and once for the simulator!) and will also pave the way for supporting Template Haskell and compiler plugins in the cross-compiler, since a GHC that knows how to deal with both the target and host platforms can simply ensure that it only loads code built for the host platform (a user can then, if necessary, build code twice, once for the host for Template Haskell, and once for the target).
Unclear points of design:
- How should GHC get the information about the GCC cross-compiler toolchain (which currently is gotten by
configure
?) Preferably, not by running aconfigure
script every time you invoke it. What is this information anyway? - How should GHC rebuild the boot libraries? Maybe
cabal-install
can simply handle this for you.
Note: please update the top of this ticket as the design becomes clearer.
Related tickets: #11378 (an alternate way to implement this without implementing multitarget support. If this ticket is solved, that ticket is moot.)
3 years later I (@Ericson2314) am getting around to this. The process is simple: look through GHC and rip out any target hard-coding one sees. Big points:
-
Config.hs
: moved a bunch of stuff tosettings
(TODO link MR) -
ghcplatform.h
andghc_boot_platform.h
rip out TARGET defs of each. Then the second can go away entirely because it's fine to use theghcplatform.h
from base built with the bootstrap compiler. -
Primops. This is the hardest to disintangle: the genprimops steps let everything just get that much more baked. !959 (closed) tried to keep things as is and add some
platform
parameter. !1100 (closed) takes the opposite tack of trying to make the primops less platform-specific. As https://gitlab.haskell.org/ghc/ghc/wikis/commentary/prim-ops there is some interest in usingforeign import prim
across the board instead of genprimops anyways.
What seems likely is all conditionally-available primops are removed, and then something else is done (with less performance penalty) for the word-size-dependence. This would be in conjunction with #11953 (closed).
Here's an update on an exact plan:
-
First primops moved out !1330 (closed) -- already done -
Clean up primops list (!1864)-- Can put off for later -
Clean up giant pattern match to be total, easier with export-only primop out of the way (!1883 (closed)) -
Real Int64
andInt32
types (!1102 (closed)), no moreMachDeps.h
needed in compiler proper (except for bootstrap RTS's header describing the host platform for e.g. parsercutils.c
, which is harmless, and available for any Haskell package). -
Generalize settings
to allow multiple target-specific toolchains (#23682) -
Target-specific package databases -
!1690 (merged) (and other dependent PRs) clean up other silly includes in compiler. -
Refactor configure scripts (#17191 (closed)) to prevent regressions where compiler snoops RTS headers again for no good reason. -
Introduction of non-linear "stages" in Hadrian? -
Sort out distribution story: How do users get the RTS, base
,ghc-bignum
, etc. for a new target? -
Stretch goal: TemplateHaskell
The key observation wrt the primops issue is we can be a bit less ambitious. Teaching the NCG about emulating 64 numbers on 32-bit arches is probably not so bad, even if it sets a bad precedent for "fake" portability, and that is the only real obstacle for getting rid of that last dodgy #include "MachDeps.h"
in the primops.