Skip to content

Per component copy #3066

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 29 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
900db44
Teach cabal-install IntegrationTests to find dist-newstyle build dire…
ezyang Jan 28, 2016
5f866cb
Simple test for Custom setup scripts.
ezyang Jan 28, 2016
8fb24c5
Remove some dead test-suite code.
ezyang Jan 28, 2016
e408cb0
Add support for providing LBI information by environment variables.
ezyang Jan 28, 2016
90b80c6
Add a custom setup to cabal-install.
ezyang Jan 3, 2016
8fcf9db
Implement "convenience libraries", fixes #269.
ezyang Jan 3, 2016
30f285c
Per-component cabal_macros.h (#1893) and install paths
ezyang Jan 11, 2016
a5f8e25
Do not install/register internal libraries when unnecessary.
ezyang Jan 12, 2016
328ddf9
Refactor ComponentLocalBuildInfo, fixing rpaths with internal libraries.
ezyang Jan 12, 2016
e289cec
Make register print the IPI when verbose (useful!)
ezyang Jan 12, 2016
5271dec
Unconditionally turn on package name munging for components.
ezyang Jan 12, 2016
3b6c13b
Tests for internal libraries (#269) and separate cabal_macros.h (#1893)
ezyang Jan 12, 2016
c0fa8be
Don't double-encode the component name string.
ezyang Jan 12, 2016
5e2de31
Don't match dist-test directories.
ezyang Jan 13, 2016
6713d37
Run sdist using bootstrapped cabal-install.
ezyang Jan 13, 2016
bbe1ec5
Undo backwards incompatible change to install paths.
ezyang Jan 13, 2016
e4ac8fe
Warning about compatibility requirements on Setup.hs in cabal-install.
ezyang Jan 13, 2016
b201121
Always generate CURRENT_COMPONENT_ID macros.
ezyang Jan 13, 2016
5ac6da5
Minor renaming to avoid conflicts.
ezyang Jan 13, 2016
cefe8c0
Warn if user attempts to define a package with a reserved name.
ezyang Jan 13, 2016
be6ebfb
Minor refactoring of compatibility keys, streamline library keys.
ezyang Jan 13, 2016
7ea446b
Fix HookedBuildInfo parsing to support old-style format (needs test.)
ezyang Jan 14, 2016
33ce54e
Test case for the Configure build-type.
ezyang Jan 14, 2016
1f71140
Enforce unique naming for internal libraries as well.
ezyang Jan 14, 2016
a4f8534
Take advantage of unique section naming to simplify some paths.
ezyang Jan 14, 2016
10b5140
Fix test-case after simplified component IDs.
ezyang Jan 14, 2016
5cbf5f1
Add NFData instance to ModuleName.
ezyang Jan 13, 2016
9200f6f
Ignore bak files.
ezyang Jan 13, 2016
eedd07f
Accept components to copy in ./Setup copy, fixes #2780.
ezyang Jan 19, 2016
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ dist-*
.#*
*~
.*.swp
*.bak

# GHC build

Expand Down
2 changes: 1 addition & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ script:
- ./dist/setup/setup haddock # see https://github.com/haskell/cabal/issues/2198
- ./dist/setup/setup test --show-details=streaming
- cabal check
- cabal sdist
- ./dist/setup/setup sdist
- install_from_tarball

# Check what we got
Expand Down
28 changes: 28 additions & 0 deletions Cabal/Cabal.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,15 @@ extra-source-files:
tests/PackageTests/CMain/Bar.hs
tests/PackageTests/CMain/foo.c
tests/PackageTests/CMain/my.cabal
tests/PackageTests/Configure/A.hs
tests/PackageTests/Configure/Setup.hs
tests/PackageTests/Configure/X11.cabal
tests/PackageTests/CopyComponent/Exe/Main.hs
tests/PackageTests/CopyComponent/Exe/Main2.hs
tests/PackageTests/CopyComponent/Exe/myprog.cabal
tests/PackageTests/CopyComponent/Lib/Main.hs
tests/PackageTests/CopyComponent/Lib/p.cabal
tests/PackageTests/CopyComponent/Lib/src/P.hs
tests/PackageTests/DeterministicAr/Lib.hs
tests/PackageTests/DeterministicAr/my.cabal
tests/PackageTests/DuplicateModuleName/DuplicateModuleName.cabal
Expand All @@ -97,6 +106,25 @@ extra-source-files:
tests/PackageTests/HaddockNewline/A.hs
tests/PackageTests/HaddockNewline/HaddockNewline.cabal
tests/PackageTests/HaddockNewline/Setup.hs
tests/PackageTests/InternalLibraries/Executable/exe/Main.hs
tests/PackageTests/InternalLibraries/Executable/foo.cabal
tests/PackageTests/InternalLibraries/Executable/src/Foo.hs
tests/PackageTests/InternalLibraries/Library/fooexe/Main.hs
tests/PackageTests/InternalLibraries/Library/fooexe/fooexe.cabal
tests/PackageTests/InternalLibraries/Library/foolib/Foo.hs
tests/PackageTests/InternalLibraries/Library/foolib/foolib.cabal
tests/PackageTests/InternalLibraries/Library/foolib/private/Internal.hs
tests/PackageTests/InternalLibraries/p/Foo.hs
tests/PackageTests/InternalLibraries/p/p.cabal
tests/PackageTests/InternalLibraries/p/p/P.hs
tests/PackageTests/InternalLibraries/p/q/Q.hs
tests/PackageTests/InternalLibraries/q/Q.hs
tests/PackageTests/InternalLibraries/q/q.cabal
tests/PackageTests/Macros/A.hs
tests/PackageTests/Macros/B.hs
tests/PackageTests/Macros/Main.hs
tests/PackageTests/Macros/macros.cabal
tests/PackageTests/Macros/src/C.hs
tests/PackageTests/OrderFlags/Foo.hs
tests/PackageTests/OrderFlags/my.cabal
tests/PackageTests/PathsModule/Executable/Main.hs
Expand Down
4 changes: 4 additions & 0 deletions Cabal/Distribution/ModuleName.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import qualified Distribution.Compat.ReadP as Parse

import qualified Data.Char as Char
( isAlphaNum, isUpper )
import Control.DeepSeq
import Data.Data (Data)
import Data.Typeable (Typeable)
import qualified Text.PrettyPrint as Disp
Expand All @@ -43,6 +44,9 @@ newtype ModuleName = ModuleName [String]

instance Binary ModuleName

instance NFData ModuleName where
rnf (ModuleName ms) = rnf ms

instance Text ModuleName where
disp (ModuleName ms) =
Disp.hcat (intersperse (Disp.char '.') (map Disp.text ms))
Expand Down
89 changes: 52 additions & 37 deletions Cabal/Distribution/PackageDescription.hs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ module Distribution.PackageDescription (
ModuleReexport(..),
emptyLibrary,
withLib,
hasPublicLib,
hasLibs,
libModules,

Expand Down Expand Up @@ -124,7 +125,6 @@ import Distribution.Text
import Language.Haskell.Extension

import Data.Data (Data)
import Data.Foldable (traverse_)
import Data.List (nub, intercalate)
import Data.Maybe (fromMaybe, maybeToList)
import Data.Foldable as Fold (Foldable(foldMap))
Expand Down Expand Up @@ -189,7 +189,7 @@ data PackageDescription
buildType :: Maybe BuildType,
setupBuildInfo :: Maybe SetupBuildInfo,
-- components
library :: Maybe Library,
libraries :: [Library],
executables :: [Executable],
testSuites :: [TestSuite],
benchmarks :: [Benchmark],
Expand Down Expand Up @@ -256,7 +256,7 @@ emptyPackageDescription
category = "",
customFieldsPD = [],
setupBuildInfo = Nothing,
library = Nothing,
libraries = [],
executables = [],
testSuites = [],
benchmarks = [],
Expand Down Expand Up @@ -390,6 +390,7 @@ instance Text ModuleRenaming where
-- The Library type

data Library = Library {
libName :: String,
exposedModules :: [ModuleName],
reexportedModules :: [ModuleReexport],
requiredSignatures:: [ModuleName], -- ^ What sigs need implementations?
Expand All @@ -403,6 +404,7 @@ instance Binary Library

instance Monoid Library where
mempty = Library {
libName = mempty,
exposedModules = mempty,
reexportedModules = mempty,
requiredSignatures = mempty,
Expand All @@ -414,6 +416,7 @@ instance Monoid Library where

instance Semigroup Library where
a <> b = Library {
libName = combine' libName,
exposedModules = combine exposedModules,
reexportedModules = combine reexportedModules,
requiredSignatures = combine requiredSignatures,
Expand All @@ -422,26 +425,31 @@ instance Semigroup Library where
libBuildInfo = combine libBuildInfo
}
where combine field = field a `mappend` field b
combine' field = case (field a, field b) of
("","") -> ""
("", x) -> x
(x, "") -> x
(x, y) -> error $ "Ambiguous values for library field: '"
++ x ++ "' and '" ++ y ++ "'"

emptyLibrary :: Library
emptyLibrary = mempty

-- |does this package have any libraries?
hasLibs :: PackageDescription -> Bool
hasLibs p = maybe False (buildable . libBuildInfo) (library p)
-- | Does this package have a PUBLIC library?
hasPublicLib :: PackageDescription -> Bool
hasPublicLib p = any f (libraries p)
where f lib = buildable (libBuildInfo lib) &&
libName lib == display (packageName (package p))

-- |'Maybe' version of 'hasLibs'
maybeHasLibs :: PackageDescription -> Maybe Library
maybeHasLibs p =
library p >>= \lib -> if buildable (libBuildInfo lib)
then Just lib
else Nothing
-- | Does this package have any libraries?
hasLibs :: PackageDescription -> Bool
hasLibs p = any (buildable . libBuildInfo) (libraries p)

-- |If the package description has a library section, call the given
-- function with the library build info as argument.
withLib :: PackageDescription -> (Library -> IO ()) -> IO ()
withLib pkg_descr f =
traverse_ f (maybeHasLibs pkg_descr)
sequence_ [f lib | lib <- libraries pkg_descr, buildable (libBuildInfo lib)]

-- | Get all the module names from the library (exposed and internal modules)
-- which need to be compiled. (This does not include reexports, which
Expand Down Expand Up @@ -919,7 +927,7 @@ emptyBuildInfo = mempty
-- all buildable executables, test suites and benchmarks. Useful for gathering
-- dependencies.
allBuildInfo :: PackageDescription -> [BuildInfo]
allBuildInfo pkg_descr = [ bi | Just lib <- [library pkg_descr]
allBuildInfo pkg_descr = [ bi | lib <- libraries pkg_descr
, let bi = libBuildInfo lib
, buildable bi ]
++ [ bi | exe <- executables pkg_descr
Expand Down Expand Up @@ -954,10 +962,10 @@ usedExtensions :: BuildInfo -> [Extension]
usedExtensions bi = oldExtensions bi
++ defaultExtensions bi

type HookedBuildInfo = (Maybe BuildInfo, [(String, BuildInfo)])
type HookedBuildInfo = ([(String, BuildInfo)], [(String, BuildInfo)])

emptyHookedBuildInfo :: HookedBuildInfo
emptyHookedBuildInfo = (Nothing, [])
emptyHookedBuildInfo = ([], [])

-- |Select options for a particular Haskell compiler.
hcOptions :: CompilerFlavor -> BuildInfo -> [String]
Expand Down Expand Up @@ -1113,28 +1121,35 @@ lowercase = map Char.toLower
-- ------------------------------------------------------------

updatePackageDescription :: HookedBuildInfo -> PackageDescription -> PackageDescription
updatePackageDescription (mb_lib_bi, exe_bi) p
= p{ executables = updateExecutables exe_bi (executables p)
, library = updateLibrary mb_lib_bi (library p)
updatePackageDescription (lib_bi, exe_bi) p
= p{ executables = updateMany exeName updateExecutable exe_bi (executables p)
, libraries = updateMany libName updateLibrary lib_bi (libraries p)
}
where
updateLibrary :: Maybe BuildInfo -> Maybe Library -> Maybe Library
updateLibrary (Just bi) (Just lib) = Just (lib{libBuildInfo = bi `mappend` libBuildInfo lib})
updateLibrary Nothing mb_lib = mb_lib
updateLibrary (Just _) Nothing = Nothing

updateExecutables :: [(String, BuildInfo)] -- ^[(exeName, new buildinfo)]
-> [Executable] -- ^list of executables to update
-> [Executable] -- ^list with exeNames updated
updateExecutables exe_bi' executables' = foldr updateExecutable executables' exe_bi'

updateExecutable :: (String, BuildInfo) -- ^(exeName, new buildinfo)
-> [Executable] -- ^list of executables to update
-> [Executable] -- ^list with exeName updated
updateExecutable _ [] = []
updateExecutable exe_bi'@(name,bi) (exe:exes)
| exeName exe == name = exe{buildInfo = bi `mappend` buildInfo exe} : exes
| otherwise = exe : updateExecutable exe_bi' exes
updateMany :: (a -> String) -- ^ @exeName@ or @libName@
-> (BuildInfo -> a -> a) -- ^ @updateExecutable@ or @updateLibrary@
-> [(String, BuildInfo)] -- ^[(name, new buildinfo)]
-> [a] -- ^list of components to update
-> [a] -- ^list with updated components
updateMany name update hooked_bi' cs' = foldr (updateOne name update) cs' hooked_bi'

updateOne :: (a -> String) -- ^ @exeName@ or @libName@
-> (BuildInfo -> a -> a) -- ^ @updateExecutable@ or @updateLibrary@
-> (String, BuildInfo) -- ^(name, new buildinfo)
-> [a] -- ^list of compnoents to update
-> [a] -- ^list with name component updated
updateOne _ _ _ [] = []
updateOne name_sel update hooked_bi'@(name,bi) (c:cs)
| name_sel c == name ||
-- Special case: an empty name means "please update the BuildInfo for
-- the public library, i.e. the one with the same name as the
-- package." See 'parseHookedBuildInfo'.
(name == "" && name_sel c == display (pkgName (package p)))
= update bi c : cs
| otherwise = c : updateOne name_sel update hooked_bi' cs

updateExecutable bi exe = exe{buildInfo = bi `mappend` buildInfo exe}
updateLibrary bi lib = lib{libBuildInfo = bi `mappend` libBuildInfo lib}

-- ---------------------------------------------------------------------------
-- The GenericPackageDescription type
Expand All @@ -1143,7 +1158,7 @@ data GenericPackageDescription =
GenericPackageDescription {
packageDescription :: PackageDescription,
genPackageFlags :: [Flag],
condLibrary :: Maybe (CondTree ConfVar [Dependency] Library),
condLibraries :: [(String, CondTree ConfVar [Dependency] Library)],
condExecutables :: [(String, CondTree ConfVar [Dependency] Executable)],
condTestSuites :: [(String, CondTree ConfVar [Dependency] TestSuite)],
condBenchmarks :: [(String, CondTree ConfVar [Dependency] Benchmark)]
Expand Down
39 changes: 29 additions & 10 deletions Cabal/Distribution/PackageDescription/Check.hs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import Distribution.Text
import Language.Haskell.Extension

import Data.Maybe
( isNothing, isJust, catMaybes, mapMaybe, maybeToList, fromMaybe )
( isNothing, isJust, catMaybes, mapMaybe, fromMaybe )
import Data.List (sort, group, isPrefixOf, nub, find)
import Control.Monad
( filterM, liftM )
Expand Down Expand Up @@ -173,19 +173,19 @@ checkSanity pkg =
, check (all ($ pkg) [ null . executables
, null . testSuites
, null . benchmarks
, isNothing . library ]) $
, null . libraries ]) $
PackageBuildImpossible
"No executables, libraries, tests, or benchmarks found. Nothing to do."

, check (not (null duplicateNames)) $
PackageBuildImpossible $ "Duplicate sections: " ++ commaSep duplicateNames
++ ". The name of every executable, test suite, and benchmark section in"
++ ". The name of every library, executable, test suite, and benchmark section in"
++ " the package must be unique."
]
--TODO: check for name clashes case insensitively: windows file systems cannot
--cope.

++ maybe [] (checkLibrary pkg) (library pkg)
++ concatMap (checkLibrary pkg) (libraries pkg)
++ concatMap (checkExecutable pkg) (executables pkg)
++ concatMap (checkTestSuite pkg) (testSuites pkg)
++ concatMap (checkBenchmark pkg) (benchmarks pkg)
Expand All @@ -199,10 +199,15 @@ checkSanity pkg =
++ "tool only supports up to version " ++ display cabalVersion ++ "."
]
where
-- The public library gets special dispensation, because it
-- is common practice to export a library and name the executable
-- the same as the package. We always put the public library
-- in the top-level directory in dist, so no conflicts either.
libNames = filter (/= unPackageName (packageName pkg)) . map libName $ libraries pkg
exeNames = map exeName $ executables pkg
testNames = map testName $ testSuites pkg
bmNames = map benchmarkName $ benchmarks pkg
duplicateNames = dups $ exeNames ++ testNames ++ bmNames
duplicateNames = dups $ libNames ++ exeNames ++ testNames ++ bmNames

checkLibrary :: PackageDescription -> Library -> [PackageCheck]
checkLibrary pkg lib =
Expand Down Expand Up @@ -359,6 +364,11 @@ checkFields pkg =
++ "need to convert package names to file names so using this name "
++ "would cause problems."

, check ((isPrefixOf "z-") . display . packageName $ pkg) $
PackageDistInexcusable $
"Package names with the prefix 'z-' are reserved by Cabal and "
++ "cannot be used."

, check (isNothing (buildType pkg)) $
PackageBuildWarning $
"No 'build-type' specified. If you do not need a custom Setup.hs or "
Expand Down Expand Up @@ -673,7 +683,7 @@ checkGhcOptions pkg =

where
all_ghc_options = concatMap get_ghc_options (allBuildInfo pkg)
lib_ghc_options = maybe [] (get_ghc_options . libBuildInfo) (library pkg)
lib_ghc_options = concatMap (get_ghc_options . libBuildInfo) (libraries pkg)
get_ghc_options bi = hcOptions GHC bi ++ hcProfOptions GHC bi

checkFlags :: [String] -> PackageCheck -> Maybe PackageCheck
Expand Down Expand Up @@ -895,9 +905,18 @@ checkCabalVersion pkg =
++ "different modules then list the other ones in the "
++ "'other-languages' field."

, checkVersion [1,23]
(case libraries pkg of
[lib] -> libName lib /= unPackageName (packageName pkg)
[] -> False
_ -> True) $
PackageDistInexcusable $
"To use multiple 'library' sections or a named library section "
++ "the package needs to specify at least 'cabal-version >= 1.23'."

-- check use of reexported-modules sections
, checkVersion [1,21]
(maybe False (not.null.reexportedModules) (library pkg)) $
(any (not.null.reexportedModules) (libraries pkg)) $
PackageDistInexcusable $
"To use the 'reexported-module' field the package needs to specify "
++ "at least 'cabal-version: >= 1.21'."
Expand Down Expand Up @@ -1296,7 +1315,7 @@ checkConditionals pkg =
unknownOSs = [ os | OS (OtherOS os) <- conditions ]
unknownArches = [ arch | Arch (OtherArch arch) <- conditions ]
unknownImpls = [ impl | Impl (OtherCompiler impl) _ <- conditions ]
conditions = maybe [] fvs (condLibrary pkg)
conditions = concatMap (fvs . snd) (condLibraries pkg)
++ concatMap (fvs . snd) (condExecutables pkg)
fvs (CondNode _ _ ifs) = concatMap compfv ifs -- free variables
compfv (c, ct, mct) = condfv c ++ fvs ct ++ maybe [] fvs mct
Expand Down Expand Up @@ -1399,8 +1418,8 @@ checkDevelopmentOnlyFlags pkg =

allConditionalBuildInfo :: [([Condition ConfVar], BuildInfo)]
allConditionalBuildInfo =
concatMap (collectCondTreePaths libBuildInfo)
(maybeToList (condLibrary pkg))
concatMap (collectCondTreePaths libBuildInfo . snd)
(condLibraries pkg)

++ concatMap (collectCondTreePaths buildInfo . snd)
(condExecutables pkg)
Expand Down
Loading