天天看點

CMakeLists.txt中常用庫檔案的查找和連結

大家好,我已經把CSDN上的部落格遷移到了知乎上,歡迎大家在知乎關注我的專欄慢慢悠悠小馬車(https://zhuanlan.zhihu.com/duangduangduang)。希望大家可以多多交流,互相學習。

目錄

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 <glog/logging.h>
           
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宏已打開
           

對于自定義的庫,庫檔案和頭檔案的名稱可能有所差別。

繼續閱讀