Skip to content
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

Cabal: Always pass -package-env=- to supported GHC versions #10828

Merged
merged 2 commits into from
Mar 26, 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
60 changes: 36 additions & 24 deletions Cabal/src/Distribution/Simple/Program/Builtin.hs
Original file line number Diff line number Diff line change
Expand Up @@ -104,32 +104,44 @@ ghcProgram :: Program
ghcProgram =
(simpleProgram "ghc")
{ programFindVersion = findProgramVersion "--numeric-version" id
, -- Workaround for https://gitlab.haskell.org/ghc/ghc/-/issues/8825
-- (spurious warning on non-english locales)
programPostConf = \_verbosity ghcProg ->
do
let ghcProg' =
ghcProg
{ programOverrideEnv =
("LANGUAGE", Just "en")
: programOverrideEnv ghcProg
}
-- Only the 7.8 branch seems to be affected. Fixed in 7.8.4.
affectedVersionRange =
intersectVersionRanges
(laterVersion $ mkVersion [7, 8, 0])
(earlierVersion $ mkVersion [7, 8, 4])
return $
maybe
ghcProg
( \v ->
if withinRange v affectedVersionRange
then ghcProg'
else ghcProg
)
(programVersion ghcProg)
, programPostConf = ghcPostConf
, programNormaliseArgs = normaliseGhcArgs
}
where
ghcPostConf _verbosity ghcProg = do
let setLanguageEnv prog =
prog
{ programOverrideEnv =
("LANGUAGE", Just "en")
: programOverrideEnv ghcProg
}

ignorePackageEnv prog = prog{programDefaultArgs = "-package-env=-" : programDefaultArgs prog}

-- Only the 7.8 branch seems to be affected. Fixed in 7.8.4.
affectedVersionRange =
intersectVersionRanges
(laterVersion $ mkVersion [7, 8, 0])
(earlierVersion $ mkVersion [7, 8, 4])

canIgnorePackageEnv = orLaterVersion $ mkVersion [8, 4, 4]

applyWhen cond f prog = if cond then f prog else prog

return $
maybe
ghcProg
( \v ->
-- By default, ignore GHC_ENVIRONMENT variable of any package environmnet
-- files. See #10759
applyWhen (withinRange v canIgnorePackageEnv) ignorePackageEnv
-- Workaround for https://gitlab.haskell.org/ghc/ghc/-/issues/8825
-- (spurious warning on non-english locales)
$
applyWhen (withinRange v affectedVersionRange) setLanguageEnv $
ghcProg
)
(programVersion ghcProg)

runghcProgram :: Program
runghcProgram =
Expand Down
26 changes: 12 additions & 14 deletions cabal-install/src/Distribution/Client/CmdExec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ import Distribution.Client.ProjectOrchestration
import Distribution.Client.ProjectPlanOutput
( PostBuildProjectStatus
, argsEquivalentOfGhcEnvironmentFile
, createPackageEnvironment
, createPackageEnvironmentAndArgs
, updatePostBuildProjectStatus
)
import Distribution.Client.ProjectPlanning
Expand Down Expand Up @@ -191,7 +191,7 @@ execAction flags@NixStyleFlags{..} extraArgs globalFlags = do
[] -> dieWithException verbosity SpecifyAnExecutable
exe : args -> do
(program, _) <- requireProgram verbosity (simpleProgram exe) programDb
let argOverrides =
let environmentPackageArgs =
argsEquivalentOfGhcEnvironmentFile
compiler
(distDirLayout baseCtx)
Expand All @@ -201,21 +201,19 @@ execAction flags@NixStyleFlags{..} extraArgs globalFlags = do
matchCompilerPath
(elaboratedShared buildCtx)
program
argOverrides' =
if envFilesSupported
|| not programIsConfiguredCompiler
then []
else argOverrides

( if envFilesSupported
then withTempEnvFile verbosity baseCtx buildCtx buildStatus
else \f -> f []
else \f ->
if programIsConfiguredCompiler
then f environmentPackageArgs []
else f [] []
)
$ \envOverrides -> do
$ \argOverrides envOverrides -> do
let program' =
withOverrides
envOverrides
argOverrides'
argOverrides
program
invocation = programInvocation program' args
dryRun =
Expand Down Expand Up @@ -253,7 +251,7 @@ withTempEnvFile
-> ProjectBaseContext
-> ProjectBuildContext
-> PostBuildProjectStatus
-> ([(String, Maybe String)] -> IO a)
-> ([String] -> [(String, Maybe String)] -> IO a)
-> IO a
withTempEnvFile verbosity baseCtx buildCtx buildStatus action = do
let tmpDirTemplate = distTempDirectory (distDirLayout baseCtx)
Expand All @@ -263,14 +261,14 @@ withTempEnvFile verbosity baseCtx buildCtx buildStatus action = do
tmpDirTemplate
"environment."
( \tmpDir -> do
envOverrides <-
createPackageEnvironment
(argOverrides, envOverrides) <-
createPackageEnvironmentAndArgs
verbosity
tmpDir
(elaboratedPlanToExecute buildCtx)
(elaboratedShared buildCtx)
buildStatus
action envOverrides
action argOverrides envOverrides
)

