Add U+2192
[llpp.git] / build.bash
blob27ab25fa50b6cc9812a8f05aba61cf85341d2be1
1 #!/bin/bash
2 set -eu
4 test "$(uname)" = Darwin && {
5 darwin=true
6 wsi="wsi/osx"
7 } || {
8 darwin=false
9 wsi="wsi/x11"
12 now() { echo "print_float @@ Unix.gettimeofday ()" | ocaml unix.cma -stdin; }
14 tstart=$(now)
15 vecho() { ${vecho-:} "$*"; }
16 digest() { sum $*; }
18 partmsg() {
19 test $? -eq 0 && msg="ok" || msg="ko"
20 echo "$msg $(echo "scale=3; $(now) - $tstart" | bc -l) sec"
23 die() {
24 echo "$*" >&2
25 exit 111
28 trap 'partmsg' EXIT
30 test $(ocamlc -version | { IFS=. read a b _; echo $a$b; }) -lt 406 && {
31 die OCaml version 4.06+ is required
34 test -n "${1-}" || die "usage: $0 build-directory"
36 outd="$1"
37 srcd="$(dirname $0)"
38 mudir=$srcd/mupdf
39 muinc="-I $mudir/include -I $mudir/thirdparty/freetype/include"
41 isfresh() {
42 test -e "$1" && test -r "$1.past" && {
43 . "$1.past"
44 test "$k" = "$2"
48 test "${USER-}" = "malc" && {
49 keycmd="cd $mudir && git describe --tags --dirty"
50 isfresh "$outd/mupdf" "$(eval $keycmd)" || (
51 mkdir -p $outd
52 make -C "$mudir" CC='ccache gcc' build=native -j4 libs && :>$outd/mupdf
53 echo "k=$(eval $keycmd)" >$outd/mupdf.past
54 ) && vecho "fresh mupdf"
57 oflags() {
58 case "${1#$outd/}" in
59 main.cmo|utils.cmo|config.cmo|parser.cmo|$wsi/wsi.cmo)
60 f="-g -strict-sequence -strict-formats -warn-error a";;
61 *) f="-g";;
62 esac
63 echo "$incs $f"
66 cflags() {
67 case "${1#$outd/}" in
68 link.o)
69 f="-g -std=c99 -O2 $muinc -Wall -Werror -pedantic-errors"
70 f="$f -D_GNU_SOURCE"
71 $darwin && echo "$f -D__COCOA__" || echo $f;;
72 */keysym2ucs.o) echo "-DKeySym=long";;
73 */ml_gl.o) echo "-g -Wno-pointer-sign -O2";;
74 *) echo "-g -O2";;
75 esac
78 mflags() { echo "-I $(ocamlc -where) -g -O2"; }
80 incs="-I $srcd/lablGL -I $srcd/$wsi -I $srcd"
81 incs="$incs -I $outd/lablGL -I $outd/$wsi -I $outd"
83 bocaml1() {
84 local s="$1"
85 local o="$2"
86 local O=${3-}
87 :>$o.depl
88 ocamlc -depend -bytecode -one-line $incs $s | {
89 read _ _ depl
90 for d in $depl; do
91 local D=${d#$srcd/}
92 test "$O" = "$D" || {
93 bocaml "$D" $n
94 test $d = "$outd/help.cmo" && dd=$d || dd=$outd/${d#$srcd/}
95 printf "$dd " >>$o.depl
97 done
99 local cmd="ocamlc $(oflags $o) -c -o $o $s"
100 local keycmd="digest $s $(cat $o.depl)"
101 grep -q "$o" $outd/ordered || {
102 echo "$o" >>"$outd/ordered"
103 isfresh "$o" "$cmd$(eval $keycmd)" || {
104 printf "%*.s%s -> %s\n" $n '' "${s#$srcd/}" "${o#$outd/}"
105 eval "$cmd" || die "$cmd failed"
106 echo "k='$cmd$(eval $keycmd)'" >"$o.past"
107 } && vecho "fresh '$o'"
111 bocaml() (
112 local o="$1"
113 local n="$2"
114 local wocmi="${o%.cmi}"
115 local s
116 test ${wocmi%help.cmo} != $wocmi && {
117 s=$outd/help.ml
118 o=$outd/help.cmo
119 } || {
120 test "$o" = "$wocmi" && s=$srcd/${o%.cmo}.ml || s=$srcd/$wocmi.mli
121 o=$outd/$o
123 bocaml1 "$s" "$o"
124 case $wocmi in
125 wsi) s="$srcd/$wsi/wsi.ml";;
126 */glMisc) s="$srcd/lablGL/glMisc.ml";;
127 */glTex) s="$srcd/lablGL/glTex.ml";;
128 *) false;;
129 esac && {
130 local s1=${s#$srcd/}
131 bocaml1 "$s" "${s1%.ml}.cmo" "${o#$outd/}"
132 } || true
135 bocamlc() {
136 local o=$outd/$1
137 local s=$srcd/${1%.o}.c
138 local cmd="ocamlc -ccopt \"$(cflags $o) -MMD -MF $o.dep -MT_ -o $o\" $s"
139 test -r $o.dep && read _ d <$o.dep || d=
140 local keycmd='digest $o $d'
141 isfresh "$o" "$cmd$(eval $keycmd)" || {
142 printf "%s -> %s\n" "${s#$srcd/}" "${o#$outd/}"
143 eval "$cmd" || die "$cmd failed"
144 read _ d <$o.dep
145 echo "k='$cmd$(eval $keycmd)'" >"$o.past"
146 } && vecho "fresh $o"
149 bobjc() {
150 local o=$outd/$1
151 local s=$srcd/${1%.o}.m
152 local cmd="$mcomp $(mflags $o) -MMD -MF $o.dep -MT_ -c -o $o $s"
153 test -r $o.dep && read _ d <$o.dep || d=
154 local keycmd='digest $o $d'
155 isfresh "$o" "$cmd$(eval $keycmd)" || {
156 printf "%s -> %s\n" "${s#$srcd/}" "${o#$outd/}"
157 eval "$cmd"
158 read _ d <$o.dep
159 echo "k='$cmd$(eval $keycmd)'" >"$o.past"
160 } && vecho "fresh $o"
163 mkdir -p $outd/$wsi
164 mkdir -p $outd/lablGL
165 :>$outd/ordered
167 mkhelp() {
168 ocaml str.cma -stdin $srcd/KEYS <<EOF
169 let fixup = let open Str in
170 let dash = regexp {|\([^ ]*\) +- +\(.*\)|}
171 and head = regexp {|-----\(.*\)-----|} in fun s ->
172 String.escaped s |> global_replace dash {|\1\t\2|}
173 |> global_replace head {|\xc2\xb7\1|};;
174 let rec iter ic = match input_line ic with
175 | s -> Printf.printf "\"%s\";\\n" @@ fixup s; iter ic
176 | exception End_of_file -> ();;
177 Printf.printf "let keys = [\\n";
178 iter @@ open_in Sys.argv.(1);;
179 Printf.printf "] and version = \"$ver\";;"
183 ver=$(cd $srcd && git describe --tags --dirty) || ver=unknown
184 cmd="mkhelp >$outd/help.ml # $ver"
185 keycmd="digest $srcd/KEYS # $ver"
186 isfresh "$outd/help.ml" "$cmd$(eval $keycmd)" || {
187 eval $cmd
188 echo "k='$cmd$(eval $keycmd)'" >"$outd/help.ml.past"
189 } && vecho "fresh $outd/help.ml"
191 case "${2-}" in
192 man)
193 md=$outd/man
194 mkdir -p $md
195 for m in llpp llppac llpphtml; do
196 man=$srcd/man/$m.man
197 xml=$md/$m.xml
198 out=$md/$m.1
199 keycmd="digest $xml $man"
200 conf="$srcd/man/asciidoc.conf"
201 cmd="asciidoc -d manpage -b docbook -f $conf -o '$xml' '$man'"
202 isfresh "$xml" "$cmd$(eval $keycmd)" || {
203 eval $cmd
204 echo "k='$cmd$(eval $keycmd)'" >"$md/$m.past"
205 } && vecho "fresh manual xmls"
206 keycmd="digest $out $xml"
207 cmd="xmlto man -o $md $xml"
208 isfresh "$out" "$cmd$(eval $keycmd)" || {
209 eval $cmd
210 echo "k='$cmd$(eval $keycmd)'" >"$out.past"
211 } && vecho "fresh manual pages"
212 done
213 shift;;
214 *) ;;
215 esac
217 bocaml main.cmo 0
219 cobjs=$outd/link.o
220 bocamlc link.o
222 libs="str.cma unix.cma"
223 clibs="-L$mudir/build/native -lmupdf -lmupdfthird -lpthread"
224 if $darwin; then
225 mcomp=$(ocamlc -config | grep bytecomp_c_co | { read _ c; echo $c; })
226 clibs="$clibs -framework Cocoa -framework OpenGL"
227 bobjc wsi/osx/wsicocoa.o
228 cobjs="$cobjs $outd/wsi/osx/wsicocoa.o"
229 else
230 clibs="$clibs -lGL -lX11"
231 cobjs="$cobjs $outd/wsi/x11/keysym2ucs.o"
232 bocamlc wsi/x11/keysym2ucs.o
235 globjs=
236 for f in ml_gl ml_glarray ml_raw; do
237 bocamlc lablGL/$f.o
238 globjs="$globjs $outd/lablGL/$f.o"
239 done
241 ord=$(grep -v \.cmi $outd/ordered)
242 cmd="ocamlc -custom $libs -o $outd/llpp $cobjs $ord"
243 cmd="$cmd $globjs -cclib \"$clibs\""
244 keycmd="digest $outd/llpp $cobjs $ord"
245 isfresh "$outd/llpp" "$cmd$(eval $keycmd)" || {
246 echo linking $outd/llpp
247 eval $cmd || die "$cmd failed"
248 echo "k='$cmd$(eval $keycmd)'" >"$outd/llpp.past"
249 } && vecho "fresh llpp"
251 if $darwin; then
252 out="$outd/llpp.app/Contents/Info.plist"
253 keycmd="digest $out $srcd/misc/Info.plist.sh"
254 isfresh $out "$(eval $keycmd)" || {
255 shortver=$(echo $ver | { IFS='-' read s _; echo ${s#v}; })
256 d=$(dirname $out)
257 test -d "$d" || mkdir -p "$d"
258 . $srcd/misc/Info.plist.sh >"$out"
259 echo "k=$(eval $keycmd)" >"$out.past"
260 } && vecho "fresh plist"
262 out=$outd/llpp.app/Contents/MacOS/llpp
263 keycmd="digest $out $outd/llpp"
264 isfresh $out "$(eval $keycmd)" || {
265 d=$(dirname $out)
266 mkdir -p "$d"
267 cp $outd/llpp $out
268 echo "k=$(eval $keycmd)" >"$out.past"
269 } && vecho "fresh bundle"