From 851772e134e1606561b51117df634b0b7cc53a3c Mon Sep 17 00:00:00 2001 From: Matthew Pickering Date: Thu, 3 Oct 2024 16:02:44 +0100 Subject: [PATCH 1/2] 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 1972e9d903f..c12fb7b2427 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 00000000000..9ede8b27d4f --- /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 00000000000..687cf16bc0c --- /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 00000000000..e657c4403f6 --- /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 00000000000..62632c53766 --- /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 00000000000..642b418a547 --- /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 00000000000..a4f2a1d65d7 --- /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 00000000000..dd4531599e4 --- /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 00000000000..9a96e47a1e9 --- /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`. + +} From 7c25fcb305663f5b26950b50f4d336a0a9f5afbe Mon Sep 17 00:00:00 2001 From: Rodrigo Mesquita Date: Mon, 7 Oct 2024 14:28:19 +0100 Subject: [PATCH 2/2] Fix build ways for foreign libs Patches the component build ways for foreign library components. --- Cabal/src/Distribution/Simple/GHC/Build.hs | 29 ++++++++++--------- .../PackageTests/ProfShared/setup.test.hs | 4 +-- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/Cabal/src/Distribution/Simple/GHC/Build.hs b/Cabal/src/Distribution/Simple/GHC/Build.hs index c12fb7b2427..0993e916886 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 (compilerBuildWay, 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) @@ -113,21 +113,24 @@ 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 + let wantedWays@(wantedLibWays, wantedFLibWay, wantedExeWay) = buildWays lbi -- 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) + 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). @@ -141,7 +144,7 @@ build numJobs pkg_descr pbci = do | otherwise -> (Nothing, Just mainFile) Nothing -> (Nothing, Nothing) - buildOpts <- buildHaskellModules numJobs ghcProg hsMainFile inputModules buildTargetDir finalLibBuildWays 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/ProfShared/setup.test.hs b/cabal-testsuite/PackageTests/ProfShared/setup.test.hs index 84fcbd47e57..54147e34575 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)