-- | Get paths to all dependency executables to be included in PATH.
Expand Down
19 changes: 11 additions & 8 deletions cabal-install/src/Distribution/Client/ProjectPlanOutput.hs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ module Distribution.Client.ProjectPlanOutput
-- | Several outputs rely on having a general overview of
, PostBuildProjectStatus (..)
, updatePostBuildProjectStatus
, createPackageEnvironment
, createPackageEnvironmentAndArgs
, writePlanGhcEnvironment
, argsEquivalentOfGhcEnvironmentFile
) where
Expand Down Expand Up @@ -777,7 +777,7 @@ writePackagesUpToDateCacheFile DistDirLayout{distProjectCacheFile} upToDate =
writeFileAtomic (distProjectCacheFile "up-to-date") $
Binary.encode upToDate

-- | Prepare a package environment that includes all the library dependencies
-- | Prepare a package environment and args that includes all the library dependencies
-- for a plan.
--
-- When running cabal new-exec, we want to set things up so that the compiler
Expand All @@ -786,14 +786,17 @@ writePackagesUpToDateCacheFile DistDirLayout{distProjectCacheFile} upToDate =
-- temporarily, in case the compiler wants to learn this information via the
-- filesystem, and returns any environment variable overrides the compiler
-- needs.
createPackageEnvironment
--
-- The function returns both the arguments you need to pass to the compiler and
-- the environment variables you need to set.
createPackageEnvironmentAndArgs
:: Verbosity
-> FilePath
-> ElaboratedInstallPlan
-> ElaboratedSharedConfig
-> PostBuildProjectStatus
-> IO [(String, Maybe String)]
createPackageEnvironment
-> IO ([String], [(String, Maybe String)])
createPackageEnvironmentAndArgs
verbosity
path
elaboratedPlan
Expand All @@ -808,14 +811,14 @@ createPackageEnvironment
elaboratedShared
buildStatus
case envFileM of
Just envFile -> return [("GHC_ENVIRONMENT", Just envFile)]
Just envFile -> return (["-package-env=" ++ envFile], [("GHC_ENVIRONMENT", Just envFile)])
Nothing -> do
warn verbosity "the configured version of GHC does not support reading package lists from the environment; commands that need the current project's package database are likely to fail"
return []
return ([], [])
| otherwise =
do
warn verbosity "package environment configuration is not supported for the currently configured compiler; commands that need the current project's package database are likely to fail"
return []
return ([], [])

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

## 0.1.0.0 -- YYYY-mm-dd

* First version. Released on an unsuspecting world.
18 changes: 18 additions & 0 deletions cabal-testsuite/PackageTests/EnvironmentFile/EnvironmentFile.cabal
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
cabal-version: 3.14
name: EnvironmentFile
version: 0.1.0.0
license: NONE
author: Matthew Pickering
maintainer: [email protected]
build-type: Simple
extra-doc-files: CHANGELOG.md

common warnings
ghc-options: -Wall

executable EnvironmentFile
import: warnings
main-is: Main.hs
build-depends: base < 5,
hs-source-dirs: app
default-language: Haskell2010
4 changes: 4 additions & 0 deletions cabal-testsuite/PackageTests/EnvironmentFile/app/Main.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module Main where

main :: IO ()
main = putStrLn "Hello, Haskell!"
8 changes: 8 additions & 0 deletions cabal-testsuite/PackageTests/EnvironmentFile/cabal.test.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Test.Cabal.Prelude
import System.FilePath
main = cabalTest $ recordMode DoNotRecord $ do
env <- getTestEnv
let cur_dir = testCurrentDir env
-- Set GHC_ENVIRONMENT to a file which contains garbage
withEnv [("GHC_ENVIRONMENT", Just (cur_dir </> "ghc.environment"))] $ do
cabal "build" ["all"]
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
this-file-(ghc.environment)-contains-garbage-it-should-not-be-read
15 changes: 15 additions & 0 deletions changelog.d/pr-10828.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
synopsis: "Isolate Cabal from the GHC_ENVIRONMENT variable"
packages: [Cabal]
prs: 10828

issues: 10759
---

For GHC 8.4.4 and later, Cabal now passes the `-package-env=-` flag to GHC.
This prevents the `GHC_ENVIRONMENT` variable or any package environment files
from affecting Cabal builds.

This change eliminates unexpected build behavior that could occur when users
had GHC environment files configured in their system that Cabal wasn't aware
of.
Loading