Oof, yeah that's painful. I'm impressed you've gone to these lengths, most maintainers don't do that. They generally rely on the folks who want to use the software packaging it for their distros. Obviously there's a bit of a chicken and egg problem there, though, if you care about getting your software in front of users.
For the Debian situation specifically:
> It would've been nice if there was a quick serverless solution where you could just say a URL to look for newer versions of a single package, and both apt and dnf would remember that and update a package.
Have you considered just hosting your own Debian repo? It's basically what you're looking for here. You don't need more infrastructure, either, you can host them straight in github pages with aptly or reprepro or something, and drop new releases in there from CI.
Yeah, the one thing you're missing is getting into the users' `apt update`/`apt upgrade` flow, right? This will get you there without needing to change the Debian package you already create (although you can ship different ones this way if e.g. older Ubuntu/Debian distros require it and you want to support them).
The software referenced is open source and it's already packaged to deb (see home page), so setting up the boilerplate for PPA submission (via AI) is very easy.
If a package doesn't have particular build requirements, setting up a PPA is overall simpler than hosting a personal repo (I do both).
To be clear, I'm not trying to argue or disagree with you. I agree that PPAs are a fine option. I'm not trying to disparage them, I'm trying to explain the reasoning behind my suggestion: PPAs enforce a number of requirements that exist for a reason, but that can be a challenge to meet depending on the project. The biggest example is that of source packages. I don't mean "your source needs to be open" (which of course this project is), but rather "your software needs to be built on Launchpad infrastructure." If you take a look at the existing CI the maintainer has in place to build the binary deb, you'll see what I mean: https://github.com/sinelaw/fresh/blob/master/.github/workflo... . The maintainer already has this, and it would need to be completely re-done to make it work in Launchpad, and the amount of work might be quite significant. A standalone Debian repo can just have binary debs, i.e. the work that has already been done can continue being used.
Thus my recommendation for aptly/reprepro: it's a more natural extension of what the project already has in place rather than a "you should do this instead."
I think that you just need to provide .tar of your app. Everything else should be problem for people who handle packages of different distros. You don't wanna be involved in that part of distribution. If people want your app, someone will make a package. There are too many package manages for you to run and add your stuff to all of them. Just have .tar on static http server and that's it!
Example: http://ftp.klid.dk/ftp/gnu/gcc/
Parent post already told you a way to distribute your software to Linux users; assuming your tarballs with prebuilt binaries "just work", as in, it's enough to untar it wherever (/opt?) and create a symlink in $PATH for your executable.
But from your comments, the message I get is that you want to apply to become a maintainer in each and every Linux distribution's package repositories, both mainstream and niche? And apparently also create packages for some alternative package managers too? (e.g. mise, npm, Terra)
The reason this seems so weirdly hard is that you're not supposed to be doing it. You provide sources and instructions on how to build them, and then your job is done. Users can follow those instructions. If you want to you can also build a binary with an old version of libc and distribute that to help users who don't want to compile it themselves.
Packaging it for a distro is someone else's job, and they'll take care of concerns like Debian's dependency policy. If they want to package it in the first place of course.
This isn't a good dichotomy though. Either "Build it from source" or "Wait for a professional 3rd party to package it for you".
The idea that your OS distro needs to explicitly support and package every software you could ever want to use seems crazy to me.
Both users and authors want the same thing: low-effort, high-quality distribution of software.
Personally I put my support behind flatpak for GUI, mise for CLI/TUI, but it's not a perfect solution and I occasionally bail out to homebrew/linuxbrew.
> This isn't a good dichotomy though. Either "Build it from source" or "Wait for a professional 3rd party to package it for you".
Somebody has to do the work. Apparently you won't accept it for that to be the developer, the user, or a "professional third party" (whatever "professional" means here). What exactly do you want?
> Personally I put my support behind flatpak for GUI, mise for CLI/TUI, but it's not a perfect solution and I occasionally bail out to homebrew/linuxbrew.
So third parties. Things that have reinvented "distributions", arguably badly. Are you saying they're not "professional"?
1. I want it to be easy for developers to publish their own packages.
2. I want it to be easy for users to install these developer-published packages.
> Are you saying they're not "professional"?
I regret using the word professional, I was replying to the claim GP made:
> Packaging it for a distro is someone else's job
Well I (as a developer) want to publish my own software without waiting and hoping someone else will do it for me.
> Somebody has to do the work.
Yes, I (the developer) want to do the work. The whole point of the article is that its painful to do today. I'm interested in how we make the packaging work easier so the developers can do it.
> [...] So third parties
the whole 3rd/1st party question is whether a developer can publish their own package. In most cases they technically can (taps, PRs, flathub, Debian registries, so on) but run into lots of issues along the way.
> Packaging it for a distro is someone else's job, and they'll take care of concerns like Debian's dependency policy. If they want to package it in the first place of course.
Yup, this is why I think so many people feel so much friction about it. On Windows and macOS, the developer is usually responsible for the entire thing, even shipping installers for users. Linux distributions tend to split the roles, and as mentioned, once you provide sources and how to build it, you're basically done and it's up to others now.
That sounds like you could have a situation where the developer wants me to run the app, and I want to run the app, but nobody at the distro I use has packaged up the app, so we're blocked.
> but nobody at the distro I use has packaged up the app
But you're "at the distro", and you want to use it, so you package it :) You might want to be nice to others too, so you make that public. Eventually, the community might end up relying on it, and the package gets an official maintainer from the distribution itself.
Sorry, I don't have those skills, or any spare time.
And if you want a system whereby software only gets made available if distro-providers care enough, then that's fine. But you're putting a filter between the software producer and non-technical users, and you should be aware that this is a choice you're making.
If they're not using your software they're not your users.
You seem to be treating this like a commercial endeavor in which you have much to gain from adoption by nontechnical people. I don't really see why though. It looks like you're developing non-commercial open source software for an audience of developers.
You are taking on the responsibility of being compatible with a large variety of different people's opinions on how software should be built, configured, and distributed. Yes that's a lot of work. Distributions have people willing to do that work for software they or their users (who can ask) care about.
Linux evangelists on the internet are some of the most unhelpful and useless people you will ever come across. My condolences in advance for every "ackshually you must pray and wait 10 years that some Debian maintainer to pick it up" reply.
I get that but I feel like its a bit different for linux users. The ecosystem has way more folks that are used to building their own tools relative to Win/Mac. Especially for something like nix. I've built nixpkgs for tools I've wanted to try & use. For something like this, I'd stick with cargo and let others do the packaging.
> You provide sources and instructions on how to build them
Have you ever interacted with actual users? This is absolute no-go which will only bring world of pain on you and your issues list and your email and your Discord and whatever other way you decide to talk to users....
Hi, I'm the author of this post (and of Fresh). I've spent a lot of time getting it distributed cleanly to Linux users of all distros, and it's an uphill battle. I'm curious how other solo maintainers are dealing with this problem. Is a self updating static binary a reasonable solution?
The answer is to not do it. Provide the source and help distro maintainers to package it for you. You can help by being responsive to maintainers' questions, making sure the source is clean (no binary blobs, weird licenses, strange build systems, generally builds like similar packages), and integrating patches from maintainers upstream.
In the early stages you can help by making your source code easy to build. No weird build system, make dependencies optional as much as possible, document how to build, reduce the number of steps required and make them as similar as possible to comparable software. Linux users will put up with this. That also helps distro packagers so it's a win-win.
Usually thats the job of the Distro maintainers, your job is to provide a .tar.gz site on your website, the distro maintainers are responsible for publishing your app on their distro's.
I mean thats the whole philosophy of Linux distros, anyone can create a Linux distro but the job they then take on is maintaining their own distribution of packages. I'm not saying your wrong; I'm just saying that is the what a Linux distribution _is_.
I personally think that a self-updating static binary is the pragmatic choice. I give out my software in the form of a single static binary which my users can update using a simple "update" command when a new released is published - they also receive access to the Git repo if they for any reason choose to build it themselves. I've had users on many different Linux distributions and no one has complained yet.
Linus Torvalds has talked about this very issue. He didn’t even release his own app for Linux as a result and relied on others to pick up the slack and package the app for Linux, while telling them they were wasting their life.
At work we maintain embedded-linux computers with a custom distro but the actual graphical interface is a separate artifact developed by another team. Moreover they have to use an SDK that only works on a specific distro (semi-closed source).
Our solution is shipping it with its own glibc and running the executable with the LD inside this separate glibc. Basically the entire userspace. It is almost like a container but the containerization is provided by systemd and there is scoped access to limited system services via mount and network namespaces.
We cannot use static programs. Our systems have limited memory so the GUI load relevant parts of the program as shared library plugins.
This is the only reliable way to distribute closed source / independently packaged Linux software. You ship it with an entire userspace. Docker and Flatpak are just that; an admittance that distributing independent software reliably on Linux is practically impossible.
That sounds like a heavier-weight wrapper over the same system services they're using through systemd today.
It could be useful if updating is a pain point.
In this case, they may also consider Podman, as it has excellent systemd integration[1] including rudimentary container orchestration and the ability to auto-update containers and Kubernetes-style pods installed as systemd units. I've run Pihole under Fedora CoreOS this way for several years without touching a single thing to update the OS or Pihole.
No we don't need / shouldn't use Docker. As jasomill guessed the disk size and memory usage that Docker needs is just unnecessary overhead. These devices have only 8 GiB disk space. systemd provides every single thing that we need; one can obtain equivalent isolation just with a systemd unit file.
If you don't need the layers of Docker and server pull-push, it is just overhead. We just fetch a single cryptographically signed squashfs file and execute the program in it with limited FS and separate namespaces.
I feel like Zed, rustup, and a lot of other applications (with CLIs) moved in that direction. (Hope someone corrects me if that’s wrong, unsure those projects are fully static, but they do self update.)
As a user that surprised me at first, but I’ve grown to really like it!
Considering you are already using Rust and looking at a static binary: why not package that inside the various distro-specific formats?
Sure, you won't get into the official repos that way, but do your users really care? Fedora users are pretty used to enabling Copr and RPMFusion, Ubuntu has its PPAs. It's not ideal, but it's good enough. Even an RPM/DEB via Github release would already be a good start.
I think the only downside with the musl binary is that there can be a performance hit compared to libc, which may or may not be an issue for a terminal text editor.
I also echo some of the comments here saying it's entirely reasonable for a single maintainer not to support absolutely every single distro unless it's straightforward or enjoyable.
Costs money and is centralized with a for-profit entity, probably best to stay far away when it comes to day-to-day software.
Don't get me wrong, I love Steam, but for video games. You can't stop auto-updating for example, and still be able to launch the "game" (program in this case) if it's out of date, which obviously breaks pretty much every professional computer user's workflow.
It doesn't have to cost money. You can write a normal Windows app and run it under Proton. For end users, provided that they have Steam installed (it's free), they can just add "Non-Steam game" to the library - it's ~4 clicks.
It works. It works great. It's actually the only sensible solution if you want something compiled today to work without changes on both Windows and Linux in 10 years.
I did an experiment, implementing a GUI calculator, and Rust + Slint + cross-compiling to Windows (I develop on Linux) + Proton runtime was the clear winner:
- compiled bundle: 20 MB (F#/dotNet + Avalonia: 207 MB)
- loc: ~1000 (dotNet: ~700)
- dlls: none other than what Wine provides (dotNet: 67 .dll files)
You have an option to build for Linux for dev/testing, then you cross-compile to Windows and provide a short (4 points) instruction for adding the Windows build to Steam on Linux. It works, and it will most likely continue to work in the future, unless Valve folds and both Wine and Proton die. The only thing worth looking out for is crates that depend on external shared libraries: you need to bundle them manually. Other than that, it works.
Another option I considered was Zig with the Win32 API, but the LOC count was unacceptably high.
I'm working on a write-up for the experiment. The premise was: "I'm working on Linux and want to create a GUI app that will, with the build done today, continue working on Windows and Linux for the next 10 years". Steam/Proton + mostly static compilation + bundled libraries is the only solution that makes this mostly painless.
> It doesn't have to cost money. You can write a normal Windows app and run it under Proton. For end users, provided that they have Steam installed (it's free), they can just add "Non-Steam game" to the library - it's ~4 clicks.
I'm saying you don't need to publish on Steam to make your app run on Steam. You really don't. A user can add any executable to the Steam Library via the "Add a Game -> Add Non-Steam Game" button in the bottom-left corner of the GUI. It works 100% locally and with any kind of executable (not just games). It also bypasses any auto-updates. Finally, you can launch an app like that from the CLI or a desktop shortcut without opening Steam (well, it'll still run and update itself when needed, but you bypass the GUI).
> A user can add any executable to the Steam Library via the "Add a Game -> Add Non-Steam Game" button in the bottom-left corner of the GUI.
Yeah, but that's also not exactly a better user-experience for the end-user than "Download .exe, double-click to launch" or "Download .msi, finish install, run program".
Distribute your software however you want, I tend to try to make the download and install as familiar as possible to the users of the specific platforms.
Btw, even your starting prompt is guiding the model to just agree with your opening statement. You can't just roll with whatever the model says and assume the conclusion of "definitely can run in 10 years unchanged" is true.
Yeah, that's why the second prompt starts with "You misunderstood" and a correction. This is a long conversation, with multiple experiments performed and a lot of inspection of all the intermediate results on my end between prompts. You assuming otherwise without reading is a bit offensive.
To your point on installation: sure, but if you value it that much, just pay Valve to add you to the Steam store? And that would be the only possible solution given my constraints, all explicitly mentioned at least once in the linked conversation:
- binary produced today works
- without changes
- on both Linux and Windows
- is a GUI app
- has some dependencies
- is developed on Linux (no Windows needed)
For this set of constrains, Proton/Wine with a cross-compiled Win32 binary/bundle is literally the only solution (care to name another?)
For other constraints, it's a solution. Worth considering. That's all.
> You assuming otherwise without reading is a bit offensive.
Yeah sorry, hurling huge LLM conversations at me tends to make me skim them, hope you don't mind I didn't study the conversation you had with ChatGPT in detail.
That you considered someone skimming a chat log offensive yet the act of sharing those chat logs and expecting others to dredge through them, is almost offensive to me. So I guess we can call it even now.
> For this set of constrains, Proton/Wine with a cross-compiled Win32 binary/bundle is literally the only solution (care to name another?)
Cross-compiling the good old way, with a Linux VM, Windows VM and a macOS host (maybe Mac Mini?). I basically have the very same requirements (+ macOS), except zero third party dependencies, and end up doing it this way, all managed with Nix so basically all the installation-bloatyness is something I deal with so users get the exact same experience they expect on their OS.
Steam provides a stable Linux runtime, but it's not containerized or isolated Docker/Flatpak-style. It's closer to a chrooted env with some specific distro, but without chroot and the need to maintain said distro. They want to provide runtime stability and compatibility comparable to that on Windows - it's a great initiative, and I really hope they'll succeed. The snowflake-like userlands on Linux are a pain, but the current solutions (Docker, Flatpak, things like conda) are all bad solutions to this particular problem (though they are good solutions to other problems, so it's not a criticism, just a difference in goals).
However, Steam Runtime for Linux was still in beta, last I checked. Plus, it doesn't solve the cross-platform part. But for Linux-native development, Steam Runtime might be what's needed to have long-term compatibility for apps (finally).
TLDR is basically that you don't have to package it for others, the expectation is that people using the distributions will package it for themselves and others if the software ends up useful enough and they want it in the distribution. Until then, just ship a zipped up binary or whatever and call it a day.
There's no end how complicated you can make things for yourself, if you really want to.
What you should do is make software good enough so your users will use it, and publish the source code under a free license. The first Debian developer that uses and likes your software will package it, and the virtous cycle can start. It can be tempting to "own" the user experience (after all, everone wants to own their customer) but one has to let go of that thought. Updates can not be expected to get pushed out the same day when you don't own the customer, but that's overall a good thing.
Ask the distro people what you can do to make their work easier, listen to them, but do not try to do their work for them. Unless you live in that distro you are unlikely to understand how they expect your software to behave and the nuances of how it should be packaged.
One of the good ideas about Linux packaging is that it is not the same people that make the software that package it. Code can be reviewed. Bad ideas can be caught. This principle is sometimes violated, but that violations happen doesn't make them a good idea. We live in a world where no one should execute random software from the Internet without any form of reputation or review, and distribution packaging suggests one way we can accomplish that. A way that has survived three decades, after all, so maybe it's worth listening to.
Fully agree. In good 'ol times, we had (and still can have!) GNU Autotools where the maintainer created distributions and the end user's (packager) system just needed to have rudimentary support for building programs from source (POSIX-compliant make, shell, compiler, linker etc.).
I know, speaking for GNU Autotools will get me downvotes and nasty comments, but there are many things the GNU Operating System got right and stable, mature distributions like Debian show still its heritage.
Apple, Microsoft, Google - none is easy meaning you need to have Play store, certs, codesign, submit... But there are steps with few results making it easy for those platform to get the software.
I have tried my best getting also Linux but as the author said, there's nothing trivial (as my metronome GitHub issues can show https://github.com/talaviram/TICK/issues)
The name is exactly the tricky part... Linux has so many flavors.
Even without installer, you have X server and Wayland and snap, AppImage, .deb each differ. add to that audio plug-in formats (CLAP, LV2, VST3) and the fact that some formats has no specific path for putting files.
For simple apps (not cli tools or ones aimed for package managers I start to think best is just providing an archive file (zip/tarball/etc)
While Linux is growing and is my goto for non-macOS, with so many releases, it still feels most users are more technical than other platforms. Add the LLM age where you can ask it to install it for you. a zip with binaries might be simplest for simple software.
The traditional way on Linux, at least in FOSS, has been to basically ship the binary somehow, also make the source available, then if people want it for Debian or whatever, they'll package it themselves. Typically, the person(s) developing the software itself are different people(s) who package it. So you'll have the application/library developer(s), then if people want it for their distribution, one of them has to decide to package it and make it available.
Of course, people nowadays try to make it easier for the distributions and provide packaging for them. But I don't think this is requirement, you can just ship a binary and most Linux users will be able to run them, and it'll basically "package itself over time" if it's interesting enough for people to want that sort of integration.
There is no right/wrong or correct/incorrect approaches here, just giving ideas :)
I just did a double take at "Windows and macOS aren't as bad as Linux".
Packaging for Windows is truly horrible. Even getting the dependencies to build your app on Windows is a nightmare (the author mentions winget which is no good for libraries)?
I maintain an app that uses libsfml, libfluidsynth and a bunch of other dependencies. Packaging on windows was only made possible by MSYS2 and pacman which is literally a linux package manager.
99% of applications on Windows will just include all their dependencies in a folder with the exe. It’s great — it works, it’s compatible, it’s simple!
Getting dependencies to build your app is definitely harder on Windows but the fact that you can just throw things in a folder for a binary distribution is unbeat!
> Packaging for Windows is truly horrible. Even getting the dependencies to build your app on Windows is a nightmare (the author mentions winget which is no good for libraries)?
The only sane way I've found to do this, is ensuring I never package it on a personal computer/computer with state, always a CI worker with fresh everything, isolated from everything else, with nothing assumed. Then for the packaging, define all required dependencies up front, and you won't end up with the typical "oh, I forgot to ship/package lib X and I didn't get any errors because I have it installed". Helps to set all this up with Nix too, can help you manage the VM lifecycle, and makes reproducible cross-platform a lot easier :)
You seem to be assuming building for Windows in a Linux-like flow. If Linux is a series of tubes, Windows is a truck. On Windows, you build the library and statically link it to your executable. The executable is one big monolith that doesn't get cut up into miniscule pieces like on Linux. If you really need a DLL for some reason, you use as few as possible, and put it right next to the executable. On Windows, binary artifacts are "heavy".
Of course this assumes your main product is an executable - if you're intentionally shipping a COM object or something, which is a DLL, different guidelines may apply. In that case you should still ship a "heavy" single-DLL COM object.
I don't think this is entirely accurate and in fact, I think you'll encounter limitations in how big the .exe could actually be, before the OS says no, compared to Linux or macOS where you can pack more into it. But still, on all platforms, you won't have multi-GB binaries, you have external resources which among them are DLLs and whatever, and the binary ("executable") itself ends up some MBs. At least most (if not all) of the large professional software I use on Windows is packaged like that.
Large professional software has components like COM servers, or several executables sharing the same app code which then goes in a DLL. What they don't do is divide up their DLLs any more than necessary. An open source library could be a DLL to comply with LGPL but it won't be one just because they can, while on Linux it would be a separate .so because it's separately updated.
I think this approach is misguided. Shipping your own DLLs is standard with Windows applications and good workflows using Visual Studio can quite easily can bundle everything you need.
If you need somewhat Linux-like build infrastructure, conan is very helpful to install all your dependencies and to create deployment packages.
Shipping in C:\\Program Files\\Your Name is standard with Windows applications; DLLs aren't shared between different applications like in Linux, so there's no reason to use them.
Additionally, the Windows dynamic loader doesn't squish all DLLs into one global namespace like the Linux one does. Every time you call a function from a DLL there is extra friction, even for the programmer.
There's also the libc linking problem. Each DLL may get its own copy for libc, either because they are statically linked or because they are compiled with different versions. If you try to fopen in one DLL and fclose in another, or malloc in one and free in another, it's liable to crash. This might've been solved in the 20 years since I learned about it, though.
I always assumed those were statically linked into the binary or installer or something on Windows. Are people pulling down dependencies through the .msi?
Windows provides almost 100% of the system-level dependencies you need. You don't need to specify things like "I need gstreamer for video decode" or "openSSL for my network". Those are all part of a standard Windows system and they have stable API/ABIs.
Only thing you ship with your application are the libraries specific to your app. If you use Qt, you ship Qt libraries as bundled DLLs. If you use Havok physics engine, you ship that as a bundled DLL.
MSI can trigger things like installing optional Windows components but it is not a package ecosystem like apt or dnf. It is more like dpkg or rpm.
I use and only package for Arch. I'm a bad maintainer. If some Debian person wants it they can package it for their distro, but I don't see why it's on me to do it.
This, exactly. It's not a developer's job to package their code for every imaginable distro; it's their job to make the build process as simple as possible and let maintainers and users handle the packaging if they want the software. The time spent chasing down the hassles in the post would be better spent thinning the dependencies, if that's remotely feasible.
If developers can’t be bothered to ship their software to my platform, what is stopped someone else from stealing their FOSS (clone and rebrand) and shipping it themselves?
If I’m going to take on maintenance burden then I might as well make it how I want with a fork and take the notoriety.
> what is stopped someone else from stealing their FOSS (clone and rebrand) and shipping it themselves?
Nothing at all. This is not stealing. The term is "forking." It's how GCC got un-stagnated (see egcs), and how we got the ecosystem of alternate wifi firmware (two examples that come readily to mind.)
This is also where Free and Open source diverge: Open Source lets someone block others from forking their fork, whereas Free Software requires that forks remain free to be forked themselves.
As someone who packaged a lot of software for Linux, I have to admit that it's bespoke and forces you to make options that come with pros and cons. But at least it _works_.
Windows? We have 1 in 100 users whose antivirus nukes a random config file. Or part of the installer. MacOS? I hope you bought a Macbook, and don't mind updating your app indefinitely.
Uff, doing all of that plus developing your software sounds really hard!
I package software for void Linux... I don't think there's an expectation from devs to know all the intricacies and particulars of each distro and contribution guidelines in order to package software for it... A tar or GitHub repo and clear instructions is all we need to package it.
It becomes a pain when the software has hard dependencies on either bleeding edge unreleased software (I'm thinking hyprland) or very old versions of libs that are no longer shipped with the distro.
Another pain point is when the software makes assumptions about Linux like all linunx use glibc or have systemd. In cases like that packaging software might entail patching it, or just giving up (void doesn't use systemd for example)
Hope this gives you a bit of insight into what packages might be looking for
Yeah distributing desktop apps is a pain. I created Conveyor to solve that, see https://hydraulic.dev/
Quick feature set of interest to your project:
• It's free for open source projects.
• It's a tool not a service so you can just download+go without even needing to sign up for an account.
• It can create signed, self updating Windows, Mac and Debian packages in one go, with a single run on any chosen host platform. So you can ship from Linux to Win/Mac without having those systems.
• Fully supports code signing, delta updates, other advanced stuff.
• Creates a nice download HTML page that detects the user's OS and CPU etc.
You probably haven't read the article, but the software they build is a TUI, not a Desktop GUI (in fact a big chunk of the article is how they need to fight against Flatpak and AppImage because they are designed around the assumption of a GUI).
> The next version will include a new built-in self-updating mechanism that users can trigger on demand. This will be the main release channel for Linux and hopefully the only one
This is what Mozilla is doing with Firefox. I downloaded the binary from their site and it autoupdates. Debian 11 and then 13, all is good.
It's convenient for those who already use npm. You are almost always not forced to install npm. You can choose another packaging path (OP supports a multitude) or choose the less convenient path of building it yourself.
> I've seen few times that people abuse npm to do install of software that is not js, but why force me to install npm?
The "npm distribution method" is for people who already have npm installed, just like apt-get instructions are for people on Debian/Ubuntu, you're not meant to install apt if you happen to be on CentOS, just like you're not supposed to install npm if there is a better installation method for you. Sucks when it's the only installation method, same with curl|bash, I tend to just close the page when that's apparent, haven't missed anything so far.
Let's say I can build my software as a single static Linux binary (or at least, one for every supported arch) with no external deps outside of the syscall ABI. Which often isn't true for nontrivial software, but let's say it is. Is there some kind of automatic "make packages for everything" tool to stuff it into a .deb, .rpm, etc., and upload to the relevant package repos?
From a historical perspective... Debian and Redhat brought package management to Linux 30 years ago. That's why so many other distros were built on top of them.
And now today, we have a lot of new packages mangers on top of that, which has increased complexity a lot.
If I wanted to publish tools/programs, I would distribute the source code and let each distro decide how/if they want to package it. I would not try to do this myself. It's not a reasonable thing to do.
Claude Code and Codex are, in my experience, quite good at packaging software for Linux. I haven't gone through the full list of Linux deployment mechanisms, but I've had good success with little more than "Please make a set of github actions that publishes packages for releases as deb and rpm files for x86-64 and ARM, and makes a deb repo in github pages, and also for nixos."
Running Fedora Silverblue 44 as one of my desktop machines. Self updatable static binary sounds like a reasonable solution to me. But I can see why this has been a problem :/
That would work only for some people and even them will forget to check for updates. They would need a crontab or systemd timer, with git pull and the configure, compile, install pipeline. It gets unwieldy soon especially when you have to update or install dependencies.
It would work for most Linux distros, since this means that it's (probably) open source and therefore the package maintainers could package it with the distro.
If your package is FOSS, having the distros ship it is arguably the easiest approach.
Seconded on having a distro pick it up if the package becomes sufficiently popular. Until then, the ./configure dance is delightfully universal and it makes the downstream packaging folks' jobs simpler.
If you're on a Debian-type distro the checkinstall is definitely what you want instead of `make install`. It wraps make and gives you a package that dpkg knows about.
In 20 years using Linux, I don't think this has ever worked cleanly for me. Inevitably this will fail with some mysterious missing dependencies, it won't be clear what .deb package provides them, it turns out the distro version is too old or too new...
The author has a point, but at the same time is overly complicating things. Seeing that it is already available via cargo, all that is left to do is offer a .tar.gz bundle as well. In the case that the software actually becomes popular, someone else will package it for the distros in question.
flatpak should really push to make it work better for non GUI apps.
right now its a total mess both for users and developers. IIRC apps cant register a command line alias that gets added to your PATH and theres no way to request permissions for a file by name (you have to open a file select dialog scoped to a directory). i dont know if you can even tell the runtime to open your app in a terminal without hacks.
its all pushing devs to opt out of sandboxing as much as possible which defeats the whole purpose of containers.
So true - I packaged C++, C and recently Python app for Linux and it takes me so much time even if I try to automate as much as possible. I hate it. I needed to read through poor or obsolete documentation, non-existent guides and tools, do ugly tricks, use various exceptionsto make it usable/work ... and now generative AI policies and exceptions. I use Linux exclusively for ~30 years, but packaging for Windows via winget was actually much simpler:-/
Real missed opportunity before this all got out of control to simply bundle everything needed in a single file and give it an extension that tells the OS its executable.
Linux already has its own binary executable format, ELF (that you could just statically link, if you wanted to bundle everything).
Also the usual way to indicate that some file is executable on linux systems is just through an execute bit, not through an extension.
But the discussion here is more about how to package properly an application (for updates, app centralized management etc,) than how to deliver an executable on linux.
Oof, yeah that's painful. I'm impressed you've gone to these lengths, most maintainers don't do that. They generally rely on the folks who want to use the software packaging it for their distros. Obviously there's a bit of a chicken and egg problem there, though, if you care about getting your software in front of users.
For the Debian situation specifically:
> It would've been nice if there was a quick serverless solution where you could just say a URL to look for newer versions of a single package, and both apt and dnf would remember that and update a package.
Have you considered just hosting your own Debian repo? It's basically what you're looking for here. You don't need more infrastructure, either, you can host them straight in github pages with aptly or reprepro or something, and drop new releases in there from CI.
I do publish deb files in the GitHub release page. Will take a look at aptly / reprepo
Yeah, the one thing you're missing is getting into the users' `apt update`/`apt upgrade` flow, right? This will get you there without needing to change the Debian package you already create (although you can ship different ones this way if e.g. older Ubuntu/Debian distros require it and you want to support them).
> Have you considered just hosting your own Debian repo?
There are Canonical PPAs for that, which make distribution much simpler (it's still not as simple as it could, but with AI's help it's simple).
Of course. Needing to ship a source package (as PPAs require) may actually complicate things, though.
The software referenced is open source and it's already packaged to deb (see home page), so setting up the boilerplate for PPA submission (via AI) is very easy.
If a package doesn't have particular build requirements, setting up a PPA is overall simpler than hosting a personal repo (I do both).
To be clear, I'm not trying to argue or disagree with you. I agree that PPAs are a fine option. I'm not trying to disparage them, I'm trying to explain the reasoning behind my suggestion: PPAs enforce a number of requirements that exist for a reason, but that can be a challenge to meet depending on the project. The biggest example is that of source packages. I don't mean "your source needs to be open" (which of course this project is), but rather "your software needs to be built on Launchpad infrastructure." If you take a look at the existing CI the maintainer has in place to build the binary deb, you'll see what I mean: https://github.com/sinelaw/fresh/blob/master/.github/workflo... . The maintainer already has this, and it would need to be completely re-done to make it work in Launchpad, and the amount of work might be quite significant. A standalone Debian repo can just have binary debs, i.e. the work that has already been done can continue being used.
Thus my recommendation for aptly/reprepro: it's a more natural extension of what the project already has in place rather than a "you should do this instead."
I think that you just need to provide .tar of your app. Everything else should be problem for people who handle packages of different distros. You don't wanna be involved in that part of distribution. If people want your app, someone will make a package. There are too many package manages for you to run and add your stuff to all of them. Just have .tar on static http server and that's it! Example: http://ftp.klid.dk/ftp/gnu/gcc/
It's a problem for my potential users. I don't get this "it's not your job to distribute your own software".
Parent post already told you a way to distribute your software to Linux users; assuming your tarballs with prebuilt binaries "just work", as in, it's enough to untar it wherever (/opt?) and create a symlink in $PATH for your executable.
But from your comments, the message I get is that you want to apply to become a maintainer in each and every Linux distribution's package repositories, both mainstream and niche? And apparently also create packages for some alternative package managers too? (e.g. mise, npm, Terra)
Yes. But I would bet, people who use a cli editor would not mind manually updating their package.
I use fedora on my work machine. It is a pain. But hey, freedom of choice has its drawbacks too.
The reason this seems so weirdly hard is that you're not supposed to be doing it. You provide sources and instructions on how to build them, and then your job is done. Users can follow those instructions. If you want to you can also build a binary with an old version of libc and distribute that to help users who don't want to compile it themselves.
Packaging it for a distro is someone else's job, and they'll take care of concerns like Debian's dependency policy. If they want to package it in the first place of course.
This isn't a good dichotomy though. Either "Build it from source" or "Wait for a professional 3rd party to package it for you".
The idea that your OS distro needs to explicitly support and package every software you could ever want to use seems crazy to me.
Both users and authors want the same thing: low-effort, high-quality distribution of software.
Personally I put my support behind flatpak for GUI, mise for CLI/TUI, but it's not a perfect solution and I occasionally bail out to homebrew/linuxbrew.
> This isn't a good dichotomy though. Either "Build it from source" or "Wait for a professional 3rd party to package it for you".
Somebody has to do the work. Apparently you won't accept it for that to be the developer, the user, or a "professional third party" (whatever "professional" means here). What exactly do you want?
> Personally I put my support behind flatpak for GUI, mise for CLI/TUI, but it's not a perfect solution and I occasionally bail out to homebrew/linuxbrew.
So third parties. Things that have reinvented "distributions", arguably badly. Are you saying they're not "professional"?
> What exactly do you want?
1. I want it to be easy for developers to publish their own packages. 2. I want it to be easy for users to install these developer-published packages.
> Are you saying they're not "professional"?
I regret using the word professional, I was replying to the claim GP made:
> Packaging it for a distro is someone else's job
Well I (as a developer) want to publish my own software without waiting and hoping someone else will do it for me.
> Somebody has to do the work.
Yes, I (the developer) want to do the work. The whole point of the article is that its painful to do today. I'm interested in how we make the packaging work easier so the developers can do it.
> [...] So third parties
the whole 3rd/1st party question is whether a developer can publish their own package. In most cases they technically can (taps, PRs, flathub, Debian registries, so on) but run into lots of issues along the way.
> Packaging it for a distro is someone else's job, and they'll take care of concerns like Debian's dependency policy. If they want to package it in the first place of course.
Yup, this is why I think so many people feel so much friction about it. On Windows and macOS, the developer is usually responsible for the entire thing, even shipping installers for users. Linux distributions tend to split the roles, and as mentioned, once you provide sources and how to build it, you're basically done and it's up to others now.
That sounds like you could have a situation where the developer wants me to run the app, and I want to run the app, but nobody at the distro I use has packaged up the app, so we're blocked.
> but nobody at the distro I use has packaged up the app
But you're "at the distro", and you want to use it, so you package it :) You might want to be nice to others too, so you make that public. Eventually, the community might end up relying on it, and the package gets an official maintainer from the distribution itself.
Then you can be the one who'll package it for your distro.
Sorry, I don't have those skills, or any spare time.
And if you want a system whereby software only gets made available if distro-providers care enough, then that's fine. But you're putting a filter between the software producer and non-technical users, and you should be aware that this is a choice you're making.
It has worked for decades and many thousands of packages just fine.
If nobody cares enough to make the application available, perhaps it just shouldn't be there.
You still need the distro maintainers to cooperate. And the packaging itself can be highly involved (as in the case of rust dependencies on Debian)
Of course you do, that's where the value comes from after all.
"Someone else's job" doesn't help getting the software into my user's hands.
I need a solution that works for my users regardless.
If they're not using your software they're not your users.
You seem to be treating this like a commercial endeavor in which you have much to gain from adoption by nontechnical people. I don't really see why though. It looks like you're developing non-commercial open source software for an audience of developers.
You are taking on the responsibility of being compatible with a large variety of different people's opinions on how software should be built, configured, and distributed. Yes that's a lot of work. Distributions have people willing to do that work for software they or their users (who can ask) care about.
Linux evangelists on the internet are some of the most unhelpful and useless people you will ever come across. My condolences in advance for every "ackshually you must pray and wait 10 years that some Debian maintainer to pick it up" reply.
I get that but I feel like its a bit different for linux users. The ecosystem has way more folks that are used to building their own tools relative to Win/Mac. Especially for something like nix. I've built nixpkgs for tools I've wanted to try & use. For something like this, I'd stick with cargo and let others do the packaging.
> You provide sources and instructions on how to build them
Have you ever interacted with actual users? This is absolute no-go which will only bring world of pain on you and your issues list and your email and your Discord and whatever other way you decide to talk to users....
Hi, I'm the author of this post (and of Fresh). I've spent a lot of time getting it distributed cleanly to Linux users of all distros, and it's an uphill battle. I'm curious how other solo maintainers are dealing with this problem. Is a self updating static binary a reasonable solution?
The answer is to not do it. Provide the source and help distro maintainers to package it for you. You can help by being responsive to maintainers' questions, making sure the source is clean (no binary blobs, weird licenses, strange build systems, generally builds like similar packages), and integrating patches from maintainers upstream.
If I don't make my program easy to install, many people won't even try it.
Being responsive to maintainers doesn't help if maintainers never reach out or even actively refuse to package your software.
In the early stages you can help by making your source code easy to build. No weird build system, make dependencies optional as much as possible, document how to build, reduce the number of steps required and make them as similar as possible to comparable software. Linux users will put up with this. That also helps distro packagers so it's a win-win.
Usually thats the job of the Distro maintainers, your job is to provide a .tar.gz site on your website, the distro maintainers are responsible for publishing your app on their distro's.
This doesn't really scale, and it doesn't really solve the problem for your (potential) users to wash your hands of software delivery like this.
I mean thats the whole philosophy of Linux distros, anyone can create a Linux distro but the job they then take on is maintaining their own distribution of packages. I'm not saying your wrong; I'm just saying that is the what a Linux distribution _is_.
I personally think that a self-updating static binary is the pragmatic choice. I give out my software in the form of a single static binary which my users can update using a simple "update" command when a new released is published - they also receive access to the Git repo if they for any reason choose to build it themselves. I've had users on many different Linux distributions and no one has complained yet.
Linus Torvalds has talked about this very issue. He didn’t even release his own app for Linux as a result and relied on others to pick up the slack and package the app for Linux, while telling them they were wasting their life.
https://m.youtube.com/watch?v=Pzl1B7nB9Kc
At work we maintain embedded-linux computers with a custom distro but the actual graphical interface is a separate artifact developed by another team. Moreover they have to use an SDK that only works on a specific distro (semi-closed source).
Our solution is shipping it with its own glibc and running the executable with the LD inside this separate glibc. Basically the entire userspace. It is almost like a container but the containerization is provided by systemd and there is scoped access to limited system services via mount and network namespaces.
We cannot use static programs. Our systems have limited memory so the GUI load relevant parts of the program as shared library plugins.
This is the only reliable way to distribute closed source / independently packaged Linux software. You ship it with an entire userspace. Docker and Flatpak are just that; an admittance that distributing independent software reliably on Linux is practically impossible.
Have you considered running Docker on the embedded device?
That sounds like a heavier-weight wrapper over the same system services they're using through systemd today.
It could be useful if updating is a pain point.
In this case, they may also consider Podman, as it has excellent systemd integration[1] including rudimentary container orchestration and the ability to auto-update containers and Kubernetes-style pods installed as systemd units. I've run Pihole under Fedora CoreOS this way for several years without touching a single thing to update the OS or Pihole.
[1] https://docs.podman.io/en/latest/markdown/podman-systemd.uni...
See https://news.ycombinator.com/item?id=49275165
TL; DR you're right. We are aware options like Podman and systemd-nspawn (check it out if you don't know). They are just overkill.
No we don't need / shouldn't use Docker. As jasomill guessed the disk size and memory usage that Docker needs is just unnecessary overhead. These devices have only 8 GiB disk space. systemd provides every single thing that we need; one can obtain equivalent isolation just with a systemd unit file.
If you don't need the layers of Docker and server pull-push, it is just overhead. We just fetch a single cryptographically signed squashfs file and execute the program in it with limited FS and separate namespaces.
I feel like Zed, rustup, and a lot of other applications (with CLIs) moved in that direction. (Hope someone corrects me if that’s wrong, unsure those projects are fully static, but they do self update.)
As a user that surprised me at first, but I’ve grown to really like it!
> Is a self updating static binary a reasonable solution?
It's a reasonable antidote against DLL hell, so I would say yes, that's as close to an ideal solution as we can get.
Considering you are already using Rust and looking at a static binary: why not package that inside the various distro-specific formats?
Sure, you won't get into the official repos that way, but do your users really care? Fedora users are pretty used to enabling Copr and RPMFusion, Ubuntu has its PPAs. It's not ideal, but it's good enough. Even an RPM/DEB via Github release would already be a good start.
Rust binaries are not static by default, they _statically link other crates_ by default. Subtle but important distinction.
Sure, I already do offer deb/rpm via GitHub release page. My problem is ensuring users have an easy way to update
Not sure about debian/ubuntu.
You can easily setup a copr repo for this to solve the auto update qualms for almost all the RPM repos. Needs a spec file and that's about it.
AUR should do.
Debian. Eeshk.
I think the only downside with the musl binary is that there can be a performance hit compared to libc, which may or may not be an issue for a terminal text editor.
I also echo some of the comments here saying it's entirely reasonable for a single maintainer not to support absolutely every single distro unless it's straightforward or enjoyable.
Just use Steam. Works on all the Linux distros. lmao Ironically this might not even be as stupid a suggestion as it sounds.
Costs money and is centralized with a for-profit entity, probably best to stay far away when it comes to day-to-day software.
Don't get me wrong, I love Steam, but for video games. You can't stop auto-updating for example, and still be able to launch the "game" (program in this case) if it's out of date, which obviously breaks pretty much every professional computer user's workflow.
It doesn't have to cost money. You can write a normal Windows app and run it under Proton. For end users, provided that they have Steam installed (it's free), they can just add "Non-Steam game" to the library - it's ~4 clicks.
It works. It works great. It's actually the only sensible solution if you want something compiled today to work without changes on both Windows and Linux in 10 years.
I did an experiment, implementing a GUI calculator, and Rust + Slint + cross-compiling to Windows (I develop on Linux) + Proton runtime was the clear winner:
You have an option to build for Linux for dev/testing, then you cross-compile to Windows and provide a short (4 points) instruction for adding the Windows build to Steam on Linux. It works, and it will most likely continue to work in the future, unless Valve folds and both Wine and Proton die. The only thing worth looking out for is crates that depend on external shared libraries: you need to bundle them manually. Other than that, it works.Another option I considered was Zig with the Win32 API, but the LOC count was unacceptably high.
I'm working on a write-up for the experiment. The premise was: "I'm working on Linux and want to create a GUI app that will, with the build done today, continue working on Windows and Linux for the next 10 years". Steam/Proton + mostly static compilation + bundled libraries is the only solution that makes this mostly painless.
> It doesn't have to cost money. You can write a normal Windows app and run it under Proton. For end users, provided that they have Steam installed (it's free), they can just add "Non-Steam game" to the library - it's ~4 clicks.
Publishing on Steam costs money: https://partner.steamgames.com/doc/gettingstarted/appfee
I'm saying you don't need to publish on Steam to make your app run on Steam. You really don't. A user can add any executable to the Steam Library via the "Add a Game -> Add Non-Steam Game" button in the bottom-left corner of the GUI. It works 100% locally and with any kind of executable (not just games). It also bypasses any auto-updates. Finally, you can launch an app like that from the CLI or a desktop shortcut without opening Steam (well, it'll still run and update itself when needed, but you bypass the GUI).
The full discussion about this I had with ChatGPT is here: https://klibert.pl/statics/Steam-Linux-Runtime-Stack-2026-08...
> A user can add any executable to the Steam Library via the "Add a Game -> Add Non-Steam Game" button in the bottom-left corner of the GUI.
Yeah, but that's also not exactly a better user-experience for the end-user than "Download .exe, double-click to launch" or "Download .msi, finish install, run program".
Distribute your software however you want, I tend to try to make the download and install as familiar as possible to the users of the specific platforms.
Btw, even your starting prompt is guiding the model to just agree with your opening statement. You can't just roll with whatever the model says and assume the conclusion of "definitely can run in 10 years unchanged" is true.
Yeah, that's why the second prompt starts with "You misunderstood" and a correction. This is a long conversation, with multiple experiments performed and a lot of inspection of all the intermediate results on my end between prompts. You assuming otherwise without reading is a bit offensive.
To your point on installation: sure, but if you value it that much, just pay Valve to add you to the Steam store? And that would be the only possible solution given my constraints, all explicitly mentioned at least once in the linked conversation:
For this set of constrains, Proton/Wine with a cross-compiled Win32 binary/bundle is literally the only solution (care to name another?)For other constraints, it's a solution. Worth considering. That's all.
> You assuming otherwise without reading is a bit offensive.
Yeah sorry, hurling huge LLM conversations at me tends to make me skim them, hope you don't mind I didn't study the conversation you had with ChatGPT in detail.
That you considered someone skimming a chat log offensive yet the act of sharing those chat logs and expecting others to dredge through them, is almost offensive to me. So I guess we can call it even now.
> For this set of constrains, Proton/Wine with a cross-compiled Win32 binary/bundle is literally the only solution (care to name another?)
Cross-compiling the good old way, with a Linux VM, Windows VM and a macOS host (maybe Mac Mini?). I basically have the very same requirements (+ macOS), except zero third party dependencies, and end up doing it this way, all managed with Nix so basically all the installation-bloatyness is something I deal with so users get the exact same experience they expect on their OS.
[dead]
And you can use Wine or Crossover to run your app on the Mac.
Better yet, build it for Windows 95, and it'll not only run under Windows, Linux, and macOS, but you can even package it to run in a browser[1].
For command-line programs, you might try something like Cosmopoliton[2] instead.
[1] https://www.pcjs.org/software/pcx86/sys/windows/win95/4.00.9...
[2] https://github.com/jart/cosmopolitan
Steam works because it packages certain distros that everyone can rely on. It's the same approach as Docker or Flatpak.
Steam provides a stable Linux runtime, but it's not containerized or isolated Docker/Flatpak-style. It's closer to a chrooted env with some specific distro, but without chroot and the need to maintain said distro. They want to provide runtime stability and compatibility comparable to that on Windows - it's a great initiative, and I really hope they'll succeed. The snowflake-like userlands on Linux are a pain, but the current solutions (Docker, Flatpak, things like conda) are all bad solutions to this particular problem (though they are good solutions to other problems, so it's not a criticism, just a difference in goals).
However, Steam Runtime for Linux was still in beta, last I checked. Plus, it doesn't solve the cross-platform part. But for Linux-native development, Steam Runtime might be what's needed to have long-term compatibility for apps (finally).
It's xkcd927 of a container.
Probably not, you'll receive flak for that in some circles.
I made a different post, but fits here as well: https://news.ycombinator.com/item?id=49271276
TLDR is basically that you don't have to package it for others, the expectation is that people using the distributions will package it for themselves and others if the software ends up useful enough and they want it in the distribution. Until then, just ship a zipped up binary or whatever and call it a day.
There's no end how complicated you can make things for yourself, if you really want to.
What you should do is make software good enough so your users will use it, and publish the source code under a free license. The first Debian developer that uses and likes your software will package it, and the virtous cycle can start. It can be tempting to "own" the user experience (after all, everone wants to own their customer) but one has to let go of that thought. Updates can not be expected to get pushed out the same day when you don't own the customer, but that's overall a good thing.
Ask the distro people what you can do to make their work easier, listen to them, but do not try to do their work for them. Unless you live in that distro you are unlikely to understand how they expect your software to behave and the nuances of how it should be packaged.
One of the good ideas about Linux packaging is that it is not the same people that make the software that package it. Code can be reviewed. Bad ideas can be caught. This principle is sometimes violated, but that violations happen doesn't make them a good idea. We live in a world where no one should execute random software from the Internet without any form of reputation or review, and distribution packaging suggests one way we can accomplish that. A way that has survived three decades, after all, so maybe it's worth listening to.
Fully agree. In good 'ol times, we had (and still can have!) GNU Autotools where the maintainer created distributions and the end user's (packager) system just needed to have rudimentary support for building programs from source (POSIX-compliant make, shell, compiler, linker etc.).
I know, speaking for GNU Autotools will get me downvotes and nasty comments, but there are many things the GNU Operating System got right and stable, mature distributions like Debian show still its heritage.
I agree with the author. I've made nice cross-platform pro metronome (as some use timer which is bad)
https://tick.talaviram.com
Apple, Microsoft, Google - none is easy meaning you need to have Play store, certs, codesign, submit... But there are steps with few results making it easy for those platform to get the software.
I have tried my best getting also Linux but as the author said, there's nothing trivial (as my metronome GitHub issues can show https://github.com/talaviram/TICK/issues)
The name is exactly the tricky part... Linux has so many flavors. Even without installer, you have X server and Wayland and snap, AppImage, .deb each differ. add to that audio plug-in formats (CLAP, LV2, VST3) and the fact that some formats has no specific path for putting files.
For simple apps (not cli tools or ones aimed for package managers I start to think best is just providing an archive file (zip/tarball/etc)
While Linux is growing and is my goto for non-macOS, with so many releases, it still feels most users are more technical than other platforms. Add the LLM age where you can ask it to install it for you. a zip with binaries might be simplest for simple software.
The traditional way on Linux, at least in FOSS, has been to basically ship the binary somehow, also make the source available, then if people want it for Debian or whatever, they'll package it themselves. Typically, the person(s) developing the software itself are different people(s) who package it. So you'll have the application/library developer(s), then if people want it for their distribution, one of them has to decide to package it and make it available.
Of course, people nowadays try to make it easier for the distributions and provide packaging for them. But I don't think this is requirement, you can just ship a binary and most Linux users will be able to run them, and it'll basically "package itself over time" if it's interesting enough for people to want that sort of integration.
There is no right/wrong or correct/incorrect approaches here, just giving ideas :)
I just did a double take at "Windows and macOS aren't as bad as Linux".
Packaging for Windows is truly horrible. Even getting the dependencies to build your app on Windows is a nightmare (the author mentions winget which is no good for libraries)?
I maintain an app that uses libsfml, libfluidsynth and a bunch of other dependencies. Packaging on windows was only made possible by MSYS2 and pacman which is literally a linux package manager.
99% of applications on Windows will just include all their dependencies in a folder with the exe. It’s great — it works, it’s compatible, it’s simple!
Getting dependencies to build your app is definitely harder on Windows but the fact that you can just throw things in a folder for a binary distribution is unbeat!
> Packaging for Windows is truly horrible. Even getting the dependencies to build your app on Windows is a nightmare (the author mentions winget which is no good for libraries)?
The only sane way I've found to do this, is ensuring I never package it on a personal computer/computer with state, always a CI worker with fresh everything, isolated from everything else, with nothing assumed. Then for the packaging, define all required dependencies up front, and you won't end up with the typical "oh, I forgot to ship/package lib X and I didn't get any errors because I have it installed". Helps to set all this up with Nix too, can help you manage the VM lifecycle, and makes reproducible cross-platform a lot easier :)
You seem to be assuming building for Windows in a Linux-like flow. If Linux is a series of tubes, Windows is a truck. On Windows, you build the library and statically link it to your executable. The executable is one big monolith that doesn't get cut up into miniscule pieces like on Linux. If you really need a DLL for some reason, you use as few as possible, and put it right next to the executable. On Windows, binary artifacts are "heavy".
Of course this assumes your main product is an executable - if you're intentionally shipping a COM object or something, which is a DLL, different guidelines may apply. In that case you should still ship a "heavy" single-DLL COM object.
> The executable is one big monolith that
I don't think this is entirely accurate and in fact, I think you'll encounter limitations in how big the .exe could actually be, before the OS says no, compared to Linux or macOS where you can pack more into it. But still, on all platforms, you won't have multi-GB binaries, you have external resources which among them are DLLs and whatever, and the binary ("executable") itself ends up some MBs. At least most (if not all) of the large professional software I use on Windows is packaged like that.
Large professional software has components like COM servers, or several executables sharing the same app code which then goes in a DLL. What they don't do is divide up their DLLs any more than necessary. An open source library could be a DLL to comply with LGPL but it won't be one just because they can, while on Linux it would be a separate .so because it's separately updated.
What are you making?
I think this approach is misguided. Shipping your own DLLs is standard with Windows applications and good workflows using Visual Studio can quite easily can bundle everything you need.
If you need somewhat Linux-like build infrastructure, conan is very helpful to install all your dependencies and to create deployment packages.
Shipping in C:\\Program Files\\Your Name is standard with Windows applications; DLLs aren't shared between different applications like in Linux, so there's no reason to use them.
Additionally, the Windows dynamic loader doesn't squish all DLLs into one global namespace like the Linux one does. Every time you call a function from a DLL there is extra friction, even for the programmer.
There's also the libc linking problem. Each DLL may get its own copy for libc, either because they are statically linked or because they are compiled with different versions. If you try to fopen in one DLL and fclose in another, or malloc in one and free in another, it's liable to crash. This might've been solved in the 20 years since I learned about it, though.
I always assumed those were statically linked into the binary or installer or something on Windows. Are people pulling down dependencies through the .msi?
Windows provides almost 100% of the system-level dependencies you need. You don't need to specify things like "I need gstreamer for video decode" or "openSSL for my network". Those are all part of a standard Windows system and they have stable API/ABIs.
Only thing you ship with your application are the libraries specific to your app. If you use Qt, you ship Qt libraries as bundled DLLs. If you use Havok physics engine, you ship that as a bundled DLL.
MSI can trigger things like installing optional Windows components but it is not a package ecosystem like apt or dnf. It is more like dpkg or rpm.
Yes, the DLLs are usually installed along with the binary by the installer on Windows.
What I was talking about was the setup required on your machine/CI to get the dependencies to build those DLLs.
I use and only package for Arch. I'm a bad maintainer. If some Debian person wants it they can package it for their distro, but I don't see why it's on me to do it.
This, exactly. It's not a developer's job to package their code for every imaginable distro; it's their job to make the build process as simple as possible and let maintainers and users handle the packaging if they want the software. The time spent chasing down the hassles in the post would be better spent thinning the dependencies, if that's remotely feasible.
If developers can’t be bothered to ship their software to my platform, what is stopped someone else from stealing their FOSS (clone and rebrand) and shipping it themselves?
If I’m going to take on maintenance burden then I might as well make it how I want with a fork and take the notoriety.
> what is stopped someone else from stealing their FOSS (clone and rebrand) and shipping it themselves?
Nothing at all. This is not stealing. The term is "forking." It's how GCC got un-stagnated (see egcs), and how we got the ecosystem of alternate wifi firmware (two examples that come readily to mind.)
This is also where Free and Open source diverge: Open Source lets someone block others from forking their fork, whereas Free Software requires that forks remain free to be forked themselves.
There is Open Build Service from openSUSE which allows you to create packages and repos for a handful of distros. https://build.opensuse.org/
As someone who packaged a lot of software for Linux, I have to admit that it's bespoke and forces you to make options that come with pros and cons. But at least it _works_.
Windows? We have 1 in 100 users whose antivirus nukes a random config file. Or part of the installer. MacOS? I hope you bought a Macbook, and don't mind updating your app indefinitely.
Uff, doing all of that plus developing your software sounds really hard!
I package software for void Linux... I don't think there's an expectation from devs to know all the intricacies and particulars of each distro and contribution guidelines in order to package software for it... A tar or GitHub repo and clear instructions is all we need to package it.
It becomes a pain when the software has hard dependencies on either bleeding edge unreleased software (I'm thinking hyprland) or very old versions of libs that are no longer shipped with the distro.
Another pain point is when the software makes assumptions about Linux like all linunx use glibc or have systemd. In cases like that packaging software might entail patching it, or just giving up (void doesn't use systemd for example)
Hope this gives you a bit of insight into what packages might be looking for
Yeah distributing desktop apps is a pain. I created Conveyor to solve that, see https://hydraulic.dev/
Quick feature set of interest to your project:
• It's free for open source projects.
• It's a tool not a service so you can just download+go without even needing to sign up for an account.
• It can create signed, self updating Windows, Mac and Debian packages in one go, with a single run on any chosen host platform. So you can ship from Linux to Win/Mac without having those systems.
• Fully supports code signing, delta updates, other advanced stuff.
• Creates a nice download HTML page that detects the user's OS and CPU etc.
• Simple config file syntax.
Check it out, see if you like it.
You probably haven't read the article, but the software they build is a TUI, not a Desktop GUI (in fact a big chunk of the article is how they need to fight against Flatpak and AppImage because they are designed around the assumption of a GUI).
> The next version will include a new built-in self-updating mechanism that users can trigger on demand. This will be the main release channel for Linux and hopefully the only one
This is what Mozilla is doing with Firefox. I downloaded the binary from their site and it autoupdates. Debian 11 and then 13, all is good.
Giving software the rights to overwrite itself is not good design.
Mozilla can, because they are so large they can have people spend their days working on it. No one else should.
mozilla hosts an apt repository for firefox, I much prefer using the native package management
So is this app written in Rust or in JS/TS? Why is he writting about npm at all if it is Rust?
I've seen few times that people abuse npm to do install of software that is not js, but why force me to install npm?
It's convenient for those who already use npm. You are almost always not forced to install npm. You can choose another packaging path (OP supports a multitude) or choose the less convenient path of building it yourself.
> I've seen few times that people abuse npm to do install of software that is not js, but why force me to install npm?
The "npm distribution method" is for people who already have npm installed, just like apt-get instructions are for people on Debian/Ubuntu, you're not meant to install apt if you happen to be on CentOS, just like you're not supposed to install npm if there is a better installation method for you. Sucks when it's the only installation method, same with curl|bash, I tend to just close the page when that's apparent, haven't missed anything so far.
You are essentially one executable just an editor so why don't you link statically ? Apart from the c runtime?
Still need to handle automatic upgrades. That's my plan. I was wondering if there's a better way...
Let's say I can build my software as a single static Linux binary (or at least, one for every supported arch) with no external deps outside of the syscall ABI. Which often isn't true for nontrivial software, but let's say it is. Is there some kind of automatic "make packages for everything" tool to stuff it into a .deb, .rpm, etc., and upload to the relevant package repos?
From a historical perspective... Debian and Redhat brought package management to Linux 30 years ago. That's why so many other distros were built on top of them.
And now today, we have a lot of new packages mangers on top of that, which has increased complexity a lot.
If I wanted to publish tools/programs, I would distribute the source code and let each distro decide how/if they want to package it. I would not try to do this myself. It's not a reasonable thing to do.
Claude Code and Codex are, in my experience, quite good at packaging software for Linux. I haven't gone through the full list of Linux deployment mechanisms, but I've had good success with little more than "Please make a set of github actions that publishes packages for releases as deb and rpm files for x86-64 and ARM, and makes a deb repo in github pages, and also for nixos."
Running Fedora Silverblue 44 as one of my desktop machines. Self updatable static binary sounds like a reasonable solution to me. But I can see why this has been a problem :/
You forgot the lines necessary for downloading the dependencies, and the dependencies of dependencies, etc.
(and compiling and installing those dependencies)
That would work only for some people and even them will forget to check for updates. They would need a crontab or systemd timer, with git pull and the configure, compile, install pipeline. It gets unwieldy soon especially when you have to update or install dependencies.
It would work for most Linux distros, since this means that it's (probably) open source and therefore the package maintainers could package it with the distro.
If your package is FOSS, having the distros ship it is arguably the easiest approach.
>It would work for most Linux distros
But not for most people.
It doesn't work for people who don't use Linux, true.
Seconded on having a distro pick it up if the package becomes sufficiently popular. Until then, the ./configure dance is delightfully universal and it makes the downstream packaging folks' jobs simpler.
No automatic updates is a desirable feature for me, not a problem.
If you're on a Debian-type distro the checkinstall is definitely what you want instead of `make install`. It wraps make and gives you a package that dpkg knows about.
cargo install (the equivalent command here) is available. Downsides:
- very slow
- need to install prerequisites
- not possible on many machines (to weak, not enough disk for running builds)
Many users don't want to deal with this
In 20 years using Linux, I don't think this has ever worked cleanly for me. Inevitably this will fail with some mysterious missing dependencies, it won't be clear what .deb package provides them, it turns out the distro version is too old or too new...
The author has a point, but at the same time is overly complicating things. Seeing that it is already available via cargo, all that is left to do is offer a .tar.gz bundle as well. In the case that the software actually becomes popular, someone else will package it for the distros in question.
flatpak should really push to make it work better for non GUI apps.
right now its a total mess both for users and developers. IIRC apps cant register a command line alias that gets added to your PATH and theres no way to request permissions for a file by name (you have to open a file select dialog scoped to a directory). i dont know if you can even tell the runtime to open your app in a terminal without hacks.
its all pushing devs to opt out of sandboxing as much as possible which defeats the whole purpose of containers.
Flathub (not sure if these are the same people behind Flatpak) makes it clear they don't welcome these types of submissions:
https://docs.flathub.org/docs/for-app-authors/requirements
So true - I packaged C++, C and recently Python app for Linux and it takes me so much time even if I try to automate as much as possible. I hate it. I needed to read through poor or obsolete documentation, non-existent guides and tools, do ugly tricks, use various exceptionsto make it usable/work ... and now generative AI policies and exceptions. I use Linux exclusively for ~30 years, but packaging for Windows via winget was actually much simpler:-/
Exactly. It's ironic that the end result is "windows is easier". Ugh.
Real missed opportunity before this all got out of control to simply bundle everything needed in a single file and give it an extension that tells the OS its executable.
We could call it a .exe
Linux already has its own binary executable format, ELF (that you could just statically link, if you wanted to bundle everything). Also the usual way to indicate that some file is executable on linux systems is just through an execute bit, not through an extension.
But the discussion here is more about how to package properly an application (for updates, app centralized management etc,) than how to deliver an executable on linux.
This is a solved problem really.
Just ship a statically compiled binary for each kernel/cpu (eg: linux/and64, linux/arm64).
That’s what terraform and kubectl do, for example.
[flagged]
[dead]
Use brew on Linux!
https://www.ypsidanger.com/homebrew-is-great-on-linux/