Add support for several toolchains
Currently a given GHC build can only produce and load code for a single platform. We are working on changing this so that:
- plugins could be loaded in cross-compilers (host /= target) (#14335)
- the target could be selected by the user at runtime (#11470). It would also allow building plugins for cross-compilers.
Both require support for several toolchains (linker, C compiler, assembler) in GHC.
(It might look weird to need this for plugins: the reason is that GHC needs the linker to produce temporary .so
libraries that are then loaded with the system loader (dlopen
), see GHC.Linker.Loader.dynLoadObjs
.)
This ticket is to track adding multi-toolchain support. Here are a few tasks to perform:
-
Enhance toolchain program interfaces in the compiler. E.g. currently to link a dynamic library we use GHC.Linker.Dynamic.linkDynLib
which takes many of its arguments directly from DynFlags (you guessed it). SeeGHC.Linker.Loader.dynLoadObjs
for an example of howDynFlags
are modified to take into account the currentLoaderState
before callinglinkDynLib
. We should never modifyDynFlags
except for command-line flags andOPTIONS_GHC
pragmas (#17957). We should have abstract documented interfaces instead. -
Split target settings from other global settings -
Split settings from DynFlags -
Remove use of CPP in GHC.Linker.Dynamic.libmLinkOpts
: the equivalent ofHAVE_LIBM
should be retrieved via platform constants -
Figure out a way to configure the toolchains. On this topic, Ben recently wrote:
I'm starting to wonder whether we should introduce some sort of implicit or explicit caching of the toolchain state. Probing the toolchain on every GHC execution is fairly expensive on some platforms (e.g. Windows). Moreover, we currently push most of the expensive checks off to
autoconf
to be saved in thesettings
file; this of course breaks when the toolchain shifts under our feet, offering the user no way forward other than reinstalling GHC.Finally, the fact that GHC may soon be a runtime-retargetable recompiler (good work @hsyl20 and @Ericson2314!) may finally force our hand as toolchains may come and go more often. Perhaps we could split out the current
configure
checks into aghc-probe-toolchain
script which would ship with the bindist and be automatically run during configure. This would produce a toolchain configuration file (perhaps in$INSTALL_PREFIX/lib/ghc-$TRIPLE/toolchain-settings
). The user could manually rerun the script if the toolchain changes or when they install a new cross-compilation toolchain.This is similar to an idea that @Ericson2314 and I discussed a few months ago, with the primary difference being that he suggested that the file be a documented interface of GHC. I am very reluctant to expose this interface as the configuration space is quite large and it's very easy to stumble into subtly broken configurations. My suggestion is therefore that the file rather be a black box, only generated by the script.
I'm not sure $TRIPLE
is enough because we may want to have two or more builds for the same platform but with different toolchains (e.g. registerised and unregisterised, or gcc vs clang). Anyway, the ability to create/load different toolchain settings is needed and we can adjust this later.