From 851772e134e1606561b51117df634b0b7cc53a3c Mon Sep 17 00:00:00 2001
From: Matthew Pickering <matthewtpickering@gmail.com>
Date: Thu, 3 Oct 2024 16:02:44 +0100
Subject: [PATCH] Cabal: Take into account compilerBuildWay when computing
 final library ways

In the profiling dynamic patch I made a mistake when computing the
needed ways for a build.

When building an executable, the Haskell modules need to be built

* For the final link way
* For the build way of the compiler if TH is enabled

Before this patch, the modules were being built for all the configured
library ways, which built modules in more configurations than the
previous version of Cabal.

Fixes #10418

(cherry picked from commit 27c266884265dc50804673eaa273d60e57eeeb91)
---
 Cabal/src/Distribution/Simple/GHC/Build.hs    | 20 ++++++++++++++++---
 .../PackageTests/BuildWays/p/CHANGELOG.md     |  5 +++++
 .../PackageTests/BuildWays/p/p.cabal          | 18 +++++++++++++++++
 .../PackageTests/BuildWays/p/src/MyLib.hs     |  4 ++++
 .../PackageTests/BuildWays/q/CHANGELOG.md     |  5 +++++
 .../PackageTests/BuildWays/q/app/Main.hs      |  7 +++++++
 .../PackageTests/BuildWays/q/q.cabal          | 19 ++++++++++++++++++
 .../PackageTests/BuildWays/setup.test.hs      | 10 ++++++++++
 changelog.d/i10418                            | 13 ++++++++++++
 9 files changed, 98 insertions(+), 3 deletions(-)
 create mode 100644 cabal-testsuite/PackageTests/BuildWays/p/CHANGELOG.md
 create mode 100644 cabal-testsuite/PackageTests/BuildWays/p/p.cabal
 create mode 100644 cabal-testsuite/PackageTests/BuildWays/p/src/MyLib.hs
 create mode 100644 cabal-testsuite/PackageTests/BuildWays/q/CHANGELOG.md
 create mode 100644 cabal-testsuite/PackageTests/BuildWays/q/app/Main.hs
 create mode 100644 cabal-testsuite/PackageTests/BuildWays/q/q.cabal
 create mode 100644 cabal-testsuite/PackageTests/BuildWays/setup.test.hs
 create mode 100644 changelog.d/i10418

diff --git a/Cabal/src/Distribution/Simple/GHC/Build.hs b/Cabal/src/Distribution/Simple/GHC/Build.hs
index 1972e9d903..c12fb7b242 100644
--- a/Cabal/src/Distribution/Simple/GHC/Build.hs
+++ b/Cabal/src/Distribution/Simple/GHC/Build.hs
@@ -12,7 +12,7 @@ import Distribution.Simple.Flag (Flag)
 import Distribution.Simple.GHC.Build.ExtraSources
 import Distribution.Simple.GHC.Build.Link
 import Distribution.Simple.GHC.Build.Modules
-import Distribution.Simple.GHC.Build.Utils (isHaskell)
+import Distribution.Simple.GHC.Build.Utils (compilerBuildWay, isHaskell)
 import Distribution.Simple.LocalBuildInfo
 import Distribution.Simple.Program.Builtin (ghcProgram)
 import Distribution.Simple.Program.Db (requireProgram)
@@ -73,6 +73,7 @@ build numJobs pkg_descr pbci = do
     verbosity = buildVerbosity pbci
     isLib = buildIsLib pbci
     lbi = localBuildInfo pbci
+    bi = buildBI pbci
     clbi = buildCLBI pbci
     isIndef = componentIsIndefinite clbi
     mbWorkDir = mbWorkDirLBI lbi
@@ -111,9 +112,22 @@ build numJobs pkg_descr pbci = do
 
   (ghcProg, _) <- liftIO $ requireProgram verbosity ghcProgram (withPrograms lbi)
 
+  -- Ways which are wanted from configuration flags
   let wantedWays@(wantedLibWays, _, wantedExeWay) = buildWays lbi
 
