# ninja constructs fn set { var=$1 { shift printf '%s = %s\n' $var $"* } } fn let { vars=() { while(! ~ $1 --) { vars=($vars $1' = '$2) shift 2 } shift $* printf ' %s\n' $vars } } fn subninja { echo subninja $* } fn include { echo include $* } fn rule { name=$1 { shift let command $"* -- echo rule $name } } fn build { out=$1 rule=$2 { shift 2 echo build $out: $rule $* } } # higher-level rules fn phony { name=$1 deps=() { shift for(dep) { if(! ~ $dep '$'* phony/*) dep='$outdir'/$dep deps=($deps $dep) } build phony/'$dir'/$name phony $deps } } fn cflags { set cflags '$cflags' $* } fn cc { src=$1 obj=$src.o { shift if(! ~ $src '$'*) { src='$srcdir'/$src obj='$outdir'/$obj } build $obj cc $src $* } } fn link { out='$outdir'/$1 objs=() { shift for(obj in $*) { if(! ~ $obj '$'*) obj='$outdir'/$obj objs=($objs $obj) } build $out link $objs } } fn ar { out='$outdir'/$1 objs=() { shift for(obj in $*) { if(! ~ $obj '$'*) obj='$outdir'/$obj objs=($objs $obj) } build $out ar $objs } } fn objects { rule=$1 out=$2 deps=() objs=() { shift 2 if(~ $1 -d) { deps=('||' $2) shift 2 } for(src) { if(~ $src *.[cS] *.cc *.cpp) { cc $src $deps obj=$src.o } if not obj=$src objs=($objs $obj) } $rule $out $objs } } fn lib { objects ar $* } fn exe { objects link $* } fn yacc { outs='$outdir'/$1.tab.^(c h) { let yaccflags '-d -b '$1 -- build $"outs yacc $2 } } # packaging rules fn file { out='$builddir/$repo.hash'/$1 mode=`{printf %4s $3 | tr ' ' 0 | tail -c 4} let args 10$mode' '$1 --\ build $out githash $2 '|' '$builddir/$repo.stamp' scripts/hash.rc tree_inputs=($tree_inputs $out) if(! ~ $mode 0755 0644) tree_perms=($tree_perms 10$mode' '$1) status=() } fn dir { tree_perms=($tree_perms '040'$2' '$1) status=() } fn sym { out='$builddir/$repo.hash'/$1 let args 120000' '$1' '$2 --\ build $out githash '|' '$builddir/$repo.stamp' scripts/hash.rc tree_inputs=($tree_inputs $out) } status=()