Skip to content

Commit 8e150ad

Browse files
authored
Merge pull request #9912 from mpickering/wip/program-db-paths
Correctly provision build tools in all situations
2 parents 8bde3a6 + ee11ac6 commit 8e150ad

File tree

39 files changed

+879
-124
lines changed

39 files changed

+879
-124
lines changed

Cabal-tests/tests/UnitTests/Distribution/Utils/Structured.hs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ md5CheckGenericPackageDescription proxy = md5Check proxy
4141
md5CheckLocalBuildInfo :: Proxy LocalBuildInfo -> Assertion
4242
md5CheckLocalBuildInfo proxy = md5Check proxy
4343
#if MIN_VERSION_base(4,19,0)
44-
0x5f774efdb0aedcbf5263d3d99e38d50b
44+
0x552eca9ce2e4a34e74deff571f279fc4
4545
#else
46-
0x0f53d756836a410f72b31feb7d9f7b09
46+
0x48497d6b3f15df06f1107b81b98febe1
4747
#endif

Cabal/src/Distribution/Simple/Bench.hs

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -23,21 +23,27 @@ module Distribution.Simple.Bench
2323
import Distribution.Compat.Prelude
2424
import Prelude ()
2525

26+
import Distribution.Compat.Environment
2627
import qualified Distribution.PackageDescription as PD
2728
import Distribution.Pretty
29+
import Distribution.Simple.Build (addInternalBuildTools)
2830
import Distribution.Simple.BuildPaths
2931
import Distribution.Simple.Compiler
32+
import Distribution.Simple.Errors
3033
import Distribution.Simple.InstallDirs
3134
import qualified Distribution.Simple.LocalBuildInfo as LBI
35+
import Distribution.Simple.Program.Db
36+
import Distribution.Simple.Program.Find
37+
import Distribution.Simple.Program.Run
3238
import Distribution.Simple.Setup.Benchmark
3339
import Distribution.Simple.Setup.Common
3440
import Distribution.Simple.UserHooks
3541
import Distribution.Simple.Utils
36-
import Distribution.Utils.Path
37-
42+
import Distribution.System (Platform (Platform))
43+
import Distribution.Types.Benchmark (Benchmark (benchmarkBuildInfo))
3844
import Distribution.Types.UnqualComponentName
45+
import Distribution.Utils.Path
3946

40-
import Distribution.Simple.Errors
4147
import System.Directory (doesFileExist)
4248

4349
-- | Perform the \"@.\/setup bench@\" action.
@@ -61,23 +67,52 @@ bench args pkg_descr lbi flags = do
6167

6268
-- Run the benchmark
6369
doBench :: (PD.Benchmark, LBI.ComponentLocalBuildInfo) -> IO ExitCode
64-
doBench (bm, _clbi) =
70+
doBench (bm, clbi) = do
71+
let lbiForBench =
72+
lbi
73+
{ -- Include any build-tool-depends on build tools internal to the current package.
74+
LBI.withPrograms =
75+
addInternalBuildTools
76+
pkg_descr
77+
lbi
78+
(benchmarkBuildInfo bm)
79+
(LBI.withPrograms lbi)
80+
}
6581
case PD.benchmarkInterface bm of
6682
PD.BenchmarkExeV10 _ _ -> do
67-
let cmd = i $ LBI.buildDir lbi </> makeRelativePathEx (name </> name <.> exeExtension (LBI.hostPlatform lbi))
83+
let cmd = i $ LBI.buildDir lbiForBench </> makeRelativePathEx (name </> name <.> exeExtension (LBI.hostPlatform lbi))
6884
options =
69-
map (benchOption pkg_descr lbi bm) $
85+
map (benchOption pkg_descr lbiForBench bm) $
7086
benchmarkOptions flags
7187
-- Check that the benchmark executable exists.
7288
exists <- doesFileExist cmd
7389
unless exists $
7490
dieWithException verbosity $
7591
NoBenchMarkProgram cmd
7692

93+
existingEnv <- getEnvironment
94+
95+
-- Compute the appropriate environment for running the benchmark
96+
let progDb = LBI.withPrograms lbiForBench
97+
pathVar = progSearchPath progDb
98+
envOverrides = progOverrideEnv progDb
99+
newPath <- programSearchPathAsPATHVar pathVar
100+
overrideEnv <- fromMaybe [] <$> getEffectiveEnvironment ([("PATH", Just newPath)] ++ envOverrides)
101+
let shellEnv = overrideEnv ++ existingEnv
102+
103+
-- Add (DY)LD_LIBRARY_PATH if needed
104+
shellEnv' <-
105+
if LBI.withDynExe lbiForBench
106+
then do
107+
let (Platform _ os) = LBI.hostPlatform lbiForBench
108+
paths <- LBI.depLibraryPaths True False lbiForBench clbi
109+
return (addLibraryPath os paths shellEnv)
110+
else return shellEnv
111+
77112
notice verbosity $ startMessage name
78113
-- This will redirect the child process
79114
-- stdout/stderr to the parent process.
80-
exitcode <- rawSystemExitCode verbosity mbWorkDir cmd options
115+
exitcode <- rawSystemExitCode verbosity mbWorkDir cmd options (Just shellEnv')
81116
notice verbosity $ finishMessage name exitcode
82117
return exitcode
83118
_ -> do

Cabal/src/Distribution/Simple/Build.hs

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,9 @@ module Distribution.Simple.Build
4545

4646
-- * Internal package database creation
4747
, createInternalPackageDB
48+
49+
-- * Handling of internal build tools
50+
, addInternalBuildTools
4851
) where
4952

5053
import Distribution.Compat.Prelude
@@ -76,7 +79,7 @@ import qualified Distribution.Simple.UHC as UHC
7679

7780
import Distribution.Simple.Build.Macros (generateCabalMacrosHeader)
7881
import Distribution.Simple.Build.PackageInfoModule (generatePackageInfoModule)
79-
import Distribution.Simple.Build.PathsModule (generatePathsModule)
82+
import Distribution.Simple.Build.PathsModule (generatePathsModule, pkgPathEnvVar)
8083
import qualified Distribution.Simple.Program.HcPkg as HcPkg
8184

8285
import Distribution.InstalledPackageInfo (InstalledPackageInfo)
@@ -95,6 +98,7 @@ import Distribution.Simple.LocalBuildInfo
9598
import Distribution.Simple.PreProcess
9699
import Distribution.Simple.Program
97100
import Distribution.Simple.Program.Builtin (haskellSuiteProgram)
101+
import Distribution.Simple.Program.Db
98102
import qualified Distribution.Simple.Program.GHC as GHC
99103
import Distribution.Simple.Program.Types
100104
import Distribution.Simple.Register
@@ -189,6 +193,7 @@ build_setupHooks
189193
let comp = targetComponent target
190194
clbi = targetCLBI target
191195
bi = componentBuildInfo comp
196+
-- Include any build-tool-depends on build tools internal to the current package.
192197
progs' = addInternalBuildTools pkg_descr lbi bi (withPrograms lbi)
193198
lbi' =
194199
lbi
@@ -208,7 +213,6 @@ build_setupHooks
208213
(ruleFromId, _mons) <- SetupHooks.computeRules verbosity inputs pbcRules
209214
SetupHooks.executeRules verbosity lbi2 tgt ruleFromId
210215
preBuildComponent runPreBuildHooks verbosity lbi' target
211-
212216
let numJobs = buildNumJobs flags
213217
par_strat <-
214218
toFlag <$> case buildUseSemaphore flags of
@@ -378,6 +382,7 @@ repl_setupHooks
378382
lbi'
379383
{ withPackageDB = withPackageDB lbi ++ [internalPackageDB]
380384
, withPrograms =
385+
-- Include any build-tool-depends on build tools internal to the current package.
381386
addInternalBuildTools
382387
pkg_descr
383388
lbi'
@@ -911,24 +916,49 @@ createInternalPackageDB verbosity lbi distPref = do
911916
dbRelPath = internalPackageDBPath lbi distPref
912917
dbPath = interpretSymbolicPathLBI lbi dbRelPath
913918

919+
-- | Update the program database to include any build-tool-depends specified
920+
-- in the given 'BuildInfo' on build tools internal to the current package.
921+
--
922+
-- This function:
923+
--
924+
-- - adds these internal build tools to the 'ProgramDb', including
925+
-- paths to their respective data directories,
926+
-- - adds their paths to the current 'progSearchPath', and adds the data
927+
-- directory environment variable for the current package to the current
928+
-- 'progOverrideEnv', so that any programs configured from now on will be
929+
-- able to invoke these build tools.
914930
addInternalBuildTools
915931
:: PackageDescription
916932
-> LocalBuildInfo
917933
-> BuildInfo
918934
-> ProgramDb
919935
-> ProgramDb
920936
addInternalBuildTools pkg lbi bi progs =
921-
foldr updateProgram progs internalBuildTools
937+
prependProgramSearchPathNoLogging
938+
internalToolPaths
939+
[pkgDataDirVar]
940+
$ foldr updateProgram progs internalBuildTools
922941
where
942+
internalToolPaths = map (takeDirectory . programPath) internalBuildTools
943+
pkgDataDirVar = (pkgPathEnvVar pkg "datadir", Just dataDirPath)
923944
internalBuildTools =
924-
[ simpleConfiguredProgram toolName' (FoundOnSystem toolLocation)
945+
[ (simpleConfiguredProgram toolName' (FoundOnSystem toolLocation))
946+
{ programOverrideEnv = [pkgDataDirVar]
947+
}
925948
| toolName <- getAllInternalToolDependencies pkg bi
926949
, let toolName' = unUnqualComponentName toolName
927950
, let toolLocation =
928951
interpretSymbolicPathLBI lbi $
929952
buildDir lbi
930953
</> makeRelativePathEx (toolName' </> toolName' <.> exeExtension (hostPlatform lbi))
931954
]
955+
mbWorkDir = mbWorkDirLBI lbi
956+
rawDataDir = dataDir pkg
957+
dataDirPath
958+
| null $ getSymbolicPath rawDataDir =
959+
interpretSymbolicPath mbWorkDir sameDirectory
960+
| otherwise =
961+
interpretSymbolicPath mbWorkDir rawDataDir
932962

933963
-- TODO: build separate libs in separate dirs so that we can build
934964
-- multiple libs, e.g. for 'LibTest' library-style test suites

Cabal/src/Distribution/Simple/Configure.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1364,7 +1364,7 @@ mkProgramDb :: ConfigFlags -> ProgramDb -> IO ProgramDb
13641364
mkProgramDb cfg initialProgramDb = do
13651365
programDb <-
13661366
modifyProgramSearchPath (getProgramSearchPath initialProgramDb ++) -- We need to have the paths to programs installed by build-tool-depends before all other paths
1367-
<$> prependProgramSearchPath (fromFlagOrDefault normal (configVerbosity cfg)) searchpath initialProgramDb
1367+
<$> prependProgramSearchPath (fromFlagOrDefault normal (configVerbosity cfg)) searchpath [] initialProgramDb
13681368
pure
13691369
. userSpecifyArgss (configProgramArgs cfg)
13701370
. userSpecifyPaths (configProgramPaths cfg)

Cabal/src/Distribution/Simple/ConfigureScript.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ runConfigureScript verbosity flags lbi = do
164164
maybeHostFlag = if hp == buildPlatform then [] else ["--host=" ++ show (pretty hp)]
165165
args' = configureFile' : args ++ ["CC=" ++ ccProgShort] ++ maybeHostFlag
166166
shProg = simpleProgram "sh"
167-
progDb <- prependProgramSearchPath verbosity extraPath emptyProgramDb
167+
progDb <- prependProgramSearchPath verbosity extraPath [] emptyProgramDb
168168
shConfiguredProg <-
169169
lookupProgram shProg
170170
`fmap` configureProgram verbosity shProg progDb

Cabal/src/Distribution/Simple/Haddock.hs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,15 @@ haddock_setupHooks
336336
let
337337
component = targetComponent target
338338
clbi = targetCLBI target
339+
bi = componentBuildInfo component
340+
-- Include any build-tool-depends on build tools internal to the current package.
341+
progs' = addInternalBuildTools pkg_descr lbi bi (withPrograms lbi)
342+
lbi' =
343+
lbi
344+
{ withPrograms = progs'
345+
, withPackageDB = withPackageDB lbi ++ [internalPackageDB]
346+
, installedPkgs = index
347+
}
339348

340349
runPreBuildHooks :: LocalBuildInfo -> TargetInfo -> IO ()
341350
runPreBuildHooks lbi2 tgt =
@@ -348,15 +357,7 @@ haddock_setupHooks
348357
in for_ mbPbcRules $ \pbcRules -> do
349358
(ruleFromId, _mons) <- SetupHooks.computeRules verbosity inputs pbcRules
350359
SetupHooks.executeRules verbosity lbi2 tgt ruleFromId
351-
preBuildComponent runPreBuildHooks verbosity lbi target
352-
353-
let
354-
lbi' =
355-
lbi
356-
{ withPackageDB = withPackageDB lbi ++ [internalPackageDB]
357-
, installedPkgs = index
358-
}
359-
360+
preBuildComponent runPreBuildHooks verbosity lbi' target
360361
preprocessComponent pkg_descr component lbi' clbi False verbosity suffixes
361362
let
362363
doExe com = case (compToExe com) of

Cabal/src/Distribution/Simple/Program/Db.hs

Lines changed: 29 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ module Distribution.Simple.Program.Db
3535
, addKnownProgram
3636
, addKnownPrograms
3737
, prependProgramSearchPath
38+
, prependProgramSearchPathNoLogging
3839
, lookupKnownProgram
3940
, knownPrograms
4041
, getProgramSearchPath
@@ -102,6 +103,7 @@ import Distribution.Simple.Errors
102103
data ProgramDb = ProgramDb
103104
{ unconfiguredProgs :: UnconfiguredProgs
104105
, progSearchPath :: ProgramSearchPath
106+
, progOverrideEnv :: [(String, Maybe String)]
105107
, configuredProgs :: ConfiguredProgs
106108
}
107109
deriving (Typeable)
@@ -111,7 +113,7 @@ type UnconfiguredProgs = Map.Map String UnconfiguredProgram
111113
type ConfiguredProgs = Map.Map String ConfiguredProgram
112114

113115
emptyProgramDb :: ProgramDb
114-
emptyProgramDb = ProgramDb Map.empty defaultProgramSearchPath Map.empty
116+
emptyProgramDb = ProgramDb Map.empty defaultProgramSearchPath [] Map.empty
115117

116118
defaultProgramDb :: ProgramDb
117119
defaultProgramDb = restoreProgramDb builtinPrograms emptyProgramDb
@@ -151,14 +153,17 @@ instance Read ProgramDb where
151153
instance Binary ProgramDb where
152154
put db = do
153155
put (progSearchPath db)
156+
put (progOverrideEnv db)
154157
put (configuredProgs db)
155158

156159
get = do
157160
searchpath <- get
161+
overrides <- get
158162
progs <- get
159163
return $!
160164
emptyProgramDb
161165
{ progSearchPath = searchpath
166+
, progOverrideEnv = overrides
162167
, configuredProgs = progs
163168
}
164169

@@ -169,6 +174,7 @@ instance Structured ProgramDb where
169174
0
170175
"ProgramDb"
171176
[ structure (Proxy :: Proxy ProgramSearchPath)
177+
, structure (Proxy :: Proxy [(String, Maybe String)])
172178
, structure (Proxy :: Proxy ConfiguredProgs)
173179
]
174180

@@ -230,19 +236,32 @@ modifyProgramSearchPath f db =
230236
setProgramSearchPath (f $ getProgramSearchPath db) db
231237

232238
-- | Modify the current 'ProgramSearchPath' used by the 'ProgramDb'
233-
-- by prepending the provided extra paths. Also logs the added paths
234-
-- in info verbosity.
239+
-- by prepending the provided extra paths.
240+
--
241+
-- - Logs the added paths in info verbosity.
242+
-- - Prepends environment variable overrides.
235243
prependProgramSearchPath
236244
:: Verbosity
237245
-> [FilePath]
246+
-> [(String, Maybe FilePath)]
238247
-> ProgramDb
239248
-> IO ProgramDb
240-
prependProgramSearchPath verbosity extraPaths db =
241-
if not $ null extraPaths
242-
then do
243-
logExtraProgramSearchPath verbosity extraPaths
244-
pure $ modifyProgramSearchPath (map ProgramSearchPathDir extraPaths ++) db
245-
else pure db
249+
prependProgramSearchPath verbosity extraPaths extraEnv db = do
250+
unless (null extraPaths) $
251+
logExtraProgramSearchPath verbosity extraPaths
252+
unless (null extraEnv) $
253+
logExtraProgramOverrideEnv verbosity extraEnv
254+
return $ prependProgramSearchPathNoLogging extraPaths extraEnv db
255+
256+
prependProgramSearchPathNoLogging
257+
:: [FilePath]
258+
-> [(String, Maybe String)]
259+
-> ProgramDb
260+
-> ProgramDb
261+
prependProgramSearchPathNoLogging extraPaths extraEnv db =
262+
let db' = modifyProgramSearchPath (nub . (map ProgramSearchPathDir extraPaths ++)) db
263+
db'' = db'{progOverrideEnv = extraEnv ++ progOverrideEnv db'}
264+
in db''
246265

247266
-- | User-specify this path. Basically override any path information
248267
-- for this program in the configuration. If it's not a known
@@ -410,7 +429,7 @@ configureUnconfiguredProgram verbosity prog progdb = do
410429
, programVersion = version
411430
, programDefaultArgs = []
412431
, programOverrideArgs = userSpecifiedArgs prog progdb
413-
, programOverrideEnv = [("PATH", Just newPath)]
432+
, programOverrideEnv = [("PATH", Just newPath)] ++ progOverrideEnv progdb
414433
, programProperties = Map.empty
415434
, programLocation = location
416435
, programMonitorFiles = triedLocations

Cabal/src/Distribution/Simple/Program/Find.hs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ module Distribution.Simple.Program.Find
3333
, findProgramOnSearchPath
3434
, programSearchPathAsPATHVar
3535
, logExtraProgramSearchPath
36+
, logExtraProgramOverrideEnv
3637
, getSystemSearchPath
3738
, getExtraPathEnv
3839
, simpleProgram
@@ -74,6 +75,19 @@ logExtraProgramSearchPath verbosity extraPaths =
7475
"Including the following directories in PATH:"
7576
: map ("- " ++) extraPaths
7677

78+
logExtraProgramOverrideEnv
79+
:: Verbosity
80+
-> [(String, Maybe String)]
81+
-> IO ()
82+
logExtraProgramOverrideEnv verbosity extraEnv =
83+
info verbosity . unlines $
84+
"Including the following environment variable overrides:"
85+
: [ "- " ++ case mbVal of
86+
Nothing -> "unset " ++ var
87+
Just val -> var ++ "=" ++ val
88+
| (var, mbVal) <- extraEnv
89+
]
90+
7791
findProgramOnSearchPath
7892
:: Verbosity
7993
-> ProgramSearchPath

Cabal/src/Distribution/Simple/Program/Types.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,7 @@ data ProgramSearchPathEntry
107107
ProgramSearchPathDir FilePath
108108
| -- | The system default
109109
ProgramSearchPathDefault
110-
deriving (Eq, Generic, Typeable)
110+
deriving (Show, Eq, Generic, Typeable)
111111

112112
instance Binary ProgramSearchPathEntry
113113
instance Structured ProgramSearchPathEntry

0 commit comments

Comments
 (0)