-  liftIO $ info verbosity ("Wanted build ways(" ++ show isLib ++ "): " ++ show (if isLib then wantedLibWays isIndef else [wantedExeWay]))
+  -- Ways which are needed due to the compiler configuration
+  let doingTH = usesTemplateHaskellOrQQ bi
+      defaultGhcWay = compilerBuildWay (buildCompiler pbci)
+      wantedLibBuildWays =
+        if isLib
+          then wantedLibWays isIndef
+          else [wantedExeWay]
+      finalLibBuildWays =
+        wantedLibBuildWays
+          ++ [defaultGhcWay | doingTH && defaultGhcWay `notElem` wantedLibBuildWays]
+
+  liftIO $ info verbosity ("Wanted build ways(" ++ show isLib ++ "): " ++ show wantedLibBuildWays)
+  liftIO $ info verbosity ("Final lib build ways(" ++ show isLib ++ "): " ++ show finalLibBuildWays)
   -- We need a separate build and link phase, and C sources must be compiled
   -- after Haskell modules, because C sources may depend on stub headers
   -- generated from compiling Haskell modules (#842, #3294).
@@ -127,7 +141,7 @@ build numJobs pkg_descr pbci = do
             | otherwise ->
                 (Nothing, Just mainFile)
           Nothing -> (Nothing, Nothing)
-  buildOpts <- buildHaskellModules numJobs ghcProg hsMainFile inputModules buildTargetDir (wantedLibWays isIndef) pbci
+  buildOpts <- buildHaskellModules numJobs ghcProg hsMainFile inputModules buildTargetDir finalLibBuildWays pbci
   extraSources <- buildAllExtraSources nonHsMainFile ghcProg buildTargetDir wantedWays pbci
   linkOrLoadComponent
     ghcProg
diff --git a/cabal-testsuite/PackageTests/BuildWays/p/CHANGELOG.md b/cabal-testsuite/PackageTests/BuildWays/p/CHANGELOG.md
new file mode 100644
index 0000000000..9ede8b27d4
--- /dev/null
+++ b/cabal-testsuite/PackageTests/BuildWays/p/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Revision history for p
+
+## 0.1.0.0 -- YYYY-mm-dd
+
+* First version. Released on an unsuspecting world.
diff --git a/cabal-testsuite/PackageTests/BuildWays/p/p.cabal b/cabal-testsuite/PackageTests/BuildWays/p/p.cabal
new file mode 100644
index 0000000000..687cf16bc0
--- /dev/null
+++ b/cabal-testsuite/PackageTests/BuildWays/p/p.cabal
@@ -0,0 +1,18 @@
+cabal-version:   3.12
+name:            p
+version:         0.1.0.0
+license:         NONE
+author:          Matthew Pickering
+maintainer:      matthewtpickering@gmail.com
+build-type:      Simple
+extra-doc-files: CHANGELOG.md
+
+common warnings
+    ghc-options: -Wall
+
+library
+    import:           warnings
+    exposed-modules:  MyLib
+    build-depends:    base
+    hs-source-dirs:   src
+    default-language: Haskell2010
diff --git a/cabal-testsuite/PackageTests/BuildWays/p/src/MyLib.hs b/cabal-testsuite/PackageTests/BuildWays/p/src/MyLib.hs
new file mode 100644
index 0000000000..e657c4403f
--- /dev/null
+++ b/cabal-testsuite/PackageTests/BuildWays/p/src/MyLib.hs
@@ -0,0 +1,4 @@
+module MyLib (someFunc) where
+
+someFunc :: IO ()
+someFunc = putStrLn "someFunc"
diff --git a/cabal-testsuite/PackageTests/BuildWays/q/CHANGELOG.md b/cabal-testsuite/PackageTests/BuildWays/q/CHANGELOG.md
new file mode 100644
index 0000000000..62632c5376
--- /dev/null
+++ b/cabal-testsuite/PackageTests/BuildWays/q/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Revision history for q
+
+## 0.1.0.0 -- YYYY-mm-dd
+
+* First version. Released on an unsuspecting world.
diff --git a/cabal-testsuite/PackageTests/BuildWays/q/app/Main.hs b/cabal-testsuite/PackageTests/BuildWays/q/app/Main.hs
new file mode 100644
index 0000000000..642b418a54
--- /dev/null
+++ b/cabal-testsuite/PackageTests/BuildWays/q/app/Main.hs
@@ -0,0 +1,7 @@
+{-# LANGUAGE TemplateHaskell #-}
+module Main where
+
+import MyLib
+
+main :: IO ()
+main = someFunc
diff --git a/cabal-testsuite/PackageTests/BuildWays/q/q.cabal b/cabal-testsuite/PackageTests/BuildWays/q/q.cabal
new file mode 100644
index 0000000000..a4f2a1d65d
--- /dev/null
+++ b/cabal-testsuite/PackageTests/BuildWays/q/q.cabal
@@ -0,0 +1,19 @@
+cabal-version:   3.12
+name:            q
+version:         0.1.0.0
+license:         NONE
+author:          Matthew Pickering
+maintainer:      matthewtpickering@gmail.com
+build-type:      Simple
+extra-doc-files: CHANGELOG.md
+
+common warnings
+    ghc-options: -Wall
+
+executable q
+    import:           warnings
+    main-is:          Main.hs
+    build-depends:    p, base
+    hs-source-dirs:   app
+    ghc-options: -dynamic-too
+    default-language: Haskell2010
diff --git a/cabal-testsuite/PackageTests/BuildWays/setup.test.hs b/cabal-testsuite/PackageTests/BuildWays/setup.test.hs
new file mode 100644
index 0000000000..dd4531599e
--- /dev/null
+++ b/cabal-testsuite/PackageTests/BuildWays/setup.test.hs
@@ -0,0 +1,10 @@
+import Test.Cabal.Prelude
+
+opts = ["--enable-shared", "--enable-library-vanilla", "--enable-library-profiling"]
+
+-- See #10418
+main = setupTest $ recordMode DoNotRecord $ withPackageDb $ do
+    skipIfNoSharedLibraries
+    skipIfNoProfiledLibraries
+    withDirectory "p" $ setup_install opts
+    withDirectory "q" $ setup_install opts
diff --git a/changelog.d/i10418 b/changelog.d/i10418
new file mode 100644
index 0000000000..9a96e47a1e
--- /dev/null
+++ b/changelog.d/i10418
@@ -0,0 +1,13 @@
+synopsis: Fix build ways for modules in executables
+packages: Cabal
+prs: #10419
+issues: #10418
+significance: significant
+
+description: {
+
+- Modules belonging to executables were being built in too many ways. For instance, if you
+had configured to build profiled library files then your executable modules would also
+be built profiled. Which was a regression in behaviour since `Cabal-3.12`.
+
+}
-- 
GitLab