On Mon, 18 Feb 2008, chromatic wrote:

> On Monday 18 February 2008 06:43:22 Andy Dougherty wrote:
> 
> > The problem here looks relatively simple:  The symbol _Parrot_conv_i2_i
> > is defined in two places: myops_ops.o and
> > /usr/local/lib/libparrot.dylib(core_ops.o)
> >
> > That '/usr/local/lib/libparrot.dylib' shouldn't be there.  It's probably a
> > remnant of an old installation.  Uninstalling the old libparrot should fix
> > this problem.
> 
> Ah, you're right.
> 
> > This is also a good example of why parrot shouldn't be installed at
> > present, and why I think attempts to make it easy to install (e.g via yum,
> > macports, rpm, apt-get, etc.) are not a good idea at this time.
> 
> We have to fix it eventually.  What kind of solution do you think is best?  
> Will re-arranging the order of library include paths to the linker fix it, or 
> is there something even better?

I think there are two broad issues, the first primarily aimed at end 
users, and the second primarily aimed at developers.

First, installing libparrot.so into any prominent public directory (such
as /usr/local/lib) makes it available for others to use, and can even
reasonably be seen as inviting others to use it, no matter what version
number you put on it or what caveats you stick in the documentation.
However, I don't think libparrot's ABI is anywhere near remotely stable
enough for this to be a wise course of action.  libparrot currently
exports thousands and thousands of symbols that it probably shouldn't, and
there are whole subsystems waiting to be implemented.  It is reasonable
to expect that subsequent releases of parrot over the coming years will
repeatedly break binary compatibility in big ways.  If people want to
install a shared libparrot.so anyway, some sort of mechanism to support
simultaneous installation of different versions will be needed to avoid
breaking everything that relies on libparrot.so.

Second, there is a difficulty building and testing a development
version of parrot if you already have a shared libparrot.so in a
directory that is part of the standard load path.  To be specific:
Suppose you have installed libparrot.so into /usr/lib/libparrot.so,
and you are now building a fresh copy of parrot in $HOME/src.
How can you ensure that during building and testing that the new
$HOME/src/parrot executable picks up the new version of the shared
library in $HOME/src/parrot/lib/blib/libparrot.so, and doesn't pick
up /usr/lib/libparrot.so?  The answer is "it depends on your operating
system, and I'm not sure there's a guaranteed way to do it on every
operating system."

We face the same issue with perl5's shared libperl.so, so I'll share
some relevant snippets of that documentation here.  Here is the relevant
passage from perl5's INSTALL document.  (This only applies to Unix
systems.  I don't know the equivalent Windows incantations.)

    There is also an potential problem with the shared perl library if you
    want to have more than one "flavor" of the same version of perl (e.g.
    with and without -DDEBUGGING).  For example, suppose you build and
    install a standard Perl 5.10.0 with a shared library.  Then, suppose
    you try to build Perl 5.10.0 with -DDEBUGGING enabled, but everything
    else the same, including all the installation directories.  How can
    you ensure that your newly built perl will link with your newly built
    libperl.so.8 rather with the installed libperl.so.8?  The answer
    is that you might not be able to.  The installation directory is
    encoded in the perl binary with the LD_RUN_PATH environment variable
    (or equivalent ld command-line option).  On Solaris, you can override
    that with LD_LIBRARY_PATH; on Linux, you can only override at runtime
    via LD_PRELOAD, specifying the exact filename you wish to be used;
    and on Digital Unix, you can override LD_LIBRARY_PATH by setting the
    _RLD_ROOT environment variable to point to the perl build directory.

    In other words, it is generally not a good idea to try to build a
    perl with a shared library if $archlib/CORE/$libperl already exists
    from a previous build.

    A good workaround is to specify a different directory for the
    architecture-dependent library for your -DDEBUGGING version of perl.
    You can do this by changing all the *archlib* variables in config.sh to
    point to your new architecture-dependent library.

Also in the perl5 source tree, in the file Porting/pumpkin.pod,
(available with 'perldoc pumpkin' on most systems) I have the following
musings on a this topic:

    =head2 Shared libperl.so location

    Why isn't the shared libperl.so installed in /usr/lib/ along with
    "all the other" shared libraries?  Instead, it is installed in
    $archlib, which is typically something like

            /usr/local/lib/perl5/archname/5.00404

    and is architecture- and version-specific.

    The basic reason why a shared libperl.so gets put in $archlib is
    so that you can have more than one version of perl on the system at
    the same time, and have each refer to its own libperl.so.

    Three examples might help.  All of these work now; none would work
    if you put libperl.so in /usr/lib.

    =over

    =item 1.

    Suppose you want to have both threaded and non-threaded perl versions
    around.  Configure will name both perl libraries "libperl.so" (so
    that you can link to them with -lperl).  The perl binaries tell them
    apart by having looking in the appropriate $archlib directories.

    =item 2.

    Suppose you have perl5.004_04 installed and you want to try to compile
    it again, perhaps with different options or after applying a patch.
    If you already have libperl.so installed in /usr/lib/, then it
    may be either difficult or impossible to get ld.so to find the new
    libperl.so that you're trying to build.  If, instead, libperl.so is
    tucked away in $archlib, then you can always just change $archlib
    in the current perl you're trying to build so that ld.so won't find
    your old libperl.so.  (The INSTALL file suggests you do this when
    building a debugging perl.)

    =item 3.

    The shared perl library is not a "well-behaved" shared library with
    proper major and minor version numbers, so you can't necessarily
    have perl5.004_04 and perl5.004_05 installed simultaneously.
    Suppose perl5.004_04 were to install /usr/lib/libperl.so.4.4, and
    perl5.004_05 were to install /usr/lib/libperl.so.4.5.  Now, when you
    try to run perl5.004_04, ld.so might try to load libperl.so.4.5, since
    it has the right "major version" number.  If this works at all, it
    almost certainly defeats the reason for keeping perl5.004_04 around.
    Worse, with development subversions, you certaily can't guarantee
    that libperl.so.4.4 and libperl.so.4.55 will be compatible.

    Anyway, all this leads to quite obscure failures that are sure
    to drive casual users crazy.  Even experienced users will get
    confused :-).  Upon reflection, I'd say leave libperl.so in $archlib.


So, what is needed?  I think what is needed is a grand design --
an understanding of what an installed parrot ought to present to the
outside world (in terms of embedding interface, libparrot ABI, extension
interface, etc.)  and an understanding of how upgrades might work and
multiple versions might be supported.  (Just because parrot gets upgraded
doesn't mean every application relying on libparrot.so also simultaneously
gets upgraded.)  Failing that, installing only a static libperl.a avoids
most of the problems for now, and often boosts performance as well!

-- 

    Andy Dougherty              [EMAIL PROTECTED]

Reply via email to