"Local" Build and CMake

2,172 views
Skip to first unread message

Garrett Warnell

unread,
Nov 13, 2013, 2:55:26 PM11/13/13
to ceres-...@googlegroups.com
I did a "local" install today (1.8.0) using
  • --prefix during the gflags and glog installs
  • -DGLOG_INCLUDE_DIR_HINTS, -DGLOG_LIBRARY_DIR_HINTS, -DGFLAGS_INCLUDE_DIR_HINTS, -DGFLAGS_LIBRARY_INCLUDE_HINTS, and -DCMAKE_INSTALL_PREFIX during the Ceres Solver install
but I still ran into a couple issues when trying to use CMake to build my project:
  1. Unless I made ceres-bin/ a subdirectory of ceres-solver-1.8.0/, CMake couldn't find Eigen
  2. Unless I used -DGLOG_INCLUDE_DIR and -DGLOG_LIBRARY, CMake couldn't find glog
I'm pretty new to CMake, so my question is: are either of these issues avoidable?  For 1, the build instructions (docs/html/building.html) don't seem to indicate that ceres-bin/ should be a subdirectory of ceres-solver-1.8.0/.  For 2, it shouldn't (or, couldn't) the Ceres install process take care of pointing CMake to my local gflags and glog installs?

Sameer Agarwal

unread,
Nov 13, 2013, 3:09:09 PM11/13/13
to ceres-...@googlegroups.com
On Wed, Nov 13, 2013 at 11:55 AM, Garrett Warnell <warn...@gmail.com> wrote:
I did a "local" install today (1.8.0) using
  • --prefix during the gflags and glog installs
  • -DGLOG_INCLUDE_DIR_HINTS, -DGLOG_LIBRARY_DIR_HINTS, -DGFLAGS_INCLUDE_DIR_HINTS, -DGFLAGS_LIBRARY_INCLUDE_HINTS, and -DCMAKE_INSTALL_PREFIX during the Ceres Solver install
but I still ran into a couple issues when trying to use CMake to build my project:
  1. Unless I made ceres-bin/ a subdirectory of ceres-solver-1.8.0/, CMake couldn't find Eigen
that is odd.
  1. Unless I used -DGLOG_INCLUDE_DIR and -DGLOG_LIBRARY, CMake couldn't find glog
this looks like a bug.

Alex can comment on both of these issues.

Sameer

 
I'm pretty new to CMake, so my question is: are either of these issues avoidable?  For 1, the build instructions (docs/html/building.html) don't seem to indicate that ceres-bin/ should be a subdirectory of ceres-solver-1.8.0/.  For 2, it shouldn't (or, couldn't) the Ceres install process take care of pointing CMake to my local gflags and glog installs?

--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/ceres-solver/58a34958-4266-4fce-8195-ddead9ecff78%40googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.

Alex Stewart

unread,
Nov 13, 2013, 5:24:17 PM11/13/13
to ceres-...@googlegroups.com
Hi Garrett,

OK - so, to clarify are these problems:

A) When you are trying to build Ceres locally.

B) When you are trying to build a separate project (possibly locally) that _uses_ a compiled version of Ceres that was built locally?

Initially I thought A), but on reflection I think you might mean B) - I have tried to answer both:

== If A):

On Wed, Nov 13, 2013 at 11:55 AM, Garrett Warnell <warn...@gmail.com> wrote:
I did a "local" install today (1.8.0) using
  • --prefix during the gflags and glog installs
  • -DGLOG_INCLUDE_DIR_HINTS, -DGLOG_LIBRARY_DIR_HINTS, -DGFLAGS_INCLUDE_DIR_HINTS, -DGFLAGS_LIBRARY_INCLUDE_HINTS, and -DCMAKE_INSTALL_PREFIX during the Ceres Solver install
but I still ran into a couple issues when trying to use CMake to build my project:
  1. Unless I made ceres-bin/ a subdirectory of ceres-solver-1.8.0/, CMake couldn't find Eigen
that is odd.

This is indeed very odd - there certainly shouldn't be any requirement over where the build directory is for Ceres, conventionally it would be at the same level as the source directory but that is just a convention, nothing in CMake, or the Ceres buildsystem should require it.

Could you please provide a bit more information on the following:

1. What OS is this, running what version of CMake?

2. Where is Eigen actually installed? - particularly where is this relative to the Ceres source and build directories? - note that if Eigen is not installed in a standard location you are going to have to pass EIGEN_INCLUDE_DIR_HINTS or EIGEN_INCLUDE_DIR to tell CMake where to search / find it.

3. Can you send the output of running:

cmake -DGLOG_INCLUDE_DIR_HINTS=<path to dir containing glog dir> -DGLOG_INCLUDE_DIR_HINTS=<path to dir containing glog library> <path_to_ceres_source_dir>

I certainly haven't seen this kind of behaviour before, 
  1. Unless I used -DGLOG_INCLUDE_DIR and -DGLOG_LIBRARY, CMake couldn't find glog
this looks like a bug.

This is very odd, as I can't replicate this even by forcing all search paths from FindGlog and adding extra directions to CMake to search nothing else - even in that case passing the HINTS variables for glog are enough and everything works.

I did notice a mistake of mine in the documentation in FindGlog.cmake though, it listed GLOG_INCLUDE_DIR<S>_HINTS and GLOG_LIBRARY_DIR<S>_HINTS, (emphasis, plural when it should have been singular) [Sameer just merged the fix for this into master], but I note that you list the correct variables in your email, but perhaps this is still the issue and you corrected it when writing your email?

== If B)

Currently If you are building your own project that uses Ceres, and glog and Eigen are installed in non-standard locations, you are going to have to tell CeresConfig (called when you call find_package(Ceres)) where to search for them.  As CeresConfig calls Ceres' own versions of FindEigen & FindGlog to look for them, the variables / options are the same as for when you built Ceres.

However, I have pushed a patch that should remove this requirement - if this is the situation you are in please try this and let me know: https://ceres-solver-review.googlesource.com/4271

-Alex

Garrett Warnell

unread,
Nov 14, 2013, 6:25:28 PM11/14/13
to ceres-...@googlegroups.com
Sorry for not being more clear: it's situation B.  I appear to be successfully building Ceres locally, but am having issues when trying to build my own project that tries to use that local build.

I'm running Ubuntu GNOME 13.04 and CMake version 2.8.10.1.  I installed Eigen via the Ubuntu software center, so it's in what I believe is the "standard" location: /usr/include/eigen3.

In short, I git'd your updated version (I checked to make sure your changes to CeresConfig.cmake.in made it) and am still running into issues.


The long story is as follows.  I'm going to try to be as detailed as possible, since it's very likely that my issues are due to some small error I'm making when using CMake.  ceres-solver, glog, and gflags all live in my local directory /home/warnellg/.local
  1. Before beginning, I wanted to remove 1.8.0 to avoid any potential conflicts.  So I went to my /home/warnellg/.local/ceres-solver-1.8.0/ceres-bin/ directory and ran make clean && make uninstall.  I then deleted the entire /home/warnellg/.local/ceres-1.8.0/ directory.  I hope this was appropriate (I couldn't seem to locate any uninstall directions).
  2. I git'd the latest version of Ceres to /home/warnellg/.local/ceres-solver
  3. I created /home/warnellg/.local/ceres-bin (next to, not within ceres-solver/) and ran CMake there.  I've included the specific command and output at the end of this post.
  4. Still in /home/warnellg/.local/ceres-bin, I successfully ran make, make install (as desired, no sudo necessary since this is a local install!), and make test.
  5. Now, I went to build my project that uses Ceres.  I copied the CMakeLists.txt from the Ceres documentation "Installation" page, modified the project/source names for my specific project, and added PATHS "/home/warnellg/.local" to the FIND_PACKAGE command for Ceres.
  6. I tried to run CMake
And this is where I ran into issues.  Here's the output from the terminal

-- The C compiler identification is GNU 4.7.3
-- The CXX compiler identification is GNU 4.7.3
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
CMake Error at /home/warnellg/.local/ceres-bin/CeresConfig.cmake:70 (MESSAGE):
  Failed to find Ceres - Ceres install root: /home/warnellg, determined from
  relative path from CeresConfg.cmake install location:
  /home/warnellg/.local/ceres-bin, does not contain Ceres headers.  Either
  the install directory was deleted, or the install tree was only partially
  relocated outside of CMake after Ceres was built.
Call Stack (most recent call first):
  /home/warnellg/.local/ceres-bin/CeresConfig.cmake:113 (CERES_REPORT_NOT_FOUND)
  CMakeLists.txt:5 (FIND_PACKAGE)

I think one problem might be that the install root is wrong: shouldn't it be /home/warnellg/.local?  I'm wondering if that has something to do with line 79 of ceres-bin/CeresConfig.cmake.

Anyway, I really appreciate your help so far and I await your further instructions!

Oh, and here's the copy/pasted terminal output from when I ran cmake to build Ceres:

warnellg@warnellg-u410:~/.local/ceres-bin$ cmake -DGLOG_INCLUDE_DIR_HINTS=/home/warnellg/.local/include -DGLOG_LIBRARY_DIR_HINTS=/home/warnellg/.local/lib -DGFLAGS_INCLUDE_DIR_HINTS=/home/warnellg/.local/include -DGFLAGS_LIBRARY_DIR_HINTS=/home/warnellg/.local/lib -DCMAKE_INSTALL_PREFIX=/home/warnellg/.local ../ceres-solver/
-- Found Eigen version 3.1.2: /usr/include/eigen3
-- A library with BLAS API found.
-- Found LAPACK library: /usr/lib/liblapack.so;/usr/lib/libblas.so
-- Found BLAS library: /usr/lib/libblas.so
-- A library with BLAS API found.
-- Found AMD library: /usr/lib/libamd.so
-- Found AMD header in: /usr/include/suitesparse
-- Found CAMD library: /usr/lib/libcamd.so
-- Found CAMD header in: /usr/include/suitesparse
-- Found COLAMD library: /usr/lib/libcolamd.so
-- Found COLAMD header in: /usr/include/suitesparse
-- Found CCOLAMD library: /usr/lib/libccolamd.so
-- Found CCOLAMD header in: /usr/include/suitesparse
-- Found CHOLMOD library: /usr/lib/libcholmod.so
-- Found CHOLMOD header in: /usr/include/suitesparse
-- Found SuiteSparseQR library: /usr/lib/libspqr.a
-- Found SuiteSparseQR header in: /usr/include/suitesparse
-- Did not find Intel TBB library, assuming SuiteSparseQR was not compiled with TBB.
-- Found UFconfig header in: /usr/include/suitesparse
-- Did not find METIS library (optional SuiteSparse dependency)
-- Found system install of SuiteSparse 3.4.0 running on Ubuntu, which has a known bug preventing linking of shared libraries (static linking unaffected).
-- Found SuiteSparse 3.4.0, building with SuiteSparse.
-- Building without CXSparse.
-- Found Google Flags header in: /home/warnellg/.local/include
-- Found Google Log header in: /home/warnellg/.local/include
-- Building with OpenMP.
-- Building Ceres as a static library.
-- Build the examples.
-- Configuring done
-- Generating done
CMake Warning:
  Manually-specified variables were not used by the project:
    GFLAGS_INCLUDE_DIR_HINTS
    GFLAGS_LIBRARY_DIR_HINTS

-- Build files have been written to: /home/warnellg/.local/ceres-bin

Alex Stewart

unread,
Nov 15, 2013, 9:47:16 AM11/15/13
to ceres-...@googlegroups.com
Garrett,

Thanks for the information, your problem is I think actually quite easy to fix:

CMake Error at /home/warnellg/.local/ceres-bin/CeresConfig.cmake:70 (MESSAGE):
  Failed to find Ceres - Ceres install root: /home/warnellg, determined from
  relative path from CeresConfg.cmake install location:
  /home/warnellg/.local/ceres-bin, does not contain Ceres headers.  Either
  the install directory was deleted, or the install tree was only partially
  relocated outside of CMake after Ceres was built.

Specifically:

/home/warnellg/.local/ceres-bin/CeresConfig.cmake

Means that your project is actually picking up the *build* directory (/home/warnellg/.local/ceres-bin) as the install directory, and thus it's using the version of CeresConfig.cmake that is in the build directory, not the installed version.

The significance is that the installation process puts the include, lib & configuration directories in specific relative positions.  Specifically CeresConfig.cmake is expecting to be installed in <PREFIX>/share/Ceres (on *nix) thus ../../include & ../../lib should be where the headers and libraries are installed.  Obviously, this is not the case when CeresConfig.cmake is in the build directory, which is what your problem is.

Why is this happening?  Basically because you called your build directory 'ceres-bin', are very unlucky, and Windows conventions are weird.

When you call find_package() (in CONFIG mode) it iterates over the given search paths (which includes the one you specified in PATHS) looking for <XXX>Config.cmake, for each path if it can't find it in the path itself, it adds various suffixes to the path and tries again.  To support Windows, one of these suffixes is <XXX>* - where XXX is treated as a case-*insensitive* version of the name of the package being searched for - thus your build directory, ceres-bin, matches.

Unfortunately for you, the suffix you wanted to use: <path>/share/<XXX> is tried later - and you've already matched ceres-bin, so is never checked.


You can fix this by either:

1) Changing the name of your build directory to something plain like 'build'

