Skip to content

Commit 792b257

Browse files
authored
Merge pull request #8579 from haskell/mergify/bp/3.8/pr-8496
build pkgconfig db individually when bulk fails (backport #8496)
2 parents ea54a21 + 62d7b92 commit 792b257

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,16 @@ import Distribution.Solver.Compat.Prelude
2424
import Prelude ()
2525

2626
import Control.Exception (handle)
27+
import Control.Monad (mapM)
2728
import qualified Data.Map as M
2829
import System.FilePath (splitSearchPath)
2930

3031
import Distribution.Compat.Environment (lookupEnv)
3132
import Distribution.Package (PkgconfigName, mkPkgconfigName)
3233
import Distribution.Parsec
3334
import Distribution.Simple.Program
34-
(ProgramDb, getProgramOutput, pkgConfigProgram, needProgram)
35+
(ProgramDb, getProgramOutput, pkgConfigProgram, needProgram, ConfiguredProgram)
36+
import Distribution.Simple.Program.Run (getProgramInvocationOutputAndErrors, programInvocation)
3537
import Distribution.Simple.Utils (info)
3638
import Distribution.Types.PkgconfigVersion
3739
import Distribution.Types.PkgconfigVersionRange
@@ -65,9 +67,15 @@ readPkgConfigDb verbosity progdb = handle ioErrorHandler $ do
6567
-- The output of @pkg-config --list-all@ also includes a description
6668
-- for each package, which we do not need.
6769
let pkgNames = map (takeWhile (not . isSpace)) pkgList
68-
pkgVersions <- lines <$> getProgramOutput verbosity pkgConfig
69-
("--modversion" : pkgNames)
70-
(return . pkgConfigDbFromList . zip pkgNames) pkgVersions
70+
(pkgVersions, _errs, exitCode) <-
71+
getProgramInvocationOutputAndErrors verbosity
72+
(programInvocation pkgConfig ("--modversion" : pkgNames))
73+
case exitCode of
74+
ExitSuccess -> (return . pkgConfigDbFromList . zip pkgNames) (lines pkgVersions)
75+
-- if there's a single broken pc file the above fails, so we fall back into calling it individually
76+
_ -> do
77+
info verbosity ("call to pkg-config --modversion on all packages failed. Falling back to querying pkg-config individually on each package")
78+
pkgConfigDbFromList . catMaybes <$> mapM (getIndividualVersion pkgConfig) pkgNames
7179
where
7280
-- For when pkg-config invocation fails (possibly because of a
7381
-- too long command line).
@@ -80,6 +88,15 @@ readPkgConfigDb verbosity progdb = handle ioErrorHandler $ do
8088
ioErrorHandler :: IOException -> IO PkgConfigDb
8189
ioErrorHandler e = noPkgConfig (show e)
8290

91+
getIndividualVersion :: ConfiguredProgram -> String -> IO (Maybe (String, String))
92+
getIndividualVersion pkgConfig pkg = do
93+
(pkgVersion, _errs, exitCode) <-
94+
getProgramInvocationOutputAndErrors verbosity
95+
(programInvocation pkgConfig ["--modversion",pkg])
96+
return $ case exitCode of
97+
ExitSuccess -> Just (pkg, pkgVersion)
98+
_ -> Nothing
99+
83100
-- | Create a `PkgConfigDb` from a list of @(packageName, version)@ pairs.
84101
pkgConfigDbFromList :: [(String, String)] -> PkgConfigDb
85102
pkgConfigDbFromList pairs = (PkgConfigDb . M.fromList . map convert) pairs

changelog.d/pr-8496

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
synopsis: build pkgconfig db individually when bulk fails
2+
packages: cabal-install cabal-install-solver
3+
prs: #8496
4+
issues: #8494
5+
6+
description: {
7+
8+
- When pkg-config fails to get versions for all packages in bulk, falls back to querying one-by-one.
9+
10+
}

0 commit comments

Comments
 (0)