.dylib file not loaded while loading .so files - c

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

Related

How to fix "cannot find -lz"

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?

Dynamic linking libgit2 .so in gcc

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!

Symbols missing from Linux static library using NetBeans

I'm working on a C static library that's eventually going to be open-source, so I'm cross-compiling on Windows and Ubuntu to backstop for any portability issues.
The problem I'm having is that the symbols from one of the object files are omitted from the Linux build. When I build the library using VS2015 on Windows, all symbols are present.
I'm mostly used to developing for Windows, so I'm pretty spoiled to using an IDE for most build scenarios. On Ubuntu, I'm using NetBeans , and I'm not sure if the problem is with my understanding of gcc or if I don't have NetBeans set up correctly.
Details
Ubuntu 16.04LTS using gcc(Ubuntu) 5.4.0
NetBeans IDE 8.1 C/C++
The library consists of 3 source files and 2 header files:
queue.c --> queue implementation
memutil.c --> memory utilities
mylib.c --> main library implementation
queue.h --> included by queue.c and mylib.c
mylib.h --> header file for the static library
The mylib.h header contains the header information for the memutil.c source file, wrapped in a conditional that depends on the MEMCHECK symbol on the command line. Likewise for the code in the memutil.c source file. The MEMCHECK symbol is defined when building the library, but when I run nm on libmylib.a after the Linux build, no symbols are listed for the memutil.o object file. When i look at the mylib.lib file on Windows, all the symbols for memutil.obj are listed.
Now, if I add a stubbed out source file that just includes the mylib.h header, all of the symbols are present in the libmylib.a library. I'm guessing there's some sort of header file interaction malfunction going on, but I don't where to look to find out what it is or how to fix it. I have Google'd the snot out of this with as many different phrasings as I can think of, but no joy.
Here's the NetBeans build output, less all of the directory noise:
gcc -c -g -Wall -DMEMCHECK -MMD -MP -MF "build/queue.o.d" -o build/queue.o queue.c
gcc -c -g -Wall -DMEMCHECK -MMD -MP -MF "build/memutil.o.d" -o build/memutil.o memutil.c
gcc -c -g -Wall -DMEMCHECK -MMD -MP -MF "build/mylib.o.d" -o build/mylib.o mylib.c
ar -rv dist/Debug/GNU-Linux/libmylib.a build/queue.o build/memutil.o build/mylib.o
ar: creating dist/Debug/GNU-Linux/libmylib.a
a - build/queue.o
a - build/memutil.o
a - build/mylib.o
ranlib dist/Debug/GNU-Linux/libmylib.a
BUILD SUCCESSFUL (total time: 3s)
Stubbing in the header file inclusion can't be the fix for this, can it? It works, but it seems awfully crude. Besides, I can't really credit that it would be necessary with gcc and not necessary with VS2015.
Well, I found the solution, but I'm not marking this as the accepted answer because I'm not sure exactly why it's the solution.
I noticed the -Mxx flags on the compiler lines:
gcc -c -g -Wall -DMEMCHECK -MMD -MP -MF "build/...
So I went back to Google and found this site: Auto-Dependency Generation, which covers having Make handle the generation and tracking of build dependencies.
Then I starting combing through every single menu item in NetBeans until I found this one:
Tools->Options->C/C++->[on/off] Enable dependency checking in generated makefiles
I cleared that switch, and all of the missing symbols appeared in the library. However, the -Mxx flags were still present on the compiler lines in the build output. Now, the makefile generation for NetBeans uses about 5 separate makefile templates and 3 or 4 different XML configuration files to generate the makefile at build time, based on build configuration and target. I couldn't figure out if the auto-dependency flags were rendered inert by flipping that switch or not.
But, if I'm reading the information on the above-mentioned website correctly, those -Mxx flags are actually used by gcc in support of Make, so I'm not sure how they would have a different interpretation based on something that NetBeans did. Although, there are a LOT of substitutions in those makefile templates, and with me not being an Autoconfig/Make wizard, I may have simply missed it.
So, apparently, since none of the source files actually included the function prototypes for the memory utilities -- because they are contained in the library header file, which none of the library source files include (it's meant for inclusion by client code) -- the NetBeans dependency checker decided that those functions weren't needed in the library.

GCC have include but not library

I'm writing my own kernel for fun, and in doing so I've needed to install glibc to use the standard C libraries. However, after installing the library to the desired directory, my kernel.c program includes the stdio.h header and attempts to use fopen, however I come across this error:
kernel.c:(.text+0x238): undefined reference tofopen'`
After looking around I noticed that I don't have any actual code to all of the header files, just the header files themselves. So I went and added the -L flag to GCC to add the lib folder that was created during the compilation of glibc and what I've found out is that the lib folder has nothing of what I need.
I poked around and found that the build directory I used when compiling glibc has the .o files I'm looking for (e.g it has iofopen.o for the fopen method).
So what's going on?
If needed, the commands I am using to compile my kernel are:
#!/bin/bash
nasm -felf32 boot.asm -o boot.o
/home/noah/opt/cross/bin/i686-elf-gcc -I/home/noah/Documents/NoahOS/include/ -L/home/noah/Documents/glibc/build -c *.c -std=gnu99 -ffreestanding -Wall -Wextra
/home/noah/opt/cross/bin/i686-elf-gcc -I/home/noah/Documents/NoahOS/include/ -L/home/noah/Documents/glibc/build -T linker.ld -o noahos.bin -ffreestanding -O2 -nostdlib *.o -lgcc
First line builds the boot file, which is assembly.
Second line runs gcc on all of the C language .c files and creates their object files.
Third line links all of the files together with linker.ld and outputs the final kernel to noahos.bin which is a runnable kernel using
qemu-system-i386 -kernel noahos.bin
If needed more information can be provided. Please ask.
You are correctly compiling your kernel using -nostdlib because the kernel can't use the standard library. Why not? Because it doesn't make sense: the standard library is the interface between user programs and the kernel, so that application developers don't need to know the system call specification for your kernel, all that is required is a port of the C library.
Oh, there's the answer. You need a port of the C library to use your own system calls. Starting with glibc might not be the easiest to port (it comes with the kitchen sink).

x86_64-pc-cygwin gcc compilation error

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.

Resources