返回资讯中心
外部精选
软件工程
#开发者实时流

clice v1.0 正式发布:一个用现代 C++ 编写的 C/C++ 语言服务器

来源标题:Clice v1.0 Released: Welcome to Modern C++

clice 发布首个稳定版 v1.0,核心功能已趋稳定。该项目由作者投入两年半开发,累计 1000 次提交,自 2026 年 7 月 19 日起提供 nightly 构建并经历约四个月 alpha 测试,修复了大量由早期用户反馈暴露的 bug。作者还搭建了严格测试体系,在多个真实开源项目上做了广泛测试。

Hacker News 最新molenzwiebel2026/11/15 · 今天30 分钟阅读

以下正文由 AI 翻译自 Hacker News 最新(原文版权归原站所有),可能存在偏差,重要内容请以原文为准。

clice 最近达成了 1,000 次提交,这对项目来说是一个特殊的里程碑。自 2026 年 7 月 19 日起,clice 一直在发布 nightly 构建,并经历了大约四个月的 alpha 测试,在早期用户的真实反馈帮助下修复了大量 bug。在同一段时间里,我为 clice 搭建了一套严格的测试系统,并在许多真实开源项目上做了大量测试,追踪并修复了测试中发现的问题。这意味着什么?每个核心功能现在都已稳定,日常使用中很少会遇到问题。所以我认为发布首个稳定版的时机已经成熟。与两年前《Design and Implementation of a New C++ Language Server》时相比,这个项目如今的面貌已大不相同,而这可能也是我第一次广泛宣传它,所以请允许我重新向你介绍它!这是我过去两年半全心投入的项目,是我最引以为傲的作品,是让我最兴奋、也让我无数次难过和焦虑的东西,也是我短暂人生中承担过的最具野心的事。

clice 是什么?简而言之,clice 是一个用现代 C++ 编写的 C/C++ 语言服务器,但它不止是一个语言服务器。它仍然构建在 LLVM/Clang 之上,但与同样基于 Clang 的 clangd 和 ccls 不同,clice 是从头重新设计的,以解决那些服务器多年来未能解决的架构问题。它完全用 C++23 编写,本身也是现代 C++ 最佳实践的一个范例,所有主要的现代 C++ 特性在这里都结合得相当出色:

完全使用 C++20 协程编写,采用我们自己基于 libuv 的结构化并发异步库来处理复杂的异步逻辑。它是一个复杂的并发程序,在主线程上运行事件循环,同时协调多个进程(IPC)和多个线程。完全使用 C++20 具名模块和 C++23 import std 编写,并且完全自举:第三方库的模块封装由 clice modularize 自动生成,clice 能在自己的代码库上流畅运行,提供模块感知的语言服务。使用基于模板和 C++20 concepts 的静态反射来完成所有格式的序列化和反序列化,包括 TOML、JSON、bincode、blob 和命令行参数,具备类似 Rust macro 的声明式注解和零样板代码。全程采用面向数据的代码设计,除了 Clang 要求的回调接口外几乎没有虚函数。大量使用 std::format、std::expected、std::ranges 和 std::views 等现代 C++ API,避开过时的 C++98/11 遗留 API。由 Bazel 驱动的完全封闭、可复现的构建,使用统一的 xclang 工具链编译,实现一致的跨平台交叉编译工作流。编译出的二进制经过高度优化(PGO + LTO),构建产物除系统库外不依赖任何其他东西。

人们总是在争论 modules 这类现代 C++ 特性是否真的准备好投入实际工作。clice 的回答是:是的,当然,完全可用!它们能支撑像 clice 这样拥有数十万行代码的复杂软件。也许这就是我们一直期待的现代 C++ 的样子。话虽如此,目前的周边生态确实相当不便,要把这整套工作流端到端跑通,我付出了巨大的努力去追踪问题并适配一切。

语言服务器

以下是 clice 主要功能的概览:

多进程编译:clice 在模仿现代 Web 浏览器的进程池中编译代码,而 clangd 使用的是多线程。为什么用多进程?因为 C++ 实在太复杂,在某些极端情况下编译器很容易崩溃或泄漏内存。对于编辑过程中不完整的代码尤其如此:庞大的下游用户群测试的是完整代码上的编译器,而很少有人测试写了一半的代码,此时编译器大多依赖尽力而为的启发式方法。在 clangd 中,编译器崩溃会导致整个服务器崩溃并强制重启。在 clice 中,编译发生在隔离的子进程里:损失一个工作进程不会影响服务器的其余部分,因此跳转定义、高亮和其他服务都能继续工作。这也让内存管理和编译优先级调度容易得多,减少了不必要的资源消耗。

模块与共享缓存:clice 完整支持 C++20 具名模块。你只需要一个包含所有模块文件的 compile_commands.json,clice 会自行扫描依赖并按需惰性构建所需的模块,无论你使用什么构建系统或编译器,并完整支持模块的补全、高亮、跳转定义、悬停等。构建出的 PCH 和 PCM 也会缓存在本地磁盘上,供跨会话复用。相比之下,clangd 对模块的支持非常有限,也没有持久化缓存。

编译上下文:clice 完整支持非自包含文件,更广泛地说,支持编译上下文这一概念。你可以显式选择文件的活跃上下文:源文件的某个特定编译命令,或头文件的某个特定包含位置。当你打开一个非自包含文件时,clice 会自动检测其上下文,因此开箱即用。更广泛地说,它还支持将编译命令分组为构建配置,让你可以在比如 debug 和 release 之间切换。

(原文较长,此处译出前 6000 字,完整内容请点「打开原文」。)

正文由 探How 从来源站点 RSS 同步,内容未经改写;遇到排版缺失或需要图片、视频时请以原文为准。

打开原文
去社区讨论 →