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

CMake构建和调试简单程序(windows)

一 构建简单程序

1 创建项目文件结构

新建一个项目文件夹(例如 HelloWorld),内部包含两个核心文件:

  • 源代码文件:main.cpp
  • CMake配置文件:CMakeLists.txt(告诉CMake如何构建项目)

文件结构如下:

2 编写源代码

#include <cmath>
#include <cstdlib>
#include <iostream>
#include <string>int main(int argc, char* argv[])
{if (argc < 2) {std::cout << "Usage: " << argv[0] << " number" << std::endl;return 1;}// 将输入转为double类型const double inputValue = atof(argv[1]);// 计算输入数据的平方根const double outputValue = sqrt(inputValue);std::cout << "The square root of " << inputValue<< " is " << outputValue<< std::endl;return 0;
}

3 编写 CMake 配置文件(CMakeLists.txt)

# CMakeLists.txt
cmake_minimum_required(VERSION 3.15)# set the project name
project(Hello)# add the executable
add_executable(Hello main.cpp)

4 执行 CMake 生成构建文件(外部构建推荐)

CMake 的核心作用是 根据配置文件生成对应平台的构建文件(例如 Linux 的 Makefile、Windows 的 Visual Studio 解决方案、macOS 的 Xcode 项目)。
推荐使用「外部构建」(在源文件外创建 build 文件夹),避免构建文件污染源目录。

步骤如下,进入到HelloWorld文件夹,打开cmd,输入以下命令

mkdir build  # 创建构建目录
cd build     # 进入构建目录
cmake .. -G "Visual Studio 17 2022"     # 在 build 目录下,执行 cmake ..(.. 表示引用上级目录 # 的 CMakeLists.txt),对应 VS2022

执行完上述命令后,会生成SLN(Visual Studio 解决方案)和vcxproj(项目文件)bulid文件夹内容如下:

CMake 在 Windows 生成 Visual Studio 解决方案时,会自动创建 3 个辅助目标(非可执行):

  • ALL_BUILD:编译解决方案中所有的项目(包括可执行目标 + 其他辅助目标);
  • ZERO_CHECK:检查 CMakeLists.txt 是否有修改,若修改则自动重新生成构建文件;
  • INSTALL:(可选)用于安装编译产物(如将可执行文件复制到指定目录)。

这三个目标都没有实际的可执行代码,仅用于 “管理构建流程”,因此无法作为调试入口 —— 调试必须指向写的可执行目标(比如 hello,对应 hello.exe)。

5 编译项目(生成可执行文件)

根据步骤 4 生成的构建文件,执行编译命令:

1 使用vs2022,直接打开 build 目录下的 HelloWorld.sln,在 Visual Studio 中点击「生成」→「生成解决方案」

2 使用cmd,命令如下

cmake --build .  # --build 指定编译生成的文件存放目录(包括可执行文件) . 表示存放到当前目录

6 运行程序

编译成功后,cd到可执行文件所在的目录,执行

.\hello 5   # 5是输入数字,

关键说明:

执行 CMake 生成构建文件的阶段不会调试源文件中的代码,甚至不会接触到源文件的代码逻辑 —— 这个阶段的核心作用是「根据 CMakeLists.txt 配置规则,生成对应平台的构建脚本(如 Linux 的 Makefile、Windows 的 Visual Studio 解决方案)」,本质是「搭建编译流程的框架」,而非「执行或编译代码」。

完整流程:

CMake 生成构建文件 → 编译生成可执行文件(需开启 Debug 模式) → 用调试工具(GDB/VS 调试器等)加载可执行文件并调试代码

1. CMake 生成构建文件阶段:完全不检查代码错误

这个阶段的核心是 “解析 CMakeLists.txt 的配置规则”,比如确认 “要编译的源文件路径是否存在”“指定的构建类型(Debug/Release)是否合法”,但不会读取源文件(如 main.cpp)的具体代码内容—— 哪怕代码里有明显的语法错误(比如把 std::cout 写成 std:cout),CMake 也完全感知不到,照样能生成构建文件(如 Makefile、VS 解决方案)。

举个例子:如果 main.cpp 里写了 std:cout << "Hello"(少了一个冒号,语法错误),执行 cmake .. 时依然会成功生成 Makefile,因为 CMake 只关心 “有 main.cpp 这个文件”,不关心文件里写了什么。

2. 编译生成可执行文件阶段:会检查语法错误,发现错误会报错

当执行 make(Linux/macOS)或在 VS 中点击 “生成” 时,编译器(如 GCC、Clang、MSVC)会逐行解析源文件的代码,此时会严格检查代码的 “语法正确性” 和 “基础编译规则”,常见错误都会被发现并报错:

  • 语法错误:比如少分号、括号不匹配、关键字拼写错误(如 int 写成 Int);
  • 编译规则错误:比如变量未定义、函数参数不匹配、头文件未包含(如用了 std::cout 却没写 #include <iostream>);
  • 类型错误:比如把字符串赋值给整型变量、函数返回值类型不匹配等。

需要注意的是,编译阶段只能检查 “语法 / 编译规则错误”,无法发现 “逻辑错误”

3. 加载可执行文件

调试工具会读取源文件的代码、设置断点、单步执行等,检查逻辑错误。

二 调试CMake构建的简单程序

在使用 CMake 构建的项目中调试源代码,核心是生成带调试信息的可执行文件,再通过对应平台的调试工具(如 GDB、LLDB、Visual Studio 调试器)进行断点、单步执行、变量查看等操作。

1 核心前提:配置 CMake 生成调试信息

调试的关键是让编译器生成「调试符号」(记录源代码与二进制文件的对应关系,帮助调试工具定位代码行、变量)。通过 CMake 指定 Debug 构建类型即可自动开启调试信息,无需手动写编译器参数(如 GCC 的 -g)。

方式 1:临时指定 Debug 模式(推荐,不污染配置文件)

在「生成构建文件」时,通过 -DCMAKE_BUILD_TYPE=Debug 临时设置,步骤如下:

cmake .. -G "Visual Studio 17 2022" -DCMAKE_BUILD_TYPE=Debug
方式 2:固定配置 Debug 模式(适合长期调试)

直接在 CMakeLists.txt 中添加配置,无需每次执行 CMake 时传参数:

# CMakeLists.txt
cmake_minimum_required(VERSION 3.15)# set the project name
project(Hello)# 固定设置为 Debug 模式,生成调试符号
set(CMAKE_BUILD_TYPE Debug)# add the executable
add_executable(Hello main.cpp)

之后正常执行 cmake .. 即可生成带调试信息的构建文件。

2 编译生成带调试信息的可执行文件

配置完成后,执行编译命令,生成包含调试符号的可执行文件(若代码有语法错误,此阶段会报错,需先修复):

  1. 打开 build 目录下的 HelloWorld.sln 解决方案;

  2. 顶部菜单栏选择「解决方案配置」为 Debug(确保是调试模式);

  3. 点击「生成」→「生成 hello」,或按 Ctrl+Shift+B,生成 hello.exe(路径:build/Debug/hello.exe

3 分平台进行代码调试

说明:

1 调试后修改的代码需要重新CMake吗

调试后仅修改代码逻辑(如修改 main.cpp 中的输出内容、调整变量值、修复逻辑错误等),不需要重新执行 CMake 生成构建文件;只需重新编译即可,编译工具会自动识别源文件的修改,无需重新生成构建文件。

核心原因:CMake 与编译工具的分工不同

  • CMake:仅负责「生成构建文件」(如 Makefile、Visual Studio 解决方案),本质是定义「编译规则」(比如 “要编译哪些文件”“用什么选项编译”“生成哪个可执行文件”)。一旦构建文件生成,只要编译规则不变,CMake 就无需再运行。

  • 编译工具(如 make、Visual Studio 编译器):根据 CMake 生成的「构建文件」,检测源文件的修改状态(通过文件修改时间判断),仅重新编译「被修改过的源文件」,最终生成可执行文件。

只有当修改了「影响构建配置的内容」(如新增源文件、修改 CMakeLists.txt、变更依赖库等)时,才需要重新执行 CMake。

2 调试时报错,无法启动程序“\build\x64\Debug\ALL_BUILD”

原因是:将 CMake 自动生成的 ALL_BUILD 目标设为了调试启动项,但 ALL_BUILD 并非可执行文件 —— 它是 CMake 生成的 “辅助构建目标”,仅用于触发所有项目的编译,本身没有可执行代码,因此无法启动调试。

解决方法:将 “实际可执行目标” 设为调试启动项。可执行目标:是在 CMakeLists.txt 中用 add_executable 定义的名称(比如 hello,图标是 “控制台应用” 或 “exe” 样式)。

http://www.xdnf.cn/news/1484965.html

相关文章:

  • YOLO11实战 第009期-基于yolo11的咖啡叶病害目标检测实战文档(yolo格式数据免费获取)
  • C++进阶——多态
  • 简述ajax、node.js、webpack、git
  • ncnn-Android-mediapipe_hand 踩坑部署实录
  • 【数据结构】经典 Leetcode 题
  • Java安全体系深度研究:技术演进与攻防实践
  • 嵌入式Secure Boot安全启动详解
  • JSP到Tomcat特详细教程
  • C#中的托管资源与非托管资源介绍
  • Docker启动失败 Failed to start Docker Application Container Engine.
  • ZYNQ SDK软件在线调试
  • Flutter SDK 安装与国内镜像配置全流程(Windows / macOS / Linux)
  • HTML 中的 CSS 使用说明
  • 华为HCIP-Datacom-Core Technology H12-831 书籍目录
  • 一款没有任何限制的免费远程手机控制手机的软件简介
  • linux Kbuild详解关于fixdep、Q、quiet、escsq
  • k8s核心技术-Helm
  • 去中心化投票系统开发教程 第五章:测试与部署
  • AI工具全解析:智能编码、数据标注与模型训练平台
  • 文件上传之读取文件内容保存到ES
  • 【iOS】block复习
  • 【Python脚本系列】PyCryptodome库解决网盘内.m3u8视频文件无法播放的问题(三)
  • macOS中设置环境变量的各文件及作用域
  • web后端知识(php和python)——第一阶段
  • java面试中经常会问到的mysql问题有哪些(基础版)
  • Android studio的adb和终端的adb互相抢占端口
  • SpringCloud Alibaba微服务--Gateway使用
  • 【音视频】WebRTC P2P、SFU 和 MCU 架构
  • Hadoop(九)
  • TypeORM、Sequelize、Hibernate 的优缺点对比:新手常见 SQL 与 ORM 踩坑总结