一. 為什么要使用cmake
理論上說,任意一個C++程序都可以用g++來編譯。但當程序規模越來越大時,一個工程可能有許多個文件夾和源文件,這時輸入的編譯命令將越來越長。通常一個小型C++項目可能含有十幾個類,各類間還存在着復雜的依賴關系。其中一部分要編譯成可執行文件,另一部分要編譯成庫文件。如果僅靠g++命令,我們需要輸入大量的編譯指令,整個編譯過程會變得異常繁瑣。因此,對於C++項目,使用一些工程管理工具會更加高效。歷史上工程師們曾使用makefile進行自動編譯,但cmake要比它更加方便。
在一個cmake工程中,我們會用cmake命令生成一個makefile文件,然后用make命令根據這個makefile文件的內容編譯整個工程。
二.CMakeLists.txt文件的基本寫法
#聲明要求的cmake最低版本
cmake_minimun_required( VERSION 2.8)
#聲明一個cmake工程,工程名為post_fusion
project(post_fusion)
# 添加c++ 11標准支持
set( CMAKE_CXX_FLAGS "-std=c++11" )
如果程序中使用了C++11標准,則需要設置告訴編譯器,沒有可以不用寫。
#設置編譯器編譯模式:
set( CMAKE_BUILD_TYPE "Debug" )
對於編譯用的Debug模式和調試用的Release模式,在Debug模式中,程序運行較慢,當可以在IDE中進行斷點調試,而Release模式則速度較快,但沒有調試信息。不設置默認是Debug模式。
# 添加引用的第三方頭文件,例如添加Eigen頭文件
include_directories( "/usr/include/eigen3" )
#編譯生成庫文件
add_library(irfusion comfunc.c post_sins_gnss.cpp)
這條命令告訴cmake,我們想把這些源文件編譯成一個叫作“irfusion”的庫。在linux中,庫文件分為靜態庫和動態庫兩種,靜態庫以.a作為后綴名,共享庫以.so結尾。所有庫都是一些函數打包后的集合,差別在於靜態庫每次被調用都會生成一個副本,而共享庫則只有一個副本,更省空間。如果想生成共享庫而不是靜態庫,只需要使用以下語句即可
add_library(irfusion_shared SHARED comfunc.c post_sins_gnss.cpp)
此時得到的文件就是irfusion_shared.so了。
然后,在CMakeList.txt中添加一個可執行程序的生成命令,鏈接到剛才使用的庫上:
add_executable(irfusion main.cpp)
target_link_libraries(irfusion irfusion_shared)
通過這兩行語句,irfusion程序就能順利使用irfusion_shared庫中的代碼了。
整個工程中的代碼結構:
使用cmake編譯整個工程
cd build
cmake ..
make
小結:
1. 首先,程序代碼由頭文件和源文件組成。
2. 帶有main函數的源文件編譯成可執行程序,其他的編譯成庫文件。
3. 如果可執行程序想調用庫文件中的函數,它需要參考該庫提供的頭文件,以明白調用的格式。同時,要把可執行程序鏈接到庫文件上。