Cmake 官方教程学习(step1-3)

作者: 稀土掘金  更新时间:2020-07-21 21:11:50  原文链接


Cmake 官方教程学习(step1-3)

开发工具: clion

构建工具链: VisualStudio

cmake 版本:3.16

什么是 CMake

CMake是用于管理源代码构建的工具,被广泛用于C和C ++语言.

创建项目

使用 clion 创建项目,项目名 Tutorial 将创建好项目中的 main.cpp 修改为 tutorial.cpp

了解最基本配置

project CMakeLists.txt

# 指定 cmake 最低要求版本
cmake_minimum_required(VERSION 3.10)

设置 c++ 标准

set(CMAKE_CXX_STANDARD 14)

设置项目名字

project(Tutorial)

添加可执行文件

复制代码

add_executable(Tutorial tutorial.cpp) <span>复制代码</span>

tutorial.cpp

#include <iostream>

int main() {
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

运行项目

D:\cprojects\Tutorial\cmake-build-debug\Tutorial.exe
Hello, World!

Process finished with exit code 0

添加版本及传递版本到头文件

project CMakeLists.txt

# 指定 cmake 最低要求版本
cmake_minimum_required(VERSION 3.10)

设置项目名称及版本

project(Tutorial VERSION 1.0)

设置 c++ 标准

set(CMAKE_CXX_STANDARD 14)

配置文件,将版本号传递给源代码

configure_file(TutorialConfig.h.in TutorialConfig.h)

添加可执行文件

add_executable(Tutorial tutorial.cxx)

指定编译目标(Turorial)时包含的路径

这样才能找到 .h(TutorialConfig.h) 文件

复制代码

target_include_directories(Tutorial PUBLIC &quot;${PROJECT_BINARY_DIR}&quot;) <span>复制代码</span>

TutorialConfig.h.in

// 当CMake配置此头文件时,@Tutorial_VERSION_MAJOR@和的值 @Tutorial_VERSION_MINOR@将被替换。
#define Tutorial_VERSION_MAJOR @Tutorial_VERSION_MAJOR@
#define Tutorial_VERSION_MINOR @Tutorial_VERSION_MINOR@

tutorial.cpp

#include <iostream>
#include "TutorialConfig.h"

int main(int argc, char* argv[]) {
    if (argc < 2) {
        // report version
        std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
                  << Tutorial_VERSION_MINOR << std::endl;
        std::cout << "Usage: " << argv[0] << " number" << std::endl;
        return 1;
    }
    std::cout << "Hello, World!" << std::endl;
    return 0;
}

运行项目

D:\cprojects\Tutorial\cmake-build-debug\Tutorial.exe
D:\cprojects\Tutorial\cmake-build-debug\Tutorial.exe Version 1.0
Usage: D:\cprojects\Tutorial\cmake-build-debug\Tutorial.exe number

Process finished with exit code 1

添加一个库

  1. 在根项目下创建 MathFunctions 文件夹

  2. 在 MathFunctions 文件夹下创建 MathFunctions.h

  3. 在 MathFunctions 文件夹下创建 mysqrt.cpp

  4. 在 MathFunctions 文件夹下创建 CMakeLists.txt

MathFunctions.h

double mysqrt(double x);

mysqrt.cpp

#include <iostream>
#include "MathFunctions.h"

// 使用简单操作进行hack平方根计算
double mysqrt(double x)
{
     if (x <= 0) {
        return 0;
    }

    double result = x;

    // do ten iterations
    for (int i = 0; i < 10; ++i) {
        if (result <= 0) {
            result = 0.1;
        }
        double delta = x - (result * result);
        result = result + 0.5 * delta / result;
        std::cout << "Computing sqrt of " << x << " to be " << result << std::endl;
    }
    return result;
}

MathFunctions CMakeLists.txt

# 添加 MathFunctions 为库
add_library(MathFunctions mysqrt.cpp)

project CMakeLists.txt

...

# 添加 MathFunctions 库
add_subdirectory(MathFunctions)

# 添加可执行文件
add_executable(Tutorial tutorial.cxx)

# 链接 MathFunctions 库
target_link_libraries(Tutorial PUBLIC MathFunctions)

# 新添加 MathFunctions 源文件
# 这样才能找到 MathFunctions.h
target_include_directories(Tutorial PUBLIC
        "${PROJECT_BINARY_DIR}"
        "${PROJECT_SOURCE_DIR}/MathFunctions"
        )

tutorial.cpp

#include <iostream>
#include <string>
#include "TutorialConfig.h"
#include "MathFunctions.h"

int main(int argc, char* argv[]) {
    if (argc < 2) {
        // report version
        std::cout << argv[0] << " Version " << Tutorial_VERSION_MAJOR << "."
                  << Tutorial_VERSION_MINOR << std::endl;
        std::cout << "Usage: " << argv[0] << " number" << std::endl;
        return 1;
    }
    const double inputValue = std::stod(argv[1]);
    std::cout << "inputValue is " << inputValue << std::endl;
    const double outputValue = mysqrt(inputValue);
    std::cout << "outputValue is " << outputValue << std::endl;
    return 0;
}

修改 clion 运行配置,添加 Program arguments 25

运行项目

D:\cprojects\Tutorial\cmake-build-debug\Tutorial.exe 25
inputValue is 25
Computing sqrt of 25 to be 13
Computing sqrt of 25 to be 7.46154
Computing sqrt of 25 to be 5.40603
Computing sqrt of 25 to be 5.01525
Computing sqrt of 25 to be 5.00002
Computing sqrt of 25 to be 5
Computing sqrt of 25 to be 5
Computing sqrt of 25 to be 5
Computing sqrt of 25 to be 5
Computing sqrt of 25 to be 5
outputValue is 5

Process finished with exit code 0

将MathFunctions库设为可选

project CMakeLists.txt

...
# 提供用户可以选择的选项
option(USE_MYMATH "Use tutorial provided math implementation" ON)
configure_file(TutorialConfig.h.in TutorialConfig.h)

# 根据开关决定是否添加 MathFunctions 库
# 使用变量 EXTRA_LIBS 来收集所有可选库,以便以后链接到可执行文件中
# 变量 EXTRA_INCLUDES类似地用于可选的头文件
if(USE_MYMATH)
  add_subdirectory(MathFunctions)
  list(APPEND EXTRA_LIBS MathFunctions)
  list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
endif()

# 添加可执行文件
add_executable(Tutorial tutorial.cxx)

target_link_libraries(Tutorial PUBLIC ${EXTRA_LIBS})
target_include_directories(Tutorial PUBLIC
                           "${PROJECT_BINARY_DIR}"
                           ${EXTRA_INCLUDES}
                           )

TutorialConfig.h.in

// 添加 USE_MYMATH 定义
#cmakedefine USE_MYMATH

tutorial.cpp

# 根据 USE_MYMATH 开关确定头文件
#ifdef USE_MYMATH
#include "MathFunctions.h"
#endif

...
// const double outputValue = mysqrt(inputValue); 替换为一下代码
#ifdef USE_MYMATH
    const double outputValue = mysqrt(inputValue);
#else
    const double outputValue = sqrt(inputValue);
...

运行项目

D:\cprojects\Tutorial\cmake-build-debug\Tutorial.exe 25
inputValue is 25
Computing sqrt of 25 to be 13
Computing sqrt of 25 to be 7.46154
Computing sqrt of 25 to be 5.40603
Computing sqrt of 25 to be 5.01525
Computing sqrt of 25 to be 5.00002
Computing sqrt of 25 to be 5
Computing sqrt of 25 to be 5
Computing sqrt of 25 to be 5
Computing sqrt of 25 to be 5
Computing sqrt of 25 to be 5
outputValue is 5

Process finished with exit code 0

添加库的使用要求

使用要求可以更好地控制库或可执行文件的链接并包含行,同时还可以更好地控制CMake内部目标的传递属性。

Usage requirements allow for far better control over a library or executable’s link and include line while also giving more control over the transitive property of targets inside CMake

MathFunctions CMakeLists.txt

# 添加 MathFunctions 为库
add_library(MathFunctions mysqrt.cpp)

# 指出与我们链接的任何人都需要包含当前源目录
# INTERFACE 是指消费者需要的东西
target_include_directories(MathFunctions
        INTERFACE ${CMAKE_CURRENT_SOURCE_DIR}
        )

project CMakeLists.txt

...
if(USE_MYMATH)
    add_subdirectory(MathFunctions)
    list(APPEND EXTRA_LIBS MathFunctions)
    #库已经包含依赖,所以可以移除下面注释代码
    #list(APPEND EXTRA_INCLUDES "${PROJECT_SOURCE_DIR}/MathFunctions")
endif()
...

target_include_directories(Tutorial PUBLIC
        "${PROJECT_BINARY_DIR}"
        #库已经包含依赖,所以可以移除下面注释代码
        #${EXTRA_INCLUDES}
        )

运行项目

D:\cprojects\Tutorial\cmake-build-debug\Tutorial.exe 25
inputValue is 25
Computing sqrt of 25 to be 13
Computing sqrt of 25 to be 7.46154
Computing sqrt of 25 to be 5.40603
Computing sqrt of 25 to be 5.01525
Computing sqrt of 25 to be 5.00002
Computing sqrt of 25 to be 5
Computing sqrt of 25 to be 5
Computing sqrt of 25 to be 5
Computing sqrt of 25 to be 5
Computing sqrt of 25 to be 5
outputValue is 5

Process finished with exit code 0

相关资源

本文使用 mdnice 排版