Rust: RFC:合并上游的 avr-rust 分支

创建于 2017-08-23  ·  89评论  ·  资料来源: rust-lang/rust

大家好,

我想知道关于将avr-rust fork 合并到 Rust 中的一般意见。

最近几个月,分叉本身变得更加稳定,错误更少。 它也开始吸引许多有兴趣使用它的人。

您可以在GitHub 上使用 avr-rust 找到更有趣的项目之一。

阻滞剂

LLVM 5.0

~Rust 目前在 LLVM 4.0 上,它包含一个有效的 AVR 后端,但从那时起有许多错误修正。 我们需要等待 LLVM 5.0 得到支持(即将完成:#43370),然后才能获得修复了一些重要错误的 AVR 后端版本。~

这不再是阻滞剂。 截至 2018 年 2 月 20 日,上游 Rust 处于 LLVM 6.0。

问题

樱桃采摘修复

如果 AVR 支持内置到主线中,我们需要能够在 Rust 的 LLVM 分支中挑选补丁。 我不认为这会是什么大问题,因为我们已经在其中挑选了一些重要的修复程序。

所有从 avr-rust 存储库中挑选出来的错误修复都已经上传到 LLVM 主干中,如果我们合并分叉,情况将继续如此,因为我不喜欢 LLVM 分叉与主干分叉太远。

由于 LLVM 的发布周期为 6 个月,因此挑选樱桃是必要的。

AVR 后端的当前问题

avr-rust/rust存储库中没有任何已知错误——所有已知错误都是 AVR LLVM 后端的问题; 这里有一些更有趣/有影响力的。

libcore不修改不能编译

设置了一个里程碑来跟踪需要修复哪些错误,以便在不修改的情况下成功编译libcore

到目前为止,这对用户来说还不是什么大问题,因为xargo会在需要时透明地libcore ,我们可以在Xargo.toml覆盖 libcore。

我不确定 Rust 团队对合并无法使用库存 libcore 的目标有何看法。

对除“调用”访问 RAM 以外的函数指针的任何操作,而不是程序内存 (avr-rust/rust#68)

这是 AVR 成为哈佛架构的第一个 in-tree LLVM 后端的一个症状。 LLVM 当前假设所有函数都驻留在“通用地址空间”中,它对应于 RAM。 因此,如果您尝试通过函数指针加载/存储,它将访问 RAM 而不是程序存储器。

好消息是我有待解决的上游 LLVM 补丁来修复它( D37052D37053D37054D37057 )。

32 位移位生成对不存在的compiler-rt例程的调用 (avr-llvm/llvm#163)

因为没有多少(如果有)目标本身不支持 32 位移位, libgcccompiler-rt没有 32 位版本的移位例程,即使 LLVM 仍然愉快地产生了对它的调用。

这会在链接时导致未定义的符号错误。 只有在您实际编写代码或使用执行 32 位移位的代码时才会发生这种情况,因为链接器非常擅长删除所有死代码。

请注意,由于在发布模式下编译,我有一个用户遇到了缺少的移位错误,这将乘法提升为移位作为“优化”。

要合并的实际更改

您可以通过查看此 diff找到所有特定于 AVR 的

请注意,超过一半的差异只是 README 和 Travis CI 配置 - 上游的实际代码非常小; 只是一些胶水代码来启用 AVR 后端和目标规范。

此差异还会有条件地禁用 AVR 的libcore - 这些修复不会上游,并且不是严格要求的,因为下游用户可以使用 Xargo 为 AVR 编译缩小的libcore

链接

Gitter 上的 AVR-Rust
GitHub 上的 AVR-Rust

C-feature-request O-AVR T-core WG-embedded

最有用的评论

好的,更新时间。

从今天晚上的rustc 1.47.0-nightly (0820e54a8 2020-07-23) ,当前的 Rust 夜间编译器中存在 AVR 所需的所有补丁。 Rust nightly 编译器无需修改,现在可以成功编译 LED 闪烁示例并生成 AVR ELF 文件。

  • https://avr-rust.com/创建的新的、集中的项目登陆页面
  • 一本新书 - AVR-Rust 指南已创建,托管在 GitHub 页面 book.avr-rust.com 上。
  • avr-rust/rust fork 存储库已被弃用。 存储库尚未存档,因为存在应在永久锁定和关闭之前迁移的现有问题。
  • 不再需要 Xargo - 上游 Rust 中的-Z build-std标志取代了 AVR 上对它的需求。 不再需要货叉——上游货物就可以了。

现在可以将 Rust nightly 编译器视为具有 AVR 支持的 Rust 的推荐频道。

我现在正在关闭这个问题 - 我们做到了!

报告错误的步骤可以在AVR 指南中找到。

https://github.com/avr-rust/blink上的AVR 指南和闪烁示例是开始使用目标的最佳资源。

深深地感谢所有通过这种上游努力讨论和支持该项目的人 - 非常感谢。

所有89条评论

+1! 内置在编译器中的 Avr rust 将非常有用。 现在几乎没有错误。

并非完全没有错误:)

我将更新描述以包含有关后端 wrt 错误状态的一些信息

虽然差不多😄。 只是一对夫妇去

总的来说,我们非常欢迎 rust-lang/rust 上游的平台,只要它们不会给我们带来维护负担! 从你的想法中得出一些具体的想法:

  • Cherry-picking LLVM 经常提交是完全可以的,我想你们也已经经历过几次这个过程了:)
  • 我们可以在 compiler-rt 中缺少内在函数,您可以选择在 Rust 中实现它们,也可以通过 compiler-builtins 项目来实现。
  • 您拥有的补丁看起来不错,但我认为我们希望通过 libcore 中的各种#[cfg]进行更多工作。 这些项目是由于“LLVM 中的错误”还是因为 AVR 根本不支持它们而被遗漏? 前者最好通过以某种方式“修复 LLVM”来完成,而后者会使事情变得更加棘手。

总的来说,我们目前所有平台都具有相同的 libcore/libstd 统一接口,但不清楚随着我们不断选择更多平台,这是否会保持不变。

您拥有的补丁看起来不错,但我认为我们希望通过 libcore 中的各种 #[cfg] 进行更多工作。 这些项目是由于“LLVM 中的错误”还是因为 AVR 根本不支持它们而被遗漏?

这是因为 LLVM 中的错误。

我脑子里唯一的问题是对i128 / u128类型的支持——我认为对于 AVR 来说,这些并不是很有用。 该i128支持libcore目前注释掉,因为一个错误,但可能还有其他未发现的bug,因为它不是一个很好的测试代码路径,真正行使寄存器分配的AVR只有 32 个字节的通用寄存器。

我们仍然很有可能让i128在 AVR 上工作,但我不太了解它在后端触发的具体问题。

我认为最好的前进方式是在 libcore _does_ 编译后不加修改地或至少不加修改地提出真正的补丁。

我认为最好的方法是在 libcore 编译时无需修改,或者至少没有很多修改,就提出真正的补丁。

对我来说听起来很合理!

我脑子里唯一的问题是对 i128/u128 类型的支持——我认为对于 AVR,这些并不是很有用。

我对不支持 AVR 上的i128主要担心是,为了与 AVR 或其他嵌入式平台的兼容性,它会对采用 128 位整数产生寒蝉效应。 例如,如果有一个使用 128 位整数的库,想要使用它的 AVR 用户将提交问题以放弃使用。 这可能会使 128 位整数在力求可移植的 Rust 代码中使用不“安全”,我不希望发生这种情况。

为了与 AVR 或其他嵌入式平台兼容而采用 128 位整数的令人不寒而栗的效果

我不认为这是一个非常大的交易。 小型嵌入式设备已经有很大的限制(没有标准输入/标准输出,通常没有分配器等),这使得仅仅放入任意库非常困难。 我最近了解到 AVR GCC 的double实际上是float的别名! 我不知道我们是否会保持这种陌生感,但它对 crate 的影响远远超过i128

我认为我们总是会有一些特殊的功能来制作适合嵌入式的 crate,就像我们为 no-std 做的那样。

没有标准输入/标准输出,一般没有分配器等。

您正在描述#![no_std]生态系统。 有一些图书馆针对这个生态系统。 该生态系统的一般规则是将libcore作为给定,其中还包括i128 。 每个不支持i128目标在这个生态系统中都有更大的寒蝉效应,因为嵌入式目标的“市场份额”在整个 Rust 生态系统的子集中更大,而 x86 家族并不是一个非常相关的参与者.

我不知道我们是否会保持这种陌生感,但它会比 i128 更影响板条箱。

有趣的! 我确实同意,如果我们将f64别名f32 (或不提供),它会对生态系统产生更大的影响。 但是,如果我们可以争取一致性,为什么不呢? 我们绝对有可能实现i128

我们绝对有可能实现 i128。

当然,我意识到我没有明确说明我认为我们应该为 AVR 实现 i128 。 然而,任何在 AVR 上实际使用i128的代码都将陷入痛苦的世界。

但是,如果我们可以争取一致性,为什么不呢?

什么一致,是个问题。 与 GCC ( f64 == f32 ) 或所有其他 Rust 目标 ( f64 != f32 ) 的一致性?

您正在描述 #![no_std] 生态系统。

是的,这就是为什么我说“用于制作适合嵌入的板条箱的特殊功能,就像我们为非标准所做的那样。” 😇

自从我们最初发布 16 位usize补丁以来,我一直在想的一个更​​大的问题是,从根本上说,Rust 和 Rust 程序员倾向于假设usize是“本机”一个寄存器的大小。 AFAIK,这适用于 Rust 目标的所有其他平台,但不适用于 AVR。

与什么一致,是个问题。 与 GCC (f64 == f32) 还是与其他所有 Rust 目标 (f64 != f32) 保持一致?

名称f64字面上表示它有 64 位。 如果你不遵守这个名字,那么它就像在 C 中一样变得毫无意义。

好点在这里,我可以看到对 128 位整数的关注。 我绝对认为应该支持它们,即使我们不应该鼓励它们的使用。 我不想看到 crate 必须为i128类型的 trait impls 之类的东西添加功能标志。 这应该不是问题,因为所有未使用的 i128 内容都应该由链接器修剪掉。

f32/64 问题是一个有趣的问题。 我对让 f64 实际上是 64 位的主要担忧是,这意味着 C FFI 可能非常脆弱。 如果开发人员不知道 AVR-GCC 使用 32 位双精度,那么通过 FFI 的调用可能会读取未初始化的内存或段错误。

我想我们可以通过期望用户使用libc板条箱中的类型来或多或少地解决这个问题。 我们可以添加特定于 AVR 的功能来将c_doublef32 。 我认为我们可以合理地期望人们在他们的 FFI 绑定中使用libc板条箱。

合并需要记住的东西,需要更新main()签名中使用的c_int类型: https :

编辑:为此打开了一个问题,因为它也会影响 MSP430: https :

在 main() 签名中使用

@mattico也许我只是以一种奇怪的方式做事,但我的代码都没有使用 Rust 的main

#[no_mangle]
pub extern fn main() {

更重要的是,我们无法真正返回,因为没有什么可返回。 每个程序都需要永远运行。

@mattico我们仍然肯定需要修改 libc,以便类型与 AVR 的 GCC 匹配

哦,当然,我只是不知道main会影响我们。

@shepmaster即使在非嵌入式平台上,main 中argc的大小也无关紧要,因为我们一直都错了,除了检查 IR 之外没有人注意到。 可能有一些 RTOS 为其进程使用标准的 main() 入口点? 无论如何,它很容易修复。

现在我想起来了,提交修复程序所花费的时间可能与输入此内容所花费的时间相同 😄

仅仅是 libcore 问题阻止了这次合并吗? 只是为了让我们知道在哪里集中精力。

我在 libcore 之外遇到的唯一问题是由我不知道是什么引起的奇怪的链接器错误以及 32 位位移错误(我认为缺少内在的错误)。 我不知道这些是否会阻止合并。

chocol4te:仅仅是 libcore 问题阻止了这次合并吗? 只是为了让我们知道在哪里集中精力。

是的——这里所有需要的工作都需要在 LLVM 中完成。

Restioson:我在 libcore 之外遇到的唯一问题是由我不知道是什么引起的奇怪的链接器错误以及 32 位位移错误(我认为缺少内在错误)。

那是因为所有使 AVR 后端阻塞的代码都被注释掉了 :)

Restioson:我不知道这些是否阻止了合并。

不是直接的,但最好在后端合并之前进行修复。 在合并之前,我们应该考虑修复一些像这样非常烦人的错误,但它们不一定能阻止它。

@dylanmckay LLVM6 已合并https://github.com/rust-lang/rust/pull/47828 - 这对这个 RFC 意味着什么?

@kellerkindt “AVR 后端的当前问题”中列出的所有问题仍然存在。 avr-rust 的当前 HEAD 可能会被重新定位,并且有趣的 Rust 特定代码被合并,但这仍然没有得到工作代码。

我个人还是赞成

我认为最好的方法是在 libcore 编译时无需修改,或者至少没有很多修改,就提出真正的补丁。

虽然不得不避免额外的变基好的。

我想知道 Rust 在 AVR 上的当前状态,现在我们已经开发了半年。 我在我的城镇经营一个小型 Arduino 项目组,我会_喜欢_能够使用 Rust。

所以,好消息!

我认为最好的方法是在 libcore 编译时无需修改,或者至少没有很多修改,就提出真正的补丁。

现在就是这种情况!

当前的 avr-rust fork 不包含对libcore任何修改。

从库存 Rus 支持 AVR 所需的修改是:

  • 声明并调用了 AVR 后端初始化函数LLVMInitializeAVR{Target,TargetInfo,AsmPrinter,AsmParser, ...}
  • 已添加基本最小 avr 目标规范avr-unknown-unknown 。 除非明确指定,否则这会模拟 avr-gcc 为最小公分母构建的默认行为。 不同于avr-gcc其中明确支持-mmcu=<avr mcu name>的说法,没有具体的AVR-命令行参数已添加了AVR。 这意味着必须为每个项目编写自定义目标规范 JSON 文件。 不过,许多 Rust 嵌入式项目就是这种情况。
  • 在 fork 中,AVR LLVM 后端始终在默认的 Rust 检出中编译和链接,并添加到config.toml.example文件中。 AVR 应该默认包含在上游 Rust 中,还是也应该选择加入?
  • AVR 特定逻辑添加到编译器中,所有新目标都需要
  • 添加了"avr-interrupt"调用约定。 这允许extern "avr-interrupt" fn my_isr_handler() { .. } 。 这可能需要通过 RFC 流程才能稳定下来,但我可能是错的。
  • 支持在 CPU 上进行条件编译,已添加#[cfg(target_cpu = "...")] 。 实现可以在这里找到。 它的实现与目标无关,因此它也适用于基于 CPU 的其他架构的条件编译,例如 ARM。 这允许ruduino板条箱有条件地包含一个特定于设备的模块,该模块公开芯片中支持的所有 IO、寄存器和模块。 这绝对需要在上游之前通过 RFC 流程。

我可能是时候向 LLVM-dev 发送一个关于将后端提升到非实验状态的 RFC。

您可以在此处查看从上游 Rust 到 avr-rust 的完整更改集。

目前我们仍然精选了过去两个月的几个 LLVM 补丁,但是上游 Rust 努力将 LLVM 的 emscripten 版本与用于所有其他目标的 LLVM 版本分开,这使得它非常容易引入这些变化来自rust-lang/llvm回购,因为它现在定期更新上游。

我们拥有的 <4 个精心挑选的 LLVM 补丁目前正在上游 LLVM 中进行审查,因此一旦审查者找到足够的时间,这些补丁将自动漂浮到上游 Rust 中。 上游 Rust 也有针对特定目标的 Rust 特定补丁,因此精心挑选的 LLVM 补丁可能并不是合并 avr-rust 上游的真正障碍

关于 AVR 上 Rust 状态的任何更新?

也有兴趣知道! 现在,我转而使用 STM32 蓝药丸进行黑客攻击,但是一旦 Rust 中对 avr 的支持准备就绪,我肯定想回到 arduino。

我们@slowtec也很乐意在我们的 AVR 项目中使用 Rust,当然我们会开源很多我们的生产代码:)

