about summary refs log tree commit diff stats
path: root/build4
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2018-06-25 10:20:06 -0700
committerKartik Agaram <vc@akkartik.com>2018-06-25 10:24:17 -0700
commit129a9f71ce0acb5f9156f2a7a1c559fc47ae2e80 (patch)
tree4dd5b864470220caed42eef4b063b16e41a2364b /build4
parent3ecee22a8a440b5f299729cbe49aede7e270c67c (diff)
downloadmu-129a9f71ce0acb5f9156f2a7a1c559fc47ae2e80.tar.gz
4270 - tweak the experimental concurrent builder
Diffstat (limited to 'build4')
-rwxr-xr-xbuild440
1 files changed, 24 insertions, 16 deletions
diff --git a/build4 b/build4
index 66b7a74c..d31dc455 100755
--- a/build4
+++ b/build4
@@ -5,7 +5,8 @@
 #   1. We rely on the OS to schedule steps, so thousands of independent tasks
 #      will likely be counter-productive.
 #   2. Can run out of virtual memory if you spawn too many say $CC processes.
-#   3. Compilation errors can cause the script to hang.
+#   3. Compilation errors can cause the script to hang. We tag the most common
+#      suspects with '|| quit', but can't eliminate the possibility entirely.
 #   4. Ugly as heck! This version really benefits from comparisons with its
 #      'upstream', build2. And even then, diff gets confused.
 #   5. There's a mechanical difficulty: we use mktemp to reliably create
@@ -95,12 +96,23 @@ mv_if_exists() {
   return 0
 }
 
+# wait for all the given filenames to exist
+# exit immediately if a special file called '.quit' exists
+QUITFILE=`pwd`/.quit
+rm -f $QUITFILE
 wait_for_all() {
   # could use inotify on Linux
   while ! all_exist "$@"
   do
+#?     echo waiting: $*
+    test -e $QUITFILE  &&  return 1  # some step had an error; stop all waiting steps using errexit
     sleep 1
   done
+  return 0
+}
+quit() {
+  touch $QUITFILE
+  exit 1
 }
 
 all_exist() {
@@ -117,7 +129,7 @@ mv_if_exists enumerate/enumerate $TMP
   wait_for_all enumerate/enumerate.cc
   older_than $TMP enumerate/enumerate.cc && {
     echo "building enumerate"
-    $CXX $CFLAGS enumerate/enumerate.cc -o $TMP
+    $CXX $CFLAGS enumerate/enumerate.cc -o $TMP  ||  quit
     echo "done building enumerate"
   }
   mv $TMP enumerate/enumerate
@@ -146,7 +158,7 @@ mv_if_exists tangle/tangle $TMP
       grep -h "^[[:space:]]*void test_" [0-9]*.cc  |sed 's/^\s*void \(.*\)() {$/\1,/'  |update test_list
       # }
       # Now that we have all the _lists, compile 'tangle'
-      $CXX $CFLAGS boot.cc -o $TMP
+      $CXX $CFLAGS boot.cc -o $TMP  ||  quit
     cd ..
     echo "done building tangle"
   }
@@ -165,7 +177,7 @@ mv_if_exists mu.cc $TMP
   older_than $TMP $LAYERS enumerate/enumerate tangle/tangle && {
     echo "running tangle"
     # no update here; rely on 'update' calls downstream
-    ./tangle/tangle $LAYERS  > $TMP
+    ./tangle/tangle $LAYERS >$TMP  ||  quit
     echo "done running tangle"
   }
   mv $TMP mu.cc
@@ -177,7 +189,7 @@ mv_if_exists cleave/cleave $TMP
   wait_for_all cleave/cleave.cc
   older_than $TMP cleave/cleave.cc && {
     echo "building cleave"
-    $CXX $CFLAGS cleave/cleave.cc -o $TMP
+    $CXX $CFLAGS cleave/cleave.cc -o $TMP  ||  quit
     rm -rf .build
     echo "done building cleave"
   }
@@ -203,7 +215,7 @@ mv_if_exists mu_bin $TMP
   wait_for_all mu.cc cleave/cleave termbox/*.c termbox/*.h termbox/*.inl
   older_than $TMP mu.cc *_list cleave/cleave termbox/* && {
     echo "building mu_bin"
-    ./cleave/cleave mu.cc .build
+    ./cleave/cleave mu.cc .build  ||  quit
     cd .build
       # create the list of global variable declarations from the corresponding definitions
       grep ';' global_definitions_list  |sed 's/[=(].*/;/'  |sed 's/^[^\/# ]/extern &/'  |sed 's/^extern extern /extern /'  |update global_declarations_list
@@ -215,7 +227,7 @@ mv_if_exists mu_bin $TMP
         (
           older_than $TMP $f header global_declarations_list function_list test_list && {
             echo "building $OBJ"
-            $CXX $CFLAGS -c $f -o $TMP
+            $CXX $CFLAGS -c $f -o $TMP  ||  quit
             echo "done building $OBJ"
           }
           mv $TMP $OBJ
@@ -227,7 +239,7 @@ mv_if_exists mu_bin $TMP
       (
         older_than $TMP utf8.c && {
           echo "building termbox/utf8.o"
-          $CC $CFLAGS -c utf8.c -o $TMP
+          $CC $CFLAGS -c utf8.c -o $TMP  ||  quit
           echo "done building termbox/utf8.o"
         }
         mv $TMP utf8.o
@@ -237,7 +249,7 @@ mv_if_exists mu_bin $TMP
       (
         older_than $TMP termbox.c termbox.h input.inl output.inl bytebuffer.inl && {
           echo "building termbox/termbox.o"
-          $CC $CFLAGS -c termbox.c -o $TMP
+          $CC $CFLAGS -c termbox.c -o $TMP  ||  quit
           echo "done building termbox/termbox.o"
         }
         mv $TMP termbox.o
@@ -248,7 +260,7 @@ mv_if_exists mu_bin $TMP
         wait_for_all termbox.o utf8.o
         older_than $TMP termbox.o utf8.o && {
           echo "building termbox/libtermbox.a"
-          rm $TMP;  ar rcs $TMP termbox.o utf8.o  # race condition; later mktemp may end up reusing this file
+          rm $TMP;  ar rcs $TMP termbox.o utf8.o  ||  quit  # race condition; later mktemp may end up reusing this file
           echo "done building termbox/libtermbox.a"
         }
         mv $TMP libtermbox.a
@@ -258,7 +270,7 @@ mv_if_exists mu_bin $TMP
     echo wait_for_all $MU_OBJS termbox/libtermbox.a
     wait_for_all $MU_OBJS termbox/libtermbox.a
     echo "building .build/mu_bin"
-    $CXX $CFLAGS $MU_OBJS termbox/libtermbox.a -o $TMP
+    $CXX $CFLAGS $MU_OBJS termbox/libtermbox.a -o $TMP  ||  quit
     echo "done building .build/mu_bin"
     echo "done building mu_bin"
   }
@@ -278,9 +290,5 @@ exit 0
 
 # scenarios considered:
 #   0 status when nothing needs updating
-#   no output when nothing needs updating
-#     no output for mu.cc when .mu files modified
-#     touch mu.cc but don't modify it; no output on second build
-#     touch a .cc layer but don't modify it; no output on second build
 #   only a single layer is recompiled when changing a C++ function
-#   stop immediately after failure in tangle
+#   stop immediately after any failure