Correctly detect major version of GCC (#20059)

We were doing a very poor job detecting the major version of GCC by
parsing the output of --version.

This patches uses -dumpversion to make this parsing straightforward and
it also fixes a bunch of compiling issues on different platforms with
custom output for --version switches. For example, openSUSE first line
of the output includes the revision number and the parsing that was
being done did mix that number with the major version and breaks
building the nim compiler (as it doesn't find the 3 dots for an X.Y.Z semver
format, hence returning "false").

In this patch, we simply use -dumpversion (which has been at least from
1993, so we are safe :)
This commit is contained in:
kraptor 2022-07-18 21:24:39 +02:00 • committed by GitHub
commit efcb89fa70
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -14,7 +14,7 @@
import ropes, platform, condsyms, options, msgs, lineinfos, pathutils, modulepaths import ropes, platform, condsyms, options, msgs, lineinfos, pathutils, modulepaths
import std/[os, strutils, osproc, sha1, streams, sequtils, times, strtabs, json, jsonutils, sugar] import std/[os, strutils, osproc, sha1, streams, sequtils, times, strtabs, json, jsonutils, sugar, parseutils]
when defined(nimPreviewSlimSystem): when defined(nimPreviewSlimSystem):
import std/syncio import std/syncio
@ -525,25 +525,11 @@ proc ccHasSaneOverflow*(conf: ConfigRef): bool =
result = false # assume an old or crappy GCC result = false # assume an old or crappy GCC
var exe = getConfigVar(conf, conf.cCompiler, ".exe") var exe = getConfigVar(conf, conf.cCompiler, ".exe")
if exe.len == 0: exe = CC[conf.cCompiler].compilerExe if exe.len == 0: exe = CC[conf.cCompiler].compilerExe
let (s, exitCode) = try: execCmdEx(exe & " --version") except: ("", 1) # NOTE: should we need the full version, use -dumpfullversion
let (s, exitCode) = try: execCmdEx(exe & " -dumpversion") except: ("", 1)
if exitCode == 0: if exitCode == 0:
var i = 0 var major: int
var j = 0 discard parseInt(s, major)
# the version is the last part of the first line:
while i < s.len and s[i] != '\n':
if s[i] in {' ', '\t'}: j = i+1
inc i
if j > 0:
var major = 0
while j < s.len and s[j] in {'0'..'9'}:
major = major * 10 + (ord(s[j]) - ord('0'))
inc j
if i < s.len and s[j] == '.': inc j
while j < s.len and s[j] in {'0'..'9'}:
inc j
if j+1 < s.len and s[j] == '.' and s[j+1] in {'0'..'9'}:
# we found a third version number, chances are high
# we really parsed the version:
result = major >= 5 result = major >= 5
else: else:
result = conf.cCompiler == ccCLang result = conf.cCompiler == ccCLang