4 vecho
() { ${vecho-:} "$@"; }
5 executable_p
() { command -v "$1" >/dev
/null
2>&1; }
6 dgst
='cksum "$@" | while read d _; do printf $d; done'
7 ! executable_p b3sum || dgst
='b3sum --no-names "$@"'
8 executable_p realpath || realpath
() (cd "$1" &>/dev
/null
; pwd -P)
9 eval "digest() { $dgst; } 2>/dev/null"
10 die
() { echo "$@" >&2; exit 111; }
11 trap 'test $? -eq 0 || echo "build failed"' EXIT
15 clip
="LC_CTYPE=UTF-8 xclip -i"
16 paste="LC_CTYPE=UTF-8 xclip -o"
17 uopen
="echo 'Open "%s
"' >&2"
18 print
="echo 'Print "%s
"' >&2"
19 mjobs
=$
(getconf _NPROCESSORS_ONLN ||
echo 1)
24 clip
="LC_CTYPE=UTF-8 pbcopy"
25 paste="LC_CTYPE=UTF-8 pbaste"
28 *) die $
(uname
) is not supported
;;
31 test -n "${1-}" || die
"usage: $0 build-directory"
36 muinc
="-I $mudir/include -I $mudir/thirdparty/freetype/include"
38 test -d $mudir || die muPDF wasn
\'t found
in $outd/, consult
$srcd/BUILDING
40 mkdir
-p $outd/{$wsid,lablGL
}
42 isfresh
() { test "$(<$1.past)" = "$2"; } 2>/dev
/null
45 test -n "${gmk:-}" && gmk
=false || gmk
=true
47 mulibs
="$mudir/build/$mbt/libmupdf.a $mudir/build/$mbt/libmupdf-third.a"
48 make="make -C "$mudir" build=$mbt -j $mjobs libs"
54 $wsid/wsi.cm
[oi
]|confstruct.cmo|
help.cmo
) incs
="-I $b -I $b/$wsid";;
55 glutils.cmo
) incs
="-I $b -I $b/lablGL";;
56 uiutils.cmo|main.cmo
) incs
="-I $b -I $b/$wsid -I $b/lablGL";;
57 ffi.cmo|
help.cmi|parser.cmo
) incs
="-I $b";;
59 incs
="-I $b -I $b/$wsid"
60 test "$b" = $outd || incs
="$incs -I $outd"
62 lablGL
/*) incs
="-I $b/lablGL";;
63 main.cmo|keys.cmo|utils.cmo|utf8syms.cmo
) incs
="-I $b";;
64 config.cmi
) incs
="-I $outd -I $b -I $b/$wsid";;
65 uiutils.cmi|ffi.cmi
) incs
="-I $b";;
66 glutils.cmi
) incs
="-I $b/lablGL";;
67 main.cmi|keys.cmi|utils.cmi|utf8syms.cmi|parser.cmi
) ;;
68 *) die
"ocaml include paths for '$2' aren't set";;
70 test -z "${incs-}" ||
echo $incs
76 utf8syms.cmo|confstruct.cmo|config.cmo|ffi.cmo|wsi
/cocoa
/wsi.cmo
)
77 f
="-g -strict-sequence -strict-formats -alert @all-missing-mli";;
78 *) f
="-g -strict-sequence -strict-formats -alert @all -warn-error @A";;
80 echo $
(oincs
$outd $1) $f
85 version.o
) f
=-DLLPP_VERSION=$ver;;
86 lablGL
/*.o
) f
="-g -Wno-pointer-sign -Werror -O2";;
88 f
="-g -std=c11 $muinc -Wall -Werror -Wextra -pedantic "
89 test "${mbt-}" = "debug" || f
+="-O2 "
90 $darwin && f
+="-DMACOS -D_GNU_SOURCE -DGL_H='<OpenGL/gl.h>'" \
91 || f
+="-D_POSIX_C_SOURCE -DGL_H='<GL/gl.h>'"
92 f
+=" -include $srcd/diag.h -DFIXME=0"
93 f
+=" -DTEXT_TYPE=GL_TEXTURE_RECTANGLE_ARB"
94 #f+=" -DTEXT_TYPE=GL_TEXTURE_2D"
96 *) f
="-g -O2 -Wall -Werror";;
98 ! $darwin || f
+=" -DGL_SILENCE_DEPRECATION"
103 echo "-I $(ocamlc -where) -g -Wall -Werror -O2 -DGL_SILENCE_DEPRECATION"
106 overs
=$
(ocamlc
-vnum 2>/dev
/null
) || overs
=""
107 if test "$overs" != "4.13.0"; then
108 url
=https
://caml.inria.fr
/pub
/distrib
/ocaml-4.13
/ocaml-4.13
.0.
tar.xz
109 txz
=$outd/$
(basename $url)
110 keycmd
="printf $url; digest $txz;"
111 isfresh
$txz "$(eval $keycmd)" ||
{
112 if executable_p wget
; then dl
() { wget
"$1" -O "$2"; }
113 elif executable_p curl
; then dl
() { curl
-L "$1" -o "$2"; }
114 else die
"no program to fetch remote urls found"
117 eval $keycmd >$txz.past
118 } && vecho
"fresh $txz"
119 absprefix
=$
(realpath
$outd)
120 export PATH
=$absprefix/bin
:$PATH
121 ocamlc
=$absprefix/bin
/ocamlc
122 keycmd
="printf $url; digest $ocamlc;"
123 isfresh
$ocamlc "$(eval $keycmd)" ||
(
124 # This will needlessly re{configure,make} ocaml since "past"
125 # of configure/make is hard to ascertain. "Better safe than
126 # sorry" approach is taken here. The check will work for a
127 # single ocaml url/version, but _will_ redo _everything_
128 # otherwise (even if fully built artifacts are available)
131 cd $outd/${bn%.tar.xz}
132 .
/configure
--disable-ocamldoc --disable-ocamltest \
133 --enable-debugger=no
--prefix=$absprefix
136 eval $keycmd >$absprefix/bin
/ocamlc.past
137 ) && vecho
"fresh ocamlc"
138 overs
=$
(ocamlc
-vnum 2>/dev
/null
)
143 "bytecomp_c_compiler:") ccomp
=${CAML_CC-$v};;
144 "word_size:") ! test "$darwin$v" = "true32" || die
"need 64bit ocaml";;
146 done < <(ocamlc
-config)
148 read cvers
< <($ccomp --version)
152 $gmk ||
:>$outd/Makefile
154 local n
=$1 s
=$2 o
=$3 deps
= cmd d
155 local keycmd
="digest $s $o.depl"
156 cmd
="ocamlc -depend -bytecode -one-line $(oincs $srcd $o) $s"
158 isfresh
"$o.depl" "$overs$cmd$(eval $keycmd)" ||
{
159 read _ _ depl
< <(eval $cmd) || die
"$cmd failed"
161 if test "$d" = "$outd/confstruct.cmo";
162 then d
=confstruct.cmo
; else d
=${d#$srcd/}; fi
165 printf "$deps" >$o.depl
167 echo "$overs$cmd$(eval $keycmd)" >"$o.depl.past"
168 } && vecho
"fresh $o.depl"
170 # this saves time but is overly optimistic as interface (dis)
171 # appearance will result in an invalid (stale) .depl (cache). not
172 # using a cache is correct but slow(er (much)) way to handle this.
178 cmd
="ocamlc $(oflags $o) -c -o $o $s"
179 keycmd
="digest $o $s $deps"
180 isfresh
"$o" "$overs$cmd$(eval $keycmd)" ||
{
181 printf "%*.s%s\n" $n '' "${o#$outd/}"
182 eval "$cmd" || die
"$cmd failed"
183 echo "$overs$cmd$(eval $keycmd)" >"$o.past"
184 } && vecho
"fresh $o"
185 $gmk ||
printf "$o: $deps\n\t%s\n" "$cmd" >>$outd/Makefile
192 [[ ! $seen =~
$1 ]] ||
return 0
193 local s o
=$1 n
=$2 cycle1
=$cycle
195 confstruct.cmo
) s
=$outd/confstruct.ml
;;
196 *.cmo
) s
=$srcd/${o%.cmo}.ml
;;
197 *.cmi
) s
=$srcd/${o%.cmi}.mli
;;
200 [[ "$cycle" =~
"$o" ]] && die cycle
$o || cycle
=$cycle$o
207 read 2>/dev
/null _ d
<$o.dep || d
=
208 local keycmd
='digest $o $d'
209 isfresh
"$o" "$cvers$cmd$(eval $keycmd)" ||
{
211 eval "$cmd" || die
"$cmd failed"
213 echo "$cvers$cmd$(eval $keycmd)" >"$o.past"
214 } && vecho
"fresh $o"
215 $gmk ||
printf "$o: $d\n\t$cmd\n" >>$outd/Makefile
219 local o
=$outd/$1 s
=$srcd/${1%.o}.c cc
=${CAML_CC:+-cc "'$CAML_CC'" }
220 baux
$o "ocamlc $cc-ccopt \"$(cflags $o) -MMD -MF $o.dep -MT_\" -o $o -c $s"
225 baux
$o "$mcomp $(mflags $o) -MD -MF $o.dep -MT_ -c -o $o $srcd/${1%.o}.m"
228 ver
=$
(cd $srcd && git describe
--tags --dirty) || ver
="'built on $(date)'"
230 gen
=$srcd/genconfstruct.sh
231 out
=$outd/confstruct.ml
232 cmd
="(export print paste clip uopen; . $gen >$out)"
233 keycmd
="{ echo '$print $paste $clip $uopen'; digest $gen $out; }"
234 isfresh
"$out" "$cmd$(eval $keycmd)" ||
{
235 echo "generating $out"
236 eval "$cmd" || die
$gen failed
237 echo "$cmd$(eval $keycmd)" > "${out}.past"
238 } && vecho
"fresh $out"
246 for m
in llpp llppac
; do
247 src
=$srcd/adoc
/$m.adoc
249 conf
=$srcd/man
/asciidoc.conf
250 keycmd
="digest $o $src $conf"
251 cmd
="a2x -f manpage -D $md $src"
252 isfresh
"$o" "$cmd$(eval $keycmd)" ||
{
254 eval "$cmd" || die
"$cmd failed"
255 echo "$cmd$(eval $keycmd)" >"$o.past"
256 } && vecho
"fresh $o"
259 *) die
"no such target - '$target'";;
265 [[ ! "$seen" =~
"$1" ]] ||
return 0
268 local wooutd
=${o#$outd/}
270 *.cmi
) flatten
${wooutd%.cmi}.cmo
;;
271 *.cmo
) flatten
$wooutd;;
279 # it might appear that following can be done inside bocaml* but
280 # alas due to the early cmi->cmo descent this ought to be done
281 # here (at least the solution inside bocaml* eludes me)
282 local dep cmo this
=$1
287 test $cmo = $this || collectmodules
$cmo
294 [[ $modules =~
$cmo ]] || modules
+=" $outd/$cmo"
297 collectmodules main.cmo
300 for m
in link cutils version
; do
304 for m
in ml_gl ml_glarray ml_raw
; do
306 cobjs
+=" $outd/lablGL/$m.o"
309 libs
="str.cma unix.cma"
310 clibs
="-L$mudir/build/$mbt -lmupdf -lmupdf-third -lpthread"
313 clibs
+=" -framework Cocoa -framework OpenGL"
314 cobjs
+=" $outd/wsi/cocoa/cocoa.o"
315 bobjc wsi
/cocoa
/cocoa.o
318 cobjs
+=" $outd/wsi/x11/keysym2ucs.o $outd/wsi/x11/xlib.o"
319 bocamlc wsi
/x11
/keysym2ucs.o
320 bocamlc wsi
/x11
/xlib.o
323 cmd
="ocamlc -custom $libs -o $outd/llpp $cobjs $modules -cclib \"$clibs\""
324 keycmd
="digest $outd/llpp $cobjs $modules $mulibs"
325 isfresh
"$outd/llpp" "$cmd$(eval $keycmd)" ||
{
326 echo linking
$outd/llpp
327 eval "$cmd" || die
"$cmd failed"
328 echo "$cmd$(eval $keycmd)" >"$outd/llpp.past"
329 } && vecho
"fresh llpp"
330 $gmk ||
printf "$outd/llpp: $cobjs $modules $mulibs\n\t$cmd\n" >>$outd/Makefile
333 out
="$outd/llpp.app/Contents/Info.plist"
334 keycmd
="digest $out $srcd/wsi/cocoa/genplist.sh; echo $ver"
335 isfresh
$out "$(eval $keycmd)" ||
{
338 echo "generating $out"
339 (.
$srcd/wsi
/cocoa
/genplist.sh
) >"$out"
340 eval $keycmd>"$out.past"
341 } && vecho
"fresh plist"
343 out
=$outd/llpp.app
/Contents
/MacOS
/llpp
344 keycmd
="digest $out $outd/llpp"
345 isfresh
$out "$(eval $keycmd)" ||
{
347 mkdir
-p "$(dirname $out)"
349 eval $keycmd>"$out.past"
350 } && vecho
"fresh bundle"