Skip to content

Commit 70196d5

Browse files
committed
Fix for intra-package build-tools dependencies
1 parent 7d904e9 commit 70196d5

File tree

3 files changed

+101
-54
lines changed

3 files changed

+101
-54
lines changed

cabal/Distribution/Simple/Build.hs

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ import qualified Distribution.Simple.Build.PathsModule as Build.PathsModule
6464

6565
import Distribution.Package
6666
( Package(..), PackageName(..), PackageIdentifier(..)
67-
, thisPackageVersion )
67+
, Dependency(..), thisPackageVersion )
6868
import Distribution.Simple.Compiler
6969
( CompilerFlavor(..), compilerFlavor, PackageDB(..) )
7070
import Distribution.PackageDescription
@@ -78,11 +78,13 @@ import Distribution.Simple.Setup
7878
import Distribution.Simple.PreProcess
7979
( preprocessComponent, PPSuffixHandler )
8080
import Distribution.Simple.LocalBuildInfo
81-
( LocalBuildInfo(compiler, buildDir, withPackageDB)
81+
( LocalBuildInfo(compiler, buildDir, withPackageDB, withPrograms)
8282
, Component(..), ComponentLocalBuildInfo(..), withComponentsLBI
8383
, inplacePackageId )
84+
import Distribution.Simple.Program.Types
85+
import Distribution.Simple.Program.Db
8486
import Distribution.Simple.BuildPaths
85-
( autogenModulesDir, autogenModuleName, cppHeaderName )
87+
( autogenModulesDir, autogenModuleName, cppHeaderName, exeExtension )
8688
import Distribution.Simple.Register
8789
( registerPackage, inplaceInstalledPackageInfo )
8890
import Distribution.Simple.Test ( stubFilePath, stubName )
@@ -97,6 +99,8 @@ import Distribution.Text
9799

98100
import Data.Maybe
99101
( maybeToList )
102+
import Data.List
103+
( intersect )
100104
import Control.Monad
101105
( unless )
102106
import System.FilePath
@@ -120,15 +124,16 @@ build pkg_descr lbi flags suffixes = do
120124

121125
internalPackageDB <- createInternalPackageDB distPref
122126

123-
let pre c = preprocessComponent pkg_descr c lbi False verbosity suffixes
124-
lbi' = lbi {withPackageDB = withPackageDB lbi ++ [internalPackageDB]}
125-
-- Use the internal package DB for the exes.
126-
withComponentsLBI pkg_descr lbi $ \comp clbi -> do
127-
pre comp
127+
let pre c lbi' = preprocessComponent pkg_descr c lbi' False verbosity suffixes
128+
withComponentsLBI pkg_descr lbi $ \comp clbi ->
128129
case comp of
129130
CLib lib -> do
131+
let bi = libBuildInfo lib
132+
progs' = addInternalBuildTools pkg_descr lbi bi (withPrograms lbi)
133+
lbi' = lbi { withPrograms = progs' }
134+
pre comp lbi'
130135
info verbosity "Building library..."
131-
buildLib verbosity pkg_descr lbi lib clbi
136+
buildLib verbosity pkg_descr lbi' lib clbi
132137

133138
-- Register the library in-place, so exes can depend
134139
-- on internally defined libraries.
@@ -144,25 +149,40 @@ build pkg_descr lbi flags suffixes = do
144149
(withPackageDB lbi ++ [internalPackageDB])
145150

146151
CExe exe -> do
152+
let bi = buildInfo exe
153+
progs' = addInternalBuildTools pkg_descr lbi bi (withPrograms lbi)
154+
lbi' = lbi {
155+
withPrograms = progs',
156+
withPackageDB = withPackageDB lbi ++ [internalPackageDB]
157+
}
158+
pre comp lbi'
147159
info verbosity $ "Building executable " ++ exeName exe ++ "..."
148160
buildExe verbosity pkg_descr lbi' exe clbi
149161

