xref: /spdk/scripts/detect_cc.sh (revision 7961de43413e7f818f7499bf8518909beb59c82f)
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