Can someone help me to figure out this error.
I'm trying to compile a test program and it gives this error
/usr/lib/gcc/x86_64-pc-cygwin/4.8.3/../../../../x86_64-pc-cygwin/bin/ld: cannot find -ltest.
I gave correct path of lib cc test.c -I"./include" -L"./Lib" -ltest, still it is throwing error. Library is present in mentioned folder.
I tried too many things discussed over here but nothing helped me.
On Cygwin you should be able to build a library that generates the appropriate shared object with something like:
gcc -shared -o libtest.so -Wl,--out-implib,libtest.dll.a libtest.c
libtest.c would be the name of your .c file or a list of .c files used to build your library.
This should produce a libtest.dll.a and libtest.so . You use the import library to link your programs to the shared object. So you could compile your application with:
gcc test.c -I./include -LLib/ -ltest
The Lib/libtest.dll.a is a library (import library) that knows how to load the .so file at run-time.
To be more Windows like you could drop the .so suffix and use .dll. So compiling your shared object this way would work too:
gcc -shared -o libtest.dll -Wl,--out-implib,libtest.dll.a libtest.c
And then compile the client(test) as we did above:
gcc test.c -I./include -LLib/ -ltest
Because you compiled the shared object above with -o libtest.dll the import library that is created will now search for libtest.dll instead of libtest.so when your program is executed.
Please note that at run-time Windows searches your path for shared object (or dll). So you will have to move your shared object (or dll) to the directory you are running your application from; or copy your shared object (dll) to somewhere on your path; or add your ./Lib/ directory to your path.
Related
I am working on code have Zlib.h header, This header is found in my code folder, I compile this code by using
gcc -o x xx.c -lz
but I get on this
/usr/bin/ld: cannot find -lz
collect2: error: ld returned 1 exit status
This happen just with Linux that I installed in a VBox.
How to fix that.
Try installing 'zlib1g-dev'. On Ubuntu this following command will install the library.
sudo apt install zlib1g-dev
When you type gcc foo.c, you ask gcc to compile and link the given file.
1. Compilation
Compilation consist of transforming the source file into an object file.
This step need the included files, like zlib.h to be found by gcc.
This step seems to be correct on system.
NB: You can ask gcc to only do this step typing gcc -c foo.c, or better gcc -Wall -c foo.c
2. Link
Once the object files have be created, then need to be linked to create an executable file.
It's that step that failed for you: your linked can't find the already compiled functions needed by your code.
When linking with option -lz, you tell your linker "search for libz.so file to find the missing functions"
On current linux distribution, you can install package like libz-dev to install the .so file in well known places. (/lib, /usr/lib, /usr/local/lib...)
If you don't have the libz.so file installed on the library search path, you can specify where is the library to your linker.
For instance, if libz.so is if /bar/baz directory, you can type gcc foo.c /bar/baz/libz.so. The same for libz.a.
In any case, you'll need the libz.so file or at least the libz.a file
See also What's the difference between .so, .la and .a library files?
I'm running a Debian (Buster) container and my goal is to compile a small program I wrote which relies on libgit2. First, I was installing libgit2 via the libgit2-dev package and my Makefile had the following:
gcc -O2 -fpic -shared -I /usr/local/include -lgit2 -o output.so my_app.c
However, I'd rather have a "cleaner" environment and install libgit2 via the libgit-27 which, AFAIK, only installs the shared object binary instead of also including the development files like libgit2-dev does.
Using find I can find where the .so file is installed into:
$ find / -name "*git2*" -print 2>/dev/null
/usr/lib/x86_64-linux-gnu/libgit2.so.0.27.7
/usr/lib/x86_64-linux-gnu/libgit2.so.27
/usr/share/doc/libgit2-27
/var/lib/dpkg/info/libgit2-27:amd64.list
/var/lib/dpkg/info/libgit2-27:amd64.symbols
/var/lib/dpkg/info/libgit2-27:amd64.md5sums
/var/lib/dpkg/info/libgit2-27:amd64.shlibs
/var/lib/dpkg/info/libgit2-27:amd64.triggers
and I've been trying several combinations of linking this .so with gcc like:
gcc -O2 -fpic -shared -L /usr/lib/x86_64-linux-gnu/ -libgit2.so.27 -o output.so my_app.c
but so far I always get the following error:
my_app.c:1:10: fatal error: git2.h: No such file or directory
#include <git2.h>
^~~~~~~~
compilation terminated.
I understand this is a glaring lack of knowledge on how C compilation works. My two questions are:
Is it possible to compile my program by just relying on the libgit2-27 Debian Buster package instead of libgit2-dev? If not, why?
If yes, an example and explanation would be appreciated!
Supposing I have main.c main.o libheymath.so in current directory. I want to link them together to generate an executable file. I use command "g++ -o main main.o -L./ -lheymath" to realize that. But I don't know why I should indicate the library directory and name. As far as I know, when I run "./main" the system will load the shared library into memory in specific directories such as /lib and /use/lib and directories specified in LD_LIBRARY_PATH etc. but not what I have indicated. So what's the purpose of "-L./ -lheymath"?
working directory files:
main.c, main.o, libheymath.so
command:
g++ -o main main.o -L./ -lheymath
./main
-L allows to indicates a path where to look to find lib(s) at link time (it is not 'saved' in the produced executable to be reused when you will launch the executable)
-l indicates a lib you want to link with, this allows to check if some symbols are missing or not and to know the list of libs to load when you will launch the executable.
When you link the path of these libs is not saved into the executable because both executable and libs can be moved after the link (and may be installed on an other host)
Note LD_LIBRARY_PATH is used when you start an executable to find the dynamic libs, it is not used when you link objects/libs to make an executable
I wanted to use INCR in redis beyond its maximum value 9,223,372,036,854,775,807. So I write a redis module C code using gmp.h. In C code I read the value in the key (the key to be incremented) and incremented by using functions in gmp.h and then written back to the same key.
I create .o files and then .so files and it works fine in my mac. When I gave the .so file to my friend, the .so file did not load and an error came for her.
Library not loaded: /usr/local/lib/libgmp.10.dylib
I guess this happend because my friend not installed gmp in her mac
But I thought it will work. Is there any way to make it work in my friend's macbook without installing the library ?
Commands used to created .o and .so files
gcc -dynamic -fno-common -std=gnu99 -c -o mycommand.o mycommand.c
ld -o mycommand.so mycommand.o -bundle -undefined dynamic_lookup -lc -lgmp
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.