Re: [CMake] What is the recommended ways to find libraries

2015-06-17 Thread Ondřej Čertík
Hi Oto,

On Wed, Jun 17, 2015 at 11:18 AM, Oto Petřík oto.pet...@gmail.com 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

2015-06-17 Thread Oto Petřík
2015-06-17 21:00 GMT+02:00 Ondřej Čertík ondrej.cer...@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
-- 

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

2015-06-17 Thread Oto Petřík
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

2015-06-11 Thread Ondřej Čertík
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