2) Passing the variable Ceres_DIR=<PATH_TO_CERES_CONFIG.CMAKE - e.g. /home/warnellg/.local/share/Ceres>

-Alex


Garrett Warnell

unread,
Nov 15, 2013, 1:53:22 PM11/15/13
to ceres-...@googlegroups.com
Thanks so much!  I got things working using the following modification to CMakeLists.txt for my project:

FIND_PACKAGE(Ceres REQUIRED PATH "/home/warnellg/.local/share/Ceres")

And both Eigen (standard location) and glog (local location) were detected.  And I even learned something new about CMake.  So great job all around!


There is one other quirk I wanted to ask about that's probably not related to the issue you just resolved for me.  Below is the contents of the CMakeLists.txt I'm using for my project:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8) 

PROJECT(autocal_bundleadjustment) 

FIND_PACKAGE(Ceres REQUIRED PATHS "/home/warnellg/.local/share/Ceres")
INCLUDE_DIRECTORIES(${CERES_INCLUDE_DIRS}) 

#autocal_bundleadjustment
ADD_EXECUTABLE(autocal_bundleadjustment autocal_bundleadjustment.cpp)
TARGET_LINK_LIBRARIES(autocal_bundleadjustment ${CERES_LIBRARIES})

Running cmake works great, but when I run make, I get the following error:

warnellg@warnellg-u410:~/scratch/calibration/ceres/build$ make
Scanning dependencies of target autocal_bundleadjustment
[100%] Building CXX object CMakeFiles/autocal_bundleadjustment.dir/autocal_bundleadjustment.cpp.o
Linking CXX executable autocal_bundleadjustment
/usr/bin/ld: /home/warnellg/.local/lib/libceres.a(evaluator.cc.o): undefined reference to symbol 'pthread_rwlock_wrlock@@GLIBC_2.2.5'
/usr/bin/ld: note: 'pthread_rwlock_wrlock@@GLIBC_2.2.5' is defined in DSO /lib/x86_64-linux-gnu/libpthread.so.0 so try adding it to the linker command line
/lib/x86_64-linux-gnu/libpthread.so.0: could not read symbols: Invalid operation
collect2: error: ld returned 1 exit status
make[2]: *** [autocal_bundleadjustment] Error 1
make[1]: *** [CMakeFiles/autocal_bundleadjustment.dir/all] Error 2
make: *** [all] Error 2

After some searching and trial and error, I discovered that I could fix the issue by adding the following line my CMakeLists.txt

FIND_PACKAGE(Threads)

and modifying the TARGET_LINK_LIBRARIES line to say

TARGET_LINK_LIBRARIES(autocal_bundleadjustment ${CERES_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})

Is this indicative of yet another error issue my build?  The "example" CMakeLists.txt in the documentation doesn't mention the Threads package.

Garrett Warnell

unread,
Nov 20, 2013, 1:23:51 PM11/20/13
to ceres-...@googlegroups.com
Bumping for the second "issue" I brought up in my last post.

It's not critical, but I'm wondering if it didn't get noticed because I didn't mention it until halfway through.

Alex Stewart

unread,
Nov 20, 2013, 3:01:35 PM11/20/13
to ceres-...@googlegroups.com
Garrett,


It looks like there was a bug.  Previously, when using OpenMP on *nix (which requires an explicit link to threads) we were adding ${CMAKE_THREAD_LIBS_INIT} to the linker flags for the (Ceres) project, which works locally, but means that they are not exported by CMake.

-Alex

--
You received this message because you are subscribed to the Google Groups "Ceres Solver" group.
To unsubscribe from this group and stop receiving emails from it, send an email to ceres-solver...@googlegroups.com.

Garrett Warnell

unread,
Nov 20, 2013, 4:13:33 PM11/20/13
to ceres-...@googlegroups.com
It worked!  I removed the previously-mentioned modifications to my CMakeLists.txt and the project built and ran successfully.

Thanks so much for all your help!
Reply all
Reply to author
Forward
0 new messages