dlsym, dlopen, dlclose
I tried linking in the dl library with the -ldl flag, but there is no
libdl.a library on our system. There's only a libdl.so. I noticed that the
HP and Linux systems have static libraries that define these symbols. The
HP has lib3d.a and the Linux machine has libdll.a. Is there something
special I need to do in order to build a statically linked binary ? I am
clueless here. Thanks in advance.
> I've been building a software package with g++ on several different
> platforms (Solaris, HPUX, Linux). Apparently, it's been building
> dynamically linked binaries and we now need to build statically linked
> binaries.
This is a *very* bad idea (TM): staticlly-linked executables introduce
many more problems then they solve.
Vendors generally support forward binary compatibility only with
dynamically linked executables (e.g. your static exe built on
Solaris 5.5 is not at all guaranteed to be compatible with Solaris
5.6, 5.7, 5.8 or 5.9).
On Linux you'll be in an even worse shape: it is *known* that static
exe's built against glibc-2.1 do not work on glibc-2.2 systems, and
the ones built agains glibc-2.2 do not work on glibc-2.3 systems.
Search c.o.l.d.apps for "static linking" to get the gory details.
> I tried building a statically linked binary on the SunOS 5.5.1
> machine. The problem is that when I add the "-static" option to g++, I end
> up getting unresolved symbols:
>
> dlsym, dlopen, dlclose
Your program apparently uses dynamic linking facilities.
Solaris doesn't support such use from static executables.
From "man dlopen":
Note: These routines are available to dynamically-linked
processes ONLY.
> I am clueless here.
Don't link system libraries statically.
The problem you are *probably* trying to solve is getting rid
of libstdc++.so dependency (as that library is likely not installed
on the user's machine). That doesn't require that you link everything
else statically. Search groups.google.com for "link libstdc++
static" for answers.
Cheers,
--
In order to understand recursion you must first understand recursion.
Remove /-nsp/ for email.
> dlsym, dlopen, dlclose
You aren't going to be able to make a purely static binary on Solaris,
Sun won't support it, and has made sure that you can't get around that desire.
You can mix and match dynamic and static builds, but ultimately you
should do system stuff like libdl and libc as dynamic, and if you want
static for your libs, you can.
But I would emphasize the distinction between system libraries
(primarily those in /lib and/or /usr/lib) and other libs. I tend to link
statically with non-system libs (say, zlib or similar) to avoid any
problems finding those libraries (raising the specter of LD_LIBRARY_PATH
etc) not to mention the possibility of contention between apps for the
same utility libs (the Unix equivalent of "DLL hell").
I absolutely agree that *system libraries* should never be linked
static. For one thing there's never a path problem finding them since
the runtime linker always looks in system lib dirs, and for another only
one vendor (the OS vendor) will be upgrading them and thus they can be
assumed to remain in sync with the rest of the system.
M.B.
Thanks. I'm going to try to link the libstdc++ library statically.
> dlsym, dlopen, dlclose
Static linking is barely supported on Solaris; it's also voids
the "binary compatibility guarantee" Sun gives. Many of the routines
in libc/libsocket depend on pluggable mechanisms all of which use the
dynamic linker; there is no libdl.a simply because there's really
no "libdl.so" either; "libdl.so.1" is really a wrapper for the dynamic
linker; i.e., you can't do dynamic linking without linking at least
the dynamic linker.
The solaris FAQ says:
6.24) I have problems linking my application statically.
In Solaris 2.x static linking is not supported for any of the
system libraries. All the functions that use /etc/nsswitch.conf
(getXXXbyYYY, getpwXXX, etc) require the dynamic linker to
load the code to load these functions. It is not possible
to write configurable/extensible functions in such a way that
dynamic linking is not required. E.g., you can add your own
nsswitch.conf backend which would not be known to programs
statically linked to only the standard backend code.
Programs that link statically against any of the OS libraries
may not run in the next release and are not ABI compliant.
Programs that link statically don't get some dynamic performance
enhancements found in the shared libraries: using hardware
multiply/divide on systems that support it; using fast mem*()
operations on UltraSPARC etc. And you won't pick up performance
enhancements in next releases: e.g., Solaris 2.5 comes with
a 4x faster fread/fwrite and the "Name Server Cache Daemon".
If you don't care about ABI compliance, i.e., you won't
ship your program as a product and don't care that you may
need to recompile after an OS upgrade, here are some of your
options:
Link statically against all but libdl:
cc -Bstatic .... -Bdynamic -ldl -Bstatic
Link against dl* stubs (gethostbyXXX, getpwXXX etc won't work any
longer):
char *dlopen() { return 0;}
int dlclose() { return 0;}
char *dlsym() { return 0;}
char *dlerror() { return "dynamic linking not loaded";}
If you don't want any dependencies on /usr, link against the dynamic
libs in /etc/lib:
cc -Bstatic ... -Bdynamic -R/etc/lib -Wl,-I/etc/lib/ld.so.1 -ldl
-Bstatic ....
If you still get undefined symbols, check with ldd for all your
libraries if they have any dynamic dependencies. E.g.,
% ldd /usr/lib/libsocket.so.1
libnsl.so.1 => /usr/lib/libnsl.so.1
libdl.so.1 => /usr/lib/libdl.so.1
libc.so.1 => /usr/lib/libc.so.1
libintl.so.1 => /usr/lib/libintl.so.1
libw.so.1 => /usr/lib/libw.so.1
tells you that if you want to link libsocket statically,
you need to link with -lnsl -ldl -lc -lintl and -lw as well.
There is no way to statically link 64 bit executables; no 64 bit
archive libraries are shipped with Solaris.
--- end of excerpt from the FAQ
The most recently posted version of the FAQ is available from
<http://www.science.uva.nl/pub/solaris/solaris2/>
In that case, the following should work:
-Wl,-Bstatic -lstdc++ -Wl,-Bdynamic
or some such.
Casper
--
Expressed in this posting are my opinions. They are in no way related
to opinions held by my employer, Sun Microsystems.
Statements on Sun products included here are not gospel and may
be fiction rather than truth.
Again this overstates the problem, which has only to do with static
linking of *system* libraries. The FAQ you quote makes the point more
clearly:
> In Solaris 2.x static linking is not supported for any of the
> *system* libraries.
...
> Programs that link statically *against any of the OS libraries*
> may not run in the next release and are not ABI compliant.
(emphasis mine)
M.B.
> In that case, the following should work:
>
> -Wl,-Bstatic -lstdc++ -Wl,-Bdynamic
You would think so, but it doesn't (at least not with g++-3.x).
There is a bit more to it than meets the eye.
Here is a thread that after several iterations converges on a working
solution:
http://groups.google.com/groups?threadm=u8yrxnx5t.fsfYB8X%40earthlink.net
Cheers,
>Casper H.S. Dik wrote:
>> Static linking is barely supported on Solaris; it's also voids
>> the "binary compatibility guarantee" Sun gives.
>Again this overstates the problem, which has only to do with static
>linking of *system* libraries. The FAQ you quote makes the point more
>clearly:
You are correct; however, I took the OP to mean "completely statically
link the application" which does refer to the system libraries.