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

2020-10-17 15:32:14 蜻蜓队长

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) 复制代码

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
复制代码

相关文档
cmake_minimum_required
set
project
add_executable

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

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 "${PROJECT_BINARY_DIR}") 复制代码

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
复制代码

相关文档
configure_file
target_include_directories

添加一个库

  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
复制代码

相关文档
add_subdirectory
target_link_libraries
option
list

添加库的使用要求

使用要求可以更好地控制库或可执行文件的链接并包含行,同时还可以更好地控制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
复制代码

相关资源

Cmake wiki
Cmake 文档
Cmake 教程
github

本文使用 mdnice 排版

以上内容来自于网络,如有侵权联系即删除
相关文章

上一篇: Picasso 源码 commit 日记(2):如何分发和取消下载任务?

下一篇: 错误的ViewPager用法(填坑):ViewPager2做了什么?

客服紫薇:15852074331
在线咨询
客户经理