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
Related
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.
I found a useful library on github for my project, after building this later I tried to use some predefined function on it. I couldn't compile my project because there is some header file missing like this one :
In file included from main.c:2:0:
ptask.h:11:19: fatal error: ptime.h: No such file or directory
I compiled my project using this command :
gcc main.c -L. -lptask
This is all the files in project folder :
libptask.a main.c ptask.h
This is the library content:
$ ar -t libptask.a
pbarrier.c.o
pmutex.c.o
ptask.c.o
ptime.c.o
rtmode.c.o
tstat.c.o
libdl.c.o
dle_timer.c.o
calibrate.c.o
Do I need to add all the headers of this files or just link the lib when compiling ?
Your main.c #include-s ptask.h which in turn #include-s ptime.h. Having compiled static libs alone is not enough (that's the linker's job), you still need to have all used header files (which is the compiler's job), both the ones you use and their dependencies, recursively applicable.
Normally you need to be sure that the header files are in your "include path", something that a lot of compilers define with -I as a command-line option. You'll need to include the source directory of that library, or if it has a make install option, then the place where they got installed.
regarding:
gcc main.c -L. -lptask
this is performing the compile step and the link step in one command.
It is also not enabling the warnings, which should always be enabled during the compile step.
Suggest something similar to the following to compile
gcc -Wall -Wextra -Wconversion -pedantic -std=gnu11 -g -c main.c -o main.o -I.
and when you have fixed all the warnings, then use something similar to the following to link
gcc main.o -o main -L. -lptask
I'm trying to use a C library called quirc in my C project. So far, I have generated a libquirc.dylib.1.0 by modifying the Makefile which was using Linux .so files.
quirc/helloquirc.c
#include <quirc.h>
#include <stdio.h>
int main() {
struct quirc *qr;
qr = quirc_new();
if (!qr) {
printf("Failed to allocate memory");
}
quirc_destroy(qr);
return 0;
}
I've created the above source file at the root of the repository. I'm using the following command to compile it:
gcc helloquirc.c -lquirc -L. -Ilib -o helloquirc
To my understanding the -l flag specifies the name of the dynamic library, the -L flag specifies the location of the dynamic library, the -I flag specifies the location of the header files, and -o specifies the name of the executable.
When I run this command I get the following error:
ld: library not found for -lquirc
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I changed the Makefile by using this line
.PHONY: libquirc.dylib
libquirc.dylib: libquirc.$(LIB_VERSION).dylib
libquirc.$(LIB_VERSION).dylib: $(LIB_OBJ)
$(CC) -shared -dynamiclib -o $# $(LIB_OBJ) $(LDFLAGS) -lm
and changing other instances of .so.$(LIB_VERSION) to .$(LIB_VERSION).dylib
Something is wrong with the way quirc was built. The correct library name would be something like libquirc.1.0.dylib with a symlink named libquirc.dylib.
It looks like quirc has a handwritten makefile instead of using something sensible like gyp or cmake. Handwritten makefiles are just fine as long as you're not trying to build shared libraries on multiple platforms.
However, if you are just compiling it yourself, you may find things simpler if you just use a static library instead. There is no point in having a shared library if you are not sharing it with anybody (if no other programs are using the same exact copy of libquirc).
I have three C files in total. One is a header [.h] file, two are source [.c] files.
The .h file is called encryption.h and the corresponding source file is encryption.c. The encryption.c has logic, but no main() function. My second c file is called main.c. There I have the main() function that calls methods from encryption.c.
I am compiling these files within terminal on Mac OSx. I am confused on how to compile this, I have tried the following:
gcc -c main.c
gcc -c encryption.c
gcc -c encryption.h
gcc main.o encryption.o encryption.g.gch -o encrypt
This doesn't seem to work though, it says I have a precompiled-header already. I tried finding the answer online, I know it has to be simple, but I haven't had much luck. What is the issue here?
Don't compile the header file. Header files are meant to be included to the source files (using #include directive, in c). Just compile the source files and link them together. Something like
gcc -c main.c
gcc -c encryption.c
gcc main.o encryption.o -o encrypt
or, for shorthand,
gcc main.c encryption.c -o encrypt
Note: If you're bothered about the presence (or absence) of header files while compilation, check the pre-processed output of each source files using gcc -E option.
I made a static library.
This not have error, library file too.
So, I tried use that library.
gcc -o hash_gen main.c -L../ -lhashbundle
Library file exist in that directory ../, library file name is libhashbundle.a.
So, I thought not have problem in this command.
but I tried compile with gcc, but gcc print this error.
main.c:4:10: fatal error: 'hash.h' file not found
#include "hash.h"
^
I don't understand. I made library make, and this is Makefile
all : libhashbundle.a
libhashbundle.a : hash.o
ar rscv libhashbundle.a hash.o
hash.o : src/hash.c
gcc -c src/hash.c
clean:
rm -rf hash.o
I thought this code many times, but I didn't found error.
and this is directory tree
tree
Makefile
libhashbundle.a
|src
|hash.c
|hash.h
|test
|main.c
So, I ask to you.
How could solve this problem?
You only specified a library search path (-L).
If you want a header search path, you need to use -I.
gcc -o hash_gen main.c -I.. -L.. -lhashbundle
The problem is the fact that you're running your build from your "root" directory, not from /src/. So when the compiler sees #include "hash.h" it will try to open the file in the current directory, which will be / rather than /src/ (where the files are).
To fix this, just add your source directory to the include search paths using -Isrc:
gcc -o hash_gen main.c -Isrc -lhashbundle
Note that I omitted -L since the library file is in your current working directory and should be found there anyway.