0

I am relatively new to cmake. I'm on Ubuntu 20.04, and I'm encountering an issue where I'm trying to build the project dpgo from this repository: https://github.com/mit-acl/dpgo.

From the repository, it says to install the dependency binaries with the command:

sudo apt-get install build-essential cmake-gui libsuitesparse-dev libboost-all-dev libeigen3-dev libgoogle-glog-dev
  • This installs the dependencies, including eigen3, glog, and suitesparse, where I'm having issues getting cmake to find the appropriate versions of these libraries.
  • I have another project installed from here. https://github.com/VIS4ROB-lab/covins/. This project also relies on eigen3, glog, and suitesparse, and has their headers and other necessary files installed in /home/glenn/ws/covins_ws/devel/include on my computer. For example, headers for the suitesparse library in this package are in /home/glenn/ws/covins_ws/devel/include/suitesparse

Due to the above covins_ws package and the dependencies installed there, lines 38-43 using the find_package() commands in the top-level CMakeLists.txt of dpgo end up finding the wrong ones (the ones installed in /home/glenn/ws/covins_ws instead of the default paths where the libraries and headers are installed in (/usr/lib and /usr/local).

SOLVED: I think I resolved issues with glog and eigen

  • I solved the issue with eigen3 by following Eigen3's CMake guide here:

    1. Setting the following line in CMakeLists.txt before the find_package(Eigen3 REQUIRED) command: set(CMAKE_PREFIX_PATH "/usr/include/eigen3" ${CMAKE_PREFIX_PATH})
    2. In the cmake command, I made sure the Eigen3_DIR explicitly points to where the Eigen3 cmake files are installed in the system: cmake -DEigen3_DIR=/usr/lib/cmake/eigen3 ../
  • I did the same with glog by setting the following line in CMakeLists.txt before the find_package(Glog REQUIRED) command: set(CMAKE_PREFIX_PATH "/usr/include/glog" $ {CMAKE_PREFIX_PATH})

PERSISTING ISSUE: suitesparse

  • The libraries SQPR and CHOLMOD are found in the suitesparse library. Before any attempts at fixing, running the cmake ../ command in the build folder gave the output:

      -- Found SPQR: /home/glenn/ws/covins_ws/devel/include/suitesparse 
      -- Found CHOLMOD: /home/glenn/ws/covins_ws/devel/include/suitesparse 
    
  • After setting the command set(CMAKE_PREFIX_PATH "/usr/include/suitesparse" ${CMAKE_PREFIX_PATH}) before the find_package() commands for SQPR and CHOLMOD, I get the output:

      -- Found SPQR: /usr/include/suitesparse  
      -- Found CHOLMOD: /usr/include/suitesparse
    
  • This is the same thing that happened with Eigen3 and glog as I mentioned before, and seemed to fix the issue. However, when I run make, I end up with the following error:

    [ 93%] Linking CXX executable bin/testDPGO
    /usr/bin/ld: lib/libDPGO.so: undefined reference to `SuiteSparse_time'
    collect2: error: ld returned 1 exit status
    make[2]: *** [CMakeFiles/testDPGO.dir/build.make:210: bin/testDPGO] Error 1
    make[1]: *** [CMakeFiles/Makefile2:171: CMakeFiles/testDPGO.dir/all] Error 2
    make: *** [Makefile:130: all] Error 2
    
  • The output of ldd lib/libDPGO.so is:

      ||linux-vdso.so.1 (0x00007fff6c768000)|
      |---|---|
      ||libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007ff4098e1000)|
      ||libroptlib.so => /home/glenn/Multi-Robot Libraries/dpgo/build/lib/libroptlib.so (0x00007ff409806000)|
      ||libglog.so.1 => /usr/local/lib/libglog.so.1 (0x00007ff4097b7000)|
      ||liblapack.so.3 => /lib/x86_64-linux-gnu/liblapack.so.3 (0x00007ff4090ef000)|
      ||libblas.so.3 => /lib/x86_64-linux-gnu/libblas.so.3 (0x00007ff408d29000)|
      ||libstdc++.so.6 => /lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007ff408b47000)|
      ||libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007ff4089f8000)|
      ||libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007ff4089dd000)|
      ||libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ff4087e9000)|
      ||/lib64/ld-linux-x86-64.so.2 (0x00007ff409aae000)|
      ||libgflags.so.2.2 => /home/glenn/ws/covins_ws/devel/lib/libgflags.so.2.2 (0x00007ff4087bc000)|
      ||libgfortran.so.5 => /lib/x86_64-linux-gnu/libgfortran.so.5 (0x00007ff4084f4000)|
      ||libquadmath.so.0 => /lib/x86_64-linux-gnu/libquadmath.so.0 (0x00007ff4084aa000)|
    

ADDITIONAL INFO: I'm stuck at this stage, and trying to diagnose what's wrong with the build. I feel like the issues are in the following areas, but would appreciate any pointers.

  1. When the find_package() commands are run, as I know, they run by default in module mode, which means they use the FindPACKAGE.cmake modules. In this dpgo package, they are in the cmake folder . When I look at the file FindCholmod Lines 8-19, they use the find_path and find_library command.

    • In the find_path() command, it wll look for a file "choldmod.h" in the specified directories with the suffixes "suitesparse" and "ufsparse". I think it did look for the appropriate file /usr/include/suitesparse/choldmod.h but just incase, I added /usr/include as one of the PATHS arguments. I'm unsure if any corrections needed to be done for this command.
  2. When I look at CMakeCache.txt, there are also cache variable values that look wrong, indicating cmake still didn't find the correct libraries and headers, despite the output in the terminal looking correct:

    • CHOLMOD_LIBRARY is /home/glenn/ws/covins_ws/devel/lib/libcholmod.a instead of /usr/lib/x86_64-linux-gnu/libcholmod.a. I'm assuming this is the cause of the linking issue. I manually set it to the appropriate path in the CMakeCache.txt file although I don't know if it's recomended to edit build artifacts directly made by cmake. This also did not fix the issue when running make. In the same FindCholMod.cmake, I edited the find_library command to explicitly include this path, but it did not work: find_library(CHOLMOD_LIBRARIES cholmod PATHS $ENV{CHOLMODDIR} ${LIB_INSTALL_DIR} /usr/lib/x86_64-linux-gnu)
    • Eigen3_DIR is Eigen3_DIR-NOTFOUND, even though I set it as I mentioned above when fixing the eigen3 issue. I don't know if this had any effect on the make error or will have any issues in runtime.
    • gflags_DIR is /home/glenn/ws/covins_ws/devel/lib/cmake/gflags. I'm assuming one of the dependencies needed this gflag library, and once again, it's looking at the covins_ws directory instead of the default path /usr/include/gflags
    • For the above, I tried setting each cache variable with the -D flag when running cmake with the command cmake -DCHOLMOD_LIBRARY=/usr/lib/x86_64-linux-gnu/libcholmod.a -DEigen3_DIR=/usr/lib/cmake/eigen3 -Dgflags_DIR=/usr/include/gflags ../ but it still didn't fix Eigen3_Dir or gflags_DIR. On top of that, running make now gives a new error:
      [ 85%] Linking CXX shared library lib/libDPGO.so
      /usr/bin/ld: /usr/lib/x86_64-linux-gnu/libcholmod.a(cholmod_l_csymamd.o): relocation   R_X86_64_PC32 against undefined symbol `SuiteSparse_config' can not be used when making a shared object; recompile with -fPIC
      /usr/bin/ld: final link failed: bad value
      collect2: error: ld returned 1 exit status
      make[2]: *** [CMakeFiles/DPGO.dir/build.make:262: lib/libDPGO.so] Error 1
      make[1]: *** [CMakeFiles/Makefile2:310: CMakeFiles/DPGO.dir/all] Error 2
      make: *** [Makefile:130: all] Error 2
      
    • So I decided not to include the flags to change the cache variables.
  • For reference, here is the complete output after the cmake ../ command in an empty build folder, where I think everything looks fine, but still end up with make errors:
-- The C compiler identification is GNU 9.4.0
-- The CXX compiler identification is GNU 9.4.0
-- 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
-- Detecting C compile features
-- Detecting C compile features - 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
-- Detecting CXX compile features
-- Detecting CXX compile features - done
-- No build type selected, default to Release
-- CXX compiler version: 9.4.0
-- CMAKE_MODULE_PATH: /home/glenn/Multi-Robot Libraries/dpgo/cmake
-- Configuring done
-- Generating done
-- Build files have been written to: /home/glenn/Multi-Robot Libraries/dpgo/build/roptlib-download
Scanning dependencies of target roptlib
[ 11%] Creating directories for 'roptlib'
[ 22%] Performing download step (git clone) for 'roptlib'
Cloning into 'roptlib-src'...
Branch 'feature/cmake' set up to track remote branch 'feature/cmake' from 'origin'.
Switched to a new branch 'feature/cmake'
[ 33%] No patch step for 'roptlib'
[ 44%] Performing update step for 'roptlib'
Current branch feature/cmake is up to date.
[ 55%] No configure step for 'roptlib'
[ 66%] No build step for 'roptlib'
[ 77%] No install step for 'roptlib'
[ 88%] No test step for 'roptlib'
[100%] Completed 'roptlib'
[100%] Built target roptlib
-- Found SPQR: /usr/include/suitesparse  
-- Found CHOLMOD: /usr/include/suitesparse  
-- A cache variable, namely BLAS_DIR, has been set to specify the install directory of BLAS
-- Looking for BLAS -- mkl.h not found
-- Looking for pthread.h
-- Looking for pthread.h - found
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD
-- Performing Test CMAKE_HAVE_LIBC_PTHREAD - Failed
-- Looking for pthread_create in pthreads
-- Looking for pthread_create in pthreads - not found
-- Looking for pthread_create in pthread
-- Looking for pthread_create in pthread - found
-- Found Threads: TRUE  
-- Looking for MKL BLAS: not found
-- Looking for Goto BLAS: not found
-- Looking for Open BLAS: not found
-- Looking for Eigen BLAS: not found
-- Looking for Eigen BLAS: not found
-- Looking for dgemm_
-- Looking for dgemm_ - found
-- Looking for Atlas BLAS: found
-- A library with BLAS API found.
-- BLAS_LIBRARIES /usr/lib/x86_64-linux-gnu/libf77blas.so;/usr/lib/x86_64-linux-gnu/libatlas.so
-- Found Boost: /usr/lib/x86_64-linux-gnu/cmake/Boost-1.71.0/BoostConfig.cmake (found version "1.71.0")  
-- Found Eigen3: /usr/include/eigen3 (Required is at least version "2.91.0") 
-- Found Eigen version: 3.3.7
-- EIGEN3_INCLUDE_DIR: /usr/include/eigen3
-- No preference for use of exported glog CMake configuration set, and no hints for include/library directories provided. Defaulting to preferring an installed/exported glog CMake configuration if available.
-- Found installed version of glog: /usr/local/lib/cmake/glog
-- Detected glog version: 0.7.0
-- Found Glog: glog::glog  
-- Found Google Logging: 
-- Boost version: 1.71.0
-- Configuring done
-- Generating done
-- Build files have been written to: /home/glenn/Multi-Robot Libraries/dpgo/build/googletest-download
Scanning dependencies of target googletest
[ 11%] Creating directories for 'googletest'
[ 22%] Performing download step (git clone) for 'googletest'
Cloning into 'googletest-src'...
Note: switching to 'v1.10.x'.

You are in 'detached HEAD' state. You can look around, make experimental
changes and commit them, and you can discard any commits you make in this
state without impacting any branches by switching back to a branch.

If you want to create a new branch to retain commits you create, you may
do so (now or later) by using -c with the switch command. Example:

  git switch -c <new-branch-name>

Or undo this operation with:

  git switch -

Turn off this advice by setting config variable advice.detachedHead to false

HEAD is now at 703bd9ca Googletest export
[ 33%] No patch step for 'googletest'
[ 44%] Performing update step for 'googletest'
First, rewinding head to replay your work on top of it...
Fast-forwarded HEAD to origin/v1.10.x.
[ 55%] No configure step for 'googletest'
[ 66%] No build step for 'googletest'
[ 77%] No install step for 'googletest'
[ 88%] No test step for 'googletest'
[100%] Completed 'googletest'
[100%] Built target googletest
-- Found PythonInterp: /usr/bin/python (found version "3.8.10") 
-- Configuring done
-- Generating done
-- Build files have been written to: /home/glenn/Multi-Robot Libraries/dpgo/build

I know I probably could delete this covins_ws folder, but I want to be able to build all these projects and get each of them properly linking to the appropriate libraries and headers. Any pointers to help with my issue will be greatly appreciated. Thank you

User_0603
  • 1
  • 1
  • The variable `CMAKE_PREFIX_PATH` denotes the installation **prefix** of the packages, not the *include directory*. Setting this variable to the include directory sometimes helps in hinting CMake about the location of include directory, but never helps in hinting path to the **library** (because the library is not located under include directory). Setting `CMAKE_PREFIX_PATH` to `/usr` will help in finding most packages, which include directory is `/usr/include` (or lower) and which libraries are located under `/usr/lib`. – Tsyvarev Aug 23 '23 at 08:21
  • Note, that Stack Overflow is NOT a *debugging service*. We expect a question post to contain information sufficient to provide an **answer** (with *solution*). But in your case we could only comment "try to do X", wait your response and prepare further suggestions for conversation. I agree that sometimes debugging is hard, but neither Stack Overflow purpose nor site features are compatible with debugging questions. – Tsyvarev Aug 23 '23 at 08:32
  • Thank you. I set CMAKE_PREFIX_PATH to /usr so it can search for headers under /usr/include and libraries under /usr/lib and it built propery. I noticed from the documenation for CMAKE_PREFIX_PATH https://cmake.org/cmake/help/latest/variable/CMAKE_PREFIX_PATH.html which mentions commands like find_package() appends to it. Sorry if the question involved too much debugging, as I wanted to know how to properly use installed packages and pinpoint related issues so I don't encounter similar issues in the future. – User_0603 Aug 23 '23 at 21:42

0 Answers0