ceres的错误(ps:cmake的学习):/usr/bin/ld:xxx undefined reference to `ceres::Problem::~Problem()“

令人头疼且费时的工程问题,错误的开始,不管我的函数是添加在哪个文件都有这个错误

我心想这肯定是cmakelist.txt没写好或者是ceres的版本问题。

在尝试过粘贴该错误搜索全网解决方法,然后尝试了还是有这个问题的可以试一试这个( =V=):

原本我的cmakelist的一部分:

add_executable(xxx src/xxx.cpp)#用来描述把哪个程序文件编译成可执行文件
target_link_libraries(xxx 
${CERES_LIBRARIES} 
${catkin_LIBRARIES} 
${OpenCV_LIBS} 
xxx
xxx
)

诶就是有错误,除非把ceres的函数写在src/xxx.cpp下,当然这是不可能的。

然后我觉得就是cmakelist有问题,于是我加上去,于是好了!!你说奇妙不奇妙!!

target_link_libraries(${PROJECT_NAME}
${CERES_LIBRARIES} 
${EIGEN3_LIBS}
${catkin_LIBRARIES} 
${xxx} 
${xxx} 
${xxx}
${xxx}
)#


add_executable(xxx src/xxx.cpp)#用来描述把哪个程序文件编译成可执行文件
target_link_libraries(xxx 
${PROJECT_NAME}
)

理论分析(当个复习):(参考官方网站,官方页面也有搜索栏,一搜就知道)CMake Reference Documentation — CMake 3.23.1 Documentationicon-default.png?t=M3K6https://cmake.org/cmake/help/latest/index.htmlCMake Tutorial — CMake 3.23.1 Documentationicon-default.png?t=M3K6https://cmake.org/cmake/help/latest/guide/tutorial/index.html看官网给出的steps:

 

得到简简单单的cmakelist.txt的步骤:

#---step1:添加cmake版本号、工程名字、c++ standard
cmake_minimum_required(VERSION 3.10)
# set the project name and version
project(Tutorial)
# specify the C++ standard c++11
# set(CMAKE_BUILD_TYPE Debug)#用于断点调试 默认是Release
# set(CMAKE_CXX_FLAGS "-std=c++14 -O3") 用c++14的时候也可以这样
set(CMAKE_CXX_STANDARD 11)

#---step2:构建链接库,比如说自己创建的一些h文件与c文件,是静态还是动态的
#a.cc为${PROJECT_NAME}/xxx/目录下,也可以将${PROJECT_NAME}写成自己的具体子目录
#加语法:add_subdirectory(xxx)
#如果加了条件:if(USE_COND)xxxendif(),那么在编译的时候就需要-DUSE_COND=OFF/ON
add_library(${PROJECT_NAME} SHARED(or PUBLIC)
            xxx/a.cc
            xxx/b.cc  )


#---step3: 添加构建链接库全部所需要的一些三方库链接
# --case1 :有时候会和 link_directories(${CMAKE_CURRENT_LIST_DIR}/lib)一起用
#          可以在lib目录下查找依赖库(例如在lib目录下的libxxx.a(libxxx.so libxxx.dylib))
#          ${CMAKE_CURRENT_LIST_DIR} 当前CMakeList.txt所在目录
link_directories(${CMAKE_CURRENT_LIST_DIR}/lib)
# --case2: 有时候会搭配find_package() 和 include_directories() 使用,例如:
find_package(somepackage REQUIRED) 
include_directories(${somepackage_INCLUDE_DIRS})

target_link_libraries(${PROJECT_NAME} PUBLIC 
                      ${somepackage_LIBS}
                        xxx )



#--step4:  添加执行文件 Tutorial执行文件的名字,通常在build下可以找到
add_executable(Tutorial ${执行文件下的目录}/tutorial.cxx)
#为可执行文件添加的一些依赖
target_link_libraries(Tutorial PUBLIC ${xxx_LIBS} ${PROJECT_NAME})

#最后的附加:加入过程中有啥不知道的可以添加输出来看看
message("xxx" ${xxx}) 

我自己出现的问题原因:在step 4的前面,我没有target_link_libraries,而是在add_executable后只对执行文件进行了target_link_libraries,所以出现的问题就是:只有在执行文件对应的cpp文件下可以用ceres类,其他的文件下一放就错。

to be continue...