1#!/usr/bin/env bash 2 3set -e 4 5function err() 6{ 7 echo "$@" >&2 8} 9 10function usage() 11{ 12 err "Detect compiler and linker versions, generate mk/cc.mk" 13 err "" 14 err "Usage: ./detect_cc.sh [OPTION]..." 15 err "" 16 err "Defaults for the options are specified in brackets." 17 err "" 18 err "General:" 19 err " -h, --help Display this help and exit" 20 err " --cc=path C compiler to use" 21 err " --cxx=path C++ compiler to use" 22 err " --ld=path Linker to use" 23 err " --lto=[y|n] Attempt to configure for LTO" 24 err " --cross-prefix=prefix Use the given prefix for the cross compiler toolchain" 25} 26 27 28 29for i in "$@"; do 30 case "$i" in 31 -h|--help) 32 usage 33 exit 0 34 ;; 35 --cc=*) 36 if [[ -n "${i#*=}" ]]; then 37 CC="${i#*=}" 38 fi 39 ;; 40 --cxx=*) 41 if [[ -n "${i#*=}" ]]; then 42 CXX="${i#*=}" 43 fi 44 ;; 45 --lto=*) 46 if [[ -n "${i#*=}" ]]; then 47 LTO="${i#*=}" 48 fi 49 ;; 50 --ld=*) 51 if [[ -n "${i#*=}" ]]; then 52 LD="${i#*=}" 53 fi 54 ;; 55 --cross-prefix=*) 56 if [[ -n "${i#*=}" ]]; then 57 CROSS_PREFIX="${i#*=}" 58 fi 59 ;; 60 --) 61 break 62 ;; 63 *) 64 err "Unrecognized option $i" 65 usage 66 exit 1 67 esac 68done 69 70OS=$(uname) 71 72: ${CC=cc} 73: ${CXX=c++} 74: ${LD=} 75: ${LTO=n} 76: ${CROSS_PREFIX=} 77 78if [ -z "$LD" ]; then 79 if [ "$OS" = "Linux" ]; then 80 LD=ld 81 fi 82 if [ "$OS" = "FreeBSD" ]; then 83 LD=ld.lld 84 fi 85fi 86 87CC_TYPE=$($CC -v 2>&1 | grep -o -E '\w+ version' | head -1 | awk '{ print $1 }') 88CXX_TYPE=$($CXX -v 2>&1 | grep -o -E '\w+ version' | head -1 | awk '{ print $1 }') 89if [ "$CC_TYPE" != "$CXX_TYPE" ]; then 90 err "C compiler is $CC_TYPE but C++ compiler is $CXX_TYPE" 91 err "This may result in errors" 92fi 93 94LD_TYPE=$($LD --version 2>&1 | head -n1 | awk '{print $1, $2}') 95case "$LD_TYPE" in 96 "GNU ld"*) 97 LD_TYPE=bfd 98 ;; 99 "GNU gold"*) 100 LD_TYPE=gold 101 ;; 102 "LLD"*) 103 LD_TYPE=lld 104 ;; 105 *) 106 err "Unsupported linker: $LD" 107 exit 1 108esac 109 110CCAR="ar" 111if [ "$LTO" = "y" ]; then 112 if [ "$CC_TYPE" = "clang" ]; then 113 if [ "$LD_TYPE" != "gold" ]; then 114 err "Using LTO with clang requires the gold linker." 115 exit 1 116 fi 117 CCAR="llvm-ar" 118 else 119 CCAR="gcc-ar" 120 fi 121fi 122 123if [ -n "$CROSS_PREFIX" ]; then 124 expected_prefix=$($CC -dumpmachine) 125 126 if [ ! "$expected_prefix" = "$CROSS_PREFIX" ]; then 127 err "Cross prefix specified ($CROSS_PREFIX) does not match prefix of $CC ($expected_prefix)." 128 129 # Try to fix this automatically. Maybe the user set CROSS_PREFIX but not CC. 130 CC=$CROSS_PREFIX-$CC 131 if hash $CC 2>/dev/null; then 132 expected_prefix=$($CC -dumpmachine) 133 134 if [ "$expected_prefix" = "$CROSS_PREFIX" ]; then 135 err "Automatically changed CC to $CC" 136 else 137 err "Set CC to the appropriate compiler." 138 exit 1 139 fi 140 else 141 err "Set CC to the appropriate compiler." 142 exit 1 143 fi 144 145 fi 146 147 expected_prefix=$($CXX -dumpmachine) 148 149 if [ ! "$expected_prefix" = "$CROSS_PREFIX" ]; then 150 err "Cross prefix specified ($CROSS_PREFIX) does not match prefix of $CXX ($expected_prefix)." 151 152 # Try to fix this automatically. Maybe the user set CROSS_PREFIX but not CXX. 153 CXX=$CROSS_PREFIX-$CXX 154 if hash $CXX 2>/dev/null; then 155 expected_prefix=$($CXX -dumpmachine) 156 157 if [ "$expected_prefix" = "$CROSS_PREFIX" ]; then 158 err "Automatically changed CXX to $CXX" 159 else 160 err "Set CXX to the appropriate compiler." 161 exit 1 162 fi 163 else 164 err "Set CXX to the appropriate compiler." 165 exit 1 166 fi 167 fi 168fi 169 170function set_default() { 171 echo "DEFAULT_$1=$2" 172 echo "ifeq (\$(origin $1),default)" 173 echo "$1=$2" 174 echo "endif" 175 echo "" 176} 177 178set_default CC $CC 179set_default CXX $CXX 180set_default LD $LD 181 182echo "CCAR=$CCAR" 183echo "CC_TYPE=$CC_TYPE" 184echo "LD_TYPE=$LD_TYPE" 185 186if [ -n "$CROSS_PREFIX" ]; then 187 echo "CROSS_PREFIX=$CROSS_PREFIX" 188fi 189