Skip to content

Commit 72dd249

Browse files
facchinmcmaglie
andauthored
Reuse (cache) object archives in large sketch projects (#2464)
* Reuse archiveCompiledFiles helper for long commandline shrink Since archiveCompiledFiles already handles hot cache correctly, this avoids objs.a being rebuilt even if files don't change. Would be ideal if PathList could expose a generic Filter API (to get rid of the "duplicated" filter) * Upgrade go-paths / remove duplicate filter function * Consider existing archives during the build * Simplified archiveCompiledFiles function signature It doesn't make sense anymore to keep path and filename separated. * Added integration test --------- Co-authored-by: Cristian Maglie <[email protected]>
1 parent 71ff4ac commit 72dd249

File tree

8 files changed

+40
-35
lines changed

8 files changed

+40
-35
lines changed

Diff for: .licenses/go/github.com/arduino/go-paths-helper.dep.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
name: github.com/arduino/go-paths-helper
3-
version: v1.10.1
3+
version: v1.11.0
44
type: go
55
summary:
66
homepage: https://pkg.go.dev/github.com/arduino/go-paths-helper

Diff for: go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ replace github.com/mailru/easyjson => github.com/cmaglie/easyjson v0.8.1
77

88
require (
99
github.com/ProtonMail/go-crypto v0.0.0-20230828082145-3c4c8a2d2371
10-
github.com/arduino/go-paths-helper v1.10.1
10+
github.com/arduino/go-paths-helper v1.11.0
1111
github.com/arduino/go-properties-orderedmap v1.8.0
1212
github.com/arduino/go-timeutils v0.0.0-20171220113728-d1dd9e313b1b
1313
github.com/arduino/go-win32-utils v1.0.0

Diff for: go.sum

+2-2
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ
1111
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
1212
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
1313
github.com/arduino/go-paths-helper v1.0.1/go.mod h1:HpxtKph+g238EJHq4geEPv9p+gl3v5YYu35Yb+w31Ck=
14-
github.com/arduino/go-paths-helper v1.10.1 h1:j8InnhLrSeoPiOvTnZL0XMFt7l407ciTBJJJs7W9bs4=
15-
github.com/arduino/go-paths-helper v1.10.1/go.mod h1:jcpW4wr0u69GlXhTYydsdsqAjLaYK5n7oWHfKqOG6LM=
14+
github.com/arduino/go-paths-helper v1.11.0 h1:hkpGb9AtCTByTj2FKutuHWb3klDf4kAKL10hW+fN+oE=
15+
github.com/arduino/go-paths-helper v1.11.0/go.mod h1:jcpW4wr0u69GlXhTYydsdsqAjLaYK5n7oWHfKqOG6LM=
1616
github.com/arduino/go-properties-orderedmap v1.8.0 h1:wEfa6hHdpezrVOh787OmClsf/Kd8qB+zE3P2Xbrn0CQ=
1717
github.com/arduino/go-properties-orderedmap v1.8.0/go.mod h1:DKjD2VXY/NZmlingh4lSFMEYCVubfeArCsGPGDwb2yk=
1818
github.com/arduino/go-timeutils v0.0.0-20171220113728-d1dd9e313b1b h1:9hDi4F2st6dbLC3y4i02zFT5quS4X6iioWifGlVwfy4=

Diff for: internal/arduino/builder/archive_compiled_files.go

+1-3
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ import (
2020
)
2121

2222
// ArchiveCompiledFiles fixdoc
23-
func (b *Builder) archiveCompiledFiles(buildPath *paths.Path, archiveFile *paths.Path, objectFilesToArchive paths.PathList) (*paths.Path, error) {
24-
archiveFilePath := buildPath.JoinPath(archiveFile)
25-
23+
func (b *Builder) archiveCompiledFiles(archiveFilePath *paths.Path, objectFilesToArchive paths.PathList) (*paths.Path, error) {
2624
if b.onlyUpdateCompilationDatabase {
2725
if b.logger.Verbose() {
2826
b.logger.Info(tr("Skipping archive creation of: %[1]s", archiveFilePath))

Diff for: internal/arduino/builder/core.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ func (b *Builder) compileCore() (*paths.Path, paths.PathList, error) {
128128
return nil, nil, err
129129
}
130130

131-
archiveFile, err := b.archiveCompiledFiles(b.coreBuildPath, paths.New("core.a"), coreObjectFiles)
131+
archiveFile, err := b.archiveCompiledFiles(b.coreBuildPath.Join("core.a"), coreObjectFiles)
132132
if err != nil {
133133
return nil, nil, err
134134
}

Diff for: internal/arduino/builder/libraries.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ func (b *Builder) compileLibrary(library *libraries.Library, includes []string)
196196
return nil, err
197197
}
198198
if library.DotALinkage {
199-
archiveFile, err := b.archiveCompiledFiles(libraryBuildPath, paths.New(library.DirName+".a"), libObjectFiles)
199+
archiveFile, err := b.archiveCompiledFiles(libraryBuildPath.Join(library.DirName+".a"), libObjectFiles)
200200
if err != nil {
201201
return nil, err
202202
}

Diff for: internal/arduino/builder/linker.go

+21-24
Original file line numberDiff line numberDiff line change
@@ -53,34 +53,31 @@ func (b *Builder) link() error {
5353
// it may happen that a subdir/spi.o inside the archive may be overwritten by a anotherdir/spi.o
5454
// because thery are both named spi.o.
5555

56-
properties := b.buildProperties.Clone()
57-
archives := paths.NewPathList()
56+
// Put all the existing archives apart from the other object files
57+
existingArchives := objectFiles.Clone()
58+
existingArchives.FilterSuffix(".a")
59+
objectFiles.FilterOutSuffix(".a")
60+
61+
// Generate an archive for each directory from the remaining object files
62+
newArchives := paths.NewPathList()
5863
for _, object := range objectFiles {
59-
if object.HasSuffix(".a") {
60-
archives.Add(object)
61-
continue
62-
}
6364
archive := object.Parent().Join("objs.a")
64-
if !archives.Contains(archive) {
65-
archives.Add(archive)
66-
// Cleanup old archives
67-
_ = archive.Remove()
68-
}
69-
properties.Set("archive_file", archive.Base())
70-
properties.SetPath("archive_file_path", archive)
71-
properties.SetPath("object_file", object)
72-
73-
command, err := b.prepareCommandForRecipe(properties, "recipe.ar.pattern", false)
74-
if err != nil {
75-
return err
76-
}
77-
78-
if err := b.execCommand(command); err != nil {
79-
return err
80-
}
65+
newArchives.AddIfMissing(archive)
66+
}
67+
for _, archive := range newArchives {
68+
archiveDir := archive.Parent()
69+
relatedObjectFiles := objectFiles.Clone()
70+
relatedObjectFiles.Filter(func(object *paths.Path) bool {
71+
// extract all the object files that are in the same directory of the archive
72+
return object.Parent().EquivalentTo(archiveDir)
73+
})
74+
b.archiveCompiledFiles(archive, relatedObjectFiles)
8175
}
8276

83-
objectFileList = strings.Join(f.Map(archives.AsStrings(), wrapWithDoubleQuotes), " ")
77+
// Put everything together
78+
allArchives := existingArchives.Clone()
79+
allArchives.AddAll(newArchives)
80+
objectFileList = strings.Join(f.Map(allArchives.AsStrings(), wrapWithDoubleQuotes), " ")
8481
objectFileList = "-Wl,--whole-archive " + objectFileList + " -Wl,--no-whole-archive"
8582
}
8683

Diff for: internal/integrationtest/compile_1/compile_test.go

+12-2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import (
2121
"encoding/json"
2222
"fmt"
2323
"os"
24+
"regexp"
2425
"sort"
2526
"strings"
2627
"testing"
@@ -830,8 +831,17 @@ func TestCompileWithArchivesAndLongPaths(t *testing.T) {
830831
sketchPath := paths.New(libOutput)
831832
sketchPath = sketchPath.Join("examples", "ArduinoIoTCloud-Advanced")
832833

833-
_, _, err = cli.Run("compile", "-b", "esp8266:esp8266:huzzah", sketchPath.String(), "--config-file", "arduino-cli.yaml")
834-
require.NoError(t, err)
834+
t.Run("Compile", func(t *testing.T) {
835+
_, _, err = cli.Run("compile", "-b", "esp8266:esp8266:huzzah", sketchPath.String(), "--config-file", "arduino-cli.yaml")
836+
require.NoError(t, err)
837+
})
838+
839+
t.Run("CheckCachingOfFolderArchives", func(t *testing.T) {
840+
// Run compile again and check if the archive is re-used (cached)
841+
out, _, err := cli.Run("compile", "-b", "esp8266:esp8266:huzzah", sketchPath.String(), "--config-file", "arduino-cli.yaml", "-v")
842+
require.NoError(t, err)
843+
require.True(t, regexp.MustCompile(`(?m)^Using previously compiled file:.*libraries.ArduinoIoTCloud.objs\.a$`).Match(out))
844+
})
835845
}
836846

837847
func TestCompileWithPrecompileLibrary(t *testing.T) {

0 commit comments

Comments
 (0)