当前位置: 首页 > article >正文

C++学习(十三)(构建系统,CMAKE)

构建系统是一组工具和实用程序,用于自动执行项目中的源代码文件的编译、链接和执行过程。构建系统的主要目标是管理编译过程的复杂性,并最终生成构建(可执行文件或二进制文件)。在 C++ (cpp) 中,一些常见的构建系统包括:

  • GNU Make:这是一个流行的构建系统,用于定义构建过程。它检查源文件的依赖关系和时间戳,以确定需要编译和链接哪些文件。Makefile

    代码示例:

    # Makefile
    CXX = g++
    CPPFLAGS = -Wall -std=c++11
    TARGET = HelloWorld
    
    all: $(TARGET)
    
    $(TARGET): main.cpp
        $(CXX) $(CPPFLAGS)main.cpp -o $(TARGET)
    
    clean:
        rm $(TARGET)
    
  • CMake:它是一个跨平台的构建系统,专注于定义项目依赖关系和管理构建环境。CMake 为不同的平台生成构建文件(如 Makefiles),并允许开发人员编写一次源代码,然后针对不同的目标平台进行编译。

    代码示例:

    # CMakeLists.txt
    cmake_minimum_required(VERSION 3.10)
    project(HelloWorld)
    
    set(CMAKE_CXX_STANDARD 11)
    
    add_executable(HelloWorld main.cpp)
  • Autotools:也称为 GNU 构建系统,由 GNU Autoconf、Automake 和 Libtool 工具组成,使开发人员能够跨不同的基于 Unix 的系统创建可移植软件。对于 C++ 项目,您需要创建具有特定规则的 , 文件,然后在终端中运行以下命令来构建项目:configure.acMakefile.am

    autoreconf --install
    ./configure
    make
    make install
  • SCons:此构建系统使用 Python 作为构建脚本,使其比 GNU Make 更具表现力。它还可以同时为多个平台和配置构建。

    代码示例:

    # SConstruct
    env = Environment()
    env.Program(target="HelloWorld", source=["main.cpp"])
  • Ninja:一个小型而专注的构建系统,它采用人类可读文本文件中指定的构建目标列表,并尽快构建它们。

    代码示例:

    # build.ninja
    rule cc
      command = g++ -c $in -o $out
    
    rule link
      command = g++ $in -o $out
    
    build main.o: cc main.cpp
    build HelloWorld: link main.o
      default HelloWorld

这些是 C++ 中一些流行的构建系统,每个系统都有自己的语法和功能。虽然 Make 被广泛使用,但 CMake 是一个跨平台的构建系统,可为 Make 或 Ninja 等其他构建系统生成构建文件。Autotools 适合创建便携式软件,SCons 利用 Python 作为其构建脚本,而 Ninja 专注于快速构建时间

我们可以用**“厨房自动化系统”**的比喻来理解构建系统的概念:


构建系统是什么?

想象你要做一道复杂大餐(比如佛跳墙),需要处理几十种食材、控制火候、按特定顺序烹饪。手动操作会累到崩溃,还容易出错。构建系统就像一套智能厨房机器人,它:

  1. 记住所有步骤(哪些食材要先处理,哪些要同时蒸煮)

  2. 自动检测变化(如果某个食材更新了,只重做相关步骤)

  3. 一键完成烹饪(不用手动盯着每个环节)


C++ 构建系统的作用

  1. 代替手动敲命令
    不用每次修改代码都手动输入 g++ -o main.cpp ...(就像不用自己切菜生火)。

  2. 智能跳过重复工作
    如果只改了一个文件,只重新编译这个文件,其他不变(类似只重切新到的葱,不重新炖汤)。

  3. 处理复杂依赖关系
    自动解决“文件A依赖文件B,文件B又依赖文件C”的问题(类似知道要先煮高汤才能做酱汁)。

  4. 生成最终成品
    把代码变成可执行文件(就像把食材变成菜品)。


以 GNU Make 为例

核心组成
  • Makefile:相当于菜谱,用文本文件定义:

    • 要做哪些菜(编译目标)

    • 每道菜的食材(源文件)和步骤(编译命令)

    • 食材之间的依赖关系(比如主菜需要先做好酱汁)

示例 Makefile

# 最终菜品:佛跳墙(可执行程序)
佛跳墙: 高汤.o 鲍鱼.o 海参.o  # 依赖的中间文件
    厨师机链接 -o 佛跳墙 高汤.o 鲍鱼.o 海参.o

高汤.o: 高汤.cpp 调料.h       # 高汤的食材和步骤
    厨师机编译 -c 高汤.cpp

鲍鱼.o: 鲍鱼.cpp 调料.h
    厨师机编译 -c 鲍鱼.cpp

clean:                      # 清理厨房(删除中间文件)
    洗碗机 rm *.o 佛跳墙
 
执行过程

$ make         # 机器人开始按菜谱做菜
$ make clean   # 机器人清理厨房(删除临时文件)
 

为什么需要构建系统?

场景手动操作问题构建系统解决方案
修改一个文件要重新编译所有文件 → 费时只编译改动文件 → 高效
多人协作每个人的编译命令可能不同 → 结果不一致统一流程 → 结果可靠
复杂项目(如Chrome)成千上万个文件 → 不可能手动管理自动化依赖和编译 → 可控

其他常见构建系统

  • CMake
    智能菜谱生成器,可以根据不同厨房(操作系统/编译器)自动生成对应的 Makefile

  • Bazel
    谷歌开发的“工业级厨房机器人”,适合超大型项目(如自动驾驶系统)。

  • Ninja
    追求极速的“闪电厨师”,编译速度极快。


一句话总结

构建系统是程序员的厨房机器人——你只需写菜谱(Makefile),它帮你搞定复杂烹饪流程(编译链接),省时省力不翻车! 🤖🍲

这段 CMake 代码的作用是创建一个 C++ 项目的构建配置,让 CMake 生成合适的编译文件(如 Makefile 或 Visual Studio 解决方案)。下面用通俗易懂的方式一步步解释:


1. 指定 CMake 版本

cmake_minimum_required(VERSION 3.0)
  • 这行代码的作用是确保 CMake 版本至少是 3.0,防止使用太旧的版本,避免不兼容问题。

2. 定义项目名称

 
project(MyProject)

  • 这行代码定义了项目的名称,这里项目叫 "MyProject"

3. 设置源码路径

 
set(SRC_DIR "${CMAKE_CURRENT_LIST_DIR}/src") set(SOURCES "${SRC_DIR}/main.cpp" "${SRC_DIR}/file1.cpp" "${SRC_DIR}/file2.cpp")

  • SRC_DIR 变量指定源码目录,假设 CMakeLists.txt 文件在 root 目录下,它就表示 root/src/
  • SOURCES 变量列出了所有的源码文件(main.cpp, file1.cpp, file2.cpp)。

4. 创建可执行文件

add_executable(${PROJECT_NAME} ${SOURCES})
  • add_executable() 这个命令告诉 CMake:
    • 生成一个 可执行文件MyProject)。
    • 使用 指定的源码文件 编译它。

5. 设置头文件路径

 
target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_LIST_DIR}/include")

  • 这行代码告诉编译器,头文件(.h.hpp 文件)存放在 include 目录下。
  • PRIVATE 说明这个目录只对当前目标(MyProject)可见,不会影响其他目标(如果有的话)。

6. 设置 C++ 标准

 
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 14 CXX_STANDARD_REQUIRED ON CXX_EXTENSIONS OFF )

这部分代码指定 C++ 版本,并设置相关编译选项:

  • CXX_STANDARD 14 → 代码会使用 C++14 语法。
  • CXX_STANDARD_REQUIRED ON必须使用 C++14,不允许降级到更低的标准。
  • CXX_EXTENSIONS OFF → 禁用编译器特有的扩展(比如 g++-std=gnu++14),确保代码符合标准的 C++14。

总结

这段 CMake 代码的作用是:

  1. 创建一个名为 "MyProject" 的 C++ 项目
  2. 设定源码目录 src/,并包含 main.cpp, file1.cpp, file2.cpp 作为源文件
  3. 告诉 CMake 生成一个可执行文件 "MyProject"
  4. 让编译器在 include/ 目录中查找头文件
  5. 确保使用 C++14 标准,并避免编译器特有扩展

💡 最终效果: 当你运行 cmake . 并执行 make(或在 IDE 里构建),CMake 会自动调用编译器,把 main.cpp, file1.cpp, file2.cpp 编译成可执行文件 MyProject 🎯。


📌 你可以试试运行这段 CMake

  1. 在一个空目录里创建以下结构:

     
    /MyProject ├── CMakeLists.txt ├── src/ │ ├── main.cpp │ ├── file1.cpp │ ├── file2.cpp ├── include/ │ ├── file1.h │ ├── file2.h

  2. 进入 MyProject 目录:

     
    cd MyProject mkdir build && cd build cmake .. make

  3. 运行生成的可执行文件:

     
    ./MyProject

这样你就能亲自体验这段 CMake 代码的作用啦!🚀


http://www.kler.cn/a/574319.html

相关文章:

  • 通用代码生成器正确的使用方法:电子表格
  • Uniapp 页面返回不刷新?两种方法防止 onShow 触发多次请求!
  • 极狐GitLab 正式发布安全版本17.9.1、17.8.4、17.7.6
  • 大模型——使用 Embedding 模型和向量数据库的 Spring AI RAG
  • sqlite3 c++ client选择; c++环境搭建 : abseil-cpp | fnc12/sqlite_orm
  • 【Day9】make/makeFile如何让项目构建自动化起飞
  • go语言设计模式-适配器模式
  • RV1126采集VI视频数据流
  • 自动任务:安卓与鸿蒙上的高效自动化助手
  • Mac 基于 Ollama 安装 DeepSeek-R1(蒸馏版本)、AnythingLLM 及使用体验
  • JavaEE Servlet02
  • docker目录挂载与卷映射的区别
  • 洛谷————B2056 求整数的和与均值
  • 【网络】实现电脑与笔记本电脑之间的直接网络连接
  • 双向选择排序算法
  • 文档处理控件Aspose.Total教程:使用 C# 将 Obsidian Markdown 转换为 OneNote
  • 无线可视挖耳勺适合老年人吗?无线可视挖耳勺操作简单又安全
  • WPS AI+office-ai的安装、使用
  • 3.6V-30V宽压输入降压同步IC内置MOS,电流4A/5A/6A,可以满足汽车应急电源,BMS电池,电池组USB口输出等储能应用
  • TTP/HTTPS、TCP/IP 协议、RPC、Socket 通信机制