Skip to content

Add support for platform libraries #2540

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 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
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 Cabal/Cabal.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,7 @@ test-suite package-tests
tasty,
tasty-quickcheck,
tasty-hunit,
tagged,
QuickCheck >= 2.1.0.1 && < 2.9,
Cabal,
process,
Expand Down
128 changes: 127 additions & 1 deletion Cabal/Distribution/PackageDescription.hs
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,17 @@ module Distribution.PackageDescription (
hasLibs,
libModules,

-- ** Foreign libraries
ForeignLib(..),
ForeignLibType(..),
ForeignLibOption(..),
emptyForeignLib,
withFLib,
hasForeignLibs,
flibModules,
knownForeignLibTypes,
flibIsShared,

-- ** Executables
Executable(..),
emptyExecutable,
Expand Down Expand Up @@ -142,6 +153,7 @@ import Distribution.Version
import Distribution.License (License(UnspecifiedLicense))
import Distribution.Compiler (CompilerFlavor)
import Distribution.System (OS, Arch)
import Distribution.PackageDescription.Utils (cabalBug)
import Distribution.Text
( Text(..), display )
import Language.Haskell.Extension
Expand Down Expand Up @@ -198,6 +210,7 @@ data PackageDescription
setupBuildInfo :: Maybe SetupBuildInfo,
-- components
library :: Maybe Library,
foreignLibs :: [ForeignLib],
executables :: [Executable],
testSuites :: [TestSuite],
benchmarks :: [Benchmark],
Expand Down Expand Up @@ -265,6 +278,7 @@ emptyPackageDescription
customFieldsPD = [],
setupBuildInfo = Nothing,
library = Nothing,
foreignLibs = [],
executables = [],
testSuites = [],
benchmarks = [],
Expand Down Expand Up @@ -486,6 +500,117 @@ instance Text ModuleReexport where
parse
return (ModuleReexport mpkgname origname newname)

-- ---------------------------------------------------------------------------
-- Foreign libraries

data ForeignLib = ForeignLib {
foreignLibName :: String
, foreignLibType :: ForeignLibType
, foreignLibOptions :: [ForeignLibOption]
, foreignLibBuildInfo :: BuildInfo

-- | (Windows-specific) module definition files
--
-- This is a list rather than a maybe field so that we can flatten
-- the condition trees (for instance, when creating an sdist)
, foreignLibModDefFile :: [FilePath]
}
deriving (Generic, Show, Read, Eq, Typeable, Data)

data ForeignLibType =
ForeignLibNativeShared
| ForeignLibNativeStatic
| ForeignLibTypeUnknown
deriving (Generic, Show, Read, Eq, Typeable, Data)

data ForeignLibOption =
-- | Merge in all dependent libraries
ForeignLibStandalone
deriving (Generic, Show, Read, Eq, Typeable, Data)

instance Text ForeignLibType where
disp ForeignLibNativeShared = text "native-shared"
disp ForeignLibNativeStatic = text "native-static"
disp ForeignLibTypeUnknown = text "unknown"

parse = Parse.choice [
do _ <- Parse.string "native-shared" ; return ForeignLibNativeShared
, do _ <- Parse.string "native-static" ; return ForeignLibNativeStatic
]

instance Text ForeignLibOption where
disp ForeignLibStandalone = text "standalone"

parse = Parse.choice [
do _ <- Parse.string "standalone" ; return ForeignLibStandalone
]

instance Binary ForeignLib
instance Binary ForeignLibType
instance Binary ForeignLibOption

instance Monoid ForeignLibType where
mempty = ForeignLibTypeUnknown
ForeignLibTypeUnknown `mappend` b = b
a `mappend` ForeignLibTypeUnknown = a
_ `mappend` _ = error "Ambiguous foreign library type"

instance Monoid ForeignLib where
mempty = ForeignLib {
foreignLibName = mempty
, foreignLibType = ForeignLibTypeUnknown
, foreignLibOptions = []
, foreignLibBuildInfo = mempty
, foreignLibModDefFile = []
}
mappend a b = ForeignLib {
foreignLibName = combine' foreignLibName
, foreignLibType = combine foreignLibType
, foreignLibOptions = combine foreignLibOptions
, foreignLibBuildInfo = combine foreignLibBuildInfo
, foreignLibModDefFile = combine foreignLibModDefFile
}
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 foreign library field: '"
++ x ++ "' and '" ++ y ++ "'"

emptyForeignLib :: ForeignLib
emptyForeignLib = mempty

-- |does this package have any foreign libraries?
hasForeignLibs :: PackageDescription -> Bool
hasForeignLibs p = any (buildable . foreignLibBuildInfo) (foreignLibs p)

-- | Perform the action on each buildable 'ForeignLib' in the package
-- description.
withFLib :: PackageDescription -> (ForeignLib -> IO ()) -> IO ()
withFLib pkg_descr f =
sequence_ [ f flib
| flib <- foreignLibs pkg_descr
, buildable (foreignLibBuildInfo flib)
]

-- | Get all the module names from a foreign library
flibModules :: ForeignLib -> [ModuleName]
flibModules flib = otherModules (foreignLibBuildInfo flib)

knownForeignLibTypes :: [ForeignLibType]
knownForeignLibTypes = [
ForeignLibNativeShared
, ForeignLibNativeStatic
]

flibIsShared :: ForeignLib -> Bool
flibIsShared flib =
case foreignLibType flib of
ForeignLibNativeShared -> True
ForeignLibNativeStatic -> False
ForeignLibTypeUnknown -> cabalBug "Unknown foreign library type"

-- ---------------------------------------------------------------------------
-- The Executable type

Expand Down Expand Up @@ -1127,8 +1252,9 @@ updatePackageDescription (mb_lib_bi, exe_bi) p
data GenericPackageDescription =
GenericPackageDescription {
packageDescription :: PackageDescription,
genPackageFlags :: [Flag],
genPackageFlags :: [Flag],
condLibrary :: Maybe (CondTree ConfVar [Dependency] Library),
condForeignLibs :: [(String, CondTree ConfVar [Dependency] ForeignLib)],
condExecutables :: [(String, CondTree ConfVar [Dependency] Executable)],
condTestSuites :: [(String, CondTree ConfVar [Dependency] TestSuite)],
condBenchmarks :: [(String, CondTree ConfVar [Dependency] Benchmark)]
Expand Down
4 changes: 2 additions & 2 deletions Cabal/Distribution/PackageDescription/Check.hs
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,9 @@ checkSanity pkg =
, check (null . versionBranch . packageVersion $ pkg) $
PackageBuildImpossible "No 'version' field."

, check (null (executables pkg) && isNothing (library pkg)) $
, check (null (executables pkg) && null (foreignLibs pkg) && isNothing (library pkg)) $
PackageBuildImpossible
"No executables and no library found. Nothing to do."
"No library, executable, or foreign library found. Nothing to do."

, check (not (null duplicateNames)) $
PackageBuildImpossible $ "Duplicate sections: " ++ commaSep duplicateNames
Expand Down
Loading