Q:

C header and source file confusion

I wrote myself a littly module I want to reuse. I got my header file bitstream.h with a struct and function declarations and bitstream.c with the implementations. Now I'd like to use this in my other programs, but without manually compiling bitstream.c every time, like you don't have to compile stdio.h every time you use it, but I don't get it to work. My files look like this:
bitstream.c
#include "bitstream.h"
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

bit_stream_t *fbit_stream(const char *path) {
    FILE *f;

    /* open file for reading */
    f = fopen(path, "rb");

    ...

bitstream.h
#ifndef BITSTREAM_H
#define BITSTREAM_H

#define EOS 0x0a

typedef struct {
    int size;
    int i_byte;
    unsigned char i_bit;
    unsigned char current_bit;
    unsigned char *bytes;
} bit_stream_t;

extern bit_stream_t *fbit_stream(const char *path);
extern unsigned char bit_stream_next(bit_stream_t *bs);
extern void bit_stream_close(bit_stream_t *bs);
extern void print_bit_stream(bit_stream_t *bs);

#endif

I put these two files into /usr/local/include (I'm on a Linux machine) and now I'd like to use this in main.c (somewhere else, e.g. /home/foo/main.c):
main.c
#include <bitstream.h>
#include <stdio.h>

int main(int argc, const char *argv[]) {
    if (argc != 2) {
        printf("Need 1 argument!\n");
        return 1;
    }

    bit_stream_t *my_bs;
    my_bs = fbit_stream(argv[1]);

    while (my_bs -> current_bit != EOS) {
        printf("%d", my_bs -> current_bit);
        bit_stream_next(my_bs);
    }

    bit_stream_close(my_bs);
    printf("\n");
    return 0;
}

When I try gcc -Wall -o main.o main.c I get
/tmp/ccgdq66W.o: In function `main':
main.c:(.text+0x35): Undefined reference to `fbit_stream'
main.c:(.text+0x63): Undefined reference to `bit_stream_next'
main.c:(.text+0x7b): Undefined reference to `bit_stream_close'
collect2: error: ld returned 1 exit status

What am I doing wrong? Thanks in advance for any help!
smuecke

A:

compile bitstream.c to create bitstream.o
gcc -Wall -c bitstream.c

compile main.c and bitstream.o to create main (or main.exe if on winX)
gcc -Wall -o main main.c bitstream.o

A:

The reason you don't need to "compile" stdio.h every time is that it's implementations (and a lot more) are already compiled and live at GLibC. That is, glibc is a library (a dynamic one) and GCC links your programs to it everytime you compile them. You can check that by running:
ldd hello

assuming hello is a simple Hello World! program that uses printf, for instance. And you'd get something like:
linux-vdso.so.1 =>  (0x00007fff5f98d000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f7e985b2000)
/lib64/ld-linux-x86-64.so.2 (0x00007f7e98977000)

See the line 2: libc.so.6, that's your GNU C Library, and that's the reason you don't "compile" stdio.h every time you use it.

General Case
What you want to do is implement your own library. So, in order to do that, you can do several things.

You create a directory under /usr/include called MyLib and put all your headers there. This way you can include your files using #include <MyLib/myHeader.h>.

Method 1: You compile your implementation myImp.c into an object file and put that object in a folder, /my/libs/path/myImp.o and every time you want to use, you compile with:
gcc -o prog prog.c /my/libs/path/myImp.o
Note: prog.c must #include <MyLibs/myHeader.h>.

Method 2: You can make an archive with the utility ar and have all your libraries in it. Check it's manual here. Every time you want to use something from your library, you link it with the .a library.

Method 3: You can make a dynamic library, which will decrease the size of your binaries (linking .o and ar libraries is static linking, which means larger binary sizes). You can do that using the -fPIC (Position Independent Code) gcc flag and some other small things. I'll link some resources .

Your specific case

Compile bitstream.c with gcc -c bitstream.c.
Put that file in /home/you/myLibs/bitstream.o.
Copy the bitstream.h to /usr/include/MyLib/bitstream.h (you'll need root)
Include that with #include <MyLib/bitstream.h>
Compile your program with: gcc -o main main.c ~/myLibs/bitstream.o.

Although this is far from good, this will do what you want. I suggest you read up on how to organize your own libraries and more, check out Rusty Russel's CCAN Library, pretty good starting point on how to build C libraries.
I really recommend checking out CCAN!

Resources

Static, Shared Dynamic and Loadable Linux Libraries
Shared libraries with GCC on Linux
GNU C Library Manual
How to Build Your Own C Library

