Skip to content

Commit a0a01d2

Browse files
committed
Added subroutines to detect compiler family and version
1 parent fec9619 commit a0a01d2

File tree

2 files changed

+164
-0
lines changed

2 files changed

+164
-0
lines changed

Diff for: internal/builder/diagnostics/compiler_detection.go

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
// This file is part of arduino-cli.
2+
//
3+
// Copyright 2023 ARDUINO SA (http://www.arduino.cc/)
4+
//
5+
// This software is released under the GNU General Public License version 3,
6+
// which covers the main part of arduino-cli.
7+
// The terms of this license can be found at:
8+
// https://www.gnu.org/licenses/gpl-3.0.en.html
9+
//
10+
// You can be released from the requirements of the above licenses by purchasing
11+
// a commercial license. Buying such a license is mandatory if you want to
12+
// modify or otherwise use the software for commercial activities involving the
13+
// Arduino software without disclosing the source code of your own applications.
14+
// To purchase a commercial license, send an email to [email protected].
15+
16+
package diagnostics
17+
18+
import (
19+
"bytes"
20+
"path/filepath"
21+
"strings"
22+
23+
"github.com/arduino/arduino-cli/executils"
24+
semver "go.bug.st/relaxed-semver"
25+
)
26+
27+
// DetectedCompiler represents a compiler detected from a given command line
28+
type DetectedCompiler struct {
29+
Name string
30+
Family string
31+
Version *semver.Version
32+
DetailedVersion []string
33+
}
34+
35+
// This function is overridden for mocking unit tests
36+
var runProcess = func(args ...string) []string {
37+
if cmd, err := executils.NewProcess(nil, args...); err == nil {
38+
out := &bytes.Buffer{}
39+
cmd.RedirectStdoutTo(out)
40+
cmd.Run()
41+
return splitLines(out.Bytes())
42+
}
43+
return nil
44+
}
45+
46+
// DetectCompilerFromCommandLine tries to detect a compiler from a given command line.
47+
// If probleCompiler is true, the compiler may be executed with different flags to
48+
// infer the version or capabilities.
49+
func DetectCompilerFromCommandLine(args []string, probeCompiler bool) *DetectedCompiler {
50+
if len(args) == 0 {
51+
return nil
52+
}
53+
basename := filepath.Base(args[0])
54+
family := ""
55+
if strings.Contains(basename, "g++") || strings.Contains(basename, "gcc") {
56+
family = "gcc"
57+
}
58+
res := &DetectedCompiler{
59+
Name: basename,
60+
Family: family,
61+
}
62+
63+
if family == "gcc" && probeCompiler {
64+
// Run "gcc --verion" to obtain more info
65+
res.DetailedVersion = runProcess(args[0], "--version")
66+
67+
// Usually on the first line we get the compiler architecture and
68+
// version (as last field), followed by the compiler license, for
69+
// example:
70+
//
71+
// g++ (Ubuntu 12.2.0-3ubuntu1) 12.2.0
72+
// Copyright (C) 2022 Free Software Foundation, Inc.
73+
// This is free software; see the source for copying conditions. There is NO
74+
// warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
75+
//
76+
if len(res.DetailedVersion) > 0 {
77+
split := strings.Split(res.DetailedVersion[0], " ")
78+
if len(split) >= 3 {
79+
res.Name = split[0]
80+
res.Version, _ = semver.Parse(split[len(split)-1])
81+
}
82+
}
83+
}
84+
return res
85+
}
+79
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// This file is part of arduino-cli.
2+
//
3+
// Copyright 2023 ARDUINO SA (http://www.arduino.cc/)
4+
//
5+
// This software is released under the GNU General Public License version 3,
6+
// which covers the main part of arduino-cli.
7+
// The terms of this license can be found at:
8+
// https://www.gnu.org/licenses/gpl-3.0.en.html
9+
//
10+
// You can be released from the requirements of the above licenses by purchasing
11+
// a commercial license. Buying such a license is mandatory if you want to
12+
// modify or otherwise use the software for commercial activities involving the
13+
// Arduino software without disclosing the source code of your own applications.
14+
// To purchase a commercial license, send an email to [email protected].
15+
16+
package diagnostics
17+
18+
import (
19+
"strings"
20+
"testing"
21+
22+
"github.com/stretchr/testify/require"
23+
)
24+
25+
func init() {
26+
runProcess = mockedRunProcessToGetCompilerVersion
27+
}
28+
29+
func mockedRunProcessToGetCompilerVersion(args ...string) []string {
30+
if strings.HasSuffix(args[0], "7.3.0-atmel3.6.1-arduino7/bin/avr-g++") && args[1] == "--version" {
31+
return []string{
32+
"avr-g++ (GCC) 7.3.0",
33+
"Copyright (C) 2017 Free Software Foundation, Inc.",
34+
"This is free software; see the source for copying conditions. There is NO",
35+
"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.",
36+
"",
37+
}
38+
}
39+
if strings.HasSuffix(args[0], "7.3.0-atmel3.6.1-arduino7/bin/avr-gcc") && args[1] == "--version" {
40+
return []string{
41+
"avr-gcc (GCC) 7.3.0",
42+
"Copyright (C) 2017 Free Software Foundation, Inc.",
43+
"This is free software; see the source for copying conditions. There is NO",
44+
"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.",
45+
"",
46+
}
47+
}
48+
if strings.HasSuffix(args[0], "xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch3/bin/xtensa-esp32-elf-g++") && args[1] == "--version" {
49+
return []string{
50+
"xtensa-esp32-elf-g++ (crosstool-NG esp-2021r2-patch3) 8.4.0",
51+
"Copyright (C) 2018 Free Software Foundation, Inc.",
52+
"This is free software; see the source for copying conditions. There is NO",
53+
"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.",
54+
"",
55+
}
56+
}
57+
58+
panic("missing mock for command line: " + strings.Join(args, " "))
59+
}
60+
61+
func TestCompilerDetection(t *testing.T) {
62+
comp := DetectCompilerFromCommandLine([]string{"~/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-g++"}, true)
63+
require.NotNil(t, comp)
64+
require.Equal(t, "gcc", comp.Family)
65+
require.Equal(t, "avr-g++", comp.Name)
66+
require.Equal(t, "7.3.0", comp.Version.String())
67+
68+
comp = DetectCompilerFromCommandLine([]string{"~/.arduino15/packages/arduino/tools/avr-gcc/7.3.0-atmel3.6.1-arduino7/bin/avr-gcc"}, true)
69+
require.NotNil(t, comp)
70+
require.Equal(t, "gcc", comp.Family)
71+
require.Equal(t, "avr-gcc", comp.Name)
72+
require.Equal(t, "7.3.0", comp.Version.String())
73+
74+
comp = DetectCompilerFromCommandLine([]string{"/home/megabug/.arduino15/packages/esp32/tools/xtensa-esp32-elf-gcc/gcc8_4_0-esp-2021r2-patch3/bin/xtensa-esp32-elf-g++"}, true)
75+
require.NotNil(t, comp)
76+
require.Equal(t, "gcc", comp.Family)
77+
require.Equal(t, "xtensa-esp32-elf-g++", comp.Name)
78+
require.Equal(t, "8.4.0", comp.Version.String())
79+
}

0 commit comments

Comments
 (0)