Subject: Re: [PATCH v2 0/3] detect-compiler: clang updates

From: Ævar Arnfjörð Bjarmason <[email-masked]>
Date: Sat, 07 Aug 2021 04:02:45 +0200

On Fri, Aug 06 2021, Junio C Hamano wrote:

> So here is a mini-series that summarizes what has been suggested so
> far on the topic.
>
> Carlo Marcelo Arenas Belón (1):
>   build: update detect-compiler for newer Xcode version
>
> Jeff King (1):
>   build: clang version may not be followed by extra words
>
> Junio C Hamano (1):
>   build: catch clang that identifies itself as "$VENDOR clang"
>
>  detect-compiler | 9 +++------
>  1 file changed, 3 insertions(+), 6 deletions(-)

Perhaps I've missed some obvious reason not to do this, but why are we
parsing the --version output of two modern compilers, as opposed to just
asking them what type/version they are via their usual macro facilities?
I.e. something like the below:

diff --git a/detect-compiler b/detect-compiler
index 70b754481c8..37908ac9ea8 100755
--- a/detect-compiler
+++ b/detect-compiler
@@ -5,19 +5,47 @@
 
 CC="$*"
 
-# we get something like (this is at least true for gcc and clang)
+#!/bin/sh
 #
-# FreeBSD clang version 3.4.1 (tags/RELEASE...)
-get_version_line() {
-	$CC -v 2>&1 | grep ' version '
-}
+# Probe the compiler for vintage, version, etc. This is used for setting
+# optional make knobs under the DEVELOPER knob.
+
+CC="$*"
+
+v=$($CC -E - <<-EOF 2>&1 | grep -e '=')
+GNUC=__GNUC__
+GNUC_MINOR=__GNUC_MINOR__
+GNUC_PATCHLEVEL=__GNUC_PATCHLEVEL__
+clang=__clang__
+clang_major=__clang_major__
+clang_minor=__clang_minor__
+clang_patchlevel=__clang_patchlevel__
+EOF
+eval "$v"
 
 get_family() {
-	get_version_line | sed 's/^\(.*\) version [0-9][^ ]* .*/\1/'
+	# Clang also sets the GNUC macros, but GCC does not set
+	# clang's.
+	if test "$clang" != "__clang__"
+	then
+		echo clang
+	elif test "$GNUC" != "__GNUC__"
+	then
+		echo gcc
+	else
+		echo unknown
+	fi
 }
 
 get_version() {
-	get_version_line | sed 's/^.* version \([0-9][^ ]*\) .*/\1/'
+	case "$(get_family)" in
+	clang)
+		echo "$clang_major.$clang_minor.$clang_patchlevel"
+		;;
+	gcc)
+		echo "$GNUC.$GNUC_MINOR.$GNUC_PATCHLEVEL"
+		;;
+	esac
 }
 
 print_flags() {
@@ -41,12 +69,6 @@ gcc)
 clang)
 	print_flags clang
 	;;
-"FreeBSD clang")
-	print_flags clang
-	;;
-"Apple LLVM")
-	print_flags clang
-	;;
 *)
 	: unknown compiler family
 	;;