back

教你配置 C 语言环境

通过 MSYS2 来管理你的环境

2025-08-30

luisleee


常见术语介绍

在开始前, 我们先分清几个基本概念:

编辑器:用于编写和修改源代码的软件工具. 它提供语法高亮、自动缩进等功能, 让代码更易读. 常见的有:

编译器:将人类可读的源代码转换为计算机可执行的机器代码的程序. C语言是编译型语言, 需要编译器处理.

集成开发环境 (IDE):集成了编辑器、编译器和调试器等工具的软件包, 提供一站式开发体验.

那这个教程的的目标是什么呢? 我们将通过 MSYS2 在你的 Windows 设备上安装你喜欢的我喜欢的 C 语言编译器和工具, 并且教给你它们的基本使用.

在之后的讲解里也会穿插有对术语的解释. 如果你对它们很熟悉, 可以跳过它们.

安装 MSYS2

MSYS2 是什么呢

MSYS2 是 Minimal SYstem 2 的缩写, 意为 "最小系统 2". 它旨在提供一个最精简、干净的基础运行环境, 只包含最必要的工具. 用户可以根据自己的具体需求, 从这个最小基础之上, 安装所需的开发工具链、库和应用程序. 它提供了一套基于 Unix 的工具集和包管理系统, 让开发者能够在 Windows 上获得类似 Linux 的开发体验. MSYS2 不是"万能工具", 而是专注于自己擅长的领域:为 Windows 提供原生开发环境.

MSYS2 的核心特点是:

MSYS2 填补了 Windows 平台上开源开发的空白, 为开发者提供了一个强大而灵活的环境. 它既保留了 Windows 系统的优势, 又引入了 Unix/Linux 开发环境的便利性, 是进行 C/C++ 等语言开发的优秀选择.

什么是终端
终端是一种用于与计算机系统进行文本交互的应用程序或设备. 它允许用户通过输入命令来执行操作 (如运行程序、管理文件等), 并接收系统的文本输出. 也就是命令行 (不要害怕!)

什么是 Unix
Unix 是一种多用户、多任务的操作系统, 由肯·汤普森(Ken Thompson)、丹尼斯·里奇(Dennis Ritchie)等人在 AT&T 贝尔实验室开发, 并于 1969 年首次推出. 它的设计哲学强调简洁、模块化以及 "一切皆文件" 的抽象理念, 对后续操作系统产生了深远影响. C 语言正是由丹尼斯·里奇在开发Unix过程中发明的. Unix 的大部分早期代码由 C 语言编写, 这不仅促进了 Unix 的可移植性和广泛传播, 也奠定了 C 语言作为系统编程和开源软件开发基石的地位.

什么是 GCC
GCC (GNU Compiler Collection) 是 GNU 项目开发的开源编译器套件, 支持 C、C++、Fortran、Ada 等多种编程语言. 它将源代码编译为可执行程序, 是许多开源项目和跨平台开发的核心工具.

什么是包管理系统
包管理系统是一种用于自动化软件安装、更新、配置和移除的工具. 它处理依赖关系, 确保软件环境的一致性和完整性. 有了它, 你就可以不必关心从哪里获取软件包, 安装在哪里, 需要安装什么依赖项了.

什么是依赖
在软件开发中, 依赖指的是一个组件(如项目、程序、库)需要另一个组件才能正常工作的情况. 比如你想用播放器看视频,播放器依赖于视频编解码器来翻译视频数据, 所以必须在安装播放器之前安装编解码器, 这样它才能正常工作.

MSYS2 和 MinGW

安装步骤

访问 MSYS2官网, 下载安装程序并运行. 安装包链接就在官网首页.

由于下载源在海外, 如果你觉得下载太慢, 也可以在中科大镜像下载安装包, 具体参照中科大镜像的帮助页面. 如果你对选择哪个架构有疑惑的话, 那么我猜你的电脑肯定是 x86_64 架构的.

什么是镜像
镜像是原始软件仓库或下载站点的完整副本. 建立镜像的主要目的是提升下载速度、增强可靠性并减轻主服务器压力. 用户从镜像站获取的文件与主站完全一致, 但通常能获得更快的网络连接, 特别适合网络受限的地区或环境.

什么是 x86_64 架构
x86_64(又称 x64 或 AMD64 )是一种广泛用于个人电脑、笔记本及服务器的 64 位处理器架构. 它是传统 32 位 x86 架构的 64 位扩展. 如今绝大多数现代计算机都采用此架构.

下载完成后双击开始安装. 官网的指引很清晰, 我在此处重复安装的注意事项:

请选择纯 ASCII 字符、无空格的安装路径. 安装路径

什么是 ASCII
ASCII(美国信息交换标准代码)是一种基于拉丁字母的字符编码标准, 共有 128 个字符编码, 是计算机文本存储和传输的基础. 你键盘上的英文字母和半角标点都是 ASCII 字符.

目录, 路径都是什么
所谓目录, 只是我们对文件夹的另一种叫法.
路径则像是一个地址, 告诉你浏览文件夹找到这个文件的方式. 比如说 D:\msys64\bin 的意思就是从 D 盘开始,进入 msys64 文件夹,再里面的一个叫做 bin 的文件(夹). 这里的反斜杠是路径的分隔符号

也就是说, 不要安装到 C:\我的\编程学习 或者 D:\msys 2\ 这种地方去

其他的安装选项都是无所谓的, 可以直接进入下一步.

安装过程中请耐心等待

安装结束后, 点击 "Finish" 完成安装

恭喜你, 安装已经完成了. 如果你勾选了 "Run MSYS2 now", 那么会弹出一个终端窗口

终端窗口

这样我们的第一阶段就完成了.

怎么使用 MSYS2

如前文所提到的, MSYS2 并不是单独一个软件, 而是一个类似 Linux 的基础运行环境. 我们所能直接接触到的, 就是它提供的终端. 终端窗口

MSYS2 其实提供了不止一个环境, 官方推荐使用 UCRT64 环境. 不同环境的区别我们在此先不提, 感兴趣的读者可以移步 MSYS2 官方文档.

如果你在安装时把它添加到了开始菜单, 那你可以在开始菜单里找到它

开始菜单里的 MSYS2

如果你没有在开始菜单里找到它, 你也能在刚才的安装路径里找到它. 比方说我的安装路径就是 C:\msys64\

安装路径里的 MSYS2

你可能看到了两个 ucrt64, 这是因为我没有显示文件扩展名. 它们其中一个只是一个图标, 另一个才是可执行程序.

在这里你就可以像在 Linux 系统里一样执行命令了. 你可能会说你不懂命令行, 但这其实没关系. 后面你一定会学会使用一些命令.

在 Windows Terminal 里使用 (可选)

你可能觉得这样打开太麻烦了, 在这里介绍一种在 Windows Terminal 里使用的方法.

什么是 Windows Terminal
微软开发的现代化终端应用, 支持多标签、分屏和多种Shell(如PowerShell、CMD及MSYS2), 提供更高效美观的命令行操作体验. 详见微软帮助页面

什么是Shell
Shell 是操作系统提供的命令行解释器, 它是用户与系统内核之间的桥梁. 当用户在终端中输入命令时, Shell 负责解析这些命令, 并调用相应的程序或系统功能来执行.

安装好之后, 打开它的设置界面, 配置终端

只需修改一处, 也就是"命令行"这一项, 剩下随意. 内容改为

C:/msys64/msys2_shell.cmd -defterm -here -no-start -ucrt64

这里我的安装目录是 C:/msys64, 请你把路径的前面修改成你自己的安装目录. 保存后就可以新建 msys2 终端而不是 cmd 或者 powershell 了.

在 Windows 11 里, 你可以右键文件管理器空白处, 在当前目录打开终端. 在终端中打开

如果你喜欢其他终端, 可以参考 MSYS2官方文档

在 VS Code 的终端里使用 (可选)

用 VS Code 的朋友可能会觉得单独打开一个 msys2 的终端太麻烦了, 为什么不能在 VS Code 自带的终端里打开呢?

对不熟悉 VS Code 的朋友: Ctrl+~ 可以打开内置的终端

打开 VS Code 的 settings.json 配置文件, 加入这么一段配置:

{
    "terminal.integrated.profiles.windows": {
        "MSYS2 UCRT": {
            "path": "cmd.exe",
            "args": [
                "/c",
                "C:\\msys64\\msys2_shell.cmd -defterm -here -no-start -ucrt64"
            ]
        }
    }
}

如果你不熟悉 JSON 文件的编辑或者找不到配置文件, 不妨问问 AI

这里我的安装目录是 C:/msys64, 请你把路径的前面修改成你自己的安装目录. 保存后就可以在 VS Code 里新建 msys2 终端了.

如果你喜欢其他 IDE/编辑器, 可以参考 MSYS2官方文档

安装开发工具

目前我们还只安装了一个 MSYS2 的基本系统, 开发工具我们还是一概没有安装的. 这一节我们来完成这些安装和配置.

注意: 以下的命令请在 MSYS2 的终端内执行
如果聪明的你按下 Win + R, 输入 cmd, 按下回车, 打开一个命令提示符窗口的话, 它大概不会认得 pacman 是什么.

使用自选镜像 (可选)

默认情况下, pacman 包管理器是从 msys2 的官方镜像源进行下载的, 但是网络连接有时可能比较差. 我们这里可以使用中科大源或者你喜欢的镜像来加速软件包的下载.

相关设置请参照中科大镜像的帮助页面.

其实 msys2 可能就在使用这个镜像源, 所以一般不配置也可以.

安装内容

基本来说, 你只需要安装一个 C 编译器就可以完成你的课业任务了. 但这样你就会错过很多对你大有裨益的工具了. 它们是调试器、构建工具、LSP、版本控制系统等等...

但在这里, 我们就先只安装编译器、调试器和构建工具了. 它们的名字是 gcc, gdbmake.

第一句话是不完全准确的. 一个完整的编译工具链远不止一个编译器, 它是一系列相互协作的工具集合. 当然, 编译器不只有 gcc 一家, 像前文提到的 clang, msvc 都是现代极其流行且强大的编译器. 其他工具也是一样, 我这里选择的都是最经典的, 最历史悠久的软件. 不仅仅是因为它们资历老, 更重要的是, 它们是自由软件运动(Free Software Movement)的基石与典范.

初识 pacman

我们将会使用 pacman 包管理器来安装所需的软件. 下面是一个对 pacman 基本使用方法的介绍.

对命令行新手的提示:

更新软件包目录并升级

pacman -Syu

搜索软件包

pacman -Ss

安装指定软件包 (假设要安装的软件包叫做 my-package)

pacman -S my-package

选项的含义:

卸载指定的软件包, 并同时删除其不再被其他软件所需的依赖包 (假设要卸载的软件包叫做 my-package)

pacman -Rs my-package

卸载指定的软件包, 并额外删除该软件的配置文件 (假设要卸载的软件包叫做 my-package)

pacman -Rns my-package

选项的含义:

这里建议每天在安装任何软件之前先用 pacman -Syu 选项更新一下本地的软件包. (它可能会更新自己, 使终端重启, 这时请不要恐慌.)

开始安装

其实上面我提到的工具, 安装一个 mingw-w64-ucrt-x86_64-toolchain 软件包就可以把它们一网打尽.

看看上一节的内容, 我们应该怎么做呢?

pacman -S mingw-w64-ucrt-x86_64-toolchain

敲下回车, 你大概会看到如下的场景:

:: There are 13 members in group mingw-w64-ucrt-x86_64-toolchain:
:: Repository ucrt64
   1) mingw-w64-ucrt-x86_64-binutils  2) mingw-w64-ucrt-x86_64-crt-git
   3) mingw-w64-ucrt-x86_64-gcc  4) mingw-w64-ucrt-x86_64-gdb
   5) mingw-w64-ucrt-x86_64-gdb-multiarch  6) mingw-w64-ucrt-x86_64-headers-git
   7) mingw-w64-ucrt-x86_64-libmangle-git  8) mingw-w64-ucrt-x86_64-libwinpthread
   9) mingw-w64-ucrt-x86_64-make  10) mingw-w64-ucrt-x86_64-pkgconf
   11) mingw-w64-ucrt-x86_64-tools-git  12) mingw-w64-ucrt-x86_64-winpthreads
   13) mingw-w64-ucrt-x86_64-winstorecompat-git

Enter a selection (default=all):

回车, 因为我们全要安装. 接下来大概是这样的

resolving dependencies...
looking for conflicting packages...

Packages (40) mingw-w64-ucrt-x86_64-bzip2-1.0.8-3  mingw-w64-ucrt-x86_64-expat-2.7.1-2
    mingw-w64-ucrt-x86_64-gcc-libs-15.1.0-5  mingw-w64-ucrt-x86_64-gettext-runtime-0.25-1
    mingw-w64-ucrt-x86_64-gmp-6.3.0-2  mingw-w64-ucrt-x86_64-isl-0.27-1
    mingw-w64-ucrt-x86_64-libffi-3.5.0-1  mingw-w64-ucrt-x86_64-libiconv-1.18-1
    mingw-w64-ucrt-x86_64-libsystre-1.0.2-1  mingw-w64-ucrt-x86_64-libtre-0.9.0-1
    mingw-w64-ucrt-x86_64-mpc-1.3.1-2  mingw-w64-ucrt-x86_64-mpdecimal-4.0.1-1
    mingw-w64-ucrt-x86_64-mpfr-4.2.2-1  mingw-w64-ucrt-x86_64-ncurses-6.5.20241228-3
    mingw-w64-ucrt-x86_64-openssl-3.5.0-1  mingw-w64-ucrt-x86_64-python-3.12.11-1
    mingw-w64-ucrt-x86_64-readline-8.2.013-1  mingw-w64-ucrt-x86_64-sqlite3-3.50.1-1
    mingw-w64-ucrt-x86_64-tcl-8.6.16-1  mingw-w64-ucrt-x86_64-termcap-1.3.1-7
    mingw-w64-ucrt-x86_64-tk-8.6.16-1  mingw-w64-ucrt-x86_64-tzdata-2025b-1
    mingw-w64-ucrt-x86_64-windows-default-manifest-6.4-4
    mingw-w64-ucrt-x86_64-xxhash-0.8.3-1  mingw-w64-ucrt-x86_64-xz-5.8.1-2
    mingw-w64-ucrt-x86_64-zlib-1.3.1-1  mingw-w64-ucrt-x86_64-zstd-1.5.7-1
    mingw-w64-ucrt-x86_64-binutils-2.44-4
    mingw-w64-ucrt-x86_64-crt-git-13.0.0.r21.gf5469ff36-1
    mingw-w64-ucrt-x86_64-gcc-15.1.0-5  mingw-w64-ucrt-x86_64-gdb-16.3-1
    mingw-w64-ucrt-x86_64-gdb-multiarch-16.3-1
    mingw-w64-ucrt-x86_64-headers-git-13.0.0.r21.gf5469ff36-1
    mingw-w64-ucrt-x86_64-libmangle-git-13.0.0.r21.gf5469ff36-1
    mingw-w64-ucrt-x86_64-libwinpthread-13.0.0.r21.gf5469ff36-1
    mingw-w64-ucrt-x86_64-make-4.4.1-3  mingw-w64-ucrt-x86_64-pkgconf-1~2.5.0-1
    mingw-w64-ucrt-x86_64-tools-git-13.0.0.r21.gf5469ff36-1
    mingw-w64-ucrt-x86_64-winpthreads-13.0.0.r21.gf5469ff36-1
    mingw-w64-ucrt-x86_64-winstorecompat-git-13.0.0.r21.gf5469ff36-1

Total Download Size:   122.33 MiB
Total Installed Size:  892.16 MiB

:: Proceed with installation? [Y/n]

回车, 静候佳音.

你可以用如下命令检验安装是否成功

gcc --version

它会给出当前 gcc 的版本.

如果你想了解更多软件包, 可以在这里查询它们的信息.

如何使用开发工具

到这里, 我们已经安装好开发工具链了, 接下来就该用用它们了.

首先, 让我们创建一个简单的C程序. 打开你喜欢的的文本编辑器 (Windows 记事本都可以), 输入以下代码并保存:

#include <studio.h>

int main() {
    printf("Hello Warld!\n")
    return 0;
}

我在这段代码里故意留了几处错误, 你能发现吗? 不能发现也没有问题, 编译器会替你找到它.

在和这个文件相同的路径下打开 msys2 终端, 运行命令:

gcc helloworld.c -o helloworld

什么叫在相同路径下打开
指在文件所在的目录中启动终端. 这样终端启动后的当前工作目录就是该文件所在的位置. 终端里你输入的命令的左边显示的就是终端当前的工作路径. 插入模式输入

~ 又是个什么路径
那是你的用户目录.

你可能会试错几次, 如果你没有改对我埋下的错误. 理想情况下, 编译器会什么也不输出并通过编译, 你将在目录下找到产生的可执行文件.

一旦出错, 你将会看到编译器的报错. 你可以根据它提供的错误信息修正你的代码. 有时编译器的错误信息让人如堕五里雾中, 这个时候你可以在网上搜索, 或者把你的问题和代码丢给你喜欢的 AI, 而不是只丢一句 "我的代码为什么报错了?" 给你的同学.

除了代码问题以外, 你可能会遇到的错误有:

如果这太难了, 我在这里给你提供了可以正确编译运行的代码:

#include <stdio.h>

int main() {
    printf("Hello Warld!\n");
    return 0;
}

假设你在这里已经成功编译了你的代码, 那么我们运行这一条命令就好了

./helloworld

"./" 是什么意思
"./" 表示当前所在的目录. 在 Shell 中, 直接输入程序名(如 helloworld)时, 系统默认只在 PATH 环境变量指定的目录中查找可执行文件, 而不会搜索当前目录. 使用 ./ 显式指明程序位于当前目录下.

什么是环境变量
环境变量是操作系统或 Shell 中用于存储配置信息和系统路径的键值对. 例如, PATH 是一个最重要的环境变量, 它定义了一系列目录路径. 当用户在终端中输入命令时, 系统会按照 PATH 中列出的目录顺序去查找对应的可执行程序. 这就是你的 shell 程序能找到 gcc 并运行的原因.

不出意外的话, 你会看到输出:

Hello Warld!

还是拼错了! 代码的错误不只有编译器可以检查的!

关于程序的错误

到这里你大概可以复制这个流程了吧. 祝你好运.

附A: 一些杂事

关于 cmd

你可能注意到了, 我的所有演示全是在 msys2 的终端里进行的. 为什么不能在 cmd 里运行呢?

你不妨打开 cmd, 敲下 gcc, 回车, 看看结果. 这是什么意思? 意思是你的电脑找不到 gcc 的可执行文件. 怎么办呢? 把 gcc 所在路径加入到 PATH 变量里就好了.

具体方法我就不讲了, 请你到别处查查.

这样可能会让你方便一点, 但也有可能造成问题: 假如你的 PATH 里有两个不同版本的 gcc 呢? 所以, 保持环境隔离还是有用的.

关于 VS Code 的 C/C++ 插件

你可能会觉得: 这个人怎么一直在命令行里敲敲敲啊, 为什么不用 VS Code 的那个插件, 点一下就行了呢?

但是你可能要失望了, 我不会在这里介绍了. 我为我自己辩解几句:

你不觉得这种方式很优雅吗? 命令行提供最直接的控制, 体现最精确的理解. 每一行命令都清晰揭示了背后的工具链、参数和依赖, 简洁却强大. 请直接和你的工具对话.

谢谢理解.

附B: 之后的路

受限于篇幅与精力, 我来点到为止地向你介绍一些好东西.

man

你认识 Linux 命令吗? 不会用怎么办? 没关系, 你可以用 man 命令来翻阅命令手册. 在 msys2 里面只需要用 pacman -S man-db 就可以安装.

试试看看 man ls? 看看 man gcc? 看看 man man?

多个源文件?

当你的程序大到一个地步了, 只用一个源文件怎么受得了? 那我要怎么编译它们呢? 很简单, 一个命令就能解决

gcc some_a.c some_b.c some_c.c -o output

make

你不觉得文件大起来多起来编译很慢, 输命令很麻烦吗? 试试 make. 写好一个 makefile 作为生成的规则放在你的项目目录下面, 只需要一个 make 命令就能生成你的项目! 它还会智能地仅编译改动过的文件, 节约你宝贵的编译时间.

顺带一提, make 内置了些默认的生成规则, 所以上面提到 helloworld 其实只用一个 make helloworld 就能搞定了.

gdb

编译器会帮你找到编译错误, 可是运行时错误呢? 有时候它们像魔鬼一样藏在你的代码里, 让你无从下手. 这时用下 gdb 吧, 它能够动态追踪和分析程序运行时的错误, 支持设置断点、单步执行、查看变量和内存状态. 当然前提是在编译程序的时候先插入调试符号.

像这样

gcc -g program.c -o program

然后就可以开始调试了

gdb ./program

至于调试器怎么用, 又是一门学问了.


剧终

back