2 # YES, THIS NEEDS BASH, NOT /bin/sh (e.g. for <<<).
4 # Copyright (2013) Jann Horn <jann@thejh.net>
5 # This code is licensed under the AGPLv3.
7 # -f for files with weird names
8 # -u for coding mistakes (or against, to be precise)
9 # -e and -o pipefail so that we don't have to spam the code with error handling
10 set -f -u -e -o pipefail
12 # flags for the build - adjust for your needs
13 # delete all the generated stuff afterwards (with `rm -r gen`)
15 CFLAGS='-O3 -Wall -Werror -fPIC -std=c99 -march=native'
17 # create build environment if it doesn't exist yet
18 mkdir -p gen # contains all generated files
19 mkdir -p gen/realc # source files, with our preprocessing applied
20 mkdir -p gen/realc_preprocessed # source files, preprocessed by the C compiler
21 mkdir -p gen/chash # hashes of the preprocessed C files used to generate files in gen/obj
22 mkdir -p gen/obj # object files
24 echo "welcome. your friendly compiler will be \"$CC\" today." >&2
25 echo "going ahead with CFLAGS=\"$CFLAGS\"..." >&2
28 for source_file in $(ls|grep '\.c$'); do
29 echo "extracting header data from $source_file..." >&2
30 source_name="$(sed 's|\.c$||' <<< "$source_file")"
31 echo "/* ----======== $source_name ========---- */"
34 sed 's|^PUBLIC_FN \(.*\){|KEEPLINE \1;|g' |
35 sed 's|^PUBLIC_CONST |KEEPLINE #define |g' |
36 sed 's|^HEADER |KEEPLINE |g' |
44 # preprocess all source files
45 for source_file in $(ls|grep '\.c$'); do
46 echo "handling source file $source_file..." >&2
47 source_name="$(sed 's|\.c$||' <<< "$source_file")"
49 # do our own preprocessing
50 echo '#include "../jh.h"' > "gen/realc/$source_name.c"
53 grep -v '^PUBLIC_CONST ' |
54 sed 's|^PUBLIC_FN ||g' |
56 cat >> "gen/realc/$source_name.c"
57 if [ $? -ne 0 ]; then exit 1; fi
59 # do the normal C preprocessing
60 echo 'preprocessing...' >&2
61 $CC -E "gen/realc/$source_name.c" > "gen/realc_preprocessed/$source_name.i"
63 # compile if there have been changes since the last time
64 echo -n 'checking sha checksum... ' >&2
65 file_hash="$(shasum "gen/realc_preprocessed/$source_name.i" | cut -d' ' -f1)"
66 # drop errors: that file might well be missing
68 last_file_hash="$(cat "gen/chash/$source_name" 2>/dev/null)"
70 if [ "$file_hash" = "$last_file_hash" ]; then
71 echo 'unchanged, will not compile again' >&2
73 echo 'changed – recompiling.' >&2
74 $CC $CFLAGS -c -o "gen/obj/$source_name.o" "gen/realc_preprocessed/$source_name.i"
75 echo "$file_hash" > "gen/chash/$source_name"
81 $CC -shared -Wl,-soname,libjh.so -o ../libjh.so $(ls)