初探 CMake 跨平臺自動構建系統(1)—手寫深度學習框架預備篇

這是我參與8月更文挑戰的第5天,活動詳情查看:8月更文挑戰ios

用過 tensorflow 和 pytorch 不過仍是想本身實現一個簡單的基於 c++ 深度學習框架,幫助本身對這些算法進一步瞭解。c++

建立項目並設置可執行文件

最基本的項目是將源代碼文件構建成可執行文件。對於簡單的項目,建立一個名稱爲 CMakeLists.txt 文件,而後在文件添加以下 3 行代碼便可。這將是學習 CMake 的起點。web

cmake_minimum_required(VERSION 3.10)
 # 設置項目名稱
project(Tutorial)
 # 添加可執行文件
add_executable(Tutorial main.cppc)
複製代碼

設置項目名稱

注意這個例子在 CMakeLists.txt 文件中使用了小寫的命令。CMake 支持大寫、小寫和混合大小寫的命令。main.cpp 的源代碼在 demo 目錄下提供,也能夠放置在 build 目錄下,算法

首選要作的是建立一個項目,而後爲項目執行可執行文件。雖然能夠徹底在源代碼中作到這一點,但使用 CMakeLists.txt 提供了更多的靈活性,能夠在構建項目來設置項目名和版本號。在 CMakeLists.txt 文件,經過project() 命令來設置項目名稱和版本號。shell

project(Tutorial)
複製代碼

而後,配置一個頭文件,將版本號經過頭文件傳遞給源代碼。bash

配置項目版本號

因爲配置的文件將被寫入二進制樹中,須要將該目錄添加到搜索包含文件的路徑列表中。在 CMakeLists.txt 文件的末尾添加如下幾行。在項目目錄下建立TutorialConfig.h.in 文件,而後在文件中輸入以下markdown

// 配置選項和設置 Tutorial 主版本號和小版本號
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@
複製代碼

當 CMake 配置這個頭文件時,@Tutorial_VERSION_MAJOR@ @Tutorial_VERSION_MINOR@的值將被替換。能夠在 CMakeLists.txt 文件建立並設置一些變量,也就是在 CMakeLists.txt 將替換調用 TutorialConfig.h.in 文件中用 @ 符號包裹的變量框架

set(Tutorial_VERSION_MAJOR 1)
set(Tutorial_VERSION_MINOR 0)
複製代碼

接下來修改 main.cpp 文件,在頭部將 TutorialConfig.h 引入,自動建立好的 TutorialConfig.h 也會出現 build 目錄。函數

#include <iostream>
#include "TutorialConfig.h"
複製代碼

這樣一來就能夠 main.cpp 來打印輸出可執行文件的名稱和版本號,代碼以下工具

cout <<  Tutorial_VERSION_MAJOR << endl;
複製代碼
CMakeLists.txt
cmake_minimum_required(VERSION 3.10)

project(Tutorial)

set(Tutorial_VERSION_MAJOR 1)
set(Tutorial_VERSION_MINOR 0)

configure_file(TutorialConfig.h.in TutorialConfig.h)

add_executable(Tutorial main.cpp)

target_include_directories(Tutorial PUBLIC "${PROJECT_BINARY_DIR}")
複製代碼
main.cpp
#include <iostream>
#include "TutorialConfig.h"
using namespace std;

int main(int argc, char const *argv[]) {
    // cout << "hello world" << endl;
    cout <<  Tutorial_VERSION_MAJOR << endl;
    // cout << Tutorial_VERSION_MINOR << endl;
    return 0;
}
複製代碼

指定 c++ 標準庫

# 執行  C++ 標準庫
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)
複製代碼

接下來讓咱們在 main.cpp 中用 std::stod 替換 atof,爲咱們的項目添加一些 C++11特性。同時移除 #include <cstdlib>

#include <iostream>
#include "TutorialConfig.h"
using namespace std;

int main(int argc, char const *argv[]) {
    // cout << "hello world" << endl;
    cout <<  std::stod(argv[1]) * 10<< endl;
    // cout << Tutorial_VERSION_MINOR << endl;
    return 0;
}
複製代碼

