++项目 cmake头文件路径_CMAKE入门实战
0.導(dǎo)語
最近做的項目使用CLION構(gòu)建,而這個采用CMakeLists.txt管理,因此為了更好的學(xué)習(xí),故找到了一篇大牛級別的入門文章,有文章有代碼,本文是花了一點時間把這篇文章學(xué)習(xí)后的重要點記錄吧,原作者github地址:https://github.com/wzpan/cmake-demo。
1.單個源文件
CMakeLists.txt 的語法比較簡單,由命令、注釋和空格組成,其中命令是不區(qū)分大小寫的。符號 # 后面的內(nèi)容被認(rèn)為是注釋。命令由命令名稱、小括號和參數(shù)組成,參數(shù)之間使用空格進(jìn)行間隔。
首先創(chuàng)建一個main.cpp
#include int main() { ? ?std::cout << "Hello, World!" << std::endl; ? ?return 0;}編寫第一個CMakeLists.txt:
cmake_minimum_required(VERSION 3.10)project(cmakeLearn)add_executable(main main.cpp)cmake_minimum_required:指定運行此配置文件所需的 CMake 的最低版本;project:參數(shù)值是cmakeLearn,該命令表示項目的名稱是cmakeLearn。add_executable:將名為main.cpp的源文件編譯成一個名稱為cmakeLearn的可執(zhí)行文件。
現(xiàn)在查看一下路徑:
light@city:~/CLionProjects/cmakeLearn$ lsCMakeLists.txt ?main.cpp輸入下列命令進(jìn)行cmake
cmake .cmake過程
light@city:~/CLionProjects/cmakeLearn$ cmake .-- The C compiler identification is GNU 5.5.0-- The CXX compiler identification is GNU 5.5.0-- Check for working C compiler: /usr/bin/cc-- Check for working C compiler: /usr/bin/cc -- works-- Detecting C compiler ABI info-- Detecting C compiler ABI info - done-- Detecting C compile features-- Detecting C compile features - done-- Check for working CXX compiler: /usr/bin/c++-- Check for working CXX compiler: /usr/bin/c++ -- works-- Detecting CXX compiler ABI info-- Detecting CXX compiler ABI info - done-- Detecting CXX compile features-- Detecting CXX compile features - done-- Configuring done-- Generating done-- Build files have been written to: /home/light/CLionProjects/cmakeLearncmake 后 生成了Makefile
light@city:~/CLionProjects/cmakeLearn$ lsCMakeCache.txt cmake_install.cmake main.cppCMakeFiles ? ? CMakeLists.txt ? ? ? Makefile然后執(zhí)行make
light@city:~/CLionProjects/cmakeLearn$ makeScanning dependencies of target main[ 50%] Building CXX object CMakeFiles/main.dir/main.cpp.o[100%] Linking CXX executable main[100%] Built target main執(zhí)行
light@city:~/CLionProjects/cmakeLearn$ ./mainHello, World!2.多個源文件
2.1 同一目錄,多個源文件
在1中的cmake添加下面這行:
# 查找當(dāng)前目錄下的所有源文件# 并將名稱保存到 DIR_SRCS 變量aux_source_directory(. DIR_SRCS)當(dāng)本地源文件很多,如果將源文件都加到里面就很煩,所以這里采用aux_source_directory。CMake 會將當(dāng)前目錄所有源文件的文件名賦值給變量 DIR_SRCS ,再指示變量 DIR_SRCS 中的源文件需要編譯成一個名稱為 Demo 的可執(zhí)行文件。
這樣就避免出現(xiàn)下面這種情況:
# 指定生成目標(biāo)add_executable(Demo main.cc MathFunctions.cc xx.cc ....cc)小結(jié):
aux_source_directory(. DIR_SRCS)
查找當(dāng)前目錄下的所有源文件,并將名稱保存到 DIR_SRCS 變量。
2.2 多個目錄,多個源文件
此時目錄架構(gòu):
./Demo3 ? | ? +--- main.cc ? | ? +--- math/ ? ? ? ? | ? ? ? ? +--- MathFunctions.cc ? ? ? ? | ? ? ? ? +--- MathFunctions.h對于這種情況,需要分別在項目根目錄 Demo3 和 math 目錄里各編寫一個 CMakeLists.txt 文件。
為了方便,我們可以先將 math 目錄里的文件編譯成靜態(tài)庫再由 main 函數(shù)調(diào)用。
這里與上述2.1CMakeLists不同之處是在上面基礎(chǔ)上加上了:
# 添加 math 子目錄add_subdirectory(math)# 添加鏈接庫target_link_libraries(Demo MathFunctions)以此完成:
子目錄添加
鏈接庫添加
最后,在子目錄下指定鏈接庫名字:
子目錄中的 CMakeLists.txt:
# 查找當(dāng)前目錄下的所有源文件# 并將名稱保存到 DIR_LIB_SRCS 變量aux_source_directory(. DIR_LIB_SRCS)# 生成鏈接庫add_library (MathFunctions ${DIR_LIB_SRCS})小結(jié):
add_library(MathFunctions ${DIR_LIB_SRCS})
將 src 目錄中的源文件編譯為靜態(tài)鏈接庫。
3.自定義編譯選項
CMake 允許為項目增加編譯選項,從而可以根據(jù)用戶的環(huán)境和需求選擇最合適的編譯方案。
例如,可以將 MathFunctions 庫設(shè)為一個可選的庫,如果該選項為 ON ,就使用該庫定義的數(shù)學(xué)函數(shù)來進(jìn)行運算。否則就調(diào)用標(biāo)準(zhǔn)庫中的數(shù)學(xué)函數(shù)庫。
本節(jié)CMake與2不同如下三塊:
(1)加入一個配置頭文件,用于處理 CMake 對源碼的設(shè)置
# 加入一個配置頭文件,用于處理 CMake 對源碼的設(shè)置configure_file ( "${PROJECT_SOURCE_DIR}/config.h.in" "${PROJECT_BINARY_DIR}/config.h" )configure_file 命令用于加入一個配置頭文件 config.h ,這個文件由 CMake 從 config.h.in生成,通過這樣的機制,將可以通過預(yù)定義一些參數(shù)和變量來控制代碼的生成。
例如:修改main.cc:
#include "config.h".........#ifdef USE_MYMATH #include "math/MathFunctions.h"#else #include#endif根據(jù) USE_MYMATH 的預(yù)定義值來決定是否調(diào)用標(biāo)準(zhǔn)庫還是 MathFunctions 庫。
上修改main.cc中引用了一個 config.h 文件,這個文件預(yù)定義了 USE_MYMATH 的值。但我們并不直接編寫這個文件,為了方便從 CMakeLists.txt 中導(dǎo)入配置,我們編寫一個 config.h.in 文件:
#cmakedefine USE_MYMATH這樣 CMake 會自動根據(jù) CMakeLists 配置文件中的設(shè)置自動生成 config.h 文件。
這里使用了ccmake進(jìn)行可視化編譯選擇,Ubuntu上安裝:
sudo apt-get install cmake-curses-gui運行ccmake .后:
hjkl控制方向移動,enter 鍵可以修改該選項。修改完成后可以按下 c 選項完成配置,之后再按 g 鍵確認(rèn)生成 Makefile 。ccmake 的其他操作可以參考窗口下方給出的指令提示。
下面來看一下config.h文件內(nèi)容:
USE_MYMATH 為 ON
#define USE_MYMATHUSE_MYMATH 為 OFF
/* #undef USE_MYMATH */(2)是否加入 MathFunctions 庫
# 是否加入 MathFunctions 庫if (USE_MYMATH) include_directories ("${PROJECT_SOURCE_DIR}/math") add_subdirectory (math) ? set (EXTRA_LIBS ${EXTRA_LIBS} MathFunctions)endif (USE_MYMATH)option 命令添加了一個 USE_MYMATH 選項,并且默認(rèn)值為 ON 。
(3)是否使用自己的 MathFunctions 庫
# 是否使用自己的 MathFunctions 庫option (USE_MYMATH ? ? ? "Use provided math implementation" ON)根據(jù) USE_MYMATH 變量的值來決定是否使用我們自己編寫的 MathFunctions 庫。
4.安裝和測試
4.1 安裝
之前在編譯一些源代碼程序的時候,先make后make install,這樣會把一些頭文件與靜態(tài)/動態(tài)庫安裝到指定的目錄下。
那在CMAKE中同樣可以這么做,如下:
首先先在 math/CMakeLists.txt 文件里添加下面兩行:
指定 MathFunctions 庫的安裝路徑install (TARGETS MathFunctions DESTINATION bin)install (FILES MathFunctions.h DESTINATION include)指明 MathFunctions 庫的安裝路徑。之后同樣修改根目錄的 CMakeLists 文件,在末尾添加下面幾行:
# 指定安裝路徑install (TARGETS Demo DESTINATION bin)install (FILES "${PROJECT_BINARY_DIR}/config.h" ? ? ? ? DESTINATION include)通過上面定制,后安裝如下:
light@city:~/cmake-demo/Demo5$ sudo make install[ 50%] Built target MathFunctions[100%] Built target DemoInstall the project...-- Install configuration: ""-- Installing: /usr/local/bin/Demo-- Installing: /usr/local/include/config.h-- Installing: /usr/local/lib/libMathFunctions.a-- Installing: /usr/local/include/MathFunctions.h據(jù)此完成了安裝工作。
4.2 測試
CMake 提供了一個稱為 CTest 的測試工具。我們要做的只是在項目根目錄的 CMakeLists 文件中調(diào)用一系列的 add_test 命令。
啟動測試:
# 啟用測試enable_testing()(1)無幫助信息測試
# 測試程序是否成功運行add_test (test_run Demo 5 2)(2)有幫助信息測試
# 測試 2 的 10 次方add_test (test_2_10 Demo 2 10)set_tests_properties (test_2_10) PROPERTIES PASS_REGULAR_EXPRESSION "is 1024")其中 PASS_REGULAR_EXPRESSION 用來測試輸出是否包含后面跟著的字符串。
5.支持gdb
讓 CMake 支持 gdb 的設(shè)置也很容易,只需要指定 Debug 模式下開啟 -g 選項:
set(CMAKE_BUILD_TYPE "Debug")set(CMAKE_CXX_FLAGS_DEBUG "$ENV{CXXFLAGS} -O0 -Wall -g -ggdb")set(CMAKE_CXX_FLAGS_RELEASE "$ENV{CXXFLAGS} -O3 -Wall")6.添加版本號
在編寫項目中給項目添加版本號:
set (Demo_VERSION_MAJOR 1)set (Demo_VERSION_MINOR 0)分別指定當(dāng)前的項目的主版本號和副版本號。
如果想在代碼中獲取信息,可以修改config.h.in文件,添加兩個預(yù)定義變量:
// the configured options and settings for Tutorial#define Demo_VERSION_MAJOR @Demo_VERSION_MAJOR@#define Demo_VERSION_MINOR @Demo_VERSION_MINOR@主程序調(diào)用,打印:
printf("%s Version %d.%d\n", ? ? ? ?argv[0], ? ? ? ?Demo_VERSION_MAJOR, ? ? ? ?Demo_VERSION_MINOR);7.生成安裝包
如何配置生成各種平臺上的安裝包,包括二進(jìn)制安裝包和源碼安裝包。為了完成這個任務(wù),我們需要用到 CPack ,它同樣也是由 CMake 提供的一個工具,專門用于打包。
我們做如下三個工作:
導(dǎo)入 InstallRequiredSystemLibraries 模塊,以便之后導(dǎo)入 CPack 模塊;
設(shè)置一些 CPack 相關(guān)變量,包括版權(quán)信息和版本信息,其中版本信息用了上一節(jié)定義的版本號;
導(dǎo)入 CPack 模塊。
對應(yīng)CMakeLists.txt如下:
# 構(gòu)建一個 CPack 安裝包include (InstallRequiredSystemLibraries)set (CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/License.txt")set (CPACK_PACKAGE_VERSION_MAJOR "${Demo_VERSION_MAJOR}")set (CPACK_PACKAGE_VERSION_MINOR "${Demo_VERSION_MINOR}")include (CPack)下面就是如何使用:
輸入cpack .,也可以指定二進(jìn)制與源碼安裝包:
生成二進(jìn)制安裝包:
cpack -C CPackConfig.cmake生成源碼安裝包
cpack -C CPackSourceConfig.cmakecpack安裝:
light@city:~/cmake-demo/Demo8$ cpack -CPackConfig.cmakeCPack: Create package using STGZCPack: Install projectsCPack: - Run preinstall target for: Demo8CPack: - Install project: Demo8CPack: Create packageCPack: - package: /home/light/cmake-demo/Demo8/Demo8-1.0.1-Linux.sh generated.CPack: Create package using TGZCPack: Install projectsCPack: - Run preinstall target for: Demo8CPack: - Install project: Demo8CPack: Create packageCPack: - package: /home/light/cmake-demo/Demo8/Demo8-1.0.1-Linux.tar.gz generated.CPack: Create package using TZCPack: Install projectsCPack: - Run preinstall target for: Demo8CPack: - Install project: Demo8CPack: Create packageCPack: - package: /home/light/cmake-demo/Demo8/Demo8-1.0.1-Linux.tar.Z generated.此時會在本地目錄下創(chuàng)建3個不同格式的二進(jìn)制包文件:
light@city:~/cmake-demo/Demo8$ ls Demo8*Demo8-1.0.1-Linux.sh Demo8-1.0.1-Linux.tar.gz Demo8-1.0.1-Linux.tar.Z隨便選擇一個安裝,例如sh:
sh Demo8-1.0.1-Linux.sh使用:
light@city:~/cmake-demo/Demo8$ ./Demo8-1.0.1-Linux/bin/Demo 5 2Now we use our own Math library.5 ^ 2 is 25
總結(jié)
以上是生活随笔為你收集整理的++项目 cmake头文件路径_CMAKE入门实战的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 求助.怎么让大家快速接受新的东西。?
- 下一篇: ibm db2获取目标时间与当前时间的差