diff --git a/Cabal/src/Distribution/Simple/GHC/Build.hs b/Cabal/src/Distribution/Simple/GHC/Build.hs
index 1972e9d903fa5b4e02c2bdf05166e4eac5f23f27..0993e916886c614541990d368e7ce5b7d0ef1251 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, withDynFLib)
 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,25 @@ build numJobs pkg_descr pbci = do
 
   (ghcProg, _) <- liftIO $ requireProgram verbosity ghcProgram (withPrograms lbi)
 
-  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 wanted from configuration flags
+  let wantedWays@(wantedLibWays, wantedFLibWay, wantedExeWay) = buildWays lbi
+
+  -- Ways which are needed due to the compiler configuration
+  let doingTH = usesTemplateHaskellOrQQ bi
+      defaultGhcWay = compilerBuildWay (buildCompiler pbci)
+      wantedModBuildWays = case buildComponent pbci of
+        CLib _ -> wantedLibWays isIndef
+        CFLib fl -> [wantedFLibWay (withDynFLib fl)]
+        CExe _ -> [wantedExeWay]
+        CTest _ -> [wantedExeWay]
+        CBench _ -> [wantedExeWay]
+      finalModBuildWays =
+        wantedModBuildWays
+          ++ [defaultGhcWay | doingTH && defaultGhcWay `notElem` wantedModBuildWays]
+      compNameStr = showComponentName $ componentName $ buildComponent pbci
+
+  liftIO $ info verbosity ("Wanted module build ways(" ++ compNameStr ++ "): " ++ show wantedModBuildWays)
+  liftIO $ info verbosity ("Final module build ways(" ++ compNameStr ++ "): " ++ show finalModBuildWays)
   -- 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 +144,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 finalModBuildWays 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 0000000000000000000000000000000000000000..9ede8b27d4fdf20cd364a580ce14738dd1705dda
--- /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 0000000000000000000000000000000000000000..687cf16bc0c84f23df536875b82197a47a824b2a
--- /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 0000000000000000000000000000000000000000..e657c4403f66f966da13d2027bf595d9673387f6
--- /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 0000000000000000000000000000000000000000..62632c537666c4ccdb07c000a030a8ad1f32b863
--- /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 0000000000000000000000000000000000000000..642b418a54709c1a59b18061e658dddd818ddeb1
--- /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 0000000000000000000000000000000000000000..a4f2a1d65d74d5f1624202dca4929933799c813d
--- /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 0000000000000000000000000000000000000000..dd4531599e435dc796673e540ff45fda20bfa4dd
--- /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/cabal-testsuite/PackageTests/ProfShared/setup.test.hs b/cabal-testsuite/PackageTests/ProfShared/setup.test.hs
index 84fcbd47e57d88a3b114a423a211415f492c17d9..54147e34575dab1d891e6096a9d86e607f6b6fb5 100644
--- a/cabal-testsuite/PackageTests/ProfShared/setup.test.hs
+++ b/cabal-testsuite/PackageTests/ProfShared/setup.test.hs
@@ -16,8 +16,8 @@ main = do
 
           let ls = lines (resultOutput r)
 
-              library_prefix = "Wanted build ways(True): "
-              executable_prefix = "Wanted build ways(False): "
+              library_prefix = "Wanted module build ways(library): "
+              executable_prefix = "Wanted module build ways(executable 'Prof'): "
 
               get_ways prefix = map (drop (length prefix)) (filter (prefix `isPrefixOf`) ls)
               library_ways = read_ways (get_ways library_prefix)
diff --git a/changelog.d/i10418 b/changelog.d/i10418
new file mode 100644
index 0000000000000000000000000000000000000000..9a96e47a1e92ec2735f3cee5a9860f8f8f66118b
--- /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`.
+
+}