Skip to content

Commit b9f35ab

Browse files
authored
Merge pull request #6343 from theobat/package-component-build
Support for public sublibrary dependencies
2 parents b270c00 + 5f4ec45 commit b9f35ab

24 files changed

+644
-434
lines changed

.stan.toml

+14-10
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
id = "OBS-STAN-0102-luLR/n-522:30"
2929
# ✦ Category: #Infinite #List
3030
# ✦ File: src\Stack\New.hs
31+
#
3132
# 522 ┃
3233
# 523 ┃ let isPkgSpec f = ".cabal" `L.isSuffixOf` f || "package.yaml" `L.isSuffixOf` f
3334
# 524 ┃ ^^^^^^^^^^^^^^
@@ -38,6 +39,7 @@
3839
id = "OBS-STAN-0102-luLR/n-522:65"
3940
# ✦ Category: #Infinite #List
4041
# ✦ File: src\Stack\New.hs
42+
#
4143
# 522 ┃
4244
# 523 ┃ let isPkgSpec f = ".cabal" `L.isSuffixOf` f || "package.yaml" `L.isSuffixOf` f
4345
# 524 ┃ ^^^^^^^^^^^^^^
@@ -52,31 +54,33 @@
5254

5355
# Anti-pattern: Data.ByteString.Char8.pack
5456
[[ignore]]
55-
id = "OBS-STAN-0203-fki0nd-1124:21"
57+
id = "OBS-STAN-0203-fki0nd-1128:21"
5658
# ✦ Description: Usage of 'pack' function that doesn't handle Unicode characters
57-
# ✦ Category: #AntiPattern
58-
# ✦ File: src\Stack\Build\Execute.hs
59+
# ✦ Category: #AntiPattern
60+
# ✦ File: src\Stack\Build\Execute.hs
5961
#
60-
# 1122
61-
# 1123 ┃ newProjectRoot <- S8.pack . toFilePath <$> view projectRootL
62-
# 1124 ┃ ^^^^^^^
62+
# 1127
63+
# 1128 ┃ newProjectRoot <- S8.pack . toFilePath <$> view projectRootL
64+
# 1129 ┃ ^^^^^^^
6365

6466
# Anti-pattern: Data.ByteString.Char8.pack
6567
[[ignore]]
66-
id = "OBS-STAN-0203-fki0nd-2668:3"
68+
id = "OBS-STAN-0203-fki0nd-2672:3"
6769
# ✦ Description: Usage of 'pack' function that doesn't handle Unicode characters
6870
# ✦ Category: #AntiPattern
6971
# ✦ File: src\Stack\Build\Execute.hs
70-
# 2673 ┃
71-
# 2674 ┃ S8.pack . formatTime defaultTimeLocale "%Y-%m-%dT%H:%M:%S%6Q"
72-
# 2675 ┃ ^^^^^^^
72+
#
73+
# 2671 ┃
74+
# 2672 ┃ S8.pack . formatTime defaultTimeLocale "%Y-%m-%dT%H:%M:%S%6Q"
75+
# 2673 ┃ ^^^^^^^
7376

7477
# Anti-pattern: Data.ByteString.Char8.pack
7578
[[ignore]]
7679
id = "OBS-STAN-0203-hTeu0Y-380:17"
7780
# ✦ Description: Usage of 'pack' function that doesn't handle Unicode characters
7881
# ✦ Category: #AntiPattern
7982
# ✦ File: src\Stack\Init.hs
83+
#
8084
# 378 ┃
8185
# 379 ┃ commentHelp = BC.pack . intercalate "\n" . map commentLine
8286
# 380 ┃ ^^^^^^^

ChangeLog.md

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
Release notes:
66

7+
* After an upgrade from an earlier version of Stack, on first use only,
8+
Stack 2.14.0 may warn that it had trouble loading the CompilerPaths cache.
79
* The hash used as a key for Stack's pre-compiled package cache has changed,
810
following the dropping of support for Cabal versions older than `1.24.0.0`.
911

@@ -28,6 +30,8 @@ Behavior changes:
2830
Other enhancements:
2931

3032
* Consider GHC 9.8 to be a tested compiler and remove warnings.
33+
* Stack can build packages with dependencies on public sub-libraries of other
34+
packages.
3135
* Add flag `--no-init` to Stack's `new` command to skip the initialisation of
3236
the newly-created project for use with Stack.
3337
* The HTML file paths produced at the end of `stack haddock` are printed on

doc/maintainers/stack_errors.md

+3-2
Original file line numberDiff line numberDiff line change
@@ -375,14 +375,15 @@ to take stock of the errors that Stack itself can raise, by reference to the
375375
- `Stack.Types.Build.BuildPrettyException`
376376