颠簸,希望看到官方支持。 将尝试使用 fork 进行项目。

更新:目前,我们正在将 fork 升级到更新版本的 Rust (avr-rust/rust#137)。 我们发现我们遇到了两个错误。

LLVM 错误:在寄存器分配期间用完了寄存器

这已在 llvm/ llvm-project@45eb4c7e55341c0b83a21dedecc092e273795eda 的LLVM 主干中

LLVM 错误:无法选择:t2:i16 = addrspacecast[1 -> 0] undef:i16
t1: i16 = undef
在函数中:_ZN4core3ptr87_$LT$impl$u20$core..fmt..Debug$u20$for$u20$unsafe$u20$fn$LP$A$RP$$u20$.$GT$$u20$Ret$GT $3fmt17h0fdf8ca7140def9b

这个更难修复。 它是由 Rust 错误处理哈佛架构上的函数指针引起的,哈佛架构有两个单独的指针地址空间用于访问主内存和程序内存。

最好的解释是@ecstatic-morse

潜在的问题是 *const T 总是有 addrspace(0)。 我认为显式转换(ptr as *const T)应该在此处保留其输入的地址空间。

该错误由函数和函数指针的std::fmt::Debug实现公开。 Rust 发出目标指针类型为addrspace(0)* i16的指针取消引用,使用 LLVM 例程将隐式插入位转换(iN -> iM 位)或地址空间转换(如有必要)。 在函数指针的情况下,Rust 应该编码生成一个addrspace(1)* i16指针,这样 LLVM 就不必将( addrspacecast )PROGMEM 指针映射到 RAM 指针,这是一项不可能完成的任务,因为没有内存映射并且地址空间不重叠。

这个错误是主要的障碍。

我希望上游 Rust 从 LLVM master 中提取(AFAICT,它几乎在 8.0 版本中),因此我们可以删除一堆精选的东西。

我最近使用 AVR 模拟器成功进行了https://github.com/dylanmckay/avr-compiler-integration-tests/测试,这很棒,因为没有其他测试套件实际执行由 LLVM 吐出的 AVR 程序集。 我设置了一个 GitLab 运行器来为每个 AVR-Rust 提交运行测试(通过 GitLab 存储库镜像),但它不是非常有用,因为 GitLab 不支持基于拉取请求的 CI 构建,因为实际代码托管在分叉存储库。

感谢@dylanmckay 的更新。 我们都感谢您为此付出的努力。

我们现在已经在 Rust 基础 rust-lang/ rust@fb7cca33f 上升级了 fork,blink 程序成功编译。

这个问题搁置了吗?

你有这方面的任何更新吗? PR 还在地址空间问题上停滞不前吗?

@dylanmckay ,抱歉

大家好,这是我的一些评论

樱桃采摘修复

几乎所有使libcore正常工作所需的修复都已上传到 LLVM master,目前存在于 rust-lang/llvm fork 中。 昨天我开始 PR 将 AVR fork 更新到 1.39.0 (avr-rust/rust#155),我只需要挑选一个不存在的修复程序 - avr-rust/[email protected]

libcore 不修改就不能编译

我们不再需要自定义的 libcore fork 来使用 AVR。 目前在 avr-rust 分支中只有一个对libcore修改 - avr-rust/ rust@44240ac59c5949b8a9fd191f5cd666d0206fbe85 - 重写指针转换以获得正确的 IR 生成。

我们依赖xargo来编译 AVR-Rust 二进制文件——随着 std-aware Cargo 计划的进行(包括工作组),这将变得更容易。 目前,AVR 需要为每个 MCU 类型编译一个 sysroot——我们目前使用 Xargo 来懒惰地编译它,但是当 Cargo 能够为所需的目标规范本地编译 core/std 时,它将更加无缝。

对除“调用”访问 RAM 以外的函数指针的任何操作,而不是程序存储器 (avr-rust#68)

这已被修复。

32 位移位生成对不存在的编译器 rt 例程的调用 (avr-llvm/llvm#163)

这仍然是一个痛苦的问题。 我怀疑最好的解决方法是在 LLVM AVR 后端编写自定义降低代码,将这些转变降低到纯汇编,消除对编译器 rt 或 libgcc 的任何 ABI 依赖。 我不确定生成的代码大小可以大多少,这可能不是一个好主意。

上游前的问题

RFC 和不稳定的调用约定

我将此评论发布到线程上

添加了“avr-interrupt”调用约定。 这允许 extern "avr-interrupt" fn my_isr_handler() { .. }。 这可能需要通过 RFC 流程才能稳定下来,但我可能是错的。

可以不经过 RFC 流程就添加不稳定的调用约定吗?

目前,我们在#![feature(abi_avr_interrupt)]功能门下有"avr-interrupt""avr-non-blocking-interrupt" 。 这些是否可以作为不稳定的调用约定上传,等待未来的稳定 RFC?

建造机器人

LLVM 后端的上游需要设置一个专用的构建机器人来运行该后端的测试并对其进行维护。 这是 Rust 的情况吗? 我们如何确保测试套件在每次推送时都以 AVR 模式运行? 其他后端(如 WASM)做了什么?

分配

“合并上游 avr-rust 分支”是否意味着简单地将两个分支合并为一个,但仍然需要从源代码构建? 也许可以分发后端,但仅限夜间? 其他后端做了什么?

除此之外,avr-rust 特定补丁非常薄,现在没有任何粗糙的黑客攻击。

完整的补丁集可以在这里看到https://github.com/rust-lang/rust/compare/master...avr-rust :avr-support

我的 WIP 1.39.0 rebase 补丁集(大部分相同)可以在这里找到https://github.com/rust-lang/rust/compare/master...avr-rust :avr-support-1.39.0-4560ea788c . 这应该在接下来的几天内合并到 avr-rust/master。

我想不出有什么具体的东西会阻止这个 - 也许,是时候提交补丁看看它是怎么回事了?

https://github.com/rust-lang/rust/issues/44036

我在上面提到了这个问题,但我认为它不会阻止 AVR 后端的上游。 我们应该能够在没有 AVR 的情况下使用 rustc 登陆一个有效的、有用的版本。 我确信我们可以采取一些变通办法和技巧。 在后端假设合并之后,在官方目标 CPU 查询 API 登陆官方 Rust 之前,同时在 AVR 板条箱中检测设备。

他活着! 感谢更新@dylanmckay ,令人兴奋的进展。

伟大的工作@dylanmckay! 感谢您让我们了解最新情况。

有点跑题了,但是: rustc for avr 能用 C 库做 FFI 吗?
有许多成熟的库可用于 avr,但都是用 C/C++ 编写的。
能够为它们创建一些 Rust 风格的包装器并在我们的 Rust avr 项目中重用它们会很棒。

通常,Rust 已经可以使用 C 进行 FFI。

是的,这真的很棒! 问题是:它会转化为 rust-avr 吗?

只要 LLVM 的 AVR 的 C ABI 与 gcc 的匹配,它就应该可以工作

可以不经过 RFC 流程就添加不稳定的调用约定吗?

我的投票是肯定的,因为支持 AVR 调用约定的更改基本上只是给它们一个名称并将它们映射到 LLVM 编号。 由于我们已经支持不稳定的约定,因此不需要进行基本的代码更改。

LLVM 后端的上游需要设置一个专用的构建机器人来运行该后端的测试并对其进行维护。 这是 Rust 的情况吗? 我们如何确保测试套件在每次推送时都以 AVR 模式运行? 其他后端(如 WASM)做了什么?

Rust 的层系统定义有点松散,但我认为正确的做法是合并AVR 特定的代码。 然后 AVR 将是第 3 层,这意味着它不会自动构建或测试,只是挂在代码中。 至少,这意味着这些文件将随着编译器的更改而保持最新。

“合并上游 avr-rust 分支”是否意味着简单地将两个分支合并为一个,但仍然需要从源代码构建?

据我所知,将一次提交作为 PR

也许,是时候提交补丁了

我认同。

@edvorg非常关注 IMO 话题

有点跑题了,但是: rustc for avr 能用 C 库做 FFI 吗?
有许多成熟的库可用于 avr,但都是用 C/C++ 编写的。

是的。。主要是。 AVR 后端实现的 AVR 调用约定旨在匹配 AVR-GCC(此处记录)。 有一些怪癖,但我需要查看的 LLVM 补丁D68524应该可以修复它们。

Rust 调用站点将始终能够正确调用 Rust 或 avr-clang 编译函数(因为 avr-clang C 使用与 Rust 前端相同的extern "C"调用约定实现),并且与 AVR-GCC 的互操作_应该_工作,尤其是对于简单的函数签名,但它有时会阻塞(有关更多详细信息,请参阅 D68524 的说明)。

这事有进一步更新吗 ?
只是好奇。

提交了使 LLVM AVR 后端成为官方后端的请求 - https://reviews.llvm.org/D75099

@dylanmckay如果接受,解决此问题的剩余部分是什么?

@dylanmckay如果接受,解决此问题的剩余部分是什么?

从技术上讲,Rust 将与官方和实验性后端一起使用。 我已经提出 #69478 用于后端的大部分上游。

我不确定将 AVR 合并为 Tier 3 目标是否取决于 AVR 成为官方 LLVM 后端 - 欢迎提出想法。

想想看,LLVM 官方和实验的区别可以映射到 Rust 的层系统上,其中 Rust 有三层,LLVM 有两层。 LLVM 官方后端对应于第 1 层和第 2 层的混合 - 基本上,包含在测试套件和官方版本中。 据我所知,LLVM 实验后端在语义上与 Rust Tier 3 后端相同; 包含在源树中,默认情况下不包含在版本中,不包含在默认 CI 测试中等。

然后我想解决这个问题的唯一剩余部分将是#69478 的代码审查中出现的部分。

tl; dr 如果合并,AVR 后端将成为 rust-lang/rust#69478 中的第 3 层上游目标,从而杀死分叉。

avr-rust/rust fork 和#69478 之间的唯一区别是target_cpu cfg 标志存在于 AVR fork 中但不在上游。 我已经把它排除在最初的 PR 之外。

剩下的部分是什么

我很确定仍然存在一些对各种类型代码的错误编译,因此它仍然需要更多的人来尝试并尽量减少错误并修复它们。

上流将降低人们尝试事物的门槛,因为他们可以每晚获得一个常规的 Rust,而不是编译通常过时的 fork。

一旦它作为第 3 层目标被上游化,AVR 开发将使用 Cargo 的-Z build-std功能,还是需要 xargo? Rust 附带的 LLD 是否支持 AVR,或者是否需要 gnu 链接器?

AVR 开发将与cargo 的-Z build-std功能一起使用,还是需要xargo? Rust 附带的 LLD 是否支持 AVR,或者是否需要 gnu 链接器?

我不能说那些不会工作,但我所做的一切已经使用Xargo和GNU接头。

GNU 链接器很难在 Windows 上设置,而 xargo 还需要安装一个工具,这就是我问的原因。

Rust 附带的 LLD 是否支持 AVR,或者是否需要 gnu 链接器?

LLD 只对链接AVR 有非常基本的支持,还不能链接任何真正的程序。 因此,将需要avr-ld

这就是我问的原因。

毫无疑问,我也认为这是正确的最终目标,它可能不是世界的当前状态。 老实说,我很乐意让开销越来越低。 合并它只是迈向这一目标的第一步。

AVR 后端现已作为官方 LLVM 目标启用 :tada: LLVM master 现在默认包含 AVR 支持。 大约 6 个月后,第一个默认包含 AVR 的 LLVM 版本将是 LLVM 11。

好的! 感谢您为此付出的所有努力。

很酷!

祝贺@dylanmckay取得这一令人难以置信的成就。 社区感谢您为此所做的工作。

我已经关注这个问题一段时间了,虽然我知道这主要是题外话,但我很感兴趣这对普通的非源用户意味着什么......获得一个复杂的过程是否Arduino Uno 使用本机 Rust 启动并运行? 我对此最感兴趣,因为 Rust 有足够的保护,我可能不会引起几乎那么多的 oops 时刻 xP

@Jimmio92 据我所知,是的。 如“是的,这很复杂”。 或者至少是冗长乏味的,即使不是特别复杂,因为您仍然需要从源代码构建 Rust 编译器的这个自定义分支,这也需要从源代码构建 LLVM。 如果一切顺利,这通常需要几个小时

然而,我个人对 LLVM 的经验是,通常情况下,它只是不喜欢你系统上的某些东西(至少在 macOS 上是这样——它在 Linux 上更容易,当然甚至不希望在 Windows 上这样做),所以你不可避免地最终会修改安装路径和自定义库,直到你成功或放弃。

上述(极好的)消息仅意味着:LLVM 的开发人员现在正式瞄准/支持 AVR(?),并且 LLVM 的下一个版本将包括 AVR 支持。 没有什么可以说 Rust 现在也支持或将在短期内支持 AVR。 如果您查看这些问题和上述评论,您会发现需要大量工作才能使 AVR 支持与 Rust 工具链一起“正常工作”。

是否有一个过程/示例可以让我查看从 LLVM master 到 Rust LLVM fork 的挑选 AVR 修复?

另外,Rust 是否仍然跟踪 LLVM master? 从它的外观来看,它跟踪当前版本以及一些精心挑选的修复程序。 是否仍然接受将 LLVM 版本更新为 master 的 PR?

@dylanmckay

另外,Rust 是否仍然跟踪 LLVM master?

正如您所注意到的,它现在跟踪发布。

是否仍然接受将 LLVM 版本更新为 master 的 PR?

我不这么认为,但抄送@nikic

@dylanmckay与 10.0 版本相比,Rust 的 LLVM 分支有很多修复: https :

是否有一个过程/示例可以让我查看从 LLVM master 到 Rust LLVM fork 的挑选 AVR 修复?

这里有可用的说明: https: //rustc-dev-guide.rust-lang.org/backend/updating-llvm.html#bugfix -updates

另外,Rust 是否仍然跟踪 LLVM master? 从它的外观来看,它跟踪当前版本以及一些精心挑选的修复程序。 是否仍然接受将 LLVM 版本更新为 master 的 PR?

Rust 目前跟踪 LLVM 版本,因为这允许人们使用相应的 clang 版本轻松执行跨语言 LTO。 所以这里的默认答案可能是“否”。

也就是说,已经有一些关于更新到 LLVM master 以减轻 LLVM 10 编译时回归的讨论。 我目前正在为此进行评估。 我认为假设这不会发生更安全,并针对我们的 LLVM 10 分支提交精选(有很多吗?)

分叉已合并! 今天下午我会写一个适当的更新

https://github.com/rust-lang/rust/pull/69478

今天下午我会写一个适当的更新

我对上述更新感兴趣。 你打算把它在哪里

多年来,我一直在热切地等待 Rust 生态系统的这一补充! 然而,我天真地尝试在 master 上使用它似乎有缺陷。

我使用标准./x.py build构建了 master rust,链接为工具链master ,然后尝试构建 avr-rust/blink 示例(在更新src/main.rs以使用llvm_asm! ):

RUST_TARGET_PATH=`pwd`
XARGO_RUST_SRC=/home/nixpulvis/Projects/rust

rustup run master xargo build --target avr-atmega328p --release

这失败了:

error: no matching package named `core` found
location searched: registry `https://github.com/rust-lang/crates.io-index`
required by package `sysroot v0.0.0 (/tmp/xargo.oXlxlujoXvXJ)`
error: `"cargo" "build" "--release" "--manifest-path" "/tmp/xargo.oXlxlujoXvXJ/Cargo.toml" "--target" "avr-atmega328p" "-p" "core"` failed with exit code: Some(101)
note: run with `RUST_BACKTRACE=1` for a backtrace

我假设仍然需要我缺少的配置。

@nixpulvishttps://github.com/rust-lang/rust/issues/44052#issuecomment -591396417

我不希望现在有很多东西可以工作,因为 libcore 是错误编译的一部分。

AVR rustc fork 已经合并到上游。

上游叉一般还不能使用。 有一些事情需要先发生。

AVR LLVM 上游修复了 Rust 还不需要精心挑选的问题

要回答@nikic的问题,最多需要挑选 20 个 LLVM 提交。

我一直在使用一个脚本来自动从 LLVM 上游挑选 _all_ AVR 提交到本地分支。
这是一个很大的锤子,会有一些不必要的精心挑选的修复 - 在后端变得可用之前,需要将上游 LLVM 修复拉到上游 Rust。 它们需要被过滤掉并被挑选到上游 Rust。

从上游 Rust 主分支编译 AVR LED 闪烁程序

由于上游的努力已经进行了几个月,下游的 avr-rust fork
仍然在一个特别旧的 Rust 版本上。 从那以后,上游 Rust 至少发生了一项变化,需要泛化以支持 AVR 而不会遇到 LLVM 断言错误。 我已经打开拉取请求 #73270 来修复它。

我不确定上游 Rust 是否有其他更改需要对 AVR 进行更改 - 可能没有。

一旦我让眨眼程序工作,我将发布另一个更新,因为那时,上游 AVR 支持应该可以使用/实验了。

AVR 通信应该在哪里发生/发布

@wezm你提出了一个很好的观点 - 不一定有一个“祝福”的更新沟通渠道。 这张票服务很好,但它不可避免地很快就会关闭。

AVR-Rust Gitter通道是最自然的现有选择。 我喜欢邮件列表的想法(但如果可能的话,我不喜欢托管邮件服务器的想法)。 Gitter 频道确实有讨论,所以也许像邮件列表这样的东西会有所帮助。
也许建立一个博客会有助于集中发布/更新。 我想要一个“官方媒体”,这样那些想要随意更新的人就不会错过。 我认为博客需要不断检查新帖子,而邮件列表本身会通知
每个有兴趣的人。 欢迎提出建议。

开放问题

  • avr-rust 分支上的 GitHub 问题是否应该移动到上游 Rust 存储库?
    ** 无论如何,应该在上游存储库上提出新问题 - 旧问题跟踪器将需要结束。

    • 使用 AVR 编译 Rust 的说明应该在哪里?

未来最重要的事情(阅读:优先事项)

  • AVR Rust 二进制文件的打包和分发。 编译 Rust 对普通用户来说可能是一个很头疼的问题,
    许多发行版在某些工作流程中似乎不时出现问题。 几个 OOM 错误被误报为
    编译器错误。 进入门槛不必要地高,需要降低 - 只需下载并开始。
    https://github.com/avr-rust/rust/issues/162跟踪
  • 构建“受支持”或至少经过测试的配置列表。 我们需要一张(rustc version, Xargo version)的表格,所以
    Xargo 所依赖的私有 Rust API 的更改不会在升级时破坏 AVR Rust 工具链。
    Xargo 处于维护模式-cargo-xbuild 似乎非常有限(我几周前尝试过,我不记得原因了),
    我们可能需要分叉 Xargo。 也许最好将工具直接添加到 Cargo 中(这有一个跟踪问题)。
  • 为项目设置某种主页,包括下载链接
  • 集成测试(在模拟/模拟 AVR 上,每次提交时)

目前,我会确保将更新重新发布到这个 GitHub 问题中,直到找到更好的媒介。 我也会将它们发布到 Gitter 中。

也许建立一个博客会有助于集中发布/更新。 我想要一个“官方媒体”,这样那些想要随意更新的人就不会错过。 我认为博客需要不断检查新帖子,而邮件列表本身会通知
每个有兴趣的人。 欢迎提出建议。

我个人偏爱博客(带有 RSS 提要)。 我认为博客通常在搜索引擎结果中显示得更好,并且比邮件列表线程更易于链接。 RSS 提要解决了检查/通知方面的问题。

我不是 100% 确定它是最好的地方,但有 Embedded WG 博客。 可能是一个省力的沟通渠道。

https://rust-embedded.github.io/blog/

也许也是一个推特账户? 它可用于分享新的博客文章(以保持最新)。

我认为嵌入式工作组很乐意在这里提供帮助。 我们有一个 Twitter 帐户@rustembedded ,当然也可以在时事通讯中包含与 AVR 相关的新闻。

不久前我还创建了O-AVR标签,所以也可以随意使用 Rust 问题跟踪器来处理特定于 AVR 的问题(但请注意,有 1.5k 人在观看 repo)。 除此之外,您可能希望在 rust-lang Zulip 上进行协调,因为大多数 Rust 团队都驻扎在那里。 我们也在增加专注于特定 Rust 目标(例如 Windows 或 Arm)的“目标群体”,AVR 可能也很适合。 为此,请随时联系 Zulip。

更新。

libcore可以在股票 rust-lang/master 分支上为 AVR 编译之前,还有两件事:

  1. 有一个拉取请求修复了 AVR 上的一系列“地址空间转换无效”错误,涉及如何将哈佛架构的函数指针标记为addrspace(1) addrspace(0) 。 rust-lang/rust#73270 -目前正在代码审查中。

〜2。 还有另一个错误阻止blink示例工作 - avr-rust/rust#92。 有一个尚未上传的补丁可以修复它 - https://reviews.llvm.org/D68524。 一旦它通过单元和集成测试,这将被上游化,然后很快被挑选到 Rust 的 LLVM 分支中。~它已合并到上游 LLVM

完成这两件事后,上游的 Rust AVR 目标将能够将 AVR 代码编译到与当前 avr-rust/rust fork 相同的级别,然后我们可以开始更新blink示例的过程, arduino板条箱、文档、指南,用于上游分支。 然后上游分支应该准备好进行实验使用。

还有一个 TODO:

  1. ~为上游 Rust 中的新内联汇编语法添加 AVR 管道~

    • ~一旦支持新的内联汇编语法,必须更新 Arduino crate 才能使用它

      Arduino crate 更新后,将blink crate 更新到新版本。~我们现在可以通过llvm_asm!使用旧宏,因为它仍然存在于nightly 中。

  2. Cherry-pick AVR 正确性补丁(主要是 Ayke 的)从 LLVM master 到上游 Rust LLVM fork(编辑:PR:https://github.com/rust-lang/llvm-project/pull/66)

这是包含所有内容的分支: https :

它是从上游rust-lang/master构建的,但还包括尚未上游的 LLVM 补丁D68524 、尚未合并的 Rust PR rust-lang/rust#73270,以及来自上游 LLVM 的 46 个与 AVR 相关的提交,通过自动挑选脚本(LLVM 分支:https://github.com/dylanmckay/llvm-project/commits/dylan/avr-workable-upstream-candidate)。 请注意,并非所有 46 个都是必需的,最终列表会更小。

更新:打开了一个包含所有上游 LLVM 修复的拉取请求。

这是 LED 闪烁程序可以编译并成功运行之前剩余工作的详尽列表。

剩下的工作

  • [x] Land Rust PR rust-lang/rust#73270 。 此拉取请求修复了 AVR 上的一系列“地址空间转换无效”错误,这些错误涉及哈佛架构的函数指针必须如何标记为 addrspace(1) 与 Von-Neumann 目标相比,Rust 当前默认的 addrspace(0) 很好. 目前正在代码审查中。
  • [x] Land Rust LLVM PR https://github.com/rust-lang/llvm-project/pull/66 。 这将所有必需的 AVR 修复从上游 LLVM 拉入 Rust 的 LLVM 分支。 最后,有大约 17 到 16 个 LLVM 修复需要精心挑选。
  • [x] Land Rust PR rust-lang/rust#73658 更新 LLVM 子模块的版本。 Rust 编译器文档有这样做的说明。 目前正在代码审查中
  • [x] Land Rust PR ~rust-lang/rust#74625~ rust-lang/rust#74631 。 在 79a42e37084d0 中,Rust 开始无条件地将--eh-frame-hdr参数传递给链接器。 AVR-GCC 链接器不支持此标志,因此为 AVR 添加了一种避免传递它的特殊情况,类似于 Windows 的现有排除项。 Solaris 和 UEFI。

也许最好将工具直接添加到 Cargo 中(这有一个跟踪问题)。

我假设这是正确的问题:rust-lang/cargo#4959。

cargo build -Z build-std=core在我的 AVR 示例案例中运行良好。

@shepmaster似乎让我更接近了,谢谢! 我现在似乎被困在 bitcast 的东西上,所以我会等待它被合并(因为我似乎缺少构建 PR 所需的文件,而 IDK 我正在做什么)。

在使用-Z build-std=core的过程中,我需要提供一个目标三元组,所以我运行了rustc +master --print target-list | grep avr ,并找到了avr-unknown-unknown 。 但是存档的问题 avr-llvm/llvm#35 似乎使它听起来像三元组实际上应该是avr-atmel-none (无论如何对我来说更有意义)。 这里有什么需要更新的,还是我遗漏了什么?

avr-unknown-unknown是正确的。

开放问题

* Should GitHub issues on the avr-rust fork be moved to the upstream Rust repository?
  ** Regardless, new issues should be raised on the upstream repository - the old issue tracker will need to be wound down.

* Where should the instructions for compiling Rust with AVR live?

我认为这对用户来说并不重要。 这很容易通过 ddg 和/或 this-week-in-rust 找到。
无论如何让开发人员更容易。

开放问题

* Should GitHub issues on the avr-rust fork be moved to the upstream Rust repository?
  ** Regardless, new issues should be raised on the upstream repository - the old issue tracker will need to be wound down.

* Where should the instructions for compiling Rust with AVR live?

我认为这对用户来说并不重要。 这很容易通过 ddg 和/或 this-week-in-rust 找到。
无论如何让开发人员更容易。

我认为使用 AVR 编译 Rust 的说明应该在https://docs.rust-embedded.org/

好的,更新时间。

从今天晚上的rustc 1.47.0-nightly (0820e54a8 2020-07-23) ,当前的 Rust 夜间编译器中存在 AVR 所需的所有补丁。 Rust nightly 编译器无需修改,现在可以成功编译 LED 闪烁示例并生成 AVR ELF 文件。

  • https://avr-rust.com/创建的新的、集中的项目登陆页面
  • 一本新书 - AVR-Rust 指南已创建,托管在 GitHub 页面 book.avr-rust.com 上。
  • avr-rust/rust fork 存储库已被弃用。 存储库尚未存档,因为存在应在永久锁定和关闭之前迁移的现有问题。
  • 不再需要 Xargo - 上游 Rust 中的-Z build-std标志取代了 AVR 上对它的需求。 不再需要货叉——上游货物就可以了。

现在可以将 Rust nightly 编译器视为具有 AVR 支持的 Rust 的推荐频道。

我现在正在关闭这个问题 - 我们做到了!

报告错误的步骤可以在AVR 指南中找到。

https://github.com/avr-rust/blink上的AVR 指南和闪烁示例是开始使用目标的最佳资源。

深深地感谢所有通过这种上游努力讨论和支持该项目的人 - 非常感谢。

哇哇哇。

感谢为此做出贡献的所有人——我一直期待着这一天!

Dylan McKay 在将 Rust 移植到 avr 之前

image
之后
image

感谢所有努力工作的人! :-) 好好休息!

此页面是否有帮助?
0 / 5 - 0 等级