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

【C++】LLVM-mingw + VSCode:Windows 开发攻略

LLVM-mingw 是一个基于 LLVM 项目的开源工具链,用于在类 Unix 系统(如 Linux 或 macOS)上为 Windows 平台交叉编译应用程序,它结合了 LLVM 编译器基础设施(包括 Clang C/C++/Objective-C 编译器和 LLD 链接器,用以替代传统的 GNU 编译器 GCC)以及 MinGW-w64 运行时库(提供 Windows 平台的 API 头文件和导入库,支持 32 位和 64 位 Windows 应用程序开发)。


安装与配置 LLVM-mingw

1. 下载 LLVM-mingw

LLVM-mingw 提供了预编译工具链,可在以下地址获取:

  • MinGW-w64 官网下载
  • LLVM-mingw GitHub Releases

推荐下载文件 llvm-mingw-20250826-ucrt-x86_64.zip,并将其解压至:

C:\Development\llvm-mingw
  • 20250826:发布日期,格式为 YYYYMMDD,表示版本时间(可选最新)
  • ucrt:使用 Windows Universal C Runtime(UCRT)作为 C 运行时
  • x86_64:架构类型,表示 64 位目标平台

解压后的文件夹结构应类似如下:

LICENSE.TXT          arm64ec-w64-mingw32  bin               include  python  x86_64-w64-mingw32
aarch64-w64-mingw32  armv7-w64-mingw32    i686-w64-mingw32  lib      share

2. 配置环境变量

检查现有工具

确保系统中未添加旧版 MinGW 或其他 GCC 工具链路径。

在 PowerShell 中执行以下命令,查看是否已安装:

gcc --version
clang++ --version

如果命令未找到,说明未配置环境变量或尚未安装。


添加到 PATH

C:\Development\llvm-mingw\bin 添加到 系统级环境变量 PATH

setx PATH "$($env:Path);C:\Development\llvm-mingw\bin" /M
  • setx PATH:修改系统 PATH。
  • "$($env:Path);...":保留原有 PATH 内容并追加新路径。
  • /M:设置为系统变量,对所有用户生效。

配置完成后,需重新打开 PowerShell 或 VSCode 终端使其生效。


临时生效(当前会话)

如果仅希望当前 PowerShell 会话立即可用,可以使用:

$env:Path += ";C:\Development\llvm-mingw\bin"

这种方式不会永久保存,窗口关闭后失效。


3. 测试编译和运行

创建测试文件

使用 PowerShell 一行命令创建 main.cpp

echo '#include <iostream>' > main.cpp; echo 'int main() { std::cout << "Hello, World!" << std::endl; return 0; }' >> main.cpp

编译 C++ 程序

使用 clang++ 编译生成 main.exe

clang++ main.cpp -o main.exe

运行测试程序

执行生成的程序:

./main.exe

输出结果应为:

Hello, World!

清理测试文件

如果不再需要测试文件,可以删除:

Remove-Item main.cpp, main.exe

可以按照之前的文风,将内容润色、分段和强化说明如下:


安装 VSCode 与插件

1. 下载与安装 VSCode

访问 Visual Studio Code 官网,下载安装最新版本的 VSCode。
安装过程中可保持默认设置即可,安装完成后即可打开编辑器。


2. 安装必要插件

在 VSCode 中按下 Ctrl + Shift + X 打开插件市场,然后搜索并安装以下插件:

  • Chinese (Simplified):提供 VSCode 界面汉化,使编辑器更易上手
  • CodeLLDB:利用 LLVM 工具链中的 lldb 对 C++ 程序进行调试,包括断点、变量查看和堆栈分析
  • Clangd:基于 LLVM 工具链中的 clangd 提供 C++ 代码智能提示、格式化、高亮、跳转等功能

运行与调试单文件

1. 创建项目文件夹

  1. 新建一个代码文件夹,例如 demo
  2. 使用 VSCode 打开该文件夹,作为工作区。

2. 配置编译任务(tasks.json)

在项目根目录下创建 .vscode\tasks.json 文件,用于定义 Clang++ 编译任务

{"version": "2.0.0","tasks": [{"type": "shell","label": "Build with Clang++","command": "clang++.exe","args": ["-g3","-O0","${file}","-o","${fileDirname}\\${fileBasenameNoExtension}.exe"],"options": {"cwd": "${fileDirname}"},"group": {"kind": "build","isDefault": true},"detail": "Compiler: Clang++ from LLVM-mingw"}]
}
  • -g3:生成调试信息
  • -O0:关闭优化,便于调试
  • ${file} / ${fileDirname} / ${fileBasenameNoExtension}:VSCode 内置变量,可支持任意源文件名
  • 配置完成后,按 Ctrl + Shift + B 可以快速编译当前文件

3. 配置调试任务(launch.json)

.vscode\launch.json 中配置 CodeLLDB 调试器

{"version": "0.2.0","configurations": [{"name": "Debug with CodeLLDB","type": "lldb","request": "launch","program": "${workspaceFolder}/${fileBasenameNoExtension}.exe","args": [],"cwd": "${workspaceFolder}","stopOnEntry": false,"preLaunchTask": "Build with Clang++","sourceLanguages": ["cpp"],"terminal": "integrated"}]
}
  • preLaunchTask:在启动调试前自动执行编译任务
  • ${fileBasenameNoExtension}.exe:与源文件同名的可执行文件
  • 调试时可直接按 F5 启动

4. 创建测试源文件

在项目根目录下创建 main.cpp(支持任意文件名):

#include <iostream>int main() {std::cout << "Hello, World!" << std::endl;return 0;
}

5. 编译与调试

  1. 在 VSCode 中打开 main.cpp
  2. F5 启动调试。
  3. 如果配置正确,调试器会编译源文件并运行程序,输出:
Hello, World!

至此,你已经完成了单文件的编译与调试环境配置。
可在此基础上,逐步扩展为多文件或 CMake 项目。

可以将你的章节内容润色、补充说明,并给出一个推荐的 .clang-format 配置示例:


代码格式化

1. 快捷格式化

安装 Clangd 后,你可以:

  • Ctrl + Alt + F 或右键选择 “Format Document” 进行手动格式化
  • 打开 设置Ctrl + ,),搜索 Format On Save 并勾选
    • 这样每次保存文件时,VSCode 会自动格式化代码

使用 Format On Save 可以保证代码风格统一,减少格式相关的提交差异。


2. 配置 .clang-format

Clangd 的格式化规则可通过项目根目录下的 .clang-format 文件进行定制。
下面给出一个适用于现代 C++ 项目的推荐配置:

# 语言: None, Cpp, Java, JavaScript, ObjC, Proto, TableGen, TextProto
Language: Cpp
# BasedOnStyle:	LLVM# 访问说明符(public、private等)的偏移
AccessModifierOffset: -4# 开括号(开圆括号、开尖括号、开方括号)后的对齐: Align, DontAlign, AlwaysBreak(总是在开括号后换行)
AlignAfterOpenBracket: Align# 连续赋值时,对齐所有等号
AlignConsecutiveAssignments: false# 连续声明时,对齐所有声明的变量名
AlignConsecutiveDeclarations: false# 右对齐逃脱换行(使用反斜杠换行)的反斜杠
AlignEscapedNewlines: Right# 水平对齐二元和三元表达式的操作数
AlignOperands: true# 对齐连续的尾随的注释
AlignTrailingComments: true# 不允许函数声明的所有参数在放在下一行
AllowAllParametersOfDeclarationOnNextLine: false# 不允许短的块放在同一行
AllowShortBlocksOnASingleLine: true# 允许短的case标签放在同一行
AllowShortCaseLabelsOnASingleLine: true# 允许短的函数放在同一行: None, InlineOnly(定义在类中), Empty(空函数), Inline(定义在类中,空函数), All
AllowShortFunctionsOnASingleLine: None# 允许短的if语句保持在同一行
AllowShortIfStatementsOnASingleLine: true# 允许短的循环保持在同一行
AllowShortLoopsOnASingleLine: true# 总是在返回类型后换行: None, All, TopLevel(顶级函数,不包括在类中的函数), 
# AllDefinitions(所有的定义,不包括声明), TopLevelDefinitions(所有的顶级函数的定义)
AlwaysBreakAfterReturnType: None# 总是在多行string字面量前换行
AlwaysBreakBeforeMultilineStrings: false# 总是在template声明后换行
AlwaysBreakTemplateDeclarations: true# false表示函数实参要么都在同一行,要么都各自一行
BinPackArguments: true# false表示所有形参要么都在同一行,要么都各自一行
BinPackParameters: true# 大括号换行,只有当BreakBeforeBraces设置为Custom时才有效
BraceWrapping:# class定义后面AfterClass: false# 控制语句后面AfterControlStatement: false# enum定义后面AfterEnum: false# 函数定义后面AfterFunction: false# 命名空间定义后面AfterNamespace: false# struct定义后面AfterStruct: false# union定义后面AfterUnion: false# extern之后AfterExternBlock: false# catch之前BeforeCatch: false# else之前BeforeElse: false# 缩进大括号IndentBraces: false# 分离空函数SplitEmptyFunction: false# 分离空语句SplitEmptyRecord: false# 分离空命名空间SplitEmptyNamespace: false# 在二元运算符前换行: None(在操作符后换行), NonAssignment(在非赋值的操作符前换行), All(在操作符前换行)
BreakBeforeBinaryOperators: NonAssignment# 在大括号前换行: Attach(始终将大括号附加到周围的上下文), Linux(除函数、命名空间和类定义,与Attach类似), 
#   Mozilla(除枚举、函数、记录定义,与Attach类似), Stroustrup(除函数定义、catch、else,与Attach类似), 
#   Allman(总是在大括号前换行), GNU(总是在大括号前换行,并对于控制语句的大括号增加额外的缩进), WebKit(在函数前换行), Custom
#   注:这里认为语句块也属于函数
BreakBeforeBraces: Custom# 在三元运算符前换行
BreakBeforeTernaryOperators: false# 在构造函数的初始化列表的冒号后换行
BreakConstructorInitializers: AfterColon#BreakInheritanceList: AfterColonBreakStringLiterals: false# 每行字符的限制,0表示没有限制
ColumnLimit: 0CompactNamespaces: true# 构造函数的初始化列表要么都在同一行,要么都各自一行
ConstructorInitializerAllOnOneLineOrOnePerLine: false# 构造函数的初始化列表的缩进宽度
ConstructorInitializerIndentWidth: 4# 延续的行的缩进宽度
ContinuationIndentWidth: 4# 去除C++11的列表初始化的大括号{后和}前的空格
Cpp11BracedListStyle: true# 继承最常用的指针和引用的对齐方式
DerivePointerAlignment: false# 固定命名空间注释
FixNamespaceComments: true# 缩进case标签
IndentCaseLabels: falseIndentPPDirectives: None# 缩进宽度
IndentWidth: 4# 函数返回类型换行时,缩进函数声明或函数定义的函数名
IndentWrappedFunctionNames: false# 保留在块开始处的空行
KeepEmptyLinesAtTheStartOfBlocks: false# 连续空行的最大数量
MaxEmptyLinesToKeep: 1# 命名空间的缩进: None, Inner(缩进嵌套的命名空间中的内容), All
NamespaceIndentation: None# 指针和引用的对齐: Left, Right, Middle
PointerAlignment: Right# 允许重新排版注释
ReflowComments: true# 允许排序#include
SortIncludes: false# 允许排序 using 声明
SortUsingDeclarations: false# 在C风格类型转换后添加空格
SpaceAfterCStyleCast: false# 在Template 关键字后面添加空格
SpaceAfterTemplateKeyword: true# 在赋值运算符之前添加空格
SpaceBeforeAssignmentOperators: true# SpaceBeforeCpp11BracedList: true# SpaceBeforeCtorInitializerColon: true# SpaceBeforeInheritanceColon: true# 开圆括号之前添加一个空格: Never, ControlStatements, Always
SpaceBeforeParens: ControlStatements# SpaceBeforeRangeBasedForLoopColon: true# 在空的圆括号中添加空格
SpaceInEmptyParentheses: false# 在尾随的评论前添加的空格数(只适用于//)
SpacesBeforeTrailingComments: 1# 在尖括号的<后和>前添加空格
SpacesInAngles: false# 在C风格类型转换的括号中添加空格
SpacesInCStyleCastParentheses: false# 在容器(ObjC和JavaScript的数组和字典等)字面量中添加空格
SpacesInContainerLiterals: true# 在圆括号的(后和)前添加空格
SpacesInParentheses: false# 在方括号的[后和]前添加空格,lamda表达式和未指明大小的数组的声明不受影响
SpacesInSquareBrackets: false# 标准: Cpp03, Cpp11, Auto
Standard: Auto# tab宽度
TabWidth: 4# 使用tab字符: Never, ForIndentation, ForContinuationAndIndentation, Always
UseTab: Never

