Wednesday, June 16th, 2021 build techniques • 218w

 Usually when things/files are packaged from simple files to single monstrosity, you no longer have the ability to ls/dir to lookup what things/files exist.

An example is a Java jar, where to list for example all the packaged files you either cannot or you need to open a zip stream and figure out yourself.

Also in Java and other languages with limited introspection you cannot for example list all the classes that implement the interface X.


Create a script than generates all the information you want.

Put that script in the build/compile process.

Include the file in the project.

Write some code to parse the file.

Example of listing all the inheritance properties by finding all the extends keyword:

grep -hr extends | sed -E 's/.*class (\w+) extends (\w+) .*/\2 -> \1/'
Parent -> Child1
Parent -> Child2

No need to say again and again "This is not supported, I cannot do it", supported yourself, you are a damn programmer! 


Monday, February 24th, 2020 build c code make makefile • 284w
And here we are:

} else {
    // TODO print the --help text

On ho... where to start... Lets start by making a simple plain text file and write all the things there. Now we have a help.txt.

The easiest solution would be to just read the help.txt file and print it at runtime, but then we need to package the extra help.txt file and also is "slow".

Could we somehow just pasted in? Yes but then we have to add quotes and handle special characters and half of our main.c file will be strings.

xxd. Oh! What is that? If you run:

xxd -i help.txt

We get this very readable c-string

unsigned char help[] = {
  0x63, 0x61, 0x74, 0x69, 0x6d, 0x61, 0x67, 0x65, 0x3a, 0x20, 0x75, 0x6e,
  0x6b, 0x6e, 0x6f, 0x77, 0x6e, 0x20, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
  0x3a, 0x20, 0x25, 0x63, 0x0a, 0x0a, 0x55, 0x73, 0x61, 0x67, 0x65, 0x3a,

Seems good. Does it matter that is so readable, not really its just a build intermediate file. Lets add it to the Makefile with all the other build intermediate files:

    xxd -i help > help.c

Now, how about a include in the middle of nowhere:

} else {
    #include "help.c"

EDIT: xxd does not add a null character at the end...

Thursday, February 20th, 2020 build c code make makefile • 438w
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:

    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:


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


Where the image.c:

// image.c

#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)