Skip to content

Pass CXX and CXXFLAGS argument to ./configure scripts for build-type: Configure #10844

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 22 additions & 6 deletions Cabal/src/Distribution/Simple/ConfigureScript.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down Expand Up @@ -159,21 +171,25 @@ 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
(intercalate spSep extraPath)
((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 <-
Expand Down
21 changes: 20 additions & 1 deletion Cabal/src/Distribution/Simple/GHC/Internal.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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"
Expand Down Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions Cabal/src/Distribution/Simple/Program.hs
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ module Distribution.Simple.Program
, jhcProgram
, uhcProgram
, gccProgram
, gppProgram
, arProgram
, stripProgram
, happyProgram
Expand Down
8 changes: 8 additions & 0 deletions Cabal/src/Distribution/Simple/Program/Builtin.hs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ module Distribution.Simple.Program.Builtin
, haskellSuitePkgProgram
, uhcProgram
, gccProgram
, gppProgram
, arProgram
, stripProgram
, happyProgram
Expand Down Expand Up @@ -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"

Expand Down
5 changes: 5 additions & 0 deletions cabal-testsuite/PackageTests/ConfigureCXX/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# Revision history for ConfigureCXX

## 0.1.0.0 -- YYYY-mm-dd

* First version. Released on an unsuspecting world.
18 changes: 18 additions & 0 deletions cabal-testsuite/PackageTests/ConfigureCXX/ConfigureCXX.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
cabal-version: 3.14
name: ConfigureCXX
version: 0.1.0.0
license: NONE
author: Matthew Pickering
maintainer: [email protected]
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
3 changes: 3 additions & 0 deletions cabal-testsuite/PackageTests/ConfigureCXX/Setup.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import Distribution.Simple

main = defaultMainWithHooks autoconfUserHooks
2 changes: 2 additions & 0 deletions cabal-testsuite/PackageTests/ConfigureCXX/cabal.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Setup configure
Configuring ConfigureCXX-0.1.0.0...
8 changes: 8 additions & 0 deletions cabal-testsuite/PackageTests/ConfigureCXX/cabal.test.hs
Original file line number Diff line number Diff line change
@@ -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" []

40 changes: 40 additions & 0 deletions cabal-testsuite/PackageTests/ConfigureCXX/configure
Original file line number Diff line number Diff line change
@@ -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

6 changes: 6 additions & 0 deletions cabal-testsuite/PackageTests/ConfigureCXX/hello.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <stdio.h>
int main() {
// printf() displays the string inside quotation
printf("Hello, World!");
return 0;
}
6 changes: 6 additions & 0 deletions cabal-testsuite/PackageTests/ConfigureCXX/hello.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#include <iostream>

int main() {
std::cout << "Hello, World!" << std::endl;
return 0;
}
4 changes: 4 additions & 0 deletions cabal-testsuite/PackageTests/ConfigureCXX/src/MyLib.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module MyLib (someFunc) where

someFunc :: IO ()
someFunc = putStrLn "someFunc"
14 changes: 14 additions & 0 deletions changelog.d/pr-10844.md
Original file line number Diff line number Diff line change
@@ -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.
4 changes: 3 additions & 1 deletion doc/cabal-package-description-file.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
Loading