about summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--Readme.md8
-rwxr-xr-xbuild117
-rwxr-xr-xclean7
-rw-r--r--cleave/makefile7
-rw-r--r--makefile85
-rwxr-xr-xmu7
6 files changed, 129 insertions, 102 deletions
diff --git a/Readme.md b/Readme.md
index c6d6ed81..e9c170f3 100644
--- a/Readme.md
+++ b/Readme.md
@@ -84,10 +84,10 @@ operations (albeit at the cost of some runtime checks).
 *Taking Mu for a spin*
 
 Mu is currently implemented in C++ and requires a Unix-like environment. It's
-been tested on Ubuntu and Mac OS X, on x86, x86\_64 and ARMv7 with recent
-versions of GCC and Clang. Since it uses no recent language features and has
-no exotic dependencies, it should work with most reasonable versions,
-compilers or processors (though you do need GNU make or `gmake`).
+been tested on Ubuntu, Mac OS X and OpenBSD; on x86, x86\_64 and ARMv7; and on
+recent versions of GCC and Clang. Since it uses no bleeding-edge language
+features and has no exotic dependencies, it should work with most reasonable
+versions, compilers or processors.
 
 [![Build Status](https://api.travis-ci.org/akkartik/mu.svg)](https://travis-ci.org/akkartik/mu)
 
diff --git a/build b/build
new file mode 100755
index 00000000..86f9fa5f
--- /dev/null
+++ b/build
@@ -0,0 +1,117 @@
+#!/bin/sh
+set -e  # stop immediately on error
+
+# [0-9]*.cc -> mu.cc -> .build/*.cc -> .build/*.o -> .build/mu_bin
+# (layers)   |        |              |             |
+#          tangle  cleave          $CXX          $CXX
+
+test $CXX || export CXX=c++ 
+test $CC || export CC=cc
+test $CFLAGS || export CFLAGS="-g -O3"
+export CFLAGS="$CFLAGS -Wall -Wextra -ftrapv -fno-strict-aliasing"
+
+# return 1 if $1 is older than _any_ of the remaining args
+older_than() {
+  target=$1
+  shift
+  if [ ! -e $target ]
+  then 
+#?     echo "$target doesn't exist"
+    echo "updating $target" >&2
+    return 1
+  fi
+  for f in $*
+  do
+    if [ $f -nt $target ]
+    then
+      echo "updating $target" >&2
+      return 1
+    fi
+  done
+  return 0
+}
+
+noisy_cd() {
+  cd $1
+  echo "-- `pwd`" >&2
+}
+
+older_than enumerate/enumerate enumerate/enumerate.cc || {
+  $CXX $CFLAGS enumerate/enumerate.cc -o enumerate/enumerate
+}
+
+noisy_cd tangle
+  older_than type_list [0-9]*.cc || {
+    grep -h "^struct .* {" [0-9]*.cc |sed 's/\(struct *[^ ]*\).*/\1;/' > type_list
+    grep -h "^typedef " [0-9]*.cc >> type_list
+  }
+  older_than function_list [0-9]*.cc || {
+    grep -h "^[^ #].*) {" [0-9]*.cc |sed 's/ {.*/;/' > function_list
+  }
+  older_than file_list [0-9]*.cc || {
+    ls [0-9]*.cc |grep -v "\.test\.cc$" |sed 's/.*/#include "&"/' > file_list
+  }
+  older_than test_file_list [0-9]*.test.cc || {
+    ls [0-9]*.test.cc |sed 's/.*/#include "&"/' > test_file_list
+  }
+  older_than test_list [0-9]*.cc || {
+    grep -h "^[[:space:]]*void test_" [0-9]*.cc |sed 's/^\s*void \(.*\)() {$/\1,/' > test_list
+  }
+  older_than tangle boot.cc *_list || {
+    $CXX $CFLAGS boot.cc -o tangle
+  }
+noisy_cd ..
+
+LAYERS=$(./enumerate/enumerate --until zzz |grep -v '.mu$')
+older_than mu.cc $LAYERS enumerate/enumerate tangle/tangle || {
+  ./tangle/tangle $LAYERS > mu.cc
+}
+older_than function_list mu.cc || {
+  grep -h "^[^[:space:]#].*) {$" mu.cc |grep -v ":.*(" |sed 's/ {.*/;/' > function_list
+}
+older_than test_list mu.cc || {
+  grep -h "^\s*void test_" mu.cc |sed 's/^\s*void \(.*\)() {.*/\1,/' > test_list
+}
+
+older_than cleave/cleave cleave/cleave.cc || {
+  $CXX -O3 -Wall -Wextra -fno-strict-aliasing cleave/cleave.cc -o cleave/cleave
+  rm -rf .build
+}
+
+older_than mu_bin mu.cc *_list cleave/cleave || {
+  mkdir -p .build
+  cp function_list test_list .build
+  mkdir -p .build/termbox
+  cp termbox/termbox.h .build/termbox
+  ./cleave/cleave mu.cc .build
+  noisy_cd .build
+    older_than global_declarations_list global_definitions_list || {
+      grep ';' global_definitions_list |sed 's/[=(].*/;/' |sed 's/^[^\/# ]/extern &/' |sed 's/^extern extern /extern /' > global_declarations_list
+    }
+    for f in mu_*.cc
+    do
+      older_than `echo $f |sed 's/\.cc$/.o/'` $f || {
+        $CXX $CFLAGS -c $f
+      }
+    done
+  noisy_cd ../termbox
+    older_than utf8.o utf8.c || {
+      $CC $CFLAGS -c utf8.c
+    }
+    older_than termbox.o termbox.c termbox.h input.inl output.inl bytebuffer.inl || {
+      $CC $CFLAGS -c termbox.c
+    }
+    older_than libtermbox.a *.o || {
+      ar rcs libtermbox.a *.o
+    }
+  noisy_cd ..
+  $CXX .build/*.o termbox/libtermbox.a -o .build/mu_bin
+  cp .build/mu_bin .
+}
+
+## [0-9]*.mu -> core.mu
+
+MU_LAYERS=$(./enumerate/enumerate --until zzz |grep '.mu$')
+older_than core.mu $MU_LAYERS || {
+  cat $MU_LAYERS > core.mu
+}
diff --git a/clean b/clean
new file mode 100755
index 00000000..1cd632d0
--- /dev/null
+++ b/clean
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+set -v
+rm -rf mu.cc core.mu mu_bin* *_list .build
+rm -rf enumerate/enumerate tangle/tangle tangle/*_list cleave/cleave
+rm -rf termbox/*.o termbox/libtermbox.a
+rm -rf *.dSYM */*.dSYM
diff --git a/cleave/makefile b/cleave/makefile
deleted file mode 100644
index 33665b5c..00000000
--- a/cleave/makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-cleave: cleave.cc makefile
-	c++ -O3 -Wall -Wextra -fno-strict-aliasing cleave.cc -o cleave
-
-.PHONY: clean
-
-clean:
-	-rm cleave
diff --git a/makefile b/makefile
deleted file mode 100644
index 1f5599d7..00000000
--- a/makefile
+++ /dev/null
@@ -1,85 +0,0 @@
-# [0-9]*.cc -> mu.cc -> .build/*.cc -> .build/*.o -> .build/mu_bin
-# (layers)   |        |              |             |
-#          tangle  cleave          $CXX          $CXX
-#
-# [0-9]*.mu -> core.mu
-
-all: mu_bin core.mu
-
-# beware: if you introduce or delete functions the makefile isn't smart enough
-# to recompute dependencies. You have to manually run 'make redo' to recreate
-# the .build/ directory from scratch.
-redo: clean1 all
-
-CXX ?= c++
-CXXFLAGS ?= -g -O3
-CXXFLAGS := ${CXXFLAGS} -Wall -Wextra -ftrapv -fno-strict-aliasing
-
-core.mu: [0-9]*.mu mu.cc makefile
-	cat $$(./enumerate/enumerate --until zzz |grep '.mu$$') > core.mu
-
-mu_bin: mu.cc makefile function_list test_list cleave/cleave
-	@mkdir -p .build
-	@cp function_list test_list .build
-	@mkdir -p .build/termbox
-	@cp termbox/termbox.h .build/termbox
-	@# split mu.cc into separate compilation units under .build/ to speed up recompiles
-	./cleave/cleave mu.cc .build
-	@# recursive (potentially parallel) make to pick up BUILD_SRC after cleave
-	@${MAKE} .build/mu_bin
-	cp .build/mu_bin .
-
-BUILD_SRC=$(wildcard .build/*.cc)
-.build/mu_bin: $(BUILD_SRC:.cc=.o) termbox/libtermbox.a
-	${CXX} ${LDFLAGS} .build/*.o termbox/libtermbox.a -o .build/mu_bin
-
-.build/%.o: .build/%.cc .build/header .build/global_declarations_list
-	@# explicitly state default rule since we added dependencies
-	${CXX} ${CXXFLAGS} -c $< -o $@
-
-# To see what the program looks like after all layers have been applied, read
-# mu.cc
-mu.cc: [0-9]*.cc enumerate/enumerate tangle/tangle
-	./tangle/tangle $$(./enumerate/enumerate --until zzz |grep -v '.mu$$') > mu.cc
-
-enumerate/enumerate: enumerate/*.cc
-	cd enumerate && ${MAKE}
-
-tangle/tangle: tangle/*.cc
-	cd tangle && ${MAKE} && ./tangle test
-
-cleave/cleave: cleave/*.cc
-	cd cleave && ${MAKE}
-	rm -rf .build
-
-termbox/libtermbox.a: termbox/*.c termbox/*.h termbox/*.inl
-	cd termbox && ${MAKE}
-
-# auto-generated files; by convention they end in '_list'.
-
-# auto-generated list of function declarations, so I can define them in any order
-function_list: mu.cc
-	@# functions start out unindented, have all args on the same line, and end in ') {'
-	@#                                      ignore methods
-	@grep -h "^[^[:space:]#].*) {$$" mu.cc |grep -v ":.*(" |perl -pwe 's/ \{.*/;/' > function_list
-
-# auto-generated list of tests to run
-test_list: mu.cc
-	@grep -h "^\s*void test_" mu.cc |perl -pwe 's/^\s*void (.*)\(\) \{.*/$$1,/' > test_list
-
-# auto-generated list of extern declarations to global variables
-# for separate compilation
-.build/global_declarations_list: .build/global_definitions_list
-	@grep ';' .build/global_definitions_list |perl -pwe 's/[=(].*/;/' |perl -pwe 's/^[^\/# ]/extern $$&/' |perl -pwe 's/^extern extern /extern /' > .build/global_declarations_list
-
-.PHONY: all redo clean clena
-
-clena: clean
-clean: clean1
-	cd enumerate && ${MAKE} clean
-	cd tangle && ${MAKE} clean
-	cd cleave && ${MAKE} clean
-	cd termbox && ${MAKE} clean
-
-clean1:
-	rm -rf mu.cc core.mu mu_bin* *_list .build
diff --git a/mu b/mu
index ad3222d9..dabc77d6 100755
--- a/mu
+++ b/mu
@@ -2,12 +2,7 @@
 #
 # Compile mu if necessary before running it.
 
-# I try to keep this script working even on a minimal OpenBSD without bash.
-# In such situations you might sometimes need GNU make.
-which gmake >/dev/null 2>&1 && export MAKE=gmake || export MAKE=make
-
-# show make output only if something needs doing
-$MAKE -q || $MAKE >&2 || exit 1
+./build
 
 ./mu_bin $FLAGS "$@"