Link glibc statically but some other library dynamically with GCC - c

I need to statically link glibc to my project, because the target platform supports only a very old one ( but it works with statically linked glibc from my toolchain, I have checked it)
Unfortunately, this application has to make use of pthread library, but statically linked libpthread takes too much space.
I would like to statically link glibc, and dynamically pthread.
After running this command
powerpc-unknown-linux-gnu-gcc object_files -lrt -lpthread -Wl,-Bstatic -lc
I get:
/powerpc-unknown-linux-gnu/bin/ld: cannot find -lgcc_s

There is a -static-libgcc if that may help

You should be using -static, not -Wl,-static. The latter bypasses gcc's knowledge, and therefore gcc is still trying to link the shared libgcc_s.so rather than the static libgcc_eh.a.
If your aim is to link libc statically but libpthread dynamically, this is simply not going to work. You cannot mix and match different versions of libpthread; it's part of glibc, just a separate file, and the internals need to match. Even with the same version, I think linking libc statically and libpthread dynamically will be very broken.
If glibc is too big for your needs, you could try an alternate libc like uClibc or musl.

Related

Must link to dependent libraries' dependents; why?

I have an application - let's call it "P" - that uses custom SO's: A.so, B.so, and C.so
The A.so library uses another custom library - D.so - as well as SSL and the math library.
The "P" application makes no calls whatsoever to SSL or math routines.
On macOS (with clang), I could build P with -lA -lB -lC and all was good.
I'm migrating everything to Linux (Debian) with GCC.
Now, when I bulid P, I have to -lA -lB -lC -lD -lm -lssl
What am I doing wrong?
I'm using simple makefiles - no autoconfig, no cmake, etc.
Could this be an "install_name_tool" vs. "chrpath" issue when I build the libraries?
This is because of a combination of the following two factors:
On macOS, the standard C library (libSystem.dylib) which is automatically linked by the compiler already includes a lot more functionality than on Linux. It may include some (or all) the necessary functions for your program. For example, as you can read from this documentation page, libSystem already includes the math library (which is a separate file on Linux and needs to be linked with -lm).
The shared libraries you are linking were compiled for macOS with additional functions already embedded into them, so those don't need to link to other shared libraries. It is not uncommon for a library to depend on different other libraries on different operating systems.
On the other hand, on Linux, the standard C library is split into different files: -lc is automatically linked by the compiler, but the math library (-lm) and other parts (-ldl, -lpthread, etc) are not, and therefore need to be linked manually.
Solved it. Turns out that clang - regardless of development platform - is a lot more forgiving with the order of parameters and options when linking. With clang, you can pretty much put your -I, -L, -l, other options and object files in whatever order you want. Not so with gcc; it's much more particular. clang made me lazy.

What is the difference between shared and dynamic libraries in C?

I don't understand the difference between the two types of libraries, and many websites say that they are the same thing, but at school we use two different commands to create them
dynamic library
$ gcc -shared -o libsample.so lib.c
$ gcc -o main main.c -ldl
to execute:
$ ./main ./libsample.so
shared library
$ gcc -shared -o libsample.so lib.c
$ gcc -o main main.c -L. -lsample
to execute:
$ LD_LIBRARY_PATH=. ./main
Can someone help me in understanding the difference between the two "codes"?
Dynamic Linked Library (.DLL) is the terminology used by Microsoft Windows. Shared Object (.so) is the terminology used by Unix and Linux.
Other than that, conceptually they're the same.
Regarding your snippets of commands, I guess the difference (and I'm only guessing here, because you didn't show us the relevant parts) is how the library is loaded. There is "link time loading" where the library is tied to the executable by the linker¹. And there is "runtime loading", where the program sort of "ingests" the dynamic/shared library.
runtime loading is done in Windows with the LoadLibrary (there's an …A and a …W variant) function, and on Unix/Linux with dlopen (which is made available by libdl which is linked to by that -ldl library link statement).
1: The linker is the program that creates the actually executable file from the intermediary objects created by the various compiler stages.
Dynamic and shared libraries are usually the same. But in your case, it looks as if you are doing something special.
In the shared library case, you specify the shared library at compile-time. When the app is started, the operating system will load the shared library before the application starts.
In the dynamic libary case, the library is not specified at compile-time, so it's not loaded by the operating system. Instead, your application will contain some code to load the library.
The first case is the normal case. The second case is a special use and it's mainly relevant if your application support extensions such a plug-ins. The dynamic loading is required because there can be many plug-ins and they are built after your application. So their names are not available at compile-time.

Does gcc links to libc.a or libc.so by default?

I am using gcc 5.4.0 on Ubuntu 16.04 64 bit. When I compile a program:
gcc -o prog prog.c
GCC automatically links to the C standard library, so I don't have to specifically do that.
How can I see which C library does gcc link against to, libc.a or libc.so, or something else?
In what circumstance does it link to libc.so? Does libc.so need to be specified at run time like other shared libraries?
Thanks in advance.
How can I see which C library does gcc links against to, libc.a or libc.so, or something else?
You can use ldd command to see all linked shared libraries. If libc.so is found, it's dynamic linking.
In what circumstance does it links to libc.so?
gcc uses dynamic linking and links to libc.so by default. If you want static linking, pass -static flag.
Does libc.so need to be specified at run time like other shared libraries?
Normally no, since it's configured by compiler automatically.

gcc linker not automatically including dependency libraries

I am in the process of updating an arm cross compiler from 4.3.3 to 4.9.4. One issue I am seeing is that the new compiler no longer automatically includes dependent libraries. For example:
gcc ... -L -l -lssl -lrt
works fine with the previous compiler. If libssl needed to reference something in libcrypto, then the linker would automatically find and link with libcrypto (no -lcrypto needed).
With the new compiler, this still works, but only if libssl does not reference anything in libcrypto. If it does, then the -lcyrpto is required. The same issue applies to -lpthread, -ldl, etc.
Is this a change in the behavior of gcc or is something not configured properly when building gcc?
Are you using static or dynamic libraries? For dynamic libraries, if libssl depends on libcrypto, you don't need to explicitly link -lcrypto as long as libssl itself was correctly linked, but if you want to make direct use in your program of symbols from libcrypto, then you have to explicitly link it. This is a change/intentional-regression in newer versions of binutils.

Two method for linking a object using GCC?

I've known that I should use -l option for liking objects using GCC.
that is gcc -o test test.c -L./ -lmy
But I found that "gcc -o test2 test.c libmy.so" is working, too.
When I use readelf for those two executable I can't find any difference.
Then why people use -l option for linking objects? Does it have any advantage?
Because you may have either a static or a shared version of the library in your library directory, e. g. libmy.a and libmy.so, or both of them. This is more relevant to system libraries: if you link to libraries in your local build tree, you know which version you build, static or shared, but you may not know other systems' configuration and libraries mix.
In addition to that, some platforms may have different suffixes. So it's better to specify it in a canonical way.
The main reason is, -lname will search for libname.a (or libname.so, etc.) on the library search list. You can add directories to the library search list with the -L option. It's a convenience built into the compiler driver program, making it easier to find libraries that have been installed in standard places on the system.

Resources