Skip to content

Commit 9c073c1

Browse files
legacy: Builder refactorization (part 5...) (#2312)
* move customBuildProperties to arduino/builder * remove BuildProperties from context * remove BuildPath from context * remove sketch,libraries,core build path from Context * remove buildPath parameter to PrepareSketchBuildPath func * Make CoreBuilder a method recevier of arduino/builder * Add BuilderLogger in arduino/builder * Remove BuilderLogger from CoreBuild parameter * Make getCachedCoreArchiveDirName unexported * heavily refactored the ContainerBuildOptions * remove fqbn from Context * remove clean from Context * remove unsued properties in Context * remove sourceOverrides from Context * make SketchBuilder a method recevier of arduino/builder * make BuildLibraries a method recevier of arduino/builder * make RunRecipe a method recevier of arduino/builder * make RemoveUnusedCompiledLibraries a method recevier of arduino/builder * make MergeSketchWithBootloader a method recevier of arduino/builder * make WarnAboutArchIncompatibleLibraries a method recevier of arduino/builder * make PrintUsedLibraries a method recevier of arduino/builder * make ExportCmake and PreprocessorSketch a method recevier of arduino/builder * remove legacy/constans pkg * make Linker a method recevier of arduino/builder * make Size a method recevier of arduino/builder * remove onlyUpdateCompilationDatabase from Context * remove Progress from Context * remove ExecutableSectionSize from Context * remove CompilationDatabase from Context * remove LineOffset from Context * introduce BuilderArtifacts to better isolate write operations * remove ActualPlatform and TargetPlatform from Context * directly pass the remaining properties of Context in the builder constructor The remaning fields is used only by legacy tests * polish legacy test
1 parent 8c81d2c commit 9c073c1

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1235
-2380
lines changed

Diff for: arduino/builder/build_options_manager.go

+182
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,182 @@
1+
// This file is part of arduino-cli.
2+
//
3+
// Copyright 2020 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 builder
17+
18+
import (
19+
"encoding/json"
20+
"path/filepath"
21+
"strings"
22+
23+
"github.com/arduino/arduino-cli/arduino/builder/logger"
24+
"github.com/arduino/arduino-cli/arduino/builder/utils"
25+
"github.com/arduino/arduino-cli/arduino/cores"
26+
"github.com/arduino/arduino-cli/arduino/sketch"
27+
"github.com/arduino/go-paths-helper"
28+
properties "github.com/arduino/go-properties-orderedmap"
29+
"github.com/pkg/errors"
30+
)
31+
32+
// BuildOptionsManager fixdoc
33+
type BuildOptionsManager struct {
34+
currentOptions *properties.Map
35+
currentBuildOptionsJSON []byte
36+
37+
hardwareDirs paths.PathList
38+
builtInToolsDirs paths.PathList
39+
otherLibrariesDirs paths.PathList
40+
builtInLibrariesDirs *paths.Path
41+
buildPath *paths.Path
42+
runtimePlatformPath *paths.Path
43+
buildCorePath *paths.Path
44+
sketch *sketch.Sketch
45+
customBuildProperties []string
46+
compilerOptimizationFlags string
47+
clean bool
48+
builderLogger *logger.BuilderLogger
49+
}
50+
51+
// NewBuildOptionsManager fixdoc
52+
func NewBuildOptionsManager(
53+
hardwareDirs, builtInToolsDirs, otherLibrariesDirs paths.PathList,
54+
builtInLibrariesDirs, buildPath *paths.Path,
55+
sketch *sketch.Sketch,
56+
customBuildProperties []string,
57+
fqbn *cores.FQBN,
58+
clean bool,
59+
compilerOptimizationFlags string,
60+
runtimePlatformPath, buildCorePath *paths.Path,
61+
buildLogger *logger.BuilderLogger,
62+
) *BuildOptionsManager {
63+
opts := properties.NewMap()
64+
65+
opts.Set("hardwareFolders", strings.Join(hardwareDirs.AsStrings(), ","))
66+
opts.Set("builtInToolsFolders", strings.Join(builtInToolsDirs.AsStrings(), ","))
67+
opts.Set("otherLibrariesFolders", strings.Join(otherLibrariesDirs.AsStrings(), ","))
68+
opts.SetPath("sketchLocation", sketch.FullPath)
69+
opts.Set("fqbn", fqbn.String())
70+
opts.Set("customBuildProperties", strings.Join(customBuildProperties, ","))
71+
opts.Set("compiler.optimization_flags", compilerOptimizationFlags)
72+
73+
if builtInLibrariesDirs != nil {
74+
opts.Set("builtInLibrariesFolders", builtInLibrariesDirs.String())
75+
}
76+
77+
absPath := sketch.FullPath.Parent()
78+
var additionalFilesRelative []string
79+
for _, f := range sketch.AdditionalFiles {
80+
relPath, err := f.RelTo(absPath)
81+
if err != nil {
82+
continue // ignore
83+
}
84+
additionalFilesRelative = append(additionalFilesRelative, relPath.String())
85+
}
86+
opts.Set("additionalFiles", strings.Join(additionalFilesRelative, ","))
87+
88+
return &BuildOptionsManager{
89+
currentOptions: opts,
90+
hardwareDirs: hardwareDirs,
91+
builtInToolsDirs: builtInToolsDirs,
92+
otherLibrariesDirs: otherLibrariesDirs,
93+
builtInLibrariesDirs: builtInLibrariesDirs,
94+
buildPath: buildPath,
95+
runtimePlatformPath: runtimePlatformPath,
96+
buildCorePath: buildCorePath,
97+
sketch: sketch,
98+
customBuildProperties: customBuildProperties,
99+
compilerOptimizationFlags: compilerOptimizationFlags,
100+
clean: clean,
101+
builderLogger: buildLogger,
102+
}
103+
}
104+
105+
// WipeBuildPath fixdoc
106+
func (m *BuildOptionsManager) WipeBuildPath() error {
107+
buildOptionsJSON, err := json.MarshalIndent(m.currentOptions, "", " ")
108+
if err != nil {
109+
return errors.WithStack(err)
110+
}
111+
m.currentBuildOptionsJSON = buildOptionsJSON
112+
113+
if err := m.wipeBuildPath(); err != nil {
114+
return errors.WithStack(err)
115+
}
116+
return m.buildPath.Join("build.options.json").WriteFile(buildOptionsJSON)
117+
}
118+
119+
func (m *BuildOptionsManager) wipeBuildPath() error {
120+
wipe := func() error {
121+
// FIXME: this should go outside legacy and behind a `logrus` call so users can
122+
// control when this should be printed.
123+
// logger.Println(constants.LOG_LEVEL_INFO, constants.MSG_BUILD_OPTIONS_CHANGED + constants.MSG_REBUILD_ALL)
124+
if err := m.buildPath.RemoveAll(); err != nil {
125+
return errors.WithMessage(err, tr("cleaning build path"))
126+
}
127+
if err := m.buildPath.MkdirAll(); err != nil {
128+
return errors.WithMessage(err, tr("cleaning build path"))
129+
}
130+
return nil
131+
}
132+
133+
if m.clean {
134+
return wipe()
135+
}
136+
137+
// Load previous build options map
138+
var buildOptionsJSONPrevious []byte
139+
var _err error
140+
if buildOptionsFile := m.buildPath.Join("build.options.json"); buildOptionsFile.Exist() {
141+
buildOptionsJSONPrevious, _err = buildOptionsFile.ReadFile()
142+
if _err != nil {
143+
return errors.WithStack(_err)
144+
}
145+
}
146+
147+
if len(buildOptionsJSONPrevious) == 0 {
148+
return nil
149+
}
150+
151+
var prevOpts *properties.Map
152+
if err := json.Unmarshal(buildOptionsJSONPrevious, &prevOpts); err != nil || prevOpts == nil {
153+
m.builderLogger.Info(tr("%[1]s invalid, rebuilding all", "build.options.json"))
154+
return wipe()
155+
}
156+
157+
// If SketchLocation path is different but filename is the same, consider it equal
158+
if filepath.Base(m.currentOptions.Get("sketchLocation")) == filepath.Base(prevOpts.Get("sketchLocation")) {
159+
m.currentOptions.Remove("sketchLocation")
160+
prevOpts.Remove("sketchLocation")
161+
}
162+
163+
// If options are not changed check if core has
164+
if m.currentOptions.Equals(prevOpts) {
165+
// check if any of the files contained in the core folders has changed
166+
// since the json was generated - like platform.txt or similar
167+
// if so, trigger a "safety" wipe
168+
targetCoreFolder := m.runtimePlatformPath
169+
coreFolder := m.buildCorePath
170+
realCoreFolder := coreFolder.Parent().Parent()
171+
jsonPath := m.buildPath.Join("build.options.json")
172+
coreUnchanged, _ := utils.DirContentIsOlderThan(realCoreFolder, jsonPath, ".txt")
173+
if coreUnchanged && targetCoreFolder != nil && !realCoreFolder.EqualsTo(targetCoreFolder) {
174+
coreUnchanged, _ = utils.DirContentIsOlderThan(targetCoreFolder, jsonPath, ".txt")
175+
}
176+
if coreUnchanged {
177+
return nil
178+
}
179+
}
180+
181+
return wipe()
182+
}

Diff for: arduino/builder/builder.go

+162-9
Original file line numberDiff line numberDiff line change
@@ -16,21 +16,81 @@
1616
package builder
1717

1818
import (
19+
"errors"
20+
"fmt"
21+
22+
"github.com/arduino/arduino-cli/arduino/builder/compilation"
23+
"github.com/arduino/arduino-cli/arduino/builder/logger"
24+
"github.com/arduino/arduino-cli/arduino/builder/progress"
25+
"github.com/arduino/arduino-cli/arduino/cores"
1926
"github.com/arduino/arduino-cli/arduino/sketch"
2027
"github.com/arduino/go-paths-helper"
2128
"github.com/arduino/go-properties-orderedmap"
2229
)
2330

31+
// ErrSketchCannotBeLocatedInBuildPath fixdoc
32+
var ErrSketchCannotBeLocatedInBuildPath = errors.New("sketch cannot be located in build path")
33+
2434
// Builder is a Sketch builder.
2535
type Builder struct {
2636
sketch *sketch.Sketch
2737
buildProperties *properties.Map
2838

39+
buildPath *paths.Path
40+
sketchBuildPath *paths.Path
41+
coreBuildPath *paths.Path
42+
librariesBuildPath *paths.Path
43+
2944
// Parallel processes
3045
jobs int
3146

47+
// Custom build properties defined by user (line by line as "key=value" pairs)
48+
customBuildProperties []string
49+
3250
// core related
3351
coreBuildCachePath *paths.Path
52+
53+
logger *logger.BuilderLogger
54+
clean bool
55+
56+
// Source code overrides (filename -> content map).
57+
// The provided source data is used instead of reading it from disk.
58+
// The keys of the map are paths relative to sketch folder.
59+
sourceOverrides map[string]string
60+
61+
// Set to true to skip build and produce only Compilation Database
62+
onlyUpdateCompilationDatabase bool
63+
// Compilation Database to build/update
64+
compilationDatabase *compilation.Database
65+
66+
// Progress of all various steps
67+
Progress *progress.Struct
68+
69+
// Sizer results
70+
executableSectionsSize ExecutablesFileSections
71+
72+
// C++ Parsing
73+
lineOffset int
74+
75+
targetPlatform *cores.PlatformRelease
76+
actualPlatform *cores.PlatformRelease
77+
78+
buildArtifacts *BuildArtifacts
79+
80+
*BuildOptionsManager
81+
}
82+
83+
// BuildArtifacts contains the result of various build
84+
type BuildArtifacts struct {
85+
// populated by BuildCore
86+
coreArchiveFilePath *paths.Path
87+
coreObjectsFiles paths.PathList
88+
89+
// populated by BuildLibraries
90+
librariesObjectFiles paths.PathList
91+
92+
// populated by BuildSketch
93+
sketchObjectFiles paths.PathList
3494
}
3595

3696
// NewBuilder creates a sketch Builder.
@@ -41,7 +101,17 @@ func NewBuilder(
41101
optimizeForDebug bool,
42102
coreBuildCachePath *paths.Path,
43103
jobs int,
44-
) *Builder {
104+
requestBuildProperties []string,
105+
hardwareDirs, builtInToolsDirs, otherLibrariesDirs paths.PathList,
106+
builtInLibrariesDirs *paths.Path,
107+
fqbn *cores.FQBN,
108+
clean bool,
109+
sourceOverrides map[string]string,
110+
onlyUpdateCompilationDatabase bool,
111+
targetPlatform, actualPlatform *cores.PlatformRelease,
112+
logger *logger.BuilderLogger,
113+
progressStats *progress.Struct,
114+
) (*Builder, error) {
45115
buildProperties := properties.NewMap()
46116
if boardBuildProperties != nil {
47117
buildProperties.Merge(boardBuildProperties)
@@ -64,20 +134,103 @@ func NewBuilder(
64134
}
65135
}
66136

67-
return &Builder{
68-
sketch: sk,
69-
buildProperties: buildProperties,
70-
coreBuildCachePath: coreBuildCachePath,
71-
jobs: jobs,
137+
// Add user provided custom build properties
138+
customBuildProperties, err := properties.LoadFromSlice(requestBuildProperties)
139+
if err != nil {
140+
return nil, fmt.Errorf("invalid build properties: %w", err)
141+
}
142+
buildProperties.Merge(customBuildProperties)
143+
customBuildPropertiesArgs := append(requestBuildProperties, "build.warn_data_percentage=75")
144+
145+
sketchBuildPath, err := buildPath.Join("sketch").Abs()
146+
if err != nil {
147+
return nil, err
72148
}
149+
librariesBuildPath, err := buildPath.Join("libraries").Abs()
150+
if err != nil {
151+
return nil, err
152+
}
153+
coreBuildPath, err := buildPath.Join("core").Abs()
154+
if err != nil {
155+
return nil, err
156+
}
157+
158+
if buildPath.Canonical().EqualsTo(sk.FullPath.Canonical()) {
159+
return nil, ErrSketchCannotBeLocatedInBuildPath
160+
}
161+
162+
if progressStats == nil {
163+
progressStats = progress.New(nil)
164+
}
165+
166+
return &Builder{
167+
sketch: sk,
168+
buildProperties: buildProperties,
169+
buildPath: buildPath,
170+
sketchBuildPath: sketchBuildPath,
171+
coreBuildPath: coreBuildPath,
172+
librariesBuildPath: librariesBuildPath,
173+
jobs: jobs,
174+
customBuildProperties: customBuildPropertiesArgs,
175+
coreBuildCachePath: coreBuildCachePath,
176+
logger: logger,
177+
clean: clean,
178+
sourceOverrides: sourceOverrides,
179+
onlyUpdateCompilationDatabase: onlyUpdateCompilationDatabase,
180+
compilationDatabase: compilation.NewDatabase(buildPath.Join("compile_commands.json")),
181+
Progress: progressStats,
182+
executableSectionsSize: []ExecutableSectionSize{},
183+
buildArtifacts: &BuildArtifacts{},
184+
targetPlatform: targetPlatform,
185+
actualPlatform: actualPlatform,
186+
BuildOptionsManager: NewBuildOptionsManager(
187+
hardwareDirs, builtInToolsDirs, otherLibrariesDirs,
188+
builtInLibrariesDirs, buildPath,
189+
sk,
190+
customBuildPropertiesArgs,
191+
fqbn,
192+
clean,
193+
buildProperties.Get("compiler.optimization_flags"),
194+
buildProperties.GetPath("runtime.platform.path"),
195+
buildProperties.GetPath("build.core.path"), // TODO can we buildCorePath ?
196+
logger,
197+
),
198+
}, nil
73199
}
74200

75201
// GetBuildProperties returns the build properties for running this build
76202
func (b *Builder) GetBuildProperties() *properties.Map {
77203
return b.buildProperties
78204
}
79205

80-
// Jobs number of parallel processes
81-
func (b *Builder) Jobs() int {
82-
return b.jobs
206+
// GetBuildPath returns the build path
207+
func (b *Builder) GetBuildPath() *paths.Path {
208+
return b.buildPath
209+
}
210+
211+
// GetSketchBuildPath returns the sketch build path
212+
func (b *Builder) GetSketchBuildPath() *paths.Path {
213+
return b.sketchBuildPath
214+
}
215+
216+
// GetLibrariesBuildPath returns the libraries build path
217+
func (b *Builder) GetLibrariesBuildPath() *paths.Path {
218+
return b.librariesBuildPath
219+
}
220+
221+
// ExecutableSectionsSize fixdoc
222+
func (b *Builder) ExecutableSectionsSize() ExecutablesFileSections {
223+
return b.executableSectionsSize
224+
}
225+
226+
// SaveCompilationDatabase fixdoc
227+
func (b *Builder) SaveCompilationDatabase() {
228+
if b.compilationDatabase != nil {
229+
b.compilationDatabase.SaveToFile()
230+
}
231+
}
232+
233+
// TargetPlatform fixdoc
234+
func (b *Builder) TargetPlatform() *cores.PlatformRelease {
235+
return b.targetPlatform
83236
}

0 commit comments

Comments
 (0)