Commit 8d2229ab authored by Edward Z. Yang's avatar Edward Z. Yang Committed by Edward Z. Yang
Browse files

Track source files of dependencies so we rebuild as necessary.



The fix is a bit of a hack but it seems to work.

Fixes #4202.
Signed-off-by: default avatarEdward Z. Yang <ezyang@cs.stanford.edu>
parent 6c2eba7f
......@@ -1073,9 +1073,10 @@ buildInplaceUnpackedPackage verbosity
| otherwise
-> listSimple
let dep_monitors = map monitorFileHashed (elabInplaceDependencyBuildCacheFiles pkg)
updatePackageBuildFileMonitor packageFileMonitor srcdir timestamp
pkg buildStatus
monitors buildResult
(monitors ++ dep_monitors) buildResult
-- PURPOSELY omitted: no copy!
......
......@@ -1314,6 +1314,8 @@ elaborateInstallPlan verbosity platform compiler compilerprogdb pkgConfigDB
external_lib_dep_sids = CD.select (== compSolverName) deps0
external_lib_dep_pkgs = concatMap (elaborateLibSolverId' mapDep) external_lib_dep_sids
compInplaceDependencyBuildCacheFiles
= concatMap (elaborateLibBuildCacheFile mapDep) external_lib_dep_sids
external_exe_dep_sids = CD.select (== compSolverName) exe_deps0
external_cc_map = Map.fromList (map mkPkgNameMapping external_lib_dep_pkgs)
external_lc_map = Map.fromList (map mkShapeMapping external_lib_dep_pkgs)
......@@ -1359,6 +1361,24 @@ elaborateInstallPlan verbosity platform compiler compilerprogdb pkgConfigDB
-> SolverId -> [ConfiguredId]
elaborateLibSolverId mapDep = map configuredId . elaborateLibSolverId' mapDep
elaborateLibBuildCacheFile :: (SolverId -> [ElaboratedPlanPackage])
-> SolverId -> [FilePath]
elaborateLibBuildCacheFile mapDep = concatMap get_cache_file . mapDep
where
get_cache_file (InstallPlan.PreExisting _) = []
get_cache_file (InstallPlan.Installed elab) = go elab
get_cache_file (InstallPlan.Configured elab) = go elab
go elab
| elabBuildStyle elab == BuildInplaceOnly
, case elabPkgOrComp elab of
ElabPackage _ -> True
ElabComponent comp -> compSolverName comp == CD.ComponentLib
= [ distPackageCacheFile
(elabDistDirParams elaboratedSharedConfig elab)
"build" ]
| otherwise = []
elaborateExeSolverId :: (SolverId -> [ElaboratedPlanPackage])
-> SolverId -> [ConfiguredId]
elaborateExeSolverId mapDep = map configuredId . filter is_exe . mapDep
......@@ -1420,6 +1440,7 @@ elaborateInstallPlan verbosity platform compiler compilerprogdb pkgConfigDB
}
deps = fmap (concatMap (elaborateLibSolverId mapDep)) deps0
pkgInplaceDependencyBuildCacheFiles = fmap (concatMap (elaborateLibBuildCacheFile mapDep)) deps0
requires_reg = PD.hasPublicLib elabPkgDescription
pkgInstalledId
......@@ -2191,7 +2212,8 @@ pruneInstallPlanPass2 pkgs =
pkgStanzasEnabled = stanzas,
pkgLibDependencies = CD.filterDeps keepNeeded (pkgLibDependencies pkg),
pkgExeDependencies = CD.filterDeps keepNeeded (pkgExeDependencies pkg),
pkgExeDependencyPaths = CD.filterDeps keepNeeded (pkgExeDependencyPaths pkg)
pkgExeDependencyPaths = CD.filterDeps keepNeeded (pkgExeDependencyPaths pkg),
pkgInplaceDependencyBuildCacheFiles = CD.filterDeps keepNeeded (pkgInplaceDependencyBuildCacheFiles pkg)
}
r@(ElabComponent _) -> r
}
......
......@@ -21,6 +21,7 @@ module Distribution.Client.ProjectPlanning.Types (
elabOrderExeDependencies,
elabSetupDependencies,
elabPkgConfigDependencies,
elabInplaceDependencyBuildCacheFiles,
elabPlanPackageName,
elabConfiguredName,
......@@ -408,6 +409,32 @@ elabPkgConfigDependencies ElaboratedConfiguredPackage { elabPkgOrComp = ElabPack
elabPkgConfigDependencies ElaboratedConfiguredPackage { elabPkgOrComp = ElabComponent comp }
= compPkgConfigDependencies comp
-- | The cache files of all our inplace dependencies which,
-- when updated, require us to rebuild. See #4202 for
-- more details. Essentially, this is a list of filepaths
-- that, if our dependencies get rebuilt, will themselves
-- get updated.
--
-- Note: the hash of these cache files gets built into
-- the build cache ourselves, which means that we end
-- up tracking transitive dependencies!
--
-- Note: This tracks the "build" cache file, but not
-- "registration" or "config" cache files. Why not?
-- Arguably we should...
--
-- Note: This is a bit of a hack, because it is not really
-- the hashes of the SOURCES of our (transitive) dependencies
-- that we should use to decide whether or not to rebuild,
-- but the output BUILD PRODUCTS. The strategy we use
-- here will never work if we want to implement unchanging
-- rebuilds.
elabInplaceDependencyBuildCacheFiles :: ElaboratedConfiguredPackage -> [FilePath]
elabInplaceDependencyBuildCacheFiles ElaboratedConfiguredPackage { elabPkgOrComp = ElabPackage pkg }
= CD.flatDeps (pkgInplaceDependencyBuildCacheFiles pkg)
elabInplaceDependencyBuildCacheFiles ElaboratedConfiguredPackage { elabPkgOrComp = ElabComponent comp }
= compInplaceDependencyBuildCacheFiles comp
-- | Some extra metadata associated with an
-- 'ElaboratedConfiguredPackage' which indicates that the "package"
-- in question is actually a single component to be built. Arguably
......@@ -446,7 +473,8 @@ data ElaboratedComponent
compNonSetupDependencies :: [UnitId],
-- | The setup dependencies. TODO: Remove this when setups
-- are components of their own.
compSetupDependencies :: [ConfiguredId]
compSetupDependencies :: [ConfiguredId],
compInplaceDependencyBuildCacheFiles :: [FilePath]
}
deriving (Eq, Show, Generic)
......@@ -491,6 +519,8 @@ data ElaboratedPackage
--
pkgPkgConfigDependencies :: [(PkgconfigName, Maybe Version)],
pkgInplaceDependencyBuildCacheFiles :: ComponentDeps [FilePath],
-- | Which optional stanzas (ie testsuites, benchmarks) will actually
-- be enabled during the package configure step.
pkgStanzasEnabled :: Set OptionalStanza
......
......@@ -4,12 +4,11 @@ import Control.Monad.IO.Class
-- https://github.com/haskell/setup/issues/3294
main = setupAndCabalTest $ do
withDelay $ do
cwd <- fmap testCurrentDir getTestEnv
liftIO $ writeFile (cwd </> "Main.hs") "main = putStrLn \"aaa\""
writeSourceFile "Main.hs" "main = putStrLn \"aaa\""
setup "configure" []
setup "build" []
runExe' "T3294" [] >>= assertOutputContains "aaa"
delay
liftIO $ writeFile (cwd </> "Main.hs") "main = putStrLn \"bbb\""
writeSourceFile "Main.hs" "main = putStrLn \"bbb\""
setup "build" []
runExe' "T3294" [] >>= assertOutputContains "bbb"
import Test.Cabal.Prelude
main = cabalTest $
withDelay $ do
writeSourceFile ("p/P.hs") "module P where\np = \"AAA\""
cabal "new-build" ["p","q"]
delay
writeSourceFile ("p/P.hs") "module P where\np = \"BBB\""
cabal "new-build" ["p"]
cabal "new-build" ["q"]
withPlan $
runPlanExe' "q" "qexe" []
>>= assertOutputContains "BBB"
name: p
version: 1.0
build-type: Simple
cabal-version: >= 1.10
library
exposed-modules: P
build-depends: base
default-language: Haskell2010
name: q
version: 1.0
build-type: Simple
cabal-version: >= 1.10
executable qexe
main-is: Q.hs
build-depends: base, p
default-language: Haskell2010
......@@ -683,3 +683,8 @@ withSymlink oldpath newpath0 act = do
bracket_ (liftIO $ createSymbolicLink oldpath newpath)
(liftIO $ removeFile newpath) act
#endif
writeSourceFile :: FilePath -> String -> TestM ()
writeSourceFile fp s = do
cwd <- fmap testCurrentDir getTestEnv
liftIO $ writeFile (cwd </> fp) s
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment