rust vs golang 交叉编译

2024 年 11 月 18 日
 bli22ard

Golang

Golang 的交叉编译简直太容易了,只需设置 GOOS=linuxGOARCH=amd64 这两个环境变量,然后运行 go build。如果你的代码没有使用 CGO ,基本上都能顺利编译成功。

Rust

reqwest 这样的 HTTP 库,TLS 实现默认依赖 OpenSSL ,这会让交叉编译变得复杂起来,因为需要用到 C/C++ 的工具链,还要考虑不同的 libc 是 GNU 还是 MUSL 。虽然 Rust 也有一个纯 Rust 实现的 TLS 库 rustls,但它依赖 ring 库,而 ring 又使用了一些 C 代码,据说是为了实现加密算法的硬件加速。这些问题使得使用 TLS 的 Rust 程序交叉编译变得异常困难。

即使是在架构、系统、libc 都一致的环境下,想要静态链接编译 Rust 程序也非常麻烦。Rust 团队提供了一个工具 cross,但遇到 OpenSSL 时也可能会束手无策。

Rust 发展了这么久,为什么不能提供一个原生的、零依赖的 TLS 实现呢?

结论

Rust 完败

6062 次点击
所在节点    程序员
52 条回复
pursuer
2024 年 11 月 18 日
C/C++的静态交叉编译,glibc 是个坑我得承认,感觉上 musl 静态编译的话应该还好吧?当然 C++动态库 ABI 那就是另一个天坑暂且不提了。
mxT52CRuqR6o5
2024 年 11 月 18 日
听说把 linker 换成 zig 能解决很多交叉编译中的问题
sunny352787
2024 年 11 月 18 日
golang 的交叉编译有坑的,你能编译通过并不意味着你运行正常,之前我用 golang1.22.6 在 macos 上编译一个 windows 版本的程序,时区相关的库各种报错,在 windows 上编译就没问题
PTLin
2024 年 11 月 18 日
请问你是没了解过 rustls 吗,reqwest 也有 rustls 的 feature 呀???
PTLin
2024 年 11 月 18 日
一看 id ,原来又是哥们你呀。。。
bli22ard
2024 年 11 月 18 日
@pursuer aarch64-musl openssl 太难搞。
PTLin
2024 年 11 月 18 日
下次在得出 rust 发展这么久为什么还没有 rust 实现的 tls 的结论之前能不能拜托你去搜一搜,rustls 好歹 crates 上一亿的下载量。
bli22ard
2024 年 11 月 18 日
@mxT52CRuqR6o5
zig 貌似也有一些问题

@sunny352787
没用 cgo 情况下,golang ,linux 、mac 、windows 互相交叉编译没遇到过问题


@PTLin
😄,reqwest = {version = "0.12",default-features = false,features = ["rustls-tls"]} 加了这个, 但是编译时候,需要 gcc 来编译 ring
bli22ard
2024 年 11 月 18 日
@PTLin


(base) PS C:\Users\3\RustroverProjects\rs-certbot> cargo tree --target=x86_64-unknown-linux-musl -i ring
ring v0.17.8
|-- instant-acme v0.7.2
| `-- rs-certbot v0.1.0 (C:\Users\3\RustroverProjects\rs-certbot)
|-- rcgen v0.13.1
| `-- rs-certbot v0.1.0 (C:\Users\3\RustroverProjects\rs-certbot)
|-- rustls v0.23.16
| |-- hyper-rustls v0.27.3
| | |-- instant-acme v0.7.2 (*)
| | `-- reqwest v0.12.9
| | `-- rs-certbot v0.1.0 (C:\Users\3\RustroverProjects\rs-certbot)
| |-- reqwest v0.12.9 (*)
| `-- tokio-rustls v0.26.0
| |-- hyper-rustls v0.27.3 (*)
| `-- reqwest v0.12.9 (*)
|-- rustls-webpki v0.102.8
| `-- rustls v0.23.16 (*)
`-- x509-parser v0.16.0
`-- rs-certbot v0.1.0 (C:\Users\3\RustroverProjects\rs-certbot)
(base) PS C:\Users\3\RustroverProjects\rs-certbot>




(base) PS C:\Users\3\RustroverProjects\rs-certbot> cargo tree --target=x86_64-unknown-linux-musl -i openssl-sys
error: package ID specification `openssl-sys` did not match any packages
(base) PS C:\Users\3\RustroverProjects\rs-certbot>
Felldeadbird
2024 年 11 月 18 日
@sunny352787 体会过这个现象。不过我的项目用到一些私有库,所以不同平台结果不一样。解决办法就是对应平台编译对应版本。
zengxs
2024 年 11 月 18 日
因为 rust 一直试图去兼容 c/c++ 那一套生态,他生态里面很多 lib 都是直接调用了 c/c++ 的代码,所以把 c/c++ 糟粕的一部分也全盘接收了

不像 go 完全另起炉灶,生态基本上不依赖 c/c++,所以就没有这些问题
undeflife
2024 年 11 月 18 日
> 如果你的代码没有使用 CGO ,基本上都能顺利编译成功

你用这一句话就在 go 里把 rust 里碰到的问题跳过了,至于解决方案楼上已经说了。

至于你的疑问,但凡搜一下就能知道答案。

结论,楼主很擅长钓鱼。
seers
2024 年 11 月 18 日
go 这点还不错,一些基础设施做了实现,cgo is not go
Donaldo
2024 年 11 月 18 日
可以试试这个
> rustls-rustcrypto - an experimental provider that uses the crypto primitives from RustCrypto for cryptography.
MrKrabs
2024 年 11 月 18 日
结果就是性能稀烂
yplam
2024 年 11 月 18 日
@undeflife 你动手试试就知道楼主说的是事实,Golang tls 不需要 cgo ,tls 这种基础库 rust 官方一直没有实现实在说不过去
ihciah
2024 年 11 月 18 日
要用 openssl ,开 vendored 这个 feature 就静态链接了。
ninjashixuan
2024 年 11 月 18 日
cgo 不是 go ,所以 go 交叉编译还是挺好使的。
bli22ard
2024 年 11 月 18 日
@zengxs 感觉确实是这个思路,感觉大多数时间花费在搞编译器上了。


@undeflife golang ,带硬件加速的加密算法,以及 tls ,都是标准库自带,不依赖 cgo 。加密算法,以及 tls ,rust 没有全部原生 rust 实现。


@Donaldo 这个没试过,我是看到 rustls 里面有用到 ring 库。


@MrKrabs 性能快的不是特别多,但是带来的麻烦不小


@yplam 一看就是搞过的



@ihciah 看到过这个,但是没测试过,有时间试下
doraemonki
2024 年 11 月 18 日
go 的交叉编译确实是最简单好用的

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1090526

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX