bkchapin has asked for the wisdom of the Perl Monks concerning the following question:

We have a Perl module, ICS.pm, that uses functions from an included 32bit library, libics2.a, and we're trying to get this to run on 64bit SuSE 10.3 (Perl 5.8.8). The library is proprietary. We can't get source code for it. We can't get a 64bit build of it. readelf reports that it is indeed 32bit. So, "make test" fails with "skipping incompatible library".

We tried installing SuSE's perl-32bit package. It didn't help. That package is installed, but I have seen nothing. "whereis perl" finds only the 64bit version, perl -v reports that it is the 64bit version. There is no "i586" directory under /usr/lib/perl5/, just the x86_64 ones. Is there some "perl32" binary somewhere? Maybe uninstall 64bit perl to see it?

We tried building it on a 32bit system and copying it over. Haven't gotten that to work yet either. Any other ideas?

Replies are listed 'Best First'.
Re: 32bit lib on 64bit system
by almut (Canon) on Nov 25, 2008 at 09:09 UTC

    Have you installed the 32-bit libraries? From the top of my head I can't tell what the respective package is called, but it shouldn't be too hard to find out — the package includes ld-linux.so, libc.so, and many of the other common libs in 32-bit versions.  In general, it shouldn't be a problem to run 32-bit programs on a x86_64 system... (I'm doing it all the time)

    Update: the respective package is "glibc-32bit" (glibc-32bit-2.6.1-18.x86_64.rpm for SuSE-10.3).

    It contains all the libraries needed by a SuSE-built 32-bit perl binary, i.e.

    /lib/ld-linux.so.2 /lib/libc.so.6 /lib/libcrypt.so.1 /lib/libdl.so.2 /lib/libm.so.6 /lib/libnsl.so.1 /lib/libpthread.so.0 /lib/libutil.so.1
Re: 32bit lib on 64bit system
by Anonymous Monk on Nov 25, 2008 at 08:16 UTC
Re: 32bit lib on 64bit system
by almut (Canon) on Nov 25, 2008 at 20:18 UTC

    I just discussed the issue with a former SuSE developer... and we finally agreed that the perl-32bit package is just plain broken/incomplete1. — In other words, it's not your fault! :)

    As a workaround, you can proceed as follows:

    Get hold of the following two RPMs (e.g. from the SuSE 10.3 installation media in the i586 subdirectory), and copy them into some temporary directory:

    perl-base-5.8.8-75.i586.rpm perl-5.8.8-75.i586.rpm

    Extract the 32-bit perl binary and the i586-linux-thread-multi subtrees from those packages

    temp/ $ rpm2cpio perl-base-5.8.8-75.i586.rpm | cpio -idmv '*i586-linux +*' './usr/bin/perl' temp/ $ rpm2cpio perl-5.8.8-75.i586.rpm | cpio -idmv '*i586-linux +*'

    Rename the binary, e.g. to "perl32"

    temp/ $ mv usr/bin/perl usr/bin/perl32

    In the temp dir, you should find a directory ./usr, which you then just copy over into the existing (64-bit) perl installation, i.e. (as root):

    temp/ $ cp -af usr/ /

    (don't worry... the 64-bit version will work as before)

    ___

    1 The perl-32bit package is missing

    • the shared object file subset from the (i586) perl-base package
    • all non-.so files, i.e. the associated .pm files, etc. (which are being searched in the i586-linux-thread-multi subdirectories by the 32-bit perl)
    • the perl binary itself

    (bug report submitted, so hopefully the issue will be fixed in the next SuSE release)

      This fixed the problem, thank you! Just one thing: "perl32 Makefile.PL;make;make test" wasn't enough. Must do "perl32 Makefile.PL;make PASTHRU_INC='-m32' LD='cc -m32';make test"

      The celebration was premature. "make test" works, but when we try "perl32 icstest.pl" we get

      perl32: symbol lookup error: /usr/lib/perl5/5.8.8/i586-linux-thread-multi/auto/ICS/ICS.so: undefined symbol: Perl_Istack_sp_ptr

      No doubt we are still missing something, but what?

        It appears the symbol Perl_Istack_sp_ptr is only available in Perl 5.10.0 (in 5.8.8, the respective macro is defined as *Perl_Tstack_sp_ptr(aTHX)). In other words, my educated guess would be that, somehow, some part of your proprietary ICS lib or Perl module had been linked against libperl 5.10.0 ...

        It's not yet time to give up, however! :)

        You could install the perl-5.10.0 packages from SuSE 11.0 (I verified the package is compatible with the library versions (libc, etc.) that come with older SuSE releases (going back to 10.1), so this should - in theory - work).  You can get the RPMs from here:

        perl-base-5.10.0-37.4.i586.rpm
        perl-5.10.0-37.4.i586.rpm

        (the slightly older, original 11.0 packages can be found here, for example)

        You'd need to install the entire contents in this particular case. Most of the stuff will install under

        /usr/lib/perl5/5.10.0/i586-linux-thread-multi /usr/lib/perl5/5.10.0 /usr/lib/perl5/vendor_perl/5.10.0/i586-linux-thread-multi /usr/lib/perl5/vendor_perl/5.10.0

        so if you rename the remaining files in /usr/bin and /share, the package should peacefully coexist with your existing 5.8.8 perls.

        There's a little gotcha, though. SuSE has changed the internal compression format of their RPMs starting with 11.0, so you won't be able to install/unpack the packages using the old RPM tools from 10.3 — i.e. neither rpm nor rpm2cpio will work.  In other words, you'd first need to get the new RPM tools that come with 11.0  (luckily, it seems they were foresighted enough to use the old compression format for this very RPM package itself...).

        Alternatively, you could consider upgrading to SuSE 11.0 (or maybe 11.1 (currently beta)).

        Or, as a last resort, I could provide a re-packaged tarball (feel free to /msg me privately if all else fails).   Good luck!

Re: 32bit lib on 64bit system
by zwon (Abbot) on Nov 25, 2008 at 13:41 UTC
    We tried installing SuSE's perl-32bit package. It didn't help. That package is installed, but I have seen nothing. "whereis perl" finds only the 64bit version, perl -v reports that it is the 64bit version.
    Have you tried rpm -ql perl32_package_name to find the binary?

      We already had 32bit gcc installed, as we've had to compile other 32bit software. Those packages we installed are gcc-32bit, libstdc++42-devel-32bit, and libstdc++42-32bit.

      Thanks to that rpm command, I learned that perl-32bit does indeed install a bunch of library (.a, .o, .so) files under /usr/lib/perl5/5.8.8/i586-linux-thread-multi. Just library files, no .pm or .h files-- guess all those are the same as under x86_64.

      I got ICS to compile by altering the Makefile generated by "perl Makefile.PL". Changed every "x86_64-linux-thread-multi" to "i586-linux-thread-multi", which caused errors about not being able to find Config.pm, then not being able to find config.h. Changed PERL_ARCHLIB and PERL_INC back to x86_64-linux-thread-multi to fix those. Next, I ran make with some flags: make PASTHRU_INC='-m32' LD='cc -m32' ("-march=i386" only gives an error "CPU you selected does not support x86-64 instruction set"). That finally made ICS.c compile, and I got a file blib/arch/auto/ICS/ICS.so that is 32bit. Seems there ought to be an easier way to do that, some flag I can pass for "perl Makefile.PL".

      But it still doesn't work. Now when I try "make test", upon reaching the line with "use ICS;", I get:

      Can't load '.../blib/arch/auto/ICS/ICS.so' for module ICS: ... wrong ELF class: ELFCLASS32 at /usr/lib/perl5/5.8.8/x86_64-linux-thread-multi/DynaLoader.pm line 230.

        It looks like make test runs 64 bit version of perl

        You'd need to run Makefile.PL with the appropriate 32-bit perl binary.  Yes, I know, there wasn't one... but now that there is (i.e. after you've installed all required 32-bit files as described below), that would be

        /usr/bin/perl32 Makefile.PL

        Good luck!