[CMake] What is the recommended ways to find libraries

Oto Petřík oto.petrik at gmail.com
Wed Jun 17 17:57:24 EDT 2015


2015-06-17 21:00 GMT+02:00 Ondřej Čertík <ondrej.certik at gmail.com>:
> and just use CMAKE_PREFIX_PATH instead of COMMON_DIR. I tried it in
> our code and it works.

the idea is, that there is no need for PKG1_INCLUDE_DIRS, no
PKG1_LIBRARIES and no PKG1_DIR
just one path per dependency in CMAKE_PREFIX_PATH
(or per group of dependencies in common directory)

if dependency 'MyDependency' is installed in /opt/mydependency
then after adding /opt/mydependency to CMAKE_PREFIX_PATH, following happens:

find_library searches in:
/opt/mydependency/lib
/opt/mydependency

and find_path,find_file searches in:
/opt/mydependency/include
/opt/mydependency

(and if CMAKE_LIBRARY_ARCHITECTURE is set, then it is used as
additional subdirectory under 'lib' and 'include')

it looks like cmake documentation implies that only 'lib' and
'include' subdirectories are searched, and not the actual directory.
at least cmake 3.2.1 on windows searches even the directory itself,
looks like the behavior is not platform dependent:

Source/cmSearchPath.cxx: method cmSearchPath::AddPrefixPaths lines 241-254
(http://www.cmake.org/gitweb?p=cmake.git;a=blob;f=Source/cmSearchPath.cxx;h=c9cc81737ac9ae65593ddea30f98233844274112;hb=HEAD#l241)


when writing cmake/FindMyDependency.cmake, instead of libfind_* macros
use plain find_* commands:

find_library(MYDEPENDENCY_LIBRARY
 NAMES mydependency)

find_path(MYDEPENDENCY_INCLUDE_DIR
 NAMES mydependency.h)

if the header is in one of the following two locations, the work is done.
/opt/mydependency/include/mydependency.h
/opt/mydependency/mydependency.h

two users installing/building same dependency end up with more or less
the same directory structure,
if you get path to that directory as part of CMAKE_PREFIX_PATH, you
should be able to find headers/libraries.
for unusual directory structure or platform/compiler differences use
PATH_SUFFIXES. in exceptional cases find headers, then
assemble path to libraries based on the header path - use it as a
HINTS to find_library (probably called with NO_DEFAULT_PATH)


> However, for 1. and 2. there is no solution in CMake. There is
> CMAKE_INCLUDE_PATH and CMAKE_LIBRARY_PATH, but Isuru just tested it
> and CMAKE_PREFIX_PATH takes precedence over CMAKE_INCLUDE_PATH, which
> means that if you have a stack of packages installed in
> CMAKE_PREFIX_PATH, you cannot specify PKG1 using CMAKE_INCLUDE_PATH.
> And even if cmake changes the order, then if CMAKE_INCLUDE_PATH
> besides PKG1 also contains PKG2, but you want PKG2 from
> CMAKE_PREFIX_PATH, it won't work. The true solution is per package
> include/lib paths, just like we implemented in our macros.

when using only CMAKE_PREFIX_PATH, it should be possible to solve this
by reordering paths within CMAKE_PREFIX_PATH (PKG1 first, stack of
packages last).

it should work for cases of new version of PKG1 in separate directory
"overriding" (old) PKG1 in another directory containing e.g. oldPKG1,
PKG2, ...

it will break for two directories e.g. 'stable' and 'testing', each
with both PKG1 and PKG2 - you cannot get stable PKG1 and testing PKG2,
but in that case it is a problem to even construct the list of include
directories for the compiler.

> We tried many things, but we haven't figured out a solution other than
> our macros. So it looks like CMake itself should have our macros (or
> an equivalent functionality).
is there a case where "dependencies are in following directories,
search them in order" behavior of CMAKE_PREFIX_PATH is not enough ?

Oto


More information about the CMake mailing list