Skip to content

Commit 5c2ce7e

Browse files
committed
Fixes spurious recompiles when sublibs are involved in copyPreCompiled
TODO: The integration test fails for this currently. This needs to be fixed before upstreaming.
1 parent 1d4ea5f commit 5c2ce7e

9 files changed

Lines changed: 88 additions & 12 deletions

File tree

src/Stack/Build/ExecutePackage.hs

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -851,17 +851,21 @@ copyPreCompiled ee task pkgId (PrecompiledCache mlib subLibs exes) = do
851851
subLibNames = Set.toList $ buildableSubLibs $ case task.taskType of
852852
TTLocalMutable lp -> lp.package
853853
TTRemotePackage _ p _ -> p
854-
toMungedPackageId :: StackUnqualCompName -> MungedPackageId
855-
toMungedPackageId subLib =
856-
let subLibName = LSubLibName $ toCabalName subLib
857-
in MungedPackageId (MungedPackageName pname subLibName) pversion
858-
toPackageId :: MungedPackageId -> PackageIdentifier
859-
toPackageId (MungedPackageId n v) =
860-
PackageIdentifier (encodeCompatPackageName n) v
854+
-- The sub-library names paired with the munged package names under which
855+
-- they are registered in the package database.
856+
subLibsMungedNames :: [(StackUnqualCompName, PackageName)]
857+
subLibsMungedNames =
858+
let toMungedName subLib =
859+
( subLib
860+
, encodeCompatPackageName $ toCabalMungedPackageName pname subLib
861+
)
862+
in map toMungedName subLibNames
861863
allToUnregister :: [Either PackageIdentifier GhcPkgId]
862864
allToUnregister = mcons
863865
(Left pkgId <$ mlib)
864-
(map (Left . toPackageId . toMungedPackageId) subLibNames)
866+
(map
867+
(\(_, mungedName) -> Left $ PackageIdentifier mungedName pversion)
868+
subLibsMungedNames)
865869
allToRegister = mcons mlib subLibs
866870

867871
unless (null allToRegister) $
@@ -918,10 +922,20 @@ copyPreCompiled ee task pkgId (PrecompiledCache mlib subLibs exes) = do
918922
Just _ -> do
919923
mpkgid <- loadInstalledPkg pkgDbs ee.snapshotDumpPkgs pname
920924

921-
pure $ Just $
922-
case mpkgid of
923-
Nothing -> assert False $ Executable pkgId
924-
Just pkgid -> simpleInstalledLib pkgId pkgid mempty
925+
case mpkgid of
926+
Nothing -> pure $ Just $ assert False $ Executable pkgId
927+
Just pkgid -> do
928+
-- Gather the GhcPkgId values of the sub-libraries registered above,
929+
-- so that the 'Installed' value (and, hence, the config caches of
930+
-- packages that depend on this one) includes them, as it does when
931+
-- the package is built from source (see
932+
-- 'fetchAndMarkInstalledPackage') and when the package is loaded
933+
-- from a package database (see 'Stack.Build.Installed').
934+
subLibsPkgIds <- fmap (Map.fromList . catMaybes) $
935+
forM subLibsMungedNames $ \(subLib, mungedName) -> do
936+
mSubLibPkgId <- loadInstalledPkg pkgDbs ee.snapshotDumpPkgs mungedName
937+
pure $ fmap (\subLibPkgId -> (subLib, subLibPkgId)) mSubLibPkgId
938+
pure $ Just $ simpleInstalledLib pkgId pkgid subLibsPkgIds
925939
where
926940
bindir = ee.baseConfigOpts.snapInstallRoot </> bindirSuffix
927941

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import Control.Monad (unless)
2+
import Data.List (isInfixOf)
3+
import StackTest
4+
5+
-- This tests building a project package (pkg) that depends on an immutable
6+
-- dependency (dep) with both a main library and a sub-library, in the case
7+
-- where the dependency is installed by copying it from the precompiled cache.
8+
-- The dependency is first built from source in the custom1 project. The
9+
-- custom2 project uses a different custom snapshot, so it has a distinct
10+
-- snapshot package database and installs the dependency from the precompiled
11+
-- cache. A subsequent build of the custom2 project should then do no work.
12+
-- Previously, the Cabal configuration cache written for the project package
13+
-- recorded the dependency without the package ids of its sub-libraries, while
14+
-- later builds compared it against a set that included them, causing a
15+
-- spurious "dependencies changed" rebuild.
16+
17+
main :: IO ()
18+
main = do
19+
-- The '--install-ghc' flag is passed here, because IntegrationSpec.runApp
20+
-- sets up `config.yaml` with `system-ghc: true` and `install-ghc: false`.
21+
stack ["build", "--install-ghc", "--stack-yaml", "custom1/stack.yaml", "dep"]
22+
stackCheckStderr ["build", "--stack-yaml", "custom2/stack.yaml"] $ \out ->
23+
unless ("using precompiled package" `isInfixOf` out) $
24+
error "Didn't use precompiled package!"
25+
stackCheckStderr ["build", "--stack-yaml", "custom2/stack.yaml"] $ \out ->
26+
unless (null (compilingModulesLines out)) $
27+
error "Stack recompiled code"
28+
29+
-- Returns the lines where a module is compiled
30+
compilingModulesLines :: String -> [String]
31+
compilingModulesLines = filter (isInfixOf " Compiling ") . lines
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
snapshot: ghc-9.10.3
2+
name: custom1
3+
packages:
4+
- archive: ../dep.tar.gz
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
snapshot: custom1.yaml
2+
packages: []
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
snapshot: ghc-9.10.3
2+
name: custom2
3+
packages:
4+
- archive: ../dep.tar.gz
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
cabal-version: 2.0
2+
name: pkg
3+
version: 0.1.0.0
4+
build-type: Simple
5+
6+
library
7+
hs-source-dirs: src
8+
exposed-modules: Pkg
9+
build-depends: base, dep
10+
default-language: Haskell2010
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
module Pkg
2+
( pkgValue
3+
) where
4+
5+
import Dep ( depValue )
6+
7+
pkgValue :: Int
8+
pkgValue = depValue + 1
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
snapshot: custom2.yaml
2+
packages:
3+
- .
Binary file not shown.

0 commit comments

Comments
 (0)