[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Integration of a Perl XS module with an Automake build system
From: |
Gavin Smith |
Subject: |
Re: Integration of a Perl XS module with an Automake build system |
Date: |
Tue, 30 Jun 2015 20:46:04 +0100 |
On 30 June 2015 at 14:25, Bob Friesenhahn <address@hidden> wrote:
> In addition to behavior issues, a major problem is that the re-link
> capabilities offered by libtool are not available. If one links from the
> Perl module to a shared library in the build tree, then there is the risk of
> continued reference to the build tree after installation (a
> security/reliability issue) and the module might not even run. The Perl test
> suite is likely to use the wrong shared libraries while testing due to
> GNU/Linux's strong preference to using already-installed libraries cached by
> 'ldconfig'. Due to this, I changed GraphicsMagick so that it only links its
> Perl module at 'make install' and time it uses the already-installed shared
> library. This still does not help with DESTDIR installs.
>
> After I made this change, some GNU/Linux distributions stopped building the
> GraphicsMagick Perl module at all due to claiming that the build is
> "broken". They expect that everything builds in tree in one step and that
> 'make check' works as one would expect. I don't think that this is possible
> to accomplish in a portable way using ExtUtils::MakeMaker.
>
> If there is a viable solution which avoids ExtUtils::MakeMaker and allows
> Automake to drive behavior, with linkage managed by libtool, then I am all
> ears.
I'm not linking to another dynamic library from the XS module, just a
static library, but I've been trying to build the library with libtool
using a Makefile.am of my own writing, using the Makefile output by
ExtUtils::MakeMaker as a reference. I've had a little bit success so
far, so hopefully I'm not on a wild-goose chase. I load the *.so file
libtool produces with the Perl DynaLoader module. The main problem
seems to be getting the right compiler flags. The first time I tried I
got a bizarre error message like "Not a CODE reference" when I tried
to run the bootstrap function in the module. (Although the object
wasn't null, I couldn't find out what it was.) I got it to work when I
copied a bunch of compiler flags over from the MakeMaker Makefile. My
Makefile.am currently has the lines:
-------------------------------------------------------------
pkglib_LTLIBRARIES = XSParagraph.la
XSParagraph_la_SOURCES = XSParagraph.c mylib/xspara.c mylib/xspara.h
BUILT_SOURCES = XSParagraph.c
XSParagraph_la_CPPFLAGS = -I. -I$(PERL_INC) -D_REENTRANT -D_GNU_SOURCE
-I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64
XSParagraph_la_CFLAGS = -fno-strict-aliasing -pipe -fstack-protector
-O2 -march=i486 -mtune=i686 -DVERSION=\"6.0\" -DXS_VERSION=\"6.0\"
$(CCCDLFLAGS) "-I/usr/lib/perl5/CORE"
XSParagraph_la_LDFLAGS=-module
--------------------------------------------------------
as well as a heap of other variable definitions copied from the
MakeMaker Makefile. Now I have to see how ExtUtils:MakeMaker knew what
flags to use to see if I can replicate it.
Using the DynaLoader module instead of XSLoader gives us the
flexibility to go looking for a dynamically-loaded library file
ourselves. The code to load the module looked like this:
-----------------------------------------------------------
our $VERSION = '6.0';
#bootstrap XSParagraph $VERSION;
# TODO: Get this from XSParagraph.la, the dlname field
my $dlname = "Texinfo/Convert/XSParagraph/.libs/XSParagraph.so.0";
my $module = "XSParagraph";
# Following steps under "bootstrap" in "man DynaLoader".
# Doesn't work
#push @dl_require_symbols, "boot_$module";
# TODO: Execute blib/arch/auto/XSParagraph/XSParagraph.bs ?
# That file is empty.
#my $flags = dl_load_flags $module; # This is 0 in DynaLoader
my $flags = 0;
my $libref = DynaLoader::dl_load_file($dlname, $flags);
if (!$libref) {
die "Couldn't find *.so file\n.";
}
my @undefined_symbols = DynaLoader::dl_undef_symbols();
if ($#undefined_symbols+1 != 0) {
warn "XSParagraph: still have undefined symbols after dl_load_file\n";
}
my $symref = DynaLoader::dl_find_symbol($libref, "boot_$module");
if (!$symref) {
die "XSParagraph: Couldn't find boot_$module symbol\n";
}
my $xs = DynaLoader::dl_install_xsub("${module}::bootstrap",
$symref, $dlname);
if (!$xs) {
die "XSParagraph: Couldn't bootstrap\n";
}
# Doesn't work
#push DynaLoader::@dl_shared_objects, $file; # record files loaded
&$xs($module, $VERSION);
----------------------------------------------------