David Scott <[EMAIL PROTECTED]> writes:
>I've got a very perplexing problem involving shared libraries.
>
>I'm trying to build a Perl extension to the beepcore-c library (as
>described by Marshall Rose in his BEEP book for O'Reilly). As part of
>this API, the developer writes a number of "profiles" that are loaded
>dynamically as needed by the BEEP core (well, the wrapper, but let's not
>pick nits). I have been trying to develop a Perl API so that people
>could write profiles in Perl instead of C, thereby making the whole
>thing a lot more accessible.
Can you be more specific about what dlopen()s what?
Running whole thing under strace may provide that information.
>
>beepcore-c comes with a fairly elaborate make system that uses libtool.
>It builds fairly smoothly. I decided to solve my second problem
>(drivers) first, so I put a large part of the top-level beepcore API
>into SWIG
Personally I don't like SWIG - but if it works ...
>and use ExtUtils::MakeMaker for the makefiles. The profiles
>are still in C. Again, no problems, once I specified all the right
>libraries in Makefile.PL. But when I come to load profiles (which are
>shared object libraries) the Perl extension fails me -- the profile
>loader (written in C to use dlopen) can't find the object libraries and
>resolve the symbols correctly.
Does your perl code use any perl dynamic loaded extensions?
Extensions expect to get perl's symbols from the root executable
this doesn't happen if perl is itself dlopen()ed by some
other executable using default options. You need the RTLD_GLOBAL flag.
Alternatively if you have loaded beep stuff into perl things beep
loads may be expecting beepcore to be root executable, so perl should
have RTLD_GLOBALed it. Or maybe you can statically link beepcore into
perl so _both_ sets of symbols are in root?
>
>I tried to specify -Wl,--rpath -Wl,{LIBDIR} in the WriteMakefile
>LDDLFLAGS
I am reasonably sure MakeMaker converts -L into LD_RUN_PATH entries
which should be honoured in same way as --rpath so this _should_
be unnecessary.
>attribute and ran into what are apparently some gcc problems:
>/usr/lib/crt1.o: In function '_start':
>/usr/lib/crt1.o(.text+0x18): undefined referencet to 'main'
>collect2: ld returned 1 exit status
I have seen that before somewhere but can't remember the full details.
I have had to put dummy main() into shared objects in the past
(but that was me being extra devious on Solaris, I don't recall doing
it on linux). I _think_ it has something to do with standard start files
that GCC adds (which may be obvious), and their relative position on the
final command line to other things you are linking with.
>
>This doesn't happen in the libtool version.
Is it possible to get libtool to be verbose about what it is actually
doing?
Building ELF / dlopen shared libs _used_ to be near trivial but seems
to be getting complicated these days.
>
>Not only that, but when I explicitly specify LD_LIBRARY_PATH before
>executing my perl program, it still can't find the libraries and resolve
>the symbols.
This smells more and more like something expecting to find symbols
in the root executable.
>
>I can't help feeling that I'm close and missing something really obvious
>here. Should I be using libtool in my own make process?
Sounds as though it _might_ be worth considering.
>How do I do
>that?
Not sure. My guess is you might be able to fake it by telling MakeMaker
that libtool is your linker i.e. LD
>Or is there an easier way?
Well I don't think "we" understand the problem yet - I know I don't
and this seems to be first reply to your question so others are
probably confused as well.
>
>Incidentally, I'm using perl 5.6.2 and 5.8.3 (same results in both) and
>gcc 3.0.0 (same results in gcc 2.96) on Linux 2.4.25.
Linux 2.4.25 means next to nothing - is that a kernel version?
What is more important here is (g)libc version.