项目场景:
在Ubuntu18上编译semantic icp
问题描述
已经正确安装eigen3.3.4和sophus库,在cmake过程出现以下问题:提示找不到eigen3
Found package configuration file:
/usr/local/share/sophus/cmake/SophusConfig.cmake
but it set Sophus_FOUND to FALSE so package "Sophus" is considered to be
NOT FOUND. Reason given by package:
Sophus could not be found because dependency Eigen3 could not be found.
解决方案:
首先确定eigen3和sophus正确安装,且单独编译eigen3是可以编译通过的。第一种解决方法:在CMakeLists.txt中将eigen3和sophus相关的路径直接添加到文件中。并且将findEigen3文件复制到CMakeLists.txt所在的目录下。
set(EIGEN3_INCLUDE_DIR "/usr/include/eigen3")
# include_directories(${EIGEN3_INCLUDE_DIR})
find_package(Eigen3 REQUIRED)
include_directories((EIGEN3_INCLUDE_DIR))
set(Sophus_DIR "/usr/local/include/sophus")
find_package(Sophus REQUIRED)
include_directories((Sophus_DIR))
依然提示原有错误。
又查看了CMakeError.log,错误如下:
Determining if the pthread_create exist failed with the following output:
Change Dir: /home/qxn/code/semantic-icp/build/CMakeFiles/CMakeTmp
Run Build Command:"/usr/bin/make" "cmTC_a658e/fast"
/usr/bin/make -f CMakeFiles/cmTC_a658e.dir/build.make CMakeFiles/cmTC_a658e.dir/build
make[1]: 进入目录“/home/qxn/code/semantic-icp/build/CMakeFiles/CMakeTmp”
Building C object CMakeFiles/cmTC_a658e.dir/CheckSymbolExists.c.o
/usr/bin/cc -o CMakeFiles/cmTC_a658e.dir/CheckSymbolExists.c.o -c /home/qxn/code/semantic-icp/build/CMakeFiles/CMakeTmp/CheckSymbolExists.c
Linking C executable cmTC_a658e
/usr/bin/cmake -E cmake_link_script CMakeFiles/cmTC_a658e.dir/link.txt --verbose=1
/usr/bin/cc -rdynamic CMakeFiles/cmTC_a658e.dir/CheckSymbolExists.c.o -o cmTC_a658e
CMakeFiles/cmTC_a658e.dir/CheckSymbolExists.c.o:在函数‘main’中:
CheckSymbolExists.c:(.text+0x1b):对‘pthread_create’未定义的引用
collect2: error: ld returned 1 exit status
CMakeFiles/cmTC_a658e.dir/build.make:97: recipe for target 'cmTC_a658e' failed
make[1]: *** [cmTC_a658e] Error 1
make[1]: 离开目录“/home/qxn/code/semantic-icp/build/CMakeFiles/CMakeTmp”
Makefile:126: recipe for target 'cmTC_a658e/fast' failed
make: *** [cmTC_a658e/fast] Error 2
出现此错误的原因是
错误信息 “undefined reference to ‘pthread_create’” 是一个链接器错误。这意味着编译器找到了 ‘pthread_create’ 函数的声明,但在链接阶段没有找到它的定义。
这是因为 pthread 不是 Linux 中的默认库,所以在链接时,它无法在 pthread 库中找到函数的入口地址。
要解决这个问题,你需要链接 pthread 库。你可以通过在 gcc 命令中添加
-lpthread
来实现这一点。如果你正在使用 CMake,你可以在你的 CMakeLists.txt 文件中添加set(THREADS_PREFER_PTHREAD_FLAG ON)
和find_package(Threads REQUIRED)
,然后用${CMAKE_THREAD_LIBS_INIT}
链接你的目标。
cmake通过。
注意此时需要保证ceres版本与eigen版本对应,由于我一开始安装的eigen版本的3.3.0,此时如果不重新安装ceres,编译会报错:
CMake Error at CMakeLists.txt:26 (find_package):
Found package configuration file:/usr/local/lib/cmake/Ceres/CeresConfig.cmake
but it set Ceres_FOUND to FALSE so package "Ceres" is considered to be NOT
FOUND.
解决方法是:1. 重新安装ceres 2.更改/usr/local/lib/cmake/Ceres/CeresConfig.cmake文件,添加
set (CERES_EIGEN_VERSION 3.3.4),然后在ceres文件夹build目录下重新
cmake
make
sudo make install
编译通过。
此时继续编译又遇到了以下问题:
在函数‘fmt::v8::appender fmt::v8::detail::write<char, fmt::v8::appender>(fmt::v8::appender, fmt::v8::basic_string_view<fmt::v8::type_identity<char>::type>, fmt::v8::basic_format_specs<char> const&, fmt::v8::detail::locale_ref) [clone .isra.1371]’中: test_gradient.cc:(.text+0x1f2):对‘fmt::v8::detail::assert_fail(char const*, int, char const*)’未定义的引用 test_gradient.cc:(.text+0x201):对‘fmt::v8::detail::error_handler::on_error(char const*)’未定义的引用 ‘’
原因:
为了方便,我直接重新安装了fmt,但是依然报错。解决方法:
这可能是由于fmt库的某些部分与您的项目或其他库存在冲突。这里有一些可能的解决方案:
在源代码中定义FMT_HEADER_ONLY:这是一种常见的解决方法,特别是当您只是使用C++来编写算法时
https://bing.com/search?q=fmt%E5%BA%93%E6%9B%B4%E6%96%B0%E5%90%8E%E4%BB%8D%E7%84%B6%E5%87%BA%E7%8E%B0%E9%94%99%E8%AF%AF%E8%A7%A3%E5%86%B3%E6%96%B9%E6%B3%95可以在包含fmt/format.h的地方之前添加以下代码:
#define FMT_HEADER_ONLY #include <fmt/format.h>
添加-fPIC编译选项:如果您在链接时遇到关于relocation R_X86_64_32S的错误,您可以尝试在CMakeLists.txt文件中添加-fPIC编译选项
https://blog.csdn.net/weixin_33566282/article/details/124166346这个选项用于将静态库链接成.so动态库。您可以通过以下方式添加此选项:
add_compile_options(-fPIC)
我选了第一种,在编译时哪个文件提示错误就在哪个文件中添加代码 。
编译通过。
在../build/exec下运行./test_gradient可以正常执行。