Skip to content

Allowing pkg-config to fail #6771

Closed
Closed
@hasufell

Description

@hasufell

Currently, pkgconfig-depends imposes a hard requirement and will fail if the file is not found or pkg-config doesn't exist. This is not portable, there are a few reasons:

  1. some distros incorrectly add .pc files downstream, causing cross-distro breakage (especially debian)
  2. existence of a .pc file may depend on the version of the library
  3. it's not clear how well it works on non-linux platforms, although these are generally supported

In general, I believe users don't really care how cabal figures out the correct library destination etc. Of course pkg-config delivers better results than assuming e.g. FHS, but the latter still works for a majority of use cases, when pkg-config is absent.

As a result, I've come up with a template Setup.hs that sort of makes this optional. However, I feel this is rather fragile. @dcoutts reminded us that cabal-install feeds the pkg-config database into the solver and so should be able to use that information for resolution. A suggested way of triggering this was:

flag use-pkgconfig-foo
  description: get foo lib config from pkg-config
  manual: False
  default: True

library
  [...]

  if flag(use-pkgconfig-foo)
    pkgconfig-depends: libfoo
  else
    includes:          foo.h
    extra-libraries:   foo

This, however, doesn't work, because Cabal tries to find pkg-config deps during configure stage, before the solver:

requirePkg dep@(PkgconfigDependency pkgn range) = do
version <- pkgconfig ["--modversion", pkg]
`catchIO` (\_ -> die' verbosity notFound)
`catchExit` (\_ -> die' verbosity notFound)
let trim = dropWhile isSpace . dropWhileEnd isSpace
let v = PkgconfigVersion (toUTF8BS $ trim version)
if not (withinPkgconfigVersionRange v range)
then die' verbosity (badVersion v)
else info verbosity (depSatisfied v)
where
notFound = "The pkg-config package '" ++ pkg ++ "'"
++ versionRequirement
++ " is required but it could not be found."
badVersion v = "The pkg-config package '" ++ pkg ++ "'"
++ versionRequirement
++ " is required but the version installed on the"
++ " system is version " ++ prettyShow v
depSatisfied v = "Dependency " ++ prettyShow dep
++ ": using version " ++ prettyShow v
versionRequirement
| isAnyPkgconfigVersion range = ""
| otherwise = " version " ++ prettyShow range
pkg = unPkgconfigName pkgn

I tried commenting this out and indeed, cabal doesn't fail prematurely anymore. However, it doesn't seem to pick the alternative resolution (as in: it never disables use-pkgconfig-foo) and will fail at linking stage.

The pkg-config database is fed during the validation phase:

Any pointers would be appreciated.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions