diff --git a/Cabal/src/Distribution/Simple/GHC.hs b/Cabal/src/Distribution/Simple/GHC.hs index c1eece45c3f..e8b1a3ff252 100644 --- a/Cabal/src/Distribution/Simple/GHC.hs +++ b/Cabal/src/Distribution/Simple/GHC.hs @@ -60,7 +60,6 @@ module Distribution.Simple.GHC , hcPkgInfo , registerPackage , Internal.componentGhcOptions - , Internal.componentCcGhcOptions , getGhcAppDir , getLibDir , compilerBuildWay @@ -825,7 +824,7 @@ libAbiHash verbosity _pkg_descr lbi lib clbi = do , ghcOptFPic = toFlag True , ghcOptHiSuffix = toFlag "dyn_hi" , ghcOptObjSuffix = toFlag "dyn_o" - , ghcOptExtra = hcOptions GHC libBi ++ hcSharedOptions GHC libBi + , ghcOptExtra = hcSharedOptions GHC libBi } profArgs = vanillaArgs @@ -837,7 +836,7 @@ libAbiHash verbosity _pkg_descr lbi lib clbi = do (withProfLibDetail lbi) , ghcOptHiSuffix = toFlag "p_hi" , ghcOptObjSuffix = toFlag "p_o" - , ghcOptExtra = hcOptions GHC libBi ++ hcProfOptions GHC libBi + , ghcOptExtra = hcProfOptions GHC libBi } profDynArgs = vanillaArgs @@ -851,7 +850,7 @@ libAbiHash verbosity _pkg_descr lbi lib clbi = do , ghcOptFPic = toFlag True , ghcOptHiSuffix = toFlag "p_dyn_hi" , ghcOptObjSuffix = toFlag "p_dyn_o" - , ghcOptExtra = hcOptions GHC libBi ++ hcProfSharedOptions GHC libBi + , ghcOptExtra = hcProfSharedOptions GHC libBi } ghcArgs = let (libWays, _, _) = buildWays lbi diff --git a/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs b/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs index ad273d89212..5a7232cfe90 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build/ExtraSources.hs @@ -10,6 +10,7 @@ import Control.Monad import Data.Foldable import Distribution.Simple.Flag import qualified Distribution.Simple.GHC.Internal as Internal +import Distribution.Simple.Program import Distribution.Simple.Program.GHC import Distribution.Simple.Utils import Distribution.Utils.NubList @@ -17,12 +18,12 @@ import Distribution.Utils.NubList import Distribution.Types.BuildInfo import Distribution.Types.Component import Distribution.Types.TargetInfo +import Distribution.Types.Version import Distribution.Simple.Build.Inputs -import Distribution.Simple.GHC.Build.Modules +import Distribution.Simple.BuildWay import Distribution.Simple.GHC.Build.Utils import Distribution.Simple.LocalBuildInfo -import Distribution.Simple.Program.Types import Distribution.Simple.Setup.Common (commonSetupTempFileOptions) import Distribution.System (Arch (JavaScript), Platform (..)) import Distribution.Types.ComponentLocalBuildInfo @@ -77,7 +78,23 @@ buildCSources buildCSources mbMainFile = buildExtraSources "C Sources" - Internal.componentCcGhcOptions + ( \verbosity lbi bi clbi odir filename -> + (Internal.sourcesGhcOptions verbosity lbi bi clbi odir filename) + { -- C++ compiler options: GHC >= 8.10 requires -optcxx, older requires -optc + -- we want to be able to support cxx-options and cc-options separately + -- https://gitlab.haskell.org/ghc/ghc/-/issues/16477 + -- see example in cabal-testsuite/PackageTests/FFI/ForeignOptsC + ghcOptCxxOptions = + Internal.separateGhcOptions + (mkVersion [8, 10]) + (compiler lbi) + (Internal.optimizationCFlags lbi ++ cxxOptions bi) + , -- there are problems with linking with versions below 9.4, + -- that's why we need this replacement for linkGhcOptions + -- https://github.com/haskell/cabal/issues/11712 + ghcOptCcProgram = maybeToFlag $ programPath <$> lookupProgram gccProgram (withPrograms lbi) + } + ) ( \c -> do let cFiles = cSources (componentBuildInfo c) case c of @@ -90,7 +107,23 @@ buildCSources mbMainFile = buildCxxSources mbMainFile = buildExtraSources "C++ Sources" - Internal.componentCxxGhcOptions + ( \verbosity lbi bi clbi odir filename -> + (Internal.sourcesGhcOptions verbosity lbi bi clbi odir filename) + { -- C++ compiler options: GHC >= 8.10 requires -optcxx, older requires -optc + -- we want to be able to support cxx-options and cc-options separately + -- https://gitlab.haskell.org/ghc/ghc/-/issues/16477 + -- see example in cabal-testsuite/PackageTests/FFI/ForeignOptsCxx + ghcOptCcOptions = + Internal.separateGhcOptions + (mkVersion [8, 10]) + (compiler lbi) + (Internal.optimizationCFlags lbi ++ ccOptions bi) + , -- there are problems with linking with versions below 9.4, + -- that's why we need this replacement for linkGhcOptions + -- https://github.com/haskell/cabal/issues/11712 + ghcOptCcProgram = maybeToFlag $ programPath <$> lookupProgram gccProgram (withPrograms lbi) + } + ) ( \c -> do let cxxFiles = cxxSources (componentBuildInfo c) case c of @@ -105,7 +138,7 @@ buildJsSources _mbMainFile ghcProg buildTargetDir neededWays verbHandles = do let hasJsSupport = hostArch == JavaScript buildExtraSources "JS Sources" - Internal.componentJsGhcOptions + Internal.sourcesGhcOptions ( \c -> if hasJsSupport then -- JS files are C-like with GHC's JS backend: they are @@ -122,12 +155,12 @@ buildJsSources _mbMainFile ghcProg buildTargetDir neededWays verbHandles = do buildAsmSources _mbMainFile = buildExtraSources "Assembler Sources" - Internal.componentAsmGhcOptions + Internal.sourcesGhcOptions (asmSources . componentBuildInfo) buildCmmSources _mbMainFile = buildExtraSources "C-- Sources" - Internal.componentCmmGhcOptions + Internal.sourcesGhcOptions (cmmSources . componentBuildInfo) -- | Create 'PreBuildComponentRules' for a given type of extra build sources @@ -145,9 +178,7 @@ buildExtraSources -> GhcOptions ) -- ^ Function to determine the @'GhcOptions'@ for the - -- invocation of GHC when compiling these extra sources (e.g. - -- @'Internal.componentCxxGhcOptions'@, - -- @'Internal.componentCmmGhcOptions'@) + -- invocation of GHC when compiling these extra sources -> (Component -> [SymbolicPath Pkg File]) -- ^ View the extra sources of a component, typically from -- the build info (e.g. @'asmSources'@, @'cSources'@). diff --git a/Cabal/src/Distribution/Simple/GHC/Build/Link.hs b/Cabal/src/Distribution/Simple/GHC/Build/Link.hs index d2a967dae45..667aca05f21 100644 --- a/Cabal/src/Distribution/Simple/GHC/Build/Link.hs +++ b/Cabal/src/Distribution/Simple/GHC/Build/Link.hs @@ -122,10 +122,9 @@ linkOrLoadComponent linkerOpts rpaths = mempty { ghcOptLinkOptions = - PD.ldOptions bi - ++ [ "-static" - | withFullyStaticExe lbi - ] + [ "-static" + | withFullyStaticExe lbi + ] -- Pass extra `ld-options` given -- through to GHC's linker. ++ maybe @@ -356,36 +355,11 @@ linkLibrary buildTargetDir cleanedExtraLibDirs pkg_descr verbosity runGhcProg li -- Right now, instead, we pass the path to each object file. ghcBaseLinkArgs :: GhcOptions ghcBaseLinkArgs = - mempty - { -- TODO: This basically duplicates componentGhcOptions. - -- I think we want to do the same as we do for executables: re-use the - -- base options, and link by module names, not object paths. - ghcOptExtra = hcStaticOptions GHC libBi - , ghcOptHideAllPackages = toFlag True - , ghcOptNoAutoLinkPackages = toFlag True - , ghcOptPackageDBs = withPackageDB lbi - , ghcOptThisUnitId = case clbi of - LibComponentLocalBuildInfo{componentCompatPackageKey = pk} -> - toFlag pk - _ -> mempty - , ghcOptThisComponentId = case clbi of - LibComponentLocalBuildInfo - { componentInstantiatedWith = insts - } -> - if null insts - then mempty - else toFlag (componentComponentId clbi) - _ -> mempty - , ghcOptInstantiatedWith = case clbi of - LibComponentLocalBuildInfo - { componentInstantiatedWith = insts - } -> - insts - _ -> [] - , ghcOptPackages = - toNubListR $ - Internal.mkGhcOptPackages mempty clbi - } + Internal.linkGhcOptions (verbosityLevel verbosity) lbi libBi clbi + <> mempty + { ghcOptExtra = hcStaticOptions GHC libBi + , ghcOptNoAutoLinkPackages = toFlag True + } -- After the relocation lib is created we invoke ghc -shared -- with the dependencies spelled out as -package arguments diff --git a/Cabal/src/Distribution/Simple/GHC/Internal.hs b/Cabal/src/Distribution/Simple/GHC/Internal.hs index 51e984a141f..597d9ce5fbb 100644 --- a/Cabal/src/Distribution/Simple/GHC/Internal.hs +++ b/Cabal/src/Distribution/Simple/GHC/Internal.hs @@ -1,6 +1,5 @@ {-# LANGUAGE DataKinds #-} {-# LANGUAGE FlexibleContexts #-} -{-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE RankNTypes #-} ----------------------------------------------------------------------------- @@ -20,12 +19,8 @@ module Distribution.Simple.GHC.Internal , getExtensions , targetPlatform , getGhcInfo - , componentCcGhcOptions - , componentCmmGhcOptions - , componentCxxGhcOptions - , componentAsmGhcOptions - , componentJsGhcOptions , componentGhcOptions + , sourcesGhcOptions , mkGHCiLibName , mkGHCiProfLibName , filterGhciFlags @@ -35,6 +30,9 @@ module Distribution.Simple.GHC.Internal , substTopDir , checkPackageDbEnvVar , profDetailLevelFlag + , separateGhcOptions + , linkGhcOptions + , optimizationCFlags -- * GHC platform and version strings , ghcArchString @@ -59,16 +57,14 @@ import qualified Data.Map as Map import qualified Data.Set as Set import Distribution.Backpack import Distribution.Compat.Stack -import qualified Distribution.InstalledPackageInfo as IPI import Distribution.Lex import qualified Distribution.ModuleName as ModuleName -import Distribution.PackageDescription import Distribution.Parsec (simpleParsec) import Distribution.Pretty (prettyShow) import Distribution.Simple.BuildPaths import Distribution.Simple.Compiler import Distribution.Simple.Errors -import Distribution.Simple.Flag (Flag, maybeToFlag, toFlag, pattern NoFlag) +import Distribution.Simple.Flag import Distribution.Simple.GHC.ImplInfo import Distribution.Simple.LocalBuildInfo import Distribution.Simple.Program @@ -76,15 +72,20 @@ import Distribution.Simple.Program.GHC import Distribution.Simple.Setup.Common (extraCompilationArtifacts) import Distribution.Simple.Utils import Distribution.System +import Distribution.Types.BuildInfo import Distribution.Types.ComponentLocalBuildInfo import Distribution.Types.GivenComponent +import qualified Distribution.Types.InstalledPackageInfo as IPI +import Distribution.Types.Library import Distribution.Types.LocalBuildInfo +import Distribution.Types.ModuleRenaming +import Distribution.Types.PackageName import Distribution.Types.TargetInfo import Distribution.Types.UnitId +import Distribution.Types.Version import Distribution.Utils.NubList (NubListR, toNubListR) import Distribution.Utils.Path import Distribution.Verbosity -import Distribution.Version (Version) import Language.Haskell.Extension import System.Directory (listDirectory) import System.Environment (getEnv) @@ -377,7 +378,7 @@ includePaths lbi bi clbi odir = | dir <- mapMaybe (symbolicPathRelative_maybe . unsafeCoerceSymbolicPath) $ includeDirs bi ] -componentCcGhcOptions +sourcesGhcOptions :: VerbosityLevel -> LocalBuildInfo -> BuildInfo @@ -385,148 +386,91 @@ componentCcGhcOptions -> SymbolicPath Pkg (Dir Artifacts) -> SymbolicPath Pkg File -> GhcOptions -componentCcGhcOptions verbosity lbi bi clbi 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) +sourcesGhcOptions verbosity lbi bi clbi odir filename = + (componentGhcOptions verbosity lbi bi clbi odir) + { ghcOptVerbosity = toFlag (min verbosity Normal) , ghcOptMode = toFlag GhcModeCompile , ghcOptInputFiles = toNubListR [filename] - , ghcOptCppIncludePath = includePaths lbi bi clbi odir - , ghcOptHideAllPackages = toFlag True - , ghcOptPackageDBs = withPackageDB lbi - , ghcOptPackages = toNubListR $ mkGhcOptPackages (promisedPkgs lbi) clbi - , ghcOptCcOptions = - ( case withOptimization lbi of - NoOptimisation -> [] - _ -> ["-O2"] - ) - ++ ( case withDebugInfo lbi of - NoDebugInfo -> [] - MinimalDebugInfo -> ["-g1"] - NormalDebugInfo -> ["-g"] - MaximalDebugInfo -> ["-g3"] - ) - ++ ccOptions bi - , ghcOptCcProgram = - maybeToFlag $ - programPath - <$> lookupProgram gccProgram (withPrograms lbi) , ghcOptObjDir = toFlag odir - , ghcOptExtra = hcOptions GHC bi - } - -componentCxxGhcOptions - :: VerbosityLevel - -> LocalBuildInfo - -> BuildInfo - -> ComponentLocalBuildInfo - -> SymbolicPath Pkg (Dir Artifacts) - -> SymbolicPath Pkg File - -> GhcOptions -componentCxxGhcOptions verbosity lbi bi clbi 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 = includePaths lbi bi clbi odir - , ghcOptHideAllPackages = toFlag True - , ghcOptPackageDBs = withPackageDB lbi , ghcOptPackages = toNubListR $ mkGhcOptPackages (promisedPkgs lbi) clbi - , ghcOptCxxOptions = - ( case withOptimization lbi of - NoOptimisation -> [] - _ -> ["-O2"] - ) - ++ ( case withDebugInfo lbi of - NoDebugInfo -> [] - MinimalDebugInfo -> ["-g1"] - NormalDebugInfo -> ["-g"] - MaximalDebugInfo -> ["-g3"] - ) - ++ cxxOptions bi - , ghcOptCcProgram = - maybeToFlag $ - programPath - <$> lookupProgram gccProgram (withPrograms lbi) - , ghcOptObjDir = toFlag odir - , ghcOptExtra = hcOptions GHC bi } -componentAsmGhcOptions - :: VerbosityLevel - -> LocalBuildInfo - -> BuildInfo - -> ComponentLocalBuildInfo - -> SymbolicPath Pkg (Dir Artifacts) - -> SymbolicPath Pkg File - -> GhcOptions -componentAsmGhcOptions verbosity lbi bi clbi 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 = includePaths lbi bi clbi odir - , ghcOptHideAllPackages = toFlag True - , ghcOptPackageDBs = withPackageDB lbi - , ghcOptPackages = toNubListR $ mkGhcOptPackages (promisedPkgs lbi) clbi - , ghcOptAsmOptions = - ( case withOptimization lbi of - NoOptimisation -> [] - _ -> ["-O2"] - ) - ++ ( case withDebugInfo lbi of - NoDebugInfo -> [] - MinimalDebugInfo -> ["-g1"] - NormalDebugInfo -> ["-g"] - MaximalDebugInfo -> ["-g3"] - ) - ++ asmOptions bi - , ghcOptObjDir = toFlag odir - , ghcOptExtra = hcOptions GHC bi - } +optimizationCFlags :: LocalBuildInfo -> [String] +optimizationCFlags lbi = + ( case withOptimization lbi of + -- see --disable-optimization + NoOptimisation -> [] + -- '*-options: -O[n]' is generally not needed. When building with + -- optimisations Cabal automatically adds '-O2' for * code. Setting it + -- yourself interferes with the --disable-optimization flag. + -- see https://github.com/haskell/cabal/pull/8250 + NormalOptimisation -> ["-O2"] + -- see --enable-optimization + MaximumOptimisation -> ["-O2"] + ) + ++ ( case withDebugInfo lbi of + NoDebugInfo -> [] + MinimalDebugInfo -> ["-g1"] + NormalDebugInfo -> ["-g"] + MaximalDebugInfo -> ["-g3"] + ) + +-- Since GHC is sensitive to what is given to it, we sometimes need to +-- be able to pass options only to new versions +-- We want to be able to support C++ and C separately in older ghc +-- See example in buildExtraSources "C++ Sources" or "C Sources" +separateGhcOptions :: Monoid a => Version -> Compiler -> a -> a +separateGhcOptions ver comp defaultOptions = + case compilerCompatVersion GHC comp of + Just v + | v >= ver -> defaultOptions + | otherwise -> mempty + Nothing -> mempty -componentJsGhcOptions +componentGhcOptions :: VerbosityLevel -> LocalBuildInfo -> BuildInfo -> ComponentLocalBuildInfo - -> SymbolicPath Pkg (Dir Artifacts) - -> SymbolicPath Pkg File + -> SymbolicPath Pkg (Dir build) -> GhcOptions -componentJsGhcOptions verbosity lbi bi clbi 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] - , ghcOptJSppOptions = jsppOptions bi - , ghcOptCppIncludePath = includePaths lbi bi clbi odir - , ghcOptHideAllPackages = toFlag True - , ghcOptPackageDBs = withPackageDB lbi - , ghcOptPackages = toNubListR $ mkGhcOptPackages (promisedPkgs lbi) clbi - , ghcOptObjDir = toFlag odir - , ghcOptExtra = hcOptions GHC bi - } +componentGhcOptions verbosity lbi bi clbi odir = + let implInfo = getImplInfo $ compiler lbi + in (linkGhcOptions verbosity lbi bi clbi) + { ghcOptSourcePath = + toNubListR $ + (hsSourceDirs bi) + ++ [coerceSymbolicPath odir] + ++ [autogenComponentModulesDir lbi clbi] + ++ [autogenPackageModulesDir lbi] + , ghcOptCppIncludePath = includePaths lbi bi clbi odir + , ghcOptObjDir = toFlag $ coerceSymbolicPath odir + , ghcOptHiDir = toFlag $ coerceSymbolicPath odir + , ghcOptHieDir = bool NoFlag (toFlag $ coerceSymbolicPath odir (extraCompilationArtifacts makeRelativePathEx "hie")) $ flagHie implInfo + , ghcOptStubDir = toFlag $ coerceSymbolicPath odir + , ghcOptOutputDir = toFlag $ coerceSymbolicPath odir + , ghcOptBytecodeDir = toFlag $ coerceSymbolicPath odir + } -componentGhcOptions +linkGhcOptions :: VerbosityLevel -> LocalBuildInfo -> BuildInfo -> ComponentLocalBuildInfo - -> SymbolicPath Pkg (Dir build) -> GhcOptions -componentGhcOptions verbosity lbi bi clbi odir = +linkGhcOptions verbosity lbi bi clbi = let implInfo = getImplInfo $ compiler lbi in 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) + , ghcOptCcOptions = ccOptions bi + , ghcOptCxxOptions = cxxOptions bi + , ghcOptAsmOptions = asmOptions bi + , ghcOptLinkOptions = ldOptions bi + , ghcOptCppOptions = cppOptions bi + , ghcOptJSppOptions = jsppOptions bi + , ghcOptExtra = hcOptions GHC bi <> cmmOptions bi , ghcOptCabal = toFlag True , ghcOptThisUnitId = case clbi of LibComponentLocalBuildInfo{componentCompatPackageKey = pk} -> @@ -561,27 +505,11 @@ componentGhcOptions verbosity lbi bi clbi odir = , ghcOptSplitSections = toFlag (splitSections lbi) , ghcOptSplitObjs = toFlag (splitObjs lbi) , ghcOptSourcePathClear = toFlag True - , ghcOptSourcePath = - toNubListR $ - (hsSourceDirs bi) - ++ [coerceSymbolicPath odir] - ++ [autogenComponentModulesDir lbi clbi] - ++ [autogenPackageModulesDir lbi] - , ghcOptCppIncludePath = includePaths lbi bi clbi odir - , ghcOptCppOptions = cppOptions bi - , ghcOptJSppOptions = jsppOptions bi , ghcOptCppIncludes = toNubListR [coerceSymbolicPath (autogenComponentModulesDir lbi clbi makeRelativePathEx cppHeaderName)] , ghcOptFfiIncludes = toNubListR $ map getSymbolicPath $ includes bi - , ghcOptObjDir = toFlag $ coerceSymbolicPath odir - , ghcOptHiDir = toFlag $ coerceSymbolicPath odir - , ghcOptHieDir = bool NoFlag (toFlag $ coerceSymbolicPath odir (extraCompilationArtifacts makeRelativePathEx "hie")) $ flagHie implInfo - , ghcOptBytecodeDir = toFlag $ coerceSymbolicPath odir - , ghcOptStubDir = toFlag $ coerceSymbolicPath odir - , ghcOptOutputDir = toFlag $ coerceSymbolicPath odir , ghcOptOptimisation = toGhcOptimisation (withOptimization lbi) , ghcOptDebugInfo = toFlag (withDebugInfo lbi) - , ghcOptExtra = hcOptions GHC bi , ghcOptExtraPath = toNubListR exe_paths , ghcOptLanguage = toFlag (fromMaybe Haskell98 (defaultLanguage bi)) , -- Unsupported extensions have already been checked by configure @@ -601,34 +529,6 @@ toGhcOptimisation NoOptimisation = mempty -- TODO perhaps override? toGhcOptimisation NormalOptimisation = toFlag GhcNormalOptimisation toGhcOptimisation MaximumOptimisation = toFlag GhcMaximumOptimisation -componentCmmGhcOptions - :: VerbosityLevel - -> LocalBuildInfo - -> BuildInfo - -> ComponentLocalBuildInfo - -> SymbolicPath Pkg (Dir Artifacts) - -> SymbolicPath Pkg File - -> GhcOptions -componentCmmGhcOptions verbosity lbi bi clbi 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 = includePaths lbi bi clbi odir - , ghcOptCppOptions = cppOptions bi - , ghcOptCppIncludes = - toNubListR [autogenComponentModulesDir lbi clbi makeRelativePathEx cppHeaderName] - , ghcOptHideAllPackages = toFlag True - , ghcOptPackageDBs = withPackageDB lbi - , ghcOptPackages = toNubListR $ mkGhcOptPackages (promisedPkgs lbi) clbi - , ghcOptOptimisation = toGhcOptimisation (withOptimization lbi) - , ghcOptDebugInfo = toFlag (withDebugInfo lbi) - , ghcOptExtra = hcOptions GHC bi <> cmmOptions bi - , ghcOptObjDir = toFlag odir - } - -- | Strip out flags that are not supported in ghci filterGhciFlags :: [String] -> [String] filterGhciFlags = filter supported diff --git a/Cabal/src/Distribution/Simple/GHCJS.hs b/Cabal/src/Distribution/Simple/GHCJS.hs index 412842ed9ac..583a8060df7 100644 --- a/Cabal/src/Distribution/Simple/GHCJS.hs +++ b/Cabal/src/Distribution/Simple/GHCJS.hs @@ -24,7 +24,6 @@ module Distribution.Simple.GHCJS , hcPkgInfo , registerPackage , componentGhcOptions - , Internal.componentCcGhcOptions , getLibDir , isDynamic , getGlobalPackageDB @@ -1468,13 +1467,21 @@ gbuild verbosity numJobs pkg_descr lbi bm clbi = do sequence_ [ do let baseCxxOpts = - Internal.componentCxxGhcOptions - (verbosityLevel verbosity) - lbi - bnfo - clbi - tmpDir - filename + (Internal.sourcesGhcOptions (verbosityLevel verbosity) lbi bnfo clbi odir filename) + { -- C++ compiler options: GHC >= 8.10 requires -optcxx, older requires -optc + -- we want to be able to support cxx-options and cc-options separately + -- https://gitlab.haskell.org/ghc/ghc/-/issues/16477 + -- see example in cabal-testsuite/PackageTests/FFI/ForeignOptsCxx + ghcOptCcOptions = + Internal.separateGhcOptions + (mkVersion [8, 10]) + (compiler lbi) + (Internal.optimizationCFlags lbi ++ ccOptions bnfo) + , -- there are problems with linking with versions below 9.4, + -- that's why we need this replacement for linkGhcOptions + -- https://github.com/haskell/cabal/issues/11712 + ghcOptCcProgram = maybeToFlag $ programPath <$> lookupProgram gccProgram (withPrograms lbi) + } vanillaCxxOpts = if isGhcDynamic then -- Dynamic GHC requires C++ sources to be built @@ -1514,13 +1521,21 @@ gbuild verbosity numJobs pkg_descr lbi bm clbi = do sequence_ [ do let baseCcOpts = - Internal.componentCcGhcOptions - (verbosityLevel verbosity) - lbi - bnfo - clbi - tmpDir - filename + (Internal.sourcesGhcOptions (verbosityLevel verbosity) lbi bnfo clbi tmpDir filename) + { -- C++ compiler options: GHC >= 8.10 requires -optcxx, older requires -optc + -- we want to be able to support cxx-options and cc-options separately + -- https://gitlab.haskell.org/ghc/ghc/-/issues/16477 + -- see example in cabal-testsuite/PackageTests/FFI/ForeignOptsC + ghcOptCxxOptions = + Internal.separateGhcOptions + (mkVersion [8, 10]) + (compiler lbi) + (Internal.optimizationCFlags lbi ++ cxxOptions bnfo) + , -- there are problems with linking with versions below 9.4, + -- that's why we need this replacement for linkGhcOptions + -- https://github.com/haskell/cabal/issues/11712 + ghcOptCcProgram = maybeToFlag $ programPath <$> lookupProgram gccProgram (withPrograms lbi) + } vanillaCcOpts = if isGhcDynamic then -- Dynamic GHC requires C sources to be built diff --git a/Cabal/src/Distribution/Simple/Program/GHC.hs b/Cabal/src/Distribution/Simple/Program/GHC.hs index 7ecef3ce04a..86b8fa40fd4 100644 --- a/Cabal/src/Distribution/Simple/Program/GHC.hs +++ b/Cabal/src/Distribution/Simple/Program/GHC.hs @@ -873,6 +873,7 @@ renderGhcOptions comp _platform@(Platform _arch os) opts ] , ["-optc" ++ opt | opt <- ghcOptCcOptions opts] , -- C++ compiler options: GHC >= 8.10 requires -optcxx, older requires -optc + -- https://gitlab.haskell.org/ghc/ghc/-/issues/16477 let cxxflag = case compilerCompatVersion GHC comp of Just v | v >= mkVersion [8, 10] -> "-optcxx" _ -> "-optc" diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/Main.hs b/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/Main.hs new file mode 100644 index 00000000000..f46505ab473 --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/Main.hs @@ -0,0 +1,15 @@ +{-# LANGUAGE CApiFFI #-} + +module Main where + +import Foreign.C (CInt (..)) + +foreign import capi "clib.h myplus" + myplus :: CInt -> CInt -> IO CInt + +main :: IO () +main = do + result <- myplus 5 6 + if (result == 11) + then putStrLn ("The result is " ++ show result) + else error ("Expected value 11, got " ++ show result) diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/README.md b/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/README.md new file mode 100644 index 00000000000..e9484711f3d --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/README.md @@ -0,0 +1,3 @@ +# ForeignOptsCapi + +This test case asserts that cabal passes `cc-options` to the C compiler when use `foreign import capi`. diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/cabal.out b/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/cabal.out new file mode 100644 index 00000000000..7b6f22a35ad --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/cabal.out @@ -0,0 +1,10 @@ +# cabal v2-build +Resolving dependencies... +Build profile: -w ghc- -O1 +In order, the following will be built: + - foreign-opts-capi-0.1 (exe:foreign-opts-capi-exe) (first run) +Configuring executable 'foreign-opts-capi-exe' for foreign-opts-capi-0.1... +Preprocessing executable 'foreign-opts-capi-exe' for foreign-opts-capi-0.1... +Building executable 'foreign-opts-capi-exe' for foreign-opts-capi-0.1... +# foreign-opts-capi foreign-opts-capi-exe +The result is 11 diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/cabal.project b/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/cabal.project new file mode 100644 index 00000000000..e6fdbadb439 --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/cabal.project @@ -0,0 +1 @@ +packages: . diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/cabal.test.hs b/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/cabal.test.hs new file mode 100644 index 00000000000..dc22334a884 --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/cabal.test.hs @@ -0,0 +1,4 @@ +import Test.Cabal.Prelude +main = cabalTest $ do + cabal "v2-build" ["foreign-opts-capi-exe"] + withPlan $ runPlanExe "foreign-opts-capi" "foreign-opts-capi-exe" [] diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/cbits/clib.c b/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/cbits/clib.c new file mode 100644 index 00000000000..e69de29bb2d diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/cbits/clib.h b/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/cbits/clib.h new file mode 100644 index 00000000000..d3f26d370ca --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/cbits/clib.h @@ -0,0 +1,7 @@ +#ifndef MYDEF +#error "Did not get required MYDEF from cc-options" +#endif + +static inline int myplus(int a, int b) { + return a + b; +} diff --git a/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/foreign-opts-capi.cabal b/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/foreign-opts-capi.cabal new file mode 100644 index 00000000000..68f3b45603e --- /dev/null +++ b/cabal-testsuite/PackageTests/FFI/ForeignOptsCapi/foreign-opts-capi.cabal @@ -0,0 +1,11 @@ +cabal-version: 3.0 +name: foreign-opts-capi +version: 0.1 +build-type: Simple + +executable foreign-opts-capi-exe + main-is: Main.hs + build-depends: base + default-language: Haskell2010 + include-dirs: cbits + cc-options: -DMYDEF=1 diff --git a/changelog.d/pr-10969.md b/changelog.d/pr-10969.md new file mode 100644 index 00000000000..920ff6a64ef --- /dev/null +++ b/changelog.d/pr-10969.md @@ -0,0 +1,22 @@ +--- +synopsis: Pass *-options and -pgmc gcc to GHC when compiling ordinary Haskell sources +packages: [Cabal] +prs: 10969 +issues: [9801, 4435] +significance: significant +--- + +`cc-options`, `cxx-options`, `jspp-options`, `asm-options`, +`cmm-options`, `ld-options`, `cpp-options` should be always passed +when invoking GHC, similarly as `ghc-options` should be always used when +invoking `ghc` - regardless of what is the intention of a particular GHC-call. +GHC might use or not use the options, Cabal cannot know and should not guess. + +[Historical note] +Before `ghc` 8.10, `cc-options` and `cxx-options` were passed via one flag `-optc`, +then in 8.10 they started to split into `-optc` and `-optcxx`, cabal picked up +this change and started to give flags separately not only for new versions, +but also for old ones. That is, now for 8.8 we send `-optc` flags separately for +different sources. + +`cc-options` and `cxx-options` still need to be separated (C/C++) for versions below 8.10.