Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I don't think this is really true. There is a fairly stable core set of C libraries present on virtually any Linux distro with a desktop environment that does most of what any application needs in terms of system services. The basic problem is more what the parent was discussing: these are C libraries, and rather than using the FFI for their app language of choice and using these pre-installed libraries, developers would rather rewrite all functionality in the same language as their applications, and the Rust crate, Go mod, or Node package you find when Googling whether something exists in your language of choice is likely to be much less stable than something like libcurl.

Mac and Windows solve this by creating their own languages for app development and then porting the system services to be provided in Swift and C# or whatever in addition to the original C implementation. There is no corporation behind most Linux distros willing to do that other than Canonical and Redhat, but they're perfectly happy to just stick with C, as is Gnome (KDE being perfectly happy to stick with C++). Most app developers are not, however.

For what it's worth, Redhat did kind of solve this problem for the Linux container ecosystem with libcontainer, rewriting all of the core functionality in Go, in recognition of the fact that this is the direction the ecosystem was moving in thanks to Docker and Kubernetes using Go, and now app developers for the CNCF ecosystem can just use that single set of core dependencies that stays pretty stable.



There is no common/stable set of c libs. libc on one distro is different than libc on another (even just within glibc). It's why you generally can't run an app compiled on one distro on different one. You also at times cannot do this on a newer version of a distro and run it on an older version. When a piece of software lists an rpm targeting Fedora or a deb targeting Debian, these are not just repackaging of the same binaries (unless they are providing statically linked binaries).

RedHat did not create libcontainer and it was never rewritten to go (it was always go). libcontainer was started by Michael Crosby at Docker as a replacement to execing out to (at the time unstable) LXC, later donated to OCI (not CNCF) as a piece of tooling called "runc", which is still in use today. As part of OCI RedHat and others have certainly contributed to its development. libcontainer lives in runc, and is actively discouraged to use directly because go is really quite bad at this case (primarily due to no control of real threads), and runc's exec API is the stable API here. Side note: much of runc is written in C and imported as cgo and initialized before the go runtime has spun up. That is not to say libcontainer is bad, just that it is considered an internal api for runc.

RedHat did end up creating an alternative to runc called "crun", which is essentially runc in C with the goal of being smaller and faster.

-- edit to add more context on development in OCI


> There is no common/stable set of c libs. libc on one distro is different than libc on another (even just within glibc). It's why you generally can't run an app compiled on one distro on different one

Pretty much everything uses glibc and distros that are to be used by end users (instead of specialized uses like embedded) also tend to have glibc versions. If someone uses a non-glibc distro it'd be out of their choice so they know what they're getting into.

And glibc has been backwards compatible since practically forever. You can compile a binary on a late 90s Linux and it'll work on modern Linux as long as all libraries it depends on have a compatible and stable ABI. I've actually done this[0] with a binary that uses a simple toolkit i hack on now and then, this is the exact same binary i compiled inside the VM running Red Hat from 1997 (the colors are due to lack of proper colormap support in my toolkit and the X in the VM using plain VGA) running in my -then- 2018 Debian. This is over two decades of backwards compatibility (and i actually tested it again recently with Caldera OpenLinux from 1999 and my current openSUSE installation). Note that the binary isn't linked statically but dynamically links to glibc and Xlib (which is another one with strong backwards compatibility).

[0] https://i.imgur.com/YxGNB7h.png


Yes, you can compile with a really old glibc and use it on a newer one. But glibc does introduce incompatible changes that make it not work the other way and there are issues with stable ABI's across distros.


AFAIK the issue is the symbol versioning which is explicit by design. I can understand why it exists for glibc-specific APIs but i don't see why it is also used for standard C and POSIX APIs that shouldn't change.

It is an issue if you want to compile new programs on a new distro that can run on older distros, but IMO that is much less of a problem than not being able to run older programs in newer distros. And there are workarounds for that anyway, though none of them are trivial.


Forwards compatibility is basically non-existent in the software world. It's not like you can compile a Win 10 program and expect to any time run it on Win 7.


Actually you can, as long as it doesn't use Win10 APIs (or use them via dynamic loading) it will work on Win7.

The issue with glibc is that when you use it it adds requests for the latest versions of the exported symbols that the glibc you use in your system has. You can work around this in a variety of ways (e.g. use __asm__ to specify the version you want and use the header files of an older glibc to ensure that you aren't using incompatible calls) but you need to go out of your way to ensure that whereas in Windows you can just not use the API (well, also make sure your language's runtime library doesn't use the API either but in practice this is less of a concern).


Actually you're right, I forgot that we used to ship software to various versions of Windows with just a single build based on more or less the latest VC++ runtime (that had re-distributable versions for all intended targets).


Most of these libraries are either quite low level, or more GUI-oriented. They usually don't include mid-level decent system management utilities, like registering your app as a service, or checking if the network is up.

In general, when there are is some useful and commonly used C SDK , common FFI wrappers in any language quickly appear and become popular.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: