Skip to content

Commit c891a24

Browse files
committed
Add ghc opts and allow-newer for custom snaps
See #1265, some of the code refactor related to #849 and #863
1 parent 6f108a1 commit c891a24

File tree

20 files changed

+346
-185
lines changed

20 files changed

+346
-185
lines changed

src/Stack/Build.hs

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -273,26 +273,27 @@ withLoadPackage :: ( MonadIO m
273273
, MonadLogger m
274274
, HasEnvConfig env)
275275
=> EnvOverride
276-
-> ((PackageName -> Version -> Map FlagName Bool -> IO Package) -> m a)
276+
-> ((PackageName -> Version -> Map FlagName Bool -> [Text] -> IO Package) -> m a)
277277
-> m a
278278
withLoadPackage menv inner = do
279279
econfig <- asks getEnvConfig
280280
withCabalLoader menv $ \cabalLoader ->
281-
inner $ \name version flags -> do
281+
inner $ \name version flags ghcOptions -> do
282282
bs <- cabalLoader $ PackageIdentifier name version
283283

284284
-- Intentionally ignore warnings, as it's not really
285285
-- appropriate to print a bunch of warnings out while
286286
-- resolving the package index.
287-
(_warnings,pkg) <- readPackageBS (depPackageConfig econfig flags) bs
287+
(_warnings,pkg) <- readPackageBS (depPackageConfig econfig flags ghcOptions) bs
288288
return pkg
289289
where
290290
-- | Package config to be used for dependencies
291-
depPackageConfig :: EnvConfig -> Map FlagName Bool -> PackageConfig
292-
depPackageConfig econfig flags = PackageConfig
291+
depPackageConfig :: EnvConfig -> Map FlagName Bool -> [Text] -> PackageConfig
292+
depPackageConfig econfig flags ghcOptions = PackageConfig
293293
{ packageConfigEnableTests = False
294294
, packageConfigEnableBenchmarks = False
295295
, packageConfigFlags = flags
296+
, packageConfigGhcOptions = ghcOptions
296297
, packageConfigCompilerVersion = envConfigCompilerVersion econfig
297298
, packageConfigPlatform = configPlatform (getConfig econfig)
298299
}

