Skip to content

Commit 0b32bfb

Browse files
snoybergborsboom
authored andcommitted
Merge pull request #3955 from mihaimaruseac/mm-stack-internal-libs
Don't recompile in presence of sublibraries (cherry picked from commit a3a8754)
1 parent 811fc7c commit 0b32bfb

File tree

17 files changed

+113
-18
lines changed

17 files changed

+113
-18
lines changed

ChangeLog.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ Behavior changes:
1212
Other enhancements:
1313

1414
Bug fixes:
15+
* When a package contained sublibraries, stack was always recompiling the
16+
package. This has been fixed now, no recompilation is being done because of
17+
sublibraries. See [#3899](https://github.com/commercialhaskell/stack/issues/3899).
1518

1619

1720
## v1.7.0.1 (release candidate)

src/Stack/Build/Cache.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ buildCacheFile dir component = do
120120
let nonLibComponent prefix name = prefix <> "-" <> T.unpack name
121121
cacheFileName <- parseRelFile $ case component of
122122
CLib -> "lib"
123+
CInternalLib name -> nonLibComponent "internal-lib" name
123124
CExe name -> nonLibComponent "exe" name
124125
CTest name -> nonLibComponent "test" name
125126
CBench name -> nonLibComponent "bench" name

src/Stack/Build/Installed.hs

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -230,25 +230,37 @@ isAllowed opts mcache sourceMap mloc dp
230230
| otherwise =
231231
case Map.lookup name sourceMap of
232232
Nothing ->
233-
case mloc of
234-
-- The sourceMap has nothing to say about this global
235-
-- package, so we can use it
236-
Nothing -> Allowed
237-
Just ExtraGlobal -> Allowed
238-
-- For non-global packages, don't include unknown packages.
239-
-- See:
240-
-- https://github.com/commercialhaskell/stack/issues/292
241-
Just _ -> UnknownPkg
242-
Just pii
243-
| not (checkLocation (piiLocation pii)) -> WrongLocation mloc (piiLocation pii)
244-
| version /= piiVersion pii -> WrongVersion version (piiVersion pii)
245-
| otherwise -> Allowed
233+
-- If the sourceMap has nothing to say about this package,
234+
-- check if it represents a sublibrary first
235+
-- See: https://github.com/commercialhaskell/stack/issues/3899
236+
case dpParentLibIdent dp of
237+
Just (PackageIdentifier parentLibName version') ->
238+
case Map.lookup parentLibName sourceMap of
239+
Nothing -> checkNotFound
240+
Just pii
241+
| version' == version -> checkFound pii
242+
| otherwise -> checkNotFound -- different versions
243+
Nothing -> checkNotFound
244+
Just pii -> checkFound pii
246245
where
247246
PackageIdentifier name version = dpPackageIdent dp
248247
-- Ensure that the installed location matches where the sourceMap says it
249248
-- should be installed
250249
checkLocation Snap = mloc /= Just (InstalledTo Local) -- we can allow either global or snap
251250
checkLocation Local = mloc == Just (InstalledTo Local) || mloc == Just ExtraGlobal -- 'locally' installed snapshot packages can come from extra dbs
251+
-- Check if a package is allowed if it is found in the sourceMap
252+
checkFound pii
253+
| not (checkLocation (piiLocation pii)) = WrongLocation mloc (piiLocation pii)
254+
| version /= piiVersion pii = WrongVersion version (piiVersion pii)
255+
| otherwise = Allowed
256+
-- check if a package is allowed if it is not found in the sourceMap
257+
checkNotFound = case mloc of
258+
-- The sourceMap has nothing to say about this global package, so we can use it
259+
Nothing -> Allowed
260+
Just ExtraGlobal -> Allowed
261+
-- For non-global packages, don't include unknown packages.
262+
-- See: https://github.com/commercialhaskell/stack/issues/292
263+
Just _ -> UnknownPkg
252264

253265
data LoadHelper = LoadHelper
254266
{ lhId :: !GhcPkgId

src/Stack/Build/Source.hs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,6 +167,7 @@ splitComponents =
167167
where
168168
go a b c [] = (Set.fromList $ a [], Set.fromList $ b [], Set.fromList $ c [])
169169
go a b c (CLib:xs) = go a b c xs
170+
go a b c (CInternalLib x:xs) = go (a . (x:)) b c xs
170171
go a b c (CExe x:xs) = go (a . (x:)) b c xs
171172
go a b c (CTest x:xs) = go a (b . (x:)) c xs
172173
go a b c (CBench x:xs) = go a b (c . (x:)) xs
@@ -434,9 +435,9 @@ getPackageFilesForTargets
434435
-> Set NamedComponent
435436
-> RIO env (Map NamedComponent (Set (Path Abs File)), [PackageWarning])
436437
getPackageFilesForTargets pkg cabalFP nonLibComponents = do
437-
(_,compFiles,otherFiles,warnings) <-
438+
(components',compFiles,otherFiles,warnings) <-
438439
getPackageFiles (packageFiles pkg) cabalFP
439-
let components = Set.insert CLib nonLibComponents
440+
let components = M.keysSet components' `Set.union` nonLibComponents
440441
componentsFiles =
441442
M.map (\files -> Set.union otherFiles (Set.map dotCabalGetPath files)) $
442443
M.filterWithKey (\component _ -> component `Set.member` components) compFiles

src/Stack/Build/Target.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,7 @@ resolveRawTarget globals snap deps locals (ri, rt) =
230230
-- Helper function: check if a 'NamedComponent' matches the given 'ComponentName'
231231
isCompNamed :: ComponentName -> NamedComponent -> Bool
232232
isCompNamed _ CLib = False
233+
isCompNamed t1 (CInternalLib t2) = t1 == t2
233234
isCompNamed t1 (CExe t2) = t1 == t2
234235
isCompNamed t1 (CTest t2) = t1 == t2
235236
isCompNamed t1 (CBench t2) = t1 == t2

src/Stack/Ghci.hs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -520,6 +520,7 @@ figureOutMainFile bopts mainIsTargets targets0 packages = do
520520
renderComp c =
521521
case c of
522522
CLib -> "lib"
523+
CInternalLib name -> "internal-lib:" <> name
523524
CExe name -> "exe:" <> name
524525
CTest name -> "test:" <> name
525526
CBench name -> "bench:" <> name

src/Stack/Package.hs

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ module Stack.Package
4242
import qualified Data.ByteString as BS
4343
import qualified Data.ByteString.Char8 as C8
4444
import Data.List (isSuffixOf, isPrefixOf)
45+
import Data.Maybe (maybe)
4546
import qualified Data.Map.Strict as M
4647
import qualified Data.Set as S
4748
import qualified Data.Text as T
@@ -589,6 +590,7 @@ componentBuildDir cabalVer component distDir
589590
| otherwise =
590591
case component of
591592
CLib -> buildDir distDir
593+
CInternalLib name -> buildDir distDir </> componentNameToDir name
592594
CExe name -> buildDir distDir </> componentNameToDir name
593595
CTest name -> buildDir distDir </> componentNameToDir name
594596
CBench name -> buildDir distDir </> componentNameToDir name
@@ -598,6 +600,7 @@ componentOutputDir :: NamedComponent -> Path Abs Dir -> Path Abs Dir
598600
componentOutputDir namedComponent distDir =
599601
case namedComponent of
600602
CLib -> buildDir distDir
603+
CInternalLib name -> makeTmp name
601604
CExe name -> makeTmp name
602605
CTest name -> makeTmp name
603606
CBench name -> makeTmp name
@@ -700,6 +703,12 @@ packageDescModulesAndFiles pkg = do
700703
(return (M.empty, M.empty, []))
701704
(asModuleAndFileMap libComponent libraryFiles)
702705
(library pkg)
706+
(subLibrariesMods,subLibDotCabalFiles,subLibWarnings) <-
707+
liftM
708+
foldTuples
709+
(mapM
710+
(asModuleAndFileMap internalLibComponent libraryFiles)
711+
(subLibraries pkg))
703712
(executableMods,exeDotCabalFiles,exeWarnings) <-
704713
liftM
705714
foldTuples
@@ -719,14 +728,15 @@ packageDescModulesAndFiles pkg = do
719728
dfiles <- resolveGlobFiles
720729
(extraSrcFiles pkg
721730
++ map (dataDir pkg FilePath.</>) (dataFiles pkg))
722-
let modules = libraryMods <> executableMods <> testMods <> benchModules
731+
let modules = libraryMods <> subLibrariesMods <> executableMods <> testMods <> benchModules
723732
files =
724-
libDotCabalFiles <> exeDotCabalFiles <> testDotCabalFiles <>
733+
libDotCabalFiles <> subLibDotCabalFiles <> exeDotCabalFiles <> testDotCabalFiles <>
725734
benchDotCabalPaths
726-
warnings = libWarnings <> exeWarnings <> testWarnings <> benchWarnings
735+
warnings = libWarnings <> subLibWarnings <> exeWarnings <> testWarnings <> benchWarnings
727736
return (modules, files, dfiles, warnings)
728737
where
729738
libComponent = const CLib
739+
internalLibComponent = CInternalLib . T.pack . maybe "" Cabal.unUnqualComponentName . libName
730740
exeComponent = CExe . T.pack . Cabal.unUnqualComponentName . exeName
731741
testComponent = CTest . T.pack . Cabal.unUnqualComponentName . testName
732742
benchComponent = CBench . T.pack . Cabal.unUnqualComponentName . benchmarkName

src/Stack/PackageDump.hs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,7 @@ hasDebuggingSymbols dir lib = do
282282
data DumpPackage profiling haddock symbols = DumpPackage
283283
{ dpGhcPkgId :: !GhcPkgId
284284
, dpPackageIdent :: !PackageIdentifier
285+
, dpParentLibIdent :: !(Maybe PackageIdentifier)
285286
, dpLicense :: !(Maybe C.License)
286287
, dpLibDirs :: ![FilePath]
287288
, dpLibraries :: ![Text]
@@ -356,6 +357,11 @@ conduitDumpPackage = (.| CL.catMaybes) $ eachSection $ do
356357
_ -> Nothing
357358
depends <- mapMaybeM parseDepend $ concatMap T.words $ parseM "depends"
358359

360+
-- Handle sublibs by recording the name of the parent library
361+
-- If name of parent library is missing, this is not a sublib.
362+
let mkParentLib n = PackageIdentifier n version
363+
parentLib = mkParentLib <$> (parseS "package-name" >>= parsePackageName)
364+
359365
let parseQuoted key =
360366
case mapM (P.parseOnly (argsParser NoEscaping)) val of
361367
Left{} -> throwM (Couldn'tParseField key val)
@@ -369,6 +375,7 @@ conduitDumpPackage = (.| CL.catMaybes) $ eachSection $ do
369375
return $ Just DumpPackage
370376
{ dpGhcPkgId = ghcPkgId
371377
, dpPackageIdent = PackageIdentifier name version
378+
, dpParentLibIdent = parentLib
372379
, dpLicense = license
373380
, dpLibDirs = libDirPaths
374381
, dpLibraries = T.words $ T.unwords libraries

src/Stack/Types/NamedComponent.hs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,13 +22,15 @@ import qualified Data.Text as T
2222
-- | A single, fully resolved component of a package
2323
data NamedComponent
2424
= CLib
25+
| CInternalLib !Text
2526
| CExe !Text
2627
| CTest !Text
2728
| CBench !Text
2829
deriving (Show, Eq, Ord)
2930

3031
renderComponent :: NamedComponent -> Text
3132
renderComponent CLib = "lib"
33+
renderComponent (CInternalLib x) = "internal-lib:" <> x
3234
renderComponent (CExe x) = "exe:" <> x
3335
renderComponent (CTest x) = "test:" <> x
3436
renderComponent (CBench x) = "bench:" <> x

src/test/Stack/PackageDumpSpec.hs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ spec = do
8181
haskell2010 { dpExposedModules = [] } `shouldBe` DumpPackage
8282
{ dpGhcPkgId = ghcPkgId
8383
, dpPackageIdent = packageIdent
84+
, dpParentLibIdent = Nothing
8485
, dpLicense = Just BSD3
8586
, dpLibDirs = ["/opt/ghc/7.8.4/lib/ghc-7.8.4/haskell2010-1.1.2.0"]
8687
, dpDepends = depends
@@ -124,6 +125,7 @@ spec = do
124125
haskell2010 { dpExposedModules = [] } `shouldBe` DumpPackage
125126
{ dpGhcPkgId = ghcPkgId
126127
, dpPackageIdent = pkgIdent
128+
, dpParentLibIdent = Nothing
127129
, dpLicense = Just BSD3
128130
, dpLibDirs = ["/opt/ghc/7.10.1/lib/ghc-7.10.1/ghc_EMlWrQ42XY0BNVbSrKixqY"]
129131
, dpHaddockInterfaces = ["/opt/ghc/7.10.1/share/doc/ghc/html/libraries/ghc-7.10.1/ghc.haddock"]
@@ -160,6 +162,7 @@ spec = do
160162
hmatrix `shouldBe` DumpPackage
161163
{ dpGhcPkgId = ghcPkgId
162164
, dpPackageIdent = pkgId
165+
, dpParentLibIdent = Nothing
163166
, dpLicense = Just BSD3
164167
, dpLibDirs =
165168
[ "/Users/alexbiehl/.stack/snapshots/x86_64-osx/lts-2.13/7.8.4/lib/x86_64-osx-ghc-7.8.4/hmatrix-0.16.1.5"
@@ -197,6 +200,7 @@ spec = do
197200
ghcBoot `shouldBe` DumpPackage
198201
{ dpGhcPkgId = ghcPkgId
199202
, dpPackageIdent = pkgId
203+
, dpParentLibIdent = Nothing
200204
, dpLicense = Just BSD3
201205
, dpLibDirs =
202206
["/opt/ghc/head/lib/ghc-7.11.20151213/ghc-boot-0.0.0.0"]
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import Control.Monad (unless)
2+
import Data.List (isInfixOf)
3+
import StackTest
4+
5+
main :: IO ()
6+
main = do
7+
stack ["clean"]
8+
stack ["build"]
9+
res <- compilingModulesLines . snd <$> stackStderr ["build"]
10+
unless (null res) $ fail "Stack recompiled code"
11+
12+
-- Returns the lines where a module is compiled
13+
compilingModulesLines :: String -> [String]
14+
compilingModulesLines = filter (isInfixOf " Compiling ") . lines
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import Distribution.Simple
2+
main = defaultMain
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
name: files
2+
version: 0.1.0.0
3+
build-type: Simple
4+
cabal-version: >= 2.0
5+
6+
library
7+
hs-source-dirs: src
8+
exposed-modules: Lib
9+
build-depends: base, lib
10+
default-language: Haskell2010
11+
12+
library lib
13+
hs-source-dirs: src-internal
14+
exposed-modules: Internal
15+
build-depends: base
16+
default-language: Haskell2010
17+
18+
executable exe
19+
hs-source-dirs: src-exe
20+
main-is: Main.hs
21+
build-depends: base, files
22+
default-language: Haskell2010
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
module Main where
2+
3+
import Lib
4+
5+
main :: IO ()
6+
main = do
7+
putStrLn "hello world"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
module Internal where
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
module Lib where
2+
3+
import Internal
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
resolver: ghc-8.2.2
2+
extra-deps:
3+
- stm-2.4.4.1
4+
- mtl-2.2.1

0 commit comments

Comments
 (0)