Skip to content

Commit f28fffb

Browse files
author
Federico Fissore
committedNov 11, 2015
Brand new way of discovering libraries and related -I gcc parameters
For each source file found, gcc -E is continuously run until it doesn't report any error. When it reports an error, it is in the form of Ethernet.h: No such file or directory #include <Ethernet.h> Ethernet.h is searched from known libraries, its -I param added to gcc -E and gcc -E is rerun If Ethernet.h is not found, preprocessing fails and reports an error If found, the collected list of -I params is used to preprocess another (sketch or library) source file, until all dependendent libraries are resolved Fixes #33 Signed-off-by: Federico Fissore <f.fissore@arduino.cc>
1 parent d46c7ce commit f28fffb

File tree

23 files changed

+380
-131
lines changed

23 files changed

+380
-131
lines changed
 

‎src/arduino.cc/builder/builder_utils/utils.go

+44-11
Original file line numberDiff line numberDiff line change
@@ -34,9 +34,10 @@ import (
3434
"arduino.cc/builder/i18n"
3535
"arduino.cc/builder/props"
3636
"arduino.cc/builder/utils"
37+
"bufio"
3738
"fmt"
38-
"io"
3939
"os"
40+
"os/exec"
4041
"path/filepath"
4142
"strings"
4243
)
@@ -279,10 +280,27 @@ func ArchiveCompiledFiles(buildPath string, archiveFile string, objectFiles []st
279280
}
280281

281282
func ExecRecipe(properties map[string]string, recipe string, removeUnsetProperties bool, echoCommandLine bool, echoOutput bool, logger i18n.Logger) ([]byte, error) {
282-
return ExecRecipeSpecifyStdOutStdErr(properties, recipe, removeUnsetProperties, echoCommandLine, echoOutput, logger, os.Stdout, os.Stderr)
283+
command, err := PrepareCommandForRecipe(properties, recipe, removeUnsetProperties, echoCommandLine, echoOutput, logger)
284+
if err != nil {
285+
return nil, utils.WrapError(err)
286+
}
287+
288+
if echoOutput {
289+
command.Stdout = os.Stdout
290+
}
291+
292+
command.Stderr = os.Stderr
293+
294+
if echoOutput {
295+
err := command.Run()
296+
return nil, utils.WrapError(err)
297+
}
298+
299+
bytes, err := command.Output()
300+
return bytes, utils.WrapError(err)
283301
}
284302

285-
func ExecRecipeSpecifyStdOutStdErr(properties map[string]string, recipe string, removeUnsetProperties bool, echoCommandLine bool, echoOutput bool, logger i18n.Logger, stdout io.Writer, stderr io.Writer) ([]byte, error) {
303+
func PrepareCommandForRecipe(properties map[string]string, recipe string, removeUnsetProperties bool, echoCommandLine bool, echoOutput bool, logger i18n.Logger) (*exec.Cmd, error) {
286304
pattern := properties[recipe]
287305
if pattern == constants.EMPTY_STRING {
288306
return nil, utils.ErrorfWithLogger(logger, constants.MSG_PATTERN_MISSING, recipe)
@@ -306,19 +324,34 @@ func ExecRecipeSpecifyStdOutStdErr(properties map[string]string, recipe string,
306324
fmt.Println(commandLine)
307325
}
308326

309-
if echoOutput {
310-
command.Stdout = stdout
327+
return command, nil
328+
}
329+
330+
func ExecRecipeCollectStdErr(properties map[string]string, recipe string, removeUnsetProperties bool, echoCommandLine bool, echoOutput bool, logger i18n.Logger) (string, error, error) {
331+
command, err := PrepareCommandForRecipe(properties, recipe, removeUnsetProperties, echoCommandLine, echoOutput, logger)
332+
if err != nil {
333+
return "", nil, utils.WrapError(err)
311334
}
312335

313-
command.Stderr = stderr
336+
stderr, err := command.StderrPipe()
337+
if err != nil {
338+
return "", nil, utils.WrapError(err)
339+
}
314340

315-
if echoOutput {
316-
err := command.Run()
317-
return nil, utils.WrapError(err)
341+
err = command.Start()
342+
if err != nil {
343+
return "", nil, utils.WrapError(err)
318344
}
319345

320-
bytes, err := command.Output()
321-
return bytes, utils.WrapError(err)
346+
collectedStdErr := ""
347+
sc := bufio.NewScanner(stderr)
348+
for sc.Scan() {
349+
collectedStdErr += sc.Text() + "\n"
350+
}
351+
352+
err = command.Wait()
353+
354+
return collectedStdErr, err, nil
322355
}
323356

324357
func RemoveHyphenMDDFlagFromGCCCommandLine(properties map[string]string) {

‎src/arduino.cc/builder/constants/constants.go

+2
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,7 @@ const CTX_DEBUG_LEVEL = "debugLevel"
9595
const CTX_FOLDERS_WITH_SOURCES_QUEUE = "foldersWithSourcesQueue"
9696
const CTX_FQBN = "fqbn"
9797
const CTX_GCC_MINUS_E_SOURCE = "gccMinusESource"
98+
const CTX_GCC_MINUS_E_STDERR = "gccMinusEOutput"
9899
const CTX_GCC_MINUS_M_OUTPUT = "gccMinusMOutput"
99100
const CTX_HARDWARE_FOLDERS = "hardwareFolders"
100101
const CTX_HARDWARE = "hardware"
@@ -103,6 +104,7 @@ const CTX_IMPORTED_LIBRARIES = "importedLibraries"
103104
const CTX_INCLUDE_FOLDERS = "includeFolders"
104105
const CTX_INCLUDE_SECTION = "includeSection"
105106
const CTX_INCLUDES = "includes"
107+
const CTX_INCLUDES_JUST_FOUND = "includesJustFound"
106108
const CTX_LIBRARIES_BUILD_PATH = "librariesBuildPath"
107109
const CTX_LIBRARIES_FOLDERS = "librariesFolders"
108110
const CTX_LIBRARIES = "libraries"

‎src/arduino.cc/builder/container_find_includes.go

+37-26
Original file line numberDiff line numberDiff line change
@@ -44,22 +44,11 @@ func (s *ContainerFindIncludes) Run(context map[string]interface{}) error {
4444
return utils.WrapError(err)
4545
}
4646

47-
sketch := context[constants.CTX_SKETCH].(*types.Sketch)
4847
sketchBuildPath := context[constants.CTX_SKETCH_BUILD_PATH].(string)
49-
wheelSpins := context[constants.CTX_LIBRARY_DISCOVERY_RECURSION_DEPTH].(int)
50-
for i := 0; i < wheelSpins; i++ {
51-
commands := []types.Command{
52-
&IncludesFinderWithGCC{SourceFile: filepath.Join(sketchBuildPath, filepath.Base(sketch.MainFile.Name)+".cpp")},
53-
&GCCMinusMOutputParser{},
54-
&IncludesToIncludeFolders{},
55-
}
56-
57-
for _, command := range commands {
58-
err := runCommand(context, command)
59-
if err != nil {
60-
return utils.WrapError(err)
61-
}
62-
}
48+
sketch := context[constants.CTX_SKETCH].(*types.Sketch)
49+
err = findIncludesUntilDone(context, filepath.Join(sketchBuildPath, filepath.Base(sketch.MainFile.Name)+".cpp"))
50+
if err != nil {
51+
return utils.WrapError(err)
6352
}
6453

6554
foldersWithSources := context[constants.CTX_FOLDERS_WITH_SOURCES_QUEUE].(*types.UniqueSourceFolderQueue)
@@ -81,18 +70,13 @@ func (s *ContainerFindIncludes) Run(context map[string]interface{}) error {
8170
sourceFiles := context[constants.CTX_COLLECTED_SOURCE_FILES_QUEUE].(*types.UniqueStringQueue)
8271

8372
for !sourceFiles.Empty() {
84-
commands := []types.Command{
85-
&IncludesFinderWithGCC{SourceFile: sourceFiles.Pop().(string)},
86-
&GCCMinusMOutputParser{},
87-
&IncludesToIncludeFolders{},
88-
&CollectAllSourceFilesFromFoldersWithSources{},
73+
err = findIncludesUntilDone(context, sourceFiles.Pop().(string))
74+
if err != nil {
75+
return utils.WrapError(err)
8976
}
90-
91-
for _, command := range commands {
92-
err := runCommand(context, command)
93-
if err != nil {
94-
return utils.WrapError(err)
95-
}
77+
err := runCommand(context, &CollectAllSourceFilesFromFoldersWithSources{})
78+
if err != nil {
79+
return utils.WrapError(err)
Has a comment. Original line has a comment.
9680
}
9781
}
9882

@@ -107,3 +91,30 @@ func runCommand(context map[string]interface{}, command types.Command) error {
10791
}
10892
return nil
10993
}
94+
95+
func findIncludesUntilDone(context map[string]interface{}, sourceFile string) error {
96+
importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library)
97+
done := false
98+
for !done {
99+
commands := []types.Command{
100+
&GCCPreprocRunnerForDiscoveringIncludes{SourceFile: sourceFile},
101+
&IncludesFinderWithRegExp{ContextField: constants.CTX_GCC_MINUS_E_SOURCE},
102+
&IncludesToIncludeFolders{},
103+
}
104+
for _, command := range commands {
105+
err := runCommand(context, command)
106+
if err != nil {
107+
return utils.WrapError(err)
108+
}
109+
}
110+
if len(context[constants.CTX_INCLUDES_JUST_FOUND].([]string)) == 0 {
111+
done = true
112+
} else if len(context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library)) == len(importedLibraries) {
113+
err := runCommand(context, &GCCPreprocRunner{})
114+
return utils.WrapError(err)
115+
}
116+
importedLibraries = context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library)
117+
context[constants.CTX_INCLUDES_JUST_FOUND] = []string{}
118+
}
119+
return nil
120+
}

‎src/arduino.cc/builder/gcc_minus_m_output_parser.go

+1-6
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,7 @@ func (s *GCCMinusMOutputParser) Run(context map[string]interface{}) error {
6060
return nil
6161
}
6262

63-
previousIncludes := utils.SliceToMapStringBool(context[constants.CTX_INCLUDES].([]string), true)
64-
currentIncludes := utils.SliceToMapStringBool(includes, true)
65-
66-
mergedIncludes := utils.MergeMapsOfStringBool(previousIncludes, currentIncludes)
67-
68-
context[constants.CTX_INCLUDES] = utils.KeysOfMapOfStringBool(mergedIncludes)
63+
context[constants.CTX_INCLUDES] = utils.AddStringsToStringsSet(context[constants.CTX_INCLUDES].([]string), includes)
Has comments. Original line has comments.
6964

7065
return nil
7166
}

‎src/arduino.cc/builder/gcc_preproc_runner.go

+34-9
Original file line numberDiff line numberDiff line change
@@ -42,17 +42,9 @@ import (
4242
type GCCPreprocRunner struct{}
4343

4444
func (s *GCCPreprocRunner) Run(context map[string]interface{}) error {
45-
buildProperties := utils.GetMapStringStringOrDefault(context, constants.CTX_BUILD_PROPERTIES)
46-
properties := utils.MergeMapsOfStrings(make(map[string]string), buildProperties)
47-
4845
sketchBuildPath := context[constants.CTX_SKETCH_BUILD_PATH].(string)
4946
sketch := context[constants.CTX_SKETCH].(*types.Sketch)
50-
properties[constants.BUILD_PROPERTIES_SOURCE_FILE] = filepath.Join(sketchBuildPath, filepath.Base(sketch.MainFile.Name)+".cpp")
51-
52-
includes := context[constants.CTX_INCLUDE_FOLDERS].([]string)
53-
includes = utils.Map(includes, utils.WrapWithHyphenI)
54-
properties[constants.BUILD_PROPERTIES_INCLUDES] = strings.Join(includes, constants.SPACE)
55-
builder_utils.RemoveHyphenMDDFlagFromGCCCommandLine(properties)
47+
properties := prepareGCCPreprocRecipeProperties(context, filepath.Join(sketchBuildPath, filepath.Base(sketch.MainFile.Name)+".cpp"))
5648

5749
verbose := context[constants.CTX_VERBOSE].(bool)
5850
logger := context[constants.CTX_LOGGER].(i18n.Logger)
@@ -65,3 +57,36 @@ func (s *GCCPreprocRunner) Run(context map[string]interface{}) error {
6557

6658
return nil
6759
}
60+
61+
type GCCPreprocRunnerForDiscoveringIncludes struct {
62+
SourceFile string
63+
}
64+
65+
func (s *GCCPreprocRunnerForDiscoveringIncludes) Run(context map[string]interface{}) error {
66+
properties := prepareGCCPreprocRecipeProperties(context, s.SourceFile)
67+
68+
verbose := context[constants.CTX_VERBOSE].(bool)
69+
logger := context[constants.CTX_LOGGER].(i18n.Logger)
70+
output, _, err := builder_utils.ExecRecipeCollectStdErr(properties, constants.RECIPE_PREPROC_MACROS, true, verbose, false, logger)
Has comments. Original line has comments.
71+
if err != nil {
72+
return utils.WrapError(err)
73+
}
74+
75+
context[constants.CTX_GCC_MINUS_E_SOURCE] = string(output)
76+
77+
return nil
78+
}
79+
80+
func prepareGCCPreprocRecipeProperties(context map[string]interface{}, sourceFile string) map[string]string {
81+
buildProperties := utils.GetMapStringStringOrDefault(context, constants.CTX_BUILD_PROPERTIES)
82+
properties := utils.MergeMapsOfStrings(make(map[string]string), buildProperties)
83+
84+
properties[constants.BUILD_PROPERTIES_SOURCE_FILE] = sourceFile
85+
86+
includes := context[constants.CTX_INCLUDE_FOLDERS].([]string)
87+
includes = utils.Map(includes, utils.WrapWithHyphenI)
88+
properties[constants.BUILD_PROPERTIES_INCLUDES] = strings.Join(includes, constants.SPACE)
89+
builder_utils.RemoveHyphenMDDFlagFromGCCCommandLine(properties)
Has comments. Original line has comments.
90+
91+
return properties
92+
}

‎src/arduino.cc/builder/hardware/platform.keys.rewrite.txt

+7
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,10 @@ new.10.recipe.ar.pattern="{compiler.path}{compiler.ar.cmd}" {compiler.ar.flags}
3636

3737
old.11.recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} -o "{build.path}/{build.project_name}.elf" {object_files} "{build.path}/{archive_file}" "-L{build.path}" -lm
3838
new.11.recipe.c.combine.pattern="{compiler.path}{compiler.c.elf.cmd}" {compiler.c.elf.flags} -mmcu={build.mcu} -o "{build.path}/{build.project_name}.elf" {object_files} "{archive_file_path}" "-L{build.path}" -lm
39+
40+
#generic again
41+
old.12.preproc.includes.flags=-w -x c++ -M -MG -MP
42+
new.12.preproc.includes.flags=-w -x c++ -M -MG -MP -include Arduino.h
43+
44+
old.13.preproc.macros.flags=-w -x c++ -E -CC
45+
new.13.preproc.macros.flags=-w -x c++ -E -CC -include Arduino.h

‎src/arduino.cc/builder/hardware/platform.txt

+4-3
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,10 @@ tools.ctags.pattern="{cmd.path}" -u --language-force=c++ -f - --c++-kinds=svpf -
77
# additional entries
88
tools.avrdude.path={runtime.tools.avrdude.path}
99

10-
preproc.includes.flags=-w -x c++ -M -MG -MP
11-
recipe.preproc.includes="{compiler.path}{compiler.cpp.cmd}" {preproc.includes.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} "{source_file}"
10+
preproc.includes.flags=-w -x c++ -M -MG -MP -include Arduino.h
11+
preproc.includes.compatibility_flags={build.mbed_api_include} {build.nRF51822_api_include} {build.ble_api_include} {compiler.libsam.c.flags} {compiler.arm.cmsis.path} {build.variant_system_include}
Has comments. Original line has comments.
12+
recipe.preproc.includes="{compiler.path}{compiler.cpp.cmd}" {preproc.includes.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {preproc.includes.compatibility_flags} {includes} "{source_file}"
1213

13-
preproc.macros.flags=-w -x c++ -E -CC
14+
preproc.macros.flags=-w -x c++ -E -CC -include Arduino.h
Has comments. Original line has comments.
1415
preproc.macros.compatibility_flags={build.mbed_api_include} {build.nRF51822_api_include} {build.ble_api_include} {compiler.libsam.c.flags} {compiler.arm.cmsis.path} {build.variant_system_include}
1516
recipe.preproc.macros="{compiler.path}{compiler.cpp.cmd}" {compiler.cpreprocessor.flags} {compiler.cpp.flags} {preproc.macros.flags} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {preproc.macros.compatibility_flags} {includes} "{source_file}"

‎src/arduino.cc/builder/includes_finder_with_regexp.go

+14-4
Original file line numberDiff line numberDiff line change
@@ -31,24 +31,34 @@ package builder
3131

3232
import (
3333
"arduino.cc/builder/constants"
34+
"arduino.cc/builder/utils"
3435
"regexp"
3536
"strings"
3637
)
3738

3839
var INCLUDE_REGEXP = regexp.MustCompile("(?ms)^\\s*#include\\s*[<\"](\\S+)[\">]")
Has comments. Original line has comments.
3940

40-
type IncludesFinderWithRegExp struct{}
41+
type IncludesFinderWithRegExp struct {
42+
ContextField string
43+
}
4144

4245
func (s *IncludesFinderWithRegExp) Run(context map[string]interface{}) error {
43-
source := context[constants.CTX_SOURCE].(string)
46+
source := context[s.ContextField].(string)
4447

4548
matches := INCLUDE_REGEXP.FindAllStringSubmatch(source, -1)
46-
var includes []string
49+
includes := []string{}
4750
for _, match := range matches {
4851
includes = append(includes, strings.TrimSpace(match[1]))
4952
}
5053

51-
context[constants.CTX_INCLUDES] = includes
54+
context[constants.CTX_INCLUDES_JUST_FOUND] = includes
55+
56+
if !utils.MapHas(context, constants.CTX_INCLUDES) {
57+
context[constants.CTX_INCLUDES] = includes
58+
return nil
59+
}
60+
61+
context[constants.CTX_INCLUDES] = utils.AddStringsToStringsSet(context[constants.CTX_INCLUDES].([]string), includes)
5262

5363
return nil
5464
}

‎src/arduino.cc/builder/test/builder_test.go

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ func TestBuilderEmptySketch(t *testing.T) {
5353
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
5454
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
5555
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
56-
// context[constants.CTX_VERBOSE] = true
57-
// context[constants.CTX_DEBUG_LEVEL] = 10
56+
context[constants.CTX_VERBOSE] = true
57+
context[constants.CTX_DEBUG_LEVEL] = 10
5858

5959
command := builder.Builder{}
6060
err := command.Run(context)

‎src/arduino.cc/builder/test/coan_runner_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func TestCoanRunner(t *testing.T) {
5454
context[constants.CTX_FQBN] = "arduino:avr:leonardo"
5555
context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch2", "SketchWithIfDef.ino")
5656
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
57-
context[constants.CTX_VERBOSE] = false
57+
context[constants.CTX_VERBOSE] = true
5858

5959
commands := []types.Command{
6060
&builder.SetupHumanLoggerIfMissing{},

‎src/arduino.cc/builder/test/ctags_runner_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func TestCTagsRunner(t *testing.T) {
5656
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
5757
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
5858
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
59-
context[constants.CTX_VERBOSE] = false
59+
context[constants.CTX_VERBOSE] = true
6060

6161
commands := []types.Command{
6262
&builder.SetupHumanLoggerIfMissing{},
@@ -106,7 +106,7 @@ func TestCTagsRunnerSketchWithClass(t *testing.T) {
106106
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
107107
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
108108
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
109-
context[constants.CTX_VERBOSE] = false
109+
context[constants.CTX_VERBOSE] = true
110110

111111
commands := []types.Command{
112112
&builder.SetupHumanLoggerIfMissing{},
@@ -154,7 +154,7 @@ func TestCTagsRunnerSketchWithTypename(t *testing.T) {
154154
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
155155
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
156156
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
157-
context[constants.CTX_VERBOSE] = false
157+
context[constants.CTX_VERBOSE] = true
158158

159159
commands := []types.Command{
160160
&builder.SetupHumanLoggerIfMissing{},
@@ -201,7 +201,7 @@ func TestCTagsRunnerSketchWithNamespace(t *testing.T) {
201201
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
202202
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
203203
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
204-
context[constants.CTX_VERBOSE] = false
204+
context[constants.CTX_VERBOSE] = true
205205

206206
commands := []types.Command{
207207
&builder.SetupHumanLoggerIfMissing{},

‎src/arduino.cc/builder/test/hardware_loader_test.go

+4-4
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ func TestLoadHardware(t *testing.T) {
8181
require.Equal(t, "{runtime.tools.ctags.path}", packages.Properties["tools.ctags.path"])
8282
require.Equal(t, "\"{cmd.path}\" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives \"{source_file}\"", packages.Properties["tools.ctags.pattern"])
8383
require.Equal(t, "{runtime.tools.avrdude.path}", packages.Properties["tools.avrdude.path"])
84-
require.Equal(t, "-w -x c++ -E -CC", packages.Properties["preproc.macros.flags"])
84+
require.Equal(t, "-w -x c++ -E -CC -include Arduino.h", packages.Properties["preproc.macros.flags"])
8585
}
8686

8787
func TestLoadHardwareMixingUserHardwareFolder(t *testing.T) {
@@ -130,8 +130,8 @@ func TestLoadHardwareMixingUserHardwareFolder(t *testing.T) {
130130

131131
require.Equal(t, "AVRISP mkII", avrPlatform.Programmers["avrispmkii"][constants.PROGRAMMER_NAME])
132132

133-
require.Equal(t, "-w -x c++ -M -MG -MP", avrPlatform.Properties["preproc.includes.flags"])
134-
require.Equal(t, "-w -x c++ -E -CC", avrPlatform.Properties["preproc.macros.flags"])
133+
require.Equal(t, "-w -x c++ -M -MG -MP -include Arduino.h", avrPlatform.Properties["preproc.includes.flags"])
134+
require.Equal(t, "-w -x c++ -E -CC -include Arduino.h", avrPlatform.Properties["preproc.macros.flags"])
135135
require.Equal(t, "\"{compiler.path}{compiler.cpp.cmd}\" {compiler.cpp.flags} {preproc.includes.flags} -mmcu={build.mcu} -DF_CPU={build.f_cpu} -DARDUINO={runtime.ide.version} -DARDUINO_{build.board} -DARDUINO_ARCH_{build.arch} {compiler.cpp.extra_flags} {build.extra_flags} {includes} \"{source_file}\"", avrPlatform.Properties[constants.RECIPE_PREPROC_INCLUDES])
136136
require.False(t, utils.MapStringStringHas(avrPlatform.Properties, "preproc.macros.compatibility_flags"))
137137

@@ -146,7 +146,7 @@ func TestLoadHardwareMixingUserHardwareFolder(t *testing.T) {
146146
require.Equal(t, "{runtime.tools.ctags.path}", packages.Properties["tools.ctags.path"])
147147
require.Equal(t, "\"{cmd.path}\" -u --language-force=c++ -f - --c++-kinds=svpf --fields=KSTtzns --line-directives \"{source_file}\"", packages.Properties["tools.ctags.pattern"])
148148
require.Equal(t, "{runtime.tools.avrdude.path}", packages.Properties["tools.avrdude.path"])
149-
require.Equal(t, "-w -x c++ -E -CC", packages.Properties["preproc.macros.flags"])
149+
require.Equal(t, "-w -x c++ -E -CC -include Arduino.h", packages.Properties["preproc.macros.flags"])
150150
require.Equal(t, "{build.mbed_api_include} {build.nRF51822_api_include} {build.ble_api_include} {compiler.libsam.c.flags} {compiler.arm.cmsis.path} {build.variant_system_include}", packages.Properties["preproc.macros.compatibility_flags"])
151151

152152
if runtime.GOOS != "windows" {

‎src/arduino.cc/builder/test/helper_tools_downloader.go

+1
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ func DownloadCoresAndToolsAndLibraries(t *testing.T) {
122122

123123
boardsManagerTools := []Tool{
124124
Tool{Name: "openocd", Version: "0.9.0-arduino", Package: "arduino"},
125+
Tool{Name: "CMSIS", Version: "4.0.0-atmel", Package: "arduino"},
125126
}
126127

127128
boardsManagerRFduinoTools := []Tool{

‎src/arduino.cc/builder/test/includes_finder_with_gcc_test.go

+98-19
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func TestIncludesFinderWithGCC(t *testing.T) {
5454
context[constants.CTX_FQBN] = "arduino:avr:leonardo"
5555
context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch2", "SketchWithIfDef.ino")
5656
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
57-
context[constants.CTX_VERBOSE] = false
57+
context[constants.CTX_VERBOSE] = true
5858

5959
commands := []types.Command{
6060
&builder.SetupHumanLoggerIfMissing{},
@@ -71,12 +71,7 @@ func TestIncludesFinderWithGCC(t *testing.T) {
7171
NoError(t, err)
7272
}
7373

74-
require.NotNil(t, context[constants.CTX_INCLUDES])
75-
includes := context[constants.CTX_INCLUDES].([]string)
76-
require.Equal(t, 2, len(includes))
77-
sort.Strings(includes)
78-
require.Equal(t, filepath.Join(buildPath, constants.FOLDER_SKETCH, "empty_1.h"), includes[0])
79-
require.Equal(t, filepath.Join(buildPath, constants.FOLDER_SKETCH, "empty_2.h"), includes[1])
74+
require.Nil(t, context[constants.CTX_INCLUDES])
8075
}
8176

8277
func TestIncludesFinderWithGCCSketchWithConfig(t *testing.T) {
@@ -94,7 +89,7 @@ func TestIncludesFinderWithGCCSketchWithConfig(t *testing.T) {
9489
context[constants.CTX_FQBN] = "arduino:avr:leonardo"
9590
context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_config", "sketch_with_config.ino")
9691
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
97-
context[constants.CTX_VERBOSE] = false
92+
context[constants.CTX_VERBOSE] = true
9893

9994
commands := []types.Command{
10095
&builder.SetupHumanLoggerIfMissing{},
@@ -113,8 +108,7 @@ func TestIncludesFinderWithGCCSketchWithConfig(t *testing.T) {
113108

114109
require.NotNil(t, context[constants.CTX_INCLUDES])
115110
includes := context[constants.CTX_INCLUDES].([]string)
116-
require.True(t, utils.SliceContains(includes, filepath.Join(buildPath, constants.FOLDER_SKETCH, "config.h")))
117-
require.True(t, utils.SliceContains(includes, filepath.Join(buildPath, constants.FOLDER_SKETCH, "includes")+"/de bug.h"))
111+
require.Equal(t, 1, len(includes))
118112
require.True(t, utils.SliceContains(includes, "Bridge.h"))
119113

120114
importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library)
@@ -136,7 +130,7 @@ func TestIncludesFinderWithGCCSketchWithDependendLibraries(t *testing.T) {
136130
context[constants.CTX_FQBN] = "arduino:avr:leonardo"
137131
context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_dependend_libraries", "sketch.ino")
138132
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
139-
context[constants.CTX_VERBOSE] = false
133+
context[constants.CTX_VERBOSE] = true
140134

141135
commands := []types.Command{
142136
&builder.SetupHumanLoggerIfMissing{},
@@ -155,16 +149,13 @@ func TestIncludesFinderWithGCCSketchWithDependendLibraries(t *testing.T) {
155149

156150
require.NotNil(t, context[constants.CTX_INCLUDES])
157151
includes := context[constants.CTX_INCLUDES].([]string)
158-
require.Equal(t, 7, len(includes))
152+
require.Equal(t, 4, len(includes))
159153

160154
sort.Strings(includes)
161-
require.Equal(t, Abs(t, filepath.Join("dependent_libraries", "library1"))+"/library1.h", includes[0])
162-
require.Equal(t, Abs(t, filepath.Join("dependent_libraries", "library2"))+"/library2.h", includes[1])
163-
require.Equal(t, Abs(t, filepath.Join("dependent_libraries", "library3"))+"/library3.h", includes[2])
164-
require.Equal(t, "library1.h", includes[3])
165-
require.Equal(t, "library2.h", includes[4])
166-
require.Equal(t, "library3.h", includes[5])
167-
require.Equal(t, "library4.h", includes[6])
155+
require.Equal(t, "library1.h", includes[0])
156+
require.Equal(t, "library2.h", includes[1])
157+
require.Equal(t, "library3.h", includes[2])
158+
require.Equal(t, "library4.h", includes[3])
168159

169160
importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library)
170161
require.Equal(t, 4, len(importedLibraries))
@@ -175,3 +166,91 @@ func TestIncludesFinderWithGCCSketchWithDependendLibraries(t *testing.T) {
175166
require.Equal(t, "library3", importedLibraries[2].Name)
176167
require.Equal(t, "library4", importedLibraries[3].Name)
177168
}
169+
170+
func TestIncludesFinderWithGCCSketchWithThatChecksIfSPIHasTransactions(t *testing.T) {
171+
DownloadCoresAndToolsAndLibraries(t)
172+
173+
context := make(map[string]interface{})
174+
175+
buildPath := SetupBuildPath(t, context)
176+
defer os.RemoveAll(buildPath)
177+
178+
context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"}
179+
context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"}
180+
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
181+
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"dependent_libraries", "libraries"}
182+
context[constants.CTX_FQBN] = "arduino:avr:leonardo"
183+
context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_that_checks_if_SPI_has_transactions", "sketch.ino")
184+
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
185+
context[constants.CTX_VERBOSE] = true
186+
187+
commands := []types.Command{
188+
&builder.SetupHumanLoggerIfMissing{},
189+
190+
&builder.ContainerSetupHardwareToolsLibsSketchAndProps{},
191+
192+
&builder.ContainerMergeCopySketchFiles{},
193+
194+
&builder.ContainerFindIncludes{},
195+
}
196+
197+
for _, command := range commands {
198+
err := command.Run(context)
199+
NoError(t, err)
200+
}
201+
202+
require.NotNil(t, context[constants.CTX_INCLUDES])
203+
includes := context[constants.CTX_INCLUDES].([]string)
204+
require.Equal(t, 1, len(includes))
205+
require.Equal(t, "SPI.h", includes[0])
206+
207+
importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library)
208+
require.Equal(t, 1, len(importedLibraries))
209+
require.Equal(t, "SPI", importedLibraries[0].Name)
210+
}
211+
212+
func TestIncludesFinderWithGCCSketchWithThatChecksIfSPIHasTransactionsAndIncludesMissingEthernet(t *testing.T) {
213+
DownloadCoresAndToolsAndLibraries(t)
214+
215+
context := make(map[string]interface{})
216+
217+
buildPath := SetupBuildPath(t, context)
218+
defer os.RemoveAll(buildPath)
219+
220+
context[constants.CTX_HARDWARE_FOLDERS] = []string{filepath.Join("..", "hardware"), "hardware", "downloaded_hardware"}
221+
context[constants.CTX_TOOLS_FOLDERS] = []string{"downloaded_tools"}
222+
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
223+
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"dependent_libraries", "libraries"}
224+
context[constants.CTX_FQBN] = "arduino:avr:leonardo"
225+
context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_that_checks_if_SPI_has_transactions_and_includes_missing_Ethernet", "sketch.ino")
226+
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
227+
context[constants.CTX_VERBOSE] = true
228+
229+
commands := []types.Command{
230+
&builder.SetupHumanLoggerIfMissing{},
231+
232+
&builder.ContainerSetupHardwareToolsLibsSketchAndProps{},
233+
234+
&builder.ContainerMergeCopySketchFiles{},
235+
}
236+
237+
for _, command := range commands {
238+
err := command.Run(context)
239+
NoError(t, err)
240+
}
241+
242+
command := &builder.ContainerFindIncludes{}
243+
err := command.Run(context)
244+
require.Error(t, err)
245+
246+
require.NotNil(t, context[constants.CTX_INCLUDES])
247+
includes := context[constants.CTX_INCLUDES].([]string)
248+
require.Equal(t, 2, len(includes))
249+
sort.Strings(includes)
250+
require.Equal(t, "Ethernet.h", includes[0])
251+
require.Equal(t, "SPI.h", includes[1])
252+
253+
importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library)
254+
require.Equal(t, 1, len(importedLibraries))
255+
require.Equal(t, "SPI", importedLibraries[0].Name)
256+
}

‎src/arduino.cc/builder/test/includes_finder_with_regexp_test.go

+62-6
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ import (
3939
"testing"
4040
)
4141

42-
func TestIncludesFinderWithRegExp(t *testing.T) {
42+
func TestIncludesFinderWithRegExpCoanOutput(t *testing.T) {
4343
DownloadCoresAndToolsAndLibraries(t)
4444

4545
context := make(map[string]interface{})
@@ -52,7 +52,7 @@ func TestIncludesFinderWithRegExp(t *testing.T) {
5252
context[constants.CTX_FQBN] = "arduino:avr:leonardo"
5353
context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch2", "SketchWithIfDef.ino")
5454
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
55-
context[constants.CTX_VERBOSE] = false
55+
context[constants.CTX_VERBOSE] = true
5656

5757
commands := []types.Command{
5858
&builder.SetupHumanLoggerIfMissing{},
@@ -62,20 +62,76 @@ func TestIncludesFinderWithRegExp(t *testing.T) {
6262
&builder.ContainerMergeCopySketchFiles{},
6363

6464
&builder.CoanRunner{},
65+
66+
&builder.IncludesFinderWithRegExp{ContextField: constants.CTX_SOURCE},
6567
}
6668

6769
for _, command := range commands {
6870
err := command.Run(context)
6971
NoError(t, err)
7072
}
7173

72-
includesFinder := builder.IncludesFinderWithRegExp{}
73-
err := includesFinder.Run(context)
74-
NoError(t, err)
75-
7674
require.NotNil(t, context[constants.CTX_INCLUDES])
7775
includes := context[constants.CTX_INCLUDES].([]string)
7876
require.Equal(t, 2, len(includes))
7977
require.Equal(t, "empty_1.h", includes[0])
8078
require.Equal(t, "empty_2.h", includes[1])
8179
}
80+
81+
func TestIncludesFinderWithRegExp(t *testing.T) {
82+
context := make(map[string]interface{})
83+
84+
output := "/home/federico/materiale/works_Arduino/arduino-builder/src/arduino.cc/builder/test/sketch_that_checks_if_SPI_has_transactions/sketch.ino:1:17: fatal error: SPI.h: No such file or directory\n" +
85+
"#include <SPI.h>\n" +
86+
"^\n" +
87+
"compilation terminated."
88+
context[constants.CTX_GCC_MINUS_E_STDERR] = output
89+
90+
parser := builder.IncludesFinderWithRegExp{ContextField: constants.CTX_GCC_MINUS_E_STDERR}
91+
err := parser.Run(context)
92+
NoError(t, err)
93+
94+
require.NotNil(t, context[constants.CTX_INCLUDES])
95+
includes := context[constants.CTX_INCLUDES].([]string)
96+
require.Equal(t, 1, len(includes))
97+
require.Equal(t, "SPI.h", includes[0])
98+
}
99+
100+
func TestIncludesFinderWithRegExpEmptyOutput(t *testing.T) {
101+
context := make(map[string]interface{})
102+
103+
output := ""
104+
105+
context[constants.CTX_GCC_MINUS_E_STDERR] = output
106+
107+
parser := builder.IncludesFinderWithRegExp{ContextField: constants.CTX_GCC_MINUS_E_STDERR}
108+
err := parser.Run(context)
109+
NoError(t, err)
110+
111+
require.NotNil(t, context[constants.CTX_INCLUDES])
112+
includes := context[constants.CTX_INCLUDES].([]string)
113+
require.Equal(t, 0, len(includes))
114+
}
115+
116+
func TestIncludesFinderWithRegExpPreviousIncludes(t *testing.T) {
117+
context := make(map[string]interface{})
118+
119+
context[constants.CTX_INCLUDES] = []string{"test.h"}
120+
121+
output := "/home/federico/materiale/works_Arduino/arduino-builder/src/arduino.cc/builder/test/sketch_that_checks_if_SPI_has_transactions/sketch.ino:1:17: fatal error: SPI.h: No such file or directory\n" +
122+
"#include <SPI.h>\n" +
123+
"^\n" +
124+
"compilation terminated."
125+
126+
context[constants.CTX_GCC_MINUS_E_STDERR] = output
127+
128+
parser := builder.IncludesFinderWithRegExp{ContextField: constants.CTX_GCC_MINUS_E_STDERR}
129+
err := parser.Run(context)
130+
NoError(t, err)
131+
132+
require.NotNil(t, context[constants.CTX_INCLUDES])
133+
includes := context[constants.CTX_INCLUDES].([]string)
134+
require.Equal(t, 2, len(includes))
135+
require.Equal(t, "test.h", includes[0])
136+
require.Equal(t, "SPI.h", includes[1])
137+
}

‎src/arduino.cc/builder/test/includes_to_include_folders_test.go

+7-6
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ func TestIncludesToIncludeFolders(t *testing.T) {
5555
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
5656
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
5757
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
58-
context[constants.CTX_VERBOSE] = false
58+
context[constants.CTX_VERBOSE] = true
5959

6060
commands := []types.Command{
6161
&builder.SetupHumanLoggerIfMissing{},
@@ -96,7 +96,7 @@ func TestIncludesToIncludeFoldersSketchWithIfDef(t *testing.T) {
9696
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
9797
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
9898
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
99-
context[constants.CTX_VERBOSE] = false
99+
context[constants.CTX_VERBOSE] = true
100100

101101
commands := []types.Command{
102102
&builder.SetupHumanLoggerIfMissing{},
@@ -135,7 +135,7 @@ func TestIncludesToIncludeFoldersIRremoteLibrary(t *testing.T) {
135135
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
136136
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
137137
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
138-
context[constants.CTX_VERBOSE] = false
138+
context[constants.CTX_VERBOSE] = true
139139

140140
commands := []types.Command{
141141
&builder.SetupHumanLoggerIfMissing{},
@@ -179,7 +179,7 @@ func TestIncludesToIncludeFoldersANewLibrary(t *testing.T) {
179179
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
180180
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
181181
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
182-
context[constants.CTX_VERBOSE] = false
182+
context[constants.CTX_VERBOSE] = true
183183

184184
commands := []types.Command{
185185
&builder.SetupHumanLoggerIfMissing{},
@@ -222,7 +222,7 @@ func TestIncludesToIncludeFoldersDuplicateLibs(t *testing.T) {
222222
context[constants.CTX_SKETCH_LOCATION] = filepath.Join("user_hardware", "my_avr_platform", "avr", "libraries", "SPI", "examples", "BarometricPressureSensor", "BarometricPressureSensor.ino")
223223
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
224224
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
225-
context[constants.CTX_VERBOSE] = false
225+
context[constants.CTX_VERBOSE] = true
226226

227227
commands := []types.Command{
228228
&builder.SetupHumanLoggerIfMissing{},
@@ -265,7 +265,7 @@ func TestIncludesToIncludeFoldersDuplicateLibsWithConflictingLibsOutsideOfPlatfo
265265
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
266266
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
267267
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
268-
context[constants.CTX_VERBOSE] = false
268+
context[constants.CTX_VERBOSE] = true
269269

270270
commands := []types.Command{
271271
&builder.SetupHumanLoggerIfMissing{},
@@ -308,6 +308,7 @@ func TestIncludesToIncludeFoldersDuplicateLibs2(t *testing.T) {
308308
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
309309
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
310310
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
311+
context[constants.CTX_VERBOSE] = true
311312

312313
commands := []types.Command{
313314
&builder.SetupHumanLoggerIfMissing{},

‎src/arduino.cc/builder/test/platform_keys_rewrite_loader_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ func TestLoadPlatformKeysRewrite(t *testing.T) {
5454

5555
platformKeysRewrite := context[constants.CTX_PLATFORM_KEYS_REWRITE].(types.PlatforKeysRewrite)
5656

57-
require.Equal(t, 12, len(platformKeysRewrite.Rewrites))
57+
require.Equal(t, 14, len(platformKeysRewrite.Rewrites))
5858
require.Equal(t, constants.BUILD_PROPERTIES_COMPILER_PATH, platformKeysRewrite.Rewrites[0].Key)
5959
require.Equal(t, "{runtime.ide.path}/hardware/tools/avr/bin/", platformKeysRewrite.Rewrites[0].OldValue)
6060
require.Equal(t, "{runtime.tools.avr-gcc.path}/bin/", platformKeysRewrite.Rewrites[0].NewValue)

‎src/arduino.cc/builder/test/prototypes_adder_test.go

+17-17
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ func TestPrototypesAdderBridgeExample(t *testing.T) {
5656
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
5757
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
5858
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
59-
context[constants.CTX_VERBOSE] = false
59+
context[constants.CTX_VERBOSE] = true
6060

6161
commands := []types.Command{
6262
&builder.SetupHumanLoggerIfMissing{},
@@ -97,7 +97,7 @@ func TestPrototypesAdderSketchWithIfDef(t *testing.T) {
9797
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
9898
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
9999
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
100-
context[constants.CTX_VERBOSE] = false
100+
context[constants.CTX_VERBOSE] = true
101101

102102
commands := []types.Command{
103103
&builder.SetupHumanLoggerIfMissing{},
@@ -138,7 +138,7 @@ func TestPrototypesAdderBaladuino(t *testing.T) {
138138
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
139139
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
140140
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
141-
context[constants.CTX_VERBOSE] = false
141+
context[constants.CTX_VERBOSE] = true
142142

143143
commands := []types.Command{
144144
&builder.SetupHumanLoggerIfMissing{},
@@ -179,7 +179,7 @@ func TestPrototypesAdderCharWithEscapedDoubleQuote(t *testing.T) {
179179
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
180180
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
181181
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
182-
context[constants.CTX_VERBOSE] = false
182+
context[constants.CTX_VERBOSE] = true
183183

184184
commands := []types.Command{
185185
&builder.SetupHumanLoggerIfMissing{},
@@ -220,7 +220,7 @@ func TestPrototypesAdderIncludeBetweenMultilineComment(t *testing.T) {
220220
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
221221
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
222222
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
223-
context[constants.CTX_VERBOSE] = false
223+
context[constants.CTX_VERBOSE] = true
224224

225225
commands := []types.Command{
226226
&builder.SetupHumanLoggerIfMissing{},
@@ -261,7 +261,7 @@ func TestPrototypesAdderLineContinuations(t *testing.T) {
261261
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
262262
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
263263
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
264-
context[constants.CTX_VERBOSE] = false
264+
context[constants.CTX_VERBOSE] = true
265265

266266
commands := []types.Command{
267267
&builder.SetupHumanLoggerIfMissing{},
@@ -302,7 +302,7 @@ func TestPrototypesAdderStringWithComment(t *testing.T) {
302302
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
303303
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
304304
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
305-
context[constants.CTX_VERBOSE] = false
305+
context[constants.CTX_VERBOSE] = true
306306

307307
commands := []types.Command{
308308
&builder.SetupHumanLoggerIfMissing{},
@@ -343,7 +343,7 @@ func TestPrototypesAdderSketchWithStruct(t *testing.T) {
343343
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
344344
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
345345
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
346-
context[constants.CTX_VERBOSE] = false
346+
context[constants.CTX_VERBOSE] = true
347347

348348
commands := []types.Command{
349349
&builder.SetupHumanLoggerIfMissing{},
@@ -384,7 +384,7 @@ func TestPrototypesAdderSketchWithConfig(t *testing.T) {
384384
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
385385
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
386386
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
387-
context[constants.CTX_VERBOSE] = false
387+
context[constants.CTX_VERBOSE] = true
388388

389389
commands := []types.Command{
390390
&builder.SetupHumanLoggerIfMissing{},
@@ -428,7 +428,7 @@ func TestPrototypesAdderSketchNoFunctionsTwoFiles(t *testing.T) {
428428
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
429429
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
430430
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
431-
context[constants.CTX_VERBOSE] = false
431+
context[constants.CTX_VERBOSE] = true
432432

433433
commands := []types.Command{
434434
&builder.SetupHumanLoggerIfMissing{},
@@ -469,7 +469,7 @@ func TestPrototypesAdderSketchNoFunctions(t *testing.T) {
469469
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
470470
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
471471
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
472-
context[constants.CTX_VERBOSE] = false
472+
context[constants.CTX_VERBOSE] = true
473473

474474
commands := []types.Command{
475475
&builder.SetupHumanLoggerIfMissing{},
@@ -510,7 +510,7 @@ func TestPrototypesAdderSketchWithDefaultArgs(t *testing.T) {
510510
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
511511
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
512512
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
513-
context[constants.CTX_VERBOSE] = false
513+
context[constants.CTX_VERBOSE] = true
514514

515515
commands := []types.Command{
516516
&builder.SetupHumanLoggerIfMissing{},
@@ -551,7 +551,7 @@ func TestPrototypesAdderSketchWithInlineFunction(t *testing.T) {
551551
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
552552
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
553553
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
554-
context[constants.CTX_VERBOSE] = false
554+
context[constants.CTX_VERBOSE] = true
555555

556556
commands := []types.Command{
557557
&builder.SetupHumanLoggerIfMissing{},
@@ -592,7 +592,7 @@ func TestPrototypesAdderSketchWithFunctionSignatureInsideIFDEF(t *testing.T) {
592592
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
593593
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
594594
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
595-
context[constants.CTX_VERBOSE] = false
595+
context[constants.CTX_VERBOSE] = true
596596

597597
commands := []types.Command{
598598
&builder.SetupHumanLoggerIfMissing{},
@@ -633,7 +633,7 @@ func TestPrototypesAdderSketchWithUSBCON(t *testing.T) {
633633
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
634634
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
635635
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
636-
context[constants.CTX_VERBOSE] = false
636+
context[constants.CTX_VERBOSE] = true
637637

638638
commands := []types.Command{
639639
&builder.SetupHumanLoggerIfMissing{},
@@ -673,7 +673,7 @@ func TestPrototypesAdderSketchWithTypename(t *testing.T) {
673673
context[constants.CTX_SKETCH_LOCATION] = filepath.Join("sketch_with_typename", "sketch.ino")
674674
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
675675
context[constants.CTX_LIBRARIES_FOLDERS] = []string{"libraries", "downloaded_libraries"}
676-
context[constants.CTX_VERBOSE] = false
676+
context[constants.CTX_VERBOSE] = true
677677

678678
commands := []types.Command{
679679
&builder.SetupHumanLoggerIfMissing{},
@@ -714,7 +714,7 @@ func TestPrototypesAdderSketchWithIfDef2(t *testing.T) {
714714
context[constants.CTX_BUILD_PROPERTIES_RUNTIME_IDE_VERSION] = "10600"
715715
context[constants.CTX_BUILT_IN_LIBRARIES_FOLDERS] = []string{"downloaded_libraries"}
716716
context[constants.CTX_OTHER_LIBRARIES_FOLDERS] = []string{"libraries"}
717-
context[constants.CTX_VERBOSE] = false
717+
context[constants.CTX_VERBOSE] = true
718718

719719
commands := []types.Command{
720720
&builder.SetupHumanLoggerIfMissing{},
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <SPI.h>
2+
3+
#if !defined(SPI_HAS_TRANSACTION) || !SPI_HAS_TRANSACTION
4+
#error "Where is my SPI_HAS_TRANSACTION!?!?"
5+
#endif
6+
7+
void setup() {}
8+
void loop() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include <SPI.h>
2+
#include <Ethernet.h>
3+
4+
#if !defined(SPI_HAS_TRANSACTION) || !SPI_HAS_TRANSACTION
5+
#error "Where is my SPI_HAS_TRANSACTION!?!?"
6+
#endif
7+
8+
void setup() {}
9+
void loop() {}

‎src/arduino.cc/builder/test/tools_loader_test.go

+13-11
Original file line numberDiff line numberDiff line change
@@ -101,17 +101,18 @@ func TestLoadToolsWithBoardManagerFolderStructure(t *testing.T) {
101101
NoError(t, err)
102102

103103
tools := context[constants.CTX_TOOLS].([]*types.Tool)
104-
require.Equal(t, 2, len(tools))
104+
require.Equal(t, 3, len(tools))
105105

106106
sort.Sort(ByToolIDAndVersion(tools))
107107

108-
require.Equal(t, "arm-none-eabi-gcc", tools[0].Name)
109-
require.Equal(t, "4.8.3-2014q1", tools[0].Version)
110-
require.Equal(t, Abs(t, "./downloaded_board_manager_stuff/RFduino/tools/arm-none-eabi-gcc/4.8.3-2014q1"), tools[0].Folder)
108+
require.Equal(t, "CMSIS", tools[0].Name)
109+
require.Equal(t, "arm-none-eabi-gcc", tools[1].Name)
110+
require.Equal(t, "4.8.3-2014q1", tools[1].Version)
111+
require.Equal(t, Abs(t, "./downloaded_board_manager_stuff/RFduino/tools/arm-none-eabi-gcc/4.8.3-2014q1"), tools[1].Folder)
111112

112-
require.Equal(t, "openocd", tools[1].Name)
113-
require.Equal(t, "0.9.0-arduino", tools[1].Version)
114-
require.Equal(t, Abs(t, "./downloaded_board_manager_stuff/arduino/tools/openocd/0.9.0-arduino"), tools[1].Folder)
113+
require.Equal(t, "openocd", tools[2].Name)
114+
require.Equal(t, "0.9.0-arduino", tools[2].Version)
115+
require.Equal(t, Abs(t, "./downloaded_board_manager_stuff/arduino/tools/openocd/0.9.0-arduino"), tools[2].Folder)
115116
}
116117

117118
func TestLoadLotsOfTools(t *testing.T) {
@@ -125,12 +126,13 @@ func TestLoadLotsOfTools(t *testing.T) {
125126
NoError(t, err)
126127

127128
tools := context[constants.CTX_TOOLS].([]*types.Tool)
128-
require.Equal(t, 8, len(tools))
129+
require.Equal(t, 9, len(tools))
129130

130131
require.Equal(t, "arm-none-eabi-gcc", tools[0].Name)
131132
require.Equal(t, "4.8.3-2014q1", tools[0].Version)
132133

133-
require.Equal(t, "openocd", tools[7].Name)
134-
require.Equal(t, "0.9.0-arduino", tools[7].Version)
135-
require.Equal(t, Abs(t, "./downloaded_board_manager_stuff/arduino/tools/openocd/0.9.0-arduino"), tools[7].Folder)
134+
require.Equal(t, "CMSIS", tools[7].Name)
135+
require.Equal(t, "openocd", tools[8].Name)
136+
require.Equal(t, "0.9.0-arduino", tools[8].Version)
137+
require.Equal(t, Abs(t, "./downloaded_board_manager_stuff/arduino/tools/openocd/0.9.0-arduino"), tools[8].Folder)
136138
}

‎src/arduino.cc/builder/test/user_hardware/my_avr_platform/avr/boards.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ custom_yun.build.vid=0x2341
3030
custom_yun.build.pid=0x8041
3131
custom_yun.build.usb_product="Arduino My"
3232
custom_yun.build.board=AVR_YUN
33-
custom_yun.build.variant=yun
33+
custom_yun.build.variant=arduino:yun
3434
custom_yun.build.extra_flags={build.usb_flags}
3535

3636
mymega.name=Arduino Mega or Mega 2560

‎src/arduino.cc/builder/utils/utils.go

+9
Original file line numberDiff line numberDiff line change
@@ -426,3 +426,12 @@ func LibraryToSourceFolder(library *types.Library) []types.SourceFolder {
426426
}
427427
return sourceFolders
428428
}
429+
430+
func AddStringsToStringsSet(accumulator []string, stringsToAdd []string) []string {
431+
previousStringsSet := SliceToMapStringBool(accumulator, true)
432+
stringsSetToAdd := SliceToMapStringBool(stringsToAdd, true)
433+
434+
newStringsSet := MergeMapsOfStringBool(previousStringsSet, stringsSetToAdd)
435+
436+
return KeysOfMapOfStringBool(newStringsSet)
437+
}

0 commit comments

Comments
 (0)
Please sign in to comment.