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]