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