Reputation: 21019
I followed the following tutorials to create a static library.
http://tldp.org/HOWTO/Program-Library-HOWTO/static-libraries.html
http://www.adp-gmbh.ch/cpp/gcc/create_lib.html
http://www.cs.dartmouth.edu/~campbell/cs50/buildlib.html
I generated a static library in C using the ar
tool. The library is from a different directory. I am generating the library properly, and I'm using it to compile with my program as follows:
gcc -lpthreads main.c -o server -L thread-pool -lthreadpool
The library under the current directory is called thread-pool
which contains libthreadpool.a
.
According to the tutorials, I need to include my .h
file as follows in main.c
: #include "threadpool.h"
. GCC is throwing an error saying threadpool.h
is not found. That is obvious since it's in a different directory.
When I include is as: #include threadpool/threadpool.h"
it compiles but doesn't actually work. It still does not recognise the functions. I'm not sure why this is happening. I thought when compiling a static library, you do not need to actually send the .h
file or any source as a matter of fact.
What is the issue here? How can I overcome this?
EDIT:
I know .h files are not the same as static libraries. I'm not sure why what I said above make it seem as if I'm confused between both.
Anyway, so when one uses a static library, does it mean we also need the .h
file and include it into the source, and not just compile the program with the static library?
Upvotes: 0
Views: 1854
Reputation: 340208
The library and the header are two different (though related) things. You could have also solved your problem with an option to the compiler, giving the compiler an additional directory to look for headers in:
gcc -lpthreads -I threadpool main.c -o server -L thread-pool -lthreadpool
Since your threadpool
library likely depends on libpthread
, you may need to change the compiler command line so that libpthreads
comes after libthreadpool
to avoid problems linking:
gcc -I threadpool main.c -o server -L thread-pool -lthreadpool -lpthreads
Actually, the preferred option is to use the -pthread
option which ensures the pthread library is appropriately linked in and that any other compiler configuration that is necessary for thread support is done (the order of the -pthread
option doesn't seem to matter):
gcc -pthread -I threadpool main.c -o server -L thread-pool -lthreadpool
It is also a good idea to list libraries (e.g. -lxyz
) after any object files, not before them. On some systems, it will work both ways; on all known systems, listing the libraries after the object files always works.
Upvotes: 4
Reputation: 27632
As Michael Burr said, the #include of the .h file, and the linking with the library file, are two different (but related) things.
When you build a C program that consists of several parts, such as several .c source files, or libraries, the process is done in two steps. First the individual source .c files are compiled, that is, translated from the C source to modules of executable machine instructions. Then all the modules and libraries needed for the program are linked together, building the executable file.
The difference between static and dynamic linking is just when the linking is done. Conceptually they are the same thing, but static linking (with a static library) is done in advance, forming an executable file that can be run at a later time, and dynamic linking is done immediately before execution.
The type of linking (static or dynamic) doesn't at all affect the compilation step.
During compilation of an individual source file, the compiler needs to generate code for the calls to the library functions. For example, if a library contains a function f that takes a double as argument, and the source file contains the code f(7), the compiler needs to know that there is a function called f, and that it expects a double as argument, so the compiler can generate code that converts the integer 7 to a double, before actually calling the function f.
This is done by putting function declarations in a .h file, which is then included in your .c source file. For example, that declaration might look like this:
void f(double);
This makes the compiler able to generate the correct code, and also to give the correct warnings and error messages if there is something wrong.
The library, on the other hand, contains the compiled function definition, which is the actual code for the function that does something.
Note that the compilation step has very little to do with the library file, and nothing to do with the difference between static or dynamic linking. To be able to #include the .h file, the compiler needs to know where to find the .h file. That may be in a completely different place from the actual library file. The library file doesn't even have to be present on the same computer, or even exist at all. When the #include is performed, the actual functions in the library might not have been written yet.
One source of confusion could be that the gcc command,
gcc -lpthreads main.c -o server -L thread-pool -lthreadpool
looks like it performs both compilation and linking. It does, but that is just for convenience, and behind the scenes it is still done in two separate steps.
Upvotes: 2