开发者“疯狂”整活:用纯C语言,从头编写一个Rust编译器!

C语言与CPP编程 2024-11-01 09:01

本文经授权转自公众号CSDN(ID:CSDNnews)

作者 | John Nunley,翻译 | 郑丽媛

近日,一个项目在 HN 上引起了许多开发者注意——一富有创新精神的开发者正在尝试使用 C 语言来编写 Rust 编译器。这位开发者表示:为了引导 Rust 发展,无论付出什么代价都值得。

原文链接:https://notgull.net/announcing-dozer/


细心的 Rust 爱好者可能已经注意到,我最近不太活跃。导致这种情况的原因有很多:最近我经历了一系列非常糟糕的事情,包括一位亲人的离世让我感到极其意外,同时我在工作中承担了更多责任,不再有很多时间和精力去贡献开源项目了。亦或许,我也失去了当初在大学时代、那种足以让我全身心投入开源世界的热情。

除此之外,还有另一个原因:我正忙于一个占据了我大部分业余时间的项目。这个项目是我在开源领域中创建的最大型的一个,如果我最后能完成它,那它一定会成为我的巅峰之作。

我正在用纯 C 语言编写一个 Rust 编译器:不用 C++,不用 flex 或 yacc,甚至不用 Makefile——仅仅用纯 C 语言。这个项目叫做 Dozer。

1、为什么要这么做?

想要理解我为何走上这条“疯狂”之路,你首先需要了解 Bootstrapping(引导法)以及它的重要性(所谓引导法,这是一种在编程中常见的技术,意为通过已有的基本代码或资源来构建更复杂的系统或工具)。

假设你用 Rust 写了一些代码,为了运行这些代码,你需要先编译它们。编译器是一种程序,它会解析你的代码,验证其正确性,然后将其转换为 CPU 可以理解的机器代码。

对于 Rust 来说,主要的编译器是 rustc——也就是你运行 cargo build 时所调用的底层程序。不得不说,rustc 是一个很棒的软件,甚至可以说是开源社区的瑰宝,其代码质量可以媲美 Linux 内核和 Quake III 源代码。

然而,rustc 本身也是一个程序,所以它也需要一个编译器将其从源代码编译为机器代码。那么问题来了:rustc 是用什么语言编写的呢?

这样来看,rustc 是一个用 Rust 编写的程序,其目的是为了编译 Rust 代码。但请仔细想想,如果 rustc 是用 Rust 编写的,而我们又需要用 rustc 来编译 Rust 代码,这意味着我们需要用 rustc 来编译 rustc……?

对于一般用户来说,这其实没什么问题,因为我们可以直接从网上下载 rustc 并使用它。但有个问题:第一个 rustc 是谁编译的,总得先有“鸡”才有“蛋”吧?这到底是从哪里开始的?

其实,这个问题并不复杂:每个新 rustc 版本都是由前一个版本的 rustc 编译出来的。也就是说,rustc 1.80.0 版本是用 rustc 1.79.0 版本编译的,rustc 1.79.0 版本又是由 rustc 1.78.0 版本编译的……以此类推,一直可以追溯到 rustc 0.7 版本。而那时,编译器是用 OCaml 写的,因此只需要一个 OCaml 编译器就能得到一个完整的 rustc 程序。

好了,问题解决了,我们已经搞清楚如何从头开始创建 rustc。但是,要让这一切都正常工作,我们仍需要一个 OCaml 编译器的版本。所以说,OCaml 编译器又是用什么语言编写的呢?

额……没事儿!有一个项目能成功用 Guile 编译 OCaml 编译器,而 Guile 是 Scheme 的众多变体之一,Scheme 又是 Lisp 的众多变体之一。另外,Guile 的解释器是用 C 编写的。

于是,这一切最终都指向了 C 语言。我们只需用 GCC 来编译它,一切就能顺利进行。那么我们只需要编译 GCC,而 GCC 是用……C++编写的?!

这个说法有点不准确。GCC 直到第 5 版之前都是用 C 语言编写的,这世上也并不缺少用 C 编写的 C 编译器……但这仍然没有回答我们的问题。第一个 C 编译器是用什么写的?汇编语言?那么第一个汇编器又是用什么写的呢?


