An open API service indexing awesome lists of open source software.

https://github.com/friendlyanon/cmake-init-use-pkg-config

Using a dependency that does not support clients using CMake
https://github.com/friendlyanon/cmake-init-use-pkg-config

Last synced: 9 months ago
JSON representation

Using a dependency that does not support clients using CMake

Awesome Lists containing this project

README

          

# use-pkg-config

This project was generated by [cmake-init][1].
It's heavily stripped down to focus on showing how to use a dependency that
does not support clients using CMake.

# The problem

You are developing a project, which has a dependency that does not support
clients using CMake. You wish to use it regardless and also make it easy to
transitively depend on.

For this example, [gumbo-parser][2] was chosen, because it has the perfect
characteristics:

* It does not support clients using CMake, but does provide [pkg-config][3]
`.pc` files
* [vcpkg][4] packages this library, but does not install the `.pc` files nor
provide an unofficial CMake package (or at least until [this issue][5] is
resolved)

This would be the same problem even if the dependency used CMake, but did not
support clients using CMake. Failure to provide an install interface via a
CMake package is one way to cause this.

# The solution

When faced with a dependency that does not support clients using CMake is when
developers are forced to write a find module. This repository has such a
find module: [`Findgumbo.cmake`](cmake/find/Findgumbo.cmake)

However, we do not want to be forced or to force people building this project
to use that find module if we can help it. For this reason, project code does
not directly make use of it and instead it is the responsibility of the person
configuring this project to [provide it](CMakePresets.json#L25) if necessary.

Now we have to consider clients using vcpkg as well. When vcpkg packages
something that does not officially support clients using CMake, they usually
use an `unofficial` prefix for the package and target names (see [libuv][6]).
This is done so vcpkg is forwards compatible if a package ever starts
supporting clients who use CMake. Working around this requires quite a bit of
elbow grease:

* The package and target names must be configurable
* in the [build interface](cmake/variables.cmake#L30)
* and the [install interface](cmake/install-config.cmake.in)
* The dependency's target name used for building must not leak into the install
interface, so [hide it](CMakeLists.txt#L37)

The defaults in the CMake code highlighted above all assume an optimistic
outcome, e.g. the developer may use presets to simplify his workflow by setting
the variables up as necessary, like it is done for the CI of this project.
Package managers (the people) are given all the tools to work out the kinks by
just setting a few variables and there won't be any need to patch anything **in
this project**.

# Conclusion

Provide a CMake package, even if you don't use CMake yourself, but if you are
using CMake yourself and don't provide a CMake package, you are subjecting your
clients to the above.

[1]: https://github.com/friendlyanon/cmake-init
[2]: https://github.com/google/gumbo-parser
[3]: https://www.freedesktop.org/wiki/Software/pkg-config/
[4]: https://github.com/microsoft/vcpkg
[5]: https://github.com/microsoft/vcpkg/issues/21086
[6]: https://github.com/microsoft/vcpkg/blob/master/ports/libuv/CMakeLists.txt#L83