Bootstrapping GHC for a new architecture
Preconditions
This document provides guidance on how to bootstrap the Glasgow Haskell Compiler (GHC) for a new architecture in Debian. It is assumed that the reader has a basic understanding of cross-compilation and Debian packaging, and that the build-essential package is ready to install on the target architecture with necessary dependencies. It is also assumed that cross-compilation toolchains, i.e. crossbuild-essential-<arch>, are available on the building host. This document reflects the state of writing when ghc version 9.6 is the current version in Debian Sid.
Overview
Glasgow Haskell Compiler (GHC) is a state-of-the-art, open source compiler and interactive environment for the functional programming language Haskell. GHC is written in Haskell and requires an existing GHC installation to build from source. Therefore, bootstrapping GHC for a new architecture involves building a cross-compiler version of GHC on a building host, and then using that cross-compiler to build a native GHC running on the target architecture.
Originally, ghc used autotools and automake as its build system. However, unlike gcc, the familar build, host, and target triplet options are modified. ghc requires the build triplet to specify the architecture of the building host, which is the same as the build triplet in autotools. However, the host triplet and the target triplet are used to specify the architecture of the target system, regardless of whether ghc is being built as a cross-compiler or a native compiler running on the target system. Ghc build system requires the host triplet and the target triplet to be the same in any conditions. Ghc introduced a staged build conecpt, where, for simplicity, stage0 means the existing GHC installation on the building host, stage1 means the cross-compiler GHC built by stage0, and stage2 means the native GHC built by stage1 running on the target system. While building, the production of each stage is stored in in the directory named stage<n>, where <n> is the stage number, so that the stage2 compiler can be found in the stage1 directory after building, since stage1 builds stage2.
In 2022, ghc migrated its build system from autotools to Hadrian, a new build system written in Haskell and announced to discontinue support for autotools since ghc 9.6 and ghc 9.4 would be the last version which uses autotools. In hadrian, the above concepts of build, host, target triplets and staged build are preserved, but the actual build process is handled by hadrian program instead of makefiles, so the way to specify options and invoke the build process becomes different. Although the documentation of hadrian still claims that the concept of cross-compiling remains unchanged, to the author’s best knowledge at the time of writing (November 2025) and according to the author’s repeated experiment, hadrian cannot cross compile a native ghc and can only build a cross-compiling one. Therefore, to bootstrap ghc for a new architecture, one should use autotools-based ghc versions up to 9.4 to finish the bootstrapping process to produce a native ghc running on the target architecture. After that, use the native ghc on the target architecture to build hadrian and its necessary dependencies, and then use hadrian to build ghc versions 9.6 and later. If further ghc versions cannot be built by ghc 9.4, intermediate ghc versions between 9.6 and the target ghc version should be built alike, which is not necessary as of this writing.
Based on the above understanding, the base of our bootstrapping process should be ghc 9.4 built with autotools, as a result, the debian packaged version 9.4.6-1~exp1 should be our best choice, since it is the latest ghc version in Debian which still uses autotools as its build system.
If the makefile build system is used to build ghc 9.4, the bootstrapping process requires ghc version lower than 9.2. Ghc 9.0.2-4 in bookworm can then be used.
Process of building ghc 9.4 for the target architecture
- Download the source package of ghc 9.4.6-1~exp1 on the building host:
dget -x -u "https://snapshot.debian.org/archive/debian/20230812T090501Z/pool/main/g/ghc/ghc_9.4.6-1~exp1.dsc" cd ghc-9.4.6
- Make the ghc build system aware of the new architecture by adding the necessary entries in the config files:
m4/fptools_set_haskell_platform_vars.m4
m4/ghc_convert_cpu.m4
libraries/ghc-boot/GHC/Platform/ArchOS.hs
Then, use dpkg-source --commit to create a patch file for the changes.
Import a necessary patch to fix the detection of cross-compilation toolchains.
wcurl -O "debian/patches/configure-Use-AC_PATH_TOOL-to-detect-tools.patch" \ "https://gitlab.haskell.org/ghc/ghc/commit/ca4d7241c6d02efa02350f010b3481ed2338e600.patch" && \ echo "configure-Use-AC_PATH_TOOL-to-detect-tools.patch" >> debian/patches/series
Adjust the build dependencies in debian/control:
diff -Nru ghc-9.4.6/debian/control ghc-9.4.6/debian/control --- ghc-9.4.6/debian/control 2023-08-11 15:55:54.000000000 +0000 +++ ghc-9.4.6/debian/control 2025-11-22 01:40:00.000000000 +0000 @@ -9,11 +9,12 @@ Rules-Requires-Root: no Build-Depends: debhelper-compat (= 12), - haskell-devscripts-minimal <!cross>, + haskell-devscripts-minimal:native, devscripts, grep-dctrl, pkg-config, - ghc:native (>= 8.6), + ghc:native (>= 8.6), ghc:native (<< 9.2~), + binutils-gold:native, libgmp-dev, llvm-14 [arm64 armel armhf], libffi-dev,We add ghc:native (<< 9.2~) to ensure that ghc lower than 9.2 is used to build ghc 9.4. We also add binutils-gold:native as it is needed by the first round of building ghc. We add :native suffix to haskell-devscripts-minimal to ensure the existence of dh_haskell_provides.
- Minor bug fixes to the debian/rules to prevent it from handling the manpages which are not generated during cross-compilation:
diff -Nru ghc-9.4.6/debian/rules ghc-9.4.6/debian/rules --- ghc-9.4.6/debian/rules 2023-08-11 16:52:02.000000000 +0000 +++ ghc-9.4.6/debian/rules 2025-11-22 01:40:00.000000000 +0000 @@ -212,6 +212,7 @@ fi endif +ifeq (NO,$(BUILD_CROSS)) # manpages echo ".so man1/ghc.1" > debian/tmp/usr/share/man/man1/ghc-$(ProjectVersion).1 if test -e debian/tmp/usr/bin/ghci-$(ProjectVersion); then \ @@ -224,6 +225,7 @@ cp debian/haddock.man debian/tmp/usr/share/man/man1/haddock.1 find debian/tmp/usr/share/man $(FILES) >> debian/ghc.install +endif # #################### # Now all the files are sorted, create the package filelists Use dch to add an entry in debian/changelog to document the changes made and append a new version suffix, e.g., +<target-arch>+1.
Use sbuild to build the cross-compiler ghc for the target architecture:
sbuild \ --apt-update \ --no-apt-upgrade \ --no-apt-distupgrade \ --no-run-lintian \ --host=<target-arch> \ --build=<build-arch> \ --no-arch-all \ --build-dep-resolver=apt \ --chroot-mode=unshare \ --chroot=/path/to/some.tar.zst \ --extra-repository="deb http://deb.debian.org/debian bookworm main" \ --profiles=nodoc,nocheck,cross \ --chroot-setup-commands='echo "deb http://deb.debian.org/debian bookworm main contrib" > /etc/apt/sources.list.d/1.list && apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y ghc=9.0.2-4 && rm -f /etc/apt/sources.list.d/1.list' \ --source --force-orig-source ./ghc_9.4.6-1\~exp1+<target-arch>+1.dsc
It is assumed that necessary apt configurations and cross toolchains are configured in the rootfs tarball /path/to/some.tar.zst and other options, if required, should also be appended to the sbuild command-line, such that it can be used to cross-compile ordinary packages for the target architecture on the building architecture.
Building hadrian and the target ghc version on the target architecture
After building ghc 9.4 for the target architecture, it can be included in a temporary repository to be installed on the target system. Then use it to build hadrian and its necessary dependencies. As of this writing, the necessary dependencies to build hadrian include:
haskell-colour
haskell-prettyprinter
haskell-transformers-compat
haskell-terminal-size
haskell-lexer
haskell-unliftio-core
haskell-void
haskell-hostname
haskell-old-locale
haskell-xml
haskell-extensible-exceptions
haskell-code-page
haskell-ghc-paths
haskell-regex-base
haskell-primitive
haskell-unliftio
The above packages can be built only with the native ghc 9.4 on the target, but the build dependencies of these packages require ghc 9.6 or later, so the possible way is to build the version of these packages in bookworm with ghc 9.4 or directly modify their debian/control files to lower the required ghc.
With the above dependencies built, the following packages can be then built:
haskell-ansi-terminal-types
haskell-base-compat
haskell-base-orphans
haskell-boring
haskell-doctest
haskell-file-embed
haskell-filepattern
haskell-hspec-expectations
haskell-mmorph
haskell-quickcheck-io
haskell-regex-posix
haskell-tf-random
haskell-th-abstraction
haskell-vector
haskell-ansi-terminal
haskell-constraints
haskell-transformers-base
haskell-generic-deriving
haskell-hspec-core
haskell-prettyprinter-ansi-terminal
haskell-hspec
haskell-monad-control
haskell-lifted-base
haskell-optparse-applicative
haskell-prettyprinter-compat-ansi-wl-pprint
haskell-ansi-wl-pprint
haskell-tasty
haskell-tasty-expected-failure
haskell-tasty-hunit
haskell-tasty-quickcheck
haskell-test-framework
haskell-test-framework-hunit
haskell-wl-pprint-annotated
haskell-async
haskell-concurrent-output
haskell-lifted-async
haskell-hspec-discover
haskell-distributive
haskell-resourcet
haskell-safe-exceptions
haskell-th-compat
haskell-barbies
haskell-network-uri
haskell-http
haskell-js-flot
happy
haskell-pretty-show
haskell-hedgehog
haskell-tasty-hedgehog
haskell-nothunks
haskell-unordered-containers
haskell-shake
haskell-hadrian
It should be noted that the above list may change over time as hadrian evolves.
Finally, the ghc package of the target version can be built with hadrian on the target architecture.
Rebuild ghc on the target architecture
After building the target ghc version, it is required to discard all the above dependencies, since the above dependencies are built with ghc 9.4 and there might be dependency on ghc 9.4 libraries in the built ghc package, which prevents them from being installed together with the target ghc version. The above process should be repeated with the target ghc version to rebuild all the above dependencies and finally rebuild the target ghc version again to ensure that there is no dependency on ghc 9.4 libraries.
