提问人:User_0603 提问时间:8/23/2023 更新时间:8/23/2023 访问量:109
CMake:使用 find_package() 和 find_path() 为 suitesparse 库查找正确的头文件时出现问题
CMake: Issue with finding the right header files for suitesparse library with find_package() and find_path()
问:
我对 cmake 比较陌生。我在 Ubuntu 20.04 上,我遇到了一个问题,我试图从这个存储库构建项目 dpgo:https://github.com/mit-acl/dpgo。
在存储库中,它说使用以下命令安装依赖项二进制文件:
sudo apt-get install build-essential cmake-gui libsuitesparse-dev libboost-all-dev libeigen3-dev libgoogle-glog-dev
- 这将安装依赖项,包括 eigen3、glog 和 suitesparse,我在让 cmake 找到这些库的适当版本时遇到了问题。
- 我从这里安装了另一个项目。https://github.com/VIS4ROB-lab/covins/。这个项目还依赖于 eigen3、glog 和 suitesparse,并且它们的头文件和其他必要的文件安装在我计算机上的 /home/glenn/ws/covins_ws/devel/include 中。 例如,此包中 suitesparse 库的头文件位于 /home/glenn/ws/covins_ws/devel/include/suitesparse 中
由于上面的covins_ws包和安装在那里的依赖项,第 38-43 行使用 dpgo 顶级 CMakeLists.txt 中的 find_package() 命令最终会找到错误的路径(安装在 /home/glenn/ws/covins_ws 中的路径,而不是安装库和头文件的默认路径(/usr/lib 和 /usr/local)。
解决:我想我解决了 glog 和 eigen 的问题
我按照 Eigen3 的 CMake 指南解决了 eigen3 的问题:
- 在 CMakeLists 中.txt在 find_package(Eigen3 REQUIRED) 命令之前设置以下行:
set(CMAKE_PREFIX_PATH "/usr/include/eigen3" ${CMAKE_PREFIX_PATH})
- 在 cmake 命令中,我确保Eigen3_DIR明确指向 Eigen3 cmake 文件在系统中的安装位置:
cmake -DEigen3_DIR=/usr/lib/cmake/eigen3 ../
- 在 CMakeLists 中.txt在 find_package(Eigen3 REQUIRED) 命令之前设置以下行:
我通过在 CMakeLists 中设置以下行来对 glog 做同样的事情.txt在 find_package(Glog REQUIRED) 命令之前:
set(CMAKE_PREFIX_PATH "/usr/include/glog" $ {CMAKE_PREFIX_PATH})
持续存在的问题:suitesparse
库 SQPR 和 CHOLMOD 位于 suitesparse 库中。在尝试修复之前,在构建文件夹中运行命令会给出输出:
cmake ../
-- Found SPQR: /home/glenn/ws/covins_ws/devel/include/suitesparse -- Found CHOLMOD: /home/glenn/ws/covins_ws/devel/include/suitesparse
在 SQPR 和 CHOLMOD 的 find_package() 命令之前设置命令后,我得到输出:
set(CMAKE_PREFIX_PATH "/usr/include/suitesparse" ${CMAKE_PREFIX_PATH})
-- Found SPQR: /usr/include/suitesparse -- Found CHOLMOD: /usr/include/suitesparse
正如我之前提到的,这与 Eigen3 和 glog 发生的情况相同,并且似乎解决了这个问题。但是,当我运行make时,我最终出现以下错误:
[ 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
的输出为:
ldd lib/libDPGO.so
||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)|
附加信息:我被困在这个阶段,并试图诊断构建的问题。我觉得问题出在以下几个方面,但希望能提供任何指示。
据我所知,当运行 find_package() 命令时,它们默认以模块模式运行,这意味着它们使用 FindPACKAGE.cmake 模块。在这个 dpgo 包中,它们位于 cmake 文件夹中。当我查看文件 FindCholmod Lines 8-19 时,它们使用 find_path 和 find_library 命令。
- 在 find_path() 命令中,它将在指定目录中查找后缀为“suitesparse”和“ufsparse”的文件“choldmod.h”。我认为它确实寻找了适当的文件 /usr/include/suitesparse/choldmod.h,但以防万一,我将 /usr/include 添加为 PATHS 参数之一。我不确定是否需要对此命令进行任何更正。
当我查看 CMakeCache.txt 时,还有一些缓存变量值看起来错误,表明 cmake 仍然没有找到正确的库和标头,尽管终端中的输出看起来正确:
- CHOLMOD_LIBRARY是 /home/glenn/ws/covins_ws/devel/lib/libcholmod.a,而不是 /usr/lib/x86_64-linux-gnu/libcholmod.a。我假设这是链接问题的原因。我手动将其设置为CMakeCache.txt文件中的适当路径,尽管我不知道是否建议编辑由cmake直接制作的构建工件。这也没有解决运行 make 时的问题。在同一个 FindCholMod.cmake 中,我编辑了 find_library 命令以明确包含此路径,但它不起作用:
find_library(CHOLMOD_LIBRARIES cholmod PATHS $ENV{CHOLMODDIR} ${LIB_INSTALL_DIR} /usr/lib/x86_64-linux-gnu)
- Eigen3_DIR 是 Eigen3_DIR-NOTFOUND,即使我在修复 eigen3 问题时如上所述设置了它。我不知道这是否对make错误有任何影响,或者在运行时会出现任何问题。
- gflags_DIR是 /home/glenn/ws/covins_ws/devel/lib/cmake/gflags。我假设其中一个依赖项需要这个 gflag 库,并且再次,它查看的是 covins_ws 目录而不是默认路径 /usr/include/gflags
- 对于上述情况,我尝试在使用命令运行 cmake 时使用 -D 标志设置每个缓存变量,但它仍然没有修复Eigen3_Dir或gflags_DIR。最重要的是,现在运行 make 会给出一个新错误:
cmake -DCHOLMOD_LIBRARY=/usr/lib/x86_64-linux-gnu/libcholmod.a -DEigen3_DIR=/usr/lib/cmake/eigen3 -Dgflags_DIR=/usr/include/gflags ../
[ 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
- 因此,我决定不包含更改缓存变量的标志。
- CHOLMOD_LIBRARY是 /home/glenn/ws/covins_ws/devel/lib/libcholmod.a,而不是 /usr/lib/x86_64-linux-gnu/libcholmod.a。我假设这是链接问题的原因。我手动将其设置为CMakeCache.txt文件中的适当路径,尽管我不知道是否建议编辑由cmake直接制作的构建工件。这也没有解决运行 make 时的问题。在同一个 FindCholMod.cmake 中,我编辑了 find_library 命令以明确包含此路径,但它不起作用:
- 作为参考,这里是 cmake 之后的完整输出。/ 命令,我认为一切看起来都很好,但仍然会出现错误:
-- 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
我知道我可能会删除这个covins_ws文件夹,但我希望能够构建所有这些项目,并让每个项目正确链接到相应的库和头文件。任何有助于解决我问题的指针将不胜感激。谢谢
答: 暂无答案
评论
CMAKE_PREFIX_PATH
CMAKE_PREFIX_PATH
/usr
/usr/include
/usr/lib