From 23d8dcd3a709ef163bf917443ac47092a1ec79a6 Mon Sep 17 00:00:00 2001 From: Alex Washburn Date: Fri, 11 May 2018 22:16:41 -0400 Subject: [PATCH] Correcting missing linking objects from non-library components. --- Cabal/Distribution/PackageDescription/Check.hs | 34 +++++++----- Cabal/Distribution/Simple/BuildTarget.hs | 2 + Cabal/Distribution/Simple/GHC.hs | 64 ++++++++++++++++------ Cabal/Distribution/Simple/GHC/IPI642.hs | 2 + Cabal/Distribution/Simple/GHC/Internal.hs | 10 ++++ Cabal/Distribution/Simple/JHC.hs | 2 + Cabal/Distribution/Simple/PreProcess.hs | 11 ++-- Cabal/Distribution/Simple/Register.hs | 1 + Cabal/Distribution/Simple/SrcDist.hs | 2 +- Cabal/Distribution/Types/InstalledPackageInfo.hs | 1 + .../Types/InstalledPackageInfo/FieldGrammar.hs | 1 + .../Types/InstalledPackageInfo/Lens.hs | 4 ++ 12 files changed, 98 insertions(+), 36 deletions(-) diff --git a/Cabal/Distribution/PackageDescription/Check.hs b/Cabal/Distribution/PackageDescription/Check.hs index 87c10b8a8..06bb5307a 100644 --- a/Cabal/Distribution/PackageDescription/Check.hs +++ b/Cabal/Distribution/PackageDescription/Check.hs @@ -165,6 +165,7 @@ checkConfiguredPackage pkg = ++ checkSourceRepos pkg ++ checkGhcOptions pkg ++ checkCCOptions pkg + ++ checkCxxOptions pkg ++ checkCPPOptions pkg ++ checkPaths pkg ++ checkCabalVersion pkg @@ -960,17 +961,23 @@ checkGhcOptions pkg = disable e = Just (DisableExtension e) checkCCOptions :: PackageDescription -> [PackageCheck] -checkCCOptions pkg = +checkCCOptions = checkCLikeOptions "C" "cc-options" ccOptions + +checkCxxOptions :: PackageDescription -> [PackageCheck] +checkCxxOptions = checkCLikeOptions "C++" "cxx-options" cxxOptions + +checkCLikeOptions :: String -> String -> (BuildInfo -> [String]) -> PackageDescription -> [PackageCheck] +checkCLikeOptions label prefix accessor pkg = catMaybes [ - checkAlternatives "cc-options" "include-dirs" - [ (flag, dir) | flag@('-':'I':dir) <- all_ccOptions ] + checkAlternatives prefix "include-dirs" + [ (flag, dir) | flag@('-':'I':dir) <- all_cLikeOptions ] - , checkAlternatives "cc-options" "extra-libraries" - [ (flag, lib) | flag@('-':'l':lib) <- all_ccOptions ] + , checkAlternatives prefix "extra-libraries" + [ (flag, lib) | flag@('-':'l':lib) <- all_cLikeOptions ] - , checkAlternatives "cc-options" "extra-lib-dirs" - [ (flag, dir) | flag@('-':'L':dir) <- all_ccOptions ] + , checkAlternatives prefix "extra-lib-dirs" + [ (flag, dir) | flag@('-':'L':dir) <- all_cLikeOptions ] , checkAlternatives "ld-options" "extra-libraries" [ (flag, lib) | flag@('-':'l':lib) <- all_ldOptions ] @@ -980,19 +987,18 @@ checkCCOptions pkg = , checkCCFlags [ "-O", "-Os", "-O0", "-O1", "-O2", "-O3" ] $ PackageDistSuspicious $ - "'cc-options: -O[n]' is generally not needed. When building with " - ++ " optimisations Cabal automatically adds '-O2' for C code. " - ++ "Setting it yourself interferes with the --disable-optimization " - ++ "flag." + "'"++prefix++": -O[n]' is generally not needed. When building with " + ++ " optimisations Cabal automatically adds '-O2' for "++label++" code. " + ++ "Setting it yourself interferes with the --disable-optimization flag." ] - where all_ccOptions = [ opts | bi <- allBuildInfo pkg - , opts <- ccOptions bi ] + where all_cLikeOptions = [ opts | bi <- allBuildInfo pkg + , opts <- accessor bi ] all_ldOptions = [ opts | bi <- allBuildInfo pkg , opts <- ldOptions bi ] checkCCFlags :: [String] -> PackageCheck -> Maybe PackageCheck - checkCCFlags flags = check (any (`elem` flags) all_ccOptions) + checkCCFlags flags = check (any (`elem` flags) all_cLikeOptions) checkCPPOptions :: PackageDescription -> [PackageCheck] checkCPPOptions pkg = diff --git a/Cabal/Distribution/Simple/BuildTarget.hs b/Cabal/Distribution/Simple/BuildTarget.hs index cfa91c01c..e3aa8ef5f 100644 --- a/Cabal/Distribution/Simple/BuildTarget.hs +++ b/Cabal/Distribution/Simple/BuildTarget.hs @@ -453,6 +453,7 @@ data ComponentInfo = ComponentInfo { cinfoAsmFiles:: [FilePath], cinfoCmmFiles:: [FilePath], cinfoCFiles :: [FilePath], + cinfoCxxFiles:: [FilePath], cinfoJsFiles :: [FilePath] } @@ -469,6 +470,7 @@ pkgComponentInfo pkg = cinfoAsmFiles= asmSources bi, cinfoCmmFiles= cmmSources bi, cinfoCFiles = cSources bi, + cinfoCxxFiles= cxxSources bi, cinfoJsFiles = jsSources bi } | c <- pkgComponents pkg diff --git a/Cabal/Distribution/Simple/GHC.hs b/Cabal/Distribution/Simple/GHC.hs index 96376e3e3..c446327d8 100644 --- a/Cabal/Distribution/Simple/GHC.hs +++ b/Cabal/Distribution/Simple/GHC.hs @@ -657,19 +657,19 @@ buildOrReplLib forRepl verbosity numJobs pkg_descr lbi lib clbi = do info verbosity "Building C++ Sources..." sequence_ [ do let baseCxxOpts = Internal.componentCxxGhcOptions verbosity implInfo - lbi libBi clbi libTargetDir filename + 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" - } + ghcOptProfilingMode = toFlag True, + ghcOptObjSuffix = toFlag "p_o" + } sharedCxxOpts = vanillaCxxOpts `mappend` mempty { - ghcOptFPic = toFlag True, - ghcOptDynLinkMode = toFlag GhcDynamicOnly, - ghcOptObjSuffix = toFlag "dyn_o" - } + ghcOptFPic = toFlag True, + ghcOptDynLinkMode = toFlag GhcDynamicOnly, + ghcOptObjSuffix = toFlag "dyn_o" + } odir = fromFlag (ghcOptObjDir vanillaCxxOpts) createDirectoryIfMissingVerbose verbosity True odir let runGhcProgIfNeeded cxxOpts = do @@ -1088,7 +1088,7 @@ gbuildSources :: Verbosity -> Version -- ^ specVersion -> FilePath -> GBuildMode - -> IO ([FilePath], [FilePath], [ModuleName]) + -> IO ([FilePath], [FilePath], [FilePath], [ModuleName]) gbuildSources verbosity specVer tmpDir bm = case bm of GBuildExe exe -> exeSources exe @@ -1096,7 +1096,7 @@ gbuildSources verbosity specVer tmpDir bm = GBuildFLib flib -> return $ flibSources flib GReplFLib flib -> return $ flibSources flib where - exeSources :: Executable -> IO ([FilePath], [FilePath], [ModuleName]) + exeSources :: Executable -> IO ([FilePath], [FilePath], [FilePath], [ModuleName]) exeSources exe@Executable{buildInfo = bnfo, modulePath = modPath} = do main <- findFile (tmpDir : hsSourceDirs bnfo) modPath let mainModName = fromMaybe ModuleName.main $ exeMainModuleName exe @@ -1121,15 +1121,15 @@ gbuildSources verbosity specVer tmpDir bm = ++ display mainModName ++ "' listed in 'other-modules' illegally!" - return (cSources bnfo, [main], + return (cSources bnfo, cxxSources bnfo, [main], filter (/= mainModName) (exeModules exe)) - else return (cSources bnfo, [main], exeModules exe) - else return (main : cSources bnfo, [], exeModules exe) + else return (cSources bnfo, cxxSources bnfo, [main], exeModules exe) + else return (main : cSources bnfo, main : cxxSources bnfo, [], exeModules exe) - flibSources :: ForeignLib -> ([FilePath], [FilePath], [ModuleName]) + flibSources :: ForeignLib -> ([FilePath], [FilePath], [FilePath], [ModuleName]) flibSources flib@ForeignLib{foreignLibBuildInfo = bnfo} = - (cSources bnfo, [], foreignLibModules flib) + (cSources bnfo, cxxSources bnfo, [], foreignLibModules flib) isHaskell :: FilePath -> Bool isHaskell fp = elem (takeExtension fp) [".hs", ".lhs"] @@ -1168,12 +1168,13 @@ gbuild verbosity numJobs pkg_descr lbi bm clbi = do | otherwise = mempty rpaths <- getRPaths lbi clbi - (cSrcs, inputFiles, inputModules) <- gbuildSources verbosity + (cSrcs, cxxSrcs, inputFiles, inputModules) <- gbuildSources verbosity (specVersion pkg_descr) tmpDir bm let isGhcDynamic = isDynamic comp dynamicTooSupported = supportsDynamicToo comp cObjs = map (`replaceExtension` objExtension) cSrcs + cxxObjs = map (`replaceExtension` objExtension) cxxSrcs needDynamic = gbuildNeedDynamic lbi bm needProfiling = withProfExe lbi @@ -1223,7 +1224,7 @@ gbuild verbosity numJobs pkg_descr lbi bm clbi = do ghcOptLinkFrameworkDirs = toNubListR $ PD.extraFrameworkDirs bnfo, ghcOptInputFiles = toNubListR - [tmpDir x | x <- cObjs] + [tmpDir x | x <- cObjs ++ cxxObjs] } dynLinkerOpts = mempty { ghcOptRPaths = rpaths @@ -1283,6 +1284,34 @@ gbuild verbosity numJobs pkg_descr lbi bm clbi = do runGhcProg compileOpts { ghcOptNoLink = toFlag True , ghcOptNumJobs = numJobs } + -- build any C++ sources + unless (null cxxSrcs) $ do + info verbosity "Building C++ Sources..." + sequence_ + [ do let baseCxxOpts = Internal.componentCxxGhcOptions verbosity implInfo + lbi bnfo clbi tmpDir filename + vanillaCxxOpts = if isGhcDynamic + -- Dynamic GHC requires C++ sources to be built + -- with -fPIC for REPL to work. See #2207. + then baseCxxOpts { ghcOptFPic = toFlag True } + else baseCxxOpts + profCxxOpts = vanillaCxxOpts `mappend` mempty { + ghcOptProfilingMode = toFlag True + } + sharedCxxOpts = vanillaCxxOpts `mappend` mempty { + ghcOptFPic = toFlag True, + ghcOptDynLinkMode = toFlag GhcDynamicOnly + } + opts | needProfiling = profCxxOpts + | needDynamic = sharedCxxOpts + | otherwise = vanillaCxxOpts + odir = fromFlag (ghcOptObjDir opts) + createDirectoryIfMissingVerbose verbosity True odir + needsRecomp <- checkNeedsRecompilation filename opts + when needsRecomp $ + runGhcProg opts + | filename <- cxxSrcs ] + -- build any C sources unless (null cSrcs) $ do info verbosity "Building C Sources..." @@ -1757,6 +1786,7 @@ installLib verbosity lbi targetDir dynlibTargetDir _builtDir _pkg lib clbi = do hasLib = not $ null (allLibModules lib clbi) && null (cSources (libBuildInfo lib)) + && null (cxxSources (libBuildInfo lib)) has_code = not (componentIsIndefinite clbi) whenHasCode = when has_code whenVanilla = when (hasLib && withVanillaLib lbi) diff --git a/Cabal/Distribution/Simple/GHC/IPI642.hs b/Cabal/Distribution/Simple/GHC/IPI642.hs index 8b275035e..46def94e9 100644 --- a/Cabal/Distribution/Simple/GHC/IPI642.hs +++ b/Cabal/Distribution/Simple/GHC/IPI642.hs @@ -57,6 +57,7 @@ data InstalledPackageInfo = InstalledPackageInfo { depends :: [PackageIdentifier], hugsOptions :: [String], ccOptions :: [String], + cxxOptions :: [String], ldOptions :: [String], frameworkDirs :: [FilePath], frameworks :: [String], @@ -105,6 +106,7 @@ toCurrent ipi@InstalledPackageInfo{} = Current.depends = map (Current.mkLegacyUnitId . convertPackageId) (depends ipi), Current.abiDepends = [], Current.ccOptions = ccOptions ipi, + Current.cxxOptions = cxxOptions ipi, Current.ldOptions = ldOptions ipi, Current.frameworkDirs = frameworkDirs ipi, Current.frameworks = frameworks ipi, diff --git a/Cabal/Distribution/Simple/GHC/Internal.hs b/Cabal/Distribution/Simple/GHC/Internal.hs index 08adc9c11..2e2a6cf04 100644 --- a/Cabal/Distribution/Simple/GHC/Internal.hs +++ b/Cabal/Distribution/Simple/GHC/Internal.hs @@ -294,6 +294,16 @@ componentCcGhcOptions verbosity _implInfo lbi bi clbi odir filename = NormalDebugInfo -> ["-g"] MaximalDebugInfo -> ["-g3"]) ++ PD.ccOptions bi, + 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 } diff --git a/Cabal/Distribution/Simple/JHC.hs b/Cabal/Distribution/Simple/JHC.hs index 52e072652..39e3413d2 100644 --- a/Cabal/Distribution/Simple/JHC.hs +++ b/Cabal/Distribution/Simple/JHC.hs @@ -152,6 +152,8 @@ constructJHCCmdLine lbi bi clbi _odir verbosity = ++ concat [["-i", l] | l <- nub (hsSourceDirs bi)] ++ ["-i", autogenComponentModulesDir lbi clbi] ++ ["-i", autogenPackageModulesDir lbi] + -- Perhaps we need to add the cxxOptions here too? + -- Don't know enough about JHC ++ ["-optc" ++ opt | opt <- PD.ccOptions bi] -- It would be better if JHC would accept package names with versions, -- but JHC-0.7.2 doesn't accept this. diff --git a/Cabal/Distribution/Simple/PreProcess.hs b/Cabal/Distribution/Simple/PreProcess.hs index 33b94ab56..30c740b4f 100644 --- a/Cabal/Distribution/Simple/PreProcess.hs +++ b/Cabal/Distribution/Simple/PreProcess.hs @@ -423,7 +423,8 @@ ppHsc2hs bi lbi clbi = ++ [ "--cflag=-I" ++ dir | dir <- PD.includeDirs bi ] ++ [ "--cflag=-I" ++ buildDir lbi dir | dir <- PD.includeDirs bi ] ++ [ "--cflag=" ++ opt | opt <- PD.ccOptions bi - ++ PD.cppOptions bi ] + ++ PD.cppOptions bi + ++ PD.cxxOptions bi ] ++ [ "--cflag=" ++ opt | opt <- [ "-I" ++ autogenComponentModulesDir lbi clbi, "-I" ++ autogenPackageModulesDir lbi, @@ -438,7 +439,8 @@ ppHsc2hs bi lbi clbi = ++ [ "--cflag=" ++ opt | pkg <- pkgs , opt <- [ "-I" ++ opt | opt <- Installed.includeDirs pkg ] - ++ [ opt | opt <- Installed.ccOptions pkg ] ] + ++ [ opt | opt <- Installed.ccOptions pkg + ++ Installed.cxxOptions pkg ] ] ++ [ "--lflag=" ++ opt | pkg <- pkgs , opt <- [ "-L" ++ opt | opt <- Installed.libraryDirs pkg ] @@ -501,7 +503,8 @@ ppC2hs bi lbi clbi = ++ [ "--cppopts=" ++ opt | pkg <- pkgs , opt <- [ "-I" ++ opt | opt <- Installed.includeDirs pkg ] - ++ [ opt | opt@('-':c:_) <- Installed.ccOptions pkg + ++ [ opt | opt@('-':c:_) <- (Installed.ccOptions pkg ++ + Installed.cxxOptions pkg) , c `elem` "DIU" ] ] --TODO: install .chi files for packages, so we can --include -- those dirs here, for the dependencies @@ -525,7 +528,7 @@ getCppOptions bi lbi = platformDefines lbi ++ cppOptions bi ++ ["-I" ++ dir | dir <- PD.includeDirs bi] - ++ [opt | opt@('-':c:_) <- PD.ccOptions bi, c `elem` "DIU"] + ++ [opt | opt@('-':c:_) <- PD.ccOptions bi ++ PD.cxxOptions bi, c `elem` "DIU"] platformDefines :: LocalBuildInfo -> [String] platformDefines lbi = diff --git a/Cabal/Distribution/Simple/Register.hs b/Cabal/Distribution/Simple/Register.hs index 56474eb4b..5565d78c1 100644 --- a/Cabal/Distribution/Simple/Register.hs +++ b/Cabal/Distribution/Simple/Register.hs @@ -443,6 +443,7 @@ generalInstalledPackageInfo adjustRelIncDirs pkg abi_hash lib lbi clbi installDi IPI.ccOptions = [], -- Note. NOT ccOptions bi! -- We don't want cc-options to be propagated -- to C compilations in other packages. + IPI.cxxOptions = [], -- Also. NOT cxxOptions bi! IPI.ldOptions = ldOptions bi, IPI.frameworks = frameworks bi, IPI.frameworkDirs = extraFrameworkDirs bi, diff --git a/Cabal/Distribution/Simple/SrcDist.hs b/Cabal/Distribution/Simple/SrcDist.hs index 74098e37d..3c52350e2 100644 --- a/Cabal/Distribution/Simple/SrcDist.hs +++ b/Cabal/Distribution/Simple/SrcDist.hs @@ -453,7 +453,7 @@ allSourcesBuildInfo verbosity bi pps modules = do in findFileWithExtension fileExts (hsSourceDirs bi) file | module_ <- modules ++ otherModules bi ] - return $ sources ++ catMaybes bootFiles ++ cSources bi ++ jsSources bi + return $ sources ++ catMaybes bootFiles ++ cSources bi ++ cxxSources bi ++ jsSources bi where nonEmpty x _ [] = x diff --git a/Cabal/Distribution/Types/InstalledPackageInfo.hs b/Cabal/Distribution/Types/InstalledPackageInfo.hs index 008ac74dc..6e4e247a6 100644 --- a/Cabal/Distribution/Types/InstalledPackageInfo.hs +++ b/Cabal/Distribution/Types/InstalledPackageInfo.hs @@ -80,6 +80,7 @@ data InstalledPackageInfo depends :: [UnitId], abiDepends :: [AbiDependency], ccOptions :: [String], + cxxOptions :: [String], ldOptions :: [String], frameworkDirs :: [FilePath], frameworks :: [String], diff --git a/Cabal/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs b/Cabal/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs index b4a132f55..9b3279cb1 100644 --- a/Cabal/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs +++ b/Cabal/Distribution/Types/InstalledPackageInfo/FieldGrammar.hs @@ -92,6 +92,7 @@ ipiFieldGrammar = mkInstalledPackageInfo <+> monoidalFieldAla "depends" (alaList FSep) L.depends <+> monoidalFieldAla "abi-depends" (alaList FSep) L.abiDepends <+> monoidalFieldAla "cc-options" (alaList' FSep Token) L.ccOptions + <+> monoidalFieldAla "cxx-options" (alaList' FSep Token) L.cxxOptions <+> monoidalFieldAla "ld-options" (alaList' FSep Token) L.ldOptions <+> monoidalFieldAla "framework-dirs" (alaList' FSep FilePathNT) L.frameworkDirs <+> monoidalFieldAla "frameworks" (alaList' FSep Token) L.frameworks diff --git a/Cabal/Distribution/Types/InstalledPackageInfo/Lens.hs b/Cabal/Distribution/Types/InstalledPackageInfo/Lens.hs index 36609b011..3896e07ef 100644 --- a/Cabal/Distribution/Types/InstalledPackageInfo/Lens.hs +++ b/Cabal/Distribution/Types/InstalledPackageInfo/Lens.hs @@ -153,6 +153,10 @@ ccOptions :: Lens' InstalledPackageInfo [String] ccOptions f s = fmap (\x -> s { T.ccOptions = x }) (f (T.ccOptions s)) {-# INLINE ccOptions #-} +cxxOptions :: Lens' InstalledPackageInfo [String] +cxxOptions f s = fmap (\x -> s { T.cxxOptions = x }) (f (T.cxxOptions s)) +{-# INLINE cxxOptions #-} + ldOptions :: Lens' InstalledPackageInfo [String] ldOptions f s = fmap (\x -> s { T.ldOptions = x }) (f (T.ldOptions s)) {-# INLINE ldOptions #-} -- 2.11.4.GIT