[CMake] Providing multiple different MAJOR API versions with write_basic_package_version_file

Craig Scott craig.scott at crascit.com
Sat Dec 28 07:26:47 EST 2019


On Mon, Nov 4, 2019 at 10:54 PM Philip Van Hoof <philip at codeminded.be>
wrote:

> Hello,
>
> After Craig's very interesting presentation at CppCon 2019* I learned a
> bunch of new things which I of course immediately wanted to try out**.
>
> I read about the write_basic_package_version_file which is in
> CMakePackageConfigHelpers. Craig also mentioned in the presentation
> that you can have a so called API-version in the target's name. And
> that for example Qt does this (Qt5Core, which has the MAJOR number 5 in
> its target name).
>
> For my target name I prefer to have the API version after a dash, like
> how GLib and DBus packages do it: libglib-2.0.so.0.6200.1 on current
> Ubuntu, for example in /usr/lib/x86_64-linux-gnu.
>

Understand that from CMake's point of view, the library name is then
glib-2.0 and the fact that it contains numbers that look like a version of
some kind is completely irrelevant (to CMake). You could just as well have
called it glib-specialsauce. Putting an API version into the library name
is *changing* the library name to something else. This is particularly
inconvenient for projects using find_package() to find your library, since
they have to specify the exact API version now because you've included it
in the library name. glib-2.0 is a completely different library to glib-2.1,
for example. It might be more precise, but it is less convenient to
consume. You could potentially remove that inconvenience by naming the
config package file glibConfig.cmake instead of glib-2.0Config.cmake, then
place it under an API-versioned directory that find_package() would search
in, but that would seem to remove the very advantage you are trying to gain
by putting the API version in the library name. The consuming project would
effectively be able to ignore the API version if you did this.



>
> I wonder what that means for the <filename> property of
> write_basic_package_version_file. In the autotools and meson world, the
> usage of pkg-config files seems to indicate that the same filename
> naming scheme applies to the .pc file:
>
> /usr/lib/x86_64-linux-gnu/pkgconfig/glib-2.0.pc
>
> This allows me to distinguish between older MAJOR API versions of GLib
> and newer MAJOR API versions of it, using FindPkgConfig***
>
> Supposedly something similar is possible with find_package's .cmake
> files as installed by write_basic_package_version_file?
>

As above, you are creating an entirely different library by putting the API
version in its base name. So your call to find_package() would be looking
for that API-specific name and your package version file would have to
match that expected name too.


>
> How do I provide a PackageNameConfigVersion.cmake for major version 1.0
> and 2.0 (the equivalent of PackageName-1.0.pc and PackageName-2.0.pc in
> the pkgconfig directory)?
>

Since from CMake's perspective they are two completely different libraries,
you'd end up with PackageName-1.0ConfigVersion.cmake and
PackageName-2.0ConfigVersion.cmake as the file names.



>
> Kind regards,
>
> Philip
>
> * https://www.youtube.com/watch?v=m0DwB4OvDXk
> **
> https://github.com/pvanhoof/dir-examples/commit/523cab5edaff99acba037218d5b95227cb2487a9
> *** https://cmake.org/cmake/help/v3.15/module/FindPkgConfig.html



I've debated whether to express my own opinion on this, but in this case
I'll risk it. I personally find that putting an API version in the name of
the library itself to be an annoyance. I'm typically interested in the ABI
versioning, and I take on the responsibility of understanding how that maps
to the API. If semantic versioning is being followed for the ABI
versioning, then this mapping is typically trivial. To me, any gains from
making the API version explicit in the library name are less significant
than the negative impact on the ease of consuming that library and the
added "scare factor" of an overly complicated versioning system. Versioning
is already complex enough for most users, if we can avoid making it more
so, then users will likely appreciate that.

It may be instructive to note that there were changes in CMake 3.14 to
support Qt being found without the API version being specified as part of
the package name (i.e. as find_package(Qt)). See policy CMP0084
<https://cmake.org/cmake/help/latest/policy/CMP0084.html> for some brief
background.

-- 
Craig Scott
Melbourne, Australia
https://crascit.com

Get the hand-book for every CMake user: Professional CMake: A Practical
Guide <https://crascit.com/professional-cmake/>
Consulting services (CMake, C++, build/release processes):
https://crascit.com/services
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://cmake.org/pipermail/cmake/attachments/20191228/8afd2800/attachment.html>


More information about the CMake mailing list