2、原理介绍

这就是我要介绍 Bootstrappable Builds 项目的目的。在我看来,这就是开源社区中最有趣的项目之一,也基本上属于代码炼金术。

其 Linux 引导过程从一个 512 字节的二进制种子开始。这个种子包含了一个最简单的编译器:能接收十六进制数字并输出相应的原始字节。例如,以下为该编译器编译的部分“源代码”:

31 C0           # xor ax, ax8E D8           # mov ds, ax8E C0           # mov es, ax8E D0           # mov ss, axBC 00 77        # mov sp, 0x7700FC              # cld ; clear direction flag88 16 15 7C     # mov [boot_drive], dl

注意,井号后的所有内容都是注释,所有的空白字符也都被去掉了。坦白说,我甚至不确定这能否被称为编程语言。但严格来说,这确实是可分析、可剖析的源代码。

接下来,这个编译器就会编译一个非常简单的操作系统,一个简陋的 shell,以及一个稍微高级一点的编译器。那个编译器又编译了一个更高级一点的编译器。这样几步之后,你就有了类似汇编代码的东西。

DEFINE cmp_ebx,edx 39D3DEFINE je 0F84DEFINE sub_ebx, 81EB
:loop_options cmp_ebx,edx # Check if we are done je %loop_options_done # We are done sub_ebx, %2 # --options

说到这儿,你会觉得我把汇编代码当作比其他东西更高层次的语言,好像有点奇怪,对吧?

但这就足以得到一个非常基础的 C 语言子集,然后,利用这个子集编译一个稍微高级一点的 C 编译器。几步之后,就能编译 TinyCC 了。接着可以引导 yacc、基本 coreutils、Bash、autotools,并最终到达 GCC 和 Linux。

我这样讲,可能还是没法完全体现出这个过程的魅力,但这真的很引人入胜。总之,从“一个小到足以手动分析的二进制文件”开始,一步步到 Linux、GCC,再到基本上所有其他的东西,你基本上都经历过了。不过,我们还是从 TinyCC 开始再来一次吧。

目前,Rust 在这个过程中出现得非常晚。他们使用 mrustc,这是一种用 C++ 编写的 Rust 替代实现,可以编译 rustc 1.56 版本。在此基础上,他们再编译现代 Rust 代码。

这里的主要问题是,到引入 C++ 时,引导过程基本上已经结束了。因此,如果你想在引入 C++ 之前的任何时候使用 Rust,那是不可能的。

所以,对我来说,如果有一个 Rust 编译器能够从 C 开始引导,那就太好了。具体来说,就是一个可以从 TinyCC 开始引导的 Rust 编译器,同时假设系统中还没有可能有用的工具——这个编译器就是 Dozer。


3、未来计划

过去两个月中,我一直在忙于 Dozer 项目:把我那本就少得可怜的空闲时间,用来编写一种我有点讨厌的语言。

这个项目没有使用任何扩展功能,目前 TinyCC 和 cproc 都能顺利编译。我使用 QBE 作为后端。除此之外,我假设系统上没有其他工具,只有一个 C 编译器和一些非常基础的 shell 实现,再无其他。

在本文中,我不会深入探讨编写一个编译器的原始体验。但到目前为止,我已经完成了词法分析器,还完成了相当大一部分的语法解析器。宏/模块扩展我会尽量推迟,类型检查目前只支持 i32,而代码生成还稍显粗糙——但这已经是一个不错的开始了。

目前,我已可以成功编译以下代码:

fn rust_main() -> i32 {    (2 - 1) * 6 + 3}

那么,接下来怎么办呢?这是我的计划:

(1)慢慢推进 Dozer,直到它能够编译一些使用 libc 的基本示例代码,然后再编译 libcore,最后到 rustc。(顺便提一下,我计划编译 rustc 的 Cranelift 后端,这部分完全是用 Rust 编写的。由于我们假定还没有 C++,所以无法编译 LLVM。)

(2)创建一个等同于 cargo 的工具,可以用 Dozer 来编译 Rust 包。

