If you are trying to understand dynamic linking, this question is likely to be of interest.
One of the answers to that question provides a wonderful example of creating and using a dynamic library. Based on it, I some simple files:
main.c:
extern void someFunction (int x);
int main (int argc, char** argv ) {
someFunction(666);
}
mylibrary.c:
#include <stdio.h>
void someFunction (int x) {
printf ("\nsomeFunction called with x=%d\n", x);
}
makefile:
main: mylibrary.c main.c
gcc -c mylibrary.c
gcc -dynamiclib -current_version 1.0 mylibrary.o -o libmylibrary.dylib
gcc -c main.c
gcc -v main.o ./libmylibrary.dylib -o main
clean:
rm *.o
rm main
rm *.dylib
So far, everything works great. If I make and then enter ./main at the command prompt, I see the expected output:
someFunction called with x=666
Now, I want to mix things up a little. I've created a directory hidelib, which is a subdirectory of my main directory. And I'm adding one line to my makefile:
main: mylibrary.c main.c
gcc -c mylibrary.c
gcc -dynamiclib -current_version 1.0 mylibrary.o -o libmylibrary.dylib
gcc -c main.c
mv libmylibrary.dylib hidelib # this is the new line
clean:
rm *.o
rm main
rm hidelib/*.*
Now, I want to add another line to the makefile so it will find libmylibrary.dylib in the hidelib subdirectory. I want to be able to run ./main in the same way. How can I do that?
EDIT: Thanks for the response. Having lots of options is wonderful, but a beginner just wants one concrete option that works. Here is what I am trying for the last line, but clearly I don't understand something. The makefile executes without errors, but at runtime it says "library not found."
gcc main.o -rpath,'$$ORIGIN/hidelib' -lmylibrary -o main
Dynamic libraries are linked during the execution of the final executable. Only the name of the dynamic library is placed in the final executable. The actual linking happens during runtime, when both executable and library are placed in the main memory.
Where do DYLIB files go on a Mac? The standard locations for dynamic libraries are ~/lib, /usr/local/lib, and /usr/lib.
When you want to “link a static library with dynamic library”, you really want to include the symbols defined in the static library as a part of the dynamic library, so that the run-time linker gets the symbols when it is loading the dynamic library.
One concrete option that works would be to set the install_name
flag when linking the .dylib
.
gcc -dynamiclib -install_name '$(CURDIR)/hidelib/libmylibrary.dylib' -current_version 1.0 mylibrary.o -o libmylibrary.dylib
Then you can just link to the library normally:
gcc main.o -L '$(CURDIR)/hidelib' -lmylibrary -o main
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With