Jeff Hobbs wrote:
Jeff Hobbs wrote:
Brian Bevins wrote:
Thanks very much for your help with our little problem. I am out of
ideas on this. I can do a "package require BLT" in both wish and
tclsh just fine with no problems. And when I try to load BLT into
Perl, the error is not that it cannot find the BLT package library.
The problem is that when it tries to load that library there is a
missing symbol. That symbol is found only in libtcl8.4.so. If I
manually load that library before loading BLT then everything works.
The odd thing is that I shouldn't have to do that. The Tcl.so used
by perl should already be loading libtcl8.4.so.
Is it possible that the implicit loader (or any pre-loading occuring
through whatever means) for libtcl is using RTLD_LOCAL instead of
RTLD_GLOBAL, which would very possible cause this issue?
OK, I poked my nose in because it may well be my own code on this in
the Tcl.xs file. When this builds, it should build against -ltclstub
only, and load libtcl dynamically (you should not see -Ltcl or -Rtcl
on the compile line). Tcl.xs does use RTLD_NOW | RTLD_GLOBAL as the
flags, so that is maybe not the issue (unless libtcl is magically
getting loaded implicitly ahead of this).
Hi Jeff,
Thanks again for looking at this. Prompted by your questions, I think I
have figured out the problem.
BLT wants a symbol called TclpRealloc and our libtcl8.4.so does not
export that symbol globally. It is present, but local to the shared
object. However the symbol is exposed by the stubs mechanism. It appears
that Tcl.so was built by default without Tcl stubs enabled. It only
tries to use stubs if I explicitly add --usestubs, and then it only
passes "make test" if I also define where libtcl8.4.so can be found:
perl Makefile.PL --usestubs
--define=-DLIB_RUNTIME_DIR=\\\"/usr/csite/pubtools/tcl/8.4/lib\\\"
I was fooled by the fact that if I do just:
perl Makefile.PL
it finds our Tcl 8.4 just fine and builds without errors. It even passes
"make test" with flying colors. Only trying to load BLT showed the problem.
When built without --usestubs our Tcl.so does build against libtcl8.4.so
(not libtclstub8.4.a). When I ldd it, I get:
> ldd blib/arch/auto/Tcl/Tcl.so
libtcl8.4.so => /usr/csite/pubtools/tcl/8.4/lib/libtcl8.4.so
(0x00be5000)
libc.so.6 => /lib/tls/libc.so.6 (0x00a17000)
libdl.so.2 => /lib/libdl.so.2 (0x004e6000)
libpthread.so.0 => /lib/tls/libpthread.so.0 (0x00866000)
libm.so.6 => /lib/tls/libm.so.6 (0x00ca6000)
/lib/ld-linux.so.2 (0x00785000)
This is true even if I don't specify --nousestubs to Makefile.PL. Here
is what shows up in Makefile:
# --- MakeMaker const_loadlibs section:
# Tcl might depend on some other libraries:
# See ExtUtils::Liblist for details
#
EXTRALIBS = -L/usr/csite/pubtools/tcl/8.4/lib -ltcl8.4
LDLOADLIBS = -L/usr/csite/pubtools/tcl/8.4/lib -ltcl8.4
BSLOADLIBS =
LD_RUN_PATH = /usr/csite/pubtools/tcl/8.4/lib
I think this happens by default because our Tcl 8.4.15 was built without
stubs. The stub libraries are present, but not used by tclsh itself. (I
didn't build it.) When I ldd tclsh, I get:
> ldd tclsh
libtcl8.4.so => /usr/csite/pubtools/tcl/8.4/lib/libtcl8.4.so
(0x007fd000)
libdl.so.2 => /lib/libdl.so.2 (0x008f7000)
libpthread.so.0 => /lib/tls/libpthread.so.0 (0x00a00000)
libm.so.6 => /lib/tls/libm.so.6 (0x008d2000)
libc.so.6 => /lib/tls/libc.so.6 (0x00111000)
/lib/ld-linux.so.2 (0x00785000)
So Tcl.so wants to implicitly load the same libtcl8.4.so as our tclsh.
Somehow tclsh is making TclpRealloc available to BLT, but Tcl.so doesn't
unless I explicitly load libtcl8.4.so after it.
--Brian
--
Brian S. Bevins, PE
Computer Scientist / Mechanical Engineer
Thomas Jefferson National Accelerator Facility
"Nothing in all the world is more dangerous than
sincere ignorance and conscientious stupidity."
--Martin Luther King Jr.