autoconf
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC] Apps placement and versioning


From: Denis Vlasenko
Subject: [RFC] Apps placement and versioning
Date: Sat, 12 Oct 2002 19:43:48 -0200

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?




reply via email to

[Prev in Thread] Current Thread [Next in Thread]