初探 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"
                          )
复制代码
相关文章
相关标签/搜索