I have a linux shared library (.so) compiled with a specific version of libc (GLIBC2.4) and I need to use it on a system with different version of libc. I do not have sources for the library in question so I cannot recompile for the new system. Is it somehow possible to change the dependencies in that library to a different libc?
If you need the .so on a system with an older glibc, you would need the source code and recompile/relink it with the older glibc. The alternative is to install the required glibc on the old system in a non-default location and adjust the LD_LIBRARY_PATH for the executable that needs this .so
If there's a newer glibc rather, it should normally not be a problem as glibc tend to be backwards compatible.
Unless your library really uses interfaces that changed (unlikely), you can just hexedit the references to versions in the resulting .so file. They're all text anyway.
Best you can do is compile the old glibc version for your system and then build your application with that glibc and your shared library. Ugly though ...
Related
When building a compiler, one must specify Linux headers version and minumum supported kernel version, in addition to glibc version. And then there is actual kernel version and glibc version (with its own kernel headers version and minumum supported kernel version) on the target machine. I'm rather confused trying to understand how these versions go together.
Example 1: Assume I have system with glibc 2.13 built against kernel headers 3.14. Does that make any sense? How is it possible for glibc 2.13 (released in 2011) to use new kernel features from 3.14 (released in 2014)?
Example 2: Assume I have a compiler with glibc version newer than 2.13. Will compiled programs work on system with glibc 2.13? And if compiler's glibc version is older than 2.13?
Example 3: From https://sourceware.org/glibc/wiki/FAQ#What_version_of_the_Linux_kernel_headers_should_be_used.3F I understand that it's OK to use older kernel if it satisfies "minumum kernel version" used when compiling glibc. But I don't understand the passage The other way round (compiling the GNU C library with old kernel headers and running on a recent kernel) does not necessarily work as expected. For example you can't use new kernel features if you used old kernel headers to compile the GNU C library.. Is it the only thing that can happen to me? Won't it break something in glibc if the kernel is newer than at compile-time?
Example 4: Do more subtle differences in glibc settings (for example, linking an executable against glibc version 2.X compiled against kernel headers 3.Y with minimum supported kernel version 2.6.A and executing in on system with the same glibc 2.X, but compiled against kernel headers 3.Z with minumum supported kernel version 2.6.B) influence anything? I suspect they're not, but would like to be sure.
So many questions :) Thanks!
You can not easily (for whatever definition of the word) use newer kernel features with older versions of glibc. If you really need to, you can invoke system calls directly (using the syscall() library function) and dig whatever constant values and datastructures necessary from user-space kernel headers (the stuff which in the newer kernel is held under include/uapi). On the other hand, kernel developers usually promise not to break legacy features in newer kernels, so older glibc versions keep working as expected (well, almost).
Older programs still work with newer versions of glibc because glibc supports versioning of symbols (see here for some details: https://www.kernel.org/pub/software/libs/glibc/hjl/compat/). If your program is dynamically linked with newer version of glibc without special provisions (as described in the link above) you would not be able to run it with an older version of glibc libraries (dynamic linker will complain about unresolved symbols, as proper symbol versions will not be available).
We need to integrate a closed-source C library into our project. The other party can compile the library in any mode we need, but we support a lot of different Windows and Linux compilers.
I know a DLL will be compatible with all major Windows compilers, so we could only use one library for Windows. But I’m not familiar with Linux dynamic libraries (.so). Are these compatible across all Linux environments in a similar way?
Thanks
You may have some issues w.r.t. the version of the GNU libc against which that shared library libotherparty.so has been linked (and compiled).
You certainly need to know the version of the libc, and you might require that party to ship several variants of the binary library.
I would strongly suggest to read Drepper's paper: How To Write Shared Libraries. See also this question and Levine's linker & loader book.
If it is C code, the compiler does not matter much. What matters more is the ABI. Learn also about symbol versioning.
Be prepared to have some trouble.
You'll learn by experience that free software is preferable.
Library versions should be specified for shared objects if the function interfaces are expected to change (C++ public/protected class definitions), more or fewer functions are included in the library, the function prototype changes (return data type (int, const int, ...) or argument list changes) or data type changes (object definitions: class data members, inheritance, virtual functions, ...).
The library version can be specified when the shared object library is created. If the library is expected to be updated, then a library version should be specified. This is especially important for shared object libraries which are dynamically linked. This also avoids the Microsoft "DLL hell" problem of conflicting libraries where a system upgrade which changes a standard library breaks an older application expecting an older version of the the shared object function.
Versioning occurs with the GNU C/C++ libraries as well. This often make binaries compiled with one version of the GNU tools incompatible with binaries compiled with other versions unless those versions also reside on the system. Multiple versions of the same library can reside on the same system due to versioning. The version of the library is included in the symbol name so the linker knows which version to link with.
One can look at the symbol version used: nm csub1.o
00000000 T ctest1
No version is specified in object code by default.
Look ld and object file layout
There is one GNU C/C++ compiler flag that explicitly deals with symbol versioning. Specify the version script to use at compile time with the flag: --version-script=your-version-script-file
Note: This is only useful when creating shared libraries. It is assumed that the programmer knows which libraries to link with when static linking. Runtime linking allows opportunity for library incompatibility.
Also look here regarding ABI compatibility
i want to compile/link on a new solaris version (libc.so SUNW_1.22.6) for a system with an older solaris (libc.so SUNW_1.22.4). How can I specify that the linker (on the new version) should build a binary that uses the older (1.22.4) libc.so?
In general, UNIX systems support backward compatibility (a program built on an older system continues to work on a newer system), but not the opposite: a program built on a newer system may not work on an older system.
For this reason, build your program on the oldest OS release you are going to support.
How can I specify that the linker (on
the new version) should build a binary
that uses the older (1.22.4) libc.so
You would need a "new Solaris -> old Solars" cross-compiler for that. GCC can be built for such cross-compilation, but this is not trivial. Building on an older system is usually much simpler approach.
Don't call any functions that aren't in SUNW_1.22.4. The linker records the minimum dependency based on the functions linked to.
Is it possible to have glibc and uClibc based applications running side-by-side on one system?
Background: We have binary gcc based cross-compiler configured to link with uClibc. We have cross-compiled glibc with it. Now we want to build some applications so they will link with the glibc rather than uClibc. We don't want to rebuild the compiler.
There's no problem with glibc and uClibc living side-by-side with some programs linking to one and other programs linking to the other. However, there is a problem with additional libraries. Each shared library on your system will be built against either glibc or uClibc (using the corresponding headers, which define distinct ABIs for the standard library functions), so for example if both a glibc program and a uClibc program need ncurses, you'll need to have two versions of ncurses built, and have a way of ensuring that the correct one for the given program gets loaded at runtime. Alternatively, you could choose to only use one set of shared libraries, and use static libraries for programs linked to the other libc, but you'd still need to build your 2 sets of libraries.
Yes, it should be perfectly possible, but you might have to play around with LD_PRELOAD_PATH. If you are linking statically, change to dynamic linking.
It is nearly impossible to mix them in the same FHS, as the ABI and include dir are incompatible. However, you could install either of them in an directory offset, by tweaking dynamic-linker field in ELF and exploiting sysroot feature in gcc/binutils. An on going experiment is in Gentoo community[1], known as Prefix/libc.
http://wiki.gentoo.org/wiki/Prefix/libc
I have been looking through the source of GLib and GObject and writing programs to use certain features of each. But now I'd like to debug though something in the GLib source code without installing anything on my system.
I have a built version of the source code somewhere and I'd like to use those .so files rather than the system installed ones, and I'm not sure how to link them to my test programs. I've tried just referencing the .so files for GLib and GObject on the command-line like to GCC, but trace statements that I put in are not being run, so I suspect the regular GLib libraries are still being used.
Set your LD_LIBRARY_PATH to include the directory which holds the .so you want to link against, and use ldd to verify that ld is doing what you want.