"You can have multiple versions or variants of a package installed at the same time. This is especially important when different applications have dependencies on different versions of the same package — it prevents the “DLL hell”."
This sounds nice, and it's a direct quote from the product page, but I can guarantee that Nix does nothing of the sort. This would need to be addressed in ld.so. It's simply not possible for a packaging system to solve this problem on a typical unix system.
0install does that by tweaking PATH, LD_LIBRARY_PATH and similar variables. That way, each package gets visibility on the dependencies it requires (in exactly the desired version).
Environment variables won't work. They're either reset for security (when sudo is invoked, for example) or they bleed inappropriately into sub-processes. There is no reliable way to solve this using environment hints to the dynamic linker. End of story.
With sudo, you just set the variables in the child process (after sudo, not before).
Variables can indeed bleed into sub-processes if you're not careful. If the sub-process's command is declared as a dependency then 0install could reset the environment automatically when starting it. Currently, it instead finds a set of libraries that work with the process and its dependencies (which is safe, but could make some cases unsolvable in theory, if a program wanted to run a subcommand which used an incompatible library).
Direct support from the dynamic linker would be nice though.
Sudo was an example, and is certainly not the only place this problem occurs.
Variables cannot be set in the child process; the linker will have already run by the time you can access your environment. Furthermore, this scheme destroys the utility of LD_* variables, which itself is a non-starter.
All setuid binaries will be incompatible with any scheme which involves environment variables controlling the linker -- that's a core element of unix security architecture.
Over here [ http://news.ycombinator.com/item?id=3995200 ] someone who I believe is the author suggested that this thing uses DT_RPATH, and I've outlined the problems with that mechanism as well.
Perhaps I'm coming across as a curmudgeon, if so I apologize. But I've worked on this problem quite deeply and there's just no way to reliably solve it. Modifications to ld.so are an absolute requirement.
Feel free to try it out to see that it does, in fact, do this. No special magic is needed (most of the time): for instance, for dynamic library dependencies you can just set the RPATH at link time to indicate precisely in which directory an application should look for its dependencies.
No, it won't work. This is my area of expertise and I can unequivocally state that it is not possible to solve this problem on a unix system. The linker infrastructure does not exist, and here's why:
RPATH (or better RUNPATH) has intractable conflicts in library dependencies. For example, this cannot work for any application which uses dlopen() and packages its loadable modules independently of the invoking binary. This is a problem for very high profile software such as:
* Apache, and just about any other application server with a plugin interface
* Perl, Python, Ruby, Java, and just about every other interpreted/VM oriented language
Furthermore, there exists other intractable conflicts in complex library dependency interactions. For example:
bin/B needs SONAME=D.so.1 which needs both SONAME=C.so.1 (v2, incompatible) and SONAME=B.so.1
The dependency relationship of every shared object in this chain are not static, and you cannot modify the invoking binaries (where RPATH must be set) every time an intermediate shared object changes its linking requirements. You also cannot guarantee ordering when a single node depends on multiple libraries -- the order of evaluation is non-deterministic. You might say this is a corner case, but you would be surprised when you try at scale. This is not a corner case.
Seriously, I understand everything about this. Can't be done. You feel free to try it out and see that it doesn't.
This sounds nice, and it's a direct quote from the product page, but I can guarantee that Nix does nothing of the sort. This would need to be addressed in ld.so. It's simply not possible for a packaging system to solve this problem on a typical unix system.
reply