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