Commit b070fc9f authored by recursion-ninja's avatar recursion-ninja Committed by GitHub
Browse files

Merge pull request #4810 from recursion-ninja/master

Added `cxx-options` and `cxx-sources` build info fields for separate compilation of C and C++ source files. 
parents 49f804fe 818aec53
......@@ -1030,6 +1030,7 @@ checkPaths pkg =
++ [ (path, "license-file") | path <- licenseFiles pkg ]
++ concat
[ [ (path, "c-sources") | path <- cSources bi ]
++ [ (path, "cxx-sources") | path <- cxxSources bi ]
++ [ (path, "js-sources") | path <- jsSources bi ]
++ [ (path, "install-includes") | path <- installIncludes bi ]
++ [ (path, "hs-source-dirs") | path <- hsSourceDirs bi ]
......
......@@ -361,11 +361,13 @@ buildInfoFieldGrammar = BuildInfo
^^^ availableSince [2,0]
<*> monoidalFieldAla "cpp-options" (alaList' NoCommaFSep Token') L.cppOptions
<*> monoidalFieldAla "cc-options" (alaList' NoCommaFSep Token') L.ccOptions
<*> monoidalFieldAla "cxx-options" (alaList' NoCommaFSep Token') L.cxxOptions
<*> monoidalFieldAla "ld-options" (alaList' NoCommaFSep Token') L.ldOptions
<*> monoidalFieldAla "pkgconfig-depends" (alaList CommaFSep) L.pkgconfigDepends
<*> monoidalFieldAla "frameworks" (alaList' FSep Token) L.frameworks
<*> monoidalFieldAla "extra-framework-dirs" (alaList' FSep FilePathNT) L.extraFrameworkDirs
<*> monoidalFieldAla "c-sources" (alaList' VCat FilePathNT) L.cSources
<*> monoidalFieldAla "cxx-sources" (alaList' VCat FilePathNT) L.cxxSources
<*> monoidalFieldAla "js-sources" (alaList' VCat FilePathNT) L.jsSources
<*> hsSourceDirsGrammar
<*> monoidalFieldAla "other-modules" (alaList' VCat MQuoted) L.otherModules
......
......@@ -441,6 +441,9 @@ binfoFieldDescrs =
, spaceListField "cc-options"
showToken parseTokenQ'
ccOptions (\val binfo -> binfo{ccOptions=val})
, spaceListField "cxx-options"
showToken parseTokenQ'
cxxOptions (\val binfo -> binfo{cxxOptions=val})
, spaceListField "ld-options"
showToken parseTokenQ'
ldOptions (\val binfo -> binfo{ldOptions=val})
......@@ -456,6 +459,9 @@ binfoFieldDescrs =
, listFieldWithSep vcat "c-sources"
showFilePath parseFilePathQ
cSources (\paths binfo -> binfo{cSources=paths})
, listFieldWithSep vcat "cxx-sources"
showFilePath parseFilePathQ
cxxSources (\paths binfo -> binfo{cxxSources=paths})
, listFieldWithSep vcat "js-sources"
showFilePath parseFilePathQ
jsSources (\paths binfo -> binfo{jsSources=paths})
......
......@@ -201,7 +201,7 @@ buildComponent verbosity numJobs pkg_descr lbi suffixes
setupMessage' verbosity "Building" (packageId pkg_descr)
(componentLocalName clbi) (maybeComponentInstantiatedWith clbi)
let libbi = libBuildInfo lib
lib' = lib { libBuildInfo = addExtraCSources libbi extras }
lib' = lib { libBuildInfo = addExtraCxxSources (addExtraCSources libbi extras) extras }
buildLib verbosity numJobs pkg_descr lbi lib' clbi
let oneComponentRequested (OneComponentRequestedSpec _) = True
......@@ -329,6 +329,15 @@ addExtraCSources bi extras = bi { cSources = new }
exs = Set.fromList extras
-- | Add extra C++ sources generated by preprocessing to build
-- information.
addExtraCxxSources :: BuildInfo -> [FilePath] -> BuildInfo
addExtraCxxSources bi extras = bi { cxxSources = new }
where new = Set.toList $ old `Set.union` exs
old = Set.fromList $ cxxSources bi
exs = Set.fromList extras
replComponent :: Verbosity
-> PackageDescription
-> LocalBuildInfo
......
......@@ -559,7 +559,8 @@ buildOrReplLib forRepl verbosity numJobs pkg_descr lbi lib clbi = do
createDirectoryIfMissingVerbose verbosity True libTargetDir
-- TODO: do we need to put hs-boot files into place for mutually recursive
-- modules?
let cObjs = map (`replaceExtension` objExtension) (cSources libBi)
let cLikeFiles = fromNubListR $ toNubListR (cSources libBi) <> toNubListR (cxxSources libBi)
cObjs = map (`replaceExtension` objExtension) cLikeFiles
baseOpts = componentGhcOptions verbosity lbi libBi clbi libTargetDir
vanillaOpts = baseOpts `mappend` mempty {
ghcOptMode = toFlag GhcModeMake,
......@@ -644,6 +645,39 @@ buildOrReplLib forRepl verbosity numJobs pkg_descr lbi lib clbi = do
else do vanilla; shared
whenProfLib (runGhcProg profOpts)
-- build any C++ sources seperately
unless (not has_code || null (cxxSources libBi)) $ do
info verbosity "Building C++ Sources..."
sequence_
[ do let baseCxxOpts = Internal.componentCxxGhcOptions verbosity implInfo
lbi libBi clbi libTargetDir filename
vanillaCxxOpts = if isGhcDynamic
then baseCxxOpts { ghcOptFPic = toFlag True }
else baseCxxOpts
profCxxOpts = vanillaCxxOpts `mappend` mempty {
ghcOptProfilingMode = toFlag True,
ghcOptObjSuffix = toFlag "p_o"
}
sharedCxxOpts = vanillaCxxOpts `mappend` mempty {
ghcOptFPic = toFlag True,
ghcOptDynLinkMode = toFlag GhcDynamicOnly,
ghcOptObjSuffix = toFlag "dyn_o"
}
odir = fromFlag (ghcOptObjDir vanillaCxxOpts)
createDirectoryIfMissingVerbose verbosity True odir
let runGhcProgIfNeeded cxxOpts = do
needsRecomp <- checkNeedsRecompilation filename cxxOpts
when needsRecomp $ runGhcProg cxxOpts
runGhcProgIfNeeded vanillaCxxOpts
unless forRepl $
whenSharedLib forceSharedLib (runGhcProgIfNeeded sharedCxxOpts)
unless forRepl $ whenProfLib (runGhcProgIfNeeded profCxxOpts)
| filename <- cxxSources libBi]
when has_code . ifReplLib $ do
when (null (allLibModules lib clbi)) $ warn verbosity "No exposed modules"
ifReplLib (runGhcProg replOpts)
-- build any C sources
unless (not has_code || null (cSources libBi)) $ do
info verbosity "Building C Sources..."
......@@ -679,17 +713,13 @@ buildOrReplLib forRepl verbosity numJobs pkg_descr lbi lib clbi = do
-- with ghci, but .c files can depend on .h files generated by ghc by ffi
-- exports.
when has_code . ifReplLib $ do
when (null (allLibModules lib clbi)) $ warn verbosity "No exposed modules"
ifReplLib (runGhcProg replOpts)
-- link:
when has_code . unless forRepl $ do
info verbosity "Linking..."
let cProfObjs = map (`replaceExtension` ("p_" ++ objExtension))
(cSources libBi)
(cSources libBi ++ cxxSources libBi)
cSharedObjs = map (`replaceExtension` ("dyn_" ++ objExtension))
(cSources libBi)
(cSources libBi ++ cxxSources libBi)
compiler_id = compilerId (compiler lbi)
vanillaLibFilePath = libTargetDir </> mkLibName uid
profileLibFilePath = libTargetDir </> mkProfLibName uid
......
......@@ -19,6 +19,7 @@ module Distribution.Simple.GHC.Internal (
targetPlatform,
getGhcInfo,
componentCcGhcOptions,
componentCxxGhcOptions,
componentGhcOptions,
mkGHCiLibName,
filterGhciFlags,
......@@ -290,6 +291,40 @@ componentCcGhcOptions verbosity _implInfo lbi bi clbi odir filename =
ghcOptObjDir = toFlag odir
}
componentCxxGhcOptions :: Verbosity -> GhcImplInfo -> LocalBuildInfo
-> BuildInfo -> ComponentLocalBuildInfo
-> FilePath -> FilePath
-> GhcOptions
componentCxxGhcOptions verbosity _implInfo lbi bi cxxlbi odir filename =
mempty {
-- Respect -v0, but don't crank up verbosity on GHC if
-- Cabal verbosity is requested. For that, use --ghc-option=-v instead!
ghcOptVerbosity = toFlag (min verbosity normal),
ghcOptMode = toFlag GhcModeCompile,
ghcOptInputFiles = toNubListR [filename],
ghcOptCppIncludePath = toNubListR $ [autogenComponentModulesDir lbi cxxlbi
,autogenPackageModulesDir lbi
,odir]
++ PD.includeDirs bi,
ghcOptHideAllPackages= toFlag True,
ghcOptPackageDBs = withPackageDB lbi,
ghcOptPackages = toNubListR $ mkGhcOptPackages cxxlbi,
ghcOptCxxOptions = toNubListR $
(case withOptimization lbi of
NoOptimisation -> []
_ -> ["-O2"]) ++
(case withDebugInfo lbi of
NoDebugInfo -> []
MinimalDebugInfo -> ["-g1"]
NormalDebugInfo -> ["-g"]
MaximalDebugInfo -> ["-g3"]) ++
PD.cxxOptions bi,
ghcOptObjDir = toFlag odir
}
componentGhcOptions :: Verbosity -> GhcImplInfo -> LocalBuildInfo
-> BuildInfo -> ComponentLocalBuildInfo -> FilePath
-> GhcOptions
......
......@@ -154,6 +154,9 @@ data GhcOptions = GhcOptions {
-- | Options to pass through to the C compiler; the @ghc -optc@ flag.
ghcOptCcOptions :: NubListR String,
-- | Options to pass through to the C++ compiler.
ghcOptCxxOptions :: NubListR String,
-- | Options to pass through to CPP; the @ghc -optP@ flag.
ghcOptCppOptions :: NubListR String,
......@@ -392,13 +395,16 @@ renderGhcOptions comp _platform@(Platform _arch os) opts
, [ "-i" ++ dir | dir <- flags ghcOptSourcePath ]
--------------------
-- C and CPP stuff
--------------------
-- CPP, C, and C++ stuff
, [ "-I" ++ dir | dir <- flags ghcOptCppIncludePath ]
, [ "-optP" ++ opt | opt <- flags ghcOptCppOptions ]
, concat [ [ "-optP-include", "-optP" ++ inc]
| inc <- flags ghcOptCppIncludes ]
, [ "-optc" ++ opt | opt <- flags ghcOptCcOptions ]
, [ "-optc" ++ opt | opt <- flags ghcOptCxxOptions ]
-----------------
-- Linker stuff
......
......@@ -52,11 +52,13 @@ data BuildInfo = BuildInfo {
buildToolDepends :: [ExeDependency],
cppOptions :: [String], -- ^ options for pre-processing Haskell code
ccOptions :: [String], -- ^ options for C compiler
cxxOptions :: [String], -- ^ options for C++ compiler
ldOptions :: [String], -- ^ options for linker
pkgconfigDepends :: [PkgconfigDependency], -- ^ pkg-config packages that are used
frameworks :: [String], -- ^support frameworks for Mac OS X
extraFrameworkDirs:: [String], -- ^ extra locations to find frameworks.
cSources :: [FilePath],
cxxSources :: [FilePath],
jsSources :: [FilePath],
hsSourceDirs :: [FilePath], -- ^ where to look for the Haskell module hierarchy
otherModules :: [ModuleName], -- ^ non-exposed or non-main modules
......@@ -95,11 +97,13 @@ instance Monoid BuildInfo where
buildToolDepends = [],
cppOptions = [],
ccOptions = [],
cxxOptions = [],
ldOptions = [],
pkgconfigDepends = [],
frameworks = [],
extraFrameworkDirs = [],
cSources = [],
cxxSources = [],
jsSources = [],
hsSourceDirs = [],
otherModules = [],
......@@ -132,11 +136,13 @@ instance Semigroup BuildInfo where
buildToolDepends = combine buildToolDepends,
cppOptions = combine cppOptions,
ccOptions = combine ccOptions,
cxxOptions = combine cxxOptions,
ldOptions = combine ldOptions,
pkgconfigDepends = combine pkgconfigDepends,
frameworks = combineNub frameworks,
extraFrameworkDirs = combineNub extraFrameworkDirs,
cSources = combineNub cSources,
cxxSources = combineNub cxxSources,
jsSources = combineNub jsSources,
hsSourceDirs = combineNub hsSourceDirs,
otherModules = combineNub otherModules,
......
......@@ -43,6 +43,10 @@ class HasBuildInfo a where
ccOptions = buildInfo . ccOptions
{-# INLINE ccOptions #-}
cxxOptions :: Lens' a [String]
cxxOptions = buildInfo . cxxOptions
{-# INLINE cxxOptions #-}
ldOptions :: Lens' a [String]
ldOptions = buildInfo . ldOptions
{-# INLINE ldOptions #-}
......@@ -63,6 +67,10 @@ class HasBuildInfo a where
cSources = buildInfo . cSources
{-# INLINE cSources #-}
cxxSources :: Lens' a [FilePath]
cxxSources = buildInfo . cxxSources
{-# INLINE cxxSources #-}
jsSources :: Lens' a [FilePath]
jsSources = buildInfo . jsSources
{-# INLINE jsSources #-}
......@@ -171,6 +179,9 @@ instance HasBuildInfo BuildInfo where
ccOptions f s = fmap (\x -> s { T.ccOptions = x }) (f (T.ccOptions s))
{-# INLINE ccOptions #-}
cxxOptions f s = fmap (\x -> s { T.cxxOptions = x }) (f (T.cxxOptions s))
{-# INLINE cxxOptions #-}
ldOptions f s = fmap (\x -> s { T.ldOptions = x }) (f (T.ldOptions s))
{-# INLINE ldOptions #-}
......@@ -186,6 +197,9 @@ instance HasBuildInfo BuildInfo where
cSources f s = fmap (\x -> s { T.cSources = x }) (f (T.cSources s))
{-# INLINE cSources #-}
cxxSources f s = fmap (\x -> s { T.cSources = x }) (f (T.cxxSources s))
{-# INLINE cxxSources #-}
jsSources f s = fmap (\x -> s { T.jsSources = x }) (f (T.jsSources s))
{-# INLINE jsSources #-}
......
-*-change-log-*-
2.2.0.0 (current development version)
* Added cxx-options and cxx-sources build info fields for seperate
compilation of C++ source files (#3700)
* Remove unused '--allow-newer'/'--allow-older' support (#4527)
* Change `rawSystemStdInOut` to use proper type to represent
binary and textual data; new 'Distribution.Utils.IOData' module;
......
......@@ -2024,12 +2024,22 @@ system-dependent values for these fields.
source tree. Cabal looks in these directories when attempting to
locate files listed in :pkg-field:`includes` and
:pkg-field:`install-includes`.
.. pkg-field:: c-sources: filename list
A list of C source files to be compiled and linked with the Haskell
files.
.. pkg-field:: cxx-sources: filename list
A list of C++ source files to be compiled and linked with the Haskell
files. Useful for segregating C and C++ sources when supplying different
command-line arguments to the compiler via the :pkg-field:`cc-options`
and the :pkg-field:`cxx-options` fields. The files listed in the
:pkg-field:`cxx-sources` can reference files listed in the
:pkg-field:`c-sources` field and vice-versa. The object files will be linked
appropriately.
.. pkg-field:: js-sources: filename list
A list of JavaScript source files to be linked with the Haskell
......@@ -2060,6 +2070,18 @@ system-dependent values for these fields.
haskell source and other pre-processed Haskell source like .hsc
.chs. Does not apply to C code, that's what cc-options is for.
.. pkg-field:: cxx-options: token list
Command-line arguments to be passed to the compiler when compiling
C++ code. The C++ sources to which these command-line arguments
should be applied can be specified with the :pkg-field:`cxx-sources`
field. Command-line options for C and C++ can be passed separately to
the compiler when compiling both C and C++ sources by segregating the C
and C++ sources with the :pkg-field:`c-sources` and
:pkg-field:`cxx-sources` fields respectively, and providing different
command-line arguments with the :pkg-field:`cc-options` and the
:pkg-field:`cxx-options` fields.
.. pkg-field:: ld-options: token list
Command-line arguments to be passed to the linker. Since the
......
-*-change-log-*-
2.2.0.0 (current development version)
* New config file field: 'cxx-options' to specify which options to be
passed to the compiler when compiling C++ sources specified by the
'cxx-sources' field. (#3700)
* New config file field: 'cxx-sources' to specify C++ files to be
compiled separately from C source files. Useful in conjunction with the
'cxx-options' flag to pass different compiler options to C and C++
source files. (#3700)
* 'cabal configure' now supports '--enable-static' which can be
used to build static libaries with GHC via GHC's `-staticlib` flag.
* Don't automatically/silently case-correct mispelled package-names
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment