大家好,我已經把CSDN上的部落格遷移到了知乎上,歡迎大家在知乎關注我的專欄慢慢悠悠小馬車(https://zhuanlan.zhihu.com/duangduangduang)。希望大家可以多多交流,互相學習。
目錄
CMake連結庫的基本套路
OpenCV
Boost
ROS catkin
Eigen
glog
gtest
CMake 輸出資訊
CMake連結庫的基本套路
在使用CMake組織工程時,如果我們需要依賴某個庫檔案,需要完成以下步驟:
- 查找庫檔案(find_package指令)
- 判斷是否找到庫檔案(XXX_FOUND标記),并包含頭檔案(include_directories指令)
- 連結庫檔案到目标(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宏已打開
對于自定義的庫,庫檔案和頭檔案的名稱可能有所差別。