Skip to content

Commit c9c3af4

Browse files
committed
Add support for --one-shot flag, partial fix to haskell#2775 (haskell#3287)
--one-shot lets you compile a single component without building its dependencies. Signed-off-by: Edward Z. Yang <[email protected]>
1 parent bca8c06 commit c9c3af4

File tree

7 files changed

+82
-5
lines changed

7 files changed

+82
-5
lines changed

Cabal/Cabal.cabal

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ extra-source-files:
8080
tests/PackageTests/BuildDeps/TargetSpecificDeps3/MyLibrary.hs
8181
tests/PackageTests/BuildDeps/TargetSpecificDeps3/lemon.hs
8282
tests/PackageTests/BuildDeps/TargetSpecificDeps3/my.cabal
83+
tests/PackageTests/BuildOneShot/BuildOneShot.cabal
8384
tests/PackageTests/BuildTestSuiteDetailedV09/Dummy2.hs
8485
tests/PackageTests/BuildableField/BuildableField.cabal
8586
tests/PackageTests/BuildableField/Main.hs

Cabal/Distribution/Simple/Build.hs

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -75,10 +75,36 @@ build :: PackageDescription -- ^ Mostly information from the .cabal file
7575
-> BuildFlags -- ^ Flags that the user passed to build
7676
-> [ PPSuffixHandler ] -- ^ preprocessors to run before compiling
7777
-> IO ()
78-
build pkg_descr lbi flags suffixes = do
79-
let distPref = fromFlag (buildDistPref flags)
80-
verbosity = fromFlag (buildVerbosity flags)
81-
78+
build pkg_descr lbi flags suffixes
79+
| fromFlag (buildOneShot flags) = do
80+
-- TODO: if checkBuildTargets ignores a target we may accept
81+
-- a --one-shot with multiple arguments. Arguably, we should
82+
-- error early in this case.
83+
targets <- readBuildTargets pkg_descr (buildArgs flags)
84+
(cname, _) <- checkBuildTargets verbosity pkg_descr targets >>= \r -> case r of
85+
[] -> die "In --one-shot mode you must specify a target"
86+
[target'] -> return target'
87+
_ -> die "In --one-shot mode you can only build a single target"
88+
-- NB: do NOT 'createInternalPackageDB'; we don't want to delete it.
89+
-- But this means we have to be careful about unregistering
90+
-- ourselves.
91+
let dbPath = internalPackageDBPath lbi distPref
92+
internalPackageDB = SpecificPackageDB dbPath
93+
clbi = getComponentLocalBuildInfo lbi cname
94+
comp = getComponent pkg_descr cname
95+
-- TODO: do we need to unregister libraries? In any case, this would
96+
-- need to be done in the buildLib functionality.
97+
-- Do the build
98+
initialBuildSteps distPref pkg_descr lbi clbi verbosity
99+
let bi = componentBuildInfo comp
100+
progs' = addInternalBuildTools pkg_descr lbi bi (withPrograms lbi)
101+
lbi' = lbi {
102+
withPrograms = progs',
103+
withPackageDB = withPackageDB lbi ++ [internalPackageDB]
104+
}
105+
buildComponent verbosity (buildNumJobs flags) pkg_descr
106+
lbi' suffixes comp clbi distPref
107+
| otherwise = do
82108
targets <- readBuildTargets pkg_descr (buildArgs flags)
83109
targets' <- checkBuildTargets verbosity pkg_descr targets
84110
let componentsToBuild = componentsInBuildOrder lbi (map fst targets')
@@ -102,6 +128,9 @@ build pkg_descr lbi flags suffixes = do
102128
}
103129
buildComponent verbosity (buildNumJobs flags) pkg_descr
104130
lbi' suffixes comp clbi distPref
131+
where
132+
distPref = fromFlag (buildDistPref flags)
133+
verbosity = fromFlag (buildVerbosity flags)
105134

106135

107136
repl :: PackageDescription -- ^ Mostly information from the .cabal file
@@ -188,7 +217,7 @@ buildComponent verbosity numJobs pkg_descr lbi suffixes
188217
installedPkgInfo = inplaceInstalledPackageInfo pwd distPref pkg_descr
189218
(AbiHash "") lib' lbi clbi
190219

191-
registerPackage verbosity (compiler lbi) (withPrograms lbi) HcPkg.MultiInstance
220+
registerPackage verbosity (compiler lbi) (withPrograms lbi) HcPkg.NoMultiInstance
192221
(withPackageDB lbi) installedPkgInfo
193222

194223
buildComponent verbosity numJobs pkg_descr lbi suffixes

Cabal/Distribution/Simple/Setup.hs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1444,6 +1444,9 @@ data BuildFlags = BuildFlags {
14441444
buildDistPref :: Flag FilePath,
14451445
buildVerbosity :: Flag Verbosity,
14461446
buildNumJobs :: Flag (Maybe Int),
1447+
-- | If this is true, we don't build the dependencies of
1448+
-- 'buildArgs': only the directly referenced components.
1449+
buildOneShot :: Flag Bool,
14471450
-- TODO: this one should not be here, it's just that the silly
14481451
-- UserHooks stop us from passing extra info in other ways
14491452
buildArgs :: [String]
@@ -1461,6 +1464,7 @@ defaultBuildFlags = BuildFlags {
14611464
buildDistPref = mempty,
14621465
buildVerbosity = Flag normal,
14631466
buildNumJobs = mempty,
1467+
buildOneShot = Flag False,
14641468
buildArgs = []
14651469
}
14661470

@@ -1508,6 +1512,11 @@ buildOptions :: ProgramConfiguration -> ShowOrParseArgs
15081512
buildOptions progConf showOrParseArgs =
15091513
[ optionNumJobs
15101514
buildNumJobs (\v flags -> flags { buildNumJobs = v })
1515+
1516+
, option "" ["one-shot"]
1517+
"One-shot build"
1518+
buildOneShot (\c flags -> flags { buildOneShot = c })
1519+
trueArg
15111520
]
15121521

15131522
++ programConfigurationPaths progConf showOrParseArgs
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.hs
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
-- Initial BuildOneShot.cabal generated by cabal init. For further
2+
-- documentation, see http://haskell.org/cabal/users-guide/
3+
4+
name: BuildOneShot
5+
version: 0.1.0.0
6+
license: BSD3
7+
author: Edward Z. Yang
8+
maintainer: [email protected]
9+
build-type: Simple
10+
cabal-version: >=1.10
11+
12+
library
13+
exposed-modules: A
14+
build-depends: base
15+
reexported-modules: A as B
16+
default-language: Haskell2010
17+
18+
executable one-shot
19+
main-is: Main.hs
20+
hs-source-dirs: one-shot
21+
build-depends: BuildOneShot, base
22+
default-language: Haskell2010
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
*.hs

Cabal/tests/PackageTests/Tests.hs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -378,6 +378,20 @@ tests config = do
378378
runExe' "hello-world" []
379379
>>= assertOutputContains "hello from A"
380380

381+
-- Test build --one-shot
382+
tc "BuildOneShot" $ do
383+
pkg_dir <- packageDir
384+
liftIO $ writeFile (pkg_dir </> "A.hs") "module A where\na = \"a1\""
385+
liftIO $ writeFile (pkg_dir </> "one-shot/Main.hs") "import A\nmain = print (a ++ \" b1\")"
386+
cabal_build []
387+
runExe' "one-shot" []
388+
>>= assertOutputContains "a1 b1"
389+
liftIO $ writeFile (pkg_dir </> "A.hs") "module A where\na = \"a2\""
390+
liftIO $ writeFile (pkg_dir </> "one-shot/Main.hs") "import A\nmain = print (a ++ \" b2\")"
391+
cabal "build" ["--one-shot", "one-shot"]
392+
runExe' "one-shot" []
393+
>>= assertOutputContains "a1 b2"
394+
381395
where
382396
ghc_pkg_guess bin_name = do
383397
cwd <- packageDir

0 commit comments

Comments
 (0)