大家好,我已经把CSDN上的博客迁移到了知乎上,欢迎大家在知乎关注我的专栏慢慢悠悠小马车(https://zhuanlan.zhihu.com/c_1132958996826546176)。以后,我会把日常的思考放在CSDN上,梳理过的精华文章放在知乎上,希望大家可以多多交流,互相学习。
目录
CMake链接库的基本套路
OpenCV
Boost
ROS catkin
Eigen
glog
gtest
CMake 输出信息
在使用CMake组织工程时,如果我们需要依赖某个库文件,需要完成以下步骤:
因此,库文件、头文件的名字(大小写)我们就要清楚的写明,不要混淆。我常用的库如OpenCV, catkin, Boost, Eigen, glog, gtest等,其用法如下。常见的名字有:name_INCLUDE_DIRS, name_INCLUDE_DIR, NAME_INCLUDE_DIRS, NAME_INCLUDE_DIR; name_LIBS, NAME_LIBS, name_LIBRARIES, NAME_LIBRARIES等。
#查找OpenCV是否安装
find_package(OpenCV REQUIRED core highgui imgproc imgcodecs)
if (OPENCV_FOUND)
message(STATUS "找到OpenCV:\"${OpenCV_INCLUDE_DIRS}\",ENABLE_OPENCV宏已打开")
message(STATUS "找到OpenCV:\"${OpenCV_LIBS}\"")
include_directories(${OpenCV_INCLUDE_DIRS})
add_definitions(-DENABLE_OPENCV)
list(APPEND LINK_LIB_LIST ${OpenCV_LIBS})
endif (OPENCV_FOUND)
#查找Boost是否安装
find_package(Boost REQUIRED COMPONENTS
regex
graph
chrono
thread
system
filesystem
serialization)
if (Boost_FOUND)
message(STATUS "找到Boost:\"${Boost_INCLUDE_DIRS}\",ENABLE_BOOST宏已打开")
message(STATUS "找到Boost:\"${Boost_LIBRARIES}\"")
include_directories(${Boost_INCLUDE_DIRS})
add_definitions(-DENABLE_BOOST)
list(APPEND LINK_LIB_LIST ${Boost_LIBRARIES})
endif (Boost_FOUND)
#查找catkin是否安装
find_package(catkin REQUIRED COMPONENTS
geometry_msgs
roscpp
tf
)
if (catkin_FOUND)
message(STATUS "找到catkin:\"${catkin_INCLUDE_DIRS}\",ENABLE_CATKIN宏已打开")
message(STATUS "找到catkin:\"${catkin_LIBRARIES}\"")
include_directories(${catkin_INCLUDE_DIRS})
add_definitions(-DENABLE_CATKIN)
list(APPEND LINK_LIB_LIST ${catkin_LIBRARIES})
endif (catkin_FOUND)
Eigen比较特殊, Eigen采用源码的方式提供给用户使用,在使用时只需要包含Eigen的头文件即可进行使用。之所以采用这种方式,是因为Eigen采用模板方式实现,由于模板函数不支持分离编译,所以只能提供源码而不是动态库的方式供用户使用。Eigen的默认安装路径是/usr/local/include/eigen3/Eigen,安装后需要将Eigen文件夹移动到/usr/local/include/下,可以执行如下语句,请参考这篇博客。
sudo cp -r /usr/local/include/eigen3/Eigen /usr/local/include
#查找Eigen3是否安装
find_package(Eigen3 REQUIRED)
if (EIGEN3_FOUND)
message(STATUS "找到Eigen3:\"${EIGEN3_INCLUDE_DIR}\",ENABLE_EIGEN3宏已打开")
include_directories(${EIGEN3_INCLUDE_DIR})
add_definitions(-DENABLE_EIGEN3)
# Eigen采用源码的方式提供给用户使用,在使用时只需要包含Eigen的头文件即可进行使用。
# 之所以采用这种方式,是因为Eigen采用模板方式实现,由于模板函数不支持分离编译,所以只能提供源码而不是动态库的方式供用户使用。
# list(APPEND LINK_LIB_LIST ${EIGEN3_LIBRARIES})
endif (EIGEN3_FOUND)
先安装好glog。安装后,无需在CMakeLists.txt中 find_package() 和 include_directories(),直接 target_link_libraries()。记得在使用glog的文件中包含头文件。
#include
target_link_libraries(${PROJECT_NAME} glog)
先安装好gtest。安装后,无需在CMakeLists.txt中 find_package() 和 include_directories(),直接 target_link_libraries()。
FILE(GLOB_RECURSE TEST_SRC "${CMAKE_SOURCE_DIR}/test/*.cpp" "${CMAKE_SOURCE_DIR}/test/*.h")
add_executable(${PROJECT_NAME}_test ${TEST_SRC})
target_link_libraries(${PROJECT_NAME}_test gtest ${LINK_LIB_LIST} glog)
一般测试文件夹test会放在工程内和 src、include 文件夹同级别的位置,在test文件夹内存放不同的测试文件test cases,并包含头文件。具体的请参考gtest的tutorials。
#include "gtest/gtest.h"
另外,要记得通过main() 运行所有的test cases。如下:
#include "gtest/gtest.h"
int main(int argc,char **argv){
testing::InitGoogleTest(&argc,argv);
return RUN_ALL_TESTS();
}
执行Reload CMake Project后的输出信息如下(不同的机器不同的安装路径输出会不一样):
-- 找到OpenCV:"/opt/ros/kinetic/include/opencv-3.3.1;/opt/ros/kinetic/include/opencv-3.3.1/opencv",ENABLE_OPENCV宏已打开
-- 找到OpenCV:"opencv_core;opencv_highgui;opencv_imgproc;opencv_imgcodecs"
-- Boost version: 1.58.0
-- Found the following Boost libraries:
-- regex
-- graph
-- chrono
-- thread
-- system
-- filesystem
-- serialization
-- date_time
-- atomic
-- 找到Boost:"/usr/include",ENABLE_BOOST宏已打开
-- 找到Boost:"/usr/lib/x86_64-linux-gnu/libboost_regex.so;/usr/lib/x86_64-linux-gnu/libboost_graph.so;/usr/lib/x86_64-linux-gnu/libboost_chrono.so;/usr/lib/x86_64-linux-gnu/libboost_thread.so;/usr/lib/x86_64-linux-gnu/libboost_system.so;/usr/lib/x86_64-linux-gnu/libboost_filesystem.so;/usr/lib/x86_64-linux-gnu/libboost_serialization.so;/usr/lib/x86_64-linux-gnu/libboost_date_time.so;/usr/lib/x86_64-linux-gnu/libboost_atomic.so"
-- .......省略........
-- 找到catkin:"/home/gjs/catkin_ws/devel/include;/home/gjs/catkin_ws/src/geometry/tf/include;/opt/ros/kinetic/include;/opt/ros/kinetic/share/xmlrpcpp/cmake/../../../include/xmlrpcpp;/usr/include",ENABLE_CATKIN宏已打开
-- 找到catkin:"/opt/ros/kinetic/lib/libtf.so;/opt/ros/kinetic/lib/libtf2_ros.so;/opt/ros/kinetic/lib/libactionlib.so;/opt/ros/kinetic/lib/libmessage_filters.so;/opt/ros/kinetic/lib/libroscpp.so;/usr/lib/x86_64-linux-gnu/libboost_filesystem.so;/usr/lib/x86_64-linux-gnu/libboost_signals.so;/opt/ros/kinetic/lib/libxmlrpcpp.so;/opt/ros/kinetic/lib/libtf2.so;/opt/ros/kinetic/lib/libroscpp_serialization.so;/opt/ros/kinetic/lib/librosconsole.so;/opt/ros/kinetic/lib/librosconsole_log4cxx.so;/opt/ros/kinetic/lib/librosconsole_backend_interface.so;/usr/lib/x86_64-linux-gnu/liblog4cxx.so;/usr/lib/x86_64-linux-gnu/libboost_regex.so;/opt/ros/kinetic/lib/librostime.so;/opt/ros/kinetic/lib/libcpp_common.so;/usr/lib/x86_64-linux-gnu/libboost_system.so;/usr/lib/x86_64-linux-gnu/libboost_thread.so;/usr/lib/x86_64-linux-gnu/libboost_chrono.so;/usr/lib/x86_64-linux-gnu/libboost_date_time.so;/usr/lib/x86_64-linux-gnu/libboost_atomic.so;/usr/lib/x86_64-linux-gnu/libpthread.so;/usr/lib/x86_64-linux-gnu/libconsole_bridge.so"
-- 找到Eigen3:"/usr/include/eigen3",ENABLE_EIGEN3宏已打开
对于自定义的库,库文件和头文件的名称可能有所区别。