Hacker News new | ask | show | jobs
by jordigh 4749 days ago
The point of not using embedded libraries isn't about saving space. It's about not having several slightly different versions of the same bug spread out across several slightly different versions of the same library.

Saving space is just a nice side effect, so why not have that too?

The DLL hell problem doesn't exist in a GNU-based system because we have sonames. Windows and Mac OS X don't have those; instead, the software libraries there can't coordinate with each other harmoniously, so each program has to have all of its libraries packaged with its own set of bugs while making a hostile and rude gesture to the rest of the programs in the OS.

4 comments

And yet, the Mac OS X user experience is so much nicer than the one you get with a GNU-based system; you download an app, it is self contained, it works, end of story. I have been hearing the same old story for years about how dependency-tracking package managers are the right way, and yet that environment continues to have problems, as described in the article; while the supposedly inferior Mac OS X packaging system just works, and I never have to mess with anything.

I am happy to give up a little extra disk space in exchange for having predictable executables that work in the configuration they were built and tested for.

> And yet, the Mac OS X user experience is so much nicer than the one you get with a GNU-based system; you download an app, it is self contained, it works, end of story. I have been hearing the same old story for years about how dependency-tracking package managers are the right way, and yet that environment continues to have problems, as described in the article; while the supposedly inferior Mac OS X packaging system just works, and I never have to mess with anything.

Clearly we have differing requirements. I've found the Debian user experience so much nicer than the one you get on OS X or Windows: you install a package with apt, it pulls in all dependencies, and it Just Works. I consider "self-contained" a bug and a warning sign that makes me start looking for a ten-foot pole; "self-contained" is another way of saying "inconsistent" and "not well integrated".

I am surprised to see you compare the OS X and Windows experiences. They seem completely dissimilar to me.

With Windows, it seems like every little thing needs some complex installer procedure that splats files all over the system. Every program needs dozens of DLLs, and the only way to get rid of it is to run an uninstaller that hopefully remembers everything it created, and even more hopefully doesn't break anything else on your machine.

With Mac OS X, there's generally no installation process at all. You download the app, and you put it where you want it to go, and then you run it, and that's it. Nothing goes anywhere and you don't need any special process to manage it.

The experience I've had on Ubuntu is sort of midway between these. There's a complex installation process, and everything has to deal with it, and shit gets plastered all over your machine and there's no way you can keep track of it all, but at least things generally mostly work most of the time.

But really: why manage complexity when you can do away with it?

and you don't need any special process to manage it.

You're speaking of apt/packaging like it's a bad thing, when it's awesome. Want to download a new OSX or Win app? Open your browser, hunt it down, in the case of Win, figure out if you can trust the site, download it, open the downloaded item and do the install dance, and then have it stay sessile on your system, never updated... unless it has its own phone-home system - and now you have more crap on your system.

Want to install a package with package management? It takes literally seconds plus download time. Package management systems are all about doing away with managing complexity.

If you think OS X's approach has done away with it, you're wrong. Maybe you've found it a worthwhile tradeoff, but flattening each application's dependency tree is still a tradeoff: you get truly independent applications, but you pay for it in duplication, the costs of which are well enumerated in binarycrusader's post. Maybe you mostly don't encounter those costs. Maybe you even believe most people mostly don't encounter those costs. But they do exist.
Exactly. The "self-contained" approach means I can't just upgrade a library once and have everything using it Just Work with the features enabled (or bugs fixed) by the new version.
It's not going to just work all the time. There are so many possible libraries and possible versions of those libraries and their sub-libraries that it is possible, even likely, that nobody in the world has ever tested that precise combination of components before. You don't know whether it's going to work until you try it, and when it doesn't work, it's up to you to figure out what went wrong and fix it. This seems like a monumental waste of time. I would rather use a complete, monolithic application built and tested by the app developer, leave it the way it came, and upgrade it when the app developer has a new, complete, built, and tested version I can use.
And the opposite approach means I only need to update glibc once and flash audio is broken.
> you install a package with apt, it pulls in all dependencies, and it Just Works

And what happens in the case of a package not available through apt? ("Sorcery! All applications must be packaged! All shared libraries must be packaged individually!")

And there went your afternoon installing some just-slightly-uncommon piece of software

Then you fall back to this 'superior' individual packaging method. I don't see how this is a counter.
If you packaging partisans manage to convince developers of the merits of your position, the individual packaging method won't be easily available: it'll be "wait for the OS maintainers to decide to include the newer version" or "make; make test; make install" (i.e., be your own packager).
The developers are still free to package it themselves and distribute installers as .deb, .rpm ETC. If they have a dependency not available in your package manager (or to old a version), they can either also send you that, or have you add their PPA. The only significant problem I see is that their is a fragmented market of packaging systems, which makes it difficult for individual developers to target everyone. Of course *.tar.gz is a good universal installer for when someone doesn't use a major package manager.
We "packaging partisans" are just saying we find classical packaging superior to the every-piece-of-software-on-its-own model, not that the latter isn't an OK fallback if there is no package.
Or you set up pkgsrc under /opt or /usr/pkg or some such, and use that for the software where you want newer versions than your distro provides.
For applications its easier for sure. I've always liked how easy it is to installed statically linked applications. Still, bugs happen.

