First, an up-front conflict-of-interest disclaimer: I am a long-time GoboLinux developer.
Second, an up-front claim of domain expertise: I am a long-time GoboLinux developer.
There are a few different structures in current use. GoboLinux has one, and tools like GNU Stow, Homebrew, etc, use something quite similar (primarily for user programs). NixOS also uses a non-standard hierarchy for programs, and philosophy of life. It's also a reasonably common LFS experiment.
I'm going to describe all of those, and then comment from experience on how that works out in practice ("feasibility"). The short answer is that yes, it's feasible, but you have to really want it.
GoboLinux has a structure very similar to what you describe. Software is installed under
/Programs/ZSH/5.0.8 contains all the files belonging to ZSH 5.0.8, in the usual
lib/... directories. The system tools create symlinks to those files under a
/System/Links hierarchy, which maps onto
PATH variable contains only the single unified executable directory, and
LD_LIBRARY_PATH is unused. Multiple versions of software can coexist at once, but only one file by a given name (
bin/zsh) will be linked actively at once. You can access the others by their full paths.
A set of compatibility symlinks also exists, so
/usr/bin map to the unified executables directory, and so on. This makes life easier for software at run time. A kernel patch, GoboHide, allows those compatibility symlinks to be hidden from file listings (but still traversable).
Contra another answer, you do not need to modify kernel code: GoboHide is purely cosmetic, and the kernel does not depend on user-space paths in general². GoboLinux does have a bespoke init system, but that is also not required to do this.
The tagline has always been "the filesystem is the package manager", but there are reasonably ordinary package-management tools in the system. You can do everything using
If you want to use GoboLinux, you are very welcome. I will note, though, that it's a small development team, and you're likely to find that some software you want isn't packaged up if nobody has wanted to use it before. The good news is that it's generally fairly easy to build a program for the system (a standard "recipe" is about three lines long); the bad news is that sometimes it's unpleasantly complicated, which I'll cover more below.
There are a few "publications". I gave a presentation at linux.conf.au 2010 on the system as a whole that covers everything generally, which is available in video: ogv mp4 (also on your local Linux Australia mirror); I also wrote up my notes into prose. There are also a few older documents, including the famous "I am not clueless", on the GoboLinux website, which addresses some objections and issues. I think that we're all a bit less gung-ho these days, and I suspect that a future release will adopt
/usr as the base location for the symlinks.
NixOS puts each installed program into its own directory under
/nix/store. Those directories are named something like
/nix/store/5rnfzla9kcx4mj5zdc7nlnv8na1najvg-firefox-3.5.4/ — there is a cryptographic hash representing the whole set of dependencies and configuration leading to that program. Inside that directory are all the associated files, with more-or-less normal locations locally.
It also allows you to have multiple versions around at once, and to use any of them. NixOS has a whole philosophy associated with it of reproducible configuration: it's essentially got a configuration management system baked into it from the start. It relies on some environmental manipulation to present the right world of installed programs to the user.
It's fairly straightforward to go through Linux From Scratch and set up exactly the hierarchy you want: just make the directories and configure everything to install in the right place. I've done it a few times in building GoboLinux experiments, and it's not substantially harder than plain LFS. You do need to make the compatibility symlinks in that case; otherwise it is substantially harder, but careful use of union mounts could probably avoid that if you really wanted.
I feel like there was an LFS Hint about exactly that at one point, but I can't seem to find it now.
The thing about the FHS is that it's a standard, it's very common, and it broadly reflects the existing usage at the time it was written. Most users will never be on a system that doesn't follow that layout in essence. The result of that is that lots of software has latent dependencies on it that nobody realises, often completely unintentionally.
All those scripts with
#!/bin/bash? No good if you don't have Bash there. That is why GoboLinux has all those compatibility symlinks; it's just practical. A lot of software fails to function either at build time or at run time under a non-standard layout, and then it requires patching to correct, often quite intrusively.
Your basic Autoconf program will usually happily install itself wherever you tell it, and it's fairly easy to automate the process of passing in the correct
--prefix. Other build systems aren't always so nice, either by intentionally baking in the hierarchy, or by leading authors to write non-portable configuration. CMake is a major offender in the latter category. That means that if you want to live in this world you have to be prepared to do a lot of fiddly work up front in other people's build systems. It is a real hassle to have to dynamically patch generated files during compilation.
Runtime is another matter again. Many programs have assumptions about where their own files, or someone else's files, are found either relative to them or absolutely. When you start using symlinks to present a consistent view, lots of programs have bugs handling them (or sometimes, arguably correct behaviour that is unhelpful to you). For example, a tool
foobar may expect to find the
baz executable next to it, or in
../sbin. Depending on whether it reads its symlink or not, those can be two different places, and neither of them may be correct anyway.
A combined problem is the
/usr/share directory. It's for shared files, of course, but when you put every program in its own prefix they're no longer actually shared. That leads to programs unable to find standard icons and the like. GoboLinux dealt with this in a pretty ugly way: at build time,
$prefix/share was a symlink to
$prefix/Shared, and after building the link was pointed to the global
share directory instead. It now uses compile-time sandboxing and file movement to deal with
share (and the other directories), but runtime errors from reading links can still be an issue.
Suites of multiple programs are another problem. GoboLinux has never gotten GNOME working fully, and I don't believe NixOS has either, because the layout interdependencies are so baked in that it's just intractable to cure them all.
So, yes, it's feasible, but:
- There is quite a lot of work involved in just making things function.
- Some software may just never work.
- People will look at you funny.
All of those may or may not be a problem for you.
¹ Version 14.01 uses
/System/Index, which maps directly onto
/usr. I suspect a future version may drop the Links/Index hierarchy and use
/usr across the board.
² It does require
/bin/sh to exist by default.