1#!/bin/bash 2# 3# Build automation. 4# 5# Usage: 6# ./build.sh [function name] 7# 8# Important targets are: 9# cpp-client: Build the C++ client 10# doc: build docs with Markdown 11# fastrand: build Python extension module to speed up the client simulation 12# 13# If no function is specified all 3 targets will be built. 14 15set -o nounset 16set -o pipefail 17set -o errexit 18 19log() { 20 echo 1>&2 "$@" 21} 22 23die() { 24 log "FATAL: $@" 25 exit 1 26} 27 28run-markdown() { 29 local md=`which markdown || echo "cat"` 30 31 # Markdown is output unstyled; make it a little more readable. 32 cat <<EOF 33 <!DOCTYPE html> 34 <html> 35 <head> 36 <meta charset="UTF-8"> 37 <style type="text/css"> 38 code { color: green; } 39 pre { margin-left: 3em; } 40 </style> 41 <!-- INSERT LATCH JS --> 42 </head> 43 <body style="margin: 0 auto; width: 40em; text-align: left;"> 44 <!-- INSERT LATCH HTML --> 45EOF 46 47 $md "$@" 48 49 cat <<EOF 50 </body> 51 </html> 52EOF 53} 54 55run-dot() { 56 local in=$1 57 local out=$2 58 59 local msg="dot not found (perhaps 'sudo apt-get install graphviz')" 60 which dot >/dev/null || die "$msg" 61 62 log "Running dot" 63 # width, height 64 dot \ 65 -Tpng -Gsize='2,4!' -Gdpi=300 \ 66 -o $out $in 67} 68 69# Scan for TODOs. Does this belong somewhere else? 70todo() { 71 find . -name \*.py -o -name \*.R -o -name \*.sh -o -name \*.md \ 72 | xargs --verbose -- grep -w TODO 73} 74 75# 76# Targets: build "doc" or "fastrand" 77# 78 79# Build dependencies: markdown tool. 80doc() { 81 mkdir -p _tmp _tmp/doc 82 83 # For now, just one file. 84 # TODO: generated docs 85 run-markdown <README.md >_tmp/README.html 86 run-markdown <doc/randomness.md >_tmp/doc/randomness.html 87 88 run-markdown <doc/data-flow.md >_tmp/doc/data-flow.html 89 run-dot doc/data-flow.dot _tmp/doc/data-flow.png 90 91 log 'Wrote docs to _tmp' 92} 93 94# Build dependencies: Python development headers. Most systems should have 95# this. On Ubuntu/Debian, the 'python-dev' package contains headers. 96fastrand() { 97 pushd tests >/dev/null 98 python setup.py build 99 # So we can 'import _fastrand' without installing 100 ln -s --force build/*/_fastrand.so . 101 ./fastrand_test.py 102 103 log 'fastrand built and tests PASSED' 104 popd >/dev/null 105} 106 107cpp-client() { 108 pushd client/cpp 109 mkdir --verbose -p _tmp 110 make _tmp/rappor_sim # this builds an executable using it 111 popd 112} 113 114if test $# -eq 0 ; then 115 cpp-client 116 doc 117 fastrand 118else 119 "$@" 120fi 121