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