翻譯-cmake教程

前言

本文算是對官方文檔的翻譯內容吧,不算多麼深的技術。也將其中的代碼發佈到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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章