Development libraries, command line utilities, interpreters-- bread-n-butter developement or unixy stuff or in otherwords, the things the average user don't see-- is usually a a lot easier to get and keep up to date when you have a package manager.

Then one day somebody finds a critical bug in zlib and you need to go and fetch an update for every single application you have ever installed on your system. Then it turns out half of them don't have updates.
This is a fallacy. Just because a bug was exposed in a library you used does not mean your software will be exposed in the same way. Your use of the lib may not even overlap with the bug exposure. And I seriously doubt you carefully comb all the libs you select on a project for "security" before you release something.
Say there's a vulnerability or something in zlib's decompression, as GP suggested. That's gonna affect pretty much all software using zlib (i.e. a LOT). On a system where the package maintainers took care of having all packages use the system zlib, the whole problem is fixed by ONE ENTITY (the zlib maintainer or team) waking up and patching one package. Every user updates the zlib library package through their package manager (which informs them that they need to), and the vulnerability goes away for thousands of programs.

If, on the other hand, those thousands of programs all bundled zlib, the user won't be safe until hundreds of maintainers wake up and do (repeatedly the same) patching. Or even worse, if there isn't even a package management system, as some apparently want, the user has to also go fetch the fixed programs from thousands of upstreams. Oh, and the user also has to know about the vulnerability. Not gonna happen!

As we can see, the classical model reduces work duplication, reduces patching times and manpower need, and certainly takes a big responsibility off the user's shoulders.

Funny that you call the packaging scheme the "classical model" - to me that's the "[relatively] new and weird" scheme. I'd say that "everybody builds their own binaries" is the classical model.

This is the argument that comes up every time. Perhaps it matters to people who are running complex servers hosting an array of services. In my life, it never comes up. I am either using a personal machine or managing a server which is responsible for one single service.

The idea that upgrading one library could affect the behavior of hundreds of programs is terrifying. How do I know they all still work? I don't. I have to go test them all. What this means is that I never update any libraries at all, on a linux machine, because I can't know in advance what the upgrade might break.

My concern is not about keeping everything up to date; it is about keeping everything working. If there is a bug in one program then I want to update that program and only that program and no other programs at all. Then I can evaluate the behavior of the new program. If it is worse than the old behavior, I can hopefully go back to the old version. If it is better, then I can keep it. Nothing else should change.

This is exactly what I get on Mac OS X, and it's what I get when I build apps with statically linked libraries on Linux: stuff works until I break it, and then I know what I broke, so I can fix it.

When I let package managers update things for me, my system becomes an unknowable chaos of changing behavor. Instead, I simply never update anything until I am ready to pave the machine and start from scratch. I install everything I might want to use, then I disable updates and leave it alone until I am ready to start over.

> Funny that you call the packaging scheme the "classical model" - to me that's the "[relatively] new and weird" scheme. I'd say that "everybody builds their own binaries" is the classical model.

I stand corrected.

> In my life, it never comes up. I am either using a personal machine or managing a server which is responsible for one single service.

I just went back through my own update log a couple of months: You don't use anything that uses libxml [1], ffmpeg (audio/video Swiss army knife) [2], poppler (popular PDF library) [3] or openSSL [4]? Do you pay attention to the security notices of every program you have that bundled one of those? Are you sure that upstream is paying attention to the security ntoices of those libraries?

> The idea that upgrading one library could affect the behavior of hundreds of programs is terrifying. How do I know they all still work? I don't. I have to go test them all. What this means is that I never update any libraries at all, on a linux machine, because I can't know in advance what the upgrade might break.

For non-rolling distributions (for example Debian stable, Ubuntu, Fedora, RedHat) packages don't have their behavior changed throughout the lifetime of a release <6>. Security and bug fixes are backported to whatever version is in place for the lifespan of the distribution's release. This is part of the point of stable releases, and something that's routinely forgotten by those who hound package maintainers for newer versions of things!

As an example, let's consider [1]. Ubuntu 13.04 uses libxml2 version 2.9.0 plus some Debian/Ubuntu patches. They released version 2.9.0+dfsg1-4ubuntu4.1 with the following changelog [5]:

  * SECURITY UPDATE: multiple use after free issues
    - debian/patches/CVE-2013-1969.patch: properly reset pointers in
      HTMLparser.c, parser.c.
    - CVE-2013-1969
Only the security fix is applied, and after upgrade you know that libxml2 will continue as it has done for the lifetime of your distro release, except it's no longer vulnerable to CVE-2013-1969. Moreover, this applies to every program using libxml (i.e. a lot) with one update. Again: There's no other change in behavior for libxml!

> This is exactly what I get on Mac OS X, and it's what I get when I build apps with statically linked libraries on Linux: stuff works until I break it, and then I know what I broke, so I can fix it.

Stuff seems to work until you break it. Then a security hole is found, and it turns out things aren't really working very well at all. To me it seems like a lot of work to keep track of such things by yourself!

[1] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1969

