1#!/usr/bin/env bash 2# SPDX-License-Identifier: BSD-3-Clause 3# Copyright (C) 2016 Intel Corporation 4# All rights reserved. 5# 6set -e 7 8function err() { 9 echo "$@" >&2 10} 11 12function usage() { 13 err "Detect compiler and linker versions, generate mk/cc.mk" 14 err "" 15 err "Usage: ./detect_cc.sh [OPTION]..." 16 err "" 17 err "Defaults for the options are specified in brackets." 18 err "" 19 err "General:" 20 err " -h, --help Display this help and exit" 21 err " --cc=path C compiler to use" 22 err " --cxx=path C++ compiler to use" 23 err " --ld=path Linker to use" 24 err " --lto=[y|n] Attempt to configure for LTO" 25 err " --cross-prefix=prefix Use the given prefix for the cross compiler toolchain" 26} 27 28for i in "$@"; do 29 case "$i" in 30 -h | --help) 31 usage 32 exit 0 33 ;; 34 --cc=*) 35 if [[ -n "${i#*=}" ]]; then 36 CC="${i#*=}" 37 fi 38 ;; 39 --cxx=*) 40 if [[ -n "${i#*=}" ]]; then 41 CXX="${i#*=}" 42 fi 43 ;; 44 --lto=*) 45 if [[ -n "${i#*=}" ]]; then 46 LTO="${i#*=}" 47 fi 48 ;; 49 --ld=*) 50 if [[ -n "${i#*=}" ]]; then 51 LD="${i#*=}" 52 fi 53 ;; 54 --cross-prefix=*) 55 if [[ -n "${i#*=}" ]]; then 56 CROSS_PREFIX="${i#*=}" 57 fi 58 ;; 59 --) 60 break 61 ;; 62 *) 63 err "Unrecognized option $i" 64 usage 65 exit 1 66 ;; 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 108 ;; 109esac 110 111CCAR="ar" 112if [ "$LTO" = "y" ]; then 113 if [ "$CC_TYPE" = "clang" ]; then 114 if [[ "$LD_TYPE" != "gold" && "$LD_TYPE" != "lld" ]]; then 115 err "Using LTO with clang requires the gold or lld linker." 116 exit 1 117 fi 118 CCAR="llvm-ar" 119 else 120 CCAR="gcc-ar" 121 fi 122fi 123 124if [ -n "$CROSS_PREFIX" ]; then 125 expected_prefix=$($CC -dumpmachine) 126 127 if [ ! "$expected_prefix" = "$CROSS_PREFIX" ]; then 128 err "Cross prefix specified ($CROSS_PREFIX) does not match prefix of $CC ($expected_prefix)." 129 130 # Try to fix this automatically. Maybe the user set CROSS_PREFIX but not CC. 131 CC=$CROSS_PREFIX-$CC 132 if hash $CC 2> /dev/null; then 133 expected_prefix=$($CC -dumpmachine) 134 135 if [ "$expected_prefix" = "$CROSS_PREFIX" ]; then 136 err "Automatically changed CC to $CC" 137 else 138 err "Set CC to the appropriate compiler." 139 exit 1 140 fi 141 else 142 err "Set CC to the appropriate compiler." 143 exit 1 144 fi 145 146 fi 147 148 expected_prefix=$($CXX -dumpmachine) 149 150 if [ ! "$expected_prefix" = "$CROSS_PREFIX" ]; then 151 err "Cross prefix specified ($CROSS_PREFIX) does not match prefix of $CXX ($expected_prefix)." 152 153 # Try to fix this automatically. Maybe the user set CROSS_PREFIX but not CXX. 154 CXX=$CROSS_PREFIX-$CXX 155 if hash $CXX 2> /dev/null; then 156 expected_prefix=$($CXX -dumpmachine) 157 158 if [ "$expected_prefix" = "$CROSS_PREFIX" ]; then 159 err "Automatically changed CXX to $CXX" 160 else 161 err "Set CXX to the appropriate compiler." 162 exit 1 163 fi 164 else 165 err "Set CXX to the appropriate compiler." 166 exit 1 167 fi 168 fi 169fi 170 171function set_default() { 172 echo "DEFAULT_$1=$2" 173 echo "ifeq (\$(origin $1),default)" 174 echo "$1=$2" 175 echo "endif" 176 echo "" 177} 178 179set_default CC "$CC" 180set_default CXX "$CXX" 181set_default LD "$LD" 182 183echo "CCAR=$CCAR" 184echo "CC_TYPE=$CC_TYPE" 185echo "LD_TYPE=$LD_TYPE" 186 187if [ -n "$CROSS_PREFIX" ]; then 188 echo "CROSS_PREFIX=$CROSS_PREFIX" 189fi 190