翻译-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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章