Hacker News new | ask | show | jobs
by throwaway894345 1516 days ago
Unless something has changed in the relatively recent past, I think you're overselling a fair bit. Not only does the package author have to understand the C dependency well enough to package it correctly on all platforms (basically by verifying the build in a hermetically sealed environment, and who is doing that?), but also the process for cross compiling is (or at least was) pretty complicated: https://www.modio.se/cross-compiling-rust-binaries-to-armv7..... And even then, I'm not sure this will yield a truly static binary (i.e., no dependency on libc).

In Go, it's just `CGO_ENABLED=0 GOARCH=armv7 GOOS=linux go build` for pure Go programs.

1 comments

> (basically by verifying the build in a hermetically sealed environment, and who is doing that?)

Lots of people run stuff in CI, which isn't exactly that, but is close enough to make it not as big of a pain as it might otherwise be.

It can also help if their docs aren't great; I've looked at CI configs to realize how to install some sort of system dependency before.

> but also the process for cross compiling is (or at least was) pretty complicated

Most of this article is talking about installing and setting up both Docker and a C cross-compiled toolchain. So, you're right, but also not, sorta kinda. That is, this is certainly more hard than Go, but we're not talking about pure Rust at this point, so the fair comparison would be cgo with some C dependencies, which would also involve setting up a C cross-build toolchain, (and maybe docker). But at the same time, it doesn't have to be this way: Zig includes a full C cross toolchain in its compiler, so that you don't have to do this installation. It is, in my opinion, currently best-in-class here, far surpassing both Go and Rust.

It is also worth nothing that, IIRC, Go had to switch to dynamically linking libc on many platforms, since the idea of a "fully statically linked binary" is basically only coherent on Linux.

> Lots of people run stuff in CI, which isn't exactly that, but is close enough to make it not as big of a pain as it might otherwise be.

CI has a whole lot of variation. On the extreme end, there are people running Jenkins jobs on the same hosts as other jobs, and everyone just pre-installs whatever they need onto the base image for the host (i.e., not even working with a fresh OS image). Moreover, many people are just going to run their CI on amd64 Debian or RHEL and assume it works for all targets.

> That is, this is certainly more hard than Go, but we're not talking about pure Rust at this point, so the fair comparison would be cgo with some C dependencies

My whole thesis here is that Go leans less on FFI than other ecosystems, so you shouldn't need CGo in most cases where you would have to use FFI in other languages. It's a lot easier to get a pure-Go dependency tree than it is a pure-Rust dependency tree. Of course, that's an emergent property derived from weaknesses of Go's FFI, but it ends up being a really nice property in practice.

> But at the same time, it doesn't have to be this way: Zig includes a full C cross toolchain in its compiler, so that you don't have to do this installation. It is, in my opinion, currently best-in-class here, far surpassing both Go and Rust.

I think this is true if you assume that all ecosystems lean on C equally, but it's better by far to depend on C less because including the C cross toolchain doesn't absolve you from humans packaging C dependencies (in which case it's either easy because you neglect a bunch of packages or you test in a hermetic environment a la Nix and it becomes more bothersome than maintaining a pure-$hostLang version of the same package).

> Moreover, many people are just going to run their CI on amd64 Debian or RHEL and assume it works for all targets.

Rust has a strong concept of "tiered platforms", and so lots of people support at least Mac/Windows/Linux. Nobody uses Jenkins (for open source packages that will become your dependencies, at least), they use GitHub Actions or CircleCI, which make it easy to support many platforms. I personally run Windows, no WSL, and 99.99% of the time, everything Just Works for me.

But yes, that's why I wasn't saying it's purely just as good. For sure. But it does generally work well.

> My whole thesis here is that Go leans less on FFI than other ecosystems,

Gotcha, that's fair. Pure-x for any x often is really, really nice! Full agreement there.

> Gotcha, that's fair. Pure-x for any x often is really, really nice! Full agreement there.

Yeah, and it's really interesting how the relative ease/difficulty of FFI shapes an ecosystem. On one extreme, you have Go which has a lot of purity, but on the other you have Python where FFI is so easy that the maintainers can't really change anything including optimizations without breaking compatibility which means pure Python packages are relatively slow driving more reliance on FFI. It also means the package management tooling has to solve for the universe of C packages to be worthwhile, which drives a whole bunch of other problems. A decade ago, if you had asked me whether easy FFI was a good thing or a bad thing, I would have unequivocally said "a good thing". That might've been the correct answer if the lingua franca had a standard concept of reproducible builds.