News for hackers. Stuff that matters.
Re:Single binary executable packages by mattgreenrocks on Wednesday March 02, 2022 @10:59AM (#30528756)
> Languages suitable for single binary executables

> C/C++: certainly possible, but you'll need on retainer a UNIX graybeard, or at least an autotools-foo master

I don't understand this. The "C/C++ is black magic!!" meme just never seems to go away.

They both support static linking and always have. It mostly comes down whether you dependencies will work with it, and setting appropriate compiler flags. In other words, not terribly different than anything other supporting language.

Re:Single binary executable packages by BeeOnRope on Wednesday March 02, 2022 @12:14PM (#30529787)
Creating a portable single-executable in C/C++ on Linux is not particularly easy.

The dominant libc for Linux, glibc, says "static linking is highly discouraged", see [1] among many other sources for the subtle problems it causes.

There are solutions like [2], [3], and [4] but they all have downsides and don't compare at all to e.g., the go (or even rust) single-executable story.

---

[1] https://stackoverflow.com/questions/57476533/why-is-statical...

[2] Link glibc anyway and try to avoid the pitfalls.

[3] Link glibc dynamically but everything else static, and build your exe using an ancient toolchain (or better, a new toolchain built for an ancient libc) so that it works on most distros.

[4] Give up on glibc and statically link an alternative libc like musl.

Re:Single binary executable packages by kristov on Wednesday March 02, 2022 @12:39PM (#30530115)
Or just dynamic link to libc and static link the rest as much as you can. If a binary dynamically links to libc, but is otherwise statically linked, all good no?
Re:Single binary executable packages by BeeOnRope on Wednesday March 02, 2022 @04:20PM (#30533339)
Yes, that was option [3]. The problem is that glibc symbols are versioned and update fairly regularly, so your binary likely won't run on anything with a much older glibc, and glibc versions vary a lot across distros (e.g., some are much slower moving so use very old glibc).

To work around this you need to try to build on an old of a distro as possible, so you use only old symbols... but you don't want to build on an ancient compiler since it might not support the language version or compiler flags you need, so you first build a new old toolchain on the old distro against the old libc, or find a docker container from someone who has already gone though this pain.

Of course, this also means you can't use new libc features: libc is more than just the C runtime, it's also the shim layer between userspace and the kernel, so you might miss out on newer system calls (or have to write the wrappers manually, etc).

It gets even worse for C++.

Re:Single binary executable packages by admax88qqq on Wednesday March 02, 2022 @01:46PM (#30531108)
Pretty good. Glibc does update occasionally. I've hit issues in the past trying to run old proprietary binaries that required libc.so.5

But yeah that's pretty rare tbh.

Re:Single binary executable packages by BeeOnRope on Wednesday March 02, 2022 @04:22PM (#30533363)
The major library version number (e.g., 5 vs 6) isn't enough: the symbols even within lib.so.6 are versions and some may update every glibc version, so in general you may have problems building against a new libc 6 then running on a system with an old libc 6 (you'll get a runtime error from the dynamic loader complaining a missing versioned symbol).
Re:Single binary executable packages by admax88qqq on Thursday March 03, 2022 @01:48PM (#30545003)
Yay for "semantic versioning" lol.
Re:Single binary executable packages by irq-1 on Wednesday March 02, 2022 @01:30PM (#30530906)
*Edit: I was wrong. Just checked go 1.7 and it made a static binary; no dynamic links. Don't know when that changed.

> [3] Link glibc dynamically but everything else static

Go does this. Zig links musl [4] by default but gives you the option to link glibc. I don't know about Rust.

Re:Single binary executable packages by paxswill on Wednesday March 02, 2022 @01:48PM (#30531148)
Rust links glibc dynamically, and can use musl for some platforms. By default most (all?) of the musl targets are linked statically, but they should be able to use dynamic linking for it as well.
Re:Single binary executable packages by marcosdumay on Wednesday March 02, 2022 @01:40PM (#30531028)
The good news is that there has been a long time since glibc had breaking changes, and the formal policy of the kernel reflects on it and makes future breaking changes unlikely.
Re:Single binary executable packages by BeeOnRope on Wednesday March 02, 2022 @04:31PM (#30533469)
It depends what you mean by breaking changes, right? Do you mean they try to avoid breaking ABI in a forwards compatible way? That is, building against new glibc then runing against old glibc should work?

I don't think so: they only make it ABI backwards compatible (compile against old glibc, run against new) and API compatible (recompile your source against different versions should work).

I just checked by glibc and it had > 200 symbols versioned 2.34 which is the current glibc version. If you use any of those you can't run against older glibc.

Re:Single binary executable packages by marcosdumay on Wednesday March 02, 2022 @07:40PM (#30535588)
> Do you mean they try to avoid breaking ABI in a forwards compatible way?

Ok, I can see what I have written that could read this way, but the context is completely about backward compatibility. Forward compatibility isn't a concept that appears often in software.

Re:Single binary executable packages by BeeOnRope on Wednesday March 02, 2022 @08:16PM (#30535871)
It's not about how you wrote it, it's that the "single executable" concept needs both directions of compatibility if you dynamically link libc on any old distro.

E.g., you might use a relatively recent distro in your GitHub action (or whatever) to build this binary, but then anyone running CentOS or whatever can't run it because they ship an older libc version and required symbols aren't available.

Re:Single binary executable packages by marcosdumay on Thursday March 03, 2022 @08:16AM (#30540538)
If libc is backwards compatible, you immediately have a compatibility matrix that says where your code will run. Quite like you have for any kind of release on any environment.

You seem to want some way to have your code run on any platform whatever features you use in it. That you can't have. Of course if you want to support CentOS 6, you have to avoid any new symbol.

Re:Single binary executable packages by BeeOnRope on Thursday March 03, 2022 @09:58AM (#30541843)
The problem isn't new symbols, it's that existing symbols can get the new version depending on what version you compile it against. On my glibc ~200 symbols have the newest version (2.34) but these are largely all methods that have been around forever. A binary built here won't run in most places.
Re:Single binary executable packages by doliveira on Wednesday March 02, 2022 @11:21AM (#30529031)
> The "C/C++ is black magic!!" meme just never seems to go away

It's true, though. Proof of that is how many tools are made basically because no one wants to deal with Makefiles and autotools. I'd argue that even Docker fits this category of tools made to hide C/C++ builds away

Re:Single binary executable packages by jcelerier on Wednesday March 02, 2022 @11:49AM (#30529423)
> It's true, though. Proof of that is how many tools are made basically because no one wants to deal with Makefiles and autotools.

no one wants to deal with Makefiles and autotools because as of 2022 they don't support spaces in paths and the most used desktop OS on the planet happens to have spaces in the default path for installing software

Re:Single binary executable packages by trinovantes on Wednesday March 02, 2022 @02:15PM (#30531520)
IIRC Microsoft specifically added the space in the default path so that developers know they need to handle file paths with spaces
Re:Single binary executable packages by TillE on Wednesday March 02, 2022 @11:02AM (#30528798)
Yeah you just...link to static libraries. Which have usually already been built and installed alongside the shared libraries.

Also why would you be using autotools in 2022? CMake has been the de facto standard for about a decade now.

Re:Single binary executable packages by bally0241 on Wednesday March 02, 2022 @11:53AM (#30529484)
Came here to say this, anyone still using autohell in 2022 either is a stubborn grey beard or is seriously masochistic. Building static or shared libs/programs with CMake is treated simply as an option when calling the linker. I personally don't know anyone sane who wants to deal with the mental gymnastics needed by libtool. And don't get me started on the stupid permissions games played by 'make distcheck' where a simple git --archive would do just fine.
Re:Single binary executable packages by lenkite on Wednesday March 02, 2022 @12:52PM (#30530321)
Using CMake is like trying to do one-handed pushups to setup your build. Use https://mesonbuild.com/ and make your life comfortable as a couch potato.
Re:Single binary executable packages by mwcampbell on Wednesday March 02, 2022 @12:36PM (#30530087)
One big problem is the global symbol namespace when statically linking. If I'm not mistaken, Rust and Go are able to work around this by mangling their symbols. But it's way too easy for a C or C++ library to pollute the global namespace. Granted, on Linux, the symbol namespace is also global when dynamically linking, but that's not the case on Windows; I'm not sure about Darwin.

Combine that with the multiplicity of build systems, and it's easier to just use dynamic linking. Go and Rust solve that by having a standard build system.

Re:Single binary executable packages by dboreham on Wednesday March 02, 2022 @12:51PM (#30530307)
Hmm. I wrote C and C++ for 20 years and while I haven't used either in some time, I don't remember this ever being a problem, except when trying to port Unix code that expected errno to be global to Windows (but that's the opposite problem of the one you're talking about).
Re:Single binary executable packages by rkeene2 on Wednesday March 02, 2022 @01:59PM (#30531297)
Darwin also uses heirarchical namespaces by default; On Linux you can do this to a limited extent with dlmopen() but not as much as you may want (e.g., to link in a library linked to another libc -- but this is unique to Linux, most platforms only have the single libc)
Re:Single binary executable packages by _3u10 on Wednesday March 02, 2022 @11:05AM (#30528834)
It’s probably more realistic to have a single folder executable like .app “files” on OSX.

If the app has assets it gets a little crazy quite quickly.

Re:Single binary executable packages by AnIdiotOnTheNet on Wednesday March 02, 2022 @12:44PM (#30530199)
There actually is/was two standards for this in Linux: GNUStep Application Bundles[0] and ROX-Filer AppDirs. Currently AppImage is trying to keep the dream alive, but it bundles the files in a squashfs image attached to the executable.

[0] Which of course came from NeXT Application Bundles, which is also where OSX Application Bundles came from.

Re:Single binary executable packages by zozbot234 on Wednesday March 02, 2022 @11:28AM (#30529110)
AppImage does pretty much that out of the box.
Re:Single binary executable packages by rathboma on Wednesday March 02, 2022 @11:37AM (#30529245)
AppImages are so good. They 'just work'. They're super easy to build and distribute too. I think more Linux distributions should embrace them as the de-facto app standard to replace snap and flatpak.
Re:Single binary executable packages by teakettle42 on Wednesday March 02, 2022 @11:45AM (#30529359)
BeOS/Haiku appends assets to the end of the ELF file with a ToC and some easy-to-use APIs for accessing them.

I always wish that’d taken off.

I guess AppImage isn’t dissimilar in that it appends a squashfs image to be mounted with FUSE.

Re:Single binary executable packages by immibis on Wednesday March 02, 2022 @12:44PM (#30530200)
Windows also does this. Linux doesn't, preferring to KISS because with demand paging there's really no reason you can't just put them in your rodata section.