[2] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-2496

[3] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-1790

[4] http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-0169

[5] https://launchpad.net/ubuntu/+source/libxml2/2.9.0+dfsg1-4ub...

<6> Firefox and a few other packages, mostly web browsers who are making it hard to provide security backports, are notable exceptions.

I agree that the Mac packaging system is wonderful for installing programs, but I think this is because it does not even attempt to solve the problem of uninstalling programs.

Arguably, this is a good trade-off because users rarely uninstall software. But it means that if you ever become uncertain about the configuration state of a Mac, you're probably going to have to reinstall from scratch.

What?! This is total nonsense.

Application uninstalls are as trivial as dragging the application to the trash bin. No, this will not eliminate the application's data from ~/Library, etc, but 98% of the time you don't want that anyway. If you know what you're doing, it's usually a quick `rm -rf ~/Library/...` and you're done. Some poorly behaved apps stick stuff in other places or otherwise muck with your system, but now with the app store, that's no longer an issue.

And, if you're absolutely anal about deleting every single trace of an app, there are tools that automate the process. For example: http://www.appzapper.com/ -- But really, it's probably a waste of your time unless you had a badly behaved app go rouge. In my many years of Mac ownership, I've installed and uninstalled hundreds of apps and the only time I ever had to bang my head against the wall was when I used to use MacPorts and a Postgres install went haywire because of the same sort of packaging nonsense that the article is talking about.

> Application uninstalls are as trivial as dragging the application to the trash bin. No, this will not eliminate the application's data from ~/Library, etc, but 98% of the time you don't want that anyway.

When uninstalling an application, you usually do want to remove all of the application's components. How often do you say, "You know, I'd like to uninstall 25% of this application, even though the remaining 75% will just be dead weight without it"?

The two kinds of things there are configuration/settings, and the user data. When you uninstall Adium (for whatever reason), uninstalling the chat logs from the last five years is probably not part of your expected outcome. Uninstalling an application shouldn't reach into your homedir and delete things, either on Linux or OS X.
I do expect when I delete, say, Steam, it won't leave 20 GB of games I can't play sitting around in a totally invisible place. Similarly, when I delete some video or sound editing software, I don't expect it to leave several gigabytes of samples and filters lying around. Both of these are real situations I've encountered when people came to me asking why their hard disk was so ridiculously full.

I can understand not deleting things out of ~/Documents, but a lot of stuff that goes in the Library folders is not what users think of as data that should outlive the application.

That 'go rouge' is a neat typo, it sounds much naughtier than going rogue.
Riak could be contained in one OS X application bundle. All its dependencies in one directory. To uninstall, just trash it. It's up to the distributor.
Can you imagine using OSX as a development box without homebrew?
No, but homebrew doesn't break things up into an insane number of pieces either. In the context of this blog post, Riak on homebrew is a single package.
Yes, and my /usr/local isn't a freaking .git repository. Homebrew, bikeshedding what MacPorts achieved a decade previous (and getting it horribly wrong) since 2009
If by "achieved", you mean "aspired to". MacPorts never actually seemed to correctly build the things I needed. Of course, I gave up before 2009.
Sure, pkgsrc has made it easy to manage third-party software on Mac OS X for over a decade. Lots of other platforms too, with root or without. Homebrew is cool, but I'm pretty happy about being able to use the same package manager everywhere I go.
Yes. Never used homebrew. Not sure I'm missing anything.
MacPorts all the way, since it's sane.
The first thing I do with a new mac is install homebrew.
Your argument is disingenuous. While it might prevent a bug from spreading due to older/differing embedded libraries, it is equally likely to cause new bugs, when library signatures change, and some library function is suddenly gone.

When you bundle the libraries yourself, you only have to target the libraries you included. When you let the package manager do the magic for you, you have to target every version of the libraries, ever.

> when library signatures change, and some library function is suddenly gone.

No, no, no. This is not how you fix critical / security issues in a well maintained system. You either backport a single patch that fixes the problem without changing any signatures, or if you support a very old, incompatible software you reimplement the fix yourself. Then the release is not a new library. It's the old one + fix.

This is what the proper package maintenance is about. No functions should ever be "suddenly gone".

Also if you say in your installation requirements "this software requires libfoo >= 1.2.3, < 2.3.4", no sane package maintainer will disagree. Your application may be patched in the packaging process to work with a different supplied version, but most likely it will just get what's needed.

I think this is a key point that many people overlook the importance of when pressuring, say, Debian or Ubuntu maintainers for new package versions inside of a single release.
Just as a point of order, Windows has dynamic library versioning and multiple loading at least as good as sonames. This was first introduced in Windows 2000, 13 years ago.
I don't know about Windows, but OS X certainly does have that [1]. It's simply called by a different name.

[1] https://developer.apple.com/library/mac/documentation/develo...

And windows has winSxs - side by side assembly... Then again it's the thing that makes the c:\windows\winsxs folder grow to dozen gigabytes and more (like 9 different versions of msvcr90 which is only for vs2008)

Oh, and its the thing that totally stops me from buying surface, since I did "dir /s" on one of the devices at the store