新建万能头文件(可选)

虽然 LLVM-mingw 基于 MinGW,但它只包含标准 C++ 内容,而不包括 GCC 的扩展特性。bits/stdc++.h 是 GCC 中的一个特有头文件,它并不是 C++ 标准库的一部分,因此在 LLVM-mingw 中默认并不可用。如果你希望在 LLVM-mingw 中使用该头文件,可以手动创建一个 bits/stdc++.h 并将其放置到工具链的 include 目录中。以下是详细的操作方法:


1. 创建 stdc++.h

在任意临时目录下新建文件 stdc++.h,内容可以如下(覆盖常用 C++ 标准库):

#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cfloat>
#include <climits>
#include <csetjmp>
#include <cstdarg>
#include <cstddef>
#include <cstdlib>#if __cplusplus >= 201103L
#include <cstdint>
#if __cplusplus < 201703L
#include <ciso646>
#endif
#endif// C++
// #include <bitset>
// #include <complex>
#include <algorithm>
#include <bitset>
#include <functional>
#include <iterator>
#include <limits>
#include <memory>
#include <new>
#include <numeric>
#include <typeinfo>
#include <utility>#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <initializer_list>
#include <ratio>
#include <scoped_allocator>
#include <tuple>
#include <typeindex>
#include <type_traits>
#endif#if __cplusplus >= 201402L
#endif#if __cplusplus >= 201703L
#include <any>
// #include <execution>
#include <optional>
#include <variant>
#include <string_view>
#endif#if __cplusplus >= 202002L
#include <bit>
#include <compare>
#include <concepts>
#include <numbers>
#include <ranges>
#include <span>
#include <source_location>
#include <version>
#if __cpp_impl_coroutine
# include <coroutine>
#endif
#endif#if __cplusplus > 202002L
#include <expected>
#include <stdatomic.h>
#endif#if _GLIBCXX_HOSTED
// C
#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <cwchar>
#include <cwctype>#if __cplusplus >= 201103L
#include <cfenv>
#include <cinttypes>
#include <cstdint>
#include <cuchar>
#if __cplusplus < 201703L
#include <ccomplex>
#include <cstdalign>
#include <cstdbool>
#include <ctgmath>
#endif
#endif// C++
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>#if __cplusplus >= 201103L
#include <array>
#include <atomic>
#include <chrono>
#include <codecvt>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#endif#if __cplusplus >= 201402L
#include <shared_mutex>
#endif#if __cplusplus >= 201703L
#include <any>
#include <charconv>
// #include <execution>
#include <filesystem>
#include <optional>
#include <memory_resource>
#include <variant>
#endif#if __cplusplus >= 202002L
#include <barrier>
#include <bit>
#include <compare>
#include <concepts>
#include <format>
#include <latch>
#include <numbers>
#include <ranges>
#include <span>
#include <stop_token>
#include <semaphore>
#include <source_location>
#include <syncstream>
#include <version>
#endif#if __cplusplus > 202002L
#include <expected>
#include <flat_map>
#include <flat_set>
#include <generator>
#include <print>
#include <spanstream>
#include <stacktrace>
#include <stdatomic.h>
#include <stdfloat>
#endif#if __cplusplus > 202302L
#include <text_encoding>
#include <stdbit.h>
#include <stdckdint.h>
#endif#endif // HOSTED

注:可以根据需要裁剪头文件,只包含项目会用到的内容。


2. 放置到系统 include 路径

LLVM-mingw 的 include 路径通常在:

C:\Development\llvm-mingw\include\c++\v1\

你可以创建 bits 文件夹:

C:\Development\llvm-mingw\include\c++\v1\bits\

然后将 stdc++.h 放入该目录:

C:\Development\llvm-mingw\include\c++\v1\bits\stdc++.h

这样在你的代码中就可以:

#include <bits/stdc++.h>

总结

通过本教程,我们成功搭建了一个基于 LLVM-mingw 和 VSCode 的 Windows C++ 开发环境。使用 LLVM-mingw 工具链,不仅能享受 LLVM 编译器提供的高效优化和现代 C++ 支持,还能通过 MinGW-w64 提供的 Windows API 和运行时库实现无缝的 Windows 平台开发。

与传统的 Windows 开发工具链相比,LLVM-mingw 在跨平台开发、性能和编译速度上具有优势,同时结合 VSCode 的智能编辑功能和强大的插件支持,开发者可以在 Windows 平台上以更简洁、便捷的方式进行 C++ 开发。

整个开发流程涵盖了从环境配置、编译、调试到代码格式化等各个方面,确保了高效的开发和调试体验。通过配置 tasks.jsonlaunch.json,VSCode 能够自动化编译、调试任务,使得开发流程更加顺畅。此外,借助 Clangd 插件的代码智能提示、格式化功能,能够提高代码的可维护性和团队协作的效率。

总体来说,使用 LLVM-mingw 和 VSCode 可以帮助开发者在 Windows 平台上获得更加现代化、高效的 C++ 开发体验,尤其适合那些希望避免 Visual Studio 或 Cygwin 等重量级工具的开发者。


文章转载自:

http://UXc3Cu9N.dhmLL.cn
http://MSmn9jFS.dhmLL.cn
http://e2edJT7T.dhmLL.cn
http://mdzD2YKv.dhmLL.cn
http://jedPyKm2.dhmLL.cn
http://4PUZhepG.dhmLL.cn
http://Ng8vp1fc.dhmLL.cn
http://IpG4s6hF.dhmLL.cn
http://KDOciQXC.dhmLL.cn
http://6a06zNCQ.dhmLL.cn
http://qVYffUM2.dhmLL.cn
http://0lIhwUh6.dhmLL.cn
http://YU4ZrAcl.dhmLL.cn
http://hObsR6bW.dhmLL.cn
http://VzcDC5A0.dhmLL.cn
http://EcHFnADc.dhmLL.cn
http://adZNtz8m.dhmLL.cn
http://iocYZdiU.dhmLL.cn
http://vmWLWpGO.dhmLL.cn
http://0kr1cXQ7.dhmLL.cn
http://RW99Rfo2.dhmLL.cn
http://K4ntCcuY.dhmLL.cn
http://MXvETz7V.dhmLL.cn
http://L8iv0ibz.dhmLL.cn
http://o3sNvyJV.dhmLL.cn
http://D2GPxxJn.dhmLL.cn
http://JIjjoInX.dhmLL.cn
http://poxVQZX1.dhmLL.cn
http://LPD95WV5.dhmLL.cn
http://OWDhSvSu.dhmLL.cn
http://www.dtcms.com/a/375647.html

相关文章:

  • SRM系统有哪些核心功能?企业该如何科学选型?
  • LINUX99 centos8:网络 yum配置;shell:while [ $i -ne 5 ];do let i++ done
  • 【陇剑杯2025】密码复现(部分)
  • 漫谈《数字图像处理》之图像自适应阈值处理
  • Melon: 基于marker基因的三代宏基因组分类和定量软件
  • 水题记录1.7
  • JVM 执行引擎详解!
  • lua中 string.match返回值
  • 2025-安装集成环境XAMPP
  • 整体设计 之 绪 思维导图引擎 :思维价值链分层评估的 思维引导和提示词导航 之 引 认知系统 之6之 序 认知元架构 之1(豆包助手 之3)
  • 【教学类-07-10】20250909中3班破译电话号码(手写数字版、撕贴版、头像剪贴底纹版、抄写填空版)
  • 【初阶数据结构】算法复杂度
  • PowerBI 的双隐藏,我在QuickBI 里也找到了
  • AI赋能训诂学:解码古籍智能新纪元
  • 微服务雪崩问题与系统性防御方案
  • css3之grid布局
  • git config --global user.name指令报错时的解决方案
  • 三维仿真软件中渲染层面的孔洞优化方法调研
  • Linux学习-ARM汇编指令
  • 微软依旧稳定发挥,Windows 最新更新性能「开倒车」
  • 预录车辆号牌提示系统——车牌检测系统
  • --控制--
  • 明远智睿 H618 核心板:以硬核性能重塑多媒体智能终端新生态
  • FANUC发那科焊接机器人铝材焊接节气
  • 在python中使用mysql的方法
  • DriftingBlues: 4靶场渗透
  • Java基本数据类型
  • Ackley函数:优化算法领域的复杂试金石
  • ubuntu升级失败报错
  • 大数据存储域——Kafka实战经验总结