(3)找出 rustc 中那些自动生成的代码源文件,并将它们剔除。根据 Bootstrappable 项目的规则,不允许使用自动生成的代码。

(4)创建一个可以用来编译 rustc 和 cargo 的过程,然后使用我们编译的 rustc/cargo 版本重新编译标准版本的 rustc/cargo。

毫无疑问,这是我迄今为止创建的最困难的项目,我也很怀疑自己到底能否完成它。但你知道吗?尝试过却失败了,总比从未尝试过要好。

本文转自公众号“CSDN”,ID:CSDNnews
EOF

你好,我是飞宇。日常分享C/C++、计算机学习经验、工作体会,欢迎点击此处查看我以前的学习笔记&经验&分享的资源。

我组建了一些社群一起交流,群里有大牛也有小白,如果你有意可以一起进群交流。

欢迎你添加我的微信,我拉你进技术交流群。此外,我也会经常在微信上分享一些计算机学习经验以及工作体验,还有一些内推机会

加个微信,打开另一扇窗

经常遇到有读者后台私信想要一些编程学习资源,这里分享 1T 的编程电子书、C/C++开发手册、Github上182K+的架构路线图、LeetCode算法刷题笔记等精品学习资料,点击下方公众号会回复"编程"即可免费领取~

感谢你的分享,点赞,在看三  

