Skip to content

Commit df435d1

Browse files
committed
Ported Sysprogs extensions to the arduino-builder tool.
1 parent da8fc05 commit df435d1

File tree

10 files changed

+293
-68
lines changed

10 files changed

+293
-68
lines changed

legacy/builder/builder.go

+55
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
package builder
3131

3232
import (
33+
"encoding/json"
34+
"io/ioutil"
3335
"fmt"
3436
"os"
3537
"reflect"
@@ -114,7 +116,60 @@ func (s *Builder) Run(ctx *types.Context) error {
114116
}
115117

116118
mainErr := runCommands(ctx, commands, true)
119+
120+
if ctx.CodeModelBuilder != nil {
121+
var librariesByLocation = map[string]*types.Library{}
117122

123+
for header, libraries := range ctx.HeaderToLibraries {
124+
var knownHeader = new(types.KnownHeader)
125+
126+
knownHeader.Name = header
127+
for _, library := range libraries {
128+
knownHeader.LibraryDirectories = append(knownHeader.LibraryDirectories, library.SrcFolder)
129+
librariesByLocation[library.Folder] = library
130+
}
131+
132+
ctx.CodeModelBuilder.Prototypes = ctx.Prototypes
133+
ctx.CodeModelBuilder.KnownHeaders = append(ctx.CodeModelBuilder.KnownHeaders, knownHeader)
134+
}
135+
136+
for _, library := range librariesByLocation {
137+
var knownLib = new(types.KnownLibrary)
138+
139+
knownLib.Folder = library.Folder
140+
knownLib.SrcFolder = library.SrcFolder
141+
knownLib.UtilityFolder = library.UtilityFolder
142+
knownLib.Layout = library.Layout
143+
knownLib.Name = library.Name
144+
knownLib.RealName = library.RealName
145+
knownLib.IsLegacy = library.IsLegacy
146+
knownLib.Version = library.Version
147+
knownLib.Author = library.Author
148+
knownLib.Maintainer = library.Maintainer
149+
knownLib.Sentence = library.Sentence
150+
knownLib.Paragraph = library.Paragraph
151+
knownLib.URL = library.URL
152+
knownLib.Category = library.Category
153+
knownLib.License = library.License
154+
155+
ctx.CodeModelBuilder.KnownLibraries = append(ctx.CodeModelBuilder.KnownLibraries, knownLib)
156+
}
157+
158+
for key, value := range ctx.BuildProperties {
159+
var kv = new(types.KeyValuePair)
160+
kv.Key = key
161+
kv.Value = value
162+
ctx.CodeModelBuilder.BuildProperties = append(ctx.CodeModelBuilder.BuildProperties, *kv)
163+
}
164+
165+
var bytes, err = json.MarshalIndent(ctx.CodeModelBuilder, "", " ")
166+
if err != nil {
167+
return err
168+
}
169+
ioutil.WriteFile(ctx.CodeModelBuilderFile, bytes, 0644)
170+
return nil
171+
}
172+
118173
commands = []types.Command{
119174
&PrintUsedAndNotUsedLibraries{SketchError: mainErr != nil},
120175

legacy/builder/builder_utils/utils.go

+103-49
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ import (
4040

4141
"github.com/arduino/arduino-cli/legacy/builder/constants"
4242
"github.com/arduino/arduino-cli/legacy/builder/i18n"
43+
"github.com/arduino/arduino-builder/types"
4344
"github.com/arduino/arduino-cli/legacy/builder/types"
4445
"github.com/arduino/arduino-cli/legacy/builder/utils"
4546
"github.com/arduino/go-paths-helper"
@@ -59,8 +60,8 @@ func PrintProgressIfProgressEnabledAndMachineLogger(ctx *types.Context) {
5960
}
6061
}
6162

62-
func CompileFilesRecursive(ctx *types.Context, sourcePath *paths.Path, buildPath *paths.Path, buildProperties *properties.Map, includes []string) (paths.PathList, error) {
63-
objectFiles, err := CompileFiles(ctx, sourcePath, false, buildPath, buildProperties, includes)
63+
func CompileFilesRecursive(ctx *types.Context, sourcePath *paths.Path, buildPath *paths.Path, buildProperties *properties.Map, includes []string, libraryModel *types.CodeModelLibrary) (paths.PathList, error) {
64+
objectFiles, err := CompileFiles(ctx, sourcePath, false, buildPath, buildProperties, includes, libraryModel)
6465
if err != nil {
6566
return nil, i18n.WrapError(err)
6667
}
@@ -71,7 +72,7 @@ func CompileFilesRecursive(ctx *types.Context, sourcePath *paths.Path, buildPath
7172
}
7273

7374
for _, folder := range folders {
74-
subFolderObjectFiles, err := CompileFilesRecursive(ctx, sourcePath.Join(folder.Name()), buildPath.Join(folder.Name()), buildProperties, includes)
75+
subFolderObjectFiles, err := CompileFilesRecursive(ctx, sourcePath.Join(folder.Name()), buildPath.Join(folder.Name()), buildProperties, includes, libraryModel)
7576
if err != nil {
7677
return nil, i18n.WrapError(err)
7778
}
@@ -81,16 +82,16 @@ func CompileFilesRecursive(ctx *types.Context, sourcePath *paths.Path, buildPath
8182
return objectFiles, nil
8283
}
8384

84-
func CompileFiles(ctx *types.Context, sourcePath *paths.Path, recurse bool, buildPath *paths.Path, buildProperties *properties.Map, includes []string) (paths.PathList, error) {
85-
sObjectFiles, err := compileFilesWithExtensionWithRecipe(ctx, sourcePath, recurse, buildPath, buildProperties, includes, ".S", constants.RECIPE_S_PATTERN)
85+
func CompileFiles(ctx *types.Context, sourcePath *paths.Path, recurse bool, buildPath *paths.Path, buildProperties *properties.Map, includes []string, libraryModel *types.CodeModelLibrary) (paths.PathList, error) {
86+
sObjectFiles, err := compileFilesWithExtensionWithRecipe(ctx, sourcePath, recurse, buildPath, buildProperties, includes, ".S", constants.RECIPE_S_PATTERN, libraryModel)
8687
if err != nil {
8788
return nil, i18n.WrapError(err)
8889
}
89-
cObjectFiles, err := compileFilesWithExtensionWithRecipe(ctx, sourcePath, recurse, buildPath, buildProperties, includes, ".c", constants.RECIPE_C_PATTERN)
90+
cObjectFiles, err := compileFilesWithExtensionWithRecipe(ctx, sourcePath, recurse, buildPath, buildProperties, includes, ".c", constants.RECIPE_C_PATTERN, libraryModel)
9091
if err != nil {
9192
return nil, i18n.WrapError(err)
9293
}
93-
cppObjectFiles, err := compileFilesWithExtensionWithRecipe(ctx, sourcePath, recurse, buildPath, buildProperties, includes, ".cpp", constants.RECIPE_CPP_PATTERN)
94+
cppObjectFiles, err := compileFilesWithExtensionWithRecipe(ctx, sourcePath, recurse, buildPath, buildProperties, includes, ".cpp", constants.RECIPE_CPP_PATTERN, libraryModel)
9495
if err != nil {
9596
return nil, i18n.WrapError(err)
9697
}
@@ -101,12 +102,47 @@ func CompileFiles(ctx *types.Context, sourcePath *paths.Path, recurse bool, buil
101102
return objectFiles, nil
102103
}
103104

104-
func compileFilesWithExtensionWithRecipe(ctx *types.Context, sourcePath *paths.Path, recurse bool, buildPath *paths.Path, buildProperties *properties.Map, includes []string, extension string, recipe string) (paths.PathList, error) {
105+
func ReplaceOptimizationFlags(str string) string {
106+
var tmp = strings.Split(str, " ")
107+
for k, v := range tmp {
108+
if v == "-O2" || v == "-Os" || v == "-O1" || v == "-Og" || v == "-O3" {
109+
tmp[k] = "-O0"
110+
} else if v == "-flto" {
111+
tmp[k] = ""
112+
}
113+
}
114+
115+
return strings.Join(tmp, " ")
116+
}
117+
118+
func RemoveOptimizationFromBuildProperties(properties properties.Map) properties.Map {
119+
var result = make(map[string]string)
120+
for k, v := range properties {
121+
result[k] = v
122+
}
123+
124+
result["compiler.c.flags"] = ReplaceOptimizationFlags(result["compiler.c.flags"])
125+
result["compiler.cpp.flags"] = ReplaceOptimizationFlags(result["compiler.cpp.flags"])
126+
return result
127+
}
128+
129+
func ExpandSysprogsExtensionProperties(properties properties.Map) properties.Map {
130+
var result = make(map[string]string)
131+
for k, v := range properties {
132+
result[k] = v
133+
}
134+
135+
result["compiler.c.flags"] += " " + result["com.sysprogs.extraflags"]
136+
result["compiler.cpp.flags"] += " " + result["com.sysprogs.extraflags"]
137+
return result
138+
}
139+
140+
func compileFilesWithExtensionWithRecipe(ctx *types.Context, sourcePath *paths.Path, recurse bool, buildPath *paths.Path, buildProperties *properties.Map, includes []string, extension string, recipe string, libraryModel *types.CodeModelLibrary) (paths.PathList, error) {
105141
sources, err := findFilesInFolder(sourcePath, extension, recurse)
106142
if err != nil {
107143
return nil, i18n.WrapError(err)
108144
}
109-
return compileFilesWithRecipe(ctx, sourcePath, sources, buildPath, buildProperties, includes, recipe)
145+
return compileFilesWithRecipe(ctx, sourcePath, sources, buildPath, buildProperties, includes, recipe, libraryModel)
110146
}
111147

112148
func findFilesInFolder(sourcePath *paths.Path, extension string, recurse bool) (paths.PathList, error) {
@@ -168,7 +204,7 @@ func findAllFilesInFolder(sourcePath string, recurse bool) ([]string, error) {
168204
return sources, nil
169205
}
170206

171-
func compileFilesWithRecipe(ctx *types.Context, sourcePath *paths.Path, sources paths.PathList, buildPath *paths.Path, buildProperties *properties.Map, includes []string, recipe string) (paths.PathList, error) {
207+
func compileFilesWithRecipe(ctx *types.Context, sourcePath *paths.Path, sources paths.PathList, buildPath *paths.Path, buildProperties *properties.Map, includes []string, recipe string, libraryModel *types.CodeModelLibrary) (paths.PathList, error) {
172208
objectFiles := paths.NewPathList()
173209
if len(sources) == 0 {
174210
return objectFiles, nil
@@ -182,7 +218,7 @@ func compileFilesWithRecipe(ctx *types.Context, sourcePath *paths.Path, sources
182218
queue := make(chan *paths.Path)
183219
job := func(source *paths.Path) {
184220
PrintProgressIfProgressEnabledAndMachineLogger(ctx)
185-
objectFile, err := compileFileWithRecipe(ctx, sourcePath, source, buildPath, buildProperties, includes, recipe)
221+
objectFile, err := compileFileWithRecipe(ctx, sourcePath, source, buildPath, buildProperties, includes, recipe, libraryModel)
186222
if err != nil {
187223
errorsMux.Lock()
188224
errors = append(errors, err)
@@ -230,7 +266,7 @@ func compileFilesWithRecipe(ctx *types.Context, sourcePath *paths.Path, sources
230266
return objectFiles, nil
231267
}
232268

233-
func compileFileWithRecipe(ctx *types.Context, sourcePath *paths.Path, source *paths.Path, buildPath *paths.Path, buildProperties *properties.Map, includes []string, recipe string) (*paths.Path, error) {
269+
func compileFileWithRecipe(ctx *types.Context, sourcePath *paths.Path, source *paths.Path, buildPath *paths.Path, buildProperties *properties.Map, includes []string, recipe string, libraryModel *types.CodeModelLibrary) (*paths.Path, error) {
234270
logger := ctx.GetLogger()
235271
properties := buildProperties.Clone()
236272
properties.Set(constants.BUILD_PROPERTIES_COMPILER_WARNING_FLAGS, properties.Get(constants.BUILD_PROPERTIES_COMPILER_WARNING_FLAGS+"."+ctx.WarningsLevel))
@@ -249,17 +285,32 @@ func compileFileWithRecipe(ctx *types.Context, sourcePath *paths.Path, source *p
249285
return nil, i18n.WrapError(err)
250286
}
251287

252-
objIsUpToDate, err := ObjFileIsUpToDate(ctx, source, objectFile, depsFile)
253-
if err != nil {
254-
return nil, i18n.WrapError(err)
255-
}
256-
if !objIsUpToDate {
257-
_, _, err = ExecRecipe(ctx, properties, recipe, false /* stdout */, utils.ShowIfVerbose /* stderr */, utils.Show)
288+
if libraryModel != nil {
289+
//We are not actually building, just dumping the model
290+
command, err := PrepareCommandForRecipe(properties, recipe, false, false, false, logger)
291+
if err != nil {
292+
return "", i18n.WrapError(err)
293+
}
294+
295+
var invocation = new(types.CodeModelGCCInvocation)
296+
invocation.GCC = command.Path
297+
invocation.InputFile = source
298+
invocation.ObjectFile = properties[constants.BUILD_PROPERTIES_OBJECT_FILE]
299+
invocation.Arguments = command.Args[1:]
300+
libraryModel.Invocations = append(libraryModel.Invocations, invocation)
301+
} else {
302+
objIsUpToDate, err := ObjFileIsUpToDate(ctx, source, objectFile, depsFile)
258303
if err != nil {
259304
return nil, i18n.WrapError(err)
260305
}
261-
} else if ctx.Verbose {
262-
logger.Println(constants.LOG_LEVEL_INFO, constants.MSG_USING_PREVIOUS_COMPILED_FILE, objectFile)
306+
if !objIsUpToDate {
307+
_, _, err = ExecRecipe(ctx, properties, recipe, false /* stdout */, utils.ShowIfVerbose /* stderr */, utils.Show)
308+
if err != nil {
309+
return nil, i18n.WrapError(err)
310+
}
311+
} else if ctx.Verbose {
312+
logger.Println(constants.LOG_LEVEL_INFO, constants.MSG_USING_PREVIOUS_COMPILED_FILE, objectFile)
313+
}
263314
}
264315

265316
return objectFile, nil
@@ -449,46 +500,49 @@ func TXTBuildRulesHaveChanged(corePath, targetCorePath, targetFile *paths.Path)
449500
return true
450501
}
451502

452-
func ArchiveCompiledFiles(ctx *types.Context, buildPath *paths.Path, archiveFile *paths.Path, objectFilesToArchive paths.PathList, buildProperties *properties.Map) (*paths.Path, error) {
503+
func ArchiveCompiledFiles(ctx *types.Context, buildPath *paths.Path, archiveFile *paths.Path, objectFilesToArchive paths.PathList, buildProperties *properties.Map, libraryModel *types.CodeModelLibrary) (*paths.Path, error) {
453504
logger := ctx.GetLogger()
454505
archiveFilePath := buildPath.JoinPath(archiveFile)
455506

456507
rebuildArchive := false
508+
if libraryModel != nil {
509+
libraryModel.ArchiveFile = archiveFilePath
510+
} else {
511+
if archiveFileStat, err := archiveFilePath.Stat(); err == nil {
512+
513+
for _, objectFile := range objectFilesToArchive {
514+
objectFileStat, err := objectFile.Stat()
515+
if err != nil || objectFileStat.ModTime().After(archiveFileStat.ModTime()) {
516+
// need to rebuild the archive
517+
rebuildArchive = true
518+
break
519+
}
520+
}
457521

458-
if archiveFileStat, err := archiveFilePath.Stat(); err == nil {
459-
460-
for _, objectFile := range objectFilesToArchive {
461-
objectFileStat, err := objectFile.Stat()
462-
if err != nil || objectFileStat.ModTime().After(archiveFileStat.ModTime()) {
463-
// need to rebuild the archive
464-
rebuildArchive = true
465-
break
522+
// something changed, rebuild the core archive
523+
if rebuildArchive {
524+
err = archiveFilePath.Remove()
525+
if err != nil {
526+
return nil, i18n.WrapError(err)
527+
}
528+
} else {
529+
if ctx.Verbose {
530+
logger.Println(constants.LOG_LEVEL_INFO, constants.MSG_USING_PREVIOUS_COMPILED_FILE, archiveFilePath)
531+
}
532+
return archiveFilePath, nil
466533
}
467534
}
468535

469-
// something changed, rebuild the core archive
470-
if rebuildArchive {
471-
err = archiveFilePath.Remove()
536+
for _, objectFile := range objectFilesToArchive {
537+
properties := buildProperties.Clone()
538+
properties.Set(constants.BUILD_PROPERTIES_ARCHIVE_FILE, archiveFilePath.Base())
539+
properties.SetPath(constants.BUILD_PROPERTIES_ARCHIVE_FILE_PATH, archiveFilePath)
540+
properties.SetPath(constants.BUILD_PROPERTIES_OBJECT_FILE, objectFile)
541+
542+
_, _, err := ExecRecipe(ctx, properties, constants.RECIPE_AR_PATTERN, false /* stdout */, utils.ShowIfVerbose /* stderr */, utils.Show)
472543
if err != nil {
473544
return nil, i18n.WrapError(err)
474545
}
475-
} else {
476-
if ctx.Verbose {
477-
logger.Println(constants.LOG_LEVEL_INFO, constants.MSG_USING_PREVIOUS_COMPILED_FILE, archiveFilePath)
478-
}
479-
return archiveFilePath, nil
480-
}
481-
}
482-
483-
for _, objectFile := range objectFilesToArchive {
484-
properties := buildProperties.Clone()
485-
properties.Set(constants.BUILD_PROPERTIES_ARCHIVE_FILE, archiveFilePath.Base())
486-
properties.SetPath(constants.BUILD_PROPERTIES_ARCHIVE_FILE_PATH, archiveFilePath)
487-
properties.SetPath(constants.BUILD_PROPERTIES_OBJECT_FILE, objectFile)
488-
489-
_, _, err := ExecRecipe(ctx, properties, constants.RECIPE_AR_PATTERN, false /* stdout */, utils.ShowIfVerbose /* stderr */, utils.Show)
490-
if err != nil {
491-
return nil, i18n.WrapError(err)
492546
}
493547
}
494548

legacy/builder/phases/core_builder.go

+24-7
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ type CoreBuilder struct{}
4646
func (s *CoreBuilder) Run(ctx *types.Context) error {
4747
coreBuildPath := ctx.CoreBuildPath
4848
coreBuildCachePath := ctx.CoreBuildCachePath
49-
buildProperties := ctx.BuildProperties
49+
var buildProperties = ctx.BuildProperties
5050

5151
if err := coreBuildPath.MkdirAll(); err != nil {
5252
return i18n.WrapError(err)
@@ -64,7 +64,19 @@ func (s *CoreBuilder) Run(ctx *types.Context) error {
6464
}
6565
}
6666

67-
archiveFile, objectFiles, err := compileCore(ctx, coreBuildPath, coreBuildCachePath, buildProperties)
67+
var coreModel *types.CodeModelLibrary
68+
if ctx.CodeModelBuilder != nil {
69+
coreModel = new(types.CodeModelLibrary)
70+
ctx.CodeModelBuilder.Core = coreModel
71+
}
72+
73+
if ctx.UnoptimizeCore {
74+
buildProperties = builder_utils.RemoveOptimizationFromBuildProperties(buildProperties)
75+
}
76+
77+
buildProperties = builder_utils.ExpandSysprogsExtensionProperties(buildProperties)
78+
79+
archiveFile, objectFiles, err := compileCore(ctx, coreBuildPath, coreBuildCachePath, buildProperties, coreModel)
6880
if err != nil {
6981
return i18n.WrapError(err)
7082
}
@@ -75,12 +87,17 @@ func (s *CoreBuilder) Run(ctx *types.Context) error {
7587
return nil
7688
}
7789

78-
func compileCore(ctx *types.Context, buildPath *paths.Path, buildCachePath *paths.Path, buildProperties *properties.Map) (*paths.Path, paths.PathList, error) {
90+
func compileCore(ctx *types.Context, buildPath *paths.Path, buildCachePath *paths.Path, buildProperties *properties.Map, coreModel *types.CodeModelLibrary) (*paths.Path, paths.PathList, error) {
7991
logger := ctx.GetLogger()
8092
coreFolder := buildProperties.GetPath(constants.BUILD_PROPERTIES_BUILD_CORE_PATH)
8193
variantFolder := buildProperties.GetPath(constants.BUILD_PROPERTIES_BUILD_VARIANT_PATH)
8294

8395
targetCoreFolder := buildProperties.GetPath(constants.BUILD_PROPERTIES_RUNTIME_PLATFORM_PATH)
96+
97+
if coreModel != nil {
98+
coreModel.SourceDirectory = coreFolder
99+
coreModel.Name = buildProperties[constants.LIBRARY_NAME]
100+
}
84101

85102
includes := []string{}
86103
includes = append(includes, coreFolder.String())
@@ -93,7 +110,7 @@ func compileCore(ctx *types.Context, buildPath *paths.Path, buildCachePath *path
93110

94111
variantObjectFiles := paths.NewPathList()
95112
if variantFolder != nil && variantFolder.IsDir() {
96-
variantObjectFiles, err = builder_utils.CompileFiles(ctx, variantFolder, true, buildPath, buildProperties, includes)
113+
variantObjectFiles, err = builder_utils.CompileFiles(ctx, variantFolder, true, buildPath, buildProperties, includes, coreModel)
97114
if err != nil {
98115
return nil, nil, i18n.WrapError(err)
99116
}
@@ -117,18 +134,18 @@ func compileCore(ctx *types.Context, buildPath *paths.Path, buildCachePath *path
117134
}
118135
}
119136

120-
coreObjectFiles, err := builder_utils.CompileFiles(ctx, coreFolder, true, buildPath, buildProperties, includes)
137+
coreObjectFiles, err := builder_utils.CompileFiles(ctx, coreFolder, true, buildPath, buildProperties, includes, coreModel)
121138
if err != nil {
122139
return nil, nil, i18n.WrapError(err)
123140
}
124141

125-
archiveFile, err := builder_utils.ArchiveCompiledFiles(ctx, buildPath, paths.New("core.a"), coreObjectFiles, buildProperties)
142+
archiveFile, err := builder_utils.ArchiveCompiledFiles(ctx, buildPath, paths.New("core.a"), coreObjectFiles, buildProperties, coreModel)
126143
if err != nil {
127144
return nil, nil, i18n.WrapError(err)
128145
}
129146

130147
// archive core.a
131-
if targetArchivedCore != nil {
148+
if targetArchivedCore != nil && coreModel != nil {
132149
err := archiveFile.CopyTo(targetArchivedCore)
133150
if ctx.Verbose {
134151
if err == nil {

0 commit comments

Comments
 (0)