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