A bit better
[llpp.git] / build.sh
blob801934d96531df7a288df30d2285575e4974a895
1 #!/bin/sh
2 set -e
4 trap 'test $? -eq 0 || echo build failed' EXIT
6 date --help | grep -q GNU-date-that-actually-works-with-N && {
7 now() { date +%N; }
8 scl=1000000000.0
9 } || {
10 now() { date +%s; }
11 scl=1
13 tstart=$(now)
15 die() {
16 echo "$*" >&2
17 exit 111
20 test -n "$1" || die "usage: $0 build-directory"
22 outd=$1
23 srcd=$PWD
25 getpast() {
26 past="$1.past"
27 cur_cmd="$2"
28 key_cmd="$3"
29 test -r $past && {
30 . $past
31 test "$cmd" = "$cur_cmd" && {
32 eval "cur_key=\$($key_cmd)" || cur_key=none
33 test "$cur_key" = "$key" || dirty="$cur_key!=$key"
34 } || dirty="cmd"
35 } || dirty="initial"
38 bocaml1() {
39 s="$1"
40 o="$2"
41 eval ocamlc -depend -bytecode -one-line $incs $s | {
42 read _ _ depl
43 test -z "$depl" || {
44 for d in $(eval echo $depl); do
45 d=${d#$srcd/}
46 bocaml $d $((n+1))
47 test $? -eq 0 || dirty=transitive
48 done
51 cmd="ocamlc $incs -c -o $o $s"
52 keycmd="stat -c %Y $o $s 2>/dev/null | tr -d '\n'"
53 getpast "$o" "$cmd" "$keycmd"
54 test -n "$dirty" && {
55 printf "%*.s%s -> %s\n" $n '' \
56 "${s#$srcd/}" "${o#$outd/} [${dirty-fresh}]"
57 eval "$cmd" || die "compilation failed"
58 eval "key=\$($keycmd)"
59 printf "cmd='$cmd'\nkey='$key'\n" >$o.past
60 grep -q "$o" $outd/ordered || echo "$o" >>$outd/ordered
61 return 1
62 } || {
63 grep -q "$o" $outd/ordered || echo "$o" >>$outd/ordered
64 return 0
68 bocaml() (
69 o=$1
70 n=$2
71 wocmi="${o%.cmi}"
72 test ${wocmi%help.cmo} != ${wocmi} && {
73 s=$outd/help.ml
74 o=$outd/help.cmo
75 } || {
76 test "$o" = "$wocmi" && {
77 s=${o%.cmo}.ml
78 } || {
79 s=$wocmi.mli
81 s=$srcd/$s
82 o=$outd/$o
84 incs="-I lablGL -I $outd/lablGL -I wsi/x11 -I $outd/wsi/x11 -I $outd"
85 bocaml1 "$s" "$o" || return 1 && return 0
88 bocamlc() {
89 o=$outd/$1
90 s=$srcd/${1%.o}.c
91 mudir=$srcd/mupdf
92 muinc="-I $mudir/include -I $mudir/thirdparty/freetype/include"
93 cmd="ocamlc -ccopt \"-O2 $muinc -o $o\" $s"
94 keycmd="stat -c %Y $o 2>/dev/null"
95 getpast "$o" "$cmd" "$keycmd"
96 test -n "$dirty" && {
97 printf "%s -> %s\n" "${s#$srcd/}" "${o#$outd/} [${dirty-fresh}]"
98 eval "$cmd" || die "compilation failed"
99 eval "key=\$($keycmd)" || die "$keycmd failed"
100 printf "cmd='$cmd'\nkey='$key'\n" >$o.past
101 } || true
104 mkdir -p $outd/wsi/x11
105 mkdir -p $outd/lablGL
106 :>$outd/ordered
108 cmd="$SHELL $srcd/mkhelp.sh $srcd/KEYS >$outd/help.ml"
109 keycmd="stat -c %Y $srcd/KEYS 2>/dev/null"
110 getpast "$outd/help.ml" "$cmd" "$keycmd"
111 test -n "$dirty" && { eval $cmd || die "mkhelp failed"; }
112 eval "key=\$($keycmd)" || die "$keycmd: failed"
113 printf "cmd='$cmd'\nkey='$key'\n" >$outd/help.ml.past
115 for m in lablGL/glMisc.cmo lablGL/glTex.cmo wsi/x11/wsi.cmo main.cmo; do
116 bocaml $m 0 || true
117 done
118 bocamlc link.o
120 libs="str.cma unix.cma"
121 clibs="-lGL -lX11 -L$mudir/build/native -lmupdf -lmupdfthird -lpthread"
122 globjs=
123 for f in ml_gl ml_glarray ml_raw; do
124 bocamlc lablGL/$f.o || true
125 globjs="$globjs $outd/lablGL/$f.o"
126 done
128 ord=$(grep -v \.cmi $outd/ordered | tr "\n" " ")
129 cmd="ocamlc -custom $libs -o $outd/llpp $ord"
130 cmd="$cmd $globjs $outd/link.o -cclib \"$clibs\""
131 keycmd="stat -c %Y $outd/llpp 2>/dev/null"
132 getpast "$outd/llpp" "$cmd" "$keycmd"
133 test -n "$dirty" && {
134 eval $cmd
135 eval "key=\$($keycmd)" || die "$keycmd: failed"
136 printf "cmd='$cmd'\nkey='$key'\n" >$outd/llpp.past
137 } || echo "nothing to be done"
139 printf "took %s sec\n" $(echo "scale=3; ($(now) - $tstart) / $scl" | bc -l)