src/Stack/Build/ConstructPlan.hs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ type M = RWST
102102
data Ctx = Ctx
103103
{ mbp :: !MiniBuildPlan
104104
, baseConfigOpts :: !BaseConfigOpts
105-
, loadPackage :: !(PackageName -> Version -> Map FlagName Bool -> IO Package)
105+
, loadPackage :: !(PackageName -> Version -> Map FlagName Bool -> [Text] -> IO Package)
106106
, combinedMap :: !CombinedMap
107107
, toolToPackages :: !(Cabal.Dependency -> Map PackageName VersionRange)
108108
, ctxEnvConfig :: !EnvConfig
@@ -129,7 +129,7 @@ constructPlan :: forall env m.
129129
-> [LocalPackage]
130130
-> Set PackageName -- ^ additional packages that must be built
131131
-> [DumpPackage () ()] -- ^ locally registered
132-
-> (PackageName -> Version -> Map FlagName Bool -> IO Package) -- ^ load upstream package
132+
-> (PackageName -> Version -> Map FlagName Bool -> [Text] -> IO Package) -- ^ load upstream package
133133
-> SourceMap
134134
-> InstalledMap
135135
-> m Plan
@@ -205,7 +205,7 @@ mkUnregisterLocal tasks dirtyReason locallyRegistered sourceMap =
205205
case M.lookup name tasks of
206206
Nothing ->
207207
case M.lookup name sourceMap of
208-
Just (PSUpstream _ Snap _ _) -> Map.singleton gid
208+
Just (PSUpstream _ Snap _ _ _) -> Map.singleton gid
209209
( ident
210210
, Just "Switching to snapshot installed package"
211211
)
@@ -234,7 +234,6 @@ addFinal lp package isAllInOne = do
234234
(getEnvConfig ctx)
235235
(baseConfigOpts ctx)
236236
allDeps
237-
True -- wanted
238237
True -- local
239238
Local
240239
package
@@ -279,14 +278,16 @@ tellExecutables :: PackageName -> PackageSource -> M ()
279278
tellExecutables _ (PSLocal lp)
280279
| lpWanted lp = tellExecutablesPackage Local $ lpPackage lp
281280
| otherwise = return ()
282-
tellExecutables name (PSUpstream version loc flags _) =
281+
-- Ignores ghcOptions because they don't matter for enumerating
282+
-- executables.
283+
tellExecutables name (PSUpstream version loc flags _ghcOptions _gitSha) =
283284
tellExecutablesUpstream name version loc flags
284285

285286
tellExecutablesUpstream :: PackageName -> Version -> InstallLocation -> Map FlagName Bool -> M ()
286287
tellExecutablesUpstream name version loc flags = do
287288
ctx <- ask
288289
when (name `Set.member` extraToBuild ctx) $ do
289-
p <- liftIO $ loadPackage ctx name version flags
290+
p <- liftIO $ loadPackage ctx name version flags []
290291
tellExecutablesPackage loc p
291292

292293
tellExecutablesPackage :: InstallLocation -> Package -> M ()
@@ -319,8 +320,8 @@ installPackage :: Bool -- ^ is this being used by a dependency?
319320
installPackage treatAsDep name ps minstalled = do
320321
ctx <- ask
321322
case ps of
322-
PSUpstream version _ flags _ -> do
323-
package <- liftIO $ loadPackage ctx name version flags
323+
PSUpstream version _ flags ghcOptions _ -> do
324+
package <- liftIO $ loadPackage ctx name version flags ghcOptions
324325
resolveDepsAndInstall False treatAsDep ps package minstalled
325326
PSLocal lp ->
326327
case lpTestBench lp of
@@ -403,7 +404,6 @@ installPackageGivenDeps isAllInOne ps package minstalled (missing, present, minL
403404
(getEnvConfig ctx)
404405
(baseConfigOpts ctx)
405406
allDeps
406-
(psWanted ps)
407407
(psLocal ps)
408408
-- An assertion to check for a recurrence of
409409
-- https://github.com/commercialhaskell/stack/issues/345
@@ -413,7 +413,7 @@ installPackageGivenDeps isAllInOne ps package minstalled (missing, present, minL
413413
, taskType =
414414
case ps of
415415
PSLocal lp -> TTLocal lp
416-
PSUpstream _ loc _ sha -> TTUpstream package (loc <> minLoc) sha
416+
PSUpstream _ loc _ _ sha -> TTUpstream package (loc <> minLoc) sha
417417
, taskAllInOne = isAllInOne
418418
}
419419

@@ -503,7 +503,6 @@ checkDirtiness ps installed package present wanted = do
503503
(getEnvConfig ctx)
504504
(baseConfigOpts ctx)
505505
present
506-
(psWanted ps)
507506
(psLocal ps)
508507
(piiLocation ps) -- should be Local always
509508
package
@@ -599,10 +598,6 @@ psDirty :: PackageSource -> Maybe (Set FilePath)
599598
psDirty (PSLocal lp) = lpDirtyFiles lp
600599
psDirty (PSUpstream {}) = Nothing -- files never change in an upstream package
601600

602-
psWanted :: PackageSource -> Bool
603-
psWanted (PSLocal lp) = lpWanted lp
604-
psWanted (PSUpstream {}) = False
605-
606601
psLocal :: PackageSource -> Bool
607602
psLocal (PSLocal _) = True
608603
psLocal (PSUpstream {}) = False

src/Stack/Build/Source.hs

Lines changed: 102 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,20 @@ module Stack.Build.Source
1111
( loadSourceMap
1212
, SourceMap
1313
, PackageSource (..)
14-
, localFlags
14+
, getLocalFlags
15+
, getGhcOptions
1516
, getLocalPackageViews
16-
, loadLocalPackage
1717
, parseTargetsFromBuildOpts
1818
, addUnlistedToBuildCache
19+
, getDefaultPackageConfig
1920
, getPackageConfig
2021
) where
2122

2223
import Control.Applicative
2324
import Control.Arrow ((&&&))
2425
import Control.Exception (assert, catch)
2526
import Control.Monad
26-
import Control.Monad.Catch (MonadMask)
27+
import Control.Monad.Catch (MonadMask, MonadCatch)
2728
import Control.Monad.IO.Class
2829
import Control.Monad.Logger
2930
import Control.Monad.Reader (MonadReader, asks)
@@ -91,6 +92,7 @@ loadSourceMap needTargets boptsCli = do
9192
locals <- mapM (loadLocalPackage boptsCli targets) $ Map.toList rawLocals
9293
checkFlagsUsed boptsCli locals extraDeps0 (mbpPackages mbp0)
9394
checkComponentsBuildable locals
95+
warnAllowNewer mbp0
9496

9597
let
9698
-- loadLocals returns PackageName (foo) and PackageIdentifier (bar-1.2.3) targets separately;
@@ -111,31 +113,34 @@ loadSourceMap needTargets boptsCli = do
111113
-- Add the extra deps from the stack.yaml file to the deps grabbed from
112114
-- the snapshot
113115
extraDeps2 = Map.union
114-
(Map.map (\v -> (v, Map.empty)) extraDeps0)
115-
(Map.map (mpiVersion &&& mpiFlags) extraDeps1)
116+
(Map.map (\v -> (v, Map.empty, [])) extraDeps0)
117+
(Map.map (\mpi -> (mpiVersion mpi, mpiFlags mpi, mpiGhcOptions mpi)) extraDeps1)
116118

117-
-- Overwrite any flag settings with those from the config file
119+
-- Add flag and ghc-option settings from the config file / cli
118120
extraDeps3 = Map.mapWithKey
119-
(\n (v, f) -> PSUpstream v Local
120-
(case ( Map.lookup (Just n) $ boptsCLIFlags boptsCli
121-
, Map.lookup Nothing $ boptsCLIFlags boptsCli
122-
, Map.lookup n $ bcFlags bconfig
123-
) of
124-
-- Didn't have any flag overrides, fall back to the flags
125-
-- defined in the snapshot.
126-
(Nothing, Nothing, Nothing) -> f
127-
-- Either command line flag for this package, general
128-
-- command line flag, or flag in stack.yaml is defined.
129-
-- Take all of those and ignore the snapshot flags.
130-
(x, y, z) -> Map.unions
131-
[ fromMaybe Map.empty x
132-
, fromMaybe Map.empty y
133-
, fromMaybe Map.empty z
134-
])
135-
121+
(\n (v, flags0, ghcOptions0) ->
122+
let flags =
123+
case ( Map.lookup (Just n) $ boptsCLIFlags boptsCli
124+
, Map.lookup Nothing $ boptsCLIFlags boptsCli
125+
, Map.lookup n $ unPackageFlags $ bcFlags bconfig
126+
) of
127+
-- Didn't have any flag overrides, fall back to the flags
128+
-- defined in the snapshot.
129+
(Nothing, Nothing, Nothing) -> flags0
130+
-- Either command line flag for this package, general
131+
-- command line flag, or flag in stack.yaml is defined.
132+
-- Take all of those and ignore the snapshot flags.
133+
(x, y, z) -> Map.unions
134+
[ fromMaybe Map.empty x
135+
, fromMaybe Map.empty y
136+
, fromMaybe Map.empty z
137+
]
138+
ghcOptions =
139+
ghcOptions0 ++
140+
getGhcOptions bconfig boptsCli n False False
136141
-- currently have no ability for extra-deps to specify their
137142
-- cabal file hashes
138-
Nothing)
143+
in PSUpstream v Local flags ghcOptions Nothing)
139144
extraDeps2
140145

141146
let sourceMap = Map.unions
@@ -144,11 +149,45 @@ loadSourceMap needTargets boptsCli = do
144149
in (packageName p, PSLocal lp)
145150
, extraDeps3
146151
, flip fmap (mbpPackages mbp) $ \mpi ->
147-
PSUpstream (mpiVersion mpi) Snap (mpiFlags mpi) (mpiGitSHA1 mpi)
152+
PSUpstream (mpiVersion mpi) Snap (mpiFlags mpi) (mpiGhcOptions mpi) (mpiGitSHA1 mpi)
148153
] `Map.difference` Map.fromList (map (, ()) (HashSet.toList wiredInPackages))
149154

150155
return (targets, mbp, locals, nonLocalTargets, sourceMap)
151156

157+
-- | All flags for a local package
158+
getLocalFlags
159+
:: BuildConfig
160+
-> BuildOptsCLI
161+
-> PackageName
162+
-> Map FlagName Bool
163+
getLocalFlags bconfig boptsCli name = Map.unions
164+
[ Map.findWithDefault Map.empty (Just name) cliFlags
165+
, Map.findWithDefault Map.empty Nothing cliFlags
166+
, Map.findWithDefault Map.empty name (unPackageFlags (bcFlags bconfig))
167+
]
168+
where
169+
cliFlags = boptsCLIFlags boptsCli
170+
171+
getGhcOptions :: BuildConfig -> BuildOptsCLI -> PackageName -> Bool -> Bool -> [Text]
172+
getGhcOptions bconfig boptsCli name isTarget isLocal = concat
173+
[ ghcOptionsFor name (configGhcOptions config)
174+
, concat [["-fhpc"] | isLocal && toCoverage (boptsTestOpts bopts)]
175+
, if (boptsLibProfile bopts || boptsExeProfile bopts)
176+
then ["-auto-all","-caf-all"]
177+
else []
178+
, if includeExtraOptions
179+
then boptsCLIGhcOptions boptsCli
180+
else []
181+
]
182+
where
183+
bopts = configBuild config
184+
config = bcConfig bconfig
185+
includeExtraOptions =
186+
case configApplyGhcOptions config of
187+
AGOTargets -> isTarget
188+
AGOLocals -> isLocal
189+
AGOEverything -> True
190+
152191
-- | Use the build options and environment to parse targets.
153192
parseTargetsFromBuildOpts
154193
:: (MonadIO m, MonadMask m, MonadReader env m, HasBuildConfig env, MonadBaseControl IO m, HasHttpManager env, MonadLogger m, HasEnvConfig env)
@@ -170,6 +209,7 @@ parseTargetsFromBuildOpts needTargets boptscli = do
170209
return MiniBuildPlan
171210
{ mbpCompilerVersion = version
172211
, mbpPackages = Map.empty
212+
, mbpAllowNewer = False
173213
}
174214
ResolverCustom _ url -> do
175215
stackYamlFP <- asks $ bcStackYaml . getBuildConfig
@@ -285,11 +325,11 @@ loadLocalPackage
285325
-> (PackageName, (LocalPackageView, GenericPackageDescription))
286326
-> m LocalPackage
287327
loadLocalPackage boptsCli targets (name, (lpv, gpkg)) = do
288-
config <- getPackageConfig boptsCli name
328+
let mtarget = Map.lookup name targets
329+
config <- getPackageConfig boptsCli name (isJust mtarget) True
289330
bopts <- asks (configBuild . getConfig)
290331
let pkg = resolvePackage config gpkg
291332

292-
mtarget = Map.lookup name targets
293333
(exes, tests, benches) =
294334
case mtarget of
295335
Just (STLocalComps comps) -> splitComponents $ Set.toList comps
@@ -384,7 +424,7 @@ checkFlagsUsed boptsCli lps extraDeps snapshot = do
384424
-- Check if flags specified in stack.yaml and the command line are
385425
-- used, see https://github.com/commercialhaskell/stack/issues/617
386426
let flags = map (, FSCommandLine) [(k, v) | (Just k, v) <- Map.toList $ boptsCLIFlags boptsCli]
387-
++ map (, FSStackYaml) (Map.toList $ bcFlags bconfig)
427+
++ map (, FSStackYaml) (Map.toList $ unPackageFlags $ bcFlags bconfig)
388428

389429
localNameMap = Map.fromList $ map (packageName . lpPackage &&& lpPackage) lps
390430
checkFlagUsed ((name, userFlags), source) =
@@ -415,17 +455,6 @@ checkFlagsUsed boptsCli lps extraDeps snapshot = do
415455
$ InvalidFlagSpecification
416456
$ Set.fromList unusedFlags
417457

418-
-- | All flags for a local package
419-
localFlags :: Map (Maybe PackageName) (Map FlagName Bool)
420-
-> BuildConfig
421-
-> PackageName
422-
-> Map FlagName Bool
423-
localFlags boptsflags bconfig name = Map.unions
424-
[ Map.findWithDefault Map.empty (Just name) boptsflags
425-
, Map.findWithDefault Map.empty Nothing boptsflags
426-
, Map.findWithDefault Map.empty name (bcFlags bconfig)
427-
]
428-
429458
-- | Add in necessary packages to extra dependencies
430459
--
431460
-- Originally part of https://github.com/commercialhaskell/stack/issues/272,
@@ -568,18 +597,50 @@ checkComponentsBuildable lps =
568597
, c <- Set.toList (lpUnbuildable lp)
569598
]
570599