C语言与CPP编程 C语言/C++开发,C语言/C++基础知识,C语言/C++学习路线,C语言/C++进阶,数据结构;算法;python;计算机基础等
评论 (0)
  • 长期以来,智能家居对于大众家庭而言就像空中楼阁一般,华而不实,更有甚者,还将智能家居认定为资本家的营销游戏。商家们举着“智慧家居、智慧办公”的口号,将原本价格亲民、能用几十年的家电器具包装成为了高档商品,而消费者们最终得到的却是家居设备之间缺乏互操作性、不同品牌生态之间互不兼容的碎片化体验。这种早期的生态割裂现象致使消费者们对智能家居兴趣缺失,也造就了“智能家居无用论”的刻板印象。然而,自Matter协议发布之后,“命运的齿轮”开始转动,智能家居中的生态割裂现象与品牌生态之间的隔阂正被基于IP架
    华普微HOPERF 2025-03-27 09:46 109浏览
  •       知识产权保护对工程师的双向影响      正向的激励,保护了工程师的创新成果与权益,给企业带来了知识产权方面的收益,企业的创新和发明大都是工程师的劳动成果,他们的职务发明应当受到奖励和保护,是企业发展的重要源泉。专利同时也成了工程师职称评定的指标之一,专利体现了工程师的创新能力,在求职、竞聘技术岗位或参与重大项目时,专利证书能显著增强个人竞争力。专利将工程师的创意转化为受法律保护的“无形资产”,避免技术成果被他人抄袭或无偿使
    广州铁金刚 2025-03-25 11:48 181浏览
  • 家电,在人们的日常生活中扮演着不可或缺的角色,也是提升人们幸福感的重要组成部分,那你了解家电的发展史吗?#70年代结婚流行“四大件”:手表、自行车、缝纫机,收音机,合成“三转一响”。#80年代随着改革开放的深化,中国经济开始飞速发展,黑白电视机、冰箱、洗衣机这“新三件”,成为了人们对生活的新诉求。#90年代彩电、冰箱、全自动洗衣机开始大量进入普通家庭,快速全面普及,90年代末,家电产品实现了从奢侈品到必需品的转变。#00年代至今00年代,随着人们追求高品质生活的愿望,常用的电视机、洗衣机等已经远
    启英AI平台 2025-03-25 14:12 89浏览
  • 汽车导航系统市场及应用环境参照调研机构GII的研究报告中的市场预测,全球汽车导航系统市场预计将于 2030年达到472亿美元的市场规模,而2024年至2030年的年复合成长率则为可观的6.7%。汽车导航系统无疑已成为智能汽车不可或缺的重要功能之一。随着人们在日常生活中对汽车导航功能的日渐依赖,一旦出现定位不准确或地图错误等问题,就可能导致车主开错路线,平白浪费更多行车时间,不仅造成行车不便,甚或可能引发交通事故的发生。有鉴于此,如果想要提供消费者完善的使用者体验,在车辆开发阶段便针对汽车导航功能
    百佳泰测试实验室 2025-03-27 14:51 186浏览
  • 在嵌入式语音系统的开发过程中,广州唯创电子推出的WT588系列语音芯片凭借其优异的音质表现和灵活的编程特性,广泛应用于智能终端、工业控制、消费电子等领域。作为该系列芯片的关键状态指示信号,BUSY引脚的设计处理直接影响着系统交互的可靠性和功能拓展性。本文将从电路原理、应用场景、设计策略三个维度,深入解析BUSY引脚的技术特性及其工程实践要点。一、BUSY引脚工作原理与信号特性1.1 电气参数电平标准:输出3.3V TTL电平(与VDD同源)驱动能力:典型值±8mA(可直接驱动LED)响应延迟:语
    广州唯创电子 2025-03-26 09:26 198浏览
  • ​2025年3月27日​,贞光科技授权代理品牌紫光同芯正式发布新一代汽车安全芯片T97-415E。作为T97-315E的迭代升级产品,该芯片以大容量存储、全球化合规认证、双SPI接口协同为核心突破,直击智能网联汽车"多场景安全并行"与"出口合规"两大行业痛点,助力车企抢占智能驾驶与全球化市场双赛道。行业趋势锚定:三大升级回应智能化浪潮1. 大容量存储:破解车联网多任务瓶颈随着​车机功能泛在化​(数字钥匙、OTA、T-BOX等安全服务集成),传统安全芯片面临存储资源挤占难题。T97-415E创新性
    贞光科技 2025-03-27 13:50 148浏览
  • 文/陈昊编辑/cc孙聪颖‍2025 年,作为中国实施制造强国战略第一个十年计划的关键里程碑,被赋予了极为重大的意义。两会政府工作报告清晰且坚定地指出,要全力加速新质生产力的发展进程,推动传统产业全方位向高端化、智能化与绿色化转型。基于此,有代表敏锐提议,中国制造应从前沿技术的应用切入,逐步拓展至产业生态的构建,最终延伸到提升用户体验的维度,打出独树一帜、具有鲜明特色的发展牌。正是在这样至关重要的时代背景之下,于 AWE 2025(中国家电及消费电子博览会)这一备受瞩目的舞台上,高端厨房的中国方案
    华尔街科技眼 2025-03-25 16:10 82浏览
  • 在智能终端设备开发中,语音芯片与功放电路的配合直接影响音质表现。广州唯创电子的WTN6、WT588F等系列芯片虽功能强大,但若硬件设计不当,可能导致输出声音模糊、杂音明显。本文将以WTN6与WT588F系列为例,解析音质劣化的常见原因及解决方法,帮助开发者实现清晰纯净的语音输出。一、声音不清晰的典型表现与核心原因当语音芯片输出的音频信号存在以下问题时,需针对性排查:背景杂音:持续的“沙沙”声或高频啸叫,通常由信号干扰或滤波不足导致。语音失真:声音断断续续或含混不清,可能与信号幅度不匹配或功放参数
    广州唯创电子 2025-03-25 09:32 112浏览
  • 在电子设计中,电磁兼容性(EMC)是确保设备既能抵御外部电磁干扰(EMI),又不会对自身或周围环境产生过量电磁辐射的关键。电容器、电感和磁珠作为三大核心元件,通过不同的机制协同作用,有效抑制电磁干扰。以下是其原理和应用场景的详细解析:1. 电容器:高频噪声的“吸尘器”作用原理:电容器通过“通高频、阻低频”的特性,为高频噪声提供低阻抗路径到地,形成滤波效果。例如,在电源和地之间并联电容,可吸收电源中的高频纹波和瞬态干扰。关键应用场景:电源去耦:在IC电源引脚附近放置0.1μF陶瓷电容,滤除数字电路
    时源芯微 2025-03-27 11:19 146浏览
  • 案例概况在丹麦哥本哈根,西门子工程师们成功完成了一项高安全设施的数据集成项目。他们利用宏集Cogent DataHub软件,将高安全设施内的设备和仪器与远程监控位置连接起来,让技术人员能够在不违反安全规定、不引入未经授权人员的情况下,远程操作所需设备。突破OPC 服务器的远程连接难题该项目最初看似是一个常规的 OPC 应用:目标是将高安全性设施中的冷水机(chiller)设备及其 OPC DA 服务器,与远程监控站的两套 SCADA 系统(作为 OPC DA 客户端)连接起来。然而,在实际实施过
    宏集科技 2025-03-27 13:20 109浏览
  • 在当今竞争激烈的工业环境中,效率和响应速度已成为企业制胜的关键。为了满足这一需求,我们隆重推出宏集Panorama COOX,这是Panorama Suite中首款集成的制造执行系统(MES)产品。这一创新产品将Panorama平台升级为全面的工业4.0解决方案,融合了工业SCADA和MES技术的双重优势,帮助企业实现生产效率和运营能力的全面提升。深度融合SCADA与MES,开启工业新纪元宏集Panorama COOX的诞生,源于我们对创新和卓越运营的不懈追求。通过战略性收购法国知名MES领域专
    宏集科技 2025-03-27 13:22 179浏览
  • 在智能语音产品的开发过程中,麦克风阵列的选型直接决定了用户体验的优劣。广州唯创电子提供的单麦克风与双麦克风解决方案,为不同场景下的语音交互需求提供了灵活选择。本文将深入解析两种方案的性能差异、适用场景及工程实现要点,为开发者提供系统化的设计决策依据。一、基础参数对比分析维度单麦克风方案双麦克风方案BOM成本¥1.2-2.5元¥4.8-6.5元信噪比(1m)58-62dB65-68dB拾音角度全向360°波束成形±30°功耗8mW@3.3V15mW@3.3V典型响应延迟120ms80ms二、技术原
    广州唯创电子 2025-03-27 09:23 151浏览
  • WT588F02B是广州唯创电子推出的一款高性能语音芯片,广泛应用于智能家电、安防设备、玩具等领域。然而,在实际开发中,用户可能会遇到烧录失败的问题,导致项目进度受阻。本文将从下载连线、文件容量、线路长度三大核心因素出发,深入分析烧录失败的原因并提供系统化的解决方案。一、检查下载器与芯片的物理连接问题表现烧录时提示"连接超时"或"设备未响应",或烧录进度条卡顿后报错。原因解析接口错位:WT588F02B采用SPI/UART双模通信,若下载器引脚定义与芯片引脚未严格对应(如TXD/RXD交叉错误)
    广州唯创电子 2025-03-26 09:05 146浏览
  • 六西格玛首先是作为一个量度质量水平的指标,它代表了近乎完美的质量的水平。如果你每天都吃一个苹果,有一间水果店的老板跟你说,他们所卖的苹果,质量达到六西格玛水平,换言之,他们每卖一百万个苹果,只会有3.4个是坏的。你算了一下,发现你如果要从这个店里买到一个坏苹果,需要805年。你会还会选择其他店吗?首先发明六西格玛这个词的人——比尔·史密斯(Bill Smith)他是摩托罗拉(Motorloa)的工程师,在追求这个近乎完美的质量水平的时候,发明了一套方法模型,开始时是MAIC,后来慢慢演变成DMA
    优思学院 2025-03-27 11:47 147浏览
  • 在智慧城市领域中,当一个智慧路灯项目因信号盲区而被迫增设数百个网关时,当一个传感器网络因入网设备数量爆增而导致系统通信失效时,当一个智慧交通系统因基站故障而导致交通瘫痪时,星型网络拓扑与蜂窝网络拓扑在构建广覆盖与高节点数物联网网络时的局限性便愈发凸显,行业内亟需一种更高效、可靠与稳定的组网技术以满足构建智慧城市海量IoT网络节点的需求。星型网络的无线信号覆盖范围高度依赖网关的部署密度,同时单一网关的承载设备数量有限,难以支撑海量IoT网络节点的城市物联系统;而蜂窝网络的无线信号覆盖范围同样高度依
    华普微HOPERF 2025-03-24 17:00 235浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