Support changing cross compiler target at runtime
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 a
configurescript every time you invoke it. What is this information anyway?
- How should GHC rebuild the boot libraries? Maybe
cabal-installcan 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 to
settings(TODO link MR)
ghc_boot_platform.hrip out TARGET defs of each. Then the second can go away entirely because it's fine to use the
ghcplatform.hfrom 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
platformparameter. !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 using
foreign import primacross 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 of for later
- Clean up giant pattern match to be total, easier with export-only primop out of the way (!1883 (closed))
Real Int64 and Int32 types (!1102 (closed)), no more
MachDeps.hneeded in compiler proper (except for bootstrap RTS's header describing the host platform for e.g. parser
cutils.c, which is harmless, and available for any Haskell package).
- !1690 (merged) (and other dependent PRs) clean up other silly includes in compiler. We are multi-target!
- Refactor configure scripts (#17191) to prevent regressions where compiler snoops RTS headers again for no good reason.
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.