600+
warnAllowNewer :: (MonadThrow m, MonadLogger m, MonadReader env m, HasConfig env)
601+
=> MiniBuildPlan -> m ()
602+
warnAllowNewer mpb = do
603+
-- TODO: Perhaps we should just have the snapshot setting imply
604+
-- allow-newer? I just didn't want to make 'configAllowNewer'
605+
-- non-authoritative about whether allow-newer is enabled.
606+
allowNewer <- asks (configAllowNewer . getConfig)
607+
when (mbpAllowNewer mpb && not allowNewer) $ do
608+
$logWarn $ T.unlines
609+
[ ""
610+
, "WARNING: The snapshot specifies that allow-newer needs to be used."
611+
, "You should probably add 'allow-newer: true' to suppress this warning."
612+
, ""
613+
]
614+
615+
getDefaultPackageConfig :: (MonadIO m, MonadThrow m, MonadCatch m, MonadLogger m, MonadReader env m, HasEnvConfig env)
616+
=> m PackageConfig
617+
getDefaultPackageConfig = do
618+
econfig <- asks getEnvConfig
619+
bconfig <- asks getBuildConfig
620+
return PackageConfig
621+
{ packageConfigEnableTests = False
622+
, packageConfigEnableBenchmarks = False
623+
, packageConfigFlags = M.empty
624+
, packageConfigGhcOptions = []
625+
, packageConfigCompilerVersion = envConfigCompilerVersion econfig
626+
, packageConfigPlatform = configPlatform $ getConfig bconfig
627+
}
628+
571629
-- | Get 'PackageConfig' for package given its name.
572630
getPackageConfig :: (MonadIO m, MonadThrow m, MonadMask m, MonadLogger m, MonadReader env m, HasEnvConfig env)
573631
=> BuildOptsCLI
574632
-> PackageName
633+
-> Bool
634+
-> Bool
575635
-> m PackageConfig
576-
getPackageConfig boptsCli name = do
636+
getPackageConfig boptsCli name isTarget isLocal = do
577637
econfig <- asks getEnvConfig
578638
bconfig <- asks getBuildConfig
579639
return PackageConfig
580640
{ packageConfigEnableTests = False
581641
, packageConfigEnableBenchmarks = False
582-
, packageConfigFlags = localFlags (boptsCLIFlags boptsCli) bconfig name
642+
, packageConfigFlags = getLocalFlags bconfig boptsCli name
643+
, packageConfigGhcOptions = getGhcOptions bconfig boptsCli name isTarget isLocal
583644
, packageConfigCompilerVersion = envConfigCompilerVersion econfig
584645
, packageConfigPlatform = configPlatform $ getConfig bconfig
585646
}

0 commit comments

Comments
 (0)