咱們將須要在 CMake 代碼中明確地說明編譯 C++ 標準庫的版本。最簡單方法是使用 CMAKE_CXX_STANDARD 變量來設置 C++ 標準庫。這裏將 CMakeLists.txt 文件中的 CMAKE_CXX_STANDARD 變量設爲 11,當 CMAKE_CXX_STANDARD_REQUIRED 設爲 True,則將CMAKE_CXX_STANDARD 指定版本引用到對 add_executable 的 cpp 文件。

運行 CMake

運行 cmake 可執行文件,而後用你選擇的構建工具來構建項目。接下來進入到構建目錄build,運行 CMake 來配置項目並生成一個本地構建系統。

cmake ..
複製代碼

使用cmake --build .調用該構建系統來編譯和鏈接(compile/link)該項目。

cmake --build .
複製代碼

若是咱們就能夠在 build 經過執行./Tutorial來運行應用看效果了。

爲項目添加本身實現 lib

如今要作的事爲項目添加一個庫,這個庫提供了用於計算數字的平方根方法,爲了解釋說明這個庫不是由編譯器提供的標準平方根函數,而是本身實現的一個庫,而後看如何編譯過程當中將其添加到項目中。

隨後建立 MathFunctions 的子目錄用於放置咱們庫文件。這個目錄已經包含一個頭文件MathFunctions.h 和一個源文件 main.cpp。在源文件中,定義名爲 add 的函數,提供了與編譯器的 add 函數相似的功能。

在 MathFunctions 目錄下建立 MathFunctions.h 文件,這個文件有點相似接口,也就是 cpp 頭文件

MathFunctions/MathFunctions.h
double add(double x, double y);
複製代碼

在 MathFunctions 目錄下,建立一個 main.cpp 的文件,這個文件會去實現add 方法。

MathFunctions/main.cpp
#include "MathFunctions.h"

double add(double x, double y){
    return x + y;
}
複製代碼

而後在 MathFunctions 這個目錄下,一樣也建立一個 CMakeLists.txt 文件,內容以下

MathFunctions/CMakeLists.txt
add_library(MathFunctions main.cpp)
複製代碼

能夠理解向項目添加一個包,MathFunctions 是包的名稱,main.cpp 能夠包向外 export 的入口文件。

main.cpp
#include <iostream>
#include "TutorialConfig.h"
#include "MathFunctions.h"

using namespace std;

int main(int argc, char const *argv[]) {
    // cout << "hello world" << endl;
    double inputValue = std::stod(argv[1]);
    // cout << std::stod(argv[1])<< endl;
    const double outputValue = add(inputValue,2.0);
    
    cout <<  outputValue << endl;
    // cout << Tutorial_VERSION_MINOR << endl;
    return 0;
}

複製代碼

在 CMakeLists.txt 文件中添加一個 add_subdirectory() 來調用 MathFunctions 目錄下 CMakeLists.txt 來構建這個庫。同時將也要添加到可執行文件 main.cpp,並將 MathFunctions 添加爲包含目錄,這樣就能夠找到 main.cpp 項目主文件引入 MathFunctions.h 頭文件。

CMakeLists.txt
cmake_minimum_required(VERSION 3.10)

project(Tutorial)

# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

set(Tutorial_VERSION_MAJOR 1)
set(Tutorial_VERSION_MINOR 0)
set(Tutorial_NAME_VERSION 1)

configure_file(TutorialConfig.h.in TutorialConfig.h)
add_subdirectory(MathFunctions)

add_executable(Tutorial main.cpp)

target_link_libraries(Tutorial PUBLIC MathFunctions)
target_include_directories(Tutorial PUBLIC
                          "${PROJECT_BINARY_DIR}"
                          "${PROJECT_SOURCE_DIR}/MathFunctions"
                          )
複製代碼
add_subdirectory(MathFunctions)
複製代碼
  • target_link_libraries
  • target_include_directories
target_link_libraries(Tutorial PUBLIC MathFunctions)
target_include_directories(Tutorial PUBLIC
                          "${PROJECT_BINARY_DIR}"
                          "${PROJECT_SOURCE_DIR}/MathFunctions"
                          )
複製代碼
相關文章
相關標籤/搜索