From 5897adf6b92694e46a538ec8c38d0a1129aec673 Mon Sep 17 00:00:00 2001
From: Cheng Shao <terrorjack@type.dance>
Date: Thu, 5 Dec 2024 20:21:59 +0000
Subject: [PATCH] ci: multi-project pipeline for wasm

(cherry picked from commit 3655c3fd295cde9a78c15aa0ac002cf94bb813be)
---
 .gitlab-ci.yml                | 169 +++++------------
 .gitlab/ci.sh                 |  44 ++++-
 .gitlab/generate-ci/gen_ci.hs |  32 +++-
 .gitlab/jobs.yaml             | 332 ++++++++++++++++++++++++++++++----
 4 files changed, 408 insertions(+), 169 deletions(-)

diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index fd1e88ec3b8..7e176e1c810 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -2,7 +2,9 @@ variables:
   GIT_SSL_NO_VERIFY: "1"
 
   # Commit of ghc/ci-images repository from which to pull Docker images
-  DOCKER_REV: efc1ab81236eb37e20cb287ec77aebb6c6341098
+  DOCKER_REV: 94df7d589f0ded990826bc7a4d7f5a40d6055a4f
+
+  GHC_WASM_META_BRANCH: master
 
   # Sequential version number of all cached things.
   # Bump to invalidate GitLab CI cache.
@@ -41,7 +43,7 @@ variables:
   #     -1            37.72s  142 MB
   #     -0            34.40s  156 MB
   #
-  XZ_OPT: "-1"
+  XZ_OPT: "-9e"
 default:
   interruptible: true
 
@@ -97,6 +99,7 @@ workflow:
     - if: $CI_PROJECT_ID == "1" && $CI_COMMIT_BRANCH == "master"
     - if: $CI_PROJECT_ID == "1" && $CI_COMMIT_BRANCH =~ /ghc-[0-9]+\.[0-9]+/
     - if: '$CI_PIPELINE_SOURCE == "web"'
+    - if: $CI_PIPELINE_SOURCE == "pipeline"
 
 # which versions of GHC to allow bootstrap with
 .bootstrap_matrix : &bootstrap_matrix
@@ -228,30 +231,6 @@ ghc-linters:
     - if: $CI_MERGE_REQUEST_ID
     - *drafts-can-fail-lint
 
