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 not found
, 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 *) f
="-g -strict-sequence -strict-formats -alert @all -warn-error @A";;
78 echo $
(oincs
$outd $1) $f
83 version.o
) f
=-DLLPP_VERSION=$ver;;
84 lablGL
/*.o
) f
="-g -Wno-pointer-sign -Werror -O2";;
86 f
="-g -std=c11 $muinc -Wall -Werror -Wextra -pedantic "
87 test "${mbt-}" = "debug" || f
+="-O2 "
88 $darwin && f
+="-DMACOS -D_GNU_SOURCE -DGL_H='<OpenGL/gl.h>'" \
89 || f
+="-D_POSIX_C_SOURCE -DGL_H='<GL/gl.h>'"
90 f
+=" -include $srcd/diag.h -DFIXME=0"
91 f
+=" -DTEXT_TYPE=GL_TEXTURE_RECTANGLE_ARB"
92 #f+=" -DTEXT_TYPE=GL_TEXTURE_2D"
94 *) f
="-g -O2 -Wall -Werror";;
96 ! $darwin || f
+=" -DGL_SILENCE_DEPRECATION"
101 echo "-I $(ocamlc -where) -g -Wall -Werror -O2 -DGL_SILENCE_DEPRECATION"
104 overs
=$
(ocamlc
-vnum 2>/dev
/null
) || overs
=""
105 if test "$overs" != "4.12.0"; then
106 url
=https
://caml.inria.fr
/pub
/distrib
/ocaml-4.12
/ocaml-4.12
.0.
tar.xz
107 txz
=$outd/$
(basename $url)
108 keycmd
="printf $url; digest $txz;"
109 isfresh
$txz "$(eval $keycmd)" ||
{
110 if executable_p wget
; then dl
() { wget
-q "$1" -O "$2"; }
111 elif executable_p curl
; then dl
() { curl
-L "$1" -o "$2"; }
112 else die
"no program to fetch remote urls found"
115 eval $keycmd >$txz.past
116 } && vecho
"fresh $txz"
117 absprefix
=$
(realpath
$outd)
118 export PATH
=$absprefix/bin
:$PATH
119 ocamlc
=$absprefix/bin
/ocamlc
120 keycmd
="printf $url; digest $ocamlc;"
121 isfresh
$ocamlc "$(eval $keycmd)" ||
(
122 # This will needlessly re{configure,make} ocaml since "past"
123 # of configure/make is hard to ascertain. "Better safe than
124 # sorry" approach is taken here. The check will work for a
125 # single ocaml url/version, but _will_ redo everything
126 # otherwise (even if fully built artifacts are available)
129 cd $outd/${bn%.tar.xz}
130 .
/configure
--disable-ocamldoc --disable-ocamltest \
131 --enable-debugger=no
--prefix=$absprefix
134 eval $keycmd >$absprefix/bin
/ocamlc.past
135 ) && vecho
"fresh ocamlc"
136 overs
=$
(ocamlc
-vnum 2>/dev
/null
)
141 "bytecomp_c_compiler:") ccomp
=${CAML_CC-$v};;
142 "word_size:") ! test "$darwin$v" = "true32" || die
"need 64bit ocaml";;
144 done < <(ocamlc
-config)
146 read cvers
< <($ccomp --version)
150 $gmk ||
:>$outd/Makefile
152 local n
=$1 s
=$2 o
=$3 deps
= cmd d
153 local keycmd
="digest $s $o.depl"
154 cmd
="ocamlc -depend -bytecode -one-line $(oincs $srcd $o) $s"
156 isfresh
"$o.depl" "$overs$cmd$(eval $keycmd)" ||
{
157 read _ _ depl
< <(eval $cmd) || die
"$cmd failed"
159 if test "$d" = "$outd/confstruct.cmo";
160 then d
=confstruct.cmo
; else d
=${d#$srcd/}; fi
163 printf "$deps" >$o.depl
165 echo "$overs$cmd$(eval $keycmd)" >"$o.depl.past"
166 } && vecho
"fresh $o.depl"
168 # this saves time but is overly optimistic as interface (dis)
169 # appearance will result in an invalid (stale) .depl (cache). not
170 # using a cache is correct but slow(er (much)) way to handle this.
176 cmd
="ocamlc $(oflags $o) -c -o $o $s"
177 keycmd
="digest $o $s $deps"
178 isfresh
"$o" "$overs$cmd$(eval $keycmd)" ||
{
179 printf "%*.s%s\n" $n '' "${o#$outd/}"
180 eval "$cmd" || die
"$cmd failed"
181 echo "$overs$cmd$(eval $keycmd)" >"$o.past"
182 } && vecho
"fresh $o"
183 $gmk ||
printf "$o: $deps\n\t%s\n" "$cmd" >>$outd/Makefile
190 [[ ! $seen =~
$1 ]] ||
return 0
191 local s o
=$1 n
=$2 cycle1
=$cycle
193 confstruct.cmo
) s
=$outd/confstruct.ml
;;
194 *.cmo
) s
=$srcd/${o%.cmo}.ml
;;
195 *.cmi
) s
=$srcd/${o%.cmi}.mli
;;
198 [[ "$cycle" =~
"$o" ]] && die cycle
$o || cycle
=$cycle$o
205 read 2>/dev
/null _ d
<$o.dep || d
=
206 local keycmd
='digest $o $d'
207 isfresh
"$o" "$cvers$cmd$(eval $keycmd)" ||
{
209 eval "$cmd" || die
"$cmd failed"
211 echo "$cvers$cmd$(eval $keycmd)" >"$o.past"
212 } && vecho
"fresh $o"
213 $gmk ||
printf "$o: $d\n\t$cmd\n" >>$outd/Makefile
217 local o
=$outd/$1 s
=$srcd/${1%.o}.c cc
=${CAML_CC:+-cc "'$CAML_CC'" }
218 baux
$o "ocamlc $cc-ccopt \"$(cflags $o) -MMD -MF $o.dep -MT_ -o $o\" $s"
223 baux
$o "$mcomp $(mflags $o) -MD -MF $o.dep -MT_ -c -o $o $srcd/${1%.o}.m"
226 ver
=$
(cd $srcd && git describe
--tags --dirty) || ver
="'built on $(date)'"
228 gen
=$srcd/genconfstruct.sh
229 out
=$outd/confstruct.ml
230 cmd
="(export print paste clip uopen; . $gen >$out)"
231 keycmd
="{ echo '$print $paste $clip $uopen'; digest $gen $out; }"
232 isfresh
"$out" "$cmd$(eval $keycmd)" ||
{
233 echo "generating $out"
234 eval "$cmd" || die
$gen failed
235 echo "$cmd$(eval $keycmd)" > "${out}.past"
236 } && vecho
"fresh $out"
244 for m
in llpp llppac llpphtml
; do
245 src
=$srcd/adoc
/$m.adoc
247 conf
=$srcd/man
/asciidoc.conf
248 keycmd
="digest $o $src $conf"
249 cmd
="a2x -f manpage -D $md $src"
250 isfresh
"$o" "$cmd$(eval $keycmd)" ||
{
252 eval "$cmd" || die
"$cmd failed"
253 echo "$cmd$(eval $keycmd)" >"$o.past"
254 } && vecho
"fresh $o"
257 *) die
"no such target - '$target'";;
263 [[ ! "$seen" =~
"$1" ]] ||
return 0
266 local wooutd
=${o#$outd/}
268 *.cmi
) flatten
${wooutd%.cmi}.cmo
;;
269 *.cmo
) flatten
$wooutd;;
277 # it might appear that following can be done inside bocaml* but
278 # alas due to the early cmi->cmo descent this ought to be done
279 # here (at least the solution inside bocaml* eludes me)
280 local dep cmo this
=$1
285 test $cmo = $this || collectmodules
$cmo
292 [[ $modules =~
$cmo ]] || modules
+=" $outd/$cmo"
295 collectmodules main.cmo
298 for m
in link cutils version
; do
302 for m
in ml_gl ml_glarray ml_raw
; do
304 cobjs
+=" $outd/lablGL/$m.o"
307 libs
="str.cma unix.cma"
308 clibs
="-L$mudir/build/$mbt -lmupdf -lmupdf-third -lpthread"
311 clibs
+=" -framework Cocoa -framework OpenGL"
312 cobjs
+=" $outd/wsi/cocoa/cocoa.o"
313 bobjc wsi
/cocoa
/cocoa.o
316 cobjs
+=" $outd/wsi/x11/keysym2ucs.o $outd/wsi/x11/xlib.o"
317 bocamlc wsi
/x11
/keysym2ucs.o
318 bocamlc wsi
/x11
/xlib.o
321 cmd
="ocamlc -custom $libs -o $outd/llpp $cobjs $modules -cclib \"$clibs\""
322 keycmd
="digest $outd/llpp $cobjs $modules $mulibs"
323 isfresh
"$outd/llpp" "$cmd$(eval $keycmd)" ||
{
324 echo linking
$outd/llpp
325 eval "$cmd" || die
"$cmd failed"
326 echo "$cmd$(eval $keycmd)" >"$outd/llpp.past"
327 } && vecho
"fresh llpp"
328 $gmk ||
printf "$outd/llpp: $cobjs $modules $mulibs\n\t$cmd\n" >>$outd/Makefile
331 out
="$outd/llpp.app/Contents/Info.plist"
332 keycmd
="digest $out $srcd/wsi/cocoa/genplist.sh; echo $ver"
333 isfresh
$out "$(eval $keycmd)" ||
{
336 echo "generating $out"
337 (.
$srcd/wsi
/cocoa
/genplist.sh
) >"$out"
338 eval $keycmd>"$out.past"
339 } && vecho
"fresh plist"
341 out
=$outd/llpp.app
/Contents
/MacOS
/llpp
342 keycmd
="digest $out $outd/llpp"
343 isfresh
$out "$(eval $keycmd)" ||
{
345 mkdir
-p "$(dirname $out)"
347 eval $keycmd>"$out.past"
348 } && vecho
"fresh bundle"