From 72e655a72035a2072625035d8f1e43dcd8316c38 Mon Sep 17 00:00:00 2001
From: Cheng Shao <terrorjack@type.dance>
Date: Sun, 2 Jun 2024 15:04:26 +0000
Subject: [PATCH] hadrian: add +text_simdutf flavour transformer to allow
 building text with simdutf

This patch adds a +text_simdutf flavour transformer to hadrian to
allow downstream packagers and users that build from source to opt-in
simdutf support for text, in order to benefit from SIMD speedup at
run-time. It's still disabled by default for the time being.

(cherry picked from commit 44e2abfb94fd5afdcd12361e63da5f63ad1b50ef)
---
 hadrian/doc/flavours.md          |  4 ++++
 hadrian/src/Flavour.hs           |  8 ++++++++
 hadrian/src/Flavour/Type.hs      |  4 +++-
 hadrian/src/Rules/Register.hs    |  9 +++++++++
 hadrian/src/Settings/Default.hs  |  1 +
 hadrian/src/Settings/Packages.hs | 10 ++++------
 6 files changed, 29 insertions(+), 7 deletions(-)

diff --git a/hadrian/doc/flavours.md b/hadrian/doc/flavours.md
index 7a3e75cf304..ca7897ba0bd 100644
--- a/hadrian/doc/flavours.md
+++ b/hadrian/doc/flavours.md
@@ -265,6 +265,10 @@ The supported transformers are listed below:
         <td><code>native_bignum</code></td>
         <td>Use the native <code>ghc-bignum</code> backend.</td>
     </tr>
+    <tr>
+        <td><code>text_simdutf</code></td>
+        <td>Enable building the <code>text</code> package with <code>simdutf</code> support.</td>
+    </tr>
     <tr>
         <td><code>no_profiled_libs</code></td>
         <td>Disables building of libraries in profiled build ways.</td>
diff --git a/hadrian/src/Flavour.hs b/hadrian/src/Flavour.hs
index 3a14fc19f21..1c9bc3c1b36 100644
--- a/hadrian/src/Flavour.hs
+++ b/hadrian/src/Flavour.hs
@@ -17,6 +17,7 @@ module Flavour
   , enableHaddock
   , enableHiCore
   , useNativeBignum
+  , enableTextWithSIMDUTF
   , omitPragmas
 
   , completeSetting
@@ -53,6 +54,7 @@ flavourTransformers = M.fromList
     , "no_dynamic_ghc"   =: disableDynamicGhcPrograms
     , "no_dynamic_libs"  =: disableDynamicLibs
     , "native_bignum"    =: useNativeBignum
+    , "text_simdutf"     =: enableTextWithSIMDUTF
     , "no_profiled_libs" =: disableProfiledLibs
     , "omit_pragmas"     =: omitPragmas
     , "ipe"              =: enableIPE
@@ -293,6 +295,12 @@ useNativeBignum flavour =
   flavour { bignumBackend = "native"
           }
 
+-- | Enable building the @text@ package with @simdutf@ support.
+enableTextWithSIMDUTF :: Flavour -> Flavour
+enableTextWithSIMDUTF flavour = flavour {
+  textWithSIMDUTF = True
+}
+
 -- | Build stage2 compiler with -fomit-interface-pragmas to reduce
 -- recompilation.
 omitPragmas :: Flavour -> Flavour
diff --git a/hadrian/src/Flavour/Type.hs b/hadrian/src/Flavour/Type.hs
index a2d0d574676..da2940f076b 100644
--- a/hadrian/src/Flavour/Type.hs
+++ b/hadrian/src/Flavour/Type.hs
@@ -23,6 +23,9 @@ data Flavour = Flavour {
     bignumBackend :: String,
     -- | Check selected bignum backend against native backend
     bignumCheck :: Bool,
+    -- | Build the @text@ package with @simdutf@ support. Disabled by
+    -- default due to packaging difficulties described in #20724.
+    textWithSIMDUTF :: Bool,
     -- | Build libraries these ways.
     libraryWays :: Ways,
     -- | Build RTS these ways.
@@ -67,4 +70,3 @@ type DocTargets = Set DocTarget
 --   distribution.
 data DocTarget = Haddocks | SphinxHTML | SphinxPDFs | SphinxMan | SphinxInfo
   deriving (Eq, Ord, Show, Bounded, Enum)
-
diff --git a/hadrian/src/Rules/Register.hs b/hadrian/src/Rules/Register.hs
index ad2df7c33de..032d747ba04 100644
--- a/hadrian/src/Rules/Register.hs
+++ b/hadrian/src/Rules/Register.hs
@@ -7,6 +7,7 @@ module Rules.Register (
 import Base
 import Context
 import Expression ( getContextData )
+import Flavour
 import Oracles.Setting
 import Hadrian.BuildPath
 import Hadrian.Expression
@@ -51,6 +52,14 @@ configurePackageRules = do
           isGmp <- (== "gmp") <$> interpretInContext ctx getBignumBackend
           when isGmp $
             need [buildP -/- "include/ghc-gmp.h"]
+        when (pkg == text) $ do
+          simdutf <- textWithSIMDUTF <$> flavour
+          when simdutf $ do
+            -- This is required, otherwise you get Error: hadrian:
+            -- Encountered missing or private dependencies:
+            -- system-cxx-std-lib ==1.0
+            cxxStdLib <- systemCxxStdLibConfPath $ PackageDbLoc stage Inplace
+            need [cxxStdLib]
         Cabal.configurePackage ctx
 
     root -/- "**/autogen/cabal_macros.h" %> \out -> do
diff --git a/hadrian/src/Settings/Default.hs b/hadrian/src/Settings/Default.hs
index 192e439c772..1b8e68ad6ab 100644
--- a/hadrian/src/Settings/Default.hs
+++ b/hadrian/src/Settings/Default.hs
@@ -270,6 +270,7 @@ defaultFlavour = Flavour
     , packages           = defaultPackages
     , bignumBackend      = defaultBignumBackend
     , bignumCheck        = False
+    , textWithSIMDUTF    = False
     , libraryWays        = defaultLibraryWays
     , rtsWays            = defaultRtsWays
     , dynamicGhcPrograms = defaultDynamicGhcPrograms
diff --git a/hadrian/src/Settings/Packages.hs b/hadrian/src/Settings/Packages.hs
index 1b37ecbb8f5..be5829015ed 100644
--- a/hadrian/src/Settings/Packages.hs
+++ b/hadrian/src/Settings/Packages.hs
@@ -208,12 +208,10 @@ packageArgs = do
             builder (Cabal Flags) ? stage0 `cabalFlag` "bootstrap"
 
         ---------------------------------- text --------------------------------
-        , package text ? mconcat
-          -- Disable SIMDUTF by default due to packaging difficulties
-          -- described in #20724.
-          [ builder (Cabal Flags) ? arg "-simdutf"
-          -- https://github.com/haskell/text/issues/415
-          , builder Ghc ? input "**/Data/Text/Encoding.hs"  ? arg "-Wno-unused-imports" ]
+        , package text ?
+            ifM (textWithSIMDUTF <$> expr flavour)
+              (builder (Cabal Flags) ? arg "+simdutf")
+              (builder (Cabal Flags) ? arg "-simdutf")
 
         ------------------------------- haskeline ------------------------------
         -- Hadrian doesn't currently support packages containing both libraries
-- 
GitLab