Compiling .c source file and .so dynamic library together - c

I have been trying to compile a C source file (driver.c) with a main method with a dynamic library (libhello.so) file that has all the implementations of the functions used in the main method.
I make the .so file with
gcc -shared -o libhello.so -fPIC hello.c
It compiles fine and returns the file in the directory as expected.
Then I try to compile the driver.c file with the dynamic library libhello.so with
gcc driver.c libhello.so -o driver
It compiles without complaint and the issue happens when I try to run the executable "driver". I get the follwing error:
./driver: error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory
I'm confused because the file is literally right there in the directory of which it is being compiled in. Can someone explain this for me?

Actually you do not dynamically link with libhello.so. You need -l option.
-lhello
You can check dependencies with ldd driver (your exec).

regarding:
gcc driver.c libhello.so -o driver
is not correct.
It should be similar to:
gcc driver.c -o driver -L. -lhello
of course, there should be a header file that contains all the prototypes, etc for the library libhello.so
That header file typically would be named: hello.h so the final compile+link statement would be:
gcc driver.c -o driver -I. -L. -lhello <<< edited
I made a misstate, The last line, the '-I' parameter should list the directory for the header file, not the header file name

Related

How to run an executable in C using a linker

Essentially I have
header.h, tree.c, main.c, and list.c
Can someone tell me how to execute this in my vi terminal. I know to run a solo c file it's gcc list.c ...., but I need these linked and the header included. I just don't understand the format for running them all together as an executable with a linker. I've included header in all the files, but main relies on list and tree, and vice versa.
Any help trying to compile and run these with gcc in the terminal would be a big help. Whenever I try, it keeps running them separately and I get a bunch of errors.
You can compile (not run) and link these files into an executable in one step by passing each of the .c files to gcc together and using the -o option to give the name of the executable:
gcc -o myprogram tree.c list.c main.c
Or you can compile each of them to object files using -c:
gcc -c tree.c
gcc -c list.c
gcc -c main.c
And then link the resulting object files:
gcc -o myprogram tree.o list.o main.o

Why doesn't putting my own C library file into ld search path work?

Currently I have two files
main.c
libxxx.a
main.c references some functions defined in the source code of a relocatable object file in libxxx.a.
Now the following command successfully compiles main.c and links it to libxxx.a:
gcc -o prog main.c libxxx.a
but if I put libxxx.a into one of the search paths of ld, the same directory with libc.a,
gcc -o prog main.c
just doesn't work. It seems that ld fails to find this archive file when searching in the directory. Can someone tell me why this happens?
but if I put libxxx.a into one of the search paths of lb linker, the same directory with libc.a,
gcc -o prog main.c
just doesn't work.
That is expected and desired: you wouldn't want every program you write to link against every library that is installed in the system search path. What you want is:
gcc -o prog main.c -lxxx
That is: copying the library into /usr/lib allows the linker to find it without any extra search arguments, but you still must tell the linker that you want to link against libxxx.

GCC shared library linked but header file in library not found

So I have some trouble using shared libraries in combination with GCC.
I'm quite new to this so that's why I came to ask it here. I was unable to find a question on stack overflow that helps me with mine (maybe i overlooked one). But first something about my setup and what I'm trying to accomplish.
So I have these two libraries that are development parallel to each other. One is named liblinkedlist, which contains the linkedlist implementation in C and the other is named libgraph, containing a graph implementation in C. Both are put in the following folder structure:
<root>
+---graph_lib(folder)
+---build(folder)
+---src(folder)
+---makefile(file)
+---linkedlist_lib
+---build(folder)
+---src(folder)
+---makefile(file)
Each src folder contains the source files (linkedlist.h and .c for liblinkedlist and graph.h and .c for libgraph)
In each build folder the .o and .so files created from the header files are stored.
Now the problem is that I want to use the liblinkedlist.so in /linkedlist_lib/build/ in my graph library. While compiling the libraries everything seems to go well. But when I try to use it in combination with including a header file (which is inside the linkedlist library), I get the message that it could not be found.
My compile commands are the following:
For the liblinkedlist:
gcc -fpic -c src/linkedlist.c -o build/linkedlist.o
gcc -shared -o build/liblinkedlist.so build/linkedlist.o
And for the libgraph wich uses the liblinkedlist:
gcc -fpic -c src/libgraph.c -o build/libgraph.o
gcc -fpic -c src/graph.c -o build/graph.o
gcc -L../linkedlist_lib/build/ -o build/libgraph build/libgraph.o build/graph.o -llinkedlist
These are the command and errors I get when using the header file:
gcc -fpic -c src/libgraph.c -o build/libgraph.o
In file included from src/libgraph.c:2:0:
src/graph.h:4:24: fatal error: linkedlist.h: File or folder does not exist
#include "linkedlist.h"
^
compilation terminated.
make: *** [build/libgraph.o] Fout 1
Any ideas on how to fix this problem, am I doing something wrong here?
Thanks in advance

How to link and compile with .so file in Linux

I am having .c and .so file. I tried by using the following compilation: gcc main.c -ldl. In that .c file i linked to .so file through dlsym(). How to compile using .so file with .c.
Probably you can do this:
when linking do:
g++ -o prog prog.o -ldllname
If libdllname.so is not in the system directory then add its directory to the library path:
g++ -o prog prog.o -L/path/to/my/library/folder -ldllname
This is based on your further comments. First guard the declarations of your header file.
#ifndef HEADER_PROTECT
#define HEADER_PROTECT
---------- Here is the content of header
#endif
Next, check in your code, are you defining multiple definitions. Or are you re-defining the standard functions again? Can you please post your code to guide you better?
Looks like you have re-defined Close_Comm(), can you check it? Error says that the definition is there in main.c also.
The following is the general way to compile shared object and link it.
To compile shared objects.
-g : for debug information
fPIC: for position independent code
$gcc -fPIC -g myfile
The following will create the shared object libmyfile.so
$gcc -shared -o libymyfile.so myfile.o
Now,In order to link it with your main.c.
I assume that the libmyfile.so is in your current path, thus -L./
$gcc main.c -o main.out -L./ -lmyfile
Now, you need to export the LD_LIBRARY_PATH on the bash; in order to execute the binary.
$LD_LIBRARAY_PATH=$LD_LIBRARAY_PATH:./
$./main.out
The dlsym is to load the symbol from the shared object at the run-time. If you want to load the shared object at run time, this can be used. The following is one of the example of dlsym Hack the standard function in library and call the native library function afterwards
dlsym() is used to find a symbol in an open library file.
you first need to use dlopen() in order to open the file, and only then use dlsym()

Compiling multiple C files with gcc

I have two files, main.o and modules.o, and I'm trying to compile them so that main.o can call functions in modules.o. I was explicitly told not to try #include module.o. I really don't know what I should be doing instead. I tried a few different versions of gcc (such as gcc -x c driver main.o modules.o), but nothing I get works: the compiler continuously returns
error: called object is not a function
The .o files are my source code files (I was instructed to put my source code in files with extension .o.) What do I do to compile this?
If you have your two source files, you can compile them into object files without linking, as so:
gcc main.c -o main.o -c
gcc module.c -o module.o -c
where the -c flag tells the compiler to stop after the compilation phase, without linking. Then, you can link your two object files as so:
gcc -o myprog main.o module.o
This is all perfectly normal behavior, you'll usually get your makefile to compile things separately and link them at the end, so you don't have to recompile every single source file every time you change one of them.
Talking about main.o "calling functions in" module.o is perfectly fine, but an .o file is not a source file, it's a compiled object file. If "put my source code in files with extension .o" actually meant "compile my source code into files with extension .o" then the situation would make a whole lot more sense.
You should define the functions that you want to call from modules.c into main.c into a header file, let us say modules.h, and include that header file in main.c. Once you have the header file, please compile both of the files together: gcc main.c modules.c -o output
Two additional notes. First, modules.o is an object file and it should not be included in a C source file. Second, we cannot have a C file have a .o extension. You should actually get an error when compiling a .o file. Something like:
$ cat t.o
int main() {
int x = 1;
return 0;
}
$
$ gcc t.o
ld: warning: in t.o, file is not of required architecture
Undefined symbols:
"_main", referenced from:
start in crt1.10.6.o
ld: symbol(s) not found
collect2: ld returned 1 exit status
$
program: main.o
gcc -o main main.c anotherSource.c
This works for me.
You should be including .h files which are "headers". So if your main file is using modules then you should include module's header file.

Resources