Skip to content

Commit

Permalink
Merge pull request #8579 from haskell/mergify/bp/3.8/pr-8496
Browse files Browse the repository at this point in the history
build pkgconfig db individually when bulk fails (backport #8496)
  • Loading branch information
mergify[bot] authored Nov 7, 2022
2 parents ea54a21 + 62d7b92 commit 792b257
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 4 deletions.
25 changes: 21 additions & 4 deletions cabal-install-solver/src/Distribution/Solver/Types/PkgConfigDb.hs
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,16 @@ import Distribution.Solver.Compat.Prelude
import Prelude ()

import Control.Exception (handle)
import Control.Monad (mapM)
import qualified Data.Map as M
import System.FilePath (splitSearchPath)

import Distribution.Compat.Environment (lookupEnv)
import Distribution.Package (PkgconfigName, mkPkgconfigName)
import Distribution.Parsec
import Distribution.Simple.Program
(ProgramDb, getProgramOutput, pkgConfigProgram, needProgram)
(ProgramDb, getProgramOutput, pkgConfigProgram, needProgram, ConfiguredProgram)
import Distribution.Simple.Program.Run (getProgramInvocationOutputAndErrors, programInvocation)
import Distribution.Simple.Utils (info)
import Distribution.Types.PkgconfigVersion
import Distribution.Types.PkgconfigVersionRange
Expand Down Expand Up @@ -65,9 +67,15 @@ readPkgConfigDb verbosity progdb = handle ioErrorHandler $ do
-- The output of @pkg-config --list-all@ also includes a description
-- for each package, which we do not need.
let pkgNames = map (takeWhile (not . isSpace)) pkgList
pkgVersions <- lines <$> getProgramOutput verbosity pkgConfig
("--modversion" : pkgNames)
(return . pkgConfigDbFromList . zip pkgNames) pkgVersions
(pkgVersions, _errs, exitCode) <-
getProgramInvocationOutputAndErrors verbosity
(programInvocation pkgConfig ("--modversion" : pkgNames))
case exitCode of
ExitSuccess -> (return . pkgConfigDbFromList . zip pkgNames) (lines pkgVersions)
-- if there's a single broken pc file the above fails, so we fall back into calling it individually
_ -> do
info verbosity ("call to pkg-config --modversion on all packages failed. Falling back to querying pkg-config individually on each package")
pkgConfigDbFromList . catMaybes <$> mapM (getIndividualVersion pkgConfig) pkgNames
where
-- For when pkg-config invocation fails (possibly because of a
-- too long command line).
Expand All @@ -80,6 +88,15 @@ readPkgConfigDb verbosity progdb = handle ioErrorHandler $ do
ioErrorHandler :: IOException -> IO PkgConfigDb
ioErrorHandler e = noPkgConfig (show e)

getIndividualVersion :: ConfiguredProgram -> String -> IO (Maybe (String, String))
getIndividualVersion pkgConfig pkg = do
(pkgVersion, _errs, exitCode) <-
getProgramInvocationOutputAndErrors verbosity
(programInvocation pkgConfig ["--modversion",pkg])
return $ case exitCode of
ExitSuccess -> Just (pkg, pkgVersion)
_ -> Nothing

-- | Create a `PkgConfigDb` from a list of @(packageName, version)@ pairs.
pkgConfigDbFromList :: [(String, String)] -> PkgConfigDb
pkgConfigDbFromList pairs = (PkgConfigDb . M.fromList . map convert) pairs
Expand Down
10 changes: 10 additions & 0 deletions changelog.d/pr-8496
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
synopsis: build pkgconfig db individually when bulk fails
packages: cabal-install cabal-install-solver
prs: #8496
issues: #8494

description: {

- When pkg-config fails to get versions for all packages in bulk, falls back to querying one-by-one.

}

0 comments on commit 792b257

Please sign in to comment.