How do I know the path of libraries used by ld? - linker

Say I'm building and linking my application with clang
clang -I/usr/local/include -c -o app.o main.c
clang -L/usr/local/lib -o app app.o -lfoo
How do I know where libfoo.a or libfoo.dylib is located? Is there a verbose mode?
It's possible to search /usr/lib and /usr/local/lib manually, but doing so would be too tedious when you use many libraries.

If the linker is GNU ld, pass the linker option --trace, e.g.
clang -L/usr/local/lib -o app app.o -lfoo -Wl,--trace
If the linker is Darwin mach-o ld, pass the linker option -t, e.g.
clang -L/usr/local/lib -o app app.o -lfoo -Wl,-t
The linker will then report the path of each object file, archive(member) or
dynamic library that it loads.

Related

Static link SDL2 on Linux

I am trying to statically link SDL2 on Linux, with the goal of creating a binary that doesn't require any libraries to be required on the system. I understand this will require statically linking more than just SDL2, such as SDL2's dependencies and things like libc, so help on that front would be appreciated as well. But right now I can't get SDL2 to statically link at all.
I am using GCC, and SDL 2.0.16 that I compiled and installed myself with the default configuration, which includes static libraries. I already had SDL2 installed through my package manager, so my installation went to /usr/local/include/SDL2 and /usr/local/lib.
Running /usr/local/bin/sdl2-config --cflags --static-libs gives:
-I/usr/local/include/SDL2 -D_REENTRANT
-L/usr/local/lib -lSDL2 -lm -ldl -lpthread -lrt
No amount of messing around with these flags and -static have been able to produce a binary that doesn't dynamically link to SDL2. How can I do it?
Other flags I am using for other reasons are -std=c89 -Wall -Wno-unknown-pragmas -DNDEBUG -Os -g0 -s
Being able to cross compile and do this would be great, but I understand that's a lot more complex. I've been trying to compile with zig cc as that would allow cross-compilation later, but couldn't get it to work. I was able to get a build that didn't dynamically link to SDL2, but it would segfault.
In response to comments:
Running pkg-config --static --cflags --libs /usr/local/lib/pkgconfig/sdl2.pc gives:
-I/usr/local/include/SDL2 -D_REENTRANT -L/usr/local/lib -Wl,-rpath,/usr/local/lib -Wl,--enable-new-dtags -lSDL2 -lm -ldl -lpthread -lrt
Using that creates a dynamically-linked executable, so not what I want. If I add -static I get the error:
/usr/bin/ld: /usr/local/lib/libSDL2.a(SDL_dynapi.o): in function `get_sdlapi_entry':
/home/makeworld/Software/SDL2-2.0.16/src/dynapi/SDL_dynapi.c:237: warning: Using 'dlopen' in statically linked applications requires at runtime the shared libraries from the glibc version used for linking
Thanks to #HolyBlackCat and #keltar, I have been able to statically link SDL2.
I basically just used the output of pkg-config as provided in my question, but with the addition of -Wl,-Bstatic before -lSDL2 and -Wl,-Bdynamic after it. This statically links SDL2, but dynamically links all the other libraries.
The final command is:
gcc your_code.c -o your_executable -I/usr/local/include/SDL2 -D_REENTRANT \
-L/usr/local/lib -Wl,-rpath,/usr/local/lib -Wl,--enable-new-dtags \
-Wl,-Bstatic -lSDL2 -Wl,-Bdynamic -lm -ldl -lpthread -lrt
If your build of SDL2 is installed elsewhere, just change the /usr/local/include/SDL2 and /usr/local/lib part of the command to point to where the header files and .a files are respectively.
If I figure out how to cross-compile this setup, I will update this answer.

windows crosscompiling from linux entry point not found curl_easy_cleanup could not located

I am unsure of what could be causing this as I have tried recompiling libcurl and using pre-compiled binaries.
My compiler command
x86_64-w64-mingw32-gcc -Wall -Lwin-lib -Iwin-lib -I./ -D WIN32 -D CURL_STATICLIB -mwindows ... -o win-export/SLM.exe -lm -lraylib -ltmx -lxml2 -lzlibstatic -lcurl
There aren't any compiler errors or linker errors. Is this a problem with my compiler? Or one the other libraries I am using?

How to statically link libc while keeping dynamic loading?

I want to build a statically linked application that could use dynamically loadable plugins.
The problem is that I can't get rid of the libc.so dependency.
I'm using musl libc and compiling like
/opt/cross/x86_64-linux-musl/bin/x86_64-linux-musl-gcc -Wl,-E -fPIC -I... -static-libgcc -Wl,-Bstatic -ldl -lc -lgcc source.c -o output_bin foo.a bar.a -Wl,-Bdynamic
readelf -d shows that executable depends on libc.so, so executable doesn't work on other machines without musl libc.
Is it possible to include libc symbols into elf executable and link all external plugins to elf itself, without external .so dependencies? How to achieve this?
Maybe you should try compiling it without the stdlib using -nostdlib parameter.

How to link c library in cdt eclipse

I'm trying to link libc.a library but always get cannot find -llibc. Library is in project lib folder. Below is my linker settings and workspace sreenshots.
Full compilation string:
arm-none-eabi-gcc -L"/home/kripton/Applications/ARM_workspace/Bell/lib" -T "/home/kripton/Applications/ARM_workspace/Bell/stm32f103.ld" -g3 -ggdb -O0 -mthumb -mcpu=cortex-m3 -mfix-cortex-m3-ldrd -Wl,-Map=linker.map -Wl,-cref -Wl,--gc-sections -o "Bell.elf" ./stm_startup/startup_stm32f10x_md.o ./stm_startup/system_stm32f10x.o ./src/main.o ./src/syscalls.o ./cmsis_core/core_cm3.o -llibc
Linker libraries settings:
As I said libc.a placed in project lib directory.
UPDATE
Problem solved by manually installing newlib and replace all sources and libraries with new.

Something about "-Wl,-rpath=."

I have build a shared library libC.so, and it depends on libA.so and libB.so.
And then I build test.c which using libC.so via the command:
gcc test.c -o test -fPIC -I./ -L./ -lC
It will output error, could not find some symbols which are in libA.so and libB.so.
I know, tt can be build successufully when I add the flags "-lA -lB".
However I could not understood, why can it build successfully via the following command:
gcc test.c -o test -fPIC -I./ -L./ -lC -Wl,-rpath=.
I think your libA.so and libB.so are present in the current directory.
Your providing the linking option -Wl -rpath as your current directory.
So your linker takes the libraries in the current directory and link the symbols.
It is not giving any errors because of the linker options you have specified.
The next doubt you might get is,
I have only specified the directories to search but not specified libraries.
How is the linker is taking libA.so and libB.so libraries also?
But the linker is intelligent and it thinks that you have forgot to include these interdependent libraries (You might not know about interdependency)but you have specified the path to search for all the dependent libraries. So it picks the interdependent libraries.
I think it only works for Interdependency only. All direct libraries should be specified with -l option i think.

Resources