diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2016-10-06 15:40:56 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2016-10-06 15:40:56 -0700 |
commit | a232af2fafd9ad974ebc6cfcb2cd5a5883f0bd4a (patch) | |
tree | 8dd0390b7fb148fcdce2b724aa7f1d5abdd13dc6 | |
parent | 6d6c37feeb72c7ab13276cec7df326f7d8cd1712 (diff) | |
download | mu-a232af2fafd9ad974ebc6cfcb2cd5a5883f0bd4a.tar.gz |
3447 - drop dependence on GNU make
A generic build system is overkill for such a small project, and it was adding complexity on OpenBSD which doesn't come with GNU make by default. In the process we also eliminate our reliance on bash and perl, at least for the core build script.
-rw-r--r-- | Readme.md | 8 | ||||
-rwxr-xr-x | build | 117 | ||||
-rwxr-xr-x | clean | 7 | ||||
-rw-r--r-- | cleave/makefile | 7 | ||||
-rw-r--r-- | makefile | 85 | ||||
-rwxr-xr-x | mu | 7 |
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 "$@" |