Home | History | Annotate | Download | only in diag-build
      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