From 056328e1d40a73bef98c5a6c9001215e3b44127e Mon Sep 17 00:00:00 2001 From: Peter Wu Date: Mon, 7 Jul 2014 16:21:19 +0200 Subject: sync-build.sh: remote compilation after editing This script helps me in syncing sources with a remote build machine and building changes once I have made a local change. It also syncs back generated binaries. --- sync-build.sh | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100755 sync-build.sh (limited to 'sync-build.sh') diff --git a/sync-build.sh b/sync-build.sh new file mode 100755 index 0000000..109e6a5 --- /dev/null +++ b/sync-build.sh @@ -0,0 +1,109 @@ +#!/bin/bash +# Detect a local change, sync to build machine and retrieve result when done. A +# notification is also send when the build is complete. +# +# Author: Peter Wu +# +# Recommendations: +# - ssh-agent (add keys before with ssh-add) +# - 2 GiB remote storage (builddir is 900 MiB, git tree is 486 MiB) +# - Gigabit link between working machine and build machine +# - Matching local + remote OS environments to avoid library mismatches. +# In my case I run schroot to enter a chroot with matching libs (see +# $remotecmd below). +# - libnotify for notifications when ready. + +# LOCAL source dir (on non-volatile storage for reliability) +localsrcdir=$HOME/projects/wireshark/ + +# REMOTE +# REMOTE host, is a ssh alias that can be defined in ~/.ssh/config, e.g.: +# Host wireshark-builder +# User foo +# Hostname 10.42.0.1 +remotehost=wireshark-builder +# Remote source dir, it can be volatile (tmpfs) since it is just a copy. On the +# local side, it is recommended to create a symlink to the localsrcdir for +# debugging purposes +remotesrcdir=/tmp/wireshark/ +# Remote directory to generate objects, it must also be accessible locally for +# easier debugging (rpath) +builddir=/tmp/wsbuild/ + +# LOCAL & REMOTE program dir (Available since 1.11.x and 1.12.0) +rundir="$builddir/run/" + +# PATH is needed for /usr/bin/core_perl/pod2man (PCAP) +remotecmd="schroot -c chroot:arch -- sh -c ' +PATH=/usr/local/sbin:/usr/local/bin:/usr/bin:/usr/bin/core_perl; +if [ ! -d $builddir ]; then + mkdir $builddir && cd $builddir && + time cmake \ + -DCMAKE_INSTALL_PREFIX=/tmp/wsroot \ + -DENABLE_GTK3=0 \ + -DENABLE_PORTAUDIO=0 \ + -DENABLE_QT5=0 \ + -DENABLE_GEOIP=0 \ + -DENABLE_KERBEROS=0 \ + -DENABLE_SMI=0 \ + -DCMAKE_BUILD_TYPE=Debug \ + $remotesrcdir \ + -DCMAKE_C_FLAGS=-fsanitize=address \ + -DCMAKE_CXX_FLAGS=-fsanitize=address \ + -DCMAKE_EXPORT_COMPILE_COMMANDS=1 +fi && +time make -C $builddir -j16 +'" + + +# Touch this file to trigger a build. +sync=$(mktemp --tmpdir 'sync-build-XXXXXXXX') +monpid= +cleanup() { + rm -f "$sync" + [ -z "$monpid" ] || kill $monpid +} +trap cleanup EXIT + +round=0 +monitor_changes() { + # Wait for changes, but ignore .git/ and vim swap files + # NOTE: you cannot add multiple --exclude options, they must be combined + inotifywait -r -m -e close_write \ + --exclude='/\.[^/]+\.swp?.$|~$|\/.git/' \ + "$localsrcdir/" | + while read x; do + printf '\e[36m%s\e[m\n' "Trigger $((++round)): $x" >&2 + touch "$sync" + done +} + + +### MAIN ### + +# For gdb +if [ ! -e "$remotesrcdir" ]; then + ln -sv "$localsrcdir" "$remotesrcdir" +fi + +monitor_changes & monpid=$! + +echo Waiting... +while inotifywait -qq -e close_write "$sync"; do + echo Woke up... + # Wait for a second in case I save something and want to do a ninja edit. + sleep 1 + + rsync -av --delete --exclude='.*.sw?' \ + "$localsrcdir/" "$remotehost:$remotesrcdir/" && + ssh -t "$remotehost" "$remotecmd" + retval=$? + if [ $retval -ne 0 ]; then + notify-send -- "$(tty) - $(date -R)" "Build broke with $retval" + sleep 3 + else + rsync -av --delete --exclude='.*.sw?' "$remotehost:$rundir" "$rundir" + notify-send -- "$(tty) - $(date -R)" "READY" + fi + echo Another satisfied customer. NEXT +done -- cgit v1.2.1