Skip to content

Commit f561da0

Browse files
[skip-changelog] builder: refactor utils functions (#2344)
1 parent c506f6a commit f561da0

13 files changed

+396
-534
lines changed

Diff for: arduino/builder/archive_compiled_files.go

+75
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// This file is part of arduino-cli.
2+
//
3+
// Copyright 2023 ARDUINO SA (http://www.arduino.cc/)
4+
//
5+
// This software is released under the GNU General Public License version 3,
6+
// which covers the main part of arduino-cli.
7+
// The terms of this license can be found at:
8+
// https://www.gnu.org/licenses/gpl-3.0.en.html
9+
//
10+
// You can be released from the requirements of the above licenses by purchasing
11+
// a commercial license. Buying such a license is mandatory if you want to
12+
// modify or otherwise use the software for commercial activities involving the
13+
// Arduino software without disclosing the source code of your own applications.
14+
// To purchase a commercial license, send an email to [email protected].
15+
16+
package builder
17+
18+
import (
19+
"github.com/arduino/go-paths-helper"
20+
"github.com/pkg/errors"
21+
)
22+
23+
// ArchiveCompiledFiles fixdoc
24+
func (b *Builder) archiveCompiledFiles(buildPath *paths.Path, archiveFile *paths.Path, objectFilesToArchive paths.PathList) (*paths.Path, error) {
25+
archiveFilePath := buildPath.JoinPath(archiveFile)
26+
27+
if b.onlyUpdateCompilationDatabase {
28+
if b.logger.Verbose() {
29+
b.logger.Info(tr("Skipping archive creation of: %[1]s", archiveFilePath))
30+
}
31+
return archiveFilePath, nil
32+
}
33+
34+
if archiveFileStat, err := archiveFilePath.Stat(); err == nil {
35+
rebuildArchive := false
36+
for _, objectFile := range objectFilesToArchive {
37+
objectFileStat, err := objectFile.Stat()
38+
if err != nil || objectFileStat.ModTime().After(archiveFileStat.ModTime()) {
39+
// need to rebuild the archive
40+
rebuildArchive = true
41+
break
42+
}
43+
}
44+
45+
// something changed, rebuild the core archive
46+
if rebuildArchive {
47+
if err := archiveFilePath.Remove(); err != nil {
48+
return nil, errors.WithStack(err)
49+
}
50+
} else {
51+
if b.logger.Verbose() {
52+
b.logger.Info(tr("Using previously compiled file: %[1]s", archiveFilePath))
53+
}
54+
return archiveFilePath, nil
55+
}
56+
}
57+
58+
for _, objectFile := range objectFilesToArchive {
59+
properties := b.buildProperties.Clone()
60+
properties.Set("archive_file", archiveFilePath.Base())
61+
properties.SetPath("archive_file_path", archiveFilePath)
62+
properties.SetPath("object_file", objectFile)
63+
64+
command, err := b.prepareCommandForRecipe(properties, "recipe.ar.pattern", false)
65+
if err != nil {
66+
return nil, errors.WithStack(err)
67+
}
68+
69+
if err := b.execCommand(command); err != nil {
70+
return nil, errors.WithStack(err)
71+
}
72+
}
73+
74+
return archiveFilePath, nil
75+
}

Diff for: arduino/builder/builder.go

+65-30
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,20 @@ import (
1919
"errors"
2020
"fmt"
2121
"io"
22+
"os"
23+
"path/filepath"
24+
"strings"
2225

2326
"github.com/arduino/arduino-cli/arduino/builder/internal/compilation"
2427
"github.com/arduino/arduino-cli/arduino/builder/internal/detector"
2528
"github.com/arduino/arduino-cli/arduino/builder/internal/logger"
2629
"github.com/arduino/arduino-cli/arduino/builder/internal/progress"
30+
"github.com/arduino/arduino-cli/arduino/builder/internal/utils"
2731
"github.com/arduino/arduino-cli/arduino/cores"
2832
"github.com/arduino/arduino-cli/arduino/libraries"
2933
"github.com/arduino/arduino-cli/arduino/libraries/librariesmanager"
3034
"github.com/arduino/arduino-cli/arduino/sketch"
35+
"github.com/arduino/arduino-cli/executils"
3136
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
3237
"github.com/arduino/go-paths-helper"
3338
"github.com/arduino/go-properties-orderedmap"
@@ -268,19 +273,16 @@ func (b *Builder) preprocess() error {
268273
return err
269274
}
270275
b.Progress.CompleteStep()
271-
b.Progress.PushProgress()
272276

273277
if err := b.RunRecipe("recipe.hooks.prebuild", ".pattern", false); err != nil {
274278
return err
275279
}
276280
b.Progress.CompleteStep()
277-
b.Progress.PushProgress()
278281

279282
if err := b.prepareSketchBuildPath(); err != nil {
280283
return err
281284
}
282285
b.Progress.CompleteStep()
283-
b.Progress.PushProgress()
284286

285287
b.logIfVerbose(false, tr("Detecting libraries used..."))
286288
err := b.libsDetector.FindIncludes(
@@ -297,18 +299,15 @@ func (b *Builder) preprocess() error {
297299
return err
298300
}
299301
b.Progress.CompleteStep()
300-
b.Progress.PushProgress()
301302

302303
b.warnAboutArchIncompatibleLibraries(b.libsDetector.ImportedLibraries())
303304
b.Progress.CompleteStep()
304-
b.Progress.PushProgress()
305305

306306
b.logIfVerbose(false, tr("Generating function prototypes..."))
307307
if err := b.preprocessSketch(b.libsDetector.IncludeFolders()); err != nil {
308308
return err
309309
}
310310
b.Progress.CompleteStep()
311-
b.Progress.PushProgress()
312311

313312
return nil
314313
}
@@ -337,11 +336,9 @@ func (b *Builder) Build() error {
337336

338337
b.libsDetector.PrintUsedAndNotUsedLibraries(buildErr != nil)
339338
b.Progress.CompleteStep()
340-
b.Progress.PushProgress()
341339

342340
b.printUsedLibraries(b.libsDetector.ImportedLibraries())
343341
b.Progress.CompleteStep()
344-
b.Progress.PushProgress()
345342

346343
if buildErr != nil {
347344
return buildErr
@@ -350,13 +347,11 @@ func (b *Builder) Build() error {
350347
return err
351348
}
352349
b.Progress.CompleteStep()
353-
b.Progress.PushProgress()
354350

355351
if err := b.size(); err != nil {
356352
return err
357353
}
358354
b.Progress.CompleteStep()
359-
b.Progress.PushProgress()
360355

361356
return nil
362357
}
@@ -368,115 +363,155 @@ func (b *Builder) build() error {
368363
return err
369364
}
370365
b.Progress.CompleteStep()
371-
b.Progress.PushProgress()
372366

373-
if err := b.BuildSketch(b.libsDetector.IncludeFolders()); err != nil {
367+
if err := b.buildSketch(b.libsDetector.IncludeFolders()); err != nil {
374368
return err
375369
}
376370
b.Progress.CompleteStep()
377-
b.Progress.PushProgress()
378371

379372
if err := b.RunRecipe("recipe.hooks.sketch.postbuild", ".pattern", true); err != nil {
380373
return err
381374
}
382375
b.Progress.CompleteStep()
383-
b.Progress.PushProgress()
384376

385377
b.logIfVerbose(false, tr("Compiling libraries..."))
386378
if err := b.RunRecipe("recipe.hooks.libraries.prebuild", ".pattern", false); err != nil {
387379
return err
388380
}
389381
b.Progress.CompleteStep()
390-
b.Progress.PushProgress()
391382

392383
if err := b.removeUnusedCompiledLibraries(b.libsDetector.ImportedLibraries()); err != nil {
393384
return err
394385
}
395386
b.Progress.CompleteStep()
396-
b.Progress.PushProgress()
397387

398388
if err := b.buildLibraries(b.libsDetector.IncludeFolders(), b.libsDetector.ImportedLibraries()); err != nil {
399389
return err
400390
}
401391
b.Progress.CompleteStep()
402-
b.Progress.PushProgress()
403392

404393
if err := b.RunRecipe("recipe.hooks.libraries.postbuild", ".pattern", true); err != nil {
405394
return err
406395
}
407396
b.Progress.CompleteStep()
408-
b.Progress.PushProgress()
409397

410398
b.logIfVerbose(false, tr("Compiling core..."))
411399
if err := b.RunRecipe("recipe.hooks.core.prebuild", ".pattern", false); err != nil {
412400
return err
413401
}
414402
b.Progress.CompleteStep()
415-
b.Progress.PushProgress()
416403

417404
if err := b.buildCore(); err != nil {
418405
return err
419406
}
420407
b.Progress.CompleteStep()
421-
b.Progress.PushProgress()
422408

423409
if err := b.RunRecipe("recipe.hooks.core.postbuild", ".pattern", true); err != nil {
424410
return err
425411
}
426412
b.Progress.CompleteStep()
427-
b.Progress.PushProgress()
428413

429414
b.logIfVerbose(false, tr("Linking everything together..."))
430415
if err := b.RunRecipe("recipe.hooks.linking.prelink", ".pattern", false); err != nil {
431416
return err
432417
}
433418
b.Progress.CompleteStep()
434-
b.Progress.PushProgress()
435419

436420
if err := b.link(); err != nil {
437421
return err
438422
}
439423
b.Progress.CompleteStep()
440-
b.Progress.PushProgress()
441424

442425
if err := b.RunRecipe("recipe.hooks.linking.postlink", ".pattern", true); err != nil {
443426
return err
444427
}
445428
b.Progress.CompleteStep()
446-
b.Progress.PushProgress()
447429

448430
if err := b.RunRecipe("recipe.hooks.objcopy.preobjcopy", ".pattern", false); err != nil {
449431
return err
450432
}
451433
b.Progress.CompleteStep()
452-
b.Progress.PushProgress()
453434

454435
if err := b.RunRecipe("recipe.objcopy.", ".pattern", true); err != nil {
455436
return err
456437
}
457438
b.Progress.CompleteStep()
458-
b.Progress.PushProgress()
459439

460440
if err := b.RunRecipe("recipe.hooks.objcopy.postobjcopy", ".pattern", true); err != nil {
461441
return err
462442
}
463443
b.Progress.CompleteStep()
464-
b.Progress.PushProgress()
465444

466-
if err := b.MergeSketchWithBootloader(); err != nil {
445+
if err := b.mergeSketchWithBootloader(); err != nil {
467446
return err
468447
}
469448
b.Progress.CompleteStep()
470-
b.Progress.PushProgress()
471449

472450
if err := b.RunRecipe("recipe.hooks.postbuild", ".pattern", true); err != nil {
473451
return err
474452
}
475453
b.Progress.CompleteStep()
476-
b.Progress.PushProgress()
477454

478455
if b.compilationDatabase != nil {
479456
b.compilationDatabase.SaveToFile()
480457
}
481458
return nil
482459
}
460+
461+
func (b *Builder) prepareCommandForRecipe(buildProperties *properties.Map, recipe string, removeUnsetProperties bool) (*executils.Process, error) {
462+
pattern := buildProperties.Get(recipe)
463+
if pattern == "" {
464+
return nil, fmt.Errorf(tr("%[1]s pattern is missing"), recipe)
465+
}
466+
467+
commandLine := buildProperties.ExpandPropsInString(pattern)
468+
if removeUnsetProperties {
469+
commandLine = properties.DeleteUnexpandedPropsFromString(commandLine)
470+
}
471+
472+
parts, err := properties.SplitQuotedString(commandLine, `"'`, false)
473+
if err != nil {
474+
return nil, err
475+
}
476+
477+
// if the overall commandline is too long for the platform
478+
// try reducing the length by making the filenames relative
479+
// and changing working directory to build.path
480+
var relativePath string
481+
if len(commandLine) > 30000 {
482+
relativePath = buildProperties.Get("build.path")
483+
for i, arg := range parts {
484+
if _, err := os.Stat(arg); os.IsNotExist(err) {
485+
continue
486+
}
487+
rel, err := filepath.Rel(relativePath, arg)
488+
if err == nil && !strings.Contains(rel, "..") && len(rel) < len(arg) {
489+
parts[i] = rel
490+
}
491+
}
492+
}
493+
494+
command, err := executils.NewProcess(nil, parts...)
495+
if err != nil {
496+
return nil, err
497+
}
498+
if relativePath != "" {
499+
command.SetDir(relativePath)
500+
}
501+
502+
return command, nil
503+
}
504+
505+
func (b *Builder) execCommand(command *executils.Process) error {
506+
if b.logger.Verbose() {
507+
b.logger.Info(utils.PrintableCommand(command.GetArgs()))
508+
command.RedirectStdoutTo(b.logger.Stdout())
509+
}
510+
command.RedirectStderrTo(b.logger.Stderr())
511+
512+
if err := command.Start(); err != nil {
513+
return err
514+
}
515+
516+
return command.Wait()
517+
}

0 commit comments

Comments
 (0)