150162
CTest test -> do
151163
case testInterface test of
152164
TestSuiteExeV10 _ f -> do
153-
let exe = Executable
165+
let bi = testBuildInfo test
166+
exe = Executable
154167
{ exeName = testName test
155168
, modulePath = f
156-
, buildInfo = testBuildInfo test
169+
, buildInfo = bi
157170
}
171+
progs' = addInternalBuildTools pkg_descr lbi bi (withPrograms lbi)
172+
lbi' = lbi {
173+
withPrograms = progs',
174+
withPackageDB = withPackageDB lbi ++ [internalPackageDB]
175+
}
176+
pre comp lbi'
158177
info verbosity $ "Building test suite " ++ testName test ++ "..."
159178
buildExe verbosity pkg_descr lbi' exe clbi
160179
TestSuiteLibV09 _ m -> do
161180
pwd <- getCurrentDirectory
162-
let lib = Library
181+
let bi = testBuildInfo test
182+
lib = Library
163183
{ exposedModules = [ m ]
164184
, libExposed = True
165-
, libBuildInfo = testBuildInfo test
185+
, libBuildInfo = bi
166186
}
167187
pkg = pkg_descr
168188
{ package = (package pkg_descr)
@@ -197,6 +217,13 @@ build pkg_descr lbi flags suffixes = do
197217
: (filter (\(_, x) -> let PackageName name = pkgName x in name == "Cabal" || name == "base")
198218
$ componentPackageDeps clbi)
199219
}
220+
progs' = addInternalBuildTools pkg_descr lbi bi (withPrograms lbi)
221+
lbi' = lbi {
222+
withPrograms = progs',
223+
withPackageDB = withPackageDB lbi ++ [internalPackageDB]
224+
}
225+
226+
pre comp lbi'
200227
info verbosity $ "Building test suite " ++ testName test ++ "..."
201228
buildLib verbosity pkg lbi' lib clbi
202229
registerPackage verbosity ipi pkg lbi' True $ withPackageDB lbi'
@@ -213,6 +240,22 @@ createInternalPackageDB distPref = do
213240
writeFile dbFile "[]"
214241
return packageDB
215242

243+
addInternalBuildTools :: PackageDescription -> LocalBuildInfo -> BuildInfo
244+
-> ProgramDb -> ProgramDb
245+
addInternalBuildTools pkg lbi bi progs =
246+
foldr updateProgram progs internalBuildTools
247+
where
248+
internalBuildTools =
249+
[ simpleConfiguredProgram toolName (FoundOnSystem toolLocation)
250+
| toolName <- toolNames
251+
, let toolLocation = buildDir lbi </> toolName </> toolName <.> exeExtension ]
252+
toolNames = intersect buildToolNames internalExeNames
253+
internalExeNames = map exeName (executables pkg)
254+
buildToolNames = map buildToolName (buildTools bi)
255+
where
256+
buildToolName (Dependency (PackageName name) _ ) = name
257+
258+
216259
-- TODO: build separate libs in separate dirs so that we can build
217260
-- multiple libs, e.g. for 'LibTest' library-style testsuites
218261
buildLib :: Verbosity -> PackageDescription -> LocalBuildInfo

cabal/Distribution/Simple/Configure.hs

Lines changed: 21 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ import Distribution.Simple.Hpc ( enableCoverage )
9191
import Distribution.Simple.Program
9292
( Program(..), ProgramLocation(..), ConfiguredProgram(..)
9393
, ProgramConfiguration, defaultProgramConfiguration
94-
, configureAllKnownPrograms, knownPrograms, lookupKnownProgram, addKnownProgram
94+
, configureAllKnownPrograms, knownPrograms, lookupKnownProgram
9595
, userSpecifyArgss, userSpecifyPaths
9696
, requireProgram, requireProgramVersion
9797
, pkgConfigProgram, gccProgram, rawSystemProgramStdoutConf )
@@ -429,21 +429,26 @@ configure (pkg_descr0, pbi) cfg
429429
++ "supported by " ++ display (compilerId comp) ++ ": "
430430
++ intercalate ", " (map display exts)
431431

432-
-- configured known/required programs & build tools
433-
let requiredBuildTools = concatMap buildTools (allBuildInfo pkg_descr)
434-
435-
-- add all exes built by this package ("internal exes") to the program
436-
-- conf; this makes the namespace of build-tools include intrapackage
437-
-- references to executables
438-
let programsConfig'' = foldr (addInternalExe buildDir') programsConfig'
439-
(executables pkg_descr)
440-
441-
programsConfig''' <-
442-
configureAllKnownPrograms (lessVerbose verbosity) programsConfig''
432+
-- configured known/required programs & external build tools
433+
-- exclude build-tool deps on "internal" exes in the same package
434+
let requiredBuildTools =
435+
[ buildTool
436+
| let exeNames = map exeName (executables pkg_descr)
437+
, bi <- allBuildInfo pkg_descr
438+
, buildTool@(Dependency (PackageName toolName) reqVer) <- buildTools bi
439+
, let isInternal =
440+
toolName `elem` exeNames
441+
-- we assume all internal build-tools are
442+
-- versioned with the package:
443+
&& packageVersion pkg_descr `withinRange` reqVer
444+
, not isInternal ]
445+
446+
programsConfig'' <-
447+
configureAllKnownPrograms (lessVerbose verbosity) programsConfig'
443448
>>= configureRequiredPrograms verbosity requiredBuildTools
444449

445-
(pkg_descr', programsConfig'''') <-
446-
configurePkgconfigPackages verbosity pkg_descr programsConfig'''
450+
(pkg_descr', programsConfig''') <-
451+
configurePkgconfigPackages verbosity pkg_descr programsConfig''
447452

448453
split_objs <-
449454
if not (fromFlag $ configSplitObjs cfg)
@@ -529,7 +534,7 @@ configure (pkg_descr0, pbi) cfg
529534
installedPkgs = packageDependsIndex,
530535
pkgDescrFile = Nothing,
531536
localPkgDescr = pkg_descr',
532-
withPrograms = programsConfig'''',
537+
withPrograms = programsConfig''',
533538
withVanillaLib = fromFlag $ configVanillaLib cfg,
534539
withProfLib = fromFlag $ configProfLib cfg,
535540
withSharedLib = fromFlag $ configSharedLib cfg,
@@ -570,20 +575,11 @@ configure (pkg_descr0, pbi) cfg
570575
dirinfo "Documentation" (docdir dirs) (docdir relative)
571576

572577
sequence_ [ reportProgram verbosity prog configuredProg
573-
| (prog, configuredProg) <- knownPrograms programsConfig'''' ]
578+
| (prog, configuredProg) <- knownPrograms programsConfig''' ]
574579

575580
return lbi
576581

577582
where
578-
addInternalExe bd exe =
579-
let nm = exeName exe in
580-
addKnownProgram Program {
581-
programName = nm,
582-
programFindLocation = \_ -> return $ Just $ bd </> nm </> nm,
583-
programFindVersion = \_ _ -> return Nothing,
584-
programPostConf = \_ _ -> return []
585-
}
586-
587583
addExtraIncludeLibDirs pkg_descr =
588584
let extraBi = mempty { extraLibDirs = configExtraLibDirs cfg
589585
, PD.includeDirs = configExtraIncludeDirs cfg}

cabal/Distribution/Simple/Program/Types.hs

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,27 +17,28 @@
1717
module Distribution.Simple.Program.Types (
1818
-- * Program and functions for constructing them
1919
Program(..),
20-
internalProgram,
2120
simpleProgram,
2221

2322
-- * Configured program and related functions
2423
ConfiguredProgram(..),
2524
programPath,
2625
ProgArg,
2726
ProgramLocation(..),
27+
simpleConfiguredProgram,
2828
) where
2929

30-
import Data.List (nub)
31-
import System.FilePath ((</>))
32-
3330
import Distribution.Simple.Utils
34-
( findProgramLocation, findFirstFile )
31+
( findProgramLocation )
3532
import Distribution.Version
3633
( Version )
3734
import Distribution.Verbosity
3835
( Verbosity )
3936

4037
-- | Represents a program which can be configured.
38+
--
39+
-- Note: rather than constructing this directly, start with 'simpleProgram' and
40+
-- override any extra fields.
41+
--
4142
data Program = Program {
4243
-- | The simple name of the program, eg. ghc
4344
programName :: String,
@@ -59,6 +60,12 @@ data Program = Program {
5960

6061
type ProgArg = String
6162

63+
-- | Represents a program which has been configured and is thus ready to be run.
64+
--
65+
-- These are usually made by configuring a 'Program', but if you have to
66+
-- construct one directly then start with 'simpleConfiguredProgram' and
67+
-- override any extra fields.
68+
--
6269
data ConfiguredProgram = ConfiguredProgram {
6370
-- | Just the name again
6471
programId :: String,
@@ -87,7 +94,7 @@ data ProgramLocation
8794
-- ^The user gave the path to this program,
8895
-- eg. --ghc-path=\/usr\/bin\/ghc-6.6
8996
| FoundOnSystem { locationPath :: FilePath }
90-
-- ^The location of the program, as located by searching PATH.
97+
-- ^The program was found automatically.
9198
deriving (Read, Show, Eq)
9299

93100
-- | The full path of a configured program.
@@ -109,14 +116,15 @@ simpleProgram name = Program {
109116
programPostConf = \_ _ -> return []
110117
}
111118

112-
-- | Make a simple 'internal' program; that is, one that was built as an
113-
-- executable already and is expected to be found in the build directory
114-
internalProgram :: [FilePath] -> String -> Program
115-
internalProgram paths name = Program {
116-
programName = name,
117-
programFindLocation = \_v ->
118-
findFirstFile id [ path </> name | path <- nub paths ],
119-
programFindVersion = \_ _ -> return Nothing,
120-
programPostConf = \_ _ -> return []
119+
-- | Make a simple 'ConfiguredProgram'.
120+
--
121+
-- > simpleConfiguredProgram "foo" (FoundOnSystem path)
122+
--
123+
simpleConfiguredProgram :: String -> ProgramLocation -> ConfiguredProgram
124+
simpleConfiguredProgram name loc = ConfiguredProgram {
125+
programId = name,
126+
programVersion = Nothing,
127+
programDefaultArgs = [],
128+
programOverrideArgs = [],
129+
programLocation = loc
121130
}
122-

0 commit comments

Comments
 (0)