377377
~~~haskell
378-
[S-4804] | ConstructPlanFailed [ConstructPlanException] (Path Abs File) (Path Abs Dir) ParentMap (Set PackageName) (Map PackageName [PackageName])
378+
[S-4804] = ConstructPlanFailed [ConstructPlanException] (Path Abs File) (Path Abs Dir) ParentMap (Set PackageName) (Map PackageName [PackageName])
379379
[S-7282] | ExecutionFailure [SomeException]
380380
[S-7011] | CabalExitedUnsuccessfully ExitCode PackageIdentifier (Path Abs File) [String] (Maybe (Path Abs File)) [Text]
381381
[S-6374] | SetupHsBuildFailure ExitCode (Maybe PackageIdentifier) (Path Abs File) [String] (Maybe (Path Abs File)) [Text]
382382
[S-8506] | TargetParseException [StyleDoc]
383383
[S-7086] | SomeTargetsNotBuildable [(PackageName, NamedComponent)]
384384
[S-8664] | InvalidFlagSpecification (Set UnusedFlags)
385-
[S-8100] = GHCProfOptionInvalid
385+
[S-8100] | GHCProfOptionInvalid
386+
[S-1727] | NotOnlyLocal [PackageName] [Text]
386387
~~~
387388

388389
- `Stack.Types.Compiler.CompilerException`

package.yaml

+2
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ library:
265265
- Stack.Types.ApplyGhcOptions
266266
- Stack.Types.ApplyProgOptions
267267
- Stack.Types.Build
268+
- Stack.Types.Build.ConstructPlan
268269
- Stack.Types.Build.Exception
269270
- Stack.Types.BuildConfig
270271
- Stack.Types.BuildOpts
@@ -277,6 +278,7 @@ library:
277278
- Stack.Types.CompilerPaths
278279
- Stack.Types.Compiler
279280
- Stack.Types.Component
281+
- Stack.Types.ComponentUtils
280282
- Stack.Types.Config
281283
- Stack.Types.Config.Exception
282284
- Stack.Types.ConfigMonoid

src/Stack/Build.hs

+5-38
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
{-# LANGUAGE NoImplicitPrelude #-}
2-
{-# LANGUAGE LambdaCase #-}
32
{-# LANGUAGE OverloadedStrings #-}
43

54
-- | Build the project.
@@ -19,8 +18,8 @@ import Data.List.Extra ( groupSort )
1918
import qualified Data.Map as Map
2019
import qualified Data.Set as Set
2120
import qualified Data.Text as T
22-
import qualified Distribution.PackageDescription as C
23-
import Distribution.Types.Dependency ( Dependency (..), depLibraries )
21+
-- import qualified Distribution.PackageDescription as C
22+
-- import Distribution.Types.Dependency ( Dependency (..), depLibraries )
2423
import Distribution.Version ( mkVersion )
2524
import RIO.NonEmpty ( nonEmpty )
2625
import qualified RIO.NonEmpty as NE
@@ -63,11 +62,12 @@ import Stack.Types.GlobalOpts ( globalOptsBuildOptsMonoidL )
6362
import Stack.Types.NamedComponent ( exeComponents )
6463
import Stack.Types.Package
6564
( InstallLocation (..), LocalPackage (..), Package (..)
66-
, PackageConfig (..), lpFiles, lpFilesForComponents )
65+
, PackageConfig (..), lpFiles, lpFilesForComponents
66+
)
6767
import Stack.Types.Platform ( HasPlatform (..) )
6868
import Stack.Types.Runner ( Runner, globalOptsL )
6969
import Stack.Types.SourceMap
70-
( CommonPackage (..), ProjectPackage (..), SMTargets (..)
70+
( SMTargets (..)
7171
, SourceMap (..), Target (..) )
7272
import System.Terminal ( fixCodePage )
7373

@@ -138,8 +138,6 @@ build msetLocalFiles = do
138138
depsLocals <- localDependencies
139139
let allLocals = locals <> depsLocals
140140

141-
checkSubLibraryDependencies (Map.elems $ smProject sourceMap)
142-
143141
boptsCli <- view $ envConfigL.to envConfigBuildOptsCLI
144142
-- Set local files, necessary for file watching
145143
stackYaml <- view stackYamlL
@@ -371,34 +369,3 @@ checkComponentsBuildable lps =
371369
| lp <- lps
372370
, c <- Set.toList (lpUnbuildable lp)
373371
]
374-
375-
-- | Find if any sub-library dependency (other than internal libraries) exists
376-
-- in each project package.
377-
checkSubLibraryDependencies :: HasTerm env => [ProjectPackage] -> RIO env ()
378-
checkSubLibraryDependencies projectPackages =
379-
forM_ projectPackages $ \projectPackage -> do
380-
C.GenericPackageDescription pkgDesc _ _ lib subLibs foreignLibs exes tests benches <-
381-
liftIO $ cpGPD . ppCommon $ projectPackage
382-
383-
let pName = pkgName . C.package $ pkgDesc
384-
dependencies = concatMap getDeps subLibs <>
385-
concatMap getDeps foreignLibs <>
386-
concatMap getDeps exes <>
387-
concatMap getDeps tests <>
388-
concatMap getDeps benches <>
389-
maybe [] C.condTreeConstraints lib
390-
notInternal (Dependency pName' _ _) = pName' /= pName
391-
publicDependencies = filter notInternal dependencies
392-
publicLibraries = concatMap (toList . depLibraries) publicDependencies
393-
394-
when (subLibDepExist publicLibraries) $
395-
prettyWarnS
396-
"Sublibrary dependency is not supported, this will almost certainly \
397-
\fail."
398-
where
399-
getDeps (_, C.CondNode _ dep _) = dep
400-
subLibDepExist = any
401-
( \case
402-
C.LSubLibName _ -> True
403-
C.LMainLibName -> False
404-
)

src/Stack/Build/Cache.hs

+37-30
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,8 @@ import Stack.Types.EnvConfig
7272
)
7373
import Stack.Types.GhcPkgId ( GhcPkgId, ghcPkgIdString )
7474
import Stack.Types.NamedComponent ( NamedComponent (..) )
75+
import Stack.Types.Package
76+
(InstalledLibraryInfo (..), installedGhcPkgId )
7577
import Stack.Types.SourceMap ( smRelDir )
7678
import System.PosixCompat.Files
7779
( modificationTime, getFileStatus, setFileTimes )
@@ -262,14 +264,11 @@ flagCacheKey :: (HasEnvConfig env) => Installed -> RIO env ConfigCacheKey
262264
flagCacheKey installed = do
263265
installationRoot <- installationRootLocal
264266
case installed of
265-
Library _ gid _ ->
266-
pure $
267-
configCacheKey installationRoot (ConfigCacheTypeFlagLibrary gid)
268-
Executable ident ->
269-
pure $
270-
configCacheKey
271-
installationRoot
272-
(ConfigCacheTypeFlagExecutable ident)
267+
Library _ installedInfo -> do
268+
let gid = iliId installedInfo
269+
pure $ configCacheKey installationRoot (ConfigCacheTypeFlagLibrary gid)
270+
Executable ident -> pure $
271+
configCacheKey installationRoot (ConfigCacheTypeFlagExecutable ident)
273272

274273
-- | Loads the flag cache for the given installed extra-deps
275274
tryGetFlagCache :: HasEnvConfig env
@@ -378,28 +377,36 @@ writePrecompiledCache ::
378377
-> [GhcPkgId] -- ^ sub-libraries, in the GhcPkgId format
379378
-> Set Text -- ^ executables
380379
-> RIO env ()
381-
writePrecompiledCache baseConfigOpts loc copts buildHaddocks mghcPkgId subLibs exes = do
382-
key <- getPrecompiledCacheKey loc copts buildHaddocks
383-
ec <- view envConfigL
384-
let stackRootRelative = makeRelative (view stackRootL ec)
385-
mlibpath <- case mghcPkgId of
386-
Executable _ -> pure Nothing
387-
Library _ ipid _ -> Just <$> pathFromPkgId stackRootRelative ipid
388-
subLibPaths <- mapM (pathFromPkgId stackRootRelative) subLibs
389-
exes' <- forM (Set.toList exes) $ \exe -> do
390-
name <- parseRelFile $ T.unpack exe
391-
stackRootRelative $ bcoSnapInstallRoot baseConfigOpts </> bindirSuffix </> name
392-
let precompiled = PrecompiledCache
393-
{ pcLibrary = mlibpath
394-
, pcSubLibs = subLibPaths
395-
, pcExes = exes'
396-
}
397-
savePrecompiledCache key precompiled
398-
-- reuse precompiled cache with haddocks also in case when haddocks are not
399-
-- required
400-
when buildHaddocks $ do
401-
key' <- getPrecompiledCacheKey loc copts False
402-
savePrecompiledCache key' precompiled
380+
writePrecompiledCache
381+
baseConfigOpts
382+
loc
383+
copts
384+
buildHaddocks
385+
mghcPkgId
386+
subLibs
387+
exes
388+
= do
389+
key <- getPrecompiledCacheKey loc copts buildHaddocks
390+
ec <- view envConfigL
391+
let stackRootRelative = makeRelative (view stackRootL ec)
392+
mlibpath <-
393+
traverse (pathFromPkgId stackRootRelative) (installedGhcPkgId mghcPkgId)
394+
subLibPaths <- mapM (pathFromPkgId stackRootRelative) subLibs
395+
exes' <- forM (Set.toList exes) $ \exe -> do
396+
name <- parseRelFile $ T.unpack exe
397+
stackRootRelative $
398+
bcoSnapInstallRoot baseConfigOpts </> bindirSuffix </> name
399+
let precompiled = PrecompiledCache
400+
{ pcLibrary = mlibpath
401+
, pcSubLibs = subLibPaths
402+
, pcExes = exes'
403+
}
404+
savePrecompiledCache key precompiled
405+
-- reuse precompiled cache with haddocks also in case when haddocks are
406+
-- not required
407+
when buildHaddocks $ do
408+
key' <- getPrecompiledCacheKey loc copts False
409+
savePrecompiledCache key' precompiled
403410
where
404411
pathFromPkgId stackRootRelative ipid = do
405412
ipid' <- parseRelFile $ ghcPkgIdString ipid ++ ".conf"

0 commit comments

Comments
 (0)