I apologize for this message being sent. Maybe it's offtopic. I failed to find a place for it being on topic, yet I feel it is of interest to many Linux people. Please direct me to the place where this can be discussed better if you know such a place.
The goals. Versioning I want to be able to use old apps along new ones as long as I wish. I want to compile things with gcc 2.95.2 _and_ gcc 3.2, I want to be able to run KDE 2 and KDE 3. Without screwing up my filesystem beyond recognition. Without shuffling stuff around. I want to compile my apps against any installed version of a lib. Say I have foo-2.3 and foo-3.4 installed. I want be able to compile and use apps against both of them. Every app which felt the pain of versioning problem came up with home-grown solution, some of them are quite smart, some not. We can borrow some of the best solutions. Keeping pieces together. I want to be able to install apps into single subdirectory somewhere under /usr (I'll call it $STATIC) if they don't have 'moving parts' like config files and rw data. This directory is 'frozen' after installation and does not require modification (may be even mounted read-only and distributed to thousands of NFS workstations). If they do have moving parts, let those parts reside in separate $PERBOX directory under /var (why PERBOX? You will have multiple PERBOX dirs on a NFS installation, one per box. STATIC will stay single). I very much dislike 'smeared' style of installation when each and every package got smashed apart and evenly distributed into /usr/{lib,bin,include,man,info,share,doc} and /etc. What we have now. [/usr]/lib: foo.so (link to foo lib with highest version) foo.so.N (link to highest N.x version) foo.so.N.M (link to highest N.M.x version) foo.so.N.M.K foo.so.N+L.J (link to highest N+L.J.x version) foo.so.N+L.J.I foo.so is for those who is not interested in version at all. foo.so.N is for those who know they need a major version N, don't care about minor. Multiple versions can easily coexist. Scheme stacks for arbitrary depth. Alternatively you may see libs named like foo.N.M.K.so, which are conceptually the same. However, you can notice that some apps do not honor this scheme and place their libs in /usr/lib WITHOUT version suffix. This precludes use of two versions of said apps at the same time. KDE readily comes to mind. /usr/include: Some apps make their own foo/ subdir, avoiding name clash. You can meet versioned foo-N.M/ dirs rarely. Global namespace pollution is common. (Example: What is /usr/include/form.h? Did author ever realized others could name their header 'form.h'?) [/usr/]bin: No versioning is done. /usr/lib/*/: Misuse of /usr/lib. God intended /usr/lib to contain only C/C++ libraries, nothing else. However, everybody picked up the idea "if you don't know where to put it, stuff it into /usr/lib". gconv/ gcc-lib/ autofs/ ldscripts/ mcop/ ipmasqadm/ ... - why are they there? /usr/local/*/: Refugee camp for those programs which are afraid to step on someone's toes in /usr/*/. They stomp on eash other's toes in /usr/local instead. I'm afraid someone might come up with brilliant idea of /usr/local[23456] or /usr/local/local/local/.... Achieving the goals. Like I said, install app into $STATIC and optionally $PERBOX. To keep things easily accessible in standard places, we have to make required symlinks. Say I am installing foo-N.M.K: /usr/bin/bar -> $STATIC_FOO-N.M.K/bin/bar /usr/lib/foo.N.M.K.so -> $STATIC_FOO-N.M.K/lib/foo.N.M.K.so /usr/include/foo.N.M.K -> $STATIC_FOO-N.M.K/include /usr/man/man.8/bar.8 -> $STATIC_FOO-N.M.K/man/man.8/bar.8 For PERBOX: /etc/foo.rc -> $PERBOX_FOO-N.M.K/etc/foo.rc Some things won't require symlinking: doc/, rw data (think mysql/postgreSQL here) Versioning. Well, we can use .so recipe: append -N.M.K to each and every binary and library, and to our include dir. Use only these qualified names when you need to execute one binary from the other. gcc comes to mind: gcc-N.M.K should exec cpp-N.M.K, not a plain cpp. When external apps will try to execute our binary, link against us or use our includes, they will pick required version number and level: exec(foo) - run highest numbered foo binary exec(foo-N.M) - run highest numbered foo-N.M.x.y.z binary gcc -lfoo - gimme latest foo.{so|a} gcc -lfoo-N.M - gimme latest foo-N.M.{so|a} #include <foo-N.M/bar.h> - likewise for include Obviously we need to run generalized version of ldconfig against common directories in order to regenerate symlinks whenever an app got installed/removed. Anybody with better solutions?