CMakeLists.txt中常用库文件的查找和链接

大家好,我已经把CSDN上的博客迁移到了知乎上,欢迎大家在知乎关注我的专栏慢慢悠悠小马车(https://zhuanlan.zhihu.com/c_1132958996826546176)。以后,我会把日常的思考放在CSDN上,梳理过的精华文章放在知乎上,希望大家可以多多交流,互相学习。


目录

CMake链接库的基本套路

OpenCV

Boost

ROS catkin

Eigen

glog

gtest 

CMake 输出信息


CMake链接库的基本套路

在使用CMake组织工程时,如果我们需要依赖某个库文件,需要完成以下步骤:

  1. 查找库文件(find_package命令)
  2. 判断是否找到库文件(XXX_FOUND标记),并包含头文件(include_directories命令)
  3. 链接库文件到目标(target_link_libraries命令)

         因此,库文件、头文件的名字(大小写)我们就要清楚的写明,不要混淆。我常用的库如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

#查找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

#查找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)

ROS catkin

#查找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采用模板方式实现,由于模板函数不支持分离编译,所以只能提供源码而不是动态库的方式供用户使用。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

先安装好glog。安装后,无需在CMakeLists.txt中 find_package() 和 include_directories(),直接 target_link_libraries()。记得在使用glog的文件中包含头文件。

#include 
target_link_libraries(${PROJECT_NAME} glog)

gtest 

先安装好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();
}

CMake 输出信息

执行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宏已打开

对于自定义的库,库文件和头文件的名称可能有所区别。

你可能感兴趣的:(小技巧)