-# Run mypy Python typechecker on linter scripts.
-lint-linters:
-  image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV"
-  extends: .lint
-  script:
-    - mypy testsuite/tests/linters/regex-linters/*.py
-  dependencies: []
-
-# Check that .T files all parse by listing broken tests.
-lint-testsuite:
-  image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb9:$DOCKER_REV"
-  extends: .lint
-  script:
-    - make -Ctestsuite list_broken TEST_HC=$GHC
-  dependencies: []
-
-# Run mypy Python typechecker on testsuite driver
-typecheck-testsuite:
-  image: "registry.gitlab.haskell.org/ghc/ci-images/linters:$DOCKER_REV"
-  extends: .lint
-  script:
-    - mypy testsuite/driver/runtests.py
-  dependencies: []
-
 # We allow the submodule checker to fail when run on merge requests (to
 # accommodate, e.g., haddock changes not yet upstream) but not on `master` or
 # Marge jobs.
@@ -288,67 +267,6 @@ lint-author:
     - if: $CI_MERGE_REQUEST_ID
     - *drafts-can-fail-lint
 
-lint-ci-config:
-  image: nixos/nix:2.25.2
-  extends: .lint
-  # We don't need history/submodules in this job
-  variables:
-    GIT_DEPTH: 1
-    GIT_SUBMODULE_STRATEGY: none
-  before_script:
-    - echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf
-    # Note [Nix-in-Docker]
-    # ~~~~~~~~~~~~~~~~~~~~
-    # The nixos/nix default config is max-jobs=1 and cores=$(logical
-    # cores num) which doesn't play nice with our $CPUS convention. We
-    # fix it before invoking any nix build to avoid oversubscribing
-    # while allowing a reasonable degree of parallelism.
-    # FIXME: Disabling build-users-group=nixbld is a workaround for a Nix-in-Docker issue. See
-    # https://gitlab.haskell.org/ghc/head.hackage/-/issues/38#note_560487 for
-    # discussion.
-    - echo "cores = $CPUS" >> /etc/nix/nix.conf
-    - echo "max-jobs = $CPUS" >> /etc/nix/nix.conf
-    - nix run nixpkgs#gnused -- -i -e 's/ nixbld//' /etc/nix/nix.conf
-  script:
-    - nix run .gitlab/generate-ci#generate-jobs
-    # 1 if .gitlab/generate_jobs changed the output of the generated config
-    - nix shell nixpkgs#git -c git diff --exit-code
-    # And run this to generate the .gitlab/jobs-metadata.json
-    - nix run .gitlab/generate-ci#generate-job-metadata
-  artifacts:
-    when: always
-    paths:
-      - .gitlab/jobs-metadata.json
-      - .gitlab/jobs.yaml
-  dependencies: []
-
-lint-submods:
-  extends: .lint-submods
-  # Allow failure on merge requests since any necessary submodule patches may
-  # not be upstreamed yet.
-  rules:
-    - if: '$CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/'
-      allow_failure: false
-    # Don't run on nightly because the program needs a base commit to check.
-    - if: $NIGHTLY
-      when: never
-    - allow_failure: true
-
-lint-submods-branch:
-  extends: .lint-submods
-  variables:
-    BUILD_FLAVOUR: default
-  script:
-    - .gitlab/ci.sh configure
-    - .gitlab/ci.sh run_hadrian stage0:exe:lint-submodule-refs
-    - "echo Linting submodule changes between $CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA"
-    - git submodule foreach git remote update
-    - _build/stageBoot/bin/lint-submodule-refs . $(git rev-list $CI_COMMIT_BEFORE_SHA..$CI_COMMIT_SHA)
-  rules:
-    - if: '$CI_COMMIT_BRANCH == "master"'
-    - if: '$CI_COMMIT_BRANCH =~ /ghc-[0.9]+\.[0-9]+/'
-    - *drafts-can-fail-lint
-
 ############################################################
 # GHC source code linting
 ############################################################
@@ -393,10 +311,8 @@ lint-submods-branch:
 hadrian-ghc-in-ghci:
   stage: quick-build
   needs:
-    - job: lint-linters
-    - job: lint-submods
-      optional: true
-  image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV"
+    - only-wasm
+  image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb12:$DOCKER_REV"
   before_script:
     # workaround for docker permissions
     - sudo chown ghc:ghc -R .
@@ -476,21 +392,6 @@ hadrian-multi:
   rules:
     - *full-ci
 
-############################################################
-# stack-hadrian-build
-############################################################
-
-# Verify that Hadrian builds with stack. Note that we don't actually perform a
-# build of GHC itself; we merely test that the Hadrian executable builds and
-# works (by invoking `hadrian --version`).
-stack-hadrian-build:
-  extends: hadrian-ghc-in-ghci
-  stage: quick-build
-  script:
-    - .gitlab/ci.sh setup
-    - .gitlab/ci.sh configure
-    - hadrian/build-stack --version
-
 ####################################
 # Testing reinstallable ghc codepath
 ####################################
@@ -1089,27 +990,6 @@ pages:
 # Generation of GHCUp metadata
 #############################################################
 
-
-project-version:
-  stage: packaging
-  image: "registry.gitlab.haskell.org/ghc/ci-images/x86_64-linux-deb10:$DOCKER_REV"
-  tags:
-    - x86_64-linux
-  variables:
-    BUILD_FLAVOUR: default
-  script:
-    # Calculate the project version
-    - sudo chown ghc:ghc -R .
-    - .gitlab/ci.sh setup
-    - .gitlab/ci.sh configure
-    - echo "ProjectVersion=$(cat VERSION)" > version.sh
-
-  needs: []
-  dependencies: []
-  artifacts:
-    paths:
-      - version.sh
-
 .ghcup-metadata:
   stage: deploy
   image: nixos/nix:2.25.2
@@ -1175,7 +1055,6 @@ ghcup-metadata-nightly:
       artifacts: false
     - job: source-tarball
       artifacts: false
-    - job: project-version
   script:
     - nix shell -f .gitlab/rel_eng -c ghcup-metadata --metadata ghcup-0.0.7.yaml --date="$(date -d $CI_PIPELINE_CREATED_AT +%Y-%m-%d)" --pipeline-id="$CI_PIPELINE_ID" --version="$ProjectVersion" > "metadata_test.yaml"
   rules:
@@ -1260,3 +1139,37 @@ ghcup-metadata-testing-release:
   rules:
     - if: '$RELEASE_JOB == "yes"'
   when: manual
+
+only-wasm:
+  stage: quick-build
+  image: nixos/nix:2.26.3
+  tags:
+    - x86_64-linux
+  needs: []
+  variables:
+    GIT_STRATEGY: none
+    KEEP_JOB_NAME: x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static
+  before_script:
+    - echo "experimental-features = nix-command flakes" >> /etc/nix/nix.conf
+    - echo "cores = $CPUS" >> /etc/nix/nix.conf
+    - echo "max-jobs = $CPUS" >> /etc/nix/nix.conf
+    - nix run nixpkgs#gnused -- -i -e 's/ nixbld//' /etc/nix/nix.conf
+  script:
+    - nix run nixpkgs#deno -- run --allow-env --allow-net https://gist.githubusercontent.com/TerrorJack/e0e886b87b9bfffb6c5fa5b3aeddcecc/raw/c927e9ef4a191d042087620965f6eb439749b9a0/cancel.js
+
+ghc-wasm-meta-ci:
+  stage: testing
+  needs:
+    - job: x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf
+      artifacts: false
+  variables:
+    UPSTREAM_GHC_FLAVOUR: "9.10"
+    UPSTREAM_GHC_PIPELINE_ID: $CI_PIPELINE_ID
+  rules:
+    - if: $UPSTREAM_WASI_SDK_PIPELINE_ID != null
+      variables:
+        UPSTREAM_WASI_SDK_PIPELINE_ID: $UPSTREAM_WASI_SDK_PIPELINE_ID
+    - when: always
+  trigger:
+    project: haskell-wasm/ghc-wasm-meta
+    branch: $GHC_WASM_META_BRANCH
diff --git a/.gitlab/ci.sh b/.gitlab/ci.sh
index fa858bac2a0..7fbf0909f27 100755
--- a/.gitlab/ci.sh
+++ b/.gitlab/ci.sh
@@ -227,7 +227,45 @@ function set_toolchain_paths() {
   export ALEX
 
   if [[ "${CROSS_TARGET:-}" == *"wasm"* ]]; then
-    source "/home/ghc/.ghc-wasm/env"
+    case "$(uname)" in
+      Linux)
+        if [[ ! -f /home/ghc/.ghc-wasm/.flag ]]; then
+          sudo sed -i -e 's/v3\.[0-9][0-9]/v3\.21/g' /etc/apk/repositories
+          sudo apk upgrade --available --update-cache
+
+          curl -f -L --retry 5 https://github.com/tweag/rust-alpine-mimalloc/archive/refs/heads/master.tar.gz | tar xz -C /tmp
+          mv /tmp/rust-alpine-mimalloc-master/mimalloc.diff /tmp
+          sudo /tmp/rust-alpine-mimalloc-master/build.sh
+
+          pushd "$(mktemp -d)"
+          curl -f -L --retry 5 https://gitlab.haskell.org/haskell-wasm/ghc-wasm-meta/-/archive/$GHC_WASM_META_BRANCH/ghc-wasm-meta-$GHC_WASM_META_BRANCH.tar.gz | tar xz --strip-components=1
+          PREFIX=/home/ghc/.ghc-wasm SKIP_GHC=1 ./setup.sh
+          popd
+
+          touch /home/ghc/.ghc-wasm/.flag
+        fi
+
+        export LD_PRELOAD=/usr/lib/libmimalloc.so
+        source /home/ghc/.ghc-wasm/env
+
+        if [[ "$(uname -m)" == "aarch64" ]]; then
+          export CONFIGURE_ARGS="--host=aarch64-alpine-linux --target=wasm32-wasi --with-intree-gmp --with-system-libffi"
+        fi
+        ;;
+
+      Darwin)
+        pushd "$(mktemp -d)"
+        curl -f -L --retry 5 https://gitlab.haskell.org/haskell-wasm/ghc-wasm-meta/-/archive/$GHC_WASM_META_BRANCH/ghc-wasm-meta-$GHC_WASM_META_BRANCH.tar.gz | tar xz --strip-components=1
+        PREFIX=/Users/$(whoami)/.ghc-wasm SKIP_GHC=1 ./setup.sh
+        popd
+
+        source /Users/$(whoami)/.ghc-wasm/env
+        ;;
+
+      *)
+        fail "wasm target only supported on linux/darwin hosts"
+        ;;
+    esac
   fi
 }
 
@@ -498,6 +536,10 @@ function build_hadrian() {
     export XZ_OPT="${XZ_OPT:-} -T$cores"
   fi
 
+  if [[ "$(uname -m)-$(uname)" != "aarch64-Linux" ]]; then
+    export WASM_SO_OPT="--debuginfo --low-memory-unused --strip-dwarf -O4"
+  fi
+
   if [[ -n "${REINSTALL_GHC:-}" ]]; then
     run_hadrian build-cabal -V
   else
diff --git a/.gitlab/generate-ci/gen_ci.hs b/.gitlab/generate-ci/gen_ci.hs
index ce03166575a..0f7749de61f 100644
--- a/.gitlab/generate-ci/gen_ci.hs
+++ b/.gitlab/generate-ci/gen_ci.hs
@@ -154,6 +154,7 @@ data BuildConfig
                 , threadSanitiser :: Bool
                 , noSplitSections :: Bool
                 , validateNonmovingGc :: Bool
+                , textWithSIMDUTF :: Bool
                 }
 
 -- Extra arguments to pass to ./configure due to the BuildConfig
@@ -176,7 +177,8 @@ mkJobFlavour BuildConfig{..} = Flavour buildFlavour opts
            [HostFullyStatic | hostFullyStatic] ++
            [ThreadSanitiser | threadSanitiser] ++
            [NoSplitSections | noSplitSections, buildFlavour == Release ] ++
-           [BootNonmovingGc | validateNonmovingGc ]
+           [BootNonmovingGc | validateNonmovingGc ] ++
+           [TextWithSIMDUTF | textWithSIMDUTF]
 
 data Flavour = Flavour BaseFlavour [FlavourTrans]
 
@@ -188,6 +190,7 @@ data FlavourTrans =
     | ThreadSanitiser
     | NoSplitSections
     | BootNonmovingGc
+    | TextWithSIMDUTF
 
 data BaseFlavour = Release | Validate | SlowValidate deriving Eq
 
@@ -215,6 +218,7 @@ vanilla = BuildConfig
   , threadSanitiser = False
   , noSplitSections = False
   , validateNonmovingGc = False
+  , textWithSIMDUTF = False
   }
 
 splitSectionsBroken :: BuildConfig -> BuildConfig
@@ -349,6 +353,7 @@ flavourString (Flavour base trans) = base_string base ++ concatMap (("+" ++) . f
     flavour_string ThreadSanitiser = "thread_sanitizer_cmm"
     flavour_string NoSplitSections = "no_split_sections"
     flavour_string BootNonmovingGc = "boot_nonmoving_gc"
+    flavour_string TextWithSIMDUTF = "text_simdutf"
 
 -- The path to the docker image (just for linux builders)
 dockerImage :: Arch -> Opsys -> Maybe String
@@ -1025,6 +1030,8 @@ job_groups =
          make_wasm_jobs wasm_build_config {bignumBackend = Native}
      , modifyValidateJobs manual $
          make_wasm_jobs wasm_build_config {unregisterised = True}
+     , wasm_darwin_jobs
+     , wasm_aarch64_jobs
      , onlyRule NonmovingGc (validateBuilds Amd64 (Linux Debian11) vanilla {validateNonmovingGc = True})
      , onlyRule IpeData (validateBuilds Amd64 (Linux Debian10) zstdIpe)
      ]
@@ -1049,10 +1056,26 @@ job_groups =
         . addVariable "HADRIAN_ARGS" "--docs=none") $
       validateBuilds Amd64 (Linux Debian12) tsan
 
+    wasm_aarch64_jobs =
+      modifyJobs
+        ( delVariable "BROKEN_TESTS"
+          . setVariable "HADRIAN_ARGS" "--docs=no-sphinx-pdfs --docs=no-sphinx-man --haddock-for-hackage"
+          . delVariable "INSTALL_CONFIGURE_ARGS"
+        )
+        $ validateBuilds AArch64 (Linux Alpine318) wasm_build_config
+
+    wasm_darwin_jobs =
+      modifyJobs
+        ( setVariable "HADRIAN_ARGS" "--docs=no-sphinx-pdfs --docs=no-sphinx-man --haddock-for-hackage"
+          . delVariable "INSTALL_CONFIGURE_ARGS"
+        )
+        $ validateBuilds AArch64 Darwin
+        $ wasm_build_config { hostFullyStatic = False }
+
     make_wasm_jobs cfg =
       modifyJobs
         ( delVariable "BROKEN_TESTS"
-            . setVariable "HADRIAN_ARGS" "--docs=none"
+            . setVariable "HADRIAN_ARGS" "--docs=no-sphinx-pdfs --docs=no-sphinx-man --haddock-for-hackage"
             . delVariable "INSTALL_CONFIGURE_ARGS"
         )
         $ validateBuilds Amd64 (Linux AlpineWasm) cfg
@@ -1062,6 +1085,7 @@ job_groups =
         {
           hostFullyStatic = True
           , buildFlavour     = Release -- TODO: This needs to be validate but wasm backend doesn't pass yet
+          , textWithSIMDUTF = True
         }
 
 
@@ -1087,10 +1111,10 @@ platform_mapping = Map.map go combined_result
                 , "x86_64-linux-fedora33-release"
                 , "x86_64-linux-deb11-cross_aarch64-linux-gnu-validate"
                 , "x86_64-windows-validate"
-                , "nightly-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static"
+                , "nightly-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+fully_static+text_simdutf"
                 , "nightly-x86_64-linux-deb11-validate"
                 , "nightly-x86_64-linux-deb12-validate"
-                , "x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static"
+                , "x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+fully_static+text_simdutf"
                 , "x86_64-linux-deb12-validate+thread_sanitizer_cmm"
                 , "nightly-aarch64-linux-deb10-validate"
                 , "nightly-x86_64-linux-alpine3_12-validate"
diff --git a/.gitlab/jobs.yaml b/.gitlab/jobs.yaml
index ec1f4cd2919..5f54d1b7986 100644
--- a/.gitlab/jobs.yaml
+++ b/.gitlab/jobs.yaml
@@ -1,5 +1,71 @@
 ### THIS IS A GENERATED FILE, DO NOT MODIFY DIRECTLY
 {
+  "aarch64-darwin-cross_wasm32-wasi-release+text_simdutf": {
+    "after_script": [
+      ".gitlab/ci.sh save_cache",
+      ".gitlab/ci.sh save_test_output",
+      ".gitlab/ci.sh clean",
+      "cat ci_timings"
+    ],
+    "allow_failure": false,
+    "artifacts": {
+      "expire_in": "2 weeks",
+      "paths": [
+        "ghc-aarch64-darwin-cross_wasm32-wasi-release+text_simdutf.tar.xz",
+        "junit.xml",
+        "unexpected-test-output.tar.gz"
+      ],
+      "reports": {
+        "junit": "junit.xml"
+      },
+      "when": "always"
+    },
+    "cache": {
+      "key": "aarch64-darwin-$CACHE_REV",
+      "paths": [
+        "cabal-cache",
+        "toolchain"
+      ]
+    },
+    "dependencies": [],
+    "image": null,
+    "needs": [
+      {
+        "artifacts": false,
+        "job": "hadrian-ghc-in-ghci"
+      }
+    ],
+    "rules": [
+      {
+        "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
+        "when": "on_success"
+      }
+    ],
+    "script": [
+      "find libraries -name config.sub -exec cp config.sub {} \\;",
+      ".gitlab/ci.sh setup",
+      ".gitlab/ci.sh configure",
+      ".gitlab/ci.sh build_hadrian",
+      ".gitlab/ci.sh test_hadrian"
+    ],
+    "stage": "full-build",
+    "tags": [
+      "aarch64-darwin"
+    ],
+    "variables": {
+      "BIGNUM_BACKEND": "gmp",
+      "BIN_DIST_NAME": "ghc-aarch64-darwin-cross_wasm32-wasi-release+text_simdutf",
+      "BUILD_FLAVOUR": "release+text_simdutf",
+      "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi --with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
+      "CROSS_TARGET": "wasm32-wasi",
+      "HADRIAN_ARGS": "--docs=no-sphinx-pdfs --docs=no-sphinx-man --haddock-for-hackage",
+      "LANG": "en_US.UTF-8",
+      "MACOSX_DEPLOYMENT_TARGET": "11.0",
+      "NIX_SYSTEM": "aarch64-darwin",
+      "RUNTEST_ARGS": "",
+      "TEST_ENV": "aarch64-darwin-cross_wasm32-wasi-release+text_simdutf"
+    }
+  },
   "aarch64-darwin-validate": {
     "after_script": [
       ".gitlab/ci.sh save_cache",
@@ -65,6 +131,69 @@
       "TEST_ENV": "aarch64-darwin-validate"
     }
   },
+  "aarch64-linux-alpine3_18-cross_wasm32-wasi-release+host_fully_static+text_simdutf": {
+    "after_script": [
+      ".gitlab/ci.sh save_cache",
+      ".gitlab/ci.sh save_test_output",
+      ".gitlab/ci.sh clean",
+      "cat ci_timings"
+    ],
+    "allow_failure": false,
+    "artifacts": {
+      "expire_in": "2 weeks",
+      "paths": [
+        "ghc-aarch64-linux-alpine3_18-cross_wasm32-wasi-release+host_fully_static+text_simdutf.tar.xz",
+        "junit.xml",
+        "unexpected-test-output.tar.gz"
+      ],
+      "reports": {
+        "junit": "junit.xml"
+      },
+      "when": "always"
+    },
+    "cache": {
+      "key": "aarch64-linux-alpine3_18-$CACHE_REV",
+      "paths": [
+        "cabal-cache",
+        "toolchain"
+      ]
+    },
+    "dependencies": [],
+    "image": "registry.gitlab.haskell.org/ghc/ci-images/aarch64-linux-alpine3_18:$DOCKER_REV",
+    "needs": [
+      {
+        "artifacts": false,
+        "job": "hadrian-ghc-in-ghci"
+      }
+    ],
+    "rules": [
+      {
+        "if": "((($CI_MERGE_REQUEST_LABELS =~ /.*full-ci.*/) || ($CI_MERGE_REQUEST_LABELS =~ /.*marge_bot_batch_merge_job.*/) || ($CI_COMMIT_BRANCH == \"master\") || ($CI_COMMIT_BRANCH =~ /ghc-[0-9]+\\.[0-9]+/))) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null)",
+        "when": "on_success"
+      }
+    ],
+    "script": [
+      "sudo chown ghc:ghc -R .",
+      ".gitlab/ci.sh setup",
+      ".gitlab/ci.sh configure",
+      ".gitlab/ci.sh build_hadrian",
+      ".gitlab/ci.sh test_hadrian"
+    ],
+    "stage": "full-build",
+    "tags": [
+      "aarch64-linux"
+    ],
+    "variables": {
+      "BIGNUM_BACKEND": "gmp",
+      "BIN_DIST_NAME": "ghc-aarch64-linux-alpine3_18-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
+      "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
+      "CONFIGURE_ARGS": "--disable-ld-override --with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
+      "CROSS_TARGET": "wasm32-wasi",
+      "HADRIAN_ARGS": "--docs=no-sphinx-pdfs --docs=no-sphinx-man --haddock-for-hackage",
+      "RUNTEST_ARGS": "",
+      "TEST_ENV": "aarch64-linux-alpine3_18-cross_wasm32-wasi-release+host_fully_static+text_simdutf"
+    }
+  },
   "aarch64-linux-deb10-validate": {
     "after_script": [
       ".gitlab/ci.sh save_cache",
@@ -248,6 +377,73 @@
       "TEST_ENV": "i386-linux-deb10-validate"
     }
   },
