Skip to content

Commit 5e2ac09

Browse files
author
Federico Fissore
committed
Storing library resolution results for later print them. Fixes #25
Signed-off-by: Federico Fissore <[email protected]>
1 parent 45b744f commit 5e2ac09

11 files changed

+157
-57
lines changed

src/arduino.cc/builder/add_additional_entries_to_context.go

+2
Original file line numberDiff line numberDiff line change
@@ -85,5 +85,7 @@ func (s *AddAdditionalEntriesToContext) Run(context map[string]interface{}) erro
8585
foldersWithSources := &types.UniqueStringQueue{}
8686
context[constants.CTX_FOLDERS_WITH_SOURCES_QUEUE] = foldersWithSources
8787

88+
context[constants.CTX_LIBRARY_RESOLUTION_RESULTS] = make(map[string]types.LibraryResolutionResult)
89+
8890
return nil
8991
}

src/arduino.cc/builder/builder.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,6 @@ func (s *Builder) Run(context map[string]interface{}) error {
8383

8484
&ContainerFindIncludes{},
8585

86-
&PrintUsedLibrariesIfVerbose{},
8786
&WarnAboutArchIncompatibleLibraries{},
8887

8988
&ContainerAddPrototypes{},
@@ -111,6 +110,10 @@ func (s *Builder) Run(context map[string]interface{}) error {
111110
&MergeSketchWithBootloader{},
112111

113112
&RecipeByPrefixSuffixRunner{Prefix: constants.HOOKS_POSTBUILD, Suffix: constants.HOOKS_PATTERN_SUFFIX},
113+
114+
&PrintUsedAndNotUsedLibraries{},
115+
116+
&PrintUsedLibrariesIfVerbose{},
114117
}
115118

116119
return runCommands(context, commands)

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

+1
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ const CTX_LIBRARIES_BUILD_PATH = "librariesBuildPath"
102102
const CTX_LIBRARIES_FOLDERS = "librariesFolders"
103103
const CTX_LIBRARIES = "libraries"
104104
const CTX_LIBRARY_DISCOVERY_RECURSION_DEPTH = "libraryDiscoveryRecursionDepth"
105+
const CTX_LIBRARY_RESOLUTION_RESULTS = "libraryResolutionResults"
105106
const CTX_LINE_OFFSET = "lineOffset"
106107
const CTX_LOGGER = "logger"
107108
const CTX_OBJECT_FILES_LIBRARIES = "objectFilesLibraries"

src/arduino.cc/builder/includes_to_include_folders.go

+17-17
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,8 @@ package builder
3131

3232
import (
3333
"arduino.cc/builder/constants"
34-
"arduino.cc/builder/i18n"
3534
"arduino.cc/builder/types"
3635
"arduino.cc/builder/utils"
37-
"os"
3836
"path/filepath"
3937
"strings"
4038
)
@@ -47,16 +45,15 @@ func (s *IncludesToIncludeFolders) Run(context map[string]interface{}) error {
4745
}
4846
includes := context[constants.CTX_INCLUDES].([]string)
4947
headerToLibraries := context[constants.CTX_HEADER_TO_LIBRARIES].(map[string][]*types.Library)
50-
debugLevel := utils.DebugLevel(context)
51-
logger := context[constants.CTX_LOGGER].(i18n.Logger)
5248
platform := context[constants.CTX_TARGET_PLATFORM].(*types.Platform)
5349
actualPlatform := context[constants.CTX_ACTUAL_PLATFORM].(*types.Platform)
50+
libraryResolutionResults := context[constants.CTX_LIBRARY_RESOLUTION_RESULTS].(map[string]types.LibraryResolutionResult)
5451

55-
var importedLibraries []*types.Library
52+
importedLibraries := []*types.Library{}
5653
if utils.MapHas(context, constants.CTX_IMPORTED_LIBRARIES) {
5754
importedLibraries = context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library)
5855
}
59-
newlyImportedLibraries, err := resolveLibraries(includes, headerToLibraries, importedLibraries, []*types.Platform{platform, actualPlatform}, debugLevel, logger)
56+
newlyImportedLibraries, err := resolveLibraries(includes, headerToLibraries, []*types.Platform{platform, actualPlatform}, libraryResolutionResults)
6057
if err != nil {
6158
return utils.WrapError(err)
6259
}
@@ -95,10 +92,10 @@ func resolveIncludeFolders(importedLibraries []*types.Library, buildProperties m
9592
}
9693

9794
//FIXME it's also resolving previously resolved libraries
98-
func resolveLibraries(includes []string, headerToLibraries map[string][]*types.Library, previousImportedLibraries []*types.Library, platforms []*types.Platform, debugLevel int, logger i18n.Logger) ([]*types.Library, error) {
95+
func resolveLibraries(includes []string, headerToLibraries map[string][]*types.Library, platforms []*types.Platform, libraryResolutionResults map[string]types.LibraryResolutionResult) ([]*types.Library, error) {
9996
markImportedLibrary := make(map[*types.Library]bool)
10097
for _, header := range includes {
101-
resolveLibrary(header, headerToLibraries, markImportedLibrary, previousImportedLibraries, platforms, debugLevel, logger)
98+
resolveLibrary(header, headerToLibraries, markImportedLibrary, platforms, libraryResolutionResults)
10299
}
103100

104101
var importedLibraries []*types.Library
@@ -109,7 +106,7 @@ func resolveLibraries(includes []string, headerToLibraries map[string][]*types.L
109106
return importedLibraries, nil
110107
}
111108

112-
func resolveLibrary(header string, headerToLibraries map[string][]*types.Library, markImportedLibrary map[*types.Library]bool, previousImportedLibraries []*types.Library, platforms []*types.Platform, debugLevel int, logger i18n.Logger) {
109+
func resolveLibrary(header string, headerToLibraries map[string][]*types.Library, markImportedLibrary map[*types.Library]bool, platforms []*types.Platform, libraryResolutionResults map[string]types.LibraryResolutionResult) {
113110
libraries := headerToLibraries[header]
114111

115112
if libraries == nil {
@@ -144,16 +141,19 @@ func resolveLibrary(header string, headerToLibraries map[string][]*types.Library
144141
library = libraries[0]
145142
}
146143

147-
if debugLevel > 0 && !sliceContainsLibrary(previousImportedLibraries, library) {
148-
logger.Fprintln(os.Stderr, constants.MSG_LIBRARIES_MULTIPLE_LIBS_FOUND_FOR, header)
149-
logger.Fprintln(os.Stderr, constants.MSG_LIBRARIES_USED, library.Folder)
150-
for _, notUsedLibrary := range libraries {
151-
if library != notUsedLibrary {
152-
logger.Fprintln(os.Stderr, constants.MSG_LIBRARIES_NOT_USED, notUsedLibrary.Folder)
153-
}
144+
libraryResolutionResults[header] = types.LibraryResolutionResult{Library: library, NotUsedLibraries: filterOutLibraryFrom(libraries, library)}
145+
146+
markImportedLibrary[library] = true
147+
}
148+
149+
func filterOutLibraryFrom(libraries []*types.Library, library *types.Library) []*types.Library {
150+
filteredOutLibraries := []*types.Library{}
151+
for _, lib := range libraries {
152+
if lib != library {
153+
filteredOutLibraries = append(filteredOutLibraries, lib)
154154
}
155155
}
156-
markImportedLibrary[library] = true
156+
return filteredOutLibraries
157157
}
158158

159159
func libraryCompatibleWithPlatform(library *types.Library, platform *types.Platform) bool {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* This file is part of Arduino Builder.
3+
*
4+
* Arduino Builder is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*
18+
* As a special exception, you may use this file as part of a free software
19+
* library without restriction. Specifically, if other files instantiate
20+
* templates or use macros or inline functions from this file, or you compile
21+
* this file and link it with other files to produce an executable, this
22+
* file does not by itself cause the resulting executable to be covered by
23+
* the GNU General Public License. This exception does not however
24+
* invalidate any other reasons why the executable file might be covered by
25+
* the GNU General Public License.
26+
*
27+
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
28+
*/
29+
30+
package builder
31+
32+
import (
33+
"arduino.cc/builder/constants"
34+
"arduino.cc/builder/i18n"
35+
"arduino.cc/builder/types"
36+
"arduino.cc/builder/utils"
37+
"os"
38+
)
39+
40+
type PrintUsedAndNotUsedLibraries struct{}
41+
42+
func (s *PrintUsedAndNotUsedLibraries) Run(context map[string]interface{}) error {
43+
if utils.DebugLevel(context) <= 0 {
44+
return nil
45+
}
46+
47+
logger := context[constants.CTX_LOGGER].(i18n.Logger)
48+
libraryResolutionResults := context[constants.CTX_LIBRARY_RESOLUTION_RESULTS].(map[string]types.LibraryResolutionResult)
49+
50+
for header, libResResult := range libraryResolutionResults {
51+
logger.Fprintln(os.Stderr, constants.MSG_LIBRARIES_MULTIPLE_LIBS_FOUND_FOR, header)
52+
logger.Fprintln(os.Stderr, constants.MSG_LIBRARIES_USED, libResResult.Library.Folder)
53+
for _, notUsedLibrary := range libResResult.NotUsedLibraries {
54+
logger.Fprintln(os.Stderr, constants.MSG_LIBRARIES_NOT_USED, notUsedLibrary.Folder)
55+
}
56+
}
57+
58+
return nil
59+
}

src/arduino.cc/builder/test/add_additional_entries_to_context_test.go

+4
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ func TestAddAdditionalEntriesToContextNoBuildPath(t *testing.T) {
5656

5757
require.True(t, context[constants.CTX_COLLECTED_SOURCE_FILES_QUEUE].(*types.UniqueStringQueue).Empty())
5858
require.True(t, context[constants.CTX_FOLDERS_WITH_SOURCES_QUEUE].(*types.UniqueStringQueue).Empty())
59+
60+
require.Equal(t, 0, len(context[constants.CTX_LIBRARY_RESOLUTION_RESULTS].(map[string]types.LibraryResolutionResult)))
5961
}
6062

6163
func TestAddAdditionalEntriesToContextWithBuildPath(t *testing.T) {
@@ -78,4 +80,6 @@ func TestAddAdditionalEntriesToContextWithBuildPath(t *testing.T) {
7880

7981
require.True(t, context[constants.CTX_COLLECTED_SOURCE_FILES_QUEUE].(*types.UniqueStringQueue).Empty())
8082
require.True(t, context[constants.CTX_FOLDERS_WITH_SOURCES_QUEUE].(*types.UniqueStringQueue).Empty())
83+
84+
require.Equal(t, 0, len(context[constants.CTX_LIBRARY_RESOLUTION_RESULTS].(map[string]types.LibraryResolutionResult)))
8185
}

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

-1
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,6 @@ func TestIncludesFinderWithGCCSketchWithDependendLibraries(t *testing.T) {
165165
require.Equal(t, "library3.h", includes[5])
166166
require.Equal(t, "library4.h", includes[6])
167167

168-
require.NotNil(t, context[constants.CTX_IMPORTED_LIBRARIES])
169168
importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library)
170169
require.Equal(t, 4, len(importedLibraries))
171170

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

+2-5
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,6 @@ func TestIncludesToIncludeFolders(t *testing.T) {
7171
NoError(t, err)
7272
}
7373

74-
require.NotNil(t, context[constants.CTX_IMPORTED_LIBRARIES])
7574
importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library)
7675
require.Equal(t, 1, len(importedLibraries))
7776
require.Equal(t, "Bridge", importedLibraries[0].Name)
@@ -108,7 +107,8 @@ func TestIncludesToIncludeFoldersSketchWithIfDef(t *testing.T) {
108107
NoError(t, err)
109108
}
110109

111-
require.Nil(t, context[constants.CTX_IMPORTED_LIBRARIES])
110+
importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library)
111+
require.Equal(t, 0, len(importedLibraries))
112112
}
113113

114114
func TestIncludesToIncludeFoldersIRremoteLibrary(t *testing.T) {
@@ -142,7 +142,6 @@ func TestIncludesToIncludeFoldersIRremoteLibrary(t *testing.T) {
142142
NoError(t, err)
143143
}
144144

145-
require.NotNil(t, context[constants.CTX_IMPORTED_LIBRARIES])
146145
importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library)
147146
sort.Sort(ByLibraryName(importedLibraries))
148147
require.Equal(t, 2, len(importedLibraries))
@@ -181,7 +180,6 @@ func TestIncludesToIncludeFoldersANewLibrary(t *testing.T) {
181180
NoError(t, err)
182181
}
183182

184-
require.NotNil(t, context[constants.CTX_IMPORTED_LIBRARIES])
185183
importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library)
186184
sort.Sort(ByLibraryName(importedLibraries))
187185
require.Equal(t, 2, len(importedLibraries))
@@ -220,7 +218,6 @@ func TestIncludesToIncludeFoldersDuplicateLibs(t *testing.T) {
220218
NoError(t, err)
221219
}
222220

223-
require.NotNil(t, context[constants.CTX_IMPORTED_LIBRARIES])
224221
importedLibraries := context[constants.CTX_IMPORTED_LIBRARIES].([]*types.Library)
225222
sort.Sort(ByLibraryName(importedLibraries))
226223
require.Equal(t, 1, len(importedLibraries))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
/*
2+
* This file is part of Arduino Builder.
3+
*
4+
* Arduino Builder is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU General Public License as published by
6+
* the Free Software Foundation; either version 2 of the License, or
7+
* (at your option) any later version.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU General Public License for more details.
13+
*
14+
* You should have received a copy of the GNU General Public License
15+
* along with this program; if not, write to the Free Software
16+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17+
*
18+
* As a special exception, you may use this file as part of a free software
19+
* library without restriction. Specifically, if other files instantiate
20+
* templates or use macros or inline functions from this file, or you compile
21+
* this file and link it with other files to produce an executable, this
22+
* file does not by itself cause the resulting executable to be covered by
23+
* the GNU General Public License. This exception does not however
24+
* invalidate any other reasons why the executable file might be covered by
25+
* the GNU General Public License.
26+
*
27+
* Copyright 2015 Arduino LLC (http://www.arduino.cc/)
28+
*/
29+
30+
package types
31+
32+
type UniqueStringQueue []string
33+
34+
func (h UniqueStringQueue) Len() int { return len(h) }
35+
func (h UniqueStringQueue) Less(i, j int) bool { return false }
36+
func (h UniqueStringQueue) Swap(i, j int) { panic("Who called me?!?") }
37+
38+
func (h *UniqueStringQueue) Push(x interface{}) {
39+
if !sliceContains(*h, x.(string)) {
40+
*h = append(*h, x.(string))
41+
}
42+
}
43+
44+
func (h *UniqueStringQueue) Pop() interface{} {
45+
old := *h
46+
x := old[0]
47+
*h = old[1:]
48+
return x
49+
}
50+
51+
func (h *UniqueStringQueue) Empty() bool {
52+
return h.Len() == 0
53+
}
54+
55+
// duplication of utils.SliceContains! Thanks golang! Why? Because you can't have import cycles, so types cannot import from utils because utils already imports from types
56+
func sliceContains(slice []string, target string) bool {
57+
for _, value := range slice {
58+
if value == target {
59+
return true
60+
}
61+
}
62+
return false
63+
}
64+
65+
type LibraryResolutionResult struct {
66+
Library *Library
67+
NotUsedLibraries []*Library
68+
}

src/arduino.cc/builder/types/types.go

-33
Original file line numberDiff line numberDiff line change
@@ -156,36 +156,3 @@ type KeyValuePair struct {
156156
type Command interface {
157157
Run(context map[string]interface{}) error
158158
}
159-
160-
type UniqueStringQueue []string
161-
162-
func (h UniqueStringQueue) Len() int { return len(h) }
163-
func (h UniqueStringQueue) Less(i, j int) bool { return false }
164-
func (h UniqueStringQueue) Swap(i, j int) { panic("Who called me?!?") }
165-
166-
func (h *UniqueStringQueue) Push(x interface{}) {
167-
if !SliceContains(*h, x.(string)) {
168-
*h = append(*h, x.(string))
169-
}
170-
}
171-
172-
func (h *UniqueStringQueue) Pop() interface{} {
173-
old := *h
174-
x := old[0]
175-
*h = old[1:]
176-
return x
177-
}
178-
179-
func (h *UniqueStringQueue) Empty() bool {
180-
return h.Len() == 0
181-
}
182-
183-
// duplication of utils.SliceContains! Thanks golang! Why? Because you can't have import cycles, so types cannot import from utils because utils already imports from types
184-
func SliceContains(slice []string, target string) bool {
185-
for _, value := range slice {
186-
if value == target {
187-
return true
188-
}
189-
}
190-
return false
191-
}

0 commit comments

Comments
 (0)