linux - make .a corresponding to .so - linux

I have some legacy 'so' file, with the corresponding header, how to make 'a' file out of it
to link with the project ?
(or could I link to 'so' - adding -L/path_to_so/ and -lsomething (assuming so is in /path_to_so and is named libsomething.so does not seem to work - ld complains about missing exports - but they are present in lib (lib is 32bit, -m32 is used, project is 32bit) ?)
I'm not a linux guru, on windows when i have dll and header I'm able to generate lib, that I'm linking with project to use dll - I assume that same is on linux right ?

I have some legacy 'so' file, with the corresponding header, how to make 'a' file out of it to link with the project ?
There is no way to make .a. from .so. On Linux .so get linked directly, no import library is required.

Related

Shared Library on Linux is not found

I have built some shared libraries on Ubuntu Linux 16.0.2 from source.
They are 64-bit libs.
I manually copied them to /usr/local/lib.
I verified that the /usr/local/lib path is indeed in one of the .conf files that ld.so.conf includes.
I then ran: sudo ldconfig to update the cache.
But then when I try to run my executable which tries to dynamically load one of the .so files that I previously copied into /usr/local/lib using dlopen, it fails.
In my code, I have:
dlopen ("foobar.so", RTLD_LAZY);
Can anybody tell me what I am doing wrong?
The dynamic linker normally doesn't access the paths recursively included from /etc/ld.so.conf directly, but it uses a cache.
You can update the cache with
sudo ldconfig
See ldconfig(8) for more details.
for dlopen to work, there's no directory list of places to find the shared object. So doing dlopen("somefile", ...); probably won't work.
You don't need to use any path or to put the shared object (or to comply with naming conventions) to use a shared object via dlopen(3). That's only a requirement of the dynamic linker that loads and links all the shared libraries at launch time: linux-vdso.so.1 (in 64bit)
To test, just put the shared in your local dir and try to open it with it's basename, like you post.
For a system library, there are more requirements, like defining a soname for the library, which is used by the loader to load the library and to construct the cache database index, so if you have no idea of what I'm talking about, you will not be able to use automatic loading procedure. If you want to see if an executable file has all the libraries it needs and where the loader finds them out, just run ldd(1) with the executable as argument, and you'll se the dependencies for automatic loading and how the dynamic linker resolves the paths.

What is the best way to look for ELF Shared Libraries under linux in C

I am currently working on a userland ELF File loader in C. LD_LIBRARY_PATH does not seem to be an option for me, as it does not seem to be set by default on my system(x86_64 openSUSE). What is the best way to get all of the directories where libraries are stored ?
/usr/lib64 and /lib64 for 64-bit binaries or /usr/lib and /lib for 32-bit binaries, than paths taken from /etc/ld.so.conf and included configs
From man ldconfig
ldconfig creates the necessary links and cache to the most recent shared libraries found in the directories specified on the command line, in the file /etc/ld.so.conf, and in the trusted directories, /lib and /usr/lib (on some 64-bit architectures such as x86-64, /lib and /usr/lib are the trusted directories for 32-bit libraries, while /lib64 and /usr/lib64 are used for 64-bit libraries).
The cache is used by the run-time linker, ld.so or ld-linux.so.
...
/etc/ld.so.conf File containing a list of directories, one per line, in which to search for libraries.
Note that this info is for openSUSE, other distros may use different paths.
LD_LIBRARY_PATH is the standard environment variable used for users to add and load their own libraries when they are unable or have no access to the system directories to install shared libraries.
There's a file which is normally read by ldconfig at boot time (it reads /etc/ld.so.conf to create a binary DBMsomewhat file /etc/ld.so.cache, with a hash table to quick access the paths to use when loading library shared objects, and that is used by the dynamic loader (there's only one such thing, as a kernel tool, so it is not dependant on which distribution you run, but just on the kernel version you use ---it has changed somewhat, but not as much as the kernel does---)
To know which sonames (soname is the common name used by a shared object to refer to an interface, which is what is required to warranty that a shared object will be compatible with the library) are being used by the dynamic loader, just run
ldconfig -p
and you'll get all the sonames registered, and the path to the library actually loaded for that soname.
If you want to know which libraries will be loaded by some specific executable by the dynamic loader, just execute this:
ldd your_executable
and It will print the sonames that executable needs and where in the system they are located.
What ldconfig(8) does, is to search al the directories included in the file /etc/ld.so.conf for shared object files, and look all the ones whose name matches the soname stored in the file, and include a reference to the file named for the soname found. Once the table is completed, the file /etc/ld.so.cache is created and used by /lib64/ld-linux-x86-64.so.2 which is the shared module in charge of user mode loading the rest of shared libraries used by a program.
There's no problem in having a local $HOME/lib directory to store your locally developed shared libraries, but as that directory will not be normally included in /etc/ld.so.conf, you'll need to create LD_LIBRARY_PATH=${HOME}/lib and be careful to export it, and never try to use it as root user, as for root user that env variable is disabled.
EDIT 1
By the way, if you need to load on demand a shared library (this is possibly what you need, probably), read about dlopen(3) and friend functions, as that is the method used by most programs to dynamically load modules you haven't heard about before compilation of main program. You'll need to load the module, look for the symbols you need (dlsym(3) or dlfunc(3)) store the references given by the module, and finally call them.

How does the dynamic loader load libs with correct arch version

For the aarch64 based system, if I provide both arm and arm64 version of library libtest.so in different path, and added the paths into /etc/ld.so.conf.
I want to know if a application depends on this library, how does the loader find out the correct version of libtest.so ?
Basically since both paths are present in ld.so.cache, so does the loader will choose according the arch of app ?
Or is there any rule needed when adding path into ld.so.conf for different arch?
I want to how does it work and many thanks for any information.
I just test it on the system, ldconfig -p output the two libraries but pointing to different place, then ld will use the one library matched with target's arch.
So that ld will match lib by arch, right?
If something wrong please correct me.

My library does not load on other systems but works fine on the system it was compiled on

My project includes a library and example projects for how to use it. I place the library in the "bin" folder along with all executable examples. I can run the example projects on the machine where they were compiled but when I try to run them on another machine I get:
./example: error while loading shared libraries: libMyLib.so: cannot
open shared object file: No such file or directory
This makes no sense since the library is in the same folder. What is causes it to ignore the library on other machines?
Just because the library is in the same directory as the executable doesn't mean it will look there for it. By default on linux, executables will only look in a limited set of directories, set by ldconfig and the LD_LIBRARY_PATH environment variable.
One trick that is very useful is to link your program with the extra linker option
-Wl,-rpath,'$ORIGIN'
which will cause the executable to also look in the directory the executable is in for shared objects.
You can usually set this by adding to your Makefile:
LDFLAGS := -Wl,-rpath,'$$ORIGIN'
Note the double-$ here -- make will interpret this as a make variable which expands to just $
The current directory is not necessarily a place where the dynamic linker will look for dynamic libraries. The directory where the executable is much less.
You might want to check ldconfig to see where it looks for them.

Strange files : *.dll.a * .la What are they? ( VLC windows build ) How to use them on Windows if possible?

I wanted to write small streaming software using VLC compoents on windows. So i look for : lib and headers file for VLC on windows. Instead of compiling it , to make it faster i looked for ready builds for windows. And i found on: http://nightlies.videolan.org/build/win32/last/
I download it (debug) : Find include file directory and lib. But lib directory contains trange (at least for me) file extensions such as libvlc.la and libvlc.dll.a
What are they? Can i use them in Visual C++?
The .la files are libtool convenience libraries, they're useless and only cause trouble (in this case).
The .a files are (import) libraries for GCC/MinGW, just like .lib for MSVC.
VLC can only be built with GCC, because MSVC lacks the proper C99 support. So all debug info will be generated by and for a GNU toolchain (GCC/Binutils/GDB). If you want to use the proper DLL in Visual Studio, you should be able to create an import library from the included .def file and the dll.

Resources