+  "nightly-aarch64-darwin-cross_wasm32-wasi-release+text_simdutf": {
+    "after_script": [
+      ".gitlab/ci.sh save_cache",
+      ".gitlab/ci.sh save_test_output",
+      ".gitlab/ci.sh clean",
+      "cat ci_timings"
+    ],
+    "allow_failure": false,
+    "artifacts": {
+      "expire_in": "8 weeks",
+      "paths": [
+        "ghc-aarch64-darwin-cross_wasm32-wasi-release+text_simdutf.tar.xz",
+        "junit.xml",
+        "unexpected-test-output.tar.gz"
+      ],
+      "reports": {
+        "junit": "junit.xml"
+      },
+      "when": "always"
+    },
+    "cache": {
+      "key": "aarch64-darwin-$CACHE_REV",
+      "paths": [
+        "cabal-cache",
+        "toolchain"
+      ]
+    },
+    "dependencies": [],
+    "image": null,
+    "needs": [
+      {
+        "artifacts": false,
+        "job": "hadrian-ghc-in-ghci"
+      }
+    ],
+    "rules": [
+      {
+        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY)",
+        "when": "on_success"
+      }
+    ],
+    "script": [
+      "find libraries -name config.sub -exec cp config.sub {} \\;",
+      ".gitlab/ci.sh setup",
+      ".gitlab/ci.sh configure",
+      ".gitlab/ci.sh build_hadrian",
+      ".gitlab/ci.sh test_hadrian"
+    ],
+    "stage": "full-build",
+    "tags": [
+      "aarch64-darwin"
+    ],
+    "variables": {
+      "BIGNUM_BACKEND": "gmp",
+      "BIN_DIST_NAME": "ghc-aarch64-darwin-cross_wasm32-wasi-release+text_simdutf",
+      "BUILD_FLAVOUR": "release+text_simdutf",
+      "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi --with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
+      "CROSS_TARGET": "wasm32-wasi",
+      "HADRIAN_ARGS": "--docs=no-sphinx-pdfs --docs=no-sphinx-man --haddock-for-hackage",
+      "LANG": "en_US.UTF-8",
+      "MACOSX_DEPLOYMENT_TARGET": "11.0",
+      "NIX_SYSTEM": "aarch64-darwin",
+      "RUNTEST_ARGS": "",
+      "TEST_ENV": "aarch64-darwin-cross_wasm32-wasi-release+text_simdutf",
+      "XZ_OPT": "-9"
+    }
+  },
   "nightly-aarch64-darwin-validate": {
     "after_script": [
       ".gitlab/ci.sh save_cache",
@@ -314,6 +510,70 @@
       "XZ_OPT": "-9"
     }
   },
+  "nightly-aarch64-linux-alpine3_18-cross_wasm32-wasi-release+host_fully_static+text_simdutf": {
+    "after_script": [
+      ".gitlab/ci.sh save_cache",
+      ".gitlab/ci.sh save_test_output",
+      ".gitlab/ci.sh clean",
+      "cat ci_timings"
+    ],
+    "allow_failure": false,
+    "artifacts": {
+      "expire_in": "8 weeks",
+      "paths": [
+        "ghc-aarch64-linux-alpine3_18-cross_wasm32-wasi-release+host_fully_static+text_simdutf.tar.xz",
+        "junit.xml",
+        "unexpected-test-output.tar.gz"
+      ],
+      "reports": {
+        "junit": "junit.xml"
+      },
+      "when": "always"
+    },
+    "cache": {
+      "key": "aarch64-linux-alpine3_18-$CACHE_REV",
+      "paths": [
+        "cabal-cache",
+        "toolchain"
+      ]
+    },
+    "dependencies": [],
+    "image": "registry.gitlab.haskell.org/ghc/ci-images/aarch64-linux-alpine3_18:$DOCKER_REV",
+    "needs": [
+      {
+        "artifacts": false,
+        "job": "hadrian-ghc-in-ghci"
+      }
+    ],
+    "rules": [
+      {
+        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY)",
+        "when": "on_success"
+      }
+    ],
+    "script": [
+      "sudo chown ghc:ghc -R .",
+      ".gitlab/ci.sh setup",
+      ".gitlab/ci.sh configure",
+      ".gitlab/ci.sh build_hadrian",
+      ".gitlab/ci.sh test_hadrian"
+    ],
+    "stage": "full-build",
+    "tags": [
+      "aarch64-linux"
+    ],
+    "variables": {
+      "BIGNUM_BACKEND": "gmp",
+      "BIN_DIST_NAME": "ghc-aarch64-linux-alpine3_18-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
+      "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
+      "CONFIGURE_ARGS": "--disable-ld-override --with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
+      "CROSS_TARGET": "wasm32-wasi",
+      "HADRIAN_ARGS": "--docs=no-sphinx-pdfs --docs=no-sphinx-man --haddock-for-hackage",
+      "RUNTEST_ARGS": "",
+      "TEST_ENV": "aarch64-linux-alpine3_18-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
+      "XZ_OPT": "-9"
+    }
+  },
   "nightly-aarch64-linux-alpine3_18-validate": {
     "after_script": [
       ".gitlab/ci.sh save_cache",
@@ -1015,7 +1275,7 @@
       "XZ_OPT": "-9"
     }
   },
-  "nightly-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static": {
+  "nightly-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf": {
     "after_script": [
       ".gitlab/ci.sh save_cache",
       ".gitlab/ci.sh save_test_output",
@@ -1026,7 +1286,7 @@
     "artifacts": {
       "expire_in": "8 weeks",
       "paths": [
-        "ghc-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static.tar.xz",
+        "ghc-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf.tar.xz",
         "junit.xml",
         "unexpected-test-output.tar.gz"
       ],
@@ -1069,17 +1329,17 @@
     ],
     "variables": {
       "BIGNUM_BACKEND": "gmp",
-      "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static",
-      "BUILD_FLAVOUR": "release+host_fully_static",
+      "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
+      "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
       "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
       "CROSS_TARGET": "wasm32-wasi",
-      "HADRIAN_ARGS": "--docs=none",
+      "HADRIAN_ARGS": "--docs=no-sphinx-pdfs --docs=no-sphinx-man --haddock-for-hackage",
       "RUNTEST_ARGS": "",
-      "TEST_ENV": "x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static",
+      "TEST_ENV": "x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
       "XZ_OPT": "-9"
     }
   },
-  "nightly-x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static": {
+  "nightly-x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static+text_simdutf": {
     "after_script": [
       ".gitlab/ci.sh save_cache",
       ".gitlab/ci.sh save_test_output",
@@ -1090,7 +1350,7 @@
     "artifacts": {
       "expire_in": "8 weeks",
       "paths": [
-        "ghc-x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static.tar.xz",
+        "ghc-x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static+text_simdutf.tar.xz",
         "junit.xml",
         "unexpected-test-output.tar.gz"
       ],
@@ -1133,17 +1393,17 @@
     ],
     "variables": {
       "BIGNUM_BACKEND": "native",
-      "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static",
-      "BUILD_FLAVOUR": "release+host_fully_static",
+      "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
+      "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
       "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
       "CROSS_TARGET": "wasm32-wasi",
-      "HADRIAN_ARGS": "--docs=none",
+      "HADRIAN_ARGS": "--docs=no-sphinx-pdfs --docs=no-sphinx-man --haddock-for-hackage",
       "RUNTEST_ARGS": "",
-      "TEST_ENV": "x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static",
+      "TEST_ENV": "x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
       "XZ_OPT": "-9"
     }
   },
-  "nightly-x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static": {
+  "nightly-x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static+text_simdutf": {
     "after_script": [
       ".gitlab/ci.sh save_cache",
       ".gitlab/ci.sh save_test_output",
@@ -1154,7 +1414,7 @@
     "artifacts": {
       "expire_in": "8 weeks",
       "paths": [
-        "ghc-x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static.tar.xz",
+        "ghc-x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static+text_simdutf.tar.xz",
         "junit.xml",
         "unexpected-test-output.tar.gz"
       ],
@@ -1197,13 +1457,13 @@
     ],
     "variables": {
       "BIGNUM_BACKEND": "gmp",
-      "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static",
-      "BUILD_FLAVOUR": "release+host_fully_static",
+      "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
+      "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
       "CONFIGURE_ARGS": "--enable-unregisterised --with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
       "CROSS_TARGET": "wasm32-wasi",
-      "HADRIAN_ARGS": "--docs=none",
+      "HADRIAN_ARGS": "--docs=no-sphinx-pdfs --docs=no-sphinx-man --haddock-for-hackage",
       "RUNTEST_ARGS": "",
-      "TEST_ENV": "x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static",
+      "TEST_ENV": "x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
       "XZ_OPT": "-9"
     }
   },
@@ -4592,7 +4852,7 @@
       "TEST_ENV": "x86_64-linux-alpine3_12-validate+fully_static"
     }
   },
-  "x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static": {
+  "x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf": {
     "after_script": [
       ".gitlab/ci.sh save_cache",
       ".gitlab/ci.sh save_test_output",
@@ -4603,7 +4863,7 @@
     "artifacts": {
       "expire_in": "2 weeks",
       "paths": [
-        "ghc-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static.tar.xz",
+        "ghc-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf.tar.xz",
         "junit.xml",
         "unexpected-test-output.tar.gz"
       ],
@@ -4646,16 +4906,16 @@
     ],
     "variables": {
       "BIGNUM_BACKEND": "gmp",
-      "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static",
-      "BUILD_FLAVOUR": "release+host_fully_static",
+      "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
+      "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
       "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
       "CROSS_TARGET": "wasm32-wasi",
-      "HADRIAN_ARGS": "--docs=none",
+      "HADRIAN_ARGS": "--docs=no-sphinx-pdfs --docs=no-sphinx-man --haddock-for-hackage",
       "RUNTEST_ARGS": "",
-      "TEST_ENV": "x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static"
+      "TEST_ENV": "x86_64-linux-alpine3_20-wasm-cross_wasm32-wasi-release+host_fully_static+text_simdutf"
     }
   },
-  "x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static": {
+  "x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static+text_simdutf": {
     "after_script": [
       ".gitlab/ci.sh save_cache",
       ".gitlab/ci.sh save_test_output",
@@ -4666,7 +4926,7 @@
     "artifacts": {
       "expire_in": "2 weeks",
       "paths": [
-        "ghc-x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static.tar.xz",
+        "ghc-x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static+text_simdutf.tar.xz",
         "junit.xml",
         "unexpected-test-output.tar.gz"
       ],
@@ -4710,16 +4970,16 @@
     ],
     "variables": {
       "BIGNUM_BACKEND": "native",
-      "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static",
-      "BUILD_FLAVOUR": "release+host_fully_static",
+      "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
+      "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
       "CONFIGURE_ARGS": "--with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
       "CROSS_TARGET": "wasm32-wasi",
-      "HADRIAN_ARGS": "--docs=none",
+      "HADRIAN_ARGS": "--docs=no-sphinx-pdfs --docs=no-sphinx-man --haddock-for-hackage",
       "RUNTEST_ARGS": "",
-      "TEST_ENV": "x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static"
+      "TEST_ENV": "x86_64-linux-alpine3_20-wasm-int_native-cross_wasm32-wasi-release+host_fully_static+text_simdutf"
     }
   },
-  "x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static": {
+  "x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static+text_simdutf": {
     "after_script": [
       ".gitlab/ci.sh save_cache",
       ".gitlab/ci.sh save_test_output",
@@ -4730,7 +4990,7 @@
     "artifacts": {
       "expire_in": "2 weeks",
       "paths": [
-        "ghc-x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static.tar.xz",
+        "ghc-x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static+text_simdutf.tar.xz",
         "junit.xml",
         "unexpected-test-output.tar.gz"
       ],
@@ -4774,13 +5034,13 @@
     ],
     "variables": {
       "BIGNUM_BACKEND": "gmp",
-      "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static",
-      "BUILD_FLAVOUR": "release+host_fully_static",
+      "BIN_DIST_NAME": "ghc-x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static+text_simdutf",
+      "BUILD_FLAVOUR": "release+host_fully_static+text_simdutf",
       "CONFIGURE_ARGS": "--enable-unregisterised --with-intree-gmp --with-system-libffi --enable-strict-ghc-toolchain-check",
       "CROSS_TARGET": "wasm32-wasi",
-      "HADRIAN_ARGS": "--docs=none",
+      "HADRIAN_ARGS": "--docs=no-sphinx-pdfs --docs=no-sphinx-man --haddock-for-hackage",
       "RUNTEST_ARGS": "",
-      "TEST_ENV": "x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static"
+      "TEST_ENV": "x86_64-linux-alpine3_20-wasm-unreg-cross_wasm32-wasi-release+host_fully_static+text_simdutf"
     }
   },
   "x86_64-linux-deb10-int_native-validate": {
-- 
GitLab