Skip to content

Commit

Permalink
Cabal custom-setup support
Browse files Browse the repository at this point in the history
  • Loading branch information
snoyberg committed Dec 21, 2016
1 parent 014d261 commit c42b7b3
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 16 deletions.
4 changes: 4 additions & 0 deletions ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ Other enhancements:
* `stack build` and related commands now allow the user to disable debug symbol stripping
with new `--no-strip`, `--no-library-stripping`, and `--no-executable-shipping` flags,
closing [#877](https://github.com/commercialhaskell/stack/issues/877).
* Respects the `custom-setup` field introduced in Cabal 1.24. This
supercedes any `explicit-setup-deps` setings in your `stack.yaml`
and trusts the package's `.cabal` file to explicitly state all its
dependencies.

Bug fixes:

Expand Down
5 changes: 5 additions & 0 deletions doc/yaml_configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,11 @@ explicit-setup-deps:
entropy: false # override the new default for one package
```

NOTE: since 1.4.0, Stack has support for Cabal's `custom-setup` block
(introduced in Cabal 1.24). If a `custom-setup` block is provided in a `.cabal`
file, it will override the setting of `explicit-setup-deps`, and instead rely
on the stated dependencies.

### allow-newer

(Since 0.1.7)
Expand Down
64 changes: 49 additions & 15 deletions src/Stack/Build/Execute.hs
Original file line number Diff line number Diff line change
Expand Up @@ -933,29 +933,58 @@ withSingleContext runInBase ActionContext {..} ExecuteEnv {..} task@Task {..} md
["-package=" ++ packageIdentifierString
(PackageIdentifier cabalPackageName
eeCabalPkgVer)]
packageArgs =
case mdeps of
packageDBArgs =
( "-clear-package-db"
: "-global-package-db"
: map (("-package-db=" ++) . toFilePathNoTrailingSep) (bcoExtraDBs eeBaseConfigOpts)
) ++
( ("-package-db=" ++ toFilePathNoTrailingSep (bcoSnapDB eeBaseConfigOpts))
: ("-package-db=" ++ toFilePathNoTrailingSep (bcoLocalDB eeBaseConfigOpts))
: ["-hide-all-packages"]
)

getPackageArgs =
case (packageSetupDeps package, mdeps) of
-- The package is using the Cabal custom-setup
-- configuraiton introduced in Cabal 1.24. In
-- this case, the package is providing an
-- explicit list of dependencies, and we
-- should simply use all of them.
(Just customSetupDeps, _) -> do
allDeps <-
case mdeps of
Just x -> return x
Nothing -> do
$logWarn "In getPackageArgs: custom-setup in use, but no dependency map present"
return Map.empty
depsArgs <- forM (Map.toList customSetupDeps) $ \(name, range) -> do
let matches (PackageIdentifier name' version) =
name == name' &&
version `withinRange` range
case map snd (filter (matches . fst) (Map.toList allDeps)) of
x:xs -> do
unless (null xs)
($logWarn (T.pack ("Found multiple installed packages for custom-setup dep: " ++ packageNameString name)))
return ("-package-id=" ++ ghcPkgIdString x)
[] -> do
$logWarn (T.pack ("Could not find custom-setup dep: " ++ packageNameString name))
return ("--package=" ++ packageNameString name)
return (packageDBArgs ++ depsArgs)

-- This branch is taken when
-- 'explicit-setup-deps' is requested in your
-- stack.yaml file.
Just deps | explicitSetupDeps (packageName package) config ->
(Nothing, Just deps) | explicitSetupDeps (packageName package) config ->
-- Stack always builds with the global Cabal for various
-- reproducibility issues.
let depsMinusCabal
= map ghcPkgIdString
$ Set.toList
$ addGlobalPackages deps (Map.elems eeGlobalDumpPkgs)
in
( "-clear-package-db"
: "-global-package-db"
: map (("-package-db=" ++) . toFilePathNoTrailingSep) (bcoExtraDBs eeBaseConfigOpts)
) ++
( ("-package-db=" ++ toFilePathNoTrailingSep (bcoSnapDB eeBaseConfigOpts))
: ("-package-db=" ++ toFilePathNoTrailingSep (bcoLocalDB eeBaseConfigOpts))
: ["-hide-all-packages"]
) ++
in return (
packageDBArgs ++
cabalPackageArg ++
map ("-package-id=" ++) depsMinusCabal
map ("-package-id=" ++) depsMinusCabal)
-- This branch is usually taken for builds, and
-- is always taken for `stack sdist`.
--
Expand All @@ -973,12 +1002,16 @@ withSingleContext runInBase ActionContext {..} ExecuteEnv {..} task@Task {..} md
-- Currently, this branch is only taken via `stack
-- sdist` or when explicitly requested in the
-- stack.yaml file.
_ ->
(Nothing, _) -> return (
cabalPackageArg ++
-- NOTE: This is different from
-- packageDBArgs above inthat it does not
-- include the local database and does not
-- pass in the -hide-all-packages argument
("-clear-package-db"
: "-global-package-db"
: map (("-package-db=" ++) . toFilePathNoTrailingSep) (bcoExtraDBs eeBaseConfigOpts)
++ ["-package-db=" ++ toFilePathNoTrailingSep (bcoSnapDB eeBaseConfigOpts)])
++ ["-package-db=" ++ toFilePathNoTrailingSep (bcoSnapDB eeBaseConfigOpts)]))

setupArgs = ("--builddir=" ++ toFilePathNoTrailingSep distRelativeDir') : args
runExe exeName fullArgs =
Expand Down Expand Up @@ -1027,6 +1060,7 @@ withSingleContext runInBase ActionContext {..} ExecuteEnv {..} task@Task {..} md
case compiler of
Ghc -> getGhcPath
Ghcjs -> getGhcjsPath
packageArgs <- getPackageArgs
runExe compilerPath $
[ "--make"
, "-odir", toFilePathNoTrailingSep setupDir
Expand Down
13 changes: 12 additions & 1 deletion src/Stack/Package.hs
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ packageFromPackageDescription packageConfig gpkg pkg =
(not . null . exposedModules)
(library pkg)
, packageSimpleType = buildType pkg == Just Simple
, packageSetupDeps = msetupDeps
}
where
pkgFiles = GetPackageFiles $
Expand Down Expand Up @@ -271,7 +272,17 @@ packageFromPackageDescription packageConfig gpkg pkg =
return (componentModules, componentFiles, buildFiles <> dataFiles', warnings)
pkgId = package pkg
name = fromCabalPackageName (pkgName pkgId)
deps = M.filterWithKey (const . (/= name)) (packageDependencies pkg)
deps = M.filterWithKey (const . (/= name)) (M.union
(packageDependencies pkg)
-- We include all custom-setup deps - if present - in the
-- package deps themselves. Stack always works with the
-- invariant that there will be a single installed package
-- relating to a package name, and this applies at the setup
-- dependency level as well.
(fromMaybe M.empty msetupDeps))
msetupDeps = fmap
(M.fromList . map (depName &&& depRange) . setupDepends)
(setupBuildInfo pkg)

-- | Generate GHC options for the package's components, and a list of
-- options which apply generally to the package, not one specific
Expand Down
2 changes: 2 additions & 0 deletions src/Stack/Types/Package.hs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ data Package =
,packageOpts :: !GetPackageOpts -- ^ Args to pass to GHC.
,packageHasExposedModules :: !Bool -- ^ Does the package have exposed modules?
,packageSimpleType :: !Bool -- ^ Does the package of build-type: Simple
,packageSetupDeps :: !(Maybe (Map PackageName VersionRange))
-- ^ If present: custom-setup dependencies
}
deriving (Show,Typeable)

Expand Down
3 changes: 3 additions & 0 deletions src/test/Stack/GhciSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,7 @@ packages_singlePackage =
, packageOpts = GetPackageOpts undefined
, packageHasExposedModules = True
, packageSimpleType = True
, packageSetupDeps = Nothing
}
}
]
Expand Down Expand Up @@ -255,6 +256,7 @@ packages_multiplePackages =
, packageOpts = GetPackageOpts undefined
, packageHasExposedModules = True
, packageSimpleType = True
, packageSetupDeps = Nothing
}
}
, GhciPkgInfo
Expand Down Expand Up @@ -285,6 +287,7 @@ packages_multiplePackages =
, packageOpts = GetPackageOpts undefined
, packageHasExposedModules = True
, packageSimpleType = True
, packageSetupDeps = Nothing
}
}
]

0 comments on commit c42b7b3

Please sign in to comment.