Chris@1: #!/bin/bash Chris@1: Chris@6: # Run this from the top-level vamp-build-and-test directory Chris@6: Chris@1: ## Things to test: Chris@1: ## the plugin builds! Chris@1: ## plugin loads Chris@1: ## passes vamp-plugin-tester tests Chris@1: ## does not export any unnecessary symbols Chris@1: ## has valid .cat and .n3 Chris@1: Chris@19: mydir=$(dirname "$0") Chris@19: case "$mydir" in /*);; *) mydir=$(pwd)/"$mydir";; esac Chris@19: Chris@22: do_rebuild="" Chris@14: Chris@22: usage() { Chris@22: echo Chris@22: echo "Usage: $0 [-c] [ ...]" Chris@22: echo Chris@31: echo " one of native, linux32, linux64, mingw32, mingw64, osx32, osx64" Chris@22: echo " -c build from clean" Chris@22: echo " directory to build (default is all of them)" Chris@22: echo Chris@22: echo "Platform usually should match the platform you are running this" Chris@22: echo "script on, unless you have a cross-compile toolset installed and" Chris@31: echo "this script knows how to run it. The special platform 'native'" Chris@31: echo "tries to guess the currently running platform." Chris@22: echo Chris@22: exit 2 Chris@22: } Chris@21: Chris@31: platform_arg="$1" Chris@31: Chris@31: if [ "$platform_arg" = "native" ]; then Chris@31: case `uname -a` in Chris@31: Linux*x86_64*) platform_arg=linux64;; Chris@31: Linux*) platform_arg=linux32;; Chris@31: Darwin*) platform_arg=osx64;; Chris@31: CYG*) platform_arg=mingw32;; Chris@31: MINGW*) platform_arg=mingw32;; Chris@31: esac Chris@31: fi Chris@31: Chris@31: case "$platform_arg" in Chris@22: linux32) Chris@22: platform=linux Chris@22: bits=32 Chris@22: toolprefix= Chris@22: pluginext=.so Chris@22: hostwrapper= Chris@22: hostext= Chris@38: valgrind=valgrind Chris@22: archflags= Chris@22: ;; Chris@22: linux64) Chris@22: platform=linux Chris@22: bits=64 Chris@22: toolprefix= Chris@22: pluginext=.so Chris@22: hostwrapper= Chris@22: hostext= Chris@38: valgrind=valgrind Chris@22: archflags= Chris@22: ;; Chris@22: mingw32) Chris@22: platform=mingw Chris@22: bits=32 Chris@22: toolprefix=i686-w64-mingw32- Chris@22: pluginext=.dll Chris@22: hostwrapper=wine Chris@22: hostext=.exe Chris@38: valgrind= Chris@22: archflags= Chris@22: ;; Chris@22: mingw64) Chris@22: platform=mingw Chris@22: bits=64 Chris@22: toolprefix=x86_64-w64-mingw32- Chris@22: pluginext=.dll Chris@22: hostwrapper=wine Chris@22: hostext=.exe Chris@38: valgrind= Chris@22: archflags= Chris@22: ;; Chris@22: osx32) Chris@22: platform=osx Chris@22: bits=32 Chris@22: toolprefix= Chris@22: pluginext=.dylib Chris@22: hostwrapper= Chris@22: hostext= Chris@38: valgrind= Chris@22: archflags="-arch i386" Chris@22: ;; Chris@22: osx64) Chris@22: platform=osx Chris@22: bits=64 Chris@22: toolprefix= Chris@22: pluginext=.dylib Chris@22: hostwrapper= Chris@22: hostext= Chris@38: valgrind= Chris@26: # This is a difficult choice for various reasons... have to ponder Chris@26: archflags="-mmacosx-version-min=10.6 -arch x86_64 -arch i386" Chris@22: ;; Chris@22: esac; Chris@22: Chris@22: shift Chris@22: Chris@22: if [ -z "$platform" ]; then Chris@22: usage Chris@22: else Chris@22: echo "(Platform is $platform, $bits bits)" Chris@22: fi Chris@22: Chris@22: if [ t"$1" = t"-c" ]; then Chris@22: echo "(Building from clean)" Chris@22: do_rebuild=yes Chris@22: shift Chris@22: fi Chris@15: Chris@19: depincdir="$mydir"/../DEPENDENCIES/$platform$bits/include Chris@19: deplibdir="$mydir"/../DEPENDENCIES/$platform$bits/lib Chris@19: Chris@19: depincdir_generic="$mydir"/../DEPENDENCIES/generic/include Chris@1: Chris@11: plugindirs="$@" Chris@11: if [ -z "$plugindirs" ]; then Chris@11: plugindirs=$(cat .hgsub | grep -v vamp-plugin-sdk | grep -v vamp-plugin-tester | awk '{ print $1; }') Chris@11: fi Chris@11: Chris@6: reportdir="REPORTS/$platform$bits" Chris@6: mkdir -p "$reportdir" || exit 1 Chris@6: Chris@9: built="/tmp/built.$$.txt" Chris@9: testfailed="/tmp/testfailed.$$.txt" Chris@19: envcheckfailed="/tmp/envcheckfailed.$$.txt" Chris@9: notbuilt="/tmp/notbuilt.$$.txt" Chris@19: trap 'rm -f "$built" "$envcheckfailed" "$testfailed" "$notbuilt"' 0 Chris@19: touch "$built" "$envcheckfailed" "$testfailed" "$notbuilt" Chris@9: Chris@4: configure() { Chris@4: dir="$1" Chris@4: if [ -f "$dir/configure" ] ; then Chris@6: ( cd "$dir" ; ./configure ) 2>&1 | tee "$reportdir/$dir.configure.txt" Chris@4: fi Chris@4: } Chris@4: Chris@1: find_makefile() { Chris@1: dir="$1" Chris@9: for f in \ Chris@19: build/$platform$bits/Makefile.$platform$bits \ Chris@13: build/$platform/Makefile.$platform$bits \ Chris@19: build/$platform$bits/Makefile.$platform \ Chris@19: build/$platform$bits/Makefile \ Chris@19: build/Makefile.$platform$bits \ Chris@19: Makefile.$platform$bits \ Chris@13: build/$platform/Makefile.$platform \ Chris@13: build/$platform/Makefile \ Chris@13: build/Makefile.$platform \ Chris@9: Makefile.$platform \ Chris@13: Makefile ; do Chris@1: if [ -f "$dir/$f" ]; then Chris@1: echo $f Chris@1: break Chris@1: fi Chris@1: done Chris@1: } Chris@1: Chris@13: configure_maybe() { Chris@13: dir="$1" Chris@13: mfile=$(find_makefile "$dir") Chris@13: if [ -z "$mfile" ]; then Chris@13: configure "$dir" Chris@13: fi Chris@13: } Chris@13: Chris@19: target_for() { Chris@19: dir="$1" Chris@19: if grep -q "^$dir: " METADATA/maketarget.txt ; then Chris@19: grep "^$dir: " METADATA/maketarget.txt | head -1 | sed 's/^[^:]*: //' Chris@19: fi Chris@19: } Chris@19: Chris@4: build() { Chris@4: dir="$1" Chris@1: if configure_maybe "$dir"; then Chris@1: mfile=$(find_makefile "$dir") Chris@1: if [ -n "$mfile" ]; then Chris@19: target=$(target_for "$dir") Chris@19: TOOLPREFIX="$toolprefix" \ Chris@21: CXXFLAGS="-I${depincdir} -I${depincdir_generic} -I../vamp-plugin-sdk" \ Chris@21: LDFLAGS="-L${deplibdir} -L../vamp-plugin-sdk" \ Chris@21: ARCHFLAGS="$archflags" \ Chris@19: make -C "$dir" -f "$mfile" $target 2>&1 | \ Chris@19: tee "$reportdir/$dir.build.txt" Chris@9: return ${PIPESTATUS[0]} Chris@1: else Chris@1: echo "Failed to find a Makefile in $dir" Chris@4: return 1 Chris@1: fi Chris@1: fi Chris@4: } Chris@4: Chris@4: rebuild() { Chris@4: dir="$1" Chris@13: if configure_maybe "$dir"; then Chris@4: mfile=$(find_makefile "$dir") Chris@4: if [ -n "$mfile" ]; then Chris@32: if make -C "$dir" -f "$mfile" clean; then Chris@32: build "$dir" Chris@32: else Chris@32: echo "Failed to 'make clean' in $dir!" | tee "$reportdir/$dir.build.txt" Chris@32: return 1 Chris@32: fi Chris@4: else Chris@32: echo "Failed to find a Makefile in $dir!" | tee "$reportdir/$dir.build.txt" Chris@4: return 1 Chris@4: fi Chris@4: fi Chris@4: } Chris@4: Chris@22: build_or_rebuild() { Chris@22: dir="$1" Chris@22: if [ -n "$do_rebuild" ]; then Chris@22: rebuild "$dir" Chris@22: else Chris@22: build "$dir" Chris@22: fi Chris@22: } Chris@22: Chris@19: have_plugin() { Chris@19: dir="$1" Chris@19: for x in "$dir/"*"$pluginext"; do Chris@19: if [ -f "$x" ]; then Chris@19: return 0 Chris@19: fi Chris@19: done Chris@19: return 1 Chris@19: } Chris@19: Chris@19: is_nondeterministic() { Chris@19: plugin_id="$1" Chris@19: grep -q "^$id\$" METADATA/nondeterministic.txt Chris@19: } Chris@19: Chris@5: run_tester() { Chris@7: ##!!! todo: timeout if the plugin takes too long and report as failure? Chris@5: dir="$1" Chris@19: ids=$(VAMP_PATH="$dir" $hostwrapper vamp-plugin-sdk/host/vamp-simple-host$hostext --list-ids | sed 's/^vamp://' | sed 's/\r//g' ) Chris@32: cat /dev/null > "$reportdir/$dir.test.txt" Chris@6: if [ -z "$ids" ]; then Chris@6: echo Chris@32: echo "No plugins reported to test in $dir" | tee -a "$reportdir/$dir.test.txt" Chris@23: echo "$dir" >> "$testfailed" Chris@6: return 1 Chris@5: else Chris@38: good=yes Chris@6: for id in $ids; do Chris@6: extra="" Chris@19: if is_nondeterministic "$id"; then Chris@6: extra="-n" Chris@6: fi Chris@38: echo "Running command: VAMP_PATH=\"$dir\" $hostwrapper vamp-plugin-tester/vamp-plugin-tester$hostext \"$extra\" \"$id\"" | tee -a "$reportdir/$dir.test.txt" Chris@32: if ( VAMP_PATH="$dir" $hostwrapper vamp-plugin-tester/vamp-plugin-tester$hostext "$extra" "$id" 2>&1 | tee -a "$reportdir/$dir.test.txt" ; exit ${PIPESTATUS[0]} ) ; then Chris@6: echo "OK" Chris@6: else Chris@6: echo Chris@38: echo "Tester failed for id $id: running again with valgrind (if available) and verbose for a report..." Chris@6: echo "$dir" >> "$testfailed" Chris@38: VAMP_PATH="$dir" $valgrind $hostwrapper vamp-plugin-tester/vamp-plugin-tester$hostext -v "$extra" "$id" 2>&1 | tee -a "$reportdir/$dir.test.txt" Chris@38: good=no Chris@6: fi Chris@6: done Chris@38: if [ "$good" != "yes" ]; then Chris@38: return 1 Chris@38: fi Chris@5: fi Chris@38: return 0 Chris@5: } Chris@5: Chris@9: public_symbols() { Chris@9: lib="$1" Chris@23: # nm -g prints global symbols in both OS/X and GNU tools, but Chris@23: # printing only global *defined* symbols is harder. In GNU it is Chris@23: # nm -g --defined-only; the OS/X docs suggest nm -gu should work, Chris@23: # but it doesn't. What I think will work with both is simply Chris@23: # grepping out the undefineds: Chris@23: "$toolprefix"nm -g "$lib" | grep -v ' U ' | awk '{ print $3; }' Chris@9: } Chris@9: Chris@9: run_environmental_tests() { Chris@9: dir="$1" Chris@19: good=yes Chris@32: cat /dev/null > "$reportdir/$dir.envtest.txt" Chris@19: for lib in $dir/*$pluginext; do Chris@19: if [ ! -f "$lib" ]; then Chris@32: echo "NOTE: no library found in $dir?" | tee -a "$reportdir/$dir.envtest.txt" Chris@19: good=no Chris@19: else Chris@19: echo Chris@19: echo "Testing for exported symbols in $lib..." Chris@19: if public_symbols "$lib" | grep -q vampGetPluginDescriptor; then Chris@19: others=`public_symbols "$lib" | grep -v vampGetPluginDescriptor` Chris@19: if [ -n "$others" ]; then Chris@19: count=`echo "$others" | wc -l` Chris@32: echo "WARNING: $count extra symbols exported by plugin library" | tee -a "$reportdir/$dir.envtest.txt" Chris@19: good=no Chris@19: else Chris@32: echo "GOOD: library $lib only exports vampGetPluginDescriptor" | tee -a "$reportdir/$dir.envtest.txt" Chris@19: fi Chris@9: else Chris@32: echo "NOTE: found library $lib that is not a Vamp plugin library" | tee -a "$reportdir/$dir.envtest.txt" Chris@9: fi Chris@9: fi Chris@9: done Chris@19: if [ "$good" != "yes" ]; then Chris@19: echo "$dir" >> "$envcheckfailed" Chris@19: fi Chris@9: } Chris@4: Chris@22: if ! build_or_rebuild "vamp-plugin-sdk"; then Chris@5: echo "Failed to build Vamp plugin SDK!" Chris@5: exit 1 Chris@5: fi Chris@5: Chris@26: # Ensure we can only link statically against these Chris@26: for x in vamp-hostsdk vamp-sdk; do Chris@26: for y in dylib dll so; do Chris@26: rm -f "vamp-plugin-sdk/lib$x.$y" Chris@26: rm -f "vamp-plugin-sdk/$x.$y" Chris@26: done Chris@26: done Chris@26: Chris@22: if ! build_or_rebuild "vamp-plugin-tester"; then Chris@5: echo "Failed to build Vamp plugin tester!" Chris@5: exit 1 Chris@5: fi Chris@5: Chris@11: for dir in $plugindirs ; do Chris@31: dir=${dir%/*} Chris@4: echo Chris@4: echo "Processing: $dir" Chris@31: if [ ! -d "$dir" ]; then Chris@31: echo "Directory $dir not found!" Chris@31: echo "$dir" >> "$notbuilt" Chris@31: elif build_or_rebuild "$dir"; then Chris@19: if have_plugin "$dir" ; then Chris@19: echo "$dir" >> "$built" Chris@19: run_tester "$dir" Chris@19: run_environmental_tests "$dir" Chris@19: else Chris@19: echo "Build apparently succeeded, but no resulting plugin(s) found" | tee -a "$reportdir/$dir.build.txt" Chris@19: echo "$dir" >> "$notbuilt" Chris@19: fi Chris@4: else Chris@6: echo "$dir" >> "$notbuilt" Chris@4: fi Chris@38: cat /dev/null > "$reportdir/$dir.summary.txt" Chris@1: done Chris@1: Chris@4: echo Chris@19: echo "** Successfully built, tested, and checked:" Chris@6: cat "$built" | while read d; do Chris@6: if ! grep -q "^$d\$" "$testfailed"; then Chris@32: if ! grep -q "^$d\$" "$envcheckfailed"; then Chris@32: echo "$d" Chris@38: echo "$d: Success" >> "$reportdir/$d.summary.txt" Chris@32: fi Chris@6: fi Chris@6: done | sort Chris@4: Chris@4: echo Chris@19: echo "** Failed tests:" Chris@6: cat "$testfailed" | sort | uniq | while read d; do Chris@6: echo "$d" Chris@38: echo "$d: Built successfully, but failed tests" >> "$reportdir/$d.summary.txt" Chris@6: done Chris@5: Chris@5: echo Chris@19: echo "** Failed environmental checks:" Chris@19: cat "$envcheckfailed" | sort | uniq | while read d; do Chris@19: echo "$d" Chris@38: echo "$d: Built successfully, but failed environmental checks" >> "$reportdir/$d.summary.txt" Chris@19: done Chris@19: Chris@19: echo Chris@4: echo "** Failed to build:" Chris@6: cat "$notbuilt" | sort | while read d; do Chris@6: echo "$d" Chris@38: echo "$d: Failed to build" >> "$reportdir/$d.summary.txt" Chris@6: done Chris@4: Chris@4: echo