Clang
llvm 安装
https://github.com/llvm/llvm-project/releases/ 安装 clang+llvm-21.1.4-x86_64-pc-windows-msvc 并将 clang 配置到环境变量中
llvm-mingw
https://github.com/mstorsjo/llvm-mingw/releases 安装 llvm-mingw-20240827-ucrt-x86_64
VSCode 配置 Clang
You have both the Microsoft C++ (cpptools) extension and clangd extension enabled. The Microsoft IntelliSense features conflict with clangd's code completion, diagnostics etc.
✅ 问题本质
你同时启用了两个 C++ 语言引擎:
- Microsoft C/C++ (cpptools):提供默认的 IntelliSense、补全、诊断。
- Clangd:基于 LLVM 的独立语言服务器,提供更精准的 Clang 语义分析。
👉 当两者同时启用时,它们会互相干扰,导致:
补全弹出两次
错误提示重复或冲突
跳转定义不准
占用更多内存和 CPU
clangd 的优势无法完全发挥
✅ 正确做法:禁用 Microsoft C/C++ 的 IntelliSense 功能,完全交给 clangd 处理
你可以选择以下 两种方案之一:
✅ 方案一(推荐):保留 Microsoft C/C++ 扩展,但关闭其 IntelliSense
这是最稳妥的方式,保留调试、构建等功能,只让 clangd 负责代码智能。
步骤:
- 打开 VSCode 设置(Ctrl+,)
- 搜索:C_Cpp.intelliSenseEngine
- 将其设置为:disabled
或者在 settings.json 中添加:
json
{
"C_Cpp.intelliSenseEngine": "disabled",
"C_Cpp.errorSquiggles": "Disabled",
"C_Cpp.autocomplete": "Disabled"
}
✅ 这样做后:
clangd 负责代码补全、错误提示、跳转
Microsoft 扩展仍负责调试(launch.json)、与 GDB/LLDB 交互
两者分工明确,无冲突
✅ 方案二:完全禁用 Microsoft C/C++ 扩展(仅使用 clangd)
如果你不需要 Microsoft 扩展的调试功能(比如你用命令行调试),可以彻底禁用它。
步骤:
- 在 VSCode 左侧扩展面板中找到:
C/C++ by Microsoft - 右键 → Disable (Workspace) 或 Disable
- 确保只启用:
clangd by LLVM
Shader languages support for VS Code
其他非语言类插件(如 GitLens)
⚠️ 注意:如果你还想用 launch.json 调试程序,不要完全禁用 Microsoft C/C++ 扩展,否则调试会失效。
📌 推荐配置总结(.vscode/settings.json)
json
{
// 让 clangd 接管语言智能
"C_Cpp.intelliSenseEngine": "disabled",
"C_Cpp.errorSquiggles": "Disabled",
"C_Cpp.autocomplete": "Disabled",
// 使用 clangd 格式化
"editor.defaultFormatter": "llvm-vs-code-extensions.vscode-clangd",
"editor.formatOnSave": true,
// clangd 启动参数
"clangd.arguments": [
"--background-index",
"--suggest-missing-includes",
"--clang-tidy",
"--header-insertion=never" // 避免自动插入头文件
]
}
✅ 验证是否生效
- 重启 VSCode
- 打开一个 .cpp 文件
- 观察底部状态栏是否有 clangd: Idle 或 clangd: Ready
- 输入代码,看是否只有 一组 补全提示(而不是两组)
- 把鼠标悬停在一个函数上,看提示是否来自 Clang(通常更详细)
💡 为什么推荐 clangd?
功能 clangd 优势
错误提示 更清晰、更接近编译器实际报错
补全精度 基于完整语义分析,更准确
重构支持 支持重命名、提取函数等
Clang-Tidy 集成 自动静态分析,发现潜在 bug
一致性 与你使用的 clang++ 编译器保持一致
✅ 最终建议
✔️ 保留 Microsoft C/C++ 扩展
✔️ 设置 "C_Cpp.intelliSenseEngine": "disabled"
✔️ 让 clangd 提供智能感知
✔️ 用 compile_commands.json 确保 clangd 理解你的项目
这样既能享受 clangd 的强大功能,又能使用 Microsoft 扩展的调试能力,完美协同。
如果你现在打开一个 C++ 文件,发现还有问题(比如红色波浪线不断),可以贴一下截图或描述现象,我可以帮你进一步诊断。祝你打造一个清爽高效的 OpenGL 开发环境!💻✨
Scons 配置
gcc
import os
from SCons.Environment import Environment
from SCons.Script import EnsureSConsVersion, EnsurePythonVersion
EnsureSConsVersion(4, 0)
EnsurePythonVersion(3, 8)
env = Environment(tools=['mingw'], CXX='x86_64-w64-mingw32-g++')
env.Program("main", "main.cpp")
clang
env = Environment(tools=['mingw', 'clang', 'clangxx'], CC='clang', CXX='clang++')
program = env.Program('helloworld', 'main.cpp')
env.Append(CXXFLAGS=['-std=c++17'])
env.Append(CXXFLAGS=['-Wall', '-Wextra'])
clang 交叉编译
在 Linux 上编译 Windows 可执行文件
Code Runner
在 settings.json 中,添加 code-runner.executorMap 设置,然后就可以对不同的语言设置自定义的运行逻辑了
在 .vscode/settings.json 中配置
{
"code-runner.executorMap": {
"cpp": "cd $dir && scons -Q && main.exe"
}
}
参考
{
"javascript": "node",
"java": "cd $dir && javac $fileName && java $fileNameWithoutExt",
"c": "cd $dir && gcc $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
"zig": "zig run",
"cpp": "cd $dir && g++ $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
"objective-c": "cd $dir && gcc -framework Cocoa $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
"php": "php",
"python": "python -u",
"perl": "perl",
"perl6": "perl6",
"ruby": "ruby",
"go": "go run",
"lua": "lua",
"groovy": "groovy",
"powershell": "powershell -ExecutionPolicy ByPass -File",
"bat": "cmd /c",
"shellscript": "bash",
"fsharp": "fsi",
"csharp": "scriptcs",
"vbscript": "cscript //Nologo",
"typescript": "ts-node",
"coffeescript": "coffee",
"scala": "scala",
"swift": "swift",
"julia": "julia",
"crystal": "crystal",
"ocaml": "ocaml",
"r": "Rscript",
"applescript": "osascript",
"clojure": "lein exec",
"haxe": "haxe --cwd $dirWithoutTrailingSlash --run $fileNameWithoutExt",
"rust": "cd $dir && rustc $fileName && $dir$fileNameWithoutExt",
"racket": "racket",
"scheme": "csi -script",
"ahk": "autohotkey",
"autoit": "autoit3",
"dart": "dart",
"pascal": "cd $dir && fpc $fileName && $dir$fileNameWithoutExt",
"d": "cd $dir && dmd $fileName && $dir$fileNameWithoutExt",
"haskell": "runghc",
"nim": "nim compile --verbosity:0 --hints:off --run",
"lisp": "sbcl --script",
"kit": "kitc --run",
"v": "v run",
"sass": "sass --style expanded",
"scss": "scss --style expanded",
"less": "cd $dir && lessc $fileName $fileNameWithoutExt.css",
"FortranFreeForm": "cd $dir && gfortran $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
"fortran-modern": "cd $dir && gfortran $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
"fortran_fixed-form": "cd $dir && gfortran $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
"fortran": "cd $dir && gfortran $fileName -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
"sml": "cd $dir && sml $fileName",
"mojo": "mojo run",
"erlang": "escript",
"spwn": "spwn build",
"pkl": "cd $dir && pkl eval -f yaml $fileName -o $fileNameWithoutExt.yaml",
"gleam": "gleam run -m $fileNameWithoutExt"
}
如果你想自定义代码运行逻辑,你可以用到下面的一些变量,在运行时,Code Runner会把相应的变量进行替换:
$workspaceRoot
$dir
$dirWithoutTrailingSlash
$fullFileName
$fileName
$fileNameWithoutExt
使用 QuickJS-Windows-Build-master
使用到的环境
PS E:\4.4> clang --version
clang version 21.1.5 (https://github.com/llvm/llvm-project.git 8e2cd28cd4ba46613a46467b0c91b1cabead26cd)
Target: x86_64-w64-windows-gnu
Thread model: posix
InstalledDir: D:/App/llvm-mingw/bin
Configuration file: D:/App/llvm-mingw/bin/x86_64-w64-windows-gnu.cfg
正确构建流程(必须两阶段)
QuickJS 的构建是 自举(bootstrap)过程:
第一阶段:用主机(host)C 编译器构建一个 原生 qjsc 工具
第二阶段:用这个 qjsc 将 repl.js 和 qjscalc.js 编译成 C 文件
第三阶段:将生成的 C 文件加入最终链接
// 在 qjsc.c 开头添加(临时)
ifndef CONFIG_VERSION
define CONFIG_VERSION "unknown"
endif
第 1 步:构建 host-qjsc(原生可执行)
# -D "CONFIG_VERSION=\"2025-11-14\"" `
# 编译 host-qjsc(不依赖 repl/qjscalc)
clang qjsc.c quickjs.c libregexp.c libbf.c cutils.c libunicode.c quickjs-libc.c `
-D_WIN64 -D_GNU_SOURCE -D__USE_MINGW_ANSI_STDIO -DCONFIG_BIGNUM `
-lwinpthread -lm `
'-Wl,-subsystem,console' `
-o host-qjsc.exe
无法定位程序输入点 clock_gettime64 于动态链接库D:\Tmp\Quickjs-Windows-Build-master\host-qjsc.exe 上
拷贝 bin/*.dll 到 host-qjsc.exe 路径下
第 2 步:用 host-qjsc 生成 C 文件
# .\host-qjsc.exe -c -o testjs.c -m testjs.js
.\host-qjsc.exe -c -o repl.c -m repl.js
.\host-qjsc.exe -fbignum -c -o qjscalc.c qjscalc.js
第 3 步:编译最终 qjs.exe(包含生成的 C 文件)
clang qjs.c repl.c qjscalc.c quickjs.c libregexp.c libbf.c cutils.c libunicode.c quickjs-libc.c `
-D_GNU_SOURCE -D__USE_MINGW_ANSI_STDIO -DCONFIG_BIGNUM `
-lwinpthread -lm `
'-Wl,-subsystem,console' `
-o qjs.exe
llvm-readobj --file-headers host-qjsc.exe | Select-String "Machine"
Machine: IMAGE_FILE_MACHINE_AMD64 (0x8664)
OpenGL Awesome
https://www.zhihu.com/question/30207624/answers/updated
https://github.com/indevn/awesome-graphics-cn
https://github.com/ZeusYang/fun-with-graphics
很高兴重新安装 MinGW 帮你解决了问题!
Clang 能够“借用” MinGW 库,并且可以通过 --target 随意切换目标平台,这得益于 LLVM/Clang 的一体化架构设计和智能的驱动程序(Driver)机制。
为什么 Clang 可以“借用” MinGW 库?
与传统 GCC 往往需要为每个目标平台单独编译一个完整的编译器可执行文件(比如 x86_64-w64-mingw32-gcc 和 arm-linux-gnueabihf-gcc 是不同的程序)不同,Clang 是一个原生的交叉编译器。你电脑上的那一个 clang.exe 内部包含了生成各种架构代码的后端(Backend)。
当你传入 --target=x86_64-w64-mingw32 时,Clang 的外层驱动(Driver)执行了以下几步操作来“借用”环境:
- 宏定义切换:Clang 会自动在内部定义特定的预处理宏(如
__MINGW32__、_WIN32),让代码在预处理阶段表现得就像在使用 MinGW GCC 一样。 - 探测 Sysroot(系统根目录):Clang 的 Driver 包含了一套探测逻辑。它会根据环境变量(如
PATH)以及注册表,去寻找系统中存在的 MinGW GCC 安装目录(比如你放在D:\App\mingw64下的目录)。 - 替换标准库与 ABI:Clang 本身只提供编译器核心,默认不带操作系统的 C/C++ 标准库。当它认出目标是 MinGW 时,它会自动链接 MinGW 的 C 运行库(CRT)以及 GCC 的 C++ 标准库(
libstdc++),而不是它自家的libc++。 - 调用外部链接器:在编译过程的最后一步,Clang 默认会去调用 MinGW 提供的
ld.exe链接器来生成最终的 Windows.exe程序。
简而言之,Clang 伪装成了 GCC,复用了 GCC 的生态(头文件、标准库、链接器),仅仅把其中“将 C++ 代码翻译成机器码”的这一步替换成了自己的 LLVM 引擎。
--target 是如何工作的?还有哪些可选参数?
--target 接收的是一个被称为 LLVM Target Triple(目标三元组) 的字符串,标准格式通常是:
<架构(arch)> - <供应商(vendor)> - <操作系统(os)> - <环境/ABI(environment)>
由于很多缩写可以省略,所以有时看起来是三元组或四元组。以下是一些在底层开发中非常有用且常见的 --target 参数:
1. Windows 平台
x86_64-w64-mingw32或x86_64-w64-windows-gnu
你当前使用的目标。使用 GCC 的 ABI 和标准库(libstdc++)。x86_64-pc-windows-msvc
使用微软 Visual Studio 的 ABI 和标准库。如果你想让 Clang 编译出能和 MSVC 完美混用的代码,就用这个(前提是你装了 Visual Studio 环境)。
2. WebAssembly (Wasm) 平台
wasm32-unknown-emscripten
当你使用 Emscripten 工具链(emcc)将 C/C++ 编译为网页运行的 WebAssembly 时,底层 Clang 实际使用的就是这个 Target。它会去对接 Emscripten 提供的 JS/Web 桥接库。wasm32-unknown-unknown
纯净版的 WebAssembly 目标。不依赖任何操作系统的标准库,常用于编写没有外部依赖的纯算法 Wasm 模块。
3. 移动端与 Android (ARM 架构)
aarch64-linux-android
如果你在编写 Android 的 C++ 插件(比如通过 JNI 调用),Clang 会使用这个参数,并去链接 Android NDK 中的库文件。armv7-linux-androideabi
针对较老的 32 位 Android 设备的编译目标。
4. Linux 与 macOS
x86_64-pc-linux-gnu
标准的 64 位 Linux 目标,使用 GNU 的 glibc。arm64-apple-darwin
苹果 M1/M2/M3 系列芯片的 macOS 目标。
小技巧:
你可以在终端输入clang -print-targets查看你当前安装的 Clang 版本所支持的所有底层架构。
浙公网安备 33010602011771号