Skip to content

Commit

Permalink
[skip-changelog] builder: refactor utils functions (#2344)
Browse files Browse the repository at this point in the history
  • Loading branch information
alessio-perugini authored Oct 2, 2023
1 parent c506f6a commit f561da0
Show file tree
Hide file tree
Showing 13 changed files with 396 additions and 534 deletions.
75 changes: 75 additions & 0 deletions arduino/builder/archive_compiled_files.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
// This file is part of arduino-cli.
//
// Copyright 2023 ARDUINO SA (http://www.arduino.cc/)
//
// This software is released under the GNU General Public License version 3,
// which covers the main part of arduino-cli.
// The terms of this license can be found at:
// https://www.gnu.org/licenses/gpl-3.0.en.html
//
// You can be released from the requirements of the above licenses by purchasing
// a commercial license. Buying such a license is mandatory if you want to
// modify or otherwise use the software for commercial activities involving the
// Arduino software without disclosing the source code of your own applications.
// To purchase a commercial license, send an email to [email protected].

package builder

import (
"github.com/arduino/go-paths-helper"
"github.com/pkg/errors"
)

// ArchiveCompiledFiles fixdoc
func (b *Builder) archiveCompiledFiles(buildPath *paths.Path, archiveFile *paths.Path, objectFilesToArchive paths.PathList) (*paths.Path, error) {
archiveFilePath := buildPath.JoinPath(archiveFile)

if b.onlyUpdateCompilationDatabase {
if b.logger.Verbose() {
b.logger.Info(tr("Skipping archive creation of: %[1]s", archiveFilePath))
}
return archiveFilePath, nil
}

if archiveFileStat, err := archiveFilePath.Stat(); err == nil {
rebuildArchive := false
for _, objectFile := range objectFilesToArchive {
objectFileStat, err := objectFile.Stat()
if err != nil || objectFileStat.ModTime().After(archiveFileStat.ModTime()) {
// need to rebuild the archive
rebuildArchive = true
break
}
}

// something changed, rebuild the core archive
if rebuildArchive {
if err := archiveFilePath.Remove(); err != nil {
return nil, errors.WithStack(err)
}
} else {
if b.logger.Verbose() {
b.logger.Info(tr("Using previously compiled file: %[1]s", archiveFilePath))
}
return archiveFilePath, nil
}
}

for _, objectFile := range objectFilesToArchive {
properties := b.buildProperties.Clone()
properties.Set("archive_file", archiveFilePath.Base())
properties.SetPath("archive_file_path", archiveFilePath)
properties.SetPath("object_file", objectFile)

command, err := b.prepareCommandForRecipe(properties, "recipe.ar.pattern", false)
if err != nil {
return nil, errors.WithStack(err)
}

if err := b.execCommand(command); err != nil {
return nil, errors.WithStack(err)
}
}

return archiveFilePath, nil
}
95 changes: 65 additions & 30 deletions arduino/builder/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,20 @@ import (
"errors"
"fmt"
"io"
"os"
"path/filepath"
"strings"

"github.com/arduino/arduino-cli/arduino/builder/internal/compilation"
"github.com/arduino/arduino-cli/arduino/builder/internal/detector"
"github.com/arduino/arduino-cli/arduino/builder/internal/logger"
"github.com/arduino/arduino-cli/arduino/builder/internal/progress"
"github.com/arduino/arduino-cli/arduino/builder/internal/utils"
"github.com/arduino/arduino-cli/arduino/cores"
"github.com/arduino/arduino-cli/arduino/libraries"
"github.com/arduino/arduino-cli/arduino/libraries/librariesmanager"
"github.com/arduino/arduino-cli/arduino/sketch"
"github.com/arduino/arduino-cli/executils"
rpc "github.com/arduino/arduino-cli/rpc/cc/arduino/cli/commands/v1"
"github.com/arduino/go-paths-helper"
"github.com/arduino/go-properties-orderedmap"
Expand Down Expand Up @@ -268,19 +273,16 @@ func (b *Builder) preprocess() error {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

if err := b.RunRecipe("recipe.hooks.prebuild", ".pattern", false); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

if err := b.prepareSketchBuildPath(); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

b.logIfVerbose(false, tr("Detecting libraries used..."))
err := b.libsDetector.FindIncludes(
Expand All @@ -297,18 +299,15 @@ func (b *Builder) preprocess() error {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

b.warnAboutArchIncompatibleLibraries(b.libsDetector.ImportedLibraries())
b.Progress.CompleteStep()
b.Progress.PushProgress()

b.logIfVerbose(false, tr("Generating function prototypes..."))
if err := b.preprocessSketch(b.libsDetector.IncludeFolders()); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

return nil
}
Expand Down Expand Up @@ -337,11 +336,9 @@ func (b *Builder) Build() error {

b.libsDetector.PrintUsedAndNotUsedLibraries(buildErr != nil)
b.Progress.CompleteStep()
b.Progress.PushProgress()

b.printUsedLibraries(b.libsDetector.ImportedLibraries())
b.Progress.CompleteStep()
b.Progress.PushProgress()

if buildErr != nil {
return buildErr
Expand All @@ -350,13 +347,11 @@ func (b *Builder) Build() error {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

if err := b.size(); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

return nil
}
Expand All @@ -368,115 +363,155 @@ func (b *Builder) build() error {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

if err := b.BuildSketch(b.libsDetector.IncludeFolders()); err != nil {
if err := b.buildSketch(b.libsDetector.IncludeFolders()); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

if err := b.RunRecipe("recipe.hooks.sketch.postbuild", ".pattern", true); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

b.logIfVerbose(false, tr("Compiling libraries..."))
if err := b.RunRecipe("recipe.hooks.libraries.prebuild", ".pattern", false); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

if err := b.removeUnusedCompiledLibraries(b.libsDetector.ImportedLibraries()); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

if err := b.buildLibraries(b.libsDetector.IncludeFolders(), b.libsDetector.ImportedLibraries()); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

if err := b.RunRecipe("recipe.hooks.libraries.postbuild", ".pattern", true); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

b.logIfVerbose(false, tr("Compiling core..."))
if err := b.RunRecipe("recipe.hooks.core.prebuild", ".pattern", false); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

if err := b.buildCore(); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

if err := b.RunRecipe("recipe.hooks.core.postbuild", ".pattern", true); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

b.logIfVerbose(false, tr("Linking everything together..."))
if err := b.RunRecipe("recipe.hooks.linking.prelink", ".pattern", false); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

if err := b.link(); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

if err := b.RunRecipe("recipe.hooks.linking.postlink", ".pattern", true); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

if err := b.RunRecipe("recipe.hooks.objcopy.preobjcopy", ".pattern", false); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

if err := b.RunRecipe("recipe.objcopy.", ".pattern", true); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

if err := b.RunRecipe("recipe.hooks.objcopy.postobjcopy", ".pattern", true); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

if err := b.MergeSketchWithBootloader(); err != nil {
if err := b.mergeSketchWithBootloader(); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

if err := b.RunRecipe("recipe.hooks.postbuild", ".pattern", true); err != nil {
return err
}
b.Progress.CompleteStep()
b.Progress.PushProgress()

if b.compilationDatabase != nil {
b.compilationDatabase.SaveToFile()
}
return nil
}

func (b *Builder) prepareCommandForRecipe(buildProperties *properties.Map, recipe string, removeUnsetProperties bool) (*executils.Process, error) {
pattern := buildProperties.Get(recipe)
if pattern == "" {
return nil, fmt.Errorf(tr("%[1]s pattern is missing"), recipe)
}

commandLine := buildProperties.ExpandPropsInString(pattern)
if removeUnsetProperties {
commandLine = properties.DeleteUnexpandedPropsFromString(commandLine)
}

parts, err := properties.SplitQuotedString(commandLine, `"'`, false)
if err != nil {
return nil, err
}

// if the overall commandline is too long for the platform
// try reducing the length by making the filenames relative
// and changing working directory to build.path
var relativePath string
if len(commandLine) > 30000 {
relativePath = buildProperties.Get("build.path")
for i, arg := range parts {
if _, err := os.Stat(arg); os.IsNotExist(err) {
continue
}
rel, err := filepath.Rel(relativePath, arg)
if err == nil && !strings.Contains(rel, "..") && len(rel) < len(arg) {
parts[i] = rel
}
}
}

command, err := executils.NewProcess(nil, parts...)
if err != nil {
return nil, err
}
if relativePath != "" {
command.SetDir(relativePath)
}

return command, nil
}

func (b *Builder) execCommand(command *executils.Process) error {
if b.logger.Verbose() {
b.logger.Info(utils.PrintableCommand(command.GetArgs()))
command.RedirectStdoutTo(b.logger.Stdout())
}
command.RedirectStderrTo(b.logger.Stderr())

if err := command.Start(); err != nil {
return err
}

return command.Wait()
}
Loading

0 comments on commit f561da0

Please sign in to comment.