Domanda

I'm trying to build DBD::Pg on a linux host via the Makefile.PL; my requirements are such that I must be able to dynamically link against perl, but statically link against libpq.so (since it may not be available on all boxes).

Is there an easy way to do this? I have tried changing the link options in the LIBS directive of the Makefile.PL but MakeMaker ignores my options.

È stato utile?

Soluzione

IMO you've mis-specified your requirements.

You do not need to statically link to libpq just because it might not be available on all systems.

What you should generally do instead is dynamically link to libq and either set LD_LIBRARY_PATH in a wrapper script or use rpath linking so that libpq can be found.

Be aware though that whether statically or dynamically linking, if some other module loads a libpq into the same Perl you'll either get two incompatible libpqs linked into the same executable (boom) or one of the modules using a libpq other than the one it was compiled against (also boom). If you use rpath linking, ld.so's awareness of link scopes might let you get away with it, but setting LD_LIBRARY_PATH will almost certainly cause issues.

You might want to look into using rpath with $ORIGIN.

Altri suggerimenti

Unfortunately, trying to do static linking of libpq is not likely to solve your problem at large.

libpq itself is likely to depend on libc (glibc). If you link it statically, but other modules dynamically, it means you will have 2 copies of libc: one inside libpq, another referenced by Perl itself and loaded dynamically. This is very dangerous situation, especially if some procedure allocates memory using malloc and passes pointer back to caller. If you have memory allocated by malloc from one copy of libc, but freeed by another copy, your program (and Perl) will definitely crash.

In other words, if you want to go static, you must go all way through - everything, 100% must be compiled statically, so only one copy of libc used by your application. And the opposite is true - if you are dynamic, everything should be dynamic, as to only ever use one copy of libc. These rules don't apply only if your libraries do not use anything from libc (not even sprintf).

Even if you succeed at static libpq compilation and it will work (not very likely), what if DBI is not installed? I have seen enough Linux boxes where DBI is not present by default. Do you compile DBI statically then as well? What if Perl is not present (as unlikely this is on Linux), or if it is very old?

Proper solution is to install it using native OS package manager:

sudo apt-get install libdbd-pg-perl   # Ubuntu/Debian
sudo yum install perl-DBD-Pg          # Redhat/Fedora

If you do not have root on hosts in question, maybe you should consider using perlbrew - install your own Perl in home directory. With this, you should be able to compile your own copy of libpq and link it with Perl provided by perlbrew dynamically.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top