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