前言
本文算是對官方文檔的翻譯內容吧,不算多麼深的技術。也將其中的代碼發佈到Github。跟官網一樣,也是一步步的來。
開始(Step 1)
大部分基礎項目都是從源代碼文件編譯成可執行文件。對於一個簡單的項目來說,CMakeLists.txt
只需要三行就可以解決。
創建一個CMakeLists.txt
文件,在Step1
的文件夾中:
# 設置cmake最低的版本號
cmake_minimum_required(VERSION 3.10)
# 設置項目名
project(Tutorial)
# 添加可執行的文件
add_executable(Tutorial tutorial.cc)
注意在這個例子中使用了小寫的命令。大寫、小寫或者大小寫都用的命令在CMake
中都是被支持的。
tutorial.cc
的源代碼是一個能夠計算一個數的平方根。
添加版本號和頭文件
第一個功能是我們給可執行文件和項目添加版本號。儘管我們可以在源代碼中這樣操作,但是使用CMake
可以提供更大的靈活性。
首先,修改CMakeLists.txt
文件以使用project()
命令設置項目名稱和版本號:
# 設置項目名和版本號
project(Tutorial VERSION 1.0)
之後,配置頭文件將版本號傳給源代碼:
configure_file(tutorial.h.in tutorial.h)
由於已配置的文件將被寫入二叉樹,因此我們必須將該目錄添加到路徑列表中以搜索包含文件。將代碼添加到CMakeLists.txt
文件的末尾:
target_include_directories(Tutorial PUBLIC
"${PROJECT_BINARY_DIR}"
)
在源目錄中創建tutorial.h.in
:
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
當CMake
配置頭文件的時候,@Tutorial_VERSION_MAJOR@
和@Tutorial_VERSION_MINOR@
都會被替換掉。
下一步,修改tutorial.cc
,包含頭文件tutorial.h
。
最後,通過更新tutorial.cc
來打印版本號:
if (argc < 2) {
// 打印版本號
std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
<< Tutorial_VERSION_MINOR << std::endl;
std::cout << "Usage: " << argv[0] << " number" << std::endl;
return 1;
}
指定C++標準
# 指定C++標準
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
編譯並且測試
通過運行cmake
程序或者cmake-gui
來配置項目,然後使用配所選的構建工具進行構建。
mkdir Step1_build && cd Step1_build
cmake ../Step1
cmake --build
./Tutorial 25
the sqrt of 25 is 5
添加庫文件(Step 2)
現在我們向我們的項目中添加一個庫文件。這個庫文件將會包含我們自己實現的求一個數的平方根。然後可執行文件使用此庫而不是編譯器提供的標準·平方根函數。
作爲教程,我們將這個庫文件放在名爲MathFunctions
的子目錄中。這個子目錄包含着``mysqrt.h的頭文件和
mysqrt.cc的源代碼文件。這個源代碼文件中包含一個叫
mysqrt的函數提供了與編譯器的
sqrt`函數類似的功能。
將下面這行添加到MathFuntions
目錄下的CMakeLists.txt
中:
add_library(MathFunctions mysqrt.cc)
爲了能夠調用庫文件,我們將Step2
文件夾中的CMakeLists.txt
文件中添加一個add_subdirectory()
以便構建該庫。我們將新庫添加到可執行文件並將MathFunctions
作爲包含文件以便可以找到mysqrt.h
頭文件。
# 設置cmake最低的版本號
cmake_minimum_required(VERSION 3.10)
# 設置項目名和版本號
project(Tutorial VERSION 1.0)
# 指定C++標準
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
configure_file(tutorial.h.in tutorial.h)
# 添加可執行的文件
add_executable(Tutorial tutorial.cc)
# 添加MathFunctions庫
add_subdirectory(MathFunctions)
# 添加可執行程序
add_executable(Tutorial tutorial.cc)
target_link_libraries(Tutorial PUBLIC MathFunctions)
# 將二叉樹添加到包含文件的搜索路徑以便讓我們能夠找到tutorial.h
target_include_directories(Tutorial PUBLIC
"${PROJECT_BINARY_DIR}"
"${PROJECT_SOURCE_DIR}/MathFunctions"
)
對於大型的項目來說,CMakeLists.txt
可以設置MathFunctions
庫設爲可選。
option(USE_MYMATH "Use tutorial provided math implementation" ON)
# 配置頭文件以傳遞某些CMake設置到源代碼
configure_file(tutorial.h.in tutorial.h)
此設置存儲在緩存中,因此用戶無需在每次構建目錄上運行CMake時都設置該值。
下一個更改是使編譯和鏈接MathFunctions
庫成爲條件:
if(USE_MYMATH)
add_subdirectory(MathFunctions)
list(APPEND EXTRA_LIBS MathFunctions)
list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
endif()
# 添加可執行程序
add_executable(Tutorial tutorial.cc)
target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
# 將二叉樹添加到包含文件的搜索路徑以便讓我們能夠找到tutorial.h
target_include_directories(Tutorial PUBLIC
"${PROJECT_BINARY_DIR}"
${EXTRA_INCLUDES}
)
注意使用變量EXTRA_LIBS
來收集所有可選庫,以供以後鏈接到可執行文件中。
變量EXTRA_INCLUDES
用於可選的頭文件。當處理許多可選組件時,這是一種經典方法。
對源代碼的相應更改非常簡單。
首先,如果需要,在tutorial.cc
中包含MathFunctions.h
頭文件
#ifdef USE_MYMATH
#include "MathFunctions.h"
#endif
然後相同的文件中使USE_MYMATH
控制使用那個平方根函數
#ifdef USE_MYMATH
const double outputValue = mysqrt(inputValue);h
#else
const double outputValue = sqrt(inputValue);
#endif
之後在tutorial.h.in
中添加:
#cmakedefine USE_MYMATH