0

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?

6
  • There seems to be some confusion here. The #include of the .h file, and the linking with the static library, are separate things. #include works the same way as always, independent of any library files. Commented Dec 2, 2012 at 1:58
  • @ThomasPadron-McCarthy I do know the difference. Please see the edit above. Commented Dec 2, 2012 at 2:06
  • Ok. But as said before, the #include of the .h file, and the linking with the library file are separate things, and I don't understand why you think linking would in some magic way let you skip the #include? I'll try to write a longer explanation in an answer. Commented Dec 2, 2012 at 2:12
  • I guess because I compiled it with it. Well anyway, I did the include correctly but it still does not work for some reason. Commented Dec 2, 2012 at 2:19
  • No, you didn't compile with it. But I've tried to explain more clearly in my answer below. Commented Dec 2, 2012 at 2:39

2 Answers 2

4

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 libthreadpoolto 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.

Sign up to request clarification or add additional context in comments.

2 Comments

So when one wants to use a static library, one must have the .h file as well, and include that? Anyway, doing that does not work. Even when including #include threadpool/threadpool.h, I get errors when trying to use the functions there.
Generally, yes - to build the program the header must be available and included at compile time, the library must be available and linked in at link time. To answer questions about the errors you continue to get, we'll need information about those errors.
2

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.

2 Comments

the #include (and all #prefixed statements) are not part of the compile process itself, those are resolved prior to compiling by the preprocessor. also it is not technically required to have the type for each argument of a function in the header file ... old syntax was: foo(a,b)int a,b;{function of a and b}... with only foo(a,b); in the header, type checking was added later, but compilers will still compile the older style.
Well, it's arguable if one should call the preprocessor part of the compilation process or not. But it certainly can be viewed as a separate step, and originally even was a separate executable program.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.