VS Code 编译 C++ 报 Exit code: -1 与 MinGW-w64 安装失败
结论
代码没有语法问题,日志反映的是两个相对独立的故障:
- VS Code 正在用
gcc.exe构建 C++ 文件。链接时没有自动加载 C++ 标准库,所以出现了大量undefined reference。这里应改用g++.exe。 - MSYS2 下载软件包时连接超时或速度过低,安装事务很可能没有完成。网络恢复后,需要重新更新并安装 UCRT64 工具链,然后检查
g++.exe是否可用。
Exit code: -1 是 VS Code 任务终止时显示的结果。判断故障原因应看前面的链接错误:
undefined reference to `std::cout'
undefined reference to `operator new(...)'
undefined reference to `__gxx_personality_seh0'
collect2.exe: error: ld returned 1 exit status
为什么会出现 undefined reference
日志中的构建命令是:
C:/msys64/ucrt64/bin/gcc.exe ... hell.cpp -o hell.exe
这里使用了 gcc.exe。
GCC 会根据 .cpp 扩展名把文件当成 C++ 源代码,因此语法检查和目标文件生成都可能成功。但由 gcc 驱动程序执行链接时,不会像 g++ 那样自动链接 C++ 标准库和相关运行库。
编译器可以识别 std::string、std::vector 和 std::cout,链接器却找不到这些符号的实现,于是报告大量 undefined reference。
C++ 程序应使用:
C:\msys64\ucrt64\bin\g++.exe
也可以为 gcc 手动添加 C++ 链接库,但通常没有必要。直接使用 g++ 更稳妥,也符合常见的配置方式。
MSYS2 下载错误是什么意思
日志中还有这些信息:
Connection timed out
Operation too slow
too many errors from mirror.msys2.org
它们表示 pacman 未能及时从 MSYS2 镜像下载软件包。可能的原因包括网络不稳定、镜像暂时不可用、代理或防火墙限制,或者连接该镜像的线路速度过低。
too many errors ... skipping for the remainder of this transaction 表示某个镜像连续失败后,pacman 在当前事务中暂时跳过了它。这不是编译器错误。
仅凭这些日志片段,无法确定整个工具链已经损坏,因为 pacman 后续仍可能从其他镜像成功下载。不过,日志显示多个镜像都失败了,这次安装事务很可能没有完成。编译输出又说明 gcc.exe 和 C++ 头文件已经存在,因此也可能是之前安装过部分组件,或者本次升级中途失败。
重新安装并检查工具链
打开开始菜单中的 MSYS2 UCRT64 终端。不要在普通 MSYS、MINGW32 或其他环境中混用这套命令。
先更新系统:
pacman -Syu
如果终端提示关闭窗口,请按提示操作。随后重新打开 MSYS2 UCRT64,再次执行:
pacman -Syu
更新完成后,重新安装 UCRT64 工具链:
pacman -S --needed mingw-w64-ucrt-x86_64-toolchain
如果下载仍然超时,可以尝试以下方法:
- 稍后重试,确认是否只是镜像临时故障。
- 换用更稳定的网络。
- 检查代理、防火墙或安全软件是否阻止了
pacman.exe。 - 按照 MSYS2 的镜像配置说明更换镜像,或调整镜像顺序。
- 如果连接能够建立,但总因速度过低而超时,可以在
/etc/pacman.conf的[options]部分临时加入:
DisableDownloadTimeout
这个配置只能取消低速超时判断,无法解决网络完全不可达的问题。安装结束后可以将其删除。
不要混用 /ucrt64、/mingw64 和其他环境的软件包。当前路径是 C:\msys64\ucrt64\bin,对应的软件包前缀应为:
mingw-w64-ucrt-x86_64-
验证安装是否完整
在 MSYS2 UCRT64 终端中运行:
pacman -Q mingw-w64-ucrt-x86_64-gcc
g++ --version
which g++
正常情况下,which g++ 应指向:
/ucrt64/bin/g++
还可以检查已安装软件包是否缺少文件:
pacman -Qkk mingw-w64-ucrt-x86_64-gcc
在 Windows PowerShell 或 cmd.exe 中执行:
where gcc
where g++
确认 VS Code 最终使用的是:
C:\msys64\ucrt64\bin\g++.exe
如果 where 返回了多套 GCC,请调整 PATH 的顺序,或者在 VS Code 配置中填写完整路径,以免选中旧版本或其他 MinGW 环境中的编译器。
先在终端直接测试
进入源文件所在目录,执行:
C:\msys64\ucrt64\bin\g++.exe -std=c++17 -g hell.cpp -o hell.exe
然后运行程序:
.\hell.exe
预期输出为:
Hello C++ World from VS Code and the C++ extension!
如果这条编译命令能够成功执行,说明工具链可以正常工作,接下来只需修正 VS Code 的构建任务配置。
修改 VS Code 的构建任务
当前任务名称是:
C/C++: gcc.exe build active file
可以重新选择 g++.exe,也可以直接修改项目中的 .vscode/tasks.json:
{
"version": "2.0.0",
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++.exe build active file",
"command": "C:\\msys64\\ucrt64\\bin\\g++.exe",
"args": [
"-fdiagnostics-color=always",
"-std=c++17",
"-g",
"${file}",
"-o",
"${fileDirname}\\${fileBasenameNoExtension}.exe"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
}
}
]
}
保存后执行 Terminal → Run Build Task,确认终端第一行显示:
C:/msys64/ucrt64/bin/g++.exe
不应再显示:
C:/msys64/ucrt64/bin/gcc.exe
如果命令面板中仍保留旧任务,可以运行 C/C++: Edit Configurations (UI),或者重新执行 C/C++: g++.exe build and debug active file,然后选择 UCRT64 目录中的 g++.exe。
保持 IntelliSense 配置一致
建议将 .vscode/c_cpp_properties.json 中的 compilerPath 也设为:
{
"configurations": [
{
"name": "Win32",
"compilerPath": "C:\\msys64\\ucrt64\\bin\\g++.exe",
"cppStandard": "c++17",
"intelliSenseMode": "windows-gcc-x64"
}
],
"version": 4
}
compilerPath 主要影响 IntelliSense、头文件搜索和代码提示。实际构建时使用哪个编译器,由 tasks.json 中的 command 决定。只修改 IntelliSense 配置,无法解决当前的链接错误。
程序代码
原代码不会导致这些链接错误。可以整理一下格式,并显式返回 0:
#include <iostream>
#include <string>
#include <vector>
using namespace std;
int main()
{
vector<string> msg {
"Hello",
"C++",
"World",
"from",
"VS Code",
"and the C++ extension!"
};
for (const string& word : msg)
{
cout << word << " ";
}
cout << endl;
return 0;
}
C++ 允许 main 在末尾隐式返回 0,所以原代码没有写 return 0; 并不是本次失败的原因。
用户名和项目路径中虽然包含西里尔字符,但日志显示编译器已经成功读取源文件并生成临时目标文件。因此,这次错误也不是由非 ASCII 路径直接引起的。
建议先让 pacman 完成 UCRT64 工具链的安装,再确认 g++ --version 能够正常执行,最后将 VS Code 的构建命令从 gcc.exe 改为 g++.exe。
备注:内容仅供参考。
