pleroma.debian.social

pleroma.debian.social

RE: https://society.oftrolls.com/@hrw/116968680594479065

I am waiting for programming language where each binary will require rebuilding whole stack.

Your package ships 3 binaries? You build everything three times. Simple.

Rust world will not even notice.

RT: https://society.oftrolls.com/users/hrw/statuses/116968680594479065

@hrw costless abstractions \o/

@hrw I think you just described NixOS (ducks)

@edolnx As long as I do not have to deal with Nix I do not care.

But I am now waiting for package written in this @%@#%$$ language to build.

It goes through compilation of 600+ rust 'packages' because this is how they prefer to kill this planet.

Instead of compiling each of them once, during their 'package' build.

@hrw The entire dynamic linking system is an old cruft that only supports C. Other languages must dumb down to what C can do, and anything that doesn't fit 1980s ABI ends up static.

Dylibs can't work with monomorphic generics. Java & C# reinvent their own JIT-based linking. Rust can't.

The problem isn't new. C++ has the same problem, but you don't see it, because people copypaste "header-only libraries", so a dozen of NIH C++ leftpads looks like one package on the outside.

@kornel that's the reason why language designers should use twenty years old middle class computers.

Building software with 600+ rust parts takes ages on slow hardware.

And rebuild of it in isolated environment (read: distribution package build) takes another ages.

Have to remember for the future: do not even try to fix software written in this language.

@hrw you're implying that the builds are heavy due to ignorance, but it's a hard set of requirements of max runtime performance + safety and correctness + backwards compatibility with native linkers, elf and distros.

Lots of effort goes into making builds faster, but ultimately there's a lot of work thrown at LLVM, and you're probably paying the horrible cost of LTO.

Distro package managers refuse to support flexibility of Cargo, so they treat it as opaque black box and don't cache anything.

@kornel risc-v is so slow that we disabled LTO.

@hrw I build the 300K+ Cargo packages for https://lib.rs/stats on a single box. It can be fast. I get 90%+ cache hit rate, but my build setup understands Cargo workspaces and lockfiles, instead of treating them as a black box that throws it all away.

@hrw There's a painful lack of interop between Cargo and distro package managers. Cargo could be less opaque.

Cargo's dependency resolution is really good, solving a bunch of painful dep management problems, but when distros only build/cache at distro package level, while refusing to have versioning compatible with Cargo's semver and no feature flags, they end up without ability to have per-crate caches and per-crate rebuilds.

@hrw and distros that want to update dependencies just by dropping a new file on disk want make it easy for themselves, but create a lot of pain for library authors maintaining ABIs and supporting wide ranges of oudated or inadequately configured deps.
Cargo has lockfiles that are precise enough for tracking what needs to be rebuilt on dep update, and incremental caches that make it almost quick as re-linking, but distros don't integrate with that.

@kornel thanks for long explanation.

Distros were always at war with language package managers. Python, Javascript, Golang and now Rust.

Different approach to things plus different expectations end in mess we have to deal with.

Ccache solves a problem with C/C++. Will have to look how to solve cargo cache then.

Thanks again.

@hrw sccache supports Rust. Works best when you build in a container that has consistent env and same file paths to build dir across builds, since sccache's cache key depends on those.

@kornel
C++ actually does support dynamic linking. On POSIX systems it does this by encoding the argument types into the symbol name. Not sure how it works on Windows but most of Windows is C++ and it does have DLLs so clearly it's possible.

Dynamic linking is really just mmap() plus a lookup table of symbol name to compiled code. It's not rocket science and absolutely not C specific, but it does require a reasonably stable ABI to make it work.
@hrw

@wouter @hrw Only if all of the generic types exist in the same binary. You can't have dynamically linked dll::TheirTemplate<exe::MyType> without introducing runtime polymorphism (or bringing the library's source code via .h that bypasses linking and is not in the dll).

Swift ABI went to great lengths to make it possible with polymorphisation and witness tables. Rust doesn't have that, mainly because for performance it wants generics monomorphic (inlining code from libraries is the point).

@kornel
Oh, I see now what you mean.

Yes, if you want to do any type of code generation, be that C++ templating, C preprocessor macros, or eval-type stuff in scripting languages, you can't do dynamic libraries for those parts of your language. In C++, the STL is typically header-only for that reason, but C++ still has a substantial standard library that is dynamic.
@hrw

IOW, having part of your language that can't be dynamically linked doesn't mean that's true for all of it, nor that there is no benefit at all.

I don't know though about rust to have a meaningful discussion about its ability to benefit from dynamic linking but if it relies on code generation to a large extent then yes obviously it becomes complicated.
@hrw @kornel
replies
1
announces
0
likes
1

@wouter @hrw Rust has implemented support for dynamic linking (-C prefer-dynamic).

The problem is that the generics and aggressive inlining leave half of the code in the exe and half in the dylib, so the ABI becomes very version-specific. Even though dynamic linking technically happens, it doesn't do what distros hope to do - upgrade the library by dropping a new file on disk.