Reputation: 45
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:
#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");
...
#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
):
#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
Upvotes: 3
Views: 146
Reputation: 3104
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.
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 .
bitstream.c
with gcc -c bitstream.c
./home/you/myLibs/bitstream.o
.bitstream.h
to /usr/include/MyLib/bitstream.h
(you'll need root)#include <MyLib/bitstream.h>
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!
Upvotes: 3
Reputation: 14376
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
Upvotes: 3