Cmake·

[#3][Special Variables][A菌严肃的CMake手记]

美式A菌

美式A菌

85 0

Intro

  • 上一篇我们学习了三种描述项目结构的API
  • 开讲之前呢,我们先来复习一下
// 指定CMake项目最低版本
cmake_minimum_required(VERSION 3.10)
// 为项目命名
project(ACM_1)
// 为项目添加可执行文件
add_executable(ACM_1 main.cxx)

Q? & A!

  • Q: 这篇A菌要介绍些什么呢?
    • 本篇围绕几个环境变量(内置变量常常以CMAKE_开头)。
    • 如何描述项目中存有的.h头文件呢?
    • 如何设置变量并替换进代码 ?

开始

Step1: 指定C++标准库版本

  • 为什么要指定版本呢?
    • A菌机器上安装的环境为C99,B菌为C11,C菌为....
    • 环境不同但代码相同,一定会有问题。
    • 那么A菌在使用C++11API的时候呢,在CMake文件中描述一下。
    • 这样可以告知CMake我们使用的标准库版本,让CMake为我们正确的构建代码。
    • 亦或是对代码结构进行约束的作用。

// main.cpp
// 这些都是标准库,标准库可以理解成 官方提供的API
#include <cmath> // 提供数学函数
#include <cstdlib> // 提供通用工具函数
#include <iostream> // 提供输入输出流功能。
#include <string> // 提供字符串处理功能

// main 函数是程序的入口点
// argc 是命令行参数的数量
// argv 是命令行参数的数组
int main(int argc, char* argv[])
{
// 检查命令行参数的数量。如果参数少于 2 个(即没有提供数字),则输出使用说明并返回 1,表示错误。
if (argc < 2) {
std::cout << "Usage: " << argv[0] << " number" << std::endl;
return 1;
}
// 将命令行参数转换为 `double` 类型的数字。
// const double inputValue = atof(argv[1]);
const double inputValue = std::stod(argv[1]);
// 计算输入值的平方根,并输出结果。程序返回 0,表示成功。
const double outputValue = sqrt(inputValue);
std::cout << "The square root of " << inputValue << " is " << outputValue
<< std::endl;
return 0;
}
  • 首先我们拿出上篇文章的计算平方根代码
  • 其次我们使用stof替换const double inputValue = atof(argv[1]);代码
# 在原基础的配置中加入如下配置
# CMAKE_CXX_STANDARD`用于指定项目所需的 C++ 标准版本。
# set(CMAKE_CXX_STANDARD 11)表示使用 C++11 标准。
# set 可以理解为为 CMake设置环境变量
set(CMAKE_CXX_STANDARD 11)

# CMAKE_CXX_STANDARD_REQUIRED用于指定所需的 C++ 标准是否是强制性的。
# 如果设置为 `True`,则编译器必须支持指定的 C++ 标准。
set(CMAKE_CXX_STANDARD_REQUIRED True)
  • 这里我们用到了3个API,含义已经在注释中了
    • CMAKE_CXX_STANDARD
    • CMAKE_CXX_STANDARD_REQUIRED
    • set

  • CMake中定义了很多环境变量例如(只列举一下,后续使用我们在详细解释)
    • CMAKE_BUILD_TYPE指定构建类型(如 Debug、Release)。
    • CMAKE_INSTALL_PREFIX指定安装路径。
    • CMAKE_SOURCE_DIR项目的根目录。
    • CMAKE_BINARY_DIR构建目录。

# 尝试编译
cd build
cmake ..
make

Step2: 描述头文件,替换变量

  • 这里我们先删除掉上面修改的代码,然后专心试用一些新的API
  • 考虑一个需求,在我们使用cli --version

  • 这里显示的3.30.5版本我们除了硬编码的方式,还有其他别的什么实现方式吗?
  • CMake为我们提供了变量替换功能(其实叫做指定配置文件啦),这样我们就可以使用名为configure_file的函式来让CMake构建程式时为我们替换其中的变量啦。

  • 首先创建头文件,其次定义两个常量。
  • ACM_1部分为CMakeLists中的project指定的项目名称。
  • _VERSION_MAJOR_VERSION_MINOR是固定写法啦。

  • 然后为project函数添加两个参数VERSION版本号
    • 1_VERSION_MAJOR
    • 0_VERSION_MINOR

  • 最后呢,我们使用configure_file来描述一下项目的配置文件替换。
  • main代码中引用我们的Config.h头描述文件。

注意哦: 在创建替换文件时我们使用.h.in这里引入的为.h

  • 加入代码输出一下试试看。

Step3: 构建项目

  • 那这里A菌在演示最后一次规范流程哦。
  • 后续构建项目打包时就以打包构建代替这个过成了喔。
# 创建build目录
mkdir build
# 切换工作目录为build目录
cd build
# 使用CMake生成项目打包配置
cmake ..
# 打包编译
make

Step4: 出错了喔

  • 编译器说: 我找不到代码中包含的Config.h文件。

如何解决这个问题呢?

  • 这里CMake又提供给我们一个名为target_include_directories的API。
  • 用于指定目标的包含目录,使编译器能够找到头文件。

  • 添加target_include_directories(ACM_1 PUBLIC "${PROJECT_BINARY_DIR}")配置,我们来帮编译器解除问题。
  • PROJECT_BINARY_DIR是什么呢?
    • 是CMake里自带的环境变量。
    • messageprint的意思,我们打印出来,看看是什么内容呢。

  • 再来。
  • 这次打印出了PROJECT_BINARY_DIR的路径,并且编译过程很顺利。
  • 运行二进制程式,输出了版本号。

总结

  • CMAKE_CXX_STANDARD
  • CMAKE_CXX_STANDARD_REQUIRED
  • set
  • project(NAME VERSION x.x.x)
  • configure_file()
  • target_include_directories()
  • message

你能否回忆起以上内容都是什么含义和功用呢?如果有问题的话要好好回顾一下哦。实在不理解也可以留言喔。 下面附上代码

Code

  • CMakeLists.txt
cmake_minimum_required(VERSION 3.10)
project(ACM_1 VERSION 1.0)
add_executable(ACM_1 main.cxx)
configure_file(Config.h.in Config.h)
target_include_directories(ACM_1 PUBLIC "${PROJECT_BINARY_DIR}")
message("CMAKE_BINARY_DIR: ${PROJECT_BINARY_DIR}")
  • Config.h.in
// the configured options and settings for Tutorial
#define ACM_1_VERSION_MAJOR @ACM_1_VERSION_MAJOR@
#define ACM_1_VERSION_MINOR @ACM_1_VERSION_MINOR@
  • main.cxx
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <string>
#include "Config.h"

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

  const double inputValue = atof(argv[1]);

  const double outputValue = sqrt(inputValue);
  std::cout << "The square root of " << inputValue << " is " << outputValue
            << std::endl;
  return 0;
}

所属系列

从当前文章继续阅读它所在合集中的前后内容。

A菌严肃的CMake手记 第 3 / 13 篇
查看合集

我也是從零開始學習CMAKE這個軟體

相关文章

优先推荐同专题、同标签和同作者内容,补足热门文章。

评论 0

登录 后参与评论

评论

成为第一个评论的人