diff --git a/Cabal/src/Distribution/Simple/ConfigureScript.hs b/Cabal/src/Distribution/Simple/ConfigureScript.hs index 86c5b384e865049ecad78d86fcc1877ddb25f8eb..6374d510c55d3bc1c3311b823df8038006721ea4 100644 --- a/Cabal/src/Distribution/Simple/ConfigureScript.hs +++ b/Cabal/src/Distribution/Simple/ConfigureScript.hs @@ -78,6 +78,18 @@ runConfigureScript cfg flags programDb hp = do -- We don't try and tell configure which ld to use, as we don't have -- a way to pass its flags too + -- Do not presume the CXX compiler is available, but it always will be after 9.4. + (mcxxProgShort, mcxxFlags) <- do + mprog <- needProgram verbosity gppProgram programDb + case mprog of + Just (p, _) -> do + let pInv = programInvocation p [] + let cxxProg = progInvokePath pInv + let cxxFlags = progInvokeArgs pInv + cxxProgShort <- getShortPathName cxxProg + return (Just cxxProgShort, Just cxxFlags) + Nothing -> return (Nothing, Nothing) + let configureFile' = toUnix configureFile -- autoconf is fussy about filenames, and has a set of forbidden -- characters that can't appear in the build directory, etc: @@ -159,9 +171,7 @@ runConfigureScript cfg flags programDb hp = do ) ] let extraPath = fromNubList $ configProgramPathExtra cfg - let cflagsEnv = - maybe (unwords ccFlags) (++ (" " ++ unwords ccFlags)) $ - lookup "CFLAGS" env + let mkFlagsEnv fs var = maybe (unwords fs) (++ (" " ++ unwords fs)) (lookup var env) spSep = [FilePath.searchPathSeparator] pathEnv = maybe @@ -169,11 +179,17 @@ runConfigureScript cfg flags programDb hp = do ((intercalate spSep extraPath ++ spSep) ++) $ lookup "PATH" env overEnv = - ("CFLAGS", Just cflagsEnv) - : [("PATH", Just pathEnv) | not (null extraPath)] + ("CFLAGS", Just (mkFlagsEnv ccFlags "CFLAGS")) + : [("CXXFLAGS", Just (mkFlagsEnv cxxFlags "CXXFLAGS")) | Just cxxFlags <- [mcxxFlags]] + ++ [("PATH", Just pathEnv) | not (null extraPath)] ++ cabalFlagEnv maybeHostFlag = if hp == buildPlatform then [] else ["--host=" ++ show (pretty hp)] - args' = configureFile' : args ++ ["CC=" ++ ccProgShort] ++ maybeHostFlag + args' = + configureFile' + : args + ++ ["CC=" ++ ccProgShort] + ++ ["CXX=" ++ cxxProgShort | Just cxxProgShort <- [mcxxProgShort]] + ++ maybeHostFlag shProg = simpleProgram "sh" progDb <- prependProgramSearchPath verbosity extraPath [] emptyProgramDb shConfiguredProg <- diff --git a/Cabal/src/Distribution/Simple/GHC/Internal.hs b/Cabal/src/Distribution/Simple/GHC/Internal.hs index 6e27b41bc838ab16e70de78981b9ffb978ac7ade..18ab1a76ff92bd599efaa646f3fba50d0445e574 100644 --- a/Cabal/src/Distribution/Simple/GHC/Internal.hs +++ b/Cabal/src/Distribution/Simple/GHC/Internal.hs @@ -110,6 +110,11 @@ configureToolchain _implInfo ghcProg ghcInfo = { programFindLocation = findProg gccProgramName extraGccPath , programPostConf = configureGcc } + . addKnownProgram + gppProgram + { programFindLocation = findProg gppProgramName extraGppPath + , programPostConf = configureGpp + } . addKnownProgram ldProgram { programFindLocation = findProg ldProgramName extraLdPath @@ -137,6 +142,7 @@ configureToolchain _implInfo ghcProg ghcInfo = maybeName prog = maybe (programName prog) (dropExeExtension . takeFileName) gccProgramName = maybeName gccProgram mbGccLocation + gppProgramName = maybeName gppProgram mbGppLocation ldProgramName = maybeName ldProgram mbLdLocation arProgramName = maybeName arProgram mbArLocation stripProgramName = maybeName stripProgram mbStripLocation @@ -149,18 +155,20 @@ configureToolchain _implInfo ghcProg ghcInfo = mbDir = maybeToList . fmap takeDirectory $ mbPath extraGccPath = mkExtraPath mbGccLocation windowsExtraGccDir + extraGppPath = mkExtraPath mbGppLocation windowsExtraGppDir extraLdPath = mkExtraPath mbLdLocation windowsExtraLdDir extraArPath = mkExtraPath mbArLocation windowsExtraArDir extraStripPath = mkExtraPath mbStripLocation windowsExtraStripDir -- on Windows finding and configuring ghc's gcc & binutils is a bit special ( windowsExtraGccDir + , windowsExtraGppDir , windowsExtraLdDir , windowsExtraArDir , windowsExtraStripDir ) = let b = mingwBinDir </> binPrefix - in (b, b, b, b) + in (b, b, b, b, b) findProg :: String @@ -176,11 +184,13 @@ configureToolchain _implInfo ghcProg ghcInfo = -- Read tool locations from the 'ghc --info' output. Useful when -- cross-compiling. mbGccLocation = Map.lookup "C compiler command" ghcInfo + mbGppLocation = Map.lookup "C++ compiler command" ghcInfo mbLdLocation = Map.lookup "ld command" ghcInfo mbArLocation = Map.lookup "ar command" ghcInfo mbStripLocation = Map.lookup "strip command" ghcInfo ccFlags = getFlags "C compiler flags" + cxxFlags = getFlags "C++ compiler flags" -- GHC 7.8 renamed "Gcc Linker flags" to "C compiler link flags" -- and "Ld Linker flags" to "ld flags" (GHC #4862). gccLinkerFlags = getFlags "Gcc Linker flags" ++ getFlags "C compiler link flags" @@ -210,6 +220,15 @@ configureToolchain _implInfo ghcProg ghcInfo = ++ gccLinkerFlags } + configureGpp :: Verbosity -> ConfiguredProgram -> IO ConfiguredProgram + configureGpp _v gppProg = do + return + gppProg + { programDefaultArgs = + programDefaultArgs gppProg + ++ cxxFlags + } + configureLd :: Verbosity -> ConfiguredProgram -> IO ConfiguredProgram configureLd v ldProg = do ldProg' <- configureLd' v ldProg diff --git a/Cabal/src/Distribution/Simple/Program.hs b/Cabal/src/Distribution/Simple/Program.hs index ae53b6875fba3b3bd109f4b6d3bd78ddd1391fd6..489a1f96dd46baa58dbb5490223c3377e2d197be 100644 --- a/Cabal/src/Distribution/Simple/Program.hs +++ b/Cabal/src/Distribution/Simple/Program.hs @@ -115,6 +115,7 @@ module Distribution.Simple.Program , jhcProgram , uhcProgram , gccProgram + , gppProgram , arProgram , stripProgram , happyProgram diff --git a/Cabal/src/Distribution/Simple/Program/Builtin.hs b/Cabal/src/Distribution/Simple/Program/Builtin.hs index 995e70d2809c28b0b64fba64235196034a1a021b..6c14f9b5651da4f57e01a79b16f542037739bb64 100644 --- a/Cabal/src/Distribution/Simple/Program/Builtin.hs +++ b/Cabal/src/Distribution/Simple/Program/Builtin.hs @@ -26,6 +26,7 @@ module Distribution.Simple.Program.Builtin , haskellSuitePkgProgram , uhcProgram , gccProgram + , gppProgram , arProgram , stripProgram , happyProgram @@ -272,6 +273,13 @@ gccProgram = { programFindVersion = findProgramVersion "-dumpversion" id } +gppProgram :: Program +gppProgram = + (simpleProgram "gpp") + { programFindVersion = findProgramVersion "-dumpversion" id + , programFindLocation = \v p -> findProgramOnSearchPath v p "g++" + } + arProgram :: Program arProgram = simpleProgram "ar" diff --git a/cabal-testsuite/PackageTests/ConfigureCXX/CHANGELOG.md b/cabal-testsuite/PackageTests/ConfigureCXX/CHANGELOG.md new file mode 100644 index 0000000000000000000000000000000000000000..ba571fb0a09197daa5ef0802dcc54e071076948a --- /dev/null +++ b/cabal-testsuite/PackageTests/ConfigureCXX/CHANGELOG.md @@ -0,0 +1,5 @@ +# Revision history for ConfigureCXX + +## 0.1.0.0 -- YYYY-mm-dd + +* First version. Released on an unsuspecting world. diff --git a/cabal-testsuite/PackageTests/ConfigureCXX/ConfigureCXX.cabal b/cabal-testsuite/PackageTests/ConfigureCXX/ConfigureCXX.cabal new file mode 100644 index 0000000000000000000000000000000000000000..bbf33bdfd88faae592b703344a45aa8c66980483 --- /dev/null +++ b/cabal-testsuite/PackageTests/ConfigureCXX/ConfigureCXX.cabal @@ -0,0 +1,18 @@ +cabal-version: 3.14 +name: ConfigureCXX +version: 0.1.0.0 +license: NONE +author: Matthew Pickering +maintainer: matthewtpickering@gmail.com +build-type: Configure +extra-doc-files: CHANGELOG.md + +common warnings + ghc-options: -Wall + +library + import: warnings + exposed-modules: MyLib + build-depends: base < 5 + hs-source-dirs: src + default-language: Haskell2010 diff --git a/cabal-testsuite/PackageTests/ConfigureCXX/Setup.hs b/cabal-testsuite/PackageTests/ConfigureCXX/Setup.hs new file mode 100644 index 0000000000000000000000000000000000000000..494eece6dadeaa88a224ecde1e98db1e3716e9ae --- /dev/null +++ b/cabal-testsuite/PackageTests/ConfigureCXX/Setup.hs @@ -0,0 +1,3 @@ +import Distribution.Simple + +main = defaultMainWithHooks autoconfUserHooks diff --git a/cabal-testsuite/PackageTests/ConfigureCXX/cabal.out b/cabal-testsuite/PackageTests/ConfigureCXX/cabal.out new file mode 100644 index 0000000000000000000000000000000000000000..392341cc923b85bf156f065ca4a5c18397a603de --- /dev/null +++ b/cabal-testsuite/PackageTests/ConfigureCXX/cabal.out @@ -0,0 +1,2 @@ +# Setup configure +Configuring ConfigureCXX-0.1.0.0... diff --git a/cabal-testsuite/PackageTests/ConfigureCXX/cabal.test.hs b/cabal-testsuite/PackageTests/ConfigureCXX/cabal.test.hs new file mode 100644 index 0000000000000000000000000000000000000000..23eea3f80a02ddac62a95bc97f7f2b080f76e01f --- /dev/null +++ b/cabal-testsuite/PackageTests/ConfigureCXX/cabal.test.hs @@ -0,0 +1,8 @@ +import Test.Cabal.Prelude + +-- Test that configure scripts are passed CXX variable. +main = setupTest $ do + -- 9.4 was the first version which required a C++ compiler. + skipUnlessGhcVersion ">= 9.4" + setup "configure" [] + diff --git a/cabal-testsuite/PackageTests/ConfigureCXX/configure b/cabal-testsuite/PackageTests/ConfigureCXX/configure new file mode 100644 index 0000000000000000000000000000000000000000..07dc1b0afca4e23630e342188b97cd840e2bd5fc --- /dev/null +++ b/cabal-testsuite/PackageTests/ConfigureCXX/configure @@ -0,0 +1,40 @@ +for argument; do #syntactic sugar for: for argument in "$@"; do + key=${argument%%=*} + value=${argument#*=} + + case "$key" in + + CC) MCC=$value;; + CFLAGS) MCFLAGS=$value;; + CXX) MCXX=$value;; + CXXFLAGS) MCXXFLAGS=$value;; + esac +done + +echo $PWD +ls $PWD + +cat > hello.c << EOF +#include <stdio.h> +int main() { + // printf() displays the string inside quotation + printf("Hello, World!"); + return 0; +} +EOF + +cat > hello.cpp << EOF +#include <iostream> + +int main() { + std::cout << "Hello, World!" << std::endl; + return 0; +} +EOF + +# Test the arguments works for C +$MCC $MCFLAGS hello.c + +# Test the arguments work for CXX +$MCXX $MCXXFLAGS hello.cpp + diff --git a/cabal-testsuite/PackageTests/ConfigureCXX/hello.c b/cabal-testsuite/PackageTests/ConfigureCXX/hello.c new file mode 100644 index 0000000000000000000000000000000000000000..34d86c44d8f9a600bc98d20f998807a8fa3a7062 --- /dev/null +++ b/cabal-testsuite/PackageTests/ConfigureCXX/hello.c @@ -0,0 +1,6 @@ +#include <stdio.h> +int main() { + // printf() displays the string inside quotation + printf("Hello, World!"); + return 0; +} diff --git a/cabal-testsuite/PackageTests/ConfigureCXX/hello.cpp b/cabal-testsuite/PackageTests/ConfigureCXX/hello.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0ab7f9b13ad7702afb25e6cb47a9a9bcff823e47 --- /dev/null +++ b/cabal-testsuite/PackageTests/ConfigureCXX/hello.cpp @@ -0,0 +1,6 @@ +#include <iostream> + +int main() { + std::cout << "Hello, World!" << std::endl; + return 0; +} diff --git a/cabal-testsuite/PackageTests/ConfigureCXX/src/MyLib.hs b/cabal-testsuite/PackageTests/ConfigureCXX/src/MyLib.hs new file mode 100644 index 0000000000000000000000000000000000000000..e657c4403f66f966da13d2027bf595d9673387f6 --- /dev/null +++ b/cabal-testsuite/PackageTests/ConfigureCXX/src/MyLib.hs @@ -0,0 +1,4 @@ +module MyLib (someFunc) where + +someFunc :: IO () +someFunc = putStrLn "someFunc" diff --git a/changelog.d/pr-10844.md b/changelog.d/pr-10844.md new file mode 100644 index 0000000000000000000000000000000000000000..184992f8ba2d71af1b10cb1a694cdf96b03b4219 --- /dev/null +++ b/changelog.d/pr-10844.md @@ -0,0 +1,14 @@ +--- +synopsis: Pass CXX and CXXFLAGS to ./configure scripts run by Configure build-type +packages: [Cabal] +prs: 10844 +issues: [10797] +--- + +./configure scripts run by build-type: Configure will now be passed the CXX and +CXXFLAGS variables. These reflect the path and flags for the C++ compiler. + +If the compiler is not available, then the flags are not passed. For GHC versions >= 9.4.*, +the CXX variable will always be set and available to be used. + +This can be useful for implementing something like `system-cxx-std-lib` in user-land. diff --git a/doc/cabal-package-description-file.rst b/doc/cabal-package-description-file.rst index af8ee34071252cace6258453172d8de6f53d18eb..2d5e267616ee3712ca6be8a38cca5c6388491eb9 100644 --- a/doc/cabal-package-description-file.rst +++ b/doc/cabal-package-description-file.rst @@ -3196,7 +3196,9 @@ platform when cross-compiling. Moreover, various bits of build configuration will be passed via environment variables: - ``CC`` will reflect the path to the C compiler - - ``CFLAGS`` will reflect the path to the C compiler + - ``CXX`` will reflect the path to the C++ compiler (if available, it always will be if ghc >= 9.4) + - ``CFLAGS`` will reflect the flags to the C compiler + - ``CXXFLAGS`` will reflect the flags to the C++ compiler (if available) - ``CABAL_FLAGS`` will contain the Cabal flag assignment of the current package using traditional Cabal flag syntax (e.g. ``+flagA -flagB``) - ``CABAL_FLAG_<flag>`` will be set to either ``0`` or ``1`` depending upon