There is some unclaimed parallelism inside the build process:

 a) all C compilation can be done in parallel

 b) ditto all _independent_ OCaml compilation (i.e. things having the
    same indentation (and growing from the same "root") in the
    following build.bash output)

The "neat" solution of how to get there is elusive though. Currently:

  - bash build.bash build
    utils.ml -> utils.cmo
    keys.ml -> keys.cmo
   wsi.mli -> wsi.cmi
   utf8syms.ml -> utf8syms.cmo
   lablGL/raw.ml -> lablGL/raw.cmo
       lablGL/gl.ml -> lablGL/gl.cmo
      lablGL/glPix.ml -> lablGL/glPix.cmo
      lablGL/glMisc.ml -> lablGL/glMisc.cmo
     lablGL/glTex.ml -> lablGL/glTex.cmo
     lablGL/glFunc.ml -> lablGL/glFunc.cmo
      lablGL/glDraw.ml -> lablGL/glDraw.cmo
     lablGL/glArray.ml -> lablGL/glArray.cmo
       parser.ml -> parser.cmo
       build/confstruct.ml -> confstruct.cmo
      config.ml -> config.cmo
     ffi.ml -> ffi.cmo
    glutils.ml -> glutils.cmo
    lablGL/glMat.ml -> lablGL/glMat.cmo
   listview.ml -> listview.cmo
   help.mli -> help.cmi
   help.ml -> help.cmo
   lablGL/glClear.ml -> lablGL/glClear.cmo
  main.ml -> main.cmo
  link.c -> link.o
  cutils.c -> cutils.o
  version.c -> version.o
  lablGL/ml_gl.c -> lablGL/ml_gl.o
  lablGL/ml_glarray.c -> lablGL/ml_glarray.o
  lablGL/ml_raw.c -> lablGL/ml_raw.o
  9 sec

IOW - whole build (including lablGL, but excluding mupdf/ocaml and its
dependencies) takes less than 10 seconds even on this circa 2014
MacMini.

Making things parallel ought to bring some benefits to the build on
the Raspberry Pi3 and it might even benefit single core PPC MacMini
due to interleaving IO/CPU bound parts (but this is just that -
baseless speculation)

=============================================================

With following applied, build.bash will produce a Makefile that builds
llpp. Building things via this Makefile (i.e. `\time -pv make -jN')
seems to suggest that there is some (a lot) parallelism that can be
harvested even for OCaml code (parallelism for interface deprived
OCaml code (as is the case with llpp) is limited)

diff --git a/build.bash b/build.bash
index e9a2919..37382df 100755
--- a/build.bash
+++ b/build.bash
@@ -1,6 +1,8 @@
 #!/bin/bash
 set -eu
 
+:>Makefile
+
 now() { date +%s; }
 S=$(now)
 vecho() { ${vecho-:} "$*"; }
@@ -159,6 +161,7 @@ bocaml2() {
 
     cmd="ocamlc $(oflags $o) -c -o $o $s"
     keycmd="digest $o $s $(< $o.depl)"
+    printf "$o: $s $(< $o.depl)\n\t$cmd\n" >>Makefile
     isfresh "$o" "$overs$cmd$(eval $keycmd)" || {
         printf "%*.s%s -> %s\n" $n '' "${s#$srcd/}" "${o#$outd/}"
         eval "$cmd || die '$cmd failed'"
@@ -191,6 +194,7 @@ bocaml() (
         *) false;;
     esac && {
         local s1=${s#$srcd/}
+        echo "$outd/${s1%.ml}.cmo: $o" >>Makefile
         bocaml1 $n "$s" "$outd/${s1%.ml}.cmo" "${o#$outd/}"
     } || true
     cycle=$cycle1
@@ -203,6 +207,7 @@ bocamlc() {
     local cmd="ocamlc $cc-ccopt \"$(cflags $o) -MMD -MF $o.dep -MT_ -o $o\" $s"
     test -r $o.dep && read _ d <$o.dep || d=
     local keycmd='digest $o $d'
+    printf "$o: $s $d\n\t$cmd\n" >>Makefile
     isfresh "$o" "$cmd$(eval $keycmd)" || {
         printf "%s -> %s\n" "${s#$srcd/}" "${o#$outd/}"
         eval "$cmd || die '$cmd failed'"
@@ -229,6 +234,7 @@ ver=$(cd $srcd && git describe --tags --dirty) || ver=unknown
 
 cmd="(. $srcd/genconfstr.sh >$outd/confstruct.ml)"
 keycmd="digest $srcd/genconfstr.sh $outd/confstruct.ml"
+printf "$outd/confstruct.ml: $srcd/genconfstr.sh\n\t$cmd\n" >>Makefile
 isfresh "$outd/confstruct.ml" "$cmd$(eval $keycmd)" || {
     echo "generating $outd/confstruct.ml"
     eval "$cmd || die genconfstr.sh failed"
@@ -295,6 +301,7 @@ fi
 ord=$(grep -v \.cmi $outd/ordered)
 cmd="ocamlc -custom $libs -o $outd/llpp $cobjs $(echo $ord) -cclib \"$clibs\""
 keycmd="digest $outd/llpp $cobjs $ord $mulibs"
+printf "$outd/llpp: $cobjs $(echo $ord)\n\t$cmd\n" >>Makefile
 isfresh "$outd/llpp" "$cmd$(eval $keycmd)" || {
     echo linking $outd/llpp
     eval "$cmd || die '$cmd failed'"





========================================
~/xsrc/llpp
- rm build/*.cm* build/lablGL/*.cm* build/wsi/x11/*.cm* build/*.o build/lablGL/*.o build/wsi/x11/*.o
~/xsrc/llpp
- \time -pv bash build.bash build 
  utils.ml -> utils.cmo
  keys.ml -> keys.cmo
 wsi.mli -> wsi.cmi
  wsi/x11/wsi.mli -> wsi/x11/wsi.cmi
 wsi/x11/wsi.ml -> wsi/x11/wsi.cmo
 utf8syms.ml -> utf8syms.cmo
 lablGL/raw.ml -> lablGL/raw.cmo
     lablGL/gl.ml -> lablGL/gl.cmo
    lablGL/glPix.ml -> lablGL/glPix.cmo
    lablGL/glMisc.ml -> lablGL/glMisc.cmo
   lablGL/glTex.ml -> lablGL/glTex.cmo
   lablGL/glFunc.ml -> lablGL/glFunc.cmo
    lablGL/glDraw.ml -> lablGL/glDraw.cmo
   lablGL/glArray.ml -> lablGL/glArray.cmo
     parser.ml -> parser.cmo
     build/confstruct.ml -> confstruct.cmo
    config.ml -> config.cmo
   ffi.ml -> ffi.cmo
  glutils.ml -> glutils.cmo
  lablGL/glMat.ml -> lablGL/glMat.cmo
 listview.ml -> listview.cmo
 help.mli -> help.cmi
 help.ml -> help.cmo
 lablGL/glClear.ml -> lablGL/glClear.cmo
main.ml -> main.cmo
link.c -> link.o
cutils.c -> cutils.o
version.c -> version.o
lablGL/ml_gl.c -> lablGL/ml_gl.o
lablGL/ml_glarray.c -> lablGL/ml_glarray.o
lablGL/ml_raw.c -> lablGL/ml_raw.o
wsi/x11/keysym2ucs.c -> wsi/x11/keysym2ucs.o
wsi/x11/xlib.c -> wsi/x11/xlib.o
10 sec
	Command being timed: "bash build.bash build"
	User time (seconds): 8.75
	System time (seconds): 0.93
	Percent of CPU this job got: 101%
	Elapsed (wall clock) time (h:mm:ss or m:ss): 0:09.55
	Average shared text size (kbytes): 0
	Average unshared data size (kbytes): 0
	Average stack size (kbytes): 0
	Average total size (kbytes): 0
	Maximum resident set size (kbytes): 77656
	Average resident set size (kbytes): 0
	Major (requiring I/O) page faults: 0
	Minor (reclaiming a frame) page faults: 348362
	Voluntary context switches: 3401
	Involuntary context switches: 706
	Swaps: 0
	File system inputs: 0
	File system outputs: 10272
	Socket messages sent: 0
	Socket messages received: 0
	Signals delivered: 0
	Page size (bytes): 4096
	Exit status: 0
~/xsrc/llpp
- rm build/*.cm* build/lablGL/*.cm* build/wsi/x11/*.cm* build/*.o build/lablGL/*.o build/wsi/x11/*.o
~/xsrc/llpp
- \time -pv make -j4 build/llpp -s
	Command being timed: "make -j4 build/llpp -s"
	User time (seconds): 5.11
	System time (seconds): 0.64
	Percent of CPU this job got: 220%
	Elapsed (wall clock) time (h:mm:ss or m:ss): 0:02.60
	Average shared text size (kbytes): 0
	Average unshared data size (kbytes): 0
	Average stack size (kbytes): 0
	Average total size (kbytes): 0
	Maximum resident set size (kbytes): 77648
	Average resident set size (kbytes): 0
	Major (requiring I/O) page faults: 0
	Minor (reclaiming a frame) page faults: 166642
	Voluntary context switches: 303
	Involuntary context switches: 369
	Swaps: 0
	File system inputs: 0
	File system outputs: 89008
	Socket messages sent: 0
	Socket messages received: 0
	Signals delivered: 0
	Page size (bytes): 4096
	Exit status: 0
~/xsrc/llpp
- \time -pv make -j1 build/llpp -s 
	Command being timed: "make -j1 build/llpp -s"
	User time (seconds): 3.62
	System time (seconds): 0.43
	Percent of CPU this job got: 99%
	Elapsed (wall clock) time (h:mm:ss or m:ss): 0:04.07
	Average shared text size (kbytes): 0
	Average unshared data size (kbytes): 0
	Average stack size (kbytes): 0
	Average total size (kbytes): 0
	Maximum resident set size (kbytes): 77592
	Average resident set size (kbytes): 0
	Major (requiring I/O) page faults: 0
	Minor (reclaiming a frame) page faults: 166577
	Voluntary context switches: 176
	Involuntary context switches: 138
	Swaps: 0
	File system inputs: 0
	File system outputs: 89008
	Socket messages sent: 0
	Socket messages received: 0
	Signals delivered: 0
	Page size (bytes): 4096
	Exit status: 0
