News for hackers. Stuff that matters.
Re:Rust Without Crates.io by chrismorgan on Tuesday November 14, 2023 @06:03AM (#38261726)
> What’s interesting is that this problem is largely solved for C and C++: Linux distributions like Debian package such a wide range of libraries that for many things that you want to develop or install, you don’t need any third-party libraries at all.

This does not reflect my observations at all. It works if you’re an end user and the software you want has been packaged. But if either of those is not the case, you’re left in the mud. Rather, you end up with builds that are difficult to set up or reproduce except on specific platforms, require a lot more maintenance over time because bitrot occurs naturally (your code depends on libexample 1, but Debian only package version 2 now, so good luck dusting off that project you made five years ago and getting it to build again), vendoring upon vendoring, more diverse and generally lower-quality dependencies for a particular task, and other problems like these. You’ve solved one problem, but at a very significant cost that must be acknowledged, even if you decide it’s still worth it.

Take an app written five years ago that depends on majorish C++ libraries, and there’s a fair chance compiling it will be a nightmare and require invasive surgery due to version incompatibilities. It’s not improbable that the most pragmatic solution may be to find and rebuild the transitive package tree for some older version of some package, and that’s generally quite painful (and can be outright incompatible).

Take an app written five years ago in pure Rust, and it’ll almost certainly (p>0.99) still work fine. Take an app written five years ago in Rust that binds to some C/C++ library, and there’s a fair chance you’ll run into trouble, but it will almost certainly be a good deal easier to resolve, much more likely to work with only a version bump and no other changes than in C/C++.

As a developer, I know which general mode of operation I prefer. Debian are welcome to twiddle the dependencies in the way that suits their chosen requirements, but the canonical sources are still crates.io, and I know that when they’ve stopped packaging example-1.0.0, I won’t be beholden to their packaging but can just use `cargo build` and it’ll still work (contingent upon extern bindings).

I’m dubious that any meaningful curation is happening, and curious if there’s even cursory review of crate contents. I’d be interested in a statistical comparison of the crates that Debian ships with the most-downloaded crates from crates.io.

Re:Rust Without Crates.io by josephg on Tuesday November 14, 2023 @07:23AM (#38262428)
Yeah. The part that gives me goosebumps with that proposal is: as an author of some not very popular packages, what do I do? Is it my job to package and promote my packages on Debian, redhat, homebrew, and all the others? Do I need usage before they’ll pick it up? Sounds like a chicken and egg problem.

It’s also quite common for me to pull out bits of code I’ve written that I want to share as a dependency between different programs I write. I have dozens of packages in npm along these lines - and it’s quite elegant. I factor out the code, package it independently, write a readme and some tests and publish it. My other packages can then just depend on the brand new package directly. In this brave new world the author is proposing - what? I make a .deb, argue for it on some mailing lists I’m not on, wait who knows how long, eventually gain permission to depend on my own code, then realise I can’t install it on my Mac laptop and do the same dance in homebrew? Oh - there’s a bug. Better manually update all the package repositories? Sounds like a complete nightmare to me.

I’m sympathetic to the problem. Supply chain attacks are way too easy. But maintaining up to date packages on every single Linux distribution, homebrew, ports, and whatever windows does sounds like a full time job. A boring full time job. And it would still not work as well for my users, because when a new feature is released in one of my upstream dependencies I can’t use it until all of those package repositories ship the new version of my upstream dependency too. I’d rather eat sand.

“It works for C/C++” by making developers working in those languages pay in blood for every dependency they pull in. You can tell by looking at just how few dependencies the average C program uses. It’s like that because of how painful it is. Anything under a certain size tends to get either reinvented every time, badly (hash table libraries in C) or vendored (eg json parsers). Common libraries like rust’s rand don’t exist in C because it’s just too much effort to pull in dependencies. So everyone rolls their own crappy version instead. Ask GTA5 how well that went for them. And that’s not the developer ecosystem I want to work in. It’s frankly a terrible proposal.

Re:Rust Without Crates.io by mid-kid on Tuesday November 14, 2023 @07:41AM (#38262590)
When you make a new library for C/C++, you generally just install it locally at first (pkg-config and PKG_CONFIG_PATH make this trivial). It doesn't (need to) get packaged by a distribution until a program using it is packaged. You don't need to do this yourself, unless you yourself use a distribution and want it packaged there. Remember, distributions are simply your users at the end of the day.
Re:Rust Without Crates.io by josephg on Tuesday November 14, 2023 @07:53AM (#38262699)
I suppose I could manually traverse my whole dependency tree myself and install all those packages myself. Set up cmake and pkg-config for all of them. If anyone else wants to try out my software, they’d have to manually look up all the dependencies in my github (?) and install those too. And hope the versions all line up nicely - which is a big if during development. Maybe I could script all of that dependency tracing - if only there were some standard software to do that. Guess not.

If C/C++ is all you know, you’re used to how painful all of that is. But what you’re proposing is a significantly worse experience in every way compared to what I can do with cargo or npm today. None of the claimed benefits seem remotely worth the cost of wading back into C dependency management hell. And cargo and npm show just how unnecessary all that pain is in C!

Just make good tooling. We can have nice things. I stopped using C not because I decided to write assembler. I stopped when better languages came along. You want me to stop using cargo? Nobody wants to go back to manual dependency management. Make something better.

Re:Rust Without Crates.io by mid-kid on Tuesday November 14, 2023 @08:00AM (#38262771)
If you're smart about it you're not gonna have a very deep or wide dependency tree for your own deps. If you need more than maybe two of your own deps, maybe you need to reconsider how you structure your libraries, or you can join multiple libraries into the same project/build system umbrella (e.g. glib/gobject or the whole of QtBase)
Re:Rust Without Crates.io by chalsprhebaodu on Tuesday November 14, 2023 @08:11AM (#38262865)
Why is this inherently better than better tooling for dependency management?
Re:Rust Without Crates.io by josephg on Tuesday November 14, 2023 @08:47AM (#38263223)
Why would I want to join unrelated modules together into a kitchen sink library? The only benefit of that is to work around bad dependency management systems that make dependencies a hassle to work with. But otherwise, they’re a bad idea. Packages should do one thing and do it well. If I want a good random number library, I don’t want to import bob’s junk draw of random code. I want a small, reusable random number library. I want one that I chose. And my users want one they chose. And if that choice is bad, I want to be able to replace it without throwing out half my ecosystem or breaking downstream compatibility.

QtBase is a symptom of C++’s bad package management. 8 unrelated utilities should be in 8 small packages that users can pick and choose based on their needs.

Re:Rust Without Crates.io by mid-kid on Tuesday November 14, 2023 @12:43PM (#38266681)
It's less a workaround around bad dependency management, and more about the fact that it's simply easier to reason about a smaller set of dependencies regardless of the ecosystem. This includes both vetting, ensuring version compatibility, checking license compatibility and reducing the SBOM, as well as governance over the project and integration between different modules.

Too often have I seen the equivalents of frameworks in other languages being split over sometimes hundreds of packages, that don't always make it clear that they're to be updated in tandem, what their exact relationship is, and that the same organization manages all of them.

As for QtBase, it's a superproject, but that doesn't mean that you can't use its individual modules separately, and depending on the distro (e.g. debian) install them separately as well. A singular project installing multiple related libraries makes a lot of sense.

Re:Rust Without Crates.io by josephg on Tuesday November 14, 2023 @03:30PM (#38269283)
> This includes both vetting, ensuring version compatibility, checking license compatibility and reducing the SBOM, as well as governance over the project and integration between different modules.

Auditing large code bases takes disproportionately longer than auditing small code bases. So I don’t think that’s a win. License compatibility is trivial to check. SBOM is strictly larger if I pull in a kitchen sink package because I’m probably not using most of the stuff inside. Better to just pick out the components I want.

The one thing I’ll grant you is that shared ownership and visibility means it’s less likely that one rogue person will sneak ransomware into the dependencies.

Personally I’d love a capability based package manager that lets me pass a package exactly the capabilities it needs to do what I downloaded it for. Why does every package need access to my files when I install or run it? That’s ridiculous. Totally unnecessary and a massive security risk. We could solve that C++ style by hobbling package managers and using fewer, jumbo packages. But that doesn’t solve the root problem. I want a package system in a language which lets me pass capabilities to each library I use, when I need to use them. Eg “Please open your web server on the port associated with this capability token.” This needs language support too but it’d be so much better from a security point of view than anything that came before.

Re:Rust Without Crates.io by Ar-Curunir on Tuesday November 14, 2023 @08:49AM (#38263238)
This is an example where your tooling limits your solution space. There’s nothing inherently wrong with a deep or wide dep tree.
Re:Rust Without Crates.io by SkiFire13 on Tuesday November 14, 2023 @09:00AM (#38263364)
> or you can join multiple libraries into the same project/build system umbrella (e.g. glib/gobject or the whole of QtBase)

This also seems worse than the status quo. So instead of having 3 or 4 dependencies I now only one that combines 20 different ones I don't need.

Re:Rust Without Crates.io by patrick451 on Tuesday November 14, 2023 @09:16AM (#38263538)
> And cargo and npm show just how unnecessary all that pain is in C!

Leftpad would like a word.

Every dependency is a liability. It's another thing to vet, another thing which can disappear. Having few dependencies in c is a feature, not a bug. The approach to dependencies in rust was a major turn off to me. I recall 15 just to get random numbers in the intro tutorial. No thanks.

Re:Rust Without Crates.io by josephg on Tuesday November 14, 2023 @03:17PM (#38269058)
Just in case you don’t know, packages can no longer be pulled from npm by the developer. At least not without emailing someone. And you need a very good reason - like that version is ransomware.

The particular pulled package version identifier ([email protected]) can also never be reused. If you audit 1.0.1, it will never change out from under you.

The leftpad fiasco was hilarious and embarrassing. But it can’t happen again because of changes in npm policy.

Re:Rust Without Crates.io by navi-desu on Tuesday November 14, 2023 @11:29AM (#38265488)
meson actually solves this problem on the build system, their wrap subsystem allows you to use the system provided lib if found, or fetch from a database during the build process if not.

best of both worlds, imo.

Re:Rust Without Crates.io by cozzyd on Tuesday November 14, 2023 @12:18PM (#38266267)
Keeping track of C/C++ dependencies is basically the point of Linux distros...

Cargo's main problem is that it's (mostly) rust only. Same problem that pip/npm have, relegating you to (mostly) single-language silos.

Re:Rust Without Crates.io by humanrebar on Tuesday November 14, 2023 @05:34PM (#38270799)
...except pip/npm often build C or C++ while packages install, at least in some cases.

And Rust has the same issues, at least when shipping or consuming libraries with C APIs is in the picture.

Re:Rust Without Crates.io by cozzyd on Tuesday November 14, 2023 @06:03PM (#38271081)
Yes, sometimes, but it won't resolve C/C++ dependencies in general.
Re:Rust Without Crates.io by josephg on Tuesday November 14, 2023 @05:42PM (#38270872)
> Keeping track of C/C++ dependencies is basically the point of Linux distros...

Judging by the proliferation of docker I don’t think they’re doing a great job of even that. Docker shouldn’t be needed if apt was up to the task. Nixos is a much better design imo.

> Cargo's main problem is that it's (mostly) rust only.

True. But apt’s main problem is that it only works on a few distributions of Linux. Limiting the users of my rust library to rust developers is usually not a problem. Limiting the users of my rust library to the people who use homebrew or arch or something is not fine. And I don’t want to redo all the packaging work on every operating system and major Linux distribution. Life is too short for this make work BS. Especially given it could be automated away anyway. Rust packages already explicitly define all their dependencies. Why can’t apt just generate .dpkgs from my Cargo.toml?

Apt’s other problems are that packages need to be installed globally. And they make a mess of versions. And there’s no feature flags. Run `apt search vim` some time and see how many packages they have! Or the same for llvm. It’s a dog’s breakfast.

The time that cargo’s rust focus hurts it is with binary packages. It’s not enough for ripgrep to live in cargo since it’s designed to be useful for people who aren’t rust developers. And I don’t have a good answer for how to solve that. I wish I did.

Re:Rust Without Crates.io by cozzyd on Tuesday November 14, 2023 @05:51PM (#38270969)
We'll this also works for rust libraries as they're usually useless for other languages, whereas libraries like gdal, opencv, fftw, etc. can be used by many languages. (Though to be fair, until rust gets a stable ABI it's not going to be a good choice for this sort of thing).

I personally consider docker/podman just completely punting on dependency management, and try to avoid them, but I'm probably in the minority...

Re:Rust Without Crates.io by 15155 on Wednesday November 15, 2023 @01:20PM (#38280263)
Rust has a stable C export ABI.
Re:Rust Without Crates.io by cozzyd on Wednesday November 15, 2023 @03:50PM (#38282274)
Funnily enough, the most notable rust-implemented with C ABI shared library I'm aware of (librsvg) just became available on crates.io a few months ago...
Re:Rust Without Crates.io by takluyver on Tuesday November 14, 2023 @01:42PM (#38267584)
> It doesn't (need to) get packaged by a distribution until a program using it is packaged.

I think this is a key difference in approach. In languages with their own packaging systems, you routinely package libraries before there are programs using them. Publishing them on Crates/PyPI/npm/whatever is the bare minimum if you expect anyone to use them!

The number of tiny dependencies can go too far - I don't think I need to mention left-pad. But the difficulty of using dependencies in C/C++, and the results of reinventing stuff, vendoring, or using kitchen-sink dependencies like Qt, don't seem optimal either. There must be a happy medium somewhere.

Re:Rust Without Crates.io by josephg on Tuesday November 14, 2023 @05:49PM (#38270945)
As I said in another thread, I think the happy medium is lots of small packages (people want that). And a capability security model within programming languages so small dependencies are limited to interacting with their parameters (and any resources their parameters provide them) and can’t speak to the OS directly. That would solve 98% of the supply chain problem.

Leftpad has already been solved by a npm policy change forbidding packages from being unpublished.

Re:Rust Without Crates.io by lmm on Tuesday November 14, 2023 @09:21PM (#38272577)
> As for the amount of dependencies, you have to wonder if it's better to have tonnes of small dependencies or whether it's better to have a few bigger ones.

You don't have to wonder, we've done the experiment. Anyone working in an ecosystem with non-joke package management knows that tonnes of small dependencies are a lot better.

Re:Rust Without Crates.io by galangalalgol on Tuesday November 14, 2023 @07:37AM (#38262565)
C++ apps don't pull in that few dependencies. Take something modern that needs to talk over flatbuffs or protobuffs and maybe has a web ui based on emscripten? Then run ldd on it and recoil in horror. C++ dependency trees now often have a hundred or more items. Many of those are packaged with the OS, but that really shouldn't comfort you.
Re:Rust Without Crates.io by pclmulqdq on Tuesday November 14, 2023 @05:31PM (#38270762)
It kind of does comfort me that they are packaged with the OS, because it's an OS problem (and is relatively major) if they are broken.
Re:Rust Without Crates.io by galangalalgol on Tuesday November 14, 2023 @05:59PM (#38271059)
It often takes months for distros as large as rhel to fix med. Or even high severity CVE. That is assuming your OS is getting updated properly. Maybe it is a container and you are doing that as part of your pipeline. But all that it means having the dependency in an rpm or deb file vs in a github repo pulled by conan or similar, is that there is someone you can sue that is supposed to notice the cve and roll out a new rpm or deb file. They aren't doing massive pipelines full of fuzzers and custom unit tests for all those packages, they are just... packaging... them. Otherwise we wouldn't be seeing things like the curl and openssl vulns. Yes you might have some recourse to bug rhel to fix it, where a crate author might not care, but that really isn't the experience I am having. If anything I end up pulling dependencies into my system to build if I can so I don't have to wait on the OS company. Between corporate IT and the OS companies delay as middle-men, my OS based dependencies are always the most aged and vulnerable of all my dependencies.
Re:Rust Without Crates.io by zozbot234 on Tuesday November 14, 2023 @07:44AM (#38262618)
> In this brave new world the author is proposing - what?

In practice, you just vendor your code as part of the source package. It's the distro maintainers' job to factor it out as a separate dependency.

Re:Rust Without Crates.io by mid-kid on Tuesday November 14, 2023 @07:45AM (#38262629)
If you do this, remember to provide an option to factor it out. Meson (mesonbuild.org) makes this completely trivial and pitfall-free, and you should use it if you can't get away with just installing your libraries locally.
Re:Rust Without Crates.io by varl on Tuesday November 14, 2023 @08:36AM (#38263111)
I went to mesonbuild.org and it doesn't match the description (some sort of betting site? I didn't stick around ...), and a search turned up:

https://mesonbuild.com/

Re:Rust Without Crates.io by mid-kid on Tuesday November 14, 2023 @12:46PM (#38266722)
Thanks, I mistyped it.
Re:Rust Without Crates.io by no_wizard on Tuesday November 14, 2023 @09:13AM (#38263508)
>I’m sympathetic to the problem. Supply chain attacks are way too easy

This is the crux as to why crate.io is great: you have one official place for packages that can be continuously audited and monitored. This is the way to do security, in my opinion, because you are always able to look at incoming and outgoing packages.

Now, you can argue if we are doing enough with this, and that is definitely up for debate, however, I contend that the premise of having one canonical place for package origination and hosting makes it easier to monitor for security purposes

Re:Rust Without Crates.io by samtheprogram on Tuesday November 14, 2023 @12:28PM (#38266438)
That’s like saying it’s best to run everything on AWS, because there’s only one place to monitor for outages.

That’s the exact opposite of how supply chain mitigation works.

Re:Rust Without Crates.io by iudqnolq on Tuesday November 14, 2023 @01:18PM (#38267205)
It's not at all like saying that.

If you want to mitigate downtime in your supply chain then diversity is good. If you want to mitigate security vulnerability then it's bad.

Imagine you have 100 api servers that all have database credentials. If one server goes down you have 99 working servers (ideally). If one is compromised then the attacker has your database credentials, game over.

Re:Rust Without Crates.io by josephg on Tuesday November 14, 2023 @05:27PM (#38270715)
I - and many others - don’t think this is enough to mitigate supply chain attacks. It’s too easy for a malicious developer to add cryptolocker ransomware in a point release. But I also don’t think having a package in Debian will somehow magically solve this problem either. Debian package maintainers do not - and never have - done security audits on the packages they add. It’s magical thinking to assume using packages in Debian will somehow protect you from supply chain attacks. Asking developers to keep their dependency trees small so we can minimise the risk is a losing battle. Using lots of small, popular dependencies is just too convenient.

There is a solution out there that I wish got more traction. And that is, capability based security. The idea is simple: we partition programs into application code and library code. Library code can never access the filesystem or network (or other protected data) directly. And this is enforced by the compiler or language runtime. Application code can. If you want a library to interact with a file, you first open the file in application code and pass the file handle to the library. Similar wrappers can be made for directories, network sockets and so on. If I want express to listen on a specific port, I pass it that port in a capability object. Not just an integer. (Eg app.listen(net.listenPort(8000))). The amount of code that would need to be changed is tiny since well behaved libraries don’t usually need many capabilities to do their job.

It is ridiculous that my 3rd party json library can invisibly access all the sensitive files on my computer. With capabilities, we take that privilege away. I have no problem trusting a random json library if it literally only has access to the json string I pass it. If we had a capability based security model, I would have no qualms about pulling in hundreds of transitive dependencies. My libraries can still only access exactly what I pass them.

Unfortunately this problem requires language level buy-in. It would be very hard to retrofit rust to work this way and that’ll probably never happen. Raw pointers and inline assembly also make a bit of a mess of things too. (Though pointer provenance might help). But a man can dream… Maybe in rust’s successor.

Re:Rust Without Crates.io by couchand on Tuesday November 14, 2023 @05:59PM (#38271055)
You don't need the language to be involved to use this strategy, if you can rely on the OS. Lots of programs are structured this way already: open your secure port as root, then daemonize as an untrusted user.

However, I quite like the idea of using the application/library interface to enforce the restrictions structurally, rather than temporally.

Re:Rust Without Crates.io by josephg on Tuesday November 14, 2023 @06:49PM (#38271466)
> open your secure port as root, then daemonize as an untrusted user.

That works for server applications. Well - so long as bad things don’t happen in a static initializer before the process drops privileges. But I also want it to work for other kinds of applications. I want to be able to fearlessly depend on a library and not need to worry about that library attacking my computer. Then we can have our cake and eat it too with big dependency trees made up of lots of small libraries written by untrusted contributors.

Another nice thing about this is it doesn’t depend on OS level capability support. Once implemented in a language, it should be pretty easy to make it work on every OS.

Interestingly, this is something wasm provides out of the box. And Firefox’s weird “compile deps with wasm as convert the result back to C” also achieves this end.

Re:Rust Without Crates.io by ashishbijlani on Tuesday November 14, 2023 @07:34PM (#38271841)
Creator of Packj [1] here. How do you envision sandboxing/security policies will be specified? Per-lib policies when you've hundreds of dependencies will become overwhelming. Having built an eBPF-based sandbox [2], I anticipate that accuracy will be another challenge here: too restrictive will block functionality, too permissive defeats the purpose.

1. https://github.com/ossillate-inc/packj flags malicious/risky NPM/PyPI/RubyGems/Rust/Maven/PHP packages by carrying out static+dynamic+metadata analysis.

2. Sandboxing file system w/o superuser privileges: https://github.com/sandfs/sandfs.github.io

Re:Rust Without Crates.io by josephg on Tuesday November 14, 2023 @08:35PM (#38272292)
Cool library!

I’m not imagining something that specifies policies at all. Capability based security systems shouldn’t need them. Instead, the main application can create capabilities programmatically - for example by opening a file for reading. The file handle is a capability. Libraries you call don’t get access to the OS, or anything outside their module scope that hasn’t been passed in as an explicit parameter. A 3rd party library can access the file handle you pass it as a function argument, but it can’t ask the OS to open any other files on your computer. Or open a network socket.

OS APIs aren’t in a scope that any of the libraries you use have access to.

There are a few things capabilities need to be able to do. They need to be able to be tightened. (So for example, if you have a file with RW flags, you can make a copy of the file handle that’s read only). And they need to be unforgeable (file handles can’t be created from an integer file descriptor). We’d also need a handful more “file handle” like objects - and this is where granularity matters. Like we need an equivalent for directories that gives you access to everything recursively in that directory and nothing outside of it.

If the library I call delegates some work to another library, it’s pretty simple. It just passes its file handle through to the other library as a function argument. There’s no policy to maintain or update. Nothing even changes from the point of view of the original caller.

The tricky part is stuff like debug output, environment variables (NODE_ENV=production) or stdout. Do libraries implicitly get access to stdout or not? Maybe they get stderr but not stdout, and they can open new temp files? You would also need to restrict JavaScript code from arbitrarily messing with the global scope or global libraries like String.

But honestly, any answer to these problems would be a massive improvement over what we have now. Being able to know your binary search library can’t make network requests, and that your database can’t interact with files outside its database directory would do so much for supply chain security it’s not funny. A good capability system should just change the APIs that your software can use a bit. Generally in good ways that make dependencies more explicit. Done right, there shouldn’t be any new syntax to learn or deno style flags to pass at the command line or anything like that.

Re:Rust Without Crates.io by dinosaurdynasty on Tuesday November 14, 2023 @06:58PM (#38271559)
This is similar to how WASI (standard system interfaces) for WASM work.
Re:Rust Without Crates.io by josephg on Tuesday November 14, 2023 @09:45PM (#38272723)
Yeah I'm really keen for that - though I think compiling a bunch of dependencies into individual wasm modules will be kind of awful to use in practice.

Apparently in firefox they've been compiling some of their dependencies using wasm, then translating the wasm back to C. The end effect of all that is that it gives C code wasm's sandboxing and safety. I wonder what it would look like to do that without needing wasm as a middle step.

Re:Rust Without Crates.io by paulddraper on Tuesday November 14, 2023 @12:55PM (#38266860)
You create apt, rpm repos.

And users install from there.

Not saying that's a nice answer, but that is the answer.

Re:Rust Without Crates.io by takluyver on Tuesday November 14, 2023 @01:20PM (#38267242)
Users install from there, so long as they're using Linux, a Debian or Red Hat based distro, and have sudo access. As you say, not such a nice answer.

For certain kinds of software, this approach is getting more viable, thanks to containers. In some contexts, you can tell everyone to run your software in a container with a specific Linux distro inside. But that software is often distributed as container images directly, rather than distro packages to be used in containers.

Re:Rust Without Crates.io by josephg on Tuesday November 14, 2023 @03:11PM (#38268970)
You create apt, rpm repos. And arch. And gentoo. And FreeBSD ports. And homebrew and macports. And whatever windows does. And you need that to be true, on all those systems, for all your dependencies too. And at a recent, usable version.

Or, I just use cargo. Up to date version. One command install that works on every operating system. Project scoped dependencies - so there’s no need for sudo, and different projects can depend on different versions of their dependencies. And I can publish new versions of my packages with 1 command and they’re available everywhere.

Just in my house I have a Linux mint workstation, a windows gaming pc, a FreeBSD server and a Mac laptop. Cargo lets me publish code that all of them can consume with 1 command. So does npm.

So long as apt is worse than cargo I won’t use it for this stuff. Why does everything have to get installed system wide? Nix doesn’t need that. Why doesn’t it have a programmatic mirror of cargo so we don’t need to mirror rust projects in it by hand? Why do major versions have different package names? And why don’t packages support feature flags? Last time I looked there were about 30 vim packages with random combinations of feature flags set. Why can’t evergreen packages like nodejs or cargo stay up to date in Debian? Old nodejs is useless because it can’t run modern JavaScript.

I really want apt to solve all these problems because I hate docker. If apt and friends did their job well, docker wouldn’t be necessary or popular.

Cargo isn’t pretty either. But it has all the features I need to get my job done. Make apt a compelling tool and I’ll switch to it. The feature list developers want is hardly a mystery.

Re:Rust Without Crates.io by paulddraper on Tuesday November 14, 2023 @05:19PM (#38270622)
Correct, there are many operating systems.

That is why each modern language has introduced their own package manager.

Re:Rust Without Crates.io by josephg on Tuesday November 14, 2023 @05:55PM (#38271015)
I assume you’re being flippant, but it’s kind of true. You support 20 different things by making a 21st thing that papers over all of them. And along the way you can try to fix some of the design problems.

The web. The C programming language. Electron. It’s a tale as old as time.

Re:Rust Without Crates.io by zajio1am on Tuesday November 14, 2023 @03:27PM (#38269247)
> as an author of some not very popular packages, what do I do?

Depends. Do you want your software to be used by users? For me as a user, software that is not in distribution repository almost does not exist. It is too much hassle to install, manage and uninstall it compared to installing software from Linux distribution. If i really, really need it, i will make exception, but that are individual cases.

Re:Rust Without Crates.io by mattpallissard on Tuesday November 14, 2023 @05:51PM (#38270967)
> “It works for C/C++” by making developers working in those languages pay in blood for every dependency they pull in.

I think the industry may have thrown the baby out with the bath water. Now they're is a complete aversion to RYO anything, no matter how simple. Personally, I'm waiting for the pendulum to swing back towards the middle a bit more.

Re:Rust Without Crates.io by josephg on Wednesday November 15, 2023 @01:40AM (#38273962)
Eh. I love rolling my own lots of things. At some point I really want to make a little OS kernel. How hard can it be?

But then there’s things like rust’s rand crate which implements about 10 different random number generators, all with different properties around speed, whether they’re cryptographically secure and so on. And fed from a variety of entropy sources to make it work everywhere from Linux to windows to wasm. Look at this documentation. It’s an absolute master class.

https://rust-random.github.io/book/guide-rngs.html

Do you need this? Probably not. You can probably get by with some wrapper around ar4random or whatever the recommended entropy source is today on your particular operating system. But I’ll be honest, until the day I decide to care about how rngs work, I’m going to just import the rand package. And serde & friends for json support. Criterion for benchmarking. And so on.

Cargo is full of great libraries that are much higher quality than anything I’d ever throw together in a side project. For most of this stuff, you’d be mad to roll your own.

This thread has reminded me that lots of people don’t know how nice it is to use a package manager like cargo. Here’s my favorite crate browsing website. You can see the most popular packages in every category and search. Look how much great stuff is in here. It’s humbling.

https://lib.rs/

Re:Rust Without Crates.io by IAmNotACellist on Tuesday November 14, 2023 @07:51PM (#38271972)
>Yeah. The part that gives me goosebumps with that proposal is: as an author of some not very popular packages, what do I do? Is it my job to package and promote my packages on Debian, redhat, homebrew, and all the others? Do I need usage before they’ll pick it up? Sounds like a chicken and egg problem. And doing all that packaging work sounds like a boring, time consuming job that I don’t want.

Github premium (or similar) will have an army of AI builder bots that spin up VMs and modify your codebase until it works, then send you PRs to approve. People would pay a ton for that service. All your projects, automatically maintained and packaged.

Re:Rust Without Crates.io by mid-kid on Tuesday November 14, 2023 @07:55AM (#38262724)
As a distro contributor, I don't share these views at all. Yes, it's sometimes a bit of a pain when some application needs an older, incompatible library, but in 99% of the cases, the fallout is minor, or there's some compatibility library or shim I can install. The advantage of doing this being that the old application will now support all modern audio/video formats (e.g. ffmpeg) and the new graphical and audio subsystems on linux (e.g. sdl), as well as whatever security fixes.

If I really need an old library, it's generally not hard to install that in a temporary prefix and set the relevant PATH variables for it, though I do wish this was easier sometimes. It gets better as more projects just use pkg-config.

That all said, Meson[1] solves all of these issues in a way that keeps both developers and distributions/users happy. But as is with all things C, getting everyone and especially windows users to adopt it is gonna take a good while.

[1]: https://mesonbuild.org/

Re:Rust Without Crates.io by dahhowl on Tuesday November 14, 2023 @08:44AM (#38263190)
(wrong link, you mean .com)
Re:Rust Without Crates.io by chrismorgan on Tuesday November 14, 2023 @03:00PM (#38268796)
Well, clearly what I wrote has resonated with people, as this is now my second-highest-voted comment, currently at +101.

(My >4000 comments range in score from −4 to +76 plus one outlier at +287 because people really hate stale bots on issue trackers. See https://news.ycombinator.com/item?id=32541391 for methodology. This comment has also clearly evoked a strong emotional reaction.)

All I can say is that I’ve had a lot of trouble over the years building older C/C++ software, often seeking to consume it from Python but sometimes just from C/C++. Maybe if I lived and breathed those languages I’d cope better, but at the very least they consistently take extra effort that requires at least mildly specialised knowledge, compared with my experiences of pure-Rust or even mostly-Rust software.

Re:Rust Without Crates.io by FullyFunctional on Tuesday November 14, 2023 @07:52PM (#38271982)
I too have moaned and ranted about this the problem with installing "modern", dependency heavy apps -- it's to the point where it's borderline anxiety inducing. I take the upvotes as a sign it's widespread. There are examples of a really valuable package that myself and two coworkers independently have given up installing because the dependency nightmare was just too horrid (a C++ app).

When I started using Rust it truly felt like magic. I could any app by anyone and essentially `cargo build` would always just work. So effortlessly.

Re:Rust Without Crates.io by chrismorgan on Thursday November 16, 2023 @10:57AM (#38291112)
Update after another day and a half just because this thread has fascinated me because it’s my second clear outlier: it’s now up to +162, over double my third-highest. Also the immediate parent to this comment has been at +2, −0, +1 and is back to −0 as I write and I’m not really sure why (I’m just describing facts, right?) but that’s part of the fun! I won’t try to predict where this one ends up :-).
Re:Rust Without Crates.io by mid-kid on Friday November 17, 2023 @06:20AM (#38302010)
I voted it down because numbers don't really mean anything. Top-level comments that directly disagree with the article always do good if they don't get drowned out by another comment doing the same, especially when it's a controversial topic or a comment that directly reinforces people's preconceptions on a topic (and the article is about dispelling the preconception). You pointing it out doesn't add anything to the discussion.

My best comment by far is one on an article about linux support for laptops being great, talking about all the problems I've experienced in recent years, even though I do agree with the article's core statement.

Re:Rust Without Crates.io by chrismorgan on Friday November 17, 2023 @01:15PM (#38307574)
I’ve given plenty of top-level dissenting and affirming opinions, probably at least a few hundred, probably less than a thousand (wild estimate based on the total and memory of likely patterns). The highest I’ve got before was +74 on a positive one (detailing my experiences with fraudulent YouTube Content ID claims of public domain melodies) and +73 on a negative one (detailing specific technical problems on an Informational-class RFC—yes, both of these were much more specific than the current case). Fundamentally such numbers may not mean anything, but when you get one that’s more than double the next highest from such a collection is very likely to mean something. And the final paragraph of my follow-up comment certainly added something (I wouldn’t have posted the number without it).

If someone had written approximately the comment I wrote first, I’d have upvoted it, because it matches my experience.

Re:Rust Without Crates.io by lolinder on Tuesday November 14, 2023 @05:14PM (#38270570)
> As a distro contributor, I don't share these views at all.

That's because you're in the very small group of people that knows how your distro's packaging process works in detail. The majority of developers don't use Linux at all, and those that do typically know just enough to install a few blessed packages, not enough to hunt down and install the correct shim in a temporary directly.

Multiply that lack of training by the dozens of Linux distros being used by users of a language, and it's no wonder most modern languages have a standard language-specific package manager. The alternative is for them to be constantly fielding impossible-to-answer questions from developers who (unlike you) don't understand their distro well enough to make compilation work.

It's far easier for the language to have a single cross-platform package management system where the answer is usually as simple as "X, or Y if you're on Windows".

Re:Rust Without Crates.io by Gigachad on Tuesday November 14, 2023 @06:06PM (#38271113)
I just don't attempt to compile C/++ software these days because the process is always an absolute nightmare where you have to attempt to compile, then google the error to see what package it's related to, try to work out what the distro name for this package is, install, recompile, repeat 10 times. And hope you don't get completely stuck where you distro just doesn't have the package or version you need.

Something in rust is always just `cargo run` and you're done.

Re:Rust Without Crates.io by saidinesh5 on Tuesday November 14, 2023 @07:03PM (#38271598)
> The advantage of doing this being that the old application will now support all modern audio/video formats (e.g. ffmpeg) and the new graphical and audio subsystems on linux (e.g. sdl), as well as whatever security fixes.

That's the theory. In practise, it just means small app developers putting up with:

1) #ifdefs for different versions of same libraries in different distros

2) distro specific bug reports for an operating system with less than 2% user base

3) binary releases that target just 'Linux' being out of question for most proprietary applications / apps that can't/won't be included in distro repositories for various reasons.

It's not as if distro maintainers will test your random little application every time they update ffmpeg anyway. It's the users, for whom the application breaks.

Re:Rust Without Crates.io by JohnFen on Tuesday November 14, 2023 @09:25AM (#38263634)
> Take an app written five years ago that depends on majorish C++ libraries, and there’s a fair chance compiling it will be a nightmare

Interesting. My experience doesn't back this up at all. I may have issues with 20+ year old code, but I don't remember ever having anything but minor issues otherwise.

I wonder what the difference between us is?

Re:Rust Without Crates.io by bfrog on Tuesday November 14, 2023 @10:23AM (#38264364)
C++ is horrendous when it comes to backwards compatibility and builds.

If you believe that you won't run into a compiler bug in a large enough sampling of C++ code to build against you are misrepresenting reality or haven't ever looked at the gcc or clang bug trackers.

Rust actually does a really nice job along these lines by continuously building and running test for some subset of crates in crates.io

The only thing maybe even close to that with gcc/clang involved I've seen is nixos's hydra.

Re:Rust Without Crates.io by estebank on Tuesday November 14, 2023 @10:44AM (#38264667)
No subset, all of crates.io gets built for every beta amd then stable right before release looking for any changes from the prior stable.

Note that this is not all Rust code that exists, but it does help a lot.

Re:Rust Without Crates.io by JohnFen on Tuesday November 14, 2023 @10:47AM (#38264705)
> If you believe that you won't run into a compiler bug

I never made anything like that claim. Nor was I making any comment about the utility of something like crates.io.

I was just relating my personal real-world experience working with code. Interesting that I got downvoted, as if what I've experienced in my career was somehow wrong. I certainly wouldn't claim that devs reporting the opposite experience from mine are wrong. It's just that the difference is stark, and I was curious as to why.

Re:Rust Without Crates.io by Aerbil313 on Tuesday November 14, 2023 @11:03AM (#38264979)
Take a look at nix-shell scripts. Much simpler, lightweight and faster alternative to Docker and friends for being able to build a project forever. Start of a build script from a C project of mine:

  #!/usr/bin/env nix-shell
  #! nix-shell -i fish --pure
  #! nix-shell -I https://github.com/NixOS/nixpkgs/archive/4ecab3273592f27479a583fb6d975d4aba3486fe.tar.gz
  #! nix-shell --packages fish gcc gnumake gmp git cacert
  ...build script goes here...
-i fish: I am using fish shell.

--pure: Environment is as pure as it can reasonably get.

--packages: Packages from nixpkgs to be made available in the environment.

-I <github_commit_hash>: pinned to a specific git commit of nixpkgs. This script will give you the exact same environment with the exact same packages with exact same dependencies forever.

You can drop into a shell with the exact same configuration by using the cli command nix-shell with the same options.

Admittedly this is not as declarative as using flakes, since it's a script, but hey, I'm lazy, still didn't sit down to learn them once and for all.

Reference: https://nixos.org/manual/nix/stable/command-ref/nix-shell

Re:Rust Without Crates.io by cge on Tuesday November 14, 2023 @11:30AM (#38265511)
> Take a look at nix-shell scripts. Much simpler, lightweight and faster alternative to Docker and friends for being able to build a project forever.

As researchers using nix derivations to preserve usability of code meant to be archived with our papers, we found that it was not particularly effective for this task. Even with nixpkgs pinning, our code failed to compile after only a few years. Outside of nixos itself, it does not appear that the build environment is the same; aspects of compilation change, and we ended up needing to change compiler flags a few years later, while expecting that we might need to again at some point.

Overall nix has been quite disappointing for us from an archival standpoint.

Re:Rust Without Crates.io by Aerbil313 on Tuesday November 14, 2023 @03:33PM (#38269317)
Nix-shell scripts are ad-hoc, what nix does here is to provide an environment. Nix derivations are different and can be fully declarative and pure. Nixpkgs pinning does not mean specific nixpkgs commit pinning or pinning a specific version of a package. You can do these as well. I wonder what was the underlying reason for your condition.
Re:Rust Without Crates.io by jolux on Tuesday November 14, 2023 @08:25PM (#38272224)
Just curious, have you written anything up about these experiences with Nix? I've been learning it recently and the reproducibility angle is a huge part of why, if it's oversold then I feel like I should reevaluate how much time I'm putting into it.
Re:Rust Without Crates.io by deredede on Wednesday November 15, 2023 @02:43AM (#38274264)
Things shouldn't change if the nixpkgs version didn't change, you didn't disable the sandbox, and you don't have master branches of random repos as dependencies. If that's the case, sounds like a major nix bug.

If the sandbox is disabled (as it is by default outside of nixos I believe) then yes, you need to be very careful that there is no outside state that leaks into your build (usually through environment variables, PATH but not only - GCC is a big offender here), which sounds like what happened in your case? For archival purposes you really should be enabling the sandbox.

Re:Rust Without Crates.io by cge on Friday November 17, 2023 @12:19PM (#38306641)
Thanks: it does seem like the lack of sandboxing is the major problem here. A difficulty in this sort of archiving is that we're not trying to make it so that we can build the code: we're trying to make it so that any reader in the future can. Close to zero of those readers are likely to be using nix for anything else, or to have any experience with nix (or any other approach we might take).

Our approach was to make a script for nix-shell that would put the readers in an environment where they could run the code, compiling specific (old) versions of two research software packages. But I think the problem here is that in writing the derivations here, we didn't put gcc in the build inputs. So the system's compiler ended up being used, and with the old, finicky code, compiler flags needed to change. A frustration here is that it appears sandboxing can't be enabled for nix-shell, a problem that has been known for close to a decade [2]. But in our case, if we can get the build inputs to be reasonably complete on our own, it should improve the situation for our readers in the future.

[1]: https://github.com/DNA-and-Natural-Algorithms-Group/SST-sequ... [2]: https://github.com/NixOS/nix/issues/903

Re:Rust Without Crates.io by gray_-_wolf on Wednesday November 15, 2023 @08:17AM (#38276306)
You might give GNU Guix a try, combination of guix time-machine and guix shell -C should give you the exact same environment each time without fear of being affected by the rest of the system (with the obvious exception of the linux kernel).

And it seems to be popular in science circles.

Re:Rust Without Crates.io by ParetoOptimal on Thursday November 16, 2023 @09:12AM (#38289695)
> Even with nixpkgs pinning, our code failed to compile after only a few years. Outside of nixos itself, it does not appear that the build environment is the same; aspects of compilation change, and we ended up needing to change compiler flags a few years later, while expecting that we might need to again at some point.

Was this using flakes or no?

Since you mention pinning, I'm guessing not.

An experience report, even if brief, would be very valuable to a Nix/NixOS community working seriously on reproducibility.

Re:Rust Without Crates.io by oneshtein on Tuesday November 14, 2023 @02:40PM (#38268472)
RPM .spec is more readable, IMHO.

Archive of system repo + mock + SRPM does the same thing, but offline.

Re:Rust Without Crates.io by bfrog on Tuesday November 14, 2023 @10:05PM (#38272831)
Rpm assumes deps and toolchain and doesn’t prevent accidental dependencies last I used it, admittedly many years ago. Are builds somehow done in a limited chroot now? Is the toolchain version dependency tracked and managed?
Re:Rust Without Crates.io by oneshtein on Wednesday November 15, 2023 @01:38AM (#38273952)
In Fedora, mock[0] is used to build packages in clean chroot for multiple of distros. In SuSE, Open Build Service[1] i used.

[0]: https://fedoraproject.org/wiki/Using_Mock_to_test_package_bu...

[1]: https://en.opensuse.org/openSUSE:Build_Service_Tutorial

Re:Rust Without Crates.io by bfrog on Wednesday November 15, 2023 @08:15AM (#38276292)
What about the toolchain being used, is that some how understood to be part of the result? This seems to be often overlooked. In nix the toolchain is considered an input I believe and taken into the output derivations hash. Meaning a toolchain change results in a new package (rightfully so!)

What if you need different versions of the same package to support end applications?

Re:Rust Without Crates.io by NobodyNada on Tuesday November 14, 2023 @04:38PM (#38270161)
It's even worse when you consider cross-platform or even cross-distro builds. Take a C++ application developed on Linux and try to build it on Mac, or vice versa. This can be really painful even without waiting 5 years because oftentimes two different package managers have incompatible versions of packages, or even if the versions are the same they're built with different settings/features.
Re:Rust Without Crates.io by j1elo on Tuesday November 14, 2023 @08:17PM (#38272184)
As a C++ dev myself, and lots of past experiences with code archeology, nowadays I wouldn't even bat an eye before reaching for a Docker container of the appropriate system version, where to build an old and unmaintained C or C++ codebase. Otherwise, pain ensues...

If we add loading binary libs built for an older system, then there is no question. Who wants to deal with incompatible versions of the GLIBC?