[CMake] What is the recommended ways to find libraries

Ondřej Čertík ondrej.certik at gmail.com
Thu Jun 11 16:39:07 EDT 2015


Hi,

What is the official recommended way to make your project depend on
other libraries using cmake?

Let's say my project wants to depend on a library PKG1 (here PKG1 can
be MPFR, MPC, PTHREAD, GMP, BZIP2, you name it). Let's say the library
is installed in $PKG1/include, $PKG1/lib, alternatively, all my
dependencies are installed in $HASHSTACK/include and $HASHSTACK/lib,
or perhaps they are installed system wide.

As a user, I would like at least the following ways to specify the library:

1. cmake -DPKG1_INCLUDE_DIRS=$PKG1/include -DPKG1_LIBRARIES=$PKG1/lib
2. cmake -DPKG1_DIR=$PKG1
3. cmake -DCOMMON_DIR=$HASHSTACK
4. cmake

For more than 1 package, I want to chain it on the command line, i.e.
cmake -DPKG1_DIR=$PKG1 -DPKG2_DIR=$PKG2 ...

In the above, 1. specifies the include and library paths separately,
2. specifies the root installation directory, 3. specifies the root
installation directory for all dependencies (but if you specify let's
say PKG3 using 1. or 2., it will take precedence) and 4. just uses
systemwide. We can find a better name for COMMON_DIR (perhaps
TPL_ROOT_DIR, or TPL_COMMON_DIR, ...).


The only official documentation that I was able to find is this:

http://www.cmake.org/Wiki/CMake:How_To_Find_Libraries

Notice that they recommend to do per project programming, so in
particular, each project must implement the above rules, and so each
project does, and implements it slightly differently, some projects
for example skip the -DPKG1_DIR option. The wiki also recommends to
use Using_LibFindMacros, which again, requires per project
programming.

Perhaps I am missing the official recommendation regarding the above,
so that's why I am asking here. But if there is none, then I think the
current state is unsatisfactory.

Such functionality should be in cmake itself, and projects should just
use it. For projects that I am involved in, we implemented the
following:

https://github.com/sympy/symengine/blob/a4b2c773f2286c6efb06e70894b672032e345faf/cmake/LibFindMacros.cmake
https://github.com/sympy/symengine/blob/a4b2c773f2286c6efb06e70894b672032e345faf/cmake/FindGMP.cmake
https://github.com/sympy/symengine/blob/a4b2c773f2286c6efb06e70894b672032e345faf/CMakeLists.txt#L41

You can see the libfind_include(), libfind_library() definitions, how
they are used in FindGMP and finally how FindGMP is used in the main
CMakeLists.txt. These macros implement the above. It is
unsatisfactory, that now I need to copy this to all other projects,
that would like to use this and projects that already programmed a
similar, but incompatible solution cannot use it at all.

Here is a list of all our (mostly optional) dependencies:

https://github.com/sympy/symengine/tree/a4b2c773f2286c6efb06e70894b672032e345faf/cmake

Some packages like Cython and Python require special code, but for
most libraries that have couple include files and couple installed
libraries, this works excellent.


We would be happy to contribute something like that into cmake itself,
so that any project can use it. But it's weird to me, that nobody has
done it yet, so perhaps we are fundamentally misunderstanding how to
depend on external libraries with a cmake project.

Thanks,
Ondrej Certik


More information about the CMake mailing list