Skip to content

Commit

Permalink
build pkgconfig db individually when bulk fails (haskell#8496)
Browse files Browse the repository at this point in the history
* build pkgconfig db individually when bulk fails

* fix typo

* changelog, comments

* address comments

* revert unnecessary extra failure check

* fix changelog

Co-authored-by: Gershom Bazerman <gershom@arista.com>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored and alexbiehl committed Dec 15, 2022
1 parent d43afd6 commit 4c94bf0
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 4c94bf0

Please sign in to comment.