Thursday, February 20, 2020

C: Have fun compiling

When I write some small C program I usually put everything in a single main.c file and to compile I just:

gcc -O3 main.c -o program_name_here

I will use the catimage program which reads an image and prints it in the terminal.

Now lets be civil and put the compile command into a Makefile:

catimage:
    gcc -O3 -lm main.c -o catimage

I also like to run a recompile on file change loop:

echo main.c | entr make

Now, a dependency. To read the images I use the stb_image, which is an awesome lib so they only I need is a single "header" file stb_image.h and two # lines to include it.

Simpler solution: Download a copy of the stb_image.h and handle it as the rest of the source code. This is a very good solution, however lets have some fun.

To compile we need the file, so lets just download it:

stb_image.h:
    wget https://raw.githubusercontent.com/nothings/stb/master/stb_image.h

catimage: stb_image.h
    gcc -O3 -lm main.c -o catimage

The stb_image.h takes some seconds to compile... the loop is too slow... I will not touch the library so lets wrap it in a image.c file and compile it once:

image.o: stb_image.h
    gcc -O3 -c image.c

stb_image.h:
    wget https://raw.githubusercontent.com/nothings/stb/master/stb_image.h

Where the image.c:

// image.c

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

unsigned char* read_image(FILE* file, ...) {
    return call_to_the_lib(...) 
}

Now we need a header image.h to use it in the main.c. No we don't, its just one function:

// main.c

// #include "image.c"
unsigned char* read_image(FILE*, ...);

Put all together:

catimage: image.o
    gcc -O3 -lm image.o main.c -o catimage

First build: download stb_image.h (slow), compile image.c (slow), compile and link main.c (instant)
Rest of the builds: compile and link main.c (instant)



done_