Skip to content

Commit eedd07f

Browse files
committed
Accept components to copy in ./Setup copy, fixes #2780.
Signed-off-by: Edward Z. Yang <ezyang@cs.stanford.edu>
1 parent 9200f6f commit eedd07f

File tree

14 files changed

+169
-67
lines changed

14 files changed

+169
-67
lines changed

Cabal/Cabal.cabal

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,15 @@ extra-source-files:
8282
tests/PackageTests/CMain/Bar.hs
8383
tests/PackageTests/CMain/foo.c
8484
tests/PackageTests/CMain/my.cabal
85+
tests/PackageTests/Configure/A.hs
86+
tests/PackageTests/Configure/Setup.hs
87+
tests/PackageTests/Configure/X11.cabal
88+
tests/PackageTests/CopyComponent/Exe/Main.hs
89+
tests/PackageTests/CopyComponent/Exe/Main2.hs
90+
tests/PackageTests/CopyComponent/Exe/myprog.cabal
91+
tests/PackageTests/CopyComponent/Lib/Main.hs
92+
tests/PackageTests/CopyComponent/Lib/p.cabal
93+
tests/PackageTests/CopyComponent/Lib/src/P.hs
8594
tests/PackageTests/DeterministicAr/Lib.hs
8695
tests/PackageTests/DeterministicAr/my.cabal
8796
tests/PackageTests/DuplicateModuleName/DuplicateModuleName.cabal

Cabal/Distribution/Simple.hs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ copyAction hooks flags args = do
305305
flags' = flags { copyDistPref = toFlag distPref }
306306
hookedAction preCopy copyHook postCopy
307307
(getBuildConfig hooks verbosity distPref)
308-
hooks flags' args
308+
hooks flags' { copyArgs = args } args
309309

310310
installAction :: UserHooks -> InstallFlags -> Args -> IO ()
311311
installAction hooks flags args = do
@@ -575,12 +575,9 @@ autoconfUserHooks
575575
= simpleUserHooks
576576
{
577577
postConf = defaultPostConf,
578-
preBuild = \_ flags ->
579-
-- not using 'readHook' here because 'build' takes
580-
-- extra args
581-
getHookedBuildInfo $ fromFlag $ buildVerbosity flags,
578+
preBuild = readHookWithArgs buildVerbosity,
579+
preCopy = readHookWithArgs copyVerbosity,
582580
preClean = readHook cleanVerbosity,
583-
preCopy = readHook copyVerbosity,
584581
preInst = readHook installVerbosity,
585582
preHscolour = readHook hscolourVerbosity,
586583
preHaddock = readHook haddockVerbosity,
@@ -604,6 +601,12 @@ autoconfUserHooks
604601

605602
backwardsCompatHack = False
606603

604+
readHookWithArgs :: (a -> Flag Verbosity) -> Args -> a -> IO HookedBuildInfo
605+
readHookWithArgs get_verbosity _ flags = do
606+
getHookedBuildInfo verbosity
607+
where
608+
verbosity = fromFlag (get_verbosity flags)
609+
607610
readHook :: (a -> Flag Verbosity) -> Args -> a -> IO HookedBuildInfo
608611
readHook get_verbosity a flags = do
609612
noExtraFlags a

Cabal/Distribution/Simple/Build.hs

Lines changed: 1 addition & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ import Distribution.Simple.Compiler hiding (Flag)
3838
import Distribution.PackageDescription hiding (Flag)
3939
import qualified Distribution.InstalledPackageInfo as IPI
4040
import qualified Distribution.ModuleName as ModuleName
41-
import Distribution.ModuleName (ModuleName)
4241

4342
import Distribution.Simple.Setup
4443
import Distribution.Simple.BuildTarget
@@ -57,12 +56,10 @@ import Distribution.Text
5756

5857
import qualified Data.Map as Map
5958
import qualified Data.Set as Set
60-
import Data.Either
61-
( partitionEithers )
6259
import Data.List
6360
( intersect )
6461
import Control.Monad
65-
( when, unless, forM_ )
62+
( when, unless )
6663
import System.FilePath
6764
( (</>), (<.>) )
6865
import System.Directory
@@ -567,48 +564,3 @@ writeAutogenFiles verbosity pkg lbi clbi = do
567564

568565
let cppHeaderPath = autogenModulesDir lbi clbi </> cppHeaderName
569566
rewriteFile cppHeaderPath (Build.Macros.generate pkg lbi clbi)
570-
571-
-- | Check that the given build targets are valid in the current context.
572-
--
573-
-- Also swizzle into a more convenient form.
574-
--
575-
checkBuildTargets :: Verbosity -> PackageDescription -> [BuildTarget]
576-
-> IO [(ComponentName, Maybe (Either ModuleName FilePath))]
577-
checkBuildTargets _ pkg [] =
578-
return [ (componentName c, Nothing) | c <- pkgEnabledComponents pkg ]
579-
580-
checkBuildTargets verbosity pkg targets = do
581-
582-
let (enabled, disabled) =
583-
partitionEithers
584-
[ case componentDisabledReason (getComponent pkg cname) of
585-
Nothing -> Left target'
586-
Just reason -> Right (cname, reason)
587-
| target <- targets
588-
, let target'@(cname,_) = swizzleTarget target ]
589-
590-
case disabled of
591-
[] -> return ()
592-
((cname,reason):_) -> die $ formatReason (showComponentName cname) reason
593-
594-
forM_ [ (c, t) | (c, Just t) <- enabled ] $ \(c, t) ->
595-
warn verbosity $ "Ignoring '" ++ either display id t ++ ". The whole "
596-
++ showComponentName c ++ " will be built. (Support for "
597-
++ "module and file targets has not been implemented yet.)"
598-
599-
return enabled
600-
601-
where
602-
swizzleTarget (BuildTargetComponent c) = (c, Nothing)
603-
swizzleTarget (BuildTargetModule c m) = (c, Just (Left m))
604-
swizzleTarget (BuildTargetFile c f) = (c, Just (Right f))
605-
606-
formatReason cn DisabledComponent =
607-
"Cannot build the " ++ cn ++ " because the component is marked "
608-
++ "as disabled in the .cabal file."
609-
formatReason cn DisabledAllTests =
610-
"Cannot build the " ++ cn ++ " because test suites are not "
611-
++ "enabled. Run configure with the flag --enable-tests"
612-
formatReason cn DisabledAllBenchmarks =
613-
"Cannot build the " ++ cn ++ " because benchmarks are not "
614-
++ "enabled. Re-run configure with the flag --enable-benchmarks"

Cabal/Distribution/Simple/BuildTarget.hs

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,17 @@ module Distribution.Simple.BuildTarget (
2929
resolveBuildTargets,
3030
BuildTargetProblem(..),
3131
reportBuildTargetProblems,
32+
33+
-- * Checking build targets
34+
checkBuildTargets
3235
) where
3336

3437
import Distribution.PackageDescription
3538
import Distribution.ModuleName
3639
import Distribution.Simple.LocalBuildInfo
3740
import Distribution.Text
3841
import Distribution.Simple.Utils
42+
import Distribution.Verbosity
3943

4044
import Distribution.Compat.Binary (Binary)
4145
import qualified Distribution.Compat.ReadP as Parse
@@ -937,3 +941,49 @@ matchInexactly cannonicalise xs =
937941

938942
caseFold :: String -> String
939943
caseFold = lowercase
944+
945+
946+
-- | Check that the given build targets are valid in the current context.
947+
--
948+
-- Also swizzle into a more convenient form.
949+
--
950+
checkBuildTargets :: Verbosity -> PackageDescription -> [BuildTarget]
951+
-> IO [(ComponentName, Maybe (Either ModuleName FilePath))]
952+
checkBuildTargets _ pkg [] =
953+
return [ (componentName c, Nothing) | c <- pkgEnabledComponents pkg ]
954+
955+
checkBuildTargets verbosity pkg targets = do
956+
957+
let (enabled, disabled) =
958+
partitionEithers
959+
[ case componentDisabledReason (getComponent pkg cname) of
960+
Nothing -> Left target'
961+
Just reason -> Right (cname, reason)
962+
| target <- targets
963+
, let target'@(cname,_) = swizzleTarget target ]
964+
965+
case disabled of
966+
[] -> return ()
967+
((cname,reason):_) -> die $ formatReason (showComponentName cname) reason
968+
969+
forM_ [ (c, t) | (c, Just t) <- enabled ] $ \(c, t) ->
970+
warn verbosity $ "Ignoring '" ++ either display id t ++ ". The whole "
971+
++ showComponentName c ++ " will be processed. (Support for "
972+
++ "module and file targets has not been implemented yet.)"
973+
974+
return enabled
975+
976+
where
977+
swizzleTarget (BuildTargetComponent c) = (c, Nothing)
978+
swizzleTarget (BuildTargetModule c m) = (c, Just (Left m))
979+
swizzleTarget (BuildTargetFile c f) = (c, Just (Right f))
980+
981+
formatReason cn DisabledComponent =
982+
"Cannot process the " ++ cn ++ " because the component is marked "
983+
++ "as disabled in the .cabal file."
984+
formatReason cn DisabledAllTests =
985+
"Cannot process the " ++ cn ++ " because test suites are not "
986+
++ "enabled. Run configure with the flag --enable-tests"
987+
formatReason cn DisabledAllBenchmarks =
988+
"Cannot process the " ++ cn ++ " because benchmarks are not "
989+
++ "enabled. Re-run configure with the flag --enable-benchmarks"

Cabal/Distribution/Simple/Install.hs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ import Distribution.Simple.Utils
2727
import Distribution.Simple.Compiler
2828
( CompilerFlavor(..), compilerFlavor )
2929
import Distribution.Simple.Setup (CopyFlags(..), fromFlag)
30+
import Distribution.Simple.BuildTarget
3031

3132
import qualified Distribution.Simple.GHC as GHC
3233
import qualified Distribution.Simple.GHCJS as GHCJS
@@ -82,10 +83,14 @@ install pkg_descr lbi flags = do
8283
unless (hasLibs pkg_descr || hasExes pkg_descr) $
8384
die "No executables and no library found. Nothing to do."
8485

86+
targets <- readBuildTargets pkg_descr (copyArgs flags)
87+
targets' <- checkBuildTargets verbosity pkg_descr targets
88+
8589
-- Install (package-global) data files
8690
installDataFiles verbosity pkg_descr dataPref
8791

8892
-- Install (package-global) Haddock files
93+
-- TODO: these should be done per-library
8994
docExists <- doesDirectoryExist $ haddockPref distPref pkg_descr
9095
info verbosity ("directory " ++ haddockPref distPref pkg_descr ++
9196
" does exist: " ++ show docExists)
@@ -117,7 +122,15 @@ install pkg_descr lbi flags = do
117122
[ installOrdinaryFile verbosity lfile (docPref </> takeFileName lfile)
118123
| lfile <- lfiles ]
119124

120-
withLibLBI pkg_descr lbi $ \lib clbi -> do
125+
-- It's not necessary to do these in build-order, but it's harmless
126+
withComponentsInBuildOrder pkg_descr lbi (map fst targets') $ \comp clbi ->
127+
copyComponent verbosity pkg_descr lbi comp clbi copydest
128+
129+
copyComponent :: Verbosity -> PackageDescription
130+
-> LocalBuildInfo -> Component -> ComponentLocalBuildInfo
131+
-> CopyDest
132+
-> IO ()
133+
copyComponent verbosity pkg_descr lbi (CLib lib) clbi copydest = do
121134
let InstallDirs{
122135
libdir = libPref,
123136
includedir = incPref
@@ -149,7 +162,7 @@ install pkg_descr lbi flags = do
149162
++ display (compilerFlavor (compiler lbi))
150163
++ " is not implemented"
151164

152-
withExeLBI pkg_descr lbi $ \exe clbi -> do
165+
copyComponent verbosity pkg_descr lbi (CExe exe) clbi copydest = do
153166
let installDirs@InstallDirs {
154167
bindir = binPref
155168
} = absoluteComponentInstallDirs pkg_descr lbi (componentUnitId clbi) copydest
@@ -175,6 +188,9 @@ install pkg_descr lbi flags = do
175188
++ display (compilerFlavor (compiler lbi))
176189
++ " is not implemented"
177190

191+
-- Nothing to do for benchmark/testsuite
192+
copyComponent _ _ _ _ _ _ = return ()
193+
178194
-- | Install the files listed in data-files
179195
--
180196
installDataFiles :: Verbosity -> PackageDescription -> FilePath -> IO ()

Cabal/Distribution/Simple/Setup.hs

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -829,27 +829,39 @@ instance Semigroup ConfigFlags where
829829
data CopyFlags = CopyFlags {
830830
copyDest :: Flag CopyDest,
831831
copyDistPref :: Flag FilePath,
832-
copyVerbosity :: Flag Verbosity
832+
copyVerbosity :: Flag Verbosity,
833+
-- This is the same hack as in 'buildArgs'. But I (ezyang) don't
834+
-- think it's a hack, it's the right way to make hooks more robust
835+
copyArgs :: [String]
833836
}
834837
deriving Show
835838

836839
defaultCopyFlags :: CopyFlags
837840
defaultCopyFlags = CopyFlags {
838841
copyDest = Flag NoCopyDest,
839842
copyDistPref = NoFlag,
840-
copyVerbosity = Flag normal
843+
copyVerbosity = Flag normal,
844+
copyArgs = []
841845
}
842846

843847
copyCommand :: CommandUI CopyFlags
844848
copyCommand = CommandUI
845849
{ commandName = "copy"
846-
, commandSynopsis = "Copy the files into the install locations."
850+
, commandSynopsis = "Copy the files of all/specific components to install locations."
847851
, commandDescription = Just $ \_ -> wrapText $
848-
"Does not call register, and allows a prefix at install time. "
852+
"Components encompass executables and libraries."
853+
++ "Does not call register, and allows a prefix at install time. "
849854
++ "Without the --destdir flag, configure determines location.\n"
850-
, commandNotes = Nothing
851-
, commandUsage = \pname ->
852-
"Usage: " ++ pname ++ " copy [FLAGS]\n"
855+
, commandNotes = Just $ \pname ->
856+
"Examples:\n"
857+
++ " " ++ pname ++ " build "
858+
++ " All the components in the package\n"
859+
++ " " ++ pname ++ " build foo "
860+
++ " A component (i.e. lib, exe, test suite)"
861+
, commandUsage = usageAlternatives "copy" $
862+
[ "[FLAGS]"
863+
, "COMPONENTS [FLAGS]"
864+
]
853865
, commandDefaultFlags = defaultCopyFlags
854866
, commandOptions = \showOrParseArgs ->
855867
[optionVerbosity copyVerbosity (\v flags -> flags { copyVerbosity = v })
@@ -873,15 +885,17 @@ instance Monoid CopyFlags where
873885
mempty = CopyFlags {
874886
copyDest = mempty,
875887
copyDistPref = mempty,
876-
copyVerbosity = mempty
888+
copyVerbosity = mempty,
889+
copyArgs = mempty
877890
}
878891
mappend = (Semi.<>)
879892

880893
instance Semigroup CopyFlags where
881894
a <> b = CopyFlags {
882895
copyDest = combine copyDest,
883896
copyDistPref = combine copyDistPref,
884-
copyVerbosity = combine copyVerbosity
897+
copyVerbosity = combine copyVerbosity,
898+
copyArgs = combine copyArgs
885899
}
886900
where combine field = field a `mappend` field b
887901

Cabal/Distribution/Simple/UserHooks.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,7 +173,7 @@ emptyUserHooks
173173
preClean = rn,
174174
cleanHook = ru,
175175
postClean = ru,
176-
preCopy = rn,
176+
preCopy = rn',
177177
copyHook = ru,
178178
postCopy = ru,
179179
preInst = rn,
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Main where
2+
3+
main :: IO ()
4+
main = putStrLn "Hello, Haskell!"
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module Main where
2+
3+
main :: IO ()
4+
main = putStrLn "Hello, Haskell!"
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
name: myprog
2+
version: 0.1.0.0
3+
license: BSD3
4+
author: Edward Z. Yang
5+
maintainer: ezyang@cs.stanford.edu
6+
build-type: Simple
7+
cabal-version: >=1.10
8+
9+
executable myprog
10+
main-is: Main.hs
11+
build-depends: base
12+
13+
executable myprog2
14+
main-is: Main2.hs
15+
build-depends: base
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
import P
2+
main = print p
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
name: p
2+
version: 0.1.0.0
3+
license: BSD3
4+
author: Edward Z. Yang
5+
maintainer: ezyang@cs.stanford.edu
6+
build-type: Simple
7+
cabal-version: >=1.10
8+
9+
library
10+
exposed-modules: P
11+
hs-source-dirs: src
12+
build-depends: base
13+
default-language: Haskell2010
14+
15+
executable pprog
16+
main-is: Main.hs
17+
build-depends: p
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
module P where
2+
p = 12

Cabal/tests/PackageTests/Tests.hs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,20 @@ tests config =
272272
-- Test for 'build-type: Configure' example from the Cabal manual.
273273
, tc "Configure" $ cabal_build []
274274

275+
-- Test that per-component copy works, when only building library
276+
, tc "CopyComponent/Lib" $
277+
withPackageDb $ do
278+
cabal "configure" []
279+
cabal "build" ["lib:p"]
280+
cabal "copy" ["lib:p"]
281+
282+
-- Test that per-component copy works, when only building one executable
283+
, tc "CopyComponent/Exe" $
284+
withPackageDb $ do
285+
cabal "configure" []
286+
cabal "build" ["myprog"]
287+
cabal "copy" ["myprog"]
288+
275289
]
276290
where
277291
-- Shared test function for BuildDeps/InternalLibrary* tests.

0 commit comments

Comments
 (0)