Open RyanGlScott opened 7 years ago
This seems like it should be possible, but a more detailed spec of how pkg-config dependencies and versions get translated into the macro (note that MIN_VERSION macros hardcode the number of components) needs to be written.
Ack, that's a good point. According to https://people.freedesktop.org/~dbn/pkg-config-guide.html#writing, pkg-config
version numbers are compared using the same algorithm as the RPM package manager, which is far more complicated than what we have in Haskell given that RPM versions can contain far more characters than what Haskell allows.
In fact, after reading the dissected algorithm in http://blog.jasonantman.com/2014/07/how-yum-and-rpm-compare-versions/#how-rpm-compares-version-parts, I'm doubtful that it'd be possible to easily port to a CPP macro...
Let me ask a slightly different question, then, since I'm doubting the possibility of accomplishing this with CPP macros more and more. Currently, we also autogenerate a file called Paths_<package>.hs
which exports a Version
value representing <package>
. Could we also generate a file exporting, say, PkgConfigVersion
values for its pkg-config
dependencies?
This way, we can avoid conflating Haskell versions with pkg-config
versions, and instead of having to put this in CPP, we could (in a separate library) develop a pkg-config
version comparison algorithm à la rpmdev-vercmp
, as ask folks to compare their pkg-config
version numbers that way.
If we went with this approach, then the ambiguity surrounding periods in .pc
filenames would go away. We could turn hyphens into underscores and periods into single quotes. That way, glib-2.0.pc
would turn into, say, glib_2'0Version :: PkgConfigVersion
.
Oh, I really should have done some searching beforehand, since there's some important background material.
First, there's https://github.com/haskell/cabal/issues/163, which laments the fact that pkg-config
versions are much more complicated than Haskell Versions
. https://github.com/haskell/cabal/pull/2730 was an attempt at incorporating odd pkg-config
versions that include string suffixes (e.g., 5.1.0alpha
) by simply dropping the suffix and interpreting pkg-config
versions as Haskell Version
s.
If we went with that approach (which hasn't been merged yet, FWIW), then we could go back to the earlier suggestion of using Cabal
macros. I don't know how many folks would care if we dropped versions' string suffixes like that. I personally wouldn't, but maybe others would.
I don't think anyone has ever been sad about being able to match against specific point releases. I know that with GHC's macros, we used to not tell people what the patch version was, and this meant people were sad sometimes. On the other hand, maybe that is good enough for you, and a fancier macro can be introduced when someone needs to scratch that itch.
I don't really know what the right thing to do here is (defer to your judgment!) just be aware that anything we do here we basically have to support forever! Cheers.
pkg-config
version numbers, so I suppose that all that remains to resolve this issue is to figure out the corresponding CPP macros to enforce that versioning scheme.@RyanGlScott PkgconfigVersion is unfortunately literally an arbitrary string. So we cannot do anything compatible MIN_PKGCONFIG_VERSION
(with openssl
being an example where we cannot even pretend).
Yet, exposing PKGCONFIG_VERSION
as a string is straight-forward.
Ugh, right. I had completey forgotten about my comments above (written three years ago) about how infeasible this would be to implement as a CPP macro. Once again, I'm force to dismiss that as a possibility.
Having PKGCONFIG_VERSION
might be worth it, but I'm somewhat worried about the potential for conflicts between the names of C packages and Haskell packages. I'm starting to wonder if perhaps the use case I had would be better suited by using Cabal
flags, i.e.,
if flag(custom)
cpp-options: -DNINE_POINT_THREE_H
pkgconfig-depends: libpq >=9.3h
else
pkgconfig-depends: libpq <9.3h
The prefix MIN_PKGCONFIG_
prevents clashes. I wouldn't worry about that.
Having that version can be useful to expose it from the compiled module. So you can say compiled against libpq "9.4"
or something like that. Note: compiled against, what's actually (usually) dynamically loaded is another story.
I'll try to add it soon. I just recently refactored cabal_macros
generation, so I'm not scare to edit that part of the code :)
I've released a Cabal setup hook library, cabal-pkg-config-version-hook
that adds such macros, as an interim solution that is compatible with existing cabal versions.
It follows a different naming convention, so it doesn't interfere with the one suggested here.
I ran into an issue today where I needed to write some code like this:
This is in a project where
<C library>
is detected withpkgconfig-depends
. I would have hoped that the autogeneratedcabal_macros.h
would provide some way of detecting<C library>
's version (as specified in<C library>.pc
, but sadly that doesn't seem to be the case, so I have to work around it manually by usingCabal
flags andcpp-options: -DC_LIBRARY_VERSION=xyz
.Would it be unreasonable to have
cabal_macros.h
spit outPKGCONFIG_VERSION
andMIN_PKGCONFIG_VERSION
macros for everypkg-config
dependency? There's the issue thatpkg-config
names can contain characters that aren't permissible inCabal
package names. For example,glib-2.0
contains a period. But maybe we could just turn periods into underscores like we currently do hyphens.