tags:

views:

142

answers:

5

I have two semi-related questions.

My first question: I can call functions in the standard library without compiling the entire library by just:

#include <stdio.h>

How would I go about doing the same thing with my header files? Just "including" my plaintext header files obviously does not work.

#include "nameofmyheader.h"

Basically, how can I create a library that other files can call?

Second question: Suppose I have a program that is split into 50 c files and a header file. What is the proper way to compile it besides:

cc main.c 1.h 1.c 2.c 3.c 4.c 5.c 6.c 7.c   /*... and so on*/

Please correct any misconceptions I am having. I'm totally lost here.

A: 

You need to create a shared library, the standard library is a shared library that is implicitly linked in your program.

Once you have your shared library you can use the .h files and just compile the program with -lyourlib wich is implicit for the libc

Create one using:

gcc -shared test.c -o libtest.so

And then compile your program like:

gcc myprogram.c -ltest -o myprogram

For your second question I advise you to use Makefiles http://www.gnu.org/software/make/

Arkaitz Jimenez
A: 

If you really want it to be as simple as just including a .h file, all of your "library" code needs to be in the .h file. However, in this scenario, someone can only include your .h file into one and only one .c file. That may be ok, depending on how someone will use your "library".

Jim Buck
A: 

You can combine several .c files to a library. Those libraries can be linked with other .c files to become the executable.

You can use a makefile to create a big project.

The makefile has a set of rules. Each rule describes the steps needed to create one piece of the program and their dependencies with other pieces or source files.

Gamecat
A: 

The standard library is already compliled and placed on your machine ready to get dynamically linked. This means that the library is dynamically loaded when needed by a program. Compare this to a static library which gets compiled INTO your program when you run the compiler/linker.

This is why you need to compile your code and not the standard library code. You could build a dynamic (shared) library yourself.

For reference, #include <stdio.h> does not IMPORT the standard library. It just allows the compile and link to see the public interface of the library (To know what functions are used, what parameters they take, what types are defined, what sizes they are, etc).

Dynamic Loading

Shared Library

You could split your files up into modules, and create shared libraries. But generally as projects get bigger you tend to need a better mechanism to build your program (and libraries). Rather than directly calling the compiler when you need to do a rebuild you should use a make program or a complete build system like the GNU Build System.

kjfletch
+12  A: 

First, you're a bit confused as to what happens with an #include. You never "compile" the standard library. The standard library is already compiled and is sitting in library files (.dll and .lib files on Windows, .a and .so on Linux). What the #include does is give you the declarations needed to link to the standard library.

The first thing to understand about #include directives is that they are very low-level. If you have programmed in Java or Python, #includes are much different from imports. Imports tell the compiler at a high level "this source file requires the use of this package" and the compiler figures out how to resolve that dependency. An #include in C directive says "take the entire contents of this file and literally paste it in right here when compiling." In particular, #include <stdio.h> brings in a file that has the forward declarations for all of the I/O functions in the standard library. Then, when you compile your code, the compiler knows how to make calls to those functions and check them for type-correctness.

Once your program is compiled, it is linked to the standard library. This means that your linker (which is automatically invoked by your compiler) will either cause your executable to make use of the shared standard library (.dll or .so), or will copy the needed parts of the static standard library (.lib or .a) into your executable. In neither case does your executable "contain" any part of the standard library that you do not use.

As for creating a library, that is a bit of a complicated topic and I will leave that to others, particularly since I don't think that's what you really want to do based on the next part of your question.

A header file is not always part of a library. It seems that what you have is multiple source files, and you want to be able to use functions from one source file in another source file. You can do that without creating a library. All you need to do is put the declarations for things foo.c that you want accessible from elsewhere into foo.h. Declarations are things like function prototypes and "extern" variable declarations. For example, if foo.c contains

int some_global;

void some_function(int a, char b)
 {
     /* Do some computation */
 }

Then in order to make these accessible from other source files, foo.h needs to contain

extern int some_global;

void some_function(int, char);

Then, you #include "foo.h" wherever you want to use some_global or some_function. Since headers can include other headers, it is usual to wrap headers in "include guards" so that declarations are not duplicated. For example, foo.h should really read:

#ifndef FOO_H
#define FOO_H

extern int some_global;

void some_function(int, char);

#endif

This means that the header will only be processed once per compilation unit (source file).

As for how to compile them, never put .h files on the compiler command line, since they should not contain any compile-able code (only declarations). In most cases it is perfectly fine to compile as

cc main.c 1.c 2.c 3.c ... [etc]

However if you have 50 source files, it is probably a lot more convenient if you use a build system. On Linux, this is a Makefile. On windows, it depends what development environment you are using. You can google for that, or ask another SO question once you specify your platform (as this question is pretty broad already).

One of the advantages of a build system is that they compile each source file independently, and then link them all together, so that when you change only one source file, only that file needs to be re-compiled (and the program re-linked) rather than having everything re-compiled including the stuff that didn't get changed. This makes a big time difference when your program gets large.

Tyler McHenry
+1 Good answer!
Avi
I wish I could +2 this. Great work. Clearly stated.
Nick Meyer
thanks for clearing that up. that was exactly the explanation i needed.
overcyn
That was very well written.
Bill