Skip to content

Commit 4bf18d6

Browse files
authored
[skip-changelog] Some refactorings on library resolution code (#1766)
* Transformed FailIfImportedLibraryIsWrong into a functon There was no need to have it encapsulated in a Command * Move variable near the place it belongs * Dramatically simplified SourceFile object Removed dependency from types.Context * Added comments about utility folder role in library discovery * Simplified if construct * Made RelativePath private * Skip includes detection of precompiled libraries early Instead of skipping include detection later, avoid to add the sources in the queue right from the beginning. * Keep extra-include dirs due to "utility" folder in SourceFile object Also remove the reference to the original Library object because it's no more needed.
1 parent a47e35f commit 4bf18d6

File tree

4 files changed

+93
-126
lines changed

4 files changed

+93
-126
lines changed

Diff for: legacy/builder/constants/constants.go

-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,6 @@ const FOLDER_TOOLS = "tools"
3939
const FOLDER_LIBRARIES = "libraries"
4040
const LIBRARY_ALL_ARCHS = "*"
4141
const LIBRARY_EMAIL = "email"
42-
const LIBRARY_FOLDER_ARCH = "arch"
4342
const LIBRARY_FOLDER_SRC = "src"
4443
const LOG_LEVEL_DEBUG = "debug"
4544
const LOG_LEVEL_ERROR = "error"

Diff for: legacy/builder/container_find_includes.go

+49-35
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ func (s *ContainerFindIncludes) findIncludes(ctx *types.Context) error {
175175
}
176176
}
177177

178-
if err := runCommand(ctx, &FailIfImportedLibraryIsWrong{}); err != nil {
178+
if err := failIfImportedLibraryIsWrong(ctx); err != nil {
179179
return errors.WithStack(err)
180180
}
181181

@@ -198,15 +198,6 @@ func appendIncludeFolder(ctx *types.Context, cache *includeCache, sourceFilePath
198198
cache.ExpectEntry(sourceFilePath, include, folder)
199199
}
200200

201-
func runCommand(ctx *types.Context, command types.Command) error {
202-
PrintRingNameIfDebug(ctx, command)
203-
err := command.Run(ctx)
204-
if err != nil {
205-
return errors.WithStack(err)
206-
}
207-
return nil
208-
}
209-
210201
type includeCacheEntry struct {
211202
Sourcefile *paths.Path
212203
Include string
@@ -318,10 +309,10 @@ func writeCache(cache *includeCache, path *paths.Path) error {
318309

319310
func findIncludesUntilDone(ctx *types.Context, cache *includeCache, sourceFileQueue *types.UniqueSourceFileQueue) error {
320311
sourceFile := sourceFileQueue.Pop()
321-
sourcePath := sourceFile.SourcePath(ctx)
312+
sourcePath := sourceFile.SourcePath()
322313
targetFilePath := paths.NullPath()
323-
depPath := sourceFile.DepfilePath(ctx)
324-
objPath := sourceFile.ObjectPath(ctx)
314+
depPath := sourceFile.DepfilePath()
315+
objPath := sourceFile.ObjectPath()
325316

326317
// TODO: This should perhaps also compare against the
327318
// include.cache file timestamp. Now, it only checks if the file
@@ -342,28 +333,21 @@ func findIncludesUntilDone(ctx *types.Context, cache *includeCache, sourceFileQu
342333

343334
first := true
344335
for {
345-
var missingIncludeH string
346336
cache.ExpectFile(sourcePath)
347337

338+
// Libraries may require the "utility" directory to be added to the include
339+
// search path, but only for the source code of the library, so we temporary
340+
// copy the current search path list and add the library' utility directory
341+
// if needed.
348342
includeFolders := ctx.IncludeFolders
349-
if library, ok := sourceFile.Origin.(*libraries.Library); ok && library.UtilityDir != nil {
350-
includeFolders = append(includeFolders, library.UtilityDir)
351-
}
352-
353-
if library, ok := sourceFile.Origin.(*libraries.Library); ok {
354-
if library.Precompiled && library.PrecompiledWithSources {
355-
// Fully precompiled libraries should have no dependencies
356-
// to avoid ABI breakage
357-
if ctx.Verbose {
358-
ctx.Info(tr("Skipping dependencies detection for precompiled library %[1]s", library.Name))
359-
}
360-
return nil
361-
}
343+
if extraInclude := sourceFile.ExtraIncludePath(); extraInclude != nil {
344+
includeFolders = append(includeFolders, extraInclude)
362345
}
363346

364347
var preprocErr error
365348
var preprocStderr []byte
366349

350+
var missingIncludeH string
367351
if unchanged && cache.valid {
368352
missingIncludeH = cache.Next().Include
369353
if first && ctx.Verbose {
@@ -376,14 +360,11 @@ func findIncludesUntilDone(ctx *types.Context, cache *includeCache, sourceFileQu
376360
ctx.WriteStdout(preprocStdout)
377361
}
378362
// Unwrap error and see if it is an ExitError.
379-
_, isExitErr := errors.Cause(preprocErr).(*exec.ExitError)
380363
if preprocErr == nil {
381364
// Preprocessor successful, done
382365
missingIncludeH = ""
383-
} else if !isExitErr || preprocStderr == nil {
384-
// Ignore ExitErrors (e.g. gcc returning
385-
// non-zero status), but bail out on
386-
// other errors
366+
} else if _, isExitErr := errors.Cause(preprocErr).(*exec.ExitError); !isExitErr || preprocStderr == nil {
367+
// Ignore ExitErrors (e.g. gcc returning non-zero status), but bail out on other errors
387368
return errors.WithStack(preprocErr)
388369
} else {
389370
missingIncludeH = IncludesFinderWithRegExp(string(preprocStderr))
@@ -426,9 +407,16 @@ func findIncludesUntilDone(ctx *types.Context, cache *includeCache, sourceFileQu
426407
// include scanning
427408
ctx.ImportedLibraries = append(ctx.ImportedLibraries, library)
428409
appendIncludeFolder(ctx, cache, sourcePath, missingIncludeH, library.SourceDir)
429-
sourceDirs := library.SourceDirs()
430-
for _, sourceDir := range sourceDirs {
431-
queueSourceFilesFromFolder(ctx, sourceFileQueue, library, sourceDir.Dir, sourceDir.Recurse)
410+
411+
if library.Precompiled && library.PrecompiledWithSources {
412+
// Fully precompiled libraries should have no dependencies to avoid ABI breakage
413+
if ctx.Verbose {
414+
ctx.Info(tr("Skipping dependencies detection for precompiled library %[1]s", library.Name))
415+
}
416+
} else {
417+
for _, sourceDir := range library.SourceDirs() {
418+
queueSourceFilesFromFolder(ctx, sourceFileQueue, library, sourceDir.Dir, sourceDir.Recurse)
419+
}
432420
}
433421
first = false
434422
}
@@ -499,3 +487,29 @@ func ResolveLibrary(ctx *types.Context, header string) *libraries.Library {
499487

500488
return selected
501489
}
490+
491+
func failIfImportedLibraryIsWrong(ctx *types.Context) error {
492+
if len(ctx.ImportedLibraries) == 0 {
493+
return nil
494+
}
495+
496+
for _, library := range ctx.ImportedLibraries {
497+
if !library.IsLegacy {
498+
if library.InstallDir.Join("arch").IsDir() {
499+
return errors.New(tr("%[1]s folder is no longer supported! See %[2]s for more information", "'arch'", "http://goo.gl/gfFJzU"))
500+
}
501+
for _, propName := range libraries.MandatoryProperties {
502+
if !library.Properties.ContainsKey(propName) {
503+
return errors.New(tr("Missing '%[1]s' from library in %[2]s", propName, library.InstallDir))
504+
}
505+
}
506+
if library.Layout == libraries.RecursiveLayout {
507+
if library.UtilityDir != nil {
508+
return errors.New(tr("Library can't use both '%[1]s' and '%[2]s' folders. Double check in '%[3]s'.", "src", "utility", library.InstallDir))
509+
}
510+
}
511+
}
512+
}
513+
514+
return nil
515+
}

Diff for: legacy/builder/fail_if_imported_library_is_wrong.go

-52
This file was deleted.

Diff for: legacy/builder/types/types.go

+44-38
Original file line numberDiff line numberDiff line change
@@ -24,69 +24,75 @@ import (
2424
)
2525

2626
type SourceFile struct {
27-
// Sketch or Library pointer that this source file lives in
28-
Origin interface{}
2927
// Path to the source file within the sketch/library root folder
30-
RelativePath *paths.Path
28+
relativePath *paths.Path
29+
30+
// ExtraIncludePath contains an extra include path that must be
31+
// used to compile this source file.
32+
// This is mainly used for source files that comes from old-style libraries
33+
// (Arduino IDE <1.5) requiring an extra include path to the "utility" folder.
34+
extraIncludePath *paths.Path
35+
36+
// The source root for the given origin, where its source files
37+
// can be found. Prepending this to SourceFile.RelativePath will give
38+
// the full path to that source file.
39+
sourceRoot *paths.Path
40+
41+
// The build root for the given origin, where build products will
42+
// be placed. Any directories inside SourceFile.RelativePath will be
43+
// appended here.
44+
buildRoot *paths.Path
3145
}
3246

3347
func (f *SourceFile) Equals(g *SourceFile) bool {
34-
return f.Origin == g.Origin &&
35-
f.RelativePath.EqualsTo(g.RelativePath)
48+
return f.relativePath.EqualsTo(g.relativePath) &&
49+
f.buildRoot.EqualsTo(g.buildRoot) &&
50+
f.sourceRoot.EqualsTo(g.sourceRoot)
3651
}
3752

3853
// Create a SourceFile containing the given source file path within the
3954
// given origin. The given path can be absolute, or relative within the
4055
// origin's root source folder
4156
func MakeSourceFile(ctx *Context, origin interface{}, path *paths.Path) (*SourceFile, error) {
42-
if path.IsAbs() {
43-
var err error
44-
path, err = sourceRoot(ctx, origin).RelTo(path)
45-
if err != nil {
46-
return nil, err
47-
}
48-
}
49-
return &SourceFile{Origin: origin, RelativePath: path}, nil
50-
}
57+
res := &SourceFile{}
5158

52-
// Return the build root for the given origin, where build products will
53-
// be placed. Any directories inside SourceFile.RelativePath will be
54-
// appended here.
55-
func buildRoot(ctx *Context, origin interface{}) *paths.Path {
5659
switch o := origin.(type) {
5760
case *sketch.Sketch:
58-
return ctx.SketchBuildPath
61+
res.buildRoot = ctx.SketchBuildPath
62+
res.sourceRoot = ctx.SketchBuildPath
5963
case *libraries.Library:
60-
return ctx.LibrariesBuildPath.Join(o.DirName)
64+
res.buildRoot = ctx.LibrariesBuildPath.Join(o.DirName)
65+
res.sourceRoot = o.SourceDir
66+
res.extraIncludePath = o.UtilityDir
6167
default:
6268
panic("Unexpected origin for SourceFile: " + fmt.Sprint(origin))
6369
}
64-
}
6570

66-
// Return the source root for the given origin, where its source files
67-
// can be found. Prepending this to SourceFile.RelativePath will give
68-
// the full path to that source file.
69-
func sourceRoot(ctx *Context, origin interface{}) *paths.Path {
70-
switch o := origin.(type) {
71-
case *sketch.Sketch:
72-
return ctx.SketchBuildPath
73-
case *libraries.Library:
74-
return o.SourceDir
75-
default:
76-
panic("Unexpected origin for SourceFile: " + fmt.Sprint(origin))
71+
if path.IsAbs() {
72+
var err error
73+
path, err = res.sourceRoot.RelTo(path)
74+
if err != nil {
75+
return nil, err
76+
}
7777
}
78+
res.relativePath = path
79+
return res, nil
80+
}
81+
82+
func (f *SourceFile) ExtraIncludePath() *paths.Path {
83+
return f.extraIncludePath
7884
}
7985

80-
func (f *SourceFile) SourcePath(ctx *Context) *paths.Path {
81-
return sourceRoot(ctx, f.Origin).JoinPath(f.RelativePath)
86+
func (f *SourceFile) SourcePath() *paths.Path {
87+
return f.sourceRoot.JoinPath(f.relativePath)
8288
}
8389

84-
func (f *SourceFile) ObjectPath(ctx *Context) *paths.Path {
85-
return buildRoot(ctx, f.Origin).Join(f.RelativePath.String() + ".o")
90+
func (f *SourceFile) ObjectPath() *paths.Path {
91+
return f.buildRoot.Join(f.relativePath.String() + ".o")
8692
}
8793

88-
func (f *SourceFile) DepfilePath(ctx *Context) *paths.Path {
89-
return buildRoot(ctx, f.Origin).Join(f.RelativePath.String() + ".d")
94+
func (f *SourceFile) DepfilePath() *paths.Path {
95+
return f.buildRoot.Join(f.relativePath.String() + ".d")
9096
}
9197

9298
type LibraryResolutionResult struct {

0 commit comments

Comments
 (0)