When building an executable, gcc requires the -l flag to list the shared libraries, even though they can be changed freely without recompiling the executable. Does gcc use that flag only to check if all the symbols are ok? Can I build the executable without performing this verification?
You can use dlopen to load the dynamic library at runtime, and dlsym to get the pointer to the function you like to call.
Here is a sample http://pubs.opengroup.org/onlinepubs/009695399/functions/dlsym.html
Related
I have followed the Installation and Quickstart instructions, and am writing a CMake project to use Drake.
I'm looking at a unittest that builds in Drake, run it, and it builds, runs, and passes. However, when I try to use some of that functionality in my CMake project, I get a linker error, such as:
undefined reference to `RigidBodyTree<double>::get_position_name(int) const'
If I look at symbols in the Drake shared library (e.g. nm -C or objdump -TC with grep), I see the signature RigidBodyTree<double>::get_position_name[abi:cxx11](int). However, if I look in the produced object code (which causes the linking to fail), I see RigidBodyTree<double>::get_position_name(int).
(Note: This post is a means to migrate from http://drake.mit.edu/faq.html to StackOverflow for user-based questions.)
This is most likely due to an incompatibilty between the compiler used to produce Drake (e.g. clang) and the compiler that CMake has selected (e.g. gcc-4.9). Specifically, gcc-4.9 or before does not tend to handle the DualABI well when linking against clang-compiled code (ref). You may be able to use other functions, because only functions that return an ABI-dependent class (e.g. std::string) are tagged with the ABI that they are using (since they cannot be distinguished in the function signature).
The fix is to change the compiler CMake is using. One way to do this is to set the CC and CXX environment variables to use a supported compiler. For a list of supported compilers, see Supported Configurations. If you are using pre-compiled binaries, please refer to Binary Packages for the compilers used.
WARNING: Do NOT change the compiler using update-alternatives in Ubuntu, as this may affect your DKMS module compatibility with the kernel (among other things) (ref).
I'm compiling a shared library with gcc and loading it using dlopen. I also pass the following to the compiler:
-fvisibility=hidden
When I compile the library WITHOUT the visibility flag, everything works perfectly. However, when I compile WITH the flag, I get the following error with dlopen:
libtest.so: cannot open shared object file: No such file or directory
The linbrary .so file exists! This seems weird to me, since if some symbols are hidden, I would expect dlsym to fail if something cannot be found. However, this already fails when loading the library (aka dlopen).
I also tried adding
__attribute__ ((visibility ("default")))
to the functions I later call (extern "C"), without any success. Does anyone know what I can do about this? Or alternatively, is there any way to debug this to figure out why dlopen fails? I do not want to remove the visibility flag, since his drastically reduces my executable size.
My lib was depended on another lib that could not be found.
You may use ldd to see the list of all dependencies, including missing.
ldd libtest.so
I am a regular C programmer, and there's something I have wondered for some time about GNU GCC/LD internals.
I have noticed that, when passing a sequence of object files to GCC (e.g gcc main.o otherfile.o), GCC automatically links libc.a library file without my explicitly specifying -lc in the options. Similarly, when I compile a program using ncurses, I just need to specify -lncurses and libtinfo.a gets linked automatically (no need to specify -ltinfo). In other words, even though ncurses functions use functions from libtinfo (for instance, unctrl()), I don't need to explicitly link libtinfo.
How can it be possible?
Does GCC/LD have a list of "default libraries" where it looks for missing symbols when linking? If such a table exists, where is it and how can it be configured?
A direct answer is that you can see what libraries are linked by command line options by adding -v to the linking command line. This will show you the commands as they are executed.
The C library and the GCC support library or libraries are linked automatically; other libraries have to be specified manually.
The case of -lncurses and libtinfo.a (libtinfo.so?) is rather different. There, the link command used to build libncurses.so tells the linker that this library also needs -ltinfo, so it automatically picks up the extra library.
I've installed GCC 4.6.3 into a non-system path on a Mac system and it works fine. However, GCC wants to use code from libgcc for all the binaries I compile, and running otool -L shows that these compiled programs look for libgcc_s.1.dylib in GCC's install path. I can override this by passing -static-libgcc, which just compiles the stuff needed into the binary and that's fine. The problem is this only seems to work with executables, not shared libraries. If I use GCC to compile some third-party lib I want to use in one of my programs as a .dylib, these libraries still look for libgcc_s.1.dylib in the local GCC install path even if I specify -static-libgcc! Needless to say, this is a problem as there's no guarantee that those libraries will find libgcc when run on some other system.
I tried this with ffmpeg. If I look at config.log, the -static-libgcc is most certainly being used. GCC is just not linking libgcc statically with the resulting dylibs. I even tried the -nostdlib, -nostartfiles and -nodefaultlibs options but they were ignored. Again, I checked config.log and they're definitely there!
I believe this is to do with throwing exceptions across the shared library boundary. This page says:
There are several situations in which an application should use the
shared libgcc instead of the static version. The most common of these
is when the application wishes to throw and catch exceptions across
different shared libraries. In that case, each of the libraries as
well as the application itself should use the shared libgcc.
Therefore, the G++ and GCJ drivers automatically add -shared-libgcc
whenever you build a shared library or a main executable, because C++
and Java programs typically use exceptions, so this is the right thing
to do.
The rest of that sections gives a possible workaround (it appears) and that is to use the GCC driver to link your shared library, however if the statically-linked library throws exceptions you'll probably get a Segmentation Violation.
I am able to build the shared object successfully using the holy native compiler "xlc" on AIX.It does build the shared object library but does not install the shared object library.
Configure command is:
./configure --prefix=/PATH/to/install --exec-prefix=/PATH/to/install --enable-shared --enable-static=no --enable-module=so --build=powerpc-ibm-aix5.3.0.0 --host=powerpc-ibm-aix5.3.0.0 LDFLAGS="-G -shared"
Any help would be appreciated?
So you are trying to compile to the shared library location.
I would suggest seeing if you can compile/link to your local directory.
If that works, try copying the new library to the correct directory. It may be that the oldshared library is open by some process and therefore can't be overwritten.
Are you getting any error messages?
I could install the shared library successfully when i had to exclusively export LDFLAGS as "-brtl -L/path/to/install".
Under AIX, there are two types of shared libraries, AIX style, and SysV compat libs.
AIX style libs are archvies that can contain static libraries as well as multiple versions of shared libraries, and have names like libFOO.a
SysV-compat libs have names like libFoo.so and are more like what you would find on Linux.
Libtool will build either type. If you want SysV-compat libs, add -Wl,-brtl to LDFLAGS.
My guess is that you see /PATH/to/install/lib/libFOO.a and are assuming that it's a static library, when in fact, it's an AIX shared library.