gcc linker not automatically including dependency libraries - c

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.

Related

How can I use libc_nano with Clang?

I'm exploring using clang as the compiler for ARM embedded development. As clang doesn't have an equivalent of .spec files, I'm having trouble convincing clang to link against libc_nano. How could I either tell clang to not link against any libraries by default so I can specify the correct library, or rewrite the -lc command to -lc_nano?
The command I'm trying to run is:
clang -target arm-none-eabi -mcpu=cortex-a5 -mfpu=neon-vfpv4 -mfloat-abi=hard -march=armv7-a main.c
Currently I get this error message:
/usr/lib/llvm-6.0/bin/ld.lld: error: unable to find library -lc
EDIT: I've noticed that clang has a -fno-autolink which according to the help text: Disable generation of linker directives for automatic library linking. However it doesn't seem to do anything?
EDIT2: I'm aware I could abuse symlinks to achieve this. I would like to avoid symlinks in this case as it can make the build system brittle.
Upon further google-fu and grep-fu, it turns out the answer was staring at me the entire time. Clang has a -nodefaultlibs that does the trick and prevents default linker directives. Although strangely it wasn't documented in --help.
You can build fake libc.a without any functions inside and use it together with libc_nano.

C - Compile with dependencies included

I have some code which I want to run on a machine which I do not have root access to.
That machine does not have some of the libraries needed to run this code.
Is there any way to include all dependencies when I compile? I realize the resultant file may be quite large.
What you're looking for is static compiling. Performing static compilation includes all of the libraries into the executable itself, so you don't have to worry as much about dependency chains on a specific system, distribution, etc.
You can do this with:
gcc -Wl,-Bstatic -llib1 -llib2 file.c
The -Wl passes the flags following to the linker, -Bstatic tells it to link static if possible, and then lib1, lib2, are the libs you intend to link.
Alternatively, try:
gcc -static file.c
The compilation will still need to match the architecture of the non-privileged system. And you need to have the static libraries installed on the compiling system (lib.a)
If compiled properly, it should show "not a dynamic executable" when you run:
ldd a.out

How to created a shared library (dylib) using automake that JNI/JNA can use?

How do I convince LibTools to generate a library identical to what gcc does automatically?
This works if I do things explicitly:
gcc -o libclique.dylib -shared disc.c phylip.c Slist.c clique.c
cp libclique.dylib [JavaTestDir]/libclique.dylib
But if I do:
Makefile libclique.la (which is what automake generates)
cp .libs/libclique.1.dylib [JavaTestDir]/libclique.dylib
Java finds the library but can't find the entry point.
I read the "How to create a shared library (.so) in an automake script?" thread and it helped a lot. I got the dylib created with a -shared flag (according to the generated Makefile). But when I try to use it from Java Native Access I get a "symbol not found" error.
Looking at the libclique.la that is generated by Makefile it doesn't seem to have any critical information in it, just looks to be link overloads and moving things around for the convenience of subsequent C/C++ compiler steps (which I don't have), so I would expect libclique.1.dylib to be a functioning dynamic library.
I'm guessing that is where I'm going wrong, but, given that JNA links directly to a dylib and is not compiled with it (per the example in the discussion cited above), it seems all the subsequent compilation steps described in the LibTools manual are moot.
Note: I'm testing on a Mac, but I'm going to have to do this on Windows and Linux machines also, which is why I'm trying to put this into Automake.
Note2: I'm using Eclipse for my Java development and, yes, I did import the dylib.
Thanks
You should be building a plugin and in particular pass
libclique_la_LDFLAGS = -avoid-version -module -shared -export-dynamic
This way you tell libtool you want a dynamically loadable module rather than a shared library (which for ELF are the same thing, but for Mach-O are not.)

Link glibc statically but some other library dynamically with GCC

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.

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