[Git][ghc/ghc][wip/marge_bot_batch_merge_job] 5 commits: Add support for external static plugins (#20964)

Marge Bot (@marge-bot) gitlab at gitlab.haskell.org
Wed Aug 10 17:18:22 UTC 2022



Marge Bot pushed to branch wip/marge_bot_batch_merge_job at Glasgow Haskell Compiler / GHC


Commits:
f95bbdca by Sylvain Henry at 2022-08-10T09:44:46-04:00
Add support for external static plugins (#20964)

This patch adds a new command-line flag:

  -fplugin-library=<file-path>;<unit-id>;<module>;<args>

used like this:

  -fplugin-library=path/to/plugin.so;package-123;Plugin.Module;["Argument","List"]

It allows a plugin to be loaded directly from a shared library. With
this approach, GHC doesn't compile anything for the plugin and doesn't
load any .hi file for the plugin and its dependencies. As such GHC
doesn't need to support two environments (one for plugins, one for
target code), which was the more ambitious approach tracked in #14335.

Fix #20964

Co-authored-by: Josh Meredith <joshmeredith2008 at gmail.com>

- - - - -
5bc489ca by Ben Gamari at 2022-08-10T09:45:22-04:00
gitlab-ci: Fix ARMv7 build

It appears that the CI refactoring carried out in
5ff690b8474c74e9c968ef31e568c1ad0fe719a1 failed to carry over some
critical configuration: setting the build/host/target platforms and
forcing use of a non-broken linker.

- - - - -
596db9a5 by Ben Gamari at 2022-08-10T09:45:22-04:00
gitlab-ci: Run ARMv7 jobs when ~ARM label is used

- - - - -
c0dfdf86 by Ben Gamari at 2022-08-10T13:17:54-04:00
hadrian: Don't attempt to install documentation if doc/ doesn't exist

Previously we would attempt to install documentation even if the `doc`
directory doesn't exist (e.g. due to `--docs=none`). This would result
in the surprising side-effect of the entire contents of the bindist
being installed in the destination documentation directory. Fix this.

Fixes #21976.

- - - - -
74351150 by normalcoder at 2022-08-10T13:17:54-04:00
ncg/aarch64: Don't use x18 register on AArch64/Darwin

Apple's ABI documentation [1] says: "The platforms reserve register x18.
Don’t use this register." While this wasn't problematic in previous
Darwin releases, macOS 13 appears to start zeroing this register
periodically. See #21964.

[1] https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms

- - - - -


22 changed files:

- .gitlab/gen_ci.hs
- .gitlab/jobs.yaml
- compiler/CodeGen.Platform.h
- compiler/GHC/Driver/Plugins.hs
- + compiler/GHC/Driver/Plugins/External.hs
- compiler/GHC/Driver/Session.hs
- compiler/GHC/Runtime/Loader.hs
- compiler/ghc.cabal.in
- docs/users_guide/extending_ghc.rst
- hadrian/bindist/Makefile
- testsuite/tests/count-deps/CountDepsAst.stdout
- testsuite/tests/count-deps/CountDepsParser.stdout
- testsuite/tests/plugins/Makefile
- testsuite/tests/plugins/all.T
- + testsuite/tests/plugins/plugins-external.hs
- + testsuite/tests/plugins/plugins-external.stderr
- + testsuite/tests/plugins/plugins-external.stdout
- + testsuite/tests/plugins/shared-plugin/LICENSE
- + testsuite/tests/plugins/shared-plugin/Makefile
- + testsuite/tests/plugins/shared-plugin/Setup.hs
- + testsuite/tests/plugins/shared-plugin/Simple/Plugin.hs
- + testsuite/tests/plugins/shared-plugin/shared-plugin.cabal


Changes:

=====================================
.gitlab/gen_ci.hs
=====================================
@@ -325,8 +325,15 @@ opsysVariables _ FreeBSD13 = mconcat
   ]
 opsysVariables ARMv7 (Linux distro) =
   distroVariables distro <>
-  mconcat [ -- ld.gold is affected by #16177 and therefore cannot be used.
-            "CONFIGURE_ARGS" =: "LD=ld.lld"
+  mconcat [ "CONFIGURE_ARGS" =: "--host=armv7-linux-gnueabihf --build=armv7-linux-gnueabihf --target=armv7-linux-gnueabihf"
+            -- N.B. We disable ld.lld explicitly here because it appears to fail
+            -- non-deterministically on ARMv7. See #18280.
+          , "LD" =: "ld.gold"
+          , "GccUseLdOpt" =: "-fuse-ld=gold"
+            -- Awkwardly, this appears to be necessary to work around a
+            -- live-lock exhibited by the CPython (at least in 3.9 and 3.8)
+            -- interpreter on ARMv7
+          , "HADRIAN_ARGS" =: "--test-verbose=3"
           ]
 opsysVariables _ (Linux distro) = distroVariables distro
 opsysVariables AArch64 (Darwin {}) =
@@ -494,6 +501,7 @@ data Rule = FastCI       -- ^ Run this job when the fast-ci label is set
           | Nightly      -- ^ Only run this job in the nightly pipeline
           | LLVMBackend  -- ^ Only run this job when the "LLVM backend" label is present
           | FreeBSDLabel -- ^ Only run this job when the "FreeBSD" label is set.
+          | ARMLabel    -- ^ Only run this job when the "ARM" label is set.
           | Disable      -- ^ Don't run this job.
           deriving (Bounded, Enum, Ord, Eq)
 
@@ -514,6 +522,8 @@ ruleString On LLVMBackend = "$CI_MERGE_REQUEST_LABELS =~ /.*LLVM backend.*/"
 ruleString Off LLVMBackend = true
 ruleString On FreeBSDLabel = "$CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/"
 ruleString Off FreeBSDLabel = true
+ruleString On ARMLabel = "$CI_MERGE_REQUEST_LABELS =~ /.*ARM.*/"
+ruleString Off ARMLabel = true
 ruleString On ReleaseOnly = "$RELEASE_JOB == \"yes\""
 ruleString Off ReleaseOnly = "$RELEASE_JOB != \"yes\""
 ruleString On Nightly = "$NIGHTLY"
@@ -785,7 +795,7 @@ jobs = M.fromList $ concatMap flattenJobGroup $
      , standardBuilds AArch64 Darwin
      , standardBuilds AArch64 (Linux Debian10)
      , disableValidate (standardBuilds AArch64 (Linux Debian11))
-     , allowFailureGroup (disableValidate (standardBuilds ARMv7 (Linux Debian10)))
+     , allowFailureGroup (addValidateRule ARMLabel (standardBuilds ARMv7 (Linux Debian10)))
      , standardBuilds I386 (Linux Debian9)
      , allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine) static)
      , disableValidate (allowFailureGroup (standardBuildsWithConfig Amd64 (Linux Alpine) staticNativeInt))


=====================================
.gitlab/jobs.yaml
=====================================
@@ -35,7 +35,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -97,7 +97,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -155,7 +155,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -213,7 +213,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && ($CI_MERGE_REQUEST_LABELS =~ /.*ARM.*/) && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -232,7 +232,10 @@
       "BIGNUM_BACKEND": "gmp",
       "BIN_DIST_NAME": "ghc-armv7-linux-deb10-validate",
       "BUILD_FLAVOUR": "validate",
-      "CONFIGURE_ARGS": "LD=ld.lld ",
+      "CONFIGURE_ARGS": "--host=armv7-linux-gnueabihf --build=armv7-linux-gnueabihf --target=armv7-linux-gnueabihf ",
+      "GccUseLdOpt": "-fuse-ld=gold",
+      "HADRIAN_ARGS": "--test-verbose=3",
+      "LD": "ld.gold",
       "TEST_ENV": "armv7-linux-deb10-validate"
     }
   },
@@ -271,7 +274,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -329,7 +332,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -392,7 +395,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -451,7 +454,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -510,7 +513,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -529,7 +532,10 @@
       "BIGNUM_BACKEND": "gmp",
       "BIN_DIST_NAME": "ghc-armv7-linux-deb10-validate",
       "BUILD_FLAVOUR": "validate",
-      "CONFIGURE_ARGS": "LD=ld.lld ",
+      "CONFIGURE_ARGS": "--host=armv7-linux-gnueabihf --build=armv7-linux-gnueabihf --target=armv7-linux-gnueabihf ",
+      "GccUseLdOpt": "-fuse-ld=gold",
+      "HADRIAN_ARGS": "--test-verbose=3",
+      "LD": "ld.gold",
       "TEST_ENV": "armv7-linux-deb10-validate",
       "XZ_OPT": "-9"
     }
@@ -569,7 +575,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -628,7 +634,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -693,7 +699,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -754,7 +760,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -816,7 +822,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -878,7 +884,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -938,7 +944,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -997,7 +1003,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1056,7 +1062,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1116,7 +1122,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1175,7 +1181,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1234,7 +1240,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1293,7 +1299,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1352,7 +1358,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1413,7 +1419,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1474,7 +1480,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1533,7 +1539,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1592,7 +1598,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1653,7 +1659,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1715,7 +1721,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1776,7 +1782,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1831,7 +1837,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1890,7 +1896,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -1953,7 +1959,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2017,7 +2023,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2077,7 +2083,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2137,7 +2143,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2156,8 +2162,11 @@
       "BIGNUM_BACKEND": "gmp",
       "BIN_DIST_NAME": "ghc-armv7-linux-deb10-release",
       "BUILD_FLAVOUR": "release",
-      "CONFIGURE_ARGS": "LD=ld.lld ",
+      "CONFIGURE_ARGS": "--host=armv7-linux-gnueabihf --build=armv7-linux-gnueabihf --target=armv7-linux-gnueabihf ",
+      "GccUseLdOpt": "-fuse-ld=gold",
+      "HADRIAN_ARGS": "--test-verbose=3",
       "IGNORE_PERF_FAILURES": "all",
+      "LD": "ld.gold",
       "TEST_ENV": "armv7-linux-deb10-release",
       "XZ_OPT": "-9"
     }
@@ -2197,7 +2206,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2257,7 +2266,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2323,7 +2332,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2385,7 +2394,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2448,7 +2457,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2511,7 +2520,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2572,7 +2581,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2632,7 +2641,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2692,7 +2701,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2752,7 +2761,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2812,7 +2821,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2874,7 +2883,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2936,7 +2945,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -2999,7 +3008,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3055,7 +3064,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3115,7 +3124,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB == \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3179,7 +3188,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3243,7 +3252,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && ($CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/) && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && ($CI_MERGE_REQUEST_LABELS =~ /.*FreeBSD.*/) && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3303,7 +3312,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -3364,7 +3373,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3425,7 +3434,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -3484,7 +3493,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3543,7 +3552,7 @@
     "rules": [
       {
         "allow_failure": true,
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "manual"
       }
     ],
@@ -3601,7 +3610,7 @@
     ],
     "rules": [
       {
-        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3660,7 +3669,7 @@
     ],
     "rules": [
       {
-        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3718,7 +3727,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -3776,7 +3785,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3834,7 +3843,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && ($CI_MERGE_REQUEST_LABELS =~ /.*LLVM backend.*/) && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && ($CI_MERGE_REQUEST_LABELS =~ /.*LLVM backend.*/) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -3893,7 +3902,7 @@
     "rules": [
       {
         "allow_failure": true,
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "manual"
       }
     ],
@@ -3953,7 +3962,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -4013,7 +4022,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -4071,7 +4080,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -4129,7 +4138,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],
@@ -4189,7 +4198,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -4250,7 +4259,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -4310,7 +4319,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -4364,7 +4373,7 @@
     ],
     "rules": [
       {
-        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
+        "if": "($CI_MERGE_REQUEST_LABELS !~ /.*fast-ci.*/) && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"disabled\" != \"disabled\")",
         "when": "on_success"
       }
     ],
@@ -4422,7 +4431,7 @@
     ],
     "rules": [
       {
-        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
+        "if": "(\"true\" == \"true\") && ($RELEASE_JOB != \"yes\") && ($NIGHTLY == null) && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\") && (\"true\" == \"true\")",
         "when": "on_success"
       }
     ],


=====================================
compiler/CodeGen.Platform.h
=====================================
@@ -926,6 +926,14 @@ freeReg 29 = False
 -- ip0 -- used for spill offset computations
 freeReg 16 = False
 
+#if defined(darwin_HOST_OS) || defined(ios_HOST_OS)
+-- x18 is reserved by the platform on Darwin/iOS, and can not be used
+-- More about ARM64 ABI that Apple platforms support:
+-- https://developer.apple.com/documentation/xcode/writing-arm64-code-for-apple-platforms
+-- https://github.com/Siguza/ios-resources/blob/master/bits/arm64.md
+freeReg 18 = False
+#endif
+
 # if defined(REG_Base)
 freeReg REG_Base  = False
 # endif


=====================================
compiler/GHC/Driver/Plugins.hs
=====================================
@@ -1,4 +1,11 @@
 {-# LANGUAGE RankNTypes #-}
+{-# LANGUAGE CPP #-}
+
+#if defined(HAVE_INTERNAL_INTERPRETER)
+{-# LANGUAGE MagicHash #-}
+{-# LANGUAGE LambdaCase #-}
+{-# LANGUAGE UnboxedTuples #-}
+#endif
 
 
 -- | Definitions for writing /plugins/ for GHC. Plugins can hook into
@@ -14,6 +21,10 @@ module GHC.Driver.Plugins (
     , CommandLineOption
     , PsMessages(..)
     , ParsedResult(..)
+
+      -- * External plugins
+    , loadExternalPlugins
+
       -- ** Recompilation checking
     , purePlugin, impurePlugin, flagRecompile
     , PluginRecompile(..)
@@ -52,6 +63,7 @@ module GHC.Driver.Plugins (
     , PluginWithArgs(..), pluginsWithArgs, pluginRecompile'
     , LoadedPlugin(..), lpModuleName
     , StaticPlugin(..)
+    , ExternalPlugin(..)
     , mapPlugins, withPlugins, withPlugins_
     ) where
 
@@ -60,6 +72,7 @@ import GHC.Prelude
 import GHC.Driver.Env
 import GHC.Driver.Monad
 import GHC.Driver.Phases
+import GHC.Driver.Plugins.External
 
 import GHC.Unit.Module
 import GHC.Unit.Module.ModIface
@@ -75,8 +88,12 @@ import GHC.Core.Opt.Monad ( CoreM )
 import GHC.Core.Opt.Pipeline.Types ( CoreToDo )
 import GHC.Hs
 import GHC.Types.Error (Messages)
+import GHC.Linker.Types
+import GHC.Types.Unique.DFM
+
 import GHC.Utils.Fingerprint
-import GHC.Utils.Outputable (Outputable(..), text, (<+>))
+import GHC.Utils.Outputable
+import GHC.Utils.Panic
 
 import Data.List (sort)
 
@@ -85,8 +102,13 @@ import Data.List (sort)
 import qualified Data.Semigroup
 
 import Control.Monad
-import GHC.Linker.Types
-import GHC.Types.Unique.DFM
+
+#if defined(HAVE_INTERNAL_INTERPRETER)
+import GHCi.ObjLink
+import GHC.Exts (addrToAny#, Ptr(..))
+import GHC.Utils.Encoding
+#endif
+
 
 -- | Command line options gathered from the -PModule.Name:stuff syntax
 -- are given to you as this type
@@ -196,6 +218,14 @@ data LoadedPlugin = LoadedPlugin
   -- ^ the module containing the plugin
   }
 
+-- | External plugin loaded directly from a library without loading module
+-- interfaces
+data ExternalPlugin = ExternalPlugin
+  { epPlugin :: PluginWithArgs -- ^ Plugin with its arguments
+  , epUnit   :: String         -- ^ UnitId
+  , epModule :: String         -- ^ Module name
+  }
+
 -- | A static plugin with its arguments. For registering compiled-in plugins
 -- through the GHC API.
 data StaticPlugin = StaticPlugin
@@ -285,6 +315,10 @@ data Plugins = Plugins
       -- To add dynamically loaded plugins through the GHC API see
       -- 'addPluginModuleName' instead.
 
+  , externalPlugins :: ![ExternalPlugin]
+      -- ^ External plugins loaded directly from libraries without loading
+      -- module interfaces.
+
   , loadedPlugins :: ![LoadedPlugin]
       -- ^ Plugins dynamically loaded after processing arguments. What
       -- will be loaded here is directed by DynFlags.pluginModNames.
@@ -299,12 +333,17 @@ data Plugins = Plugins
   }
 
 emptyPlugins :: Plugins
-emptyPlugins = Plugins [] [] ([], emptyUDFM)
-
+emptyPlugins = Plugins
+  { staticPlugins    = []
+  , externalPlugins  = []
+  , loadedPlugins    = []
+  , loadedPluginDeps = ([], emptyUDFM)
+  }
 
 pluginsWithArgs :: Plugins -> [PluginWithArgs]
 pluginsWithArgs plugins =
   map lpPlugin (loadedPlugins plugins) ++
+  map epPlugin (externalPlugins plugins) ++
   map spPlugin (staticPlugins plugins)
 
 -- | Perform an operation by using all of the plugins in turn.
@@ -328,3 +367,53 @@ data FrontendPlugin = FrontendPlugin {
     }
 defaultFrontendPlugin :: FrontendPlugin
 defaultFrontendPlugin = FrontendPlugin { frontend = \_ _ -> return () }
+
+
+-- | Load external plugins
+loadExternalPlugins :: [ExternalPluginSpec] -> IO [ExternalPlugin]
+loadExternalPlugins [] = return []
+#if !defined(HAVE_INTERNAL_INTERPRETER)
+loadExternalPlugins _ = do
+  panic "loadExternalPlugins: can't load external plugins with GHC built without internal interpreter"
+#elif !defined(CAN_LOAD_DLL)
+loadExternalPlugins _ = do
+  panic "loadExternalPlugins: loading shared libraries isn't supported by this compiler"
+#else
+loadExternalPlugins ps = do
+  -- initialize the linker
+  initObjLinker RetainCAFs
+  -- load plugins
+  forM ps $ \(ExternalPluginSpec path unit mod_name opts) -> do
+    loadExternalPluginLib path
+    -- lookup symbol
+    let ztmp = zEncodeString mod_name ++ "_plugin_closure"
+        symbol
+          | null unit = ztmp
+          | otherwise = zEncodeString unit ++ "_" ++ ztmp
+    plugin <- lookupSymbol symbol >>= \case
+      Nothing -> pprPanic "loadExternalPlugins"
+                  (vcat [ text "Symbol not found"
+                        , text "  Library path: " <> text path
+                        , text "  Symbol      : " <> text symbol
+                        ])
+      Just (Ptr addr) -> case addrToAny# addr of
+        (# a #) -> pure a
+
+    pure $ ExternalPlugin (PluginWithArgs plugin opts) unit mod_name
+
+loadExternalPluginLib :: FilePath -> IO ()
+loadExternalPluginLib path = do
+  -- load library
+  loadDLL path >>= \case
+    Just errmsg -> pprPanic "loadExternalPluginLib"
+                    (vcat [ text "Can't load plugin library"
+                          , text "  Library path: " <> text path
+                          , text "  Error       : " <> text errmsg
+                          ])
+    Nothing -> do
+      -- resolve objects
+      resolveObjs >>= \case
+        True -> return ()
+        False -> pprPanic "loadExternalPluginLib" (text "Unable to resolve objects for library: " <> text path)
+
+#endif


=====================================
compiler/GHC/Driver/Plugins/External.hs
=====================================
@@ -0,0 +1,79 @@
+-- | External plugins
+--
+-- GHC supports two kinds of "static" plugins:
+--  1. internal: setup with GHC-API
+--  2. external: setup as explained below and loaded from shared libraries
+--
+-- The intended use case for external static plugins is with cross compilers: at
+-- the time of writing, GHC is mono-target and a GHC cross-compiler (i.e. when
+-- host /= target) can't build nor load plugins for the host using the
+-- "non-static" plugin approach. Fixing this is tracked in #14335. If you're not
+-- using a cross-compiler, you'd better use non-static plugins which are easier
+-- to build and and safer to use (see below).
+--
+-- External static plugins can be configured via the command-line with
+-- the -fplugin-library flag. Syntax is:
+--
+--   -fplugin-library=⟨file-path⟩;⟨unit-id⟩;⟨module⟩;⟨args⟩
+--
+-- Example:
+--    -fplugin-library=path/to/plugin;package-123;Plugin.Module;["Argument","List"]
+--
+-- Building the plugin library:
+--  1. link with the libraries used to build the compiler you target.  If you
+--  target a cross-compiler (stage2), you can't directly use it to build the
+--  plugin library. Use the stage1 compiler instead.
+--
+--  2. if you use cabal to build the library, its unit-id will be set by cabal
+--  and will contain a hash (e.g. "my-plugin-unit-1345656546ABCDEF"). To force
+--  the unit id, use GHC's `-this-unit-id` command line flag:
+--    e.g. -this-unit-id my-plugin-unit
+--  You can set this in the .cabal file of your library with the following
+--  stanza: `ghc-options: -this-unit-id my-plugin-unit`
+--
+--  3. To make your plugin easier to distribute, you may want to link it
+--  statically with all its dependencies. You would need to use `-shared`
+--  without `-dynamic` when building your library.
+--
+--  However, all the static dependencies have to be built with `-fPIC` and it's
+--  not done by default. See
+--  https://www.hobson.space/posts/haskell-foreign-library/ for a way to modify
+--  the compiler to do it.
+--
+--  In any case, don't link your plugin library statically with the RTS (e.g.
+--  use `-fno-link-rts`) as there are some global variables in the RTS that must
+--  be shared between the plugin and the compiler.
+--
+-- With external static plugins we don't check the type of the `plugin` closure
+-- we look up. If it's not a valid `Plugin` value, it will probably crash badly.
+--
+
+module GHC.Driver.Plugins.External
+  ( ExternalPluginSpec (..)
+  , parseExternalPluginSpec
+  )
+where
+
+import GHC.Prelude
+import Text.Read
+
+-- | External plugin spec
+data ExternalPluginSpec = ExternalPluginSpec
+  { esp_lib     :: !FilePath
+  , esp_unit_id :: !String
+  , esp_module  :: !String
+  , esp_args    :: ![String]
+  }
+
+-- | Parser external static plugin specification from command-line flag
+parseExternalPluginSpec :: String -> Maybe ExternalPluginSpec
+parseExternalPluginSpec optflag =
+  case break (== ';') optflag of
+    (libPath, _:rest) -> case break (== ';') rest of
+      (libName, _:pack) -> case break (== ';') pack of
+        (modName, _:args) -> case readMaybe args of
+          Just as -> Just (ExternalPluginSpec libPath libName modName as)
+          Nothing -> Nothing
+        _ -> Nothing
+      _ -> Nothing
+    _ -> Nothing


=====================================
compiler/GHC/Driver/Session.hs
=====================================
@@ -229,6 +229,7 @@ import GHC.Builtin.Names ( mAIN_NAME )
 import GHC.Driver.Phases ( Phase(..), phaseInputExt )
 import GHC.Driver.Flags
 import GHC.Driver.Backend
+import GHC.Driver.Plugins.External
 import GHC.Settings.Config
 import GHC.Utils.CliOption
 import GHC.Core.Unfold
@@ -590,6 +591,9 @@ data DynFlags = DynFlags {
     -- ^ the @-ffrontend-opt@ flags given on the command line, in *reverse*
     -- order that they're specified on the command line.
 
+  externalPluginSpecs   :: [ExternalPluginSpec],
+    -- ^ External plugins loaded from shared libraries
+
   --  For ghc -M
   depMakefile           :: FilePath,
   depIncludePkgDeps     :: Bool,
@@ -1176,6 +1180,8 @@ defaultDynFlags mySettings =
         pluginModNameOpts       = [],
         frontendPluginOpts      = [],
 
+        externalPluginSpecs     = [],
+
         outputFile_             = Nothing,
         dynOutputFile_          = Nothing,
         outputHi                = Nothing,
@@ -1715,6 +1721,11 @@ addPluginModuleNameOption optflag d = d { pluginModNameOpts = (mkModuleName m, o
           [] -> "" -- should probably signal an error
           (_:plug_opt) -> plug_opt -- ignore the ':' from break
 
+addExternalPlugin :: String -> DynFlags -> DynFlags
+addExternalPlugin optflag d = case parseExternalPluginSpec optflag of
+  Just r  -> d { externalPluginSpecs = r : externalPluginSpecs d }
+  Nothing -> cmdLineError $ "Couldn't parse external plugin specification: " ++ optflag
+
 addFrontendPluginOption :: String -> DynFlags -> DynFlags
 addFrontendPluginOption s d = d { frontendPluginOpts = s : frontendPluginOpts d }
 
@@ -2695,6 +2706,8 @@ dynamic_flags_deps = [
   , make_ord_flag defGhcFlag "fclear-plugins" (noArg clearPluginModuleNames)
   , make_ord_flag defGhcFlag "ffrontend-opt" (hasArg addFrontendPluginOption)
 
+  , make_ord_flag defGhcFlag "fplugin-library" (hasArg addExternalPlugin)
+
         ------ Optimisation flags ------------------------------------------
   , make_dep_flag defGhcFlag "Onot"   (noArgM $ setOptLevel 0 )
                                                             "Use -O0 instead"


=====================================
compiler/GHC/Runtime/Loader.hs
=====================================
@@ -26,6 +26,7 @@ import GHC.Driver.Session
 import GHC.Driver.Ppr
 import GHC.Driver.Hooks
 import GHC.Driver.Plugins
+import GHC.Driver.Plugins.External
 
 import GHC.Linker.Loader       ( loadModule, loadName )
 import GHC.Runtime.Interpreter ( wormhole )
@@ -75,22 +76,48 @@ import Data.List (unzip4)
 -- pluginModNames or pluginModNameOpts changes.
 initializePlugins :: HscEnv -> IO HscEnv
 initializePlugins hsc_env
-    -- plugins not changed
+    -- check that plugin specifications didn't change
+
+    -- dynamic plugins
   | loaded_plugins <- loadedPlugins (hsc_plugins hsc_env)
   , map lpModuleName loaded_plugins == reverse (pluginModNames dflags)
-   -- arguments not changed
   , all same_args loaded_plugins
-  = return hsc_env -- no need to reload plugins FIXME: doesn't take static plugins into account
+
+    -- external plugins
+  , external_plugins <- externalPlugins (hsc_plugins hsc_env)
+  , check_external_plugins external_plugins (externalPluginSpecs dflags)
+
+    -- FIXME: we should check static plugins too
+
+  = return hsc_env -- no change, no need to reload plugins
+
   | otherwise
   = do (loaded_plugins, links, pkgs) <- loadPlugins hsc_env
-       let plugins' = (hsc_plugins hsc_env) { loadedPlugins = loaded_plugins, loadedPluginDeps = (links, pkgs) }
+       external_plugins <- loadExternalPlugins (externalPluginSpecs dflags)
+       let plugins' = (hsc_plugins hsc_env) { staticPlugins    = staticPlugins (hsc_plugins hsc_env)
+                                            , externalPlugins  = external_plugins
+                                            , loadedPlugins    = loaded_plugins
+                                            , loadedPluginDeps = (links, pkgs)
+                                            }
        let hsc_env' = hsc_env { hsc_plugins = plugins' }
        withPlugins (hsc_plugins hsc_env') driverPlugin hsc_env'
   where
+    dflags = hsc_dflags hsc_env
+    -- dynamic plugins
     plugin_args = pluginModNameOpts dflags
     same_args p = paArguments (lpPlugin p) == argumentsForPlugin p plugin_args
     argumentsForPlugin p = map snd . filter ((== lpModuleName p) . fst)
-    dflags = hsc_dflags hsc_env
+    -- external plugins
+    check_external_plugin p spec = and
+      [ epUnit                p  == esp_unit_id spec
+      , epModule              p  == esp_module spec
+      , paArguments (epPlugin p) == esp_args spec
+      ]
+    check_external_plugins eps specs = case (eps,specs) of
+      ([]  , [])  -> True
+      (_   , [])  -> False -- some external plugin removed
+      ([]  , _ )  -> False -- some external plugin added
+      (p:ps,s:ss) -> check_external_plugin p s && check_external_plugins ps ss
 
 loadPlugins :: HscEnv -> IO ([LoadedPlugin], [Linkable], PkgsLoaded)
 loadPlugins hsc_env


=====================================
compiler/ghc.cabal.in
=====================================
@@ -441,6 +441,7 @@ Library
         GHC.Driver.Pipeline.Phases
         GHC.Driver.Pipeline.Monad
         GHC.Driver.Plugins
+        GHC.Driver.Plugins.External
         GHC.Driver.Ppr
         GHC.Driver.Session
         GHC.Hs


=====================================
docs/users_guide/extending_ghc.rst
=====================================
@@ -268,7 +268,6 @@ option. The list of enabled plugins can be reset with the
     the command line is not possible. Instead ``:set -fclear-plugins`` can be
     used.
 
-
 As an example, in order to load the plugin exported by ``Foo.Plugin`` in
 the package ``foo-ghc-plugin``, and give it the parameter "baz", we
 would invoke GHC like this:
@@ -286,6 +285,19 @@ would invoke GHC like this:
     Linking Test ...
     $
 
+
+Plugins can be also be loaded from libraries directly. It allows plugins to be
+loaded in cross-compilers (as a workaround for #14335).
+
+.. ghc-flag:: -fplugin-library=⟨file-path⟩;⟨unit-id⟩;⟨module⟩;⟨args⟩
+    :shortdesc: Load a pre-compiled static plugin from an external library
+    :type: dynamic
+    :category: plugins
+
+    Arguments are specified in a list form, so a plugin specified to
+    :ghc-flag:`-fplugin-library=⟨file-path⟩;⟨unit-id⟩;⟨module⟩;⟨args⟩` will look
+    like ``'path/to/plugin;package-123;Plugin.Module;["Argument","List"]'``.
+
 Alternatively, core plugins can be specified with Template Haskell.
 
 ::


=====================================
hadrian/bindist/Makefile
=====================================
@@ -184,10 +184,12 @@ install_lib: lib/settings
 install_docs:
 	@echo "Copying docs to $(DESTDIR)$(docdir)"
 	$(INSTALL_DIR) "$(DESTDIR)$(docdir)"
-	cd doc; $(FIND) . -type f -exec sh -c \
-			'$(INSTALL_DIR) "$(DESTDIR)$(docdir)/`dirname $$1`" && \
-			 $(INSTALL_DATA) "$$1" "$(DESTDIR)$(docdir)/`dirname $$1`" \
-		' sh '{}' \;
+	
+	if [ -d doc ]; then \
+		cd doc; $(FIND) . -type f -exec sh -c \
+			'$(INSTALL_DIR) "$(DESTDIR)$(docdir)/`dirname $$1`" && $(INSTALL_DATA) "$$1" "$(DESTDIR)$(docdir)/`dirname $$1`"' \
+			sh '{}' ';'; \
+	fi
 	
 	if [ -d docs-utils ]; then \
 		$(INSTALL_DIR) "$(DESTDIR)$(docdir)/html/libraries/"; \


=====================================
testsuite/tests/count-deps/CountDepsAst.stdout
=====================================
@@ -116,6 +116,7 @@ GHC.Driver.Phases
 GHC.Driver.Pipeline.Monad
 GHC.Driver.Pipeline.Phases
 GHC.Driver.Plugins
+GHC.Driver.Plugins.External
 GHC.Driver.Ppr
 GHC.Driver.Session
 GHC.Hs


=====================================
testsuite/tests/count-deps/CountDepsParser.stdout
=====================================
@@ -117,6 +117,7 @@ GHC.Driver.Phases
 GHC.Driver.Pipeline.Monad
 GHC.Driver.Pipeline.Phases
 GHC.Driver.Plugins
+GHC.Driver.Plugins.External
 GHC.Driver.Ppr
 GHC.Driver.Session
 GHC.Hs


=====================================
testsuite/tests/plugins/Makefile
=====================================
@@ -205,3 +205,18 @@ test-echo-in-turn-many-args:
 .PHONY: test-echo-in-line-many-args
 test-echo-in-line-many-args:
 	"$(TEST_HC)" $(TEST_HC_OPTS) $(ghcPluginWayFlags) -v0 test-echo-in-line-many-args.hs -package-db echo-plugin/pkg.test-echo-in-line-many-args/local.package.conf
+
+
+ifeq "$(WINDOWS)" "YES"
+DLL = $1.dll
+else ifeq "$(DARWIN)" "YES"
+DLL = lib$1.dylib
+else
+DLL = lib$1.so
+endif
+
+.PHONY: plugins-external
+plugins-external:
+	cp shared-plugin/pkg.plugins01/dist/build/$(call DLL,HSsimple-plugin*) $(call DLL,HSsimple-plugin)
+	"$(TEST_HC)" $(TEST_HC_OPTS) $(ghcPluginWayFlags) --make -v0 -fplugin-library "$(PWD)/$(call DLL,HSsimple-plugin);simple-plugin-1234;Simple.Plugin;[\"Plugin\",\"loaded\",\"from\",\"a shared lib\"]" plugins-external.hs
+	./plugins-external


=====================================
testsuite/tests/plugins/all.T
=====================================
@@ -311,3 +311,8 @@ test('test-echo-in-line-many-args',
      [extra_files(['echo-plugin/']),
       pre_cmd('$MAKE -s --no-print-directory -C echo-plugin package.test-echo-in-line-many-args TOP={top}')],
      makefile_test, [])
+
+test('plugins-external',
+     [extra_files(['shared-plugin/']),
+      pre_cmd('$MAKE -s --no-print-directory -C shared-plugin package.plugins01 TOP={top}')],
+     makefile_test, [])


=====================================
testsuite/tests/plugins/plugins-external.hs
=====================================
@@ -0,0 +1,4 @@
+-- Intended to test that we can load plugins as external shared libraries
+module Main where
+
+main = putStrLn "Hello World"


=====================================
testsuite/tests/plugins/plugins-external.stderr
=====================================
@@ -0,0 +1,2 @@
+Simple Plugin Passes Queried
+Got options: Plugin loaded from a shared lib


=====================================
testsuite/tests/plugins/plugins-external.stdout
=====================================
@@ -0,0 +1 @@
+Hello World


=====================================
testsuite/tests/plugins/shared-plugin/LICENSE
=====================================
@@ -0,0 +1,10 @@
+Copyright (c) 2008, Max Bolingbroke
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+    * Neither the name of Max Bolingbroke nor the names of other contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.


=====================================
testsuite/tests/plugins/shared-plugin/Makefile
=====================================
@@ -0,0 +1,20 @@
+TOP=../../..
+include $(TOP)/mk/boilerplate.mk
+include $(TOP)/mk/test.mk
+
+clean.%:
+	rm -rf pkg.$*
+
+HERE := $(abspath .)
+$(eval $(call canonicalise,HERE))
+
+package.%:
+	$(MAKE) -s --no-print-directory clean.$*
+	mkdir pkg.$*
+	"$(TEST_HC)" -outputdir pkg.$* --make -v0 -o pkg.$*/setup Setup.hs
+	
+	"$(GHC_PKG)" init pkg.$*/local.package.conf
+	
+	pkg.$*/setup configure --distdir pkg.$*/dist -v0 $(CABAL_PLUGIN_BUILD) --prefix="$(HERE)/pkg.$*/install" --with-compiler="$(TEST_HC)" --with-hc-pkg="$(GHC_PKG)" --package-db=pkg.$*/local.package.conf $(if $(findstring YES,$(HAVE_PROFILING)), --enable-library-profiling)
+	pkg.$*/setup build     --distdir pkg.$*/dist -v0
+	pkg.$*/setup install   --distdir pkg.$*/dist -v0


=====================================
testsuite/tests/plugins/shared-plugin/Setup.hs
=====================================
@@ -0,0 +1,3 @@
+import Distribution.Simple
+
+main = defaultMain


=====================================
testsuite/tests/plugins/shared-plugin/Simple/Plugin.hs
=====================================
@@ -0,0 +1,26 @@
+{-# LANGUAGE TemplateHaskell #-}
+
+module Simple.Plugin(plugin) where
+
+import GHC.Types.Unique.FM
+import GHC.Plugins
+import qualified GHC.Utils.Error
+
+import Control.Monad
+import Data.Monoid hiding (Alt)
+import Data.Dynamic
+import qualified Language.Haskell.TH as TH
+
+plugin :: Plugin
+plugin = defaultPlugin {
+    installCoreToDos = install,
+    pluginRecompile  = purePlugin
+  }
+
+install :: [CommandLineOption] -> [CoreToDo] -> CoreM [CoreToDo]
+install options todos = do
+    putMsgS $ "Simple Plugin Passes Queried"
+    putMsgS $ "Got options: " ++ unwords options
+
+    -- Create some actual passes to continue the test.
+    return todos


=====================================
testsuite/tests/plugins/shared-plugin/shared-plugin.cabal
=====================================
@@ -0,0 +1,21 @@
+Name:           simple-plugin
+Version:        0.1
+Synopsis:       A demonstration of the GHC plugin system.
+Cabal-Version:  >= 1.2
+Build-Type:     Simple
+License:        BSD3
+License-File:   LICENSE
+Author:         Max Bolingbroke
+Homepage:       http://blog.omega-prime.co.uk
+
+Library
+    Extensions:     CPP
+    Build-Depends:
+        base,
+        template-haskell,
+        ghc >= 6.11
+    Exposed-Modules:
+        Simple.Plugin
+
+    -- explicitly set the unit-id to allow loading from a shared library
+    ghc-options: -this-unit-id simple-plugin-1234



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ad23cf018d60114800361644e690065c340b1234...74351150d32aff4866352757ac69b4eecc6b245b

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/ad23cf018d60114800361644e690065c340b1234...74351150d32aff4866352757ac69b4eecc6b245b
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20220810/5256af83/attachment-0001.html>


More information about the ghc-commits mailing list