Re: [CMake] What is the recommended ways to find libraries
2015-06-17 21:00 GMT+02:00 Ondřej Čertík : > 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 -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake
Re: [CMake] What is the recommended ways to find libraries
Hi Oto, On Wed, Jun 17, 2015 at 11:18 AM, Oto Petřík wrote: > Hi, > >> 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. > >> 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. > > you may be looking for CMAKE_PREFIX_PATH > (http://www.cmake.org/cmake/help/v3.2/variable/CMAKE_PREFIX_PATH.html) > > cmake > -DCMAKE_PREFIX_PATH=$HOME/built-libs/gmp;$HOME/built-libs/arb;$HOME/built-libs/otherdependencies > (or have a script that sets CMAKE_PREFIX_PATH environment variable) > > works with find_module, find_file, find_library,... expects > directories to have standard structure (include,lib,...), see > documentation of find_* commands for details. > it is usually enough to set CMAKE_PREFIX_PATH to DESTDIRs used in > dependencies' "make install DESTDIR=/foo" > > you may want to remove NO_DEFAULT_PATH as used in linked > LibFindMacros.cmake, it disables this functionality. Yes, indeed CMAKE_PREFIX_PATH is a replacement for our COMMON_DIR, i.e. the case 3. above. So one can apply the following patch to our macros: --- a/cmake/LibFindMacros.cmake +++ b/cmake/LibFindMacros.cmake @@ -42,7 +42,6 @@ macro (libfind_library libname pkg) ${libname} PATHS ${${PKG}_DIR} -${COMMON_DIR} PATH_SUFFIXES lib lib64 @@ -73,7 +72,6 @@ macro (libfind_include HEADER pkg) ${HEADER} PATHS ${${PKG}_DIR} -${COMMON_DIR} PATH_SUFFIXES include NO_DEFAULT_PATH and just use CMAKE_PREFIX_PATH instead of COMMON_DIR. I tried it in our code and it works. 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. 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). Ondrej -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake
Re: [CMake] What is the recommended ways to find libraries
Hi, > 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. > 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. you may be looking for CMAKE_PREFIX_PATH (http://www.cmake.org/cmake/help/v3.2/variable/CMAKE_PREFIX_PATH.html) cmake -DCMAKE_PREFIX_PATH=$HOME/built-libs/gmp;$HOME/built-libs/arb;$HOME/built-libs/otherdependencies (or have a script that sets CMAKE_PREFIX_PATH environment variable) works with find_module, find_file, find_library,... expects directories to have standard structure (include,lib,...), see documentation of find_* commands for details. it is usually enough to set CMAKE_PREFIX_PATH to DESTDIRs used in dependencies' "make install DESTDIR=/foo" you may want to remove NO_DEFAULT_PATH as used in linked LibFindMacros.cmake, it disables this functionality. Regards, Oto Petrik -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake
[CMake] What is the recommended ways to find libraries
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 -- Powered by www.kitware.com Please keep messages on-topic and check the CMake FAQ at: http://www.cmake.org/Wiki/CMake_FAQ Kitware offers various services to support the CMake community. For more information on each offering, please visit: CMake Support: http://cmake.org/cmake/help/support.html CMake Consulting: http://cmake.org/cmake/help/consulting.html CMake Training Courses: http://cmake.org/cmake/help/training.html Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html Follow this link to subscribe/unsubscribe: http://public.kitware.com/mailman/listinfo/cmake