1dceccacff28d00717774300f5fe0067286ac65bfJordan Rose#!/bin/bash 2dceccacff28d00717774300f5fe0067286ac65bfJordan Rose 3dceccacff28d00717774300f5fe0067286ac65bfJordan Roseprint_usage () { 4dceccacff28d00717774300f5fe0067286ac65bfJordan Rose echo 'Usage: diag-build.sh [-v] xcodebuild [flags]' 5dceccacff28d00717774300f5fe0067286ac65bfJordan Rose echo ' diag-build.sh [-v] make [flags]' 6dceccacff28d00717774300f5fe0067286ac65bfJordan Rose echo ' diag-build.sh [-v] <other build command>' 7dceccacff28d00717774300f5fe0067286ac65bfJordan Rose echo 8dceccacff28d00717774300f5fe0067286ac65bfJordan Rose echo 'diagtool must be in your PATH' 9dceccacff28d00717774300f5fe0067286ac65bfJordan Rose echo 'If using an alternate build command, you must ensure that' 10dceccacff28d00717774300f5fe0067286ac65bfJordan Rose echo 'the compiler used matches the CC environment variable.' 11dceccacff28d00717774300f5fe0067286ac65bfJordan Rose} 12dceccacff28d00717774300f5fe0067286ac65bfJordan Rose 13dceccacff28d00717774300f5fe0067286ac65bfJordan Rose# Mac OS X's BSD sed uses -E for extended regular expressions, 14dceccacff28d00717774300f5fe0067286ac65bfJordan Rose# but GNU sed uses -r. Find out which one this system accepts. 15dceccacff28d00717774300f5fe0067286ac65bfJordan RoseEXTENDED_SED_FLAG='-E' 16dceccacff28d00717774300f5fe0067286ac65bfJordan Roseecho -n | sed $EXTENDED_SED_FLAG 's/a/b/' 2>/dev/null || EXTENDED_SED_FLAG='-r' 17dceccacff28d00717774300f5fe0067286ac65bfJordan Rose 18dceccacff28d00717774300f5fe0067286ac65bfJordan Roseif [[ "$1" == "-v" ]]; then 19dceccacff28d00717774300f5fe0067286ac65bfJordan Rose verbose=$1 20dceccacff28d00717774300f5fe0067286ac65bfJordan Rose shift 21dceccacff28d00717774300f5fe0067286ac65bfJordan Rosefi 22dceccacff28d00717774300f5fe0067286ac65bfJordan Rose 23dceccacff28d00717774300f5fe0067286ac65bfJordan Roseguessing_cc=0 24dceccacff28d00717774300f5fe0067286ac65bfJordan Rose 25dceccacff28d00717774300f5fe0067286ac65bfJordan Roseif [[ -z "$CC" ]]; then 26dceccacff28d00717774300f5fe0067286ac65bfJordan Rose guessing_cc=1 27dceccacff28d00717774300f5fe0067286ac65bfJordan Rose if [[ -x $(dirname $0)/clang ]]; then 28dceccacff28d00717774300f5fe0067286ac65bfJordan Rose CC=$(dirname $0)/clang 29dceccacff28d00717774300f5fe0067286ac65bfJordan Rose elif [[ ! -z $(which clang) ]]; then 30dceccacff28d00717774300f5fe0067286ac65bfJordan Rose CC=$(which clang) 31dceccacff28d00717774300f5fe0067286ac65bfJordan Rose else 32dceccacff28d00717774300f5fe0067286ac65bfJordan Rose echo -n 'Error: could not find an appropriate compiler' 33dceccacff28d00717774300f5fe0067286ac65bfJordan Rose echo ' to generate build commands.' 1>&2 34dceccacff28d00717774300f5fe0067286ac65bfJordan Rose echo 'Use the CC environment variable to set one explicitly.' 1>&2 35dceccacff28d00717774300f5fe0067286ac65bfJordan Rose exit 1 36dceccacff28d00717774300f5fe0067286ac65bfJordan Rose fi 37dceccacff28d00717774300f5fe0067286ac65bfJordan Rosefi 38dceccacff28d00717774300f5fe0067286ac65bfJordan Rose 39dceccacff28d00717774300f5fe0067286ac65bfJordan Roseif [[ -z "$CXX" ]]; then 40dceccacff28d00717774300f5fe0067286ac65bfJordan Rose if [[ -x $(dirname $0)/clang++ ]]; then 41dceccacff28d00717774300f5fe0067286ac65bfJordan Rose CXX=$(dirname $0)/clang++ 42dceccacff28d00717774300f5fe0067286ac65bfJordan Rose elif [[ ! -z $(which clang++) ]]; then 43dceccacff28d00717774300f5fe0067286ac65bfJordan Rose CXX=$(which clang++) 44dceccacff28d00717774300f5fe0067286ac65bfJordan Rose else 45dceccacff28d00717774300f5fe0067286ac65bfJordan Rose CXX=$CC 46dceccacff28d00717774300f5fe0067286ac65bfJordan Rose fi 47dceccacff28d00717774300f5fe0067286ac65bfJordan Rosefi 48dceccacff28d00717774300f5fe0067286ac65bfJordan Rose 49dceccacff28d00717774300f5fe0067286ac65bfJordan Rosediagtool=$(which diagtool) 50dceccacff28d00717774300f5fe0067286ac65bfJordan Roseif [[ -z "$diagtool" ]]; then 51dceccacff28d00717774300f5fe0067286ac65bfJordan Rose if [[ -x $(dirname $0)/diagtool ]]; then 52dceccacff28d00717774300f5fe0067286ac65bfJordan Rose diagtool=$(dirname $0)/diagtool 53dceccacff28d00717774300f5fe0067286ac65bfJordan Rose else 54dceccacff28d00717774300f5fe0067286ac65bfJordan Rose echo 'Error: could not find diagtool.' 1>&2 55dceccacff28d00717774300f5fe0067286ac65bfJordan Rose exit 1 56dceccacff28d00717774300f5fe0067286ac65bfJordan Rose fi 57dceccacff28d00717774300f5fe0067286ac65bfJordan Rosefi 58dceccacff28d00717774300f5fe0067286ac65bfJordan Rose 59dceccacff28d00717774300f5fe0067286ac65bfJordan Rose 60dceccacff28d00717774300f5fe0067286ac65bfJordan Rosetool=$1 61dceccacff28d00717774300f5fe0067286ac65bfJordan Roseshift 62dceccacff28d00717774300f5fe0067286ac65bfJordan Rose 63dceccacff28d00717774300f5fe0067286ac65bfJordan Roseif [[ -z "$tool" ]]; then 64dceccacff28d00717774300f5fe0067286ac65bfJordan Rose print_usage 65dceccacff28d00717774300f5fe0067286ac65bfJordan Rose exit 1 66dceccacff28d00717774300f5fe0067286ac65bfJordan Roseelif [[ "$tool" == "xcodebuild" ]]; then 67dceccacff28d00717774300f5fe0067286ac65bfJordan Rose dry_run='-dry-run' 68dceccacff28d00717774300f5fe0067286ac65bfJordan Rose set_compiler="CC='$CC' CXX='$CXX'" 69dceccacff28d00717774300f5fe0067286ac65bfJordan Roseelif [[ "$tool" == "make" ]]; then 70dceccacff28d00717774300f5fe0067286ac65bfJordan Rose dry_run='-n' 71dceccacff28d00717774300f5fe0067286ac65bfJordan Rose set_compiler="CC='$CC' CXX='$CXX'" 72dceccacff28d00717774300f5fe0067286ac65bfJordan Roseelse 73dceccacff28d00717774300f5fe0067286ac65bfJordan Rose echo "Warning: unknown build system '$tool'" 1>&2 74dceccacff28d00717774300f5fe0067286ac65bfJordan Rose if [[ $guessing_cc -eq 1 ]]; then 75dceccacff28d00717774300f5fe0067286ac65bfJordan Rose # FIXME: We really only need $CC /or/ $CXX 76dceccacff28d00717774300f5fe0067286ac65bfJordan Rose echo 'Error: $CC must be set for other build systems' 1>&2 77dceccacff28d00717774300f5fe0067286ac65bfJordan Rose exit 1 78dceccacff28d00717774300f5fe0067286ac65bfJordan Rose fi 79dceccacff28d00717774300f5fe0067286ac65bfJordan Rosefi 80dceccacff28d00717774300f5fe0067286ac65bfJordan Rose 81dceccacff28d00717774300f5fe0067286ac65bfJordan Roseescape () { 82dceccacff28d00717774300f5fe0067286ac65bfJordan Rose echo $@ | sed 's:[]:\\|/.+*?^$(){}[]:\\&:g' 83dceccacff28d00717774300f5fe0067286ac65bfJordan Rose} 84dceccacff28d00717774300f5fe0067286ac65bfJordan Rose 85dceccacff28d00717774300f5fe0067286ac65bfJordan RoseescCC=$(escape $CC) 86dceccacff28d00717774300f5fe0067286ac65bfJordan RoseescCXX=$(escape $CXX) 87dceccacff28d00717774300f5fe0067286ac65bfJordan Rosecommand=$( 88dceccacff28d00717774300f5fe0067286ac65bfJordan Rose eval $tool $dry_run $set_compiler $@ 2>/dev/null | 89dceccacff28d00717774300f5fe0067286ac65bfJordan Rose # Remove "if" early on so we can find the right command line. 90dceccacff28d00717774300f5fe0067286ac65bfJordan Rose sed $EXTENDED_SED_FLAG "s:^[[:blank:]]*if[[:blank:]]{1,}::g" | 91dceccacff28d00717774300f5fe0067286ac65bfJordan Rose # Combine lines with trailing backslashes 92dceccacff28d00717774300f5fe0067286ac65bfJordan Rose sed -e :a -e '/\\$/N; s/\\\n//; ta' | 93dceccacff28d00717774300f5fe0067286ac65bfJordan Rose grep -E "^[[:blank:]]*($escCC|$escCXX)" | 94dceccacff28d00717774300f5fe0067286ac65bfJordan Rose head -n1 | 95dceccacff28d00717774300f5fe0067286ac65bfJordan Rose sed $EXTENDED_SED_FLAG "s:($escCC|$escCXX):${diagtool//:/\\:} show-enabled:g" 96dceccacff28d00717774300f5fe0067286ac65bfJordan Rose) 97dceccacff28d00717774300f5fe0067286ac65bfJordan Rose 98dceccacff28d00717774300f5fe0067286ac65bfJordan Roseif [[ -z "$command" ]]; then 99dceccacff28d00717774300f5fe0067286ac65bfJordan Rose echo 'Error: could not find any build commands.' 1>&2 100dceccacff28d00717774300f5fe0067286ac65bfJordan Rose if [[ "$tool" != "xcodebuild" ]]; then 101dceccacff28d00717774300f5fe0067286ac65bfJordan Rose # xcodebuild always echoes the compile commands on their own line, 102dceccacff28d00717774300f5fe0067286ac65bfJordan Rose # but other tools give no such guarantees. 103dceccacff28d00717774300f5fe0067286ac65bfJordan Rose echo -n 'This may occur if your build system embeds the call to ' 2>&1 104dceccacff28d00717774300f5fe0067286ac65bfJordan Rose echo -n 'the compiler in a larger expression. ' 2>&1 105dceccacff28d00717774300f5fe0067286ac65bfJordan Rose fi 106dceccacff28d00717774300f5fe0067286ac65bfJordan Rose exit 2 107dceccacff28d00717774300f5fe0067286ac65bfJordan Rosefi 108dceccacff28d00717774300f5fe0067286ac65bfJordan Rose 109dceccacff28d00717774300f5fe0067286ac65bfJordan Rose# Chop off trailing '&&', '||', and ';' 110dceccacff28d00717774300f5fe0067286ac65bfJordan Rosecommand=${command%%&&*} 111dceccacff28d00717774300f5fe0067286ac65bfJordan Rosecommand=${command%%||*} 112dceccacff28d00717774300f5fe0067286ac65bfJordan Rosecommand=${command%%;*} 113dceccacff28d00717774300f5fe0067286ac65bfJordan Rose 114dceccacff28d00717774300f5fe0067286ac65bfJordan Rose[[ -n "$verbose" ]] && echo $command 115dceccacff28d00717774300f5fe0067286ac65bfJordan Roseeval $command 116