Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Real Static Modules

by Anonymous Monk
on Sep 17, 2007 at 22:41 UTC ( [id://639511]=perlquestion: print w/replies, xml ) Need Help??

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

I have several shared libraries what I would like to have statically compiled into a module’s shared library. For example, instead of Perl -> Perl Module (.pm & .so) -> shared library, I’d like to be able to have Perl -> Perl Module (.pm & .so).

Here’s an example with the DBD::Sybase modules, but this applies to many other modules, MySQL, Pg, etc.

Instead of:
# ldd /opt/company/apps/perl/site/lib/auto/DBD/Sybase/Sybase.so libct.so.4 => /opt/company/apps/apps/freetds/lib/libct.so.4 (0 +x00c37000) libtds.so.5 => /opt/company/apps/apps/freetds/lib/libtds.so.5 +(0x00e83000) libdl.so.2 => /lib/libdl.so.2 (0x00f7c000) libm.so.6 => /lib/tls/libm.so.6 (0x00f53000) libc.so.6 => /lib/tls/libc.so.6 (0x001a5000) /lib/ld-linux.so.2 (0x0041b000)
I want:
# ldd /opt/company/apps/perl/site/lib/auto/DBD/Sybase/Sybase.so libdl.so.2 => /lib/libdl.so.2 (0x00f7c000) libm.so.6 => /lib/tls/libm.so.6 (0x00f53000) libc.so.6 => /lib/tls/libc.so.6 (0x001a5000) /lib/ld-linux.so.2 (0x0041b000)

The only option I can find is building the module with “make Makefile.PL LINKTYPE=static”. This will not work for me as it just creates a new statically compiled Perl binary. I’m using ActiveState’s Perlapp and it bundles the perl.so with the exe. The Perl exe with the static library built in does me no good.

I’m really looking for a way to get an external static library compiled into a Perl module shared library. Is that even possible? BTW – this same problem exists with PHP and Apache modules. There has to be a way to create a slim exe with shared object modules without requiring any external shared libraries.

Replies are listed 'Best First'.
Re: Real Static Modules
by almut (Canon) on Sep 18, 2007 at 02:42 UTC

    In case you don't want to mess with individual .o files, you can also use ExtUtils::MakeMakers's MYEXTLIB option to link against a static library (aka archive, thus extension .a), but you do need such a static library version of whatever secondary library dependencies you want to link the module's .so file against — a shared library (.so) file won't do.

    As with OBJECT (suggested by Joost), you'd simply add MYEXTLIB => '/path/to/lib/foo/libfoo.a' (or MYEXTLIB => '/path/to/lib/foo/libfoo$(LIB_EXT)') to the WriteMakefile( ... ) options. That's essentially it.

    During the make run, you should then see something like this (assuming your Perl/XS module is named MyFoo, which depends on libfoo...):

    cc -shared MyFoo.o -o blib/arch/auto/MyFoo/MyFoo.so /path/to/lib/foo/l +ibfoo.a

    This command creates a shared library MyFoo.so from the object file MyFoo.o and the other object files contained in libfoo.a (an archive is nothing but a collection of object files). In other words, your MyFoo.so is then statically linked against libfoo.

    If all else fails, you can also edit the Makefile that's written by MakeMaker to issue something similar to the above command line (but keep in mind that any modifications will be lost when you rerun MakeMaker...)

      Thanks this works perfectly and solves my problem. I worked on the Postgres and Sybase modules and made the following MYEXTLIB changes:

      Postgres
      MYEXTLIB => '/usr/lib/libpq.a'
      Before
      # ldd /opt/company.old/apps/perl/site/lib/auto/DBD/Pg/Pg.so libpq.so.3 => /usr/lib/libpq.so.3 (0x007cc000) libc.so.6 => /lib/tls/libc.so.6 (0x00ce2000) libssl.so.4 => /lib/libssl.so.4 (0x00111000) libcrypto.so.4 => /lib/libcrypto.so.4 (0x00e82000) libkrb5.so.3 => /usr/lib/libkrb5.so.3 (0x00843000) libcom_err.so.2 => /lib/libcom_err.so.2 (0x00217000) libcrypt.so.1 => /lib/libcrypt.so.1 (0x00aa2000) libresolv.so.2 => /lib/libresolv.so.2 (0x00145000) libnsl.so.1 => /lib/libnsl.so.1 (0x004d2000) libpthread.so.0 => /lib/tls/libpthread.so.0 (0x00189000) /lib/ld-linux.so.2 (0x0041b000) libgssapi_krb5.so.2 => /usr/lib/libgssapi_krb5.so.2 (0x002f500 +0) libk5crypto.so.3 => /usr/lib/libk5crypto.so.3 (0x00c33000) libdl.so.2 => /lib/libdl.so.2 (0x00b86000) libz.so.1 => /usr/lib/libz.so.1 (0x00158000)
      After
      # ldd /opt/company/apps/perl/site/lib/auto/DBD/Pg/Pg.so libc.so.6 => /lib/tls/libc.so.6 (0x00cee000) /lib/ld-linux.so.2 (0x0041b000)
      Sybase
      MYEXTLIB => '/opt/company/apps/freetds/lib/libct.a /opt/company/apps/f +reetds/lib/libtds.a'
      Before
      # ldd /opt/company.old/apps/perl/site/lib/auto/DBD/Sybase/Sybase.so libct.so.4 => /opt/company.old/apps/freetds/lib/libct.so.4 (0x +004cd000) libtds.so.5 => /opt/company.old/apps/freetds/lib/libtds.so.5 ( +0x00353000) libdl.so.2 => /lib/libdl.so.2 (0x00c24000) libm.so.6 => /lib/tls/libm.so.6 (0x00ccc000) libc.so.6 => /lib/tls/libc.so.6 (0x00111000) /lib/ld-linux.so.2 (0x0041b000)
      After
      # ldd /opt/company/apps/perl/site/lib/auto/DBD/Sybase/Sybase.so libc.so.6 => /lib/tls/libc.so.6 (0x00880000) /lib/ld-linux.so.2 (0x0041b000)
Re: Real Static Modules
by Joost (Canon) on Sep 17, 2007 at 22:45 UTC
      Yea, I'm sure a static library and a shared one don't mix. I should have really asked: "can you create a single .so from the library .so and the XS wrapper all together"?
        I think you've misunderstood me: you can't statically link an .so library to another .so library, but you can link one or more .o files into a single .so library.

        Does that make it clearer?

        In any case, if you really have to, you can always distribute the additional .so file with the perl/xs/so files.

        Other than pure curiousity, I don't really see a reason you'd want to do this.

Re: Real Static Modules
by syphilis (Archbishop) on Sep 18, 2007 at 01:29 UTC
    I’m really looking for a way to get an external static library compiled into a Perl module shared library. Is that even possible?

    Definitely possible - in fact that's precisely what happens when you build the perl module against a *static* build of the external library. (Therein lies one reason that I prefer to build static, rather than shared, libraries.)

    Your problem, as I see it, is that you want to incorporate a *shared* library into the perl module's '.so'. If that can be done, then I don't know how to do it .... it undoes what shared libraries set out to achieve, so I'm a little sceptical.

    Cheers,
    Rob
      This indeed feasible on many platforms, but on some platforms you can't dynamically load a .so that has been linked to a .a (or equivalent) file (HP-UX comes to mind).

      As an aside - I was surprised that on AIX (at least 5.2) the links are static by default, so my Sybase.so file is in fact independent of the libct.so, etc. files...

      Michael

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://639511]
Approved by Joost
Front-paged by grinder
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others meditating upon the Monastery: (5)
As of 2024-04-24 08:10 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found