Skip to content
Open
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
8 changes: 7 additions & 1 deletion Cabal/src/Distribution/Simple.hs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ import Language.Haskell.Extension

-- Base
import Data.List (unionBy, (\\))
import qualified Data.Map as Map
import System.Directory (removePathForcibly)
import System.Environment (getArgs, getProgName)
import System.IO (hPutStr, hPutStrLn)
Expand Down Expand Up @@ -981,12 +982,14 @@ autoconfUserHooks =
let common = configCommonFlags flags
verbosity = mkVerbosity defaultVerbosityHandles (fromFlag $ setupVerbosity common)
mbWorkDir = flagToMaybe $ setupWorkingDir common
compilerTargetTriple = Map.lookup "Target platform" (compilerProperties (compiler lbi))
runConfigureScript
defaultVerbosityHandles
flags
(flagAssignment lbi)
(withPrograms lbi)
(hostPlatform lbi)
compilerTargetTriple
pbi <- getHookedBuildInfo verbosity mbWorkDir (buildDir lbi)
sanityCheckHookedBuildInfo verbosity pkg_descr pbi
let pkg_descr' = updatePackageDescription pbi pkg_descr
Expand Down Expand Up @@ -1055,9 +1058,12 @@ autoconfSetupHooks =
{ LBC.configFlags = cfg
, LBC.flagAssignment = flags
, LBC.hostPlatform = plat
, LBC.compiler = compiler'
}
}
) = runConfigureScript defaultVerbosityHandles cfg flags progs plat
) =
let compilerTargetTriple = Map.lookup "Target platform" (compilerProperties compiler')
in runConfigureScript defaultVerbosityHandles cfg flags progs plat compilerTargetTriple

pre_conf_comp
:: SetupHooks.PreConfComponentInputs
Expand Down
23 changes: 20 additions & 3 deletions Cabal/src/Distribution/Simple/ConfigureScript.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import Prelude ()

-- local
import Distribution.PackageDescription
import Distribution.Pretty
import Distribution.Simple.Configure (findDistPrefOrDefault)
import Distribution.Simple.Errors
import Distribution.Simple.LocalBuildInfo
Expand Down Expand Up @@ -56,8 +55,18 @@ runConfigureScript
-> ProgramDb
-> Platform
-- ^ host platform
-> Maybe String
-- ^ The GHC target platform triple (e.g. @"x86_64-w64-mingw32"@),
-- passed as the autoconf @--host=@ flag.
--
-- Note: GHC's \"target\" is the platform that compiled Haskell code
-- runs on, which corresponds to autoconf's \"host\" (the platform
-- where the compiled artifact runs). Autoconf reserves \"target\"
-- for compiler toolchains only. See the
-- [GHC wiki on cross-compilation](https://gitlab.haskell.org/ghc/ghc/-/wikis/cross-compilation)
-- for details on GHC's platform terminology.
-> IO ()
runConfigureScript verbHandles cfg flags programDb hp = do
runConfigureScript verbHandles cfg flags programDb hp targetTriple = do
let commonCfg = configCommonFlags cfg
verbosity = mkVerbosity verbHandles (fromFlag $ setupVerbosity commonCfg)
dist_dir <- findDistPrefOrDefault $ setupDistPref commonCfg
Expand Down Expand Up @@ -183,7 +192,15 @@ runConfigureScript verbHandles cfg flags programDb hp = do
: [("CXXFLAGS", Just (mkFlagsEnv cxxFlags "CXXFLAGS")) | Just cxxFlags <- [mcxxFlags]]
++ [("PATH", Just pathEnv) | not (null extraPath)]
++ cabalFlagEnv
maybeHostFlag = ["--host=" ++ show (pretty hp) | hp /= buildPlatform]
maybeHostFlag =
case targetTriple of
Just host ->
[ "--host=" ++ host
| -- the hp =/ buildPlatform guard is too restrictive,
-- e.g. for glibc -> musl cross-compilation we don't want to omit x86_64-unknown-linux-musl.
hp /= buildPlatform
]
Nothing -> []
args' =
configureFile'
: args
Expand Down
1 change: 1 addition & 0 deletions cabal-testsuite/PackageTests/ConfigureHostTriple/A.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module A where
6 changes: 6 additions & 0 deletions cabal-testsuite/PackageTests/ConfigureHostTriple/Setup.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Main (main) where

import Distribution.Simple

main :: IO ()
main = defaultMainWithHooks autoconfUserHooks
4 changes: 4 additions & 0 deletions cabal-testsuite/PackageTests/ConfigureHostTriple/configure
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
#!/bin/sh
# Minimal configure script that records its arguments.
# We write all args to configure-args.txt so the test can inspect them.
echo "$@" > configure-args.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/bin/sh

# A fake GHC that proxies the real GHC but overrides
# "Target platform" to simulate cross-compilation
# to x86_64-w64-mingw32.

case "$*" in
*--info*)
ghc "$@" | sed 's/("Target platform","[^"]*")/("Target platform","x86_64-w64-mingw32")/'
;;
*)
exec ghc "$@"
;;
esac
42 changes: 42 additions & 0 deletions cabal-testsuite/PackageTests/ConfigureHostTriple/setup.test.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import Test.Cabal.Prelude
import Test.Cabal.Script (runghc)
import Control.Monad.IO.Class
import Data.List (isInfixOf)

-- When cross-compiling, Cabal passes a --host= flag to configure scripts.
-- The value should be the original GNU triple (e.g. x86_64-w64-mingw32),
-- not Cabal's canonical platform string (e.g. x86_64-windows).
--
-- This test uses a fake GHC wrapper that reports "x86_64-w64-mingw32"
-- as its Target platform (simulating a cross-compiler), then checks
-- that the configure script receives --host=x86_64-w64-mingw32
-- rather than the mangled --host=x86_64-windows.
main = do
skipIfWindows "uses sh script as fake ghc"
setupTest $ recordMode DoNotRecord $ do
env <- getTestEnv
let cwd = testCurrentDir env
fakeGhc = cwd </> "scripts" </> "fake-ghc.sh"
-- Run Setup.hs configure with our fake cross-compiler.
-- We call runghc ourselves to bypass the test framework's
-- --with-ghc which would override ours.
_ <- liftIO $ runghc
(testScriptEnv env)
(Just $ testTmpDir env)
(testEnvironment env)
("." </> "Setup.hs")
[ "configure"
, "--distdir", testDistDir env
, "--with-compiler", fakeGhc
]
-- The configure script writes its arguments to configure-args.txt
-- in its working directory (dist/build/).
let argsFile = testDistDir env </> "build" </> "configure-args.txt"
args <- liftIO $ readFile argsFile
-- The configure script should receive --host=x86_64-w64-mingw32
-- (the original GNU triple), not --host=x86_64-windows.
unless ("--host=x86_64-w64-mingw32" `isInfixOf` args) $
error $ unlines
[ "Expected --host=x86_64-w64-mingw32 in configure arguments"
, "but got: " ++ args
]
9 changes: 9 additions & 0 deletions cabal-testsuite/PackageTests/ConfigureHostTriple/test.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
cabal-version: 2.2
name: test
version: 0
build-type: Configure

library
exposed-modules: A
build-depends: base
default-language: Haskell2010
15 changes: 15 additions & 0 deletions changelog.d/pr-11718.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
synopsis: Fix --host= triple mangling during cross-compilation
packages: [cabal-install]
prs: 11718
Comment thread
jappeace marked this conversation as resolved.
issues: 5887
---

repairs (hopefully): https://github.com/haskell/cabal/issues/5887

Cabal now passes the unchanged GHC target platform triple as the autoconf --host, instead of a simplified version.

For example, Cabal now passes the full `--host=x86_64-w64-mingw32` instead of the incorrect `--host=x86_64-windows`.

Adds an integration test which fails on master
and now succeeds.
Loading