From df435d1dbbf69c3e8fcffe06669f0276c172d7ba Mon Sep 17 00:00:00 2001 From: Sysprogs Date: Mon, 2 Dec 2019 11:53:28 -0800 Subject: [PATCH 1/7] Ported Sysprogs extensions to the arduino-builder tool. --- legacy/builder/builder.go | 55 ++++++++ legacy/builder/builder_utils/utils.go | 152 ++++++++++++++------- legacy/builder/phases/core_builder.go | 31 ++++- legacy/builder/phases/libraries_builder.go | 32 +++-- legacy/builder/phases/linker.go | 8 ++ legacy/builder/phases/sizer.go | 2 +- legacy/builder/phases/sketch_builder.go | 22 ++- legacy/builder/recipe_runner.go | 4 + legacy/builder/types/CodeModelBuilder.go | 49 +++++++ legacy/builder/types/context.go | 6 + 10 files changed, 293 insertions(+), 68 deletions(-) create mode 100644 legacy/builder/types/CodeModelBuilder.go diff --git a/legacy/builder/builder.go b/legacy/builder/builder.go index 98efad782c0..f6fd35d9adc 100644 --- a/legacy/builder/builder.go +++ b/legacy/builder/builder.go @@ -30,6 +30,8 @@ package builder import ( + "encoding/json" + "io/ioutil" "fmt" "os" "reflect" @@ -114,7 +116,60 @@ func (s *Builder) Run(ctx *types.Context) error { } mainErr := runCommands(ctx, commands, true) + + if ctx.CodeModelBuilder != nil { + var librariesByLocation = map[string]*types.Library{} + for header, libraries := range ctx.HeaderToLibraries { + var knownHeader = new(types.KnownHeader) + + knownHeader.Name = header + for _, library := range libraries { + knownHeader.LibraryDirectories = append(knownHeader.LibraryDirectories, library.SrcFolder) + librariesByLocation[library.Folder] = library + } + + ctx.CodeModelBuilder.Prototypes = ctx.Prototypes + ctx.CodeModelBuilder.KnownHeaders = append(ctx.CodeModelBuilder.KnownHeaders, knownHeader) + } + + for _, library := range librariesByLocation { + var knownLib = new(types.KnownLibrary) + + knownLib.Folder = library.Folder + knownLib.SrcFolder = library.SrcFolder + knownLib.UtilityFolder = library.UtilityFolder + knownLib.Layout = library.Layout + knownLib.Name = library.Name + knownLib.RealName = library.RealName + knownLib.IsLegacy = library.IsLegacy + knownLib.Version = library.Version + knownLib.Author = library.Author + knownLib.Maintainer = library.Maintainer + knownLib.Sentence = library.Sentence + knownLib.Paragraph = library.Paragraph + knownLib.URL = library.URL + knownLib.Category = library.Category + knownLib.License = library.License + + ctx.CodeModelBuilder.KnownLibraries = append(ctx.CodeModelBuilder.KnownLibraries, knownLib) + } + + for key, value := range ctx.BuildProperties { + var kv = new(types.KeyValuePair) + kv.Key = key + kv.Value = value + ctx.CodeModelBuilder.BuildProperties = append(ctx.CodeModelBuilder.BuildProperties, *kv) + } + + var bytes, err = json.MarshalIndent(ctx.CodeModelBuilder, "", " ") + if err != nil { + return err + } + ioutil.WriteFile(ctx.CodeModelBuilderFile, bytes, 0644) + return nil + } + commands = []types.Command{ &PrintUsedAndNotUsedLibraries{SketchError: mainErr != nil}, diff --git a/legacy/builder/builder_utils/utils.go b/legacy/builder/builder_utils/utils.go index 86299560597..42c1bcc6297 100644 --- a/legacy/builder/builder_utils/utils.go +++ b/legacy/builder/builder_utils/utils.go @@ -40,6 +40,7 @@ import ( "github.com/arduino/arduino-cli/legacy/builder/constants" "github.com/arduino/arduino-cli/legacy/builder/i18n" + "github.com/arduino/arduino-builder/types" "github.com/arduino/arduino-cli/legacy/builder/types" "github.com/arduino/arduino-cli/legacy/builder/utils" "github.com/arduino/go-paths-helper" @@ -59,8 +60,8 @@ func PrintProgressIfProgressEnabledAndMachineLogger(ctx *types.Context) { } } -func CompileFilesRecursive(ctx *types.Context, sourcePath *paths.Path, buildPath *paths.Path, buildProperties *properties.Map, includes []string) (paths.PathList, error) { - objectFiles, err := CompileFiles(ctx, sourcePath, false, buildPath, buildProperties, includes) +func CompileFilesRecursive(ctx *types.Context, sourcePath *paths.Path, buildPath *paths.Path, buildProperties *properties.Map, includes []string, libraryModel *types.CodeModelLibrary) (paths.PathList, error) { + objectFiles, err := CompileFiles(ctx, sourcePath, false, buildPath, buildProperties, includes, libraryModel) if err != nil { return nil, i18n.WrapError(err) } @@ -71,7 +72,7 @@ func CompileFilesRecursive(ctx *types.Context, sourcePath *paths.Path, buildPath } for _, folder := range folders { - subFolderObjectFiles, err := CompileFilesRecursive(ctx, sourcePath.Join(folder.Name()), buildPath.Join(folder.Name()), buildProperties, includes) + subFolderObjectFiles, err := CompileFilesRecursive(ctx, sourcePath.Join(folder.Name()), buildPath.Join(folder.Name()), buildProperties, includes, libraryModel) if err != nil { return nil, i18n.WrapError(err) } @@ -81,16 +82,16 @@ func CompileFilesRecursive(ctx *types.Context, sourcePath *paths.Path, buildPath return objectFiles, nil } -func CompileFiles(ctx *types.Context, sourcePath *paths.Path, recurse bool, buildPath *paths.Path, buildProperties *properties.Map, includes []string) (paths.PathList, error) { - sObjectFiles, err := compileFilesWithExtensionWithRecipe(ctx, sourcePath, recurse, buildPath, buildProperties, includes, ".S", constants.RECIPE_S_PATTERN) +func CompileFiles(ctx *types.Context, sourcePath *paths.Path, recurse bool, buildPath *paths.Path, buildProperties *properties.Map, includes []string, libraryModel *types.CodeModelLibrary) (paths.PathList, error) { + sObjectFiles, err := compileFilesWithExtensionWithRecipe(ctx, sourcePath, recurse, buildPath, buildProperties, includes, ".S", constants.RECIPE_S_PATTERN, libraryModel) if err != nil { return nil, i18n.WrapError(err) } - cObjectFiles, err := compileFilesWithExtensionWithRecipe(ctx, sourcePath, recurse, buildPath, buildProperties, includes, ".c", constants.RECIPE_C_PATTERN) + cObjectFiles, err := compileFilesWithExtensionWithRecipe(ctx, sourcePath, recurse, buildPath, buildProperties, includes, ".c", constants.RECIPE_C_PATTERN, libraryModel) if err != nil { return nil, i18n.WrapError(err) } - cppObjectFiles, err := compileFilesWithExtensionWithRecipe(ctx, sourcePath, recurse, buildPath, buildProperties, includes, ".cpp", constants.RECIPE_CPP_PATTERN) + cppObjectFiles, err := compileFilesWithExtensionWithRecipe(ctx, sourcePath, recurse, buildPath, buildProperties, includes, ".cpp", constants.RECIPE_CPP_PATTERN, libraryModel) if err != nil { return nil, i18n.WrapError(err) } @@ -101,12 +102,47 @@ func CompileFiles(ctx *types.Context, sourcePath *paths.Path, recurse bool, buil return objectFiles, nil } -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) { +func ReplaceOptimizationFlags(str string) string { + var tmp = strings.Split(str, " ") + for k, v := range tmp { + if v == "-O2" || v == "-Os" || v == "-O1" || v == "-Og" || v == "-O3" { + tmp[k] = "-O0" + } else if v == "-flto" { + tmp[k] = "" + } + } + + return strings.Join(tmp, " ") +} + +func RemoveOptimizationFromBuildProperties(properties properties.Map) properties.Map { + var result = make(map[string]string) + for k, v := range properties { + result[k] = v + } + + result["compiler.c.flags"] = ReplaceOptimizationFlags(result["compiler.c.flags"]) + result["compiler.cpp.flags"] = ReplaceOptimizationFlags(result["compiler.cpp.flags"]) + return result +} + +func ExpandSysprogsExtensionProperties(properties properties.Map) properties.Map { + var result = make(map[string]string) + for k, v := range properties { + result[k] = v + } + + result["compiler.c.flags"] += " " + result["com.sysprogs.extraflags"] + result["compiler.cpp.flags"] += " " + result["com.sysprogs.extraflags"] + return result +} + +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) { sources, err := findFilesInFolder(sourcePath, extension, recurse) if err != nil { return nil, i18n.WrapError(err) } - return compileFilesWithRecipe(ctx, sourcePath, sources, buildPath, buildProperties, includes, recipe) + return compileFilesWithRecipe(ctx, sourcePath, sources, buildPath, buildProperties, includes, recipe, libraryModel) } func findFilesInFolder(sourcePath *paths.Path, extension string, recurse bool) (paths.PathList, error) { @@ -168,7 +204,7 @@ func findAllFilesInFolder(sourcePath string, recurse bool) ([]string, error) { return sources, nil } -func compileFilesWithRecipe(ctx *types.Context, sourcePath *paths.Path, sources paths.PathList, buildPath *paths.Path, buildProperties *properties.Map, includes []string, recipe string) (paths.PathList, error) { +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) { objectFiles := paths.NewPathList() if len(sources) == 0 { return objectFiles, nil @@ -182,7 +218,7 @@ func compileFilesWithRecipe(ctx *types.Context, sourcePath *paths.Path, sources queue := make(chan *paths.Path) job := func(source *paths.Path) { PrintProgressIfProgressEnabledAndMachineLogger(ctx) - objectFile, err := compileFileWithRecipe(ctx, sourcePath, source, buildPath, buildProperties, includes, recipe) + objectFile, err := compileFileWithRecipe(ctx, sourcePath, source, buildPath, buildProperties, includes, recipe, libraryModel) if err != nil { errorsMux.Lock() errors = append(errors, err) @@ -230,7 +266,7 @@ func compileFilesWithRecipe(ctx *types.Context, sourcePath *paths.Path, sources return objectFiles, nil } -func compileFileWithRecipe(ctx *types.Context, sourcePath *paths.Path, source *paths.Path, buildPath *paths.Path, buildProperties *properties.Map, includes []string, recipe string) (*paths.Path, error) { +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) { logger := ctx.GetLogger() properties := buildProperties.Clone() 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 return nil, i18n.WrapError(err) } - objIsUpToDate, err := ObjFileIsUpToDate(ctx, source, objectFile, depsFile) - if err != nil { - return nil, i18n.WrapError(err) - } - if !objIsUpToDate { - _, _, err = ExecRecipe(ctx, properties, recipe, false /* stdout */, utils.ShowIfVerbose /* stderr */, utils.Show) + if libraryModel != nil { + //We are not actually building, just dumping the model + command, err := PrepareCommandForRecipe(properties, recipe, false, false, false, logger) + if err != nil { + return "", i18n.WrapError(err) + } + + var invocation = new(types.CodeModelGCCInvocation) + invocation.GCC = command.Path + invocation.InputFile = source + invocation.ObjectFile = properties[constants.BUILD_PROPERTIES_OBJECT_FILE] + invocation.Arguments = command.Args[1:] + libraryModel.Invocations = append(libraryModel.Invocations, invocation) + } else { + objIsUpToDate, err := ObjFileIsUpToDate(ctx, source, objectFile, depsFile) if err != nil { return nil, i18n.WrapError(err) } - } else if ctx.Verbose { - logger.Println(constants.LOG_LEVEL_INFO, constants.MSG_USING_PREVIOUS_COMPILED_FILE, objectFile) + if !objIsUpToDate { + _, _, err = ExecRecipe(ctx, properties, recipe, false /* stdout */, utils.ShowIfVerbose /* stderr */, utils.Show) + if err != nil { + return nil, i18n.WrapError(err) + } + } else if ctx.Verbose { + logger.Println(constants.LOG_LEVEL_INFO, constants.MSG_USING_PREVIOUS_COMPILED_FILE, objectFile) + } } return objectFile, nil @@ -449,46 +500,49 @@ func TXTBuildRulesHaveChanged(corePath, targetCorePath, targetFile *paths.Path) return true } -func ArchiveCompiledFiles(ctx *types.Context, buildPath *paths.Path, archiveFile *paths.Path, objectFilesToArchive paths.PathList, buildProperties *properties.Map) (*paths.Path, error) { +func ArchiveCompiledFiles(ctx *types.Context, buildPath *paths.Path, archiveFile *paths.Path, objectFilesToArchive paths.PathList, buildProperties *properties.Map, libraryModel *types.CodeModelLibrary) (*paths.Path, error) { logger := ctx.GetLogger() archiveFilePath := buildPath.JoinPath(archiveFile) rebuildArchive := false + if libraryModel != nil { + libraryModel.ArchiveFile = archiveFilePath + } else { + if archiveFileStat, err := archiveFilePath.Stat(); err == nil { + + for _, objectFile := range objectFilesToArchive { + objectFileStat, err := objectFile.Stat() + if err != nil || objectFileStat.ModTime().After(archiveFileStat.ModTime()) { + // need to rebuild the archive + rebuildArchive = true + break + } + } - if archiveFileStat, err := archiveFilePath.Stat(); err == nil { - - 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 { + err = archiveFilePath.Remove() + if err != nil { + return nil, i18n.WrapError(err) + } + } else { + if ctx.Verbose { + logger.Println(constants.LOG_LEVEL_INFO, constants.MSG_USING_PREVIOUS_COMPILED_FILE, archiveFilePath) + } + return archiveFilePath, nil } } - // something changed, rebuild the core archive - if rebuildArchive { - err = archiveFilePath.Remove() + for _, objectFile := range objectFilesToArchive { + properties := buildProperties.Clone() + properties.Set(constants.BUILD_PROPERTIES_ARCHIVE_FILE, archiveFilePath.Base()) + properties.SetPath(constants.BUILD_PROPERTIES_ARCHIVE_FILE_PATH, archiveFilePath) + properties.SetPath(constants.BUILD_PROPERTIES_OBJECT_FILE, objectFile) + + _, _, err := ExecRecipe(ctx, properties, constants.RECIPE_AR_PATTERN, false /* stdout */, utils.ShowIfVerbose /* stderr */, utils.Show) if err != nil { return nil, i18n.WrapError(err) } - } else { - if ctx.Verbose { - logger.Println(constants.LOG_LEVEL_INFO, constants.MSG_USING_PREVIOUS_COMPILED_FILE, archiveFilePath) - } - return archiveFilePath, nil - } - } - - for _, objectFile := range objectFilesToArchive { - properties := buildProperties.Clone() - properties.Set(constants.BUILD_PROPERTIES_ARCHIVE_FILE, archiveFilePath.Base()) - properties.SetPath(constants.BUILD_PROPERTIES_ARCHIVE_FILE_PATH, archiveFilePath) - properties.SetPath(constants.BUILD_PROPERTIES_OBJECT_FILE, objectFile) - - _, _, err := ExecRecipe(ctx, properties, constants.RECIPE_AR_PATTERN, false /* stdout */, utils.ShowIfVerbose /* stderr */, utils.Show) - if err != nil { - return nil, i18n.WrapError(err) } } diff --git a/legacy/builder/phases/core_builder.go b/legacy/builder/phases/core_builder.go index dc6540f16ad..b6b8ba3e0cc 100644 --- a/legacy/builder/phases/core_builder.go +++ b/legacy/builder/phases/core_builder.go @@ -46,7 +46,7 @@ type CoreBuilder struct{} func (s *CoreBuilder) Run(ctx *types.Context) error { coreBuildPath := ctx.CoreBuildPath coreBuildCachePath := ctx.CoreBuildCachePath - buildProperties := ctx.BuildProperties + var buildProperties = ctx.BuildProperties if err := coreBuildPath.MkdirAll(); err != nil { return i18n.WrapError(err) @@ -64,7 +64,19 @@ func (s *CoreBuilder) Run(ctx *types.Context) error { } } - archiveFile, objectFiles, err := compileCore(ctx, coreBuildPath, coreBuildCachePath, buildProperties) + var coreModel *types.CodeModelLibrary + if ctx.CodeModelBuilder != nil { + coreModel = new(types.CodeModelLibrary) + ctx.CodeModelBuilder.Core = coreModel + } + + if ctx.UnoptimizeCore { + buildProperties = builder_utils.RemoveOptimizationFromBuildProperties(buildProperties) + } + + buildProperties = builder_utils.ExpandSysprogsExtensionProperties(buildProperties) + + archiveFile, objectFiles, err := compileCore(ctx, coreBuildPath, coreBuildCachePath, buildProperties, coreModel) if err != nil { return i18n.WrapError(err) } @@ -75,12 +87,17 @@ func (s *CoreBuilder) Run(ctx *types.Context) error { return nil } -func compileCore(ctx *types.Context, buildPath *paths.Path, buildCachePath *paths.Path, buildProperties *properties.Map) (*paths.Path, paths.PathList, error) { +func compileCore(ctx *types.Context, buildPath *paths.Path, buildCachePath *paths.Path, buildProperties *properties.Map, coreModel *types.CodeModelLibrary) (*paths.Path, paths.PathList, error) { logger := ctx.GetLogger() coreFolder := buildProperties.GetPath(constants.BUILD_PROPERTIES_BUILD_CORE_PATH) variantFolder := buildProperties.GetPath(constants.BUILD_PROPERTIES_BUILD_VARIANT_PATH) targetCoreFolder := buildProperties.GetPath(constants.BUILD_PROPERTIES_RUNTIME_PLATFORM_PATH) + + if coreModel != nil { + coreModel.SourceDirectory = coreFolder + coreModel.Name = buildProperties[constants.LIBRARY_NAME] + } includes := []string{} includes = append(includes, coreFolder.String()) @@ -93,7 +110,7 @@ func compileCore(ctx *types.Context, buildPath *paths.Path, buildCachePath *path variantObjectFiles := paths.NewPathList() if variantFolder != nil && variantFolder.IsDir() { - variantObjectFiles, err = builder_utils.CompileFiles(ctx, variantFolder, true, buildPath, buildProperties, includes) + variantObjectFiles, err = builder_utils.CompileFiles(ctx, variantFolder, true, buildPath, buildProperties, includes, coreModel) if err != nil { return nil, nil, i18n.WrapError(err) } @@ -117,18 +134,18 @@ func compileCore(ctx *types.Context, buildPath *paths.Path, buildCachePath *path } } - coreObjectFiles, err := builder_utils.CompileFiles(ctx, coreFolder, true, buildPath, buildProperties, includes) + coreObjectFiles, err := builder_utils.CompileFiles(ctx, coreFolder, true, buildPath, buildProperties, includes, coreModel) if err != nil { return nil, nil, i18n.WrapError(err) } - archiveFile, err := builder_utils.ArchiveCompiledFiles(ctx, buildPath, paths.New("core.a"), coreObjectFiles, buildProperties) + archiveFile, err := builder_utils.ArchiveCompiledFiles(ctx, buildPath, paths.New("core.a"), coreObjectFiles, buildProperties, coreModel) if err != nil { return nil, nil, i18n.WrapError(err) } // archive core.a - if targetArchivedCore != nil { + if targetArchivedCore != nil && coreModel != nil { err := archiveFile.CopyTo(targetArchivedCore) if ctx.Verbose { if err == nil { diff --git a/legacy/builder/phases/libraries_builder.go b/legacy/builder/phases/libraries_builder.go index 9c0776c5ebc..1f1e6556be4 100644 --- a/legacy/builder/phases/libraries_builder.go +++ b/legacy/builder/phases/libraries_builder.go @@ -58,7 +58,7 @@ func (s *LibrariesBuilder) Run(ctx *types.Context) error { return i18n.WrapError(err) } - objectFiles, err := compileLibraries(ctx, libs, librariesBuildPath, buildProperties, includes) + objectFiles, err := compileLibraries(ctx, libs, librariesBuildPath, buildProperties, includes, ctx.CodeModelBuilder, ctx.UnoptimizeLibraries) if err != nil { return i18n.WrapError(err) } @@ -98,10 +98,26 @@ func fixLDFLAGforPrecompiledLibraries(ctx *types.Context, libs libraries.List) e return nil } -func compileLibraries(ctx *types.Context, libraries libraries.List, buildPath *paths.Path, buildProperties *properties.Map, includes []string) (paths.PathList, error) { +func compileLibraries(ctx *types.Context, libraries libraries.List, buildPath *paths.Path, buildProperties *properties.Map, includes []string, codeModel *types.CodeModelBuilder, unoptimize bool) (paths.PathList, error) { + var unoptimizedProperties = builder_utils.RemoveOptimizationFromBuildProperties(buildProperties) objectFiles := paths.NewPathList() for _, library := range libraries { - libraryObjectFiles, err := compileLibrary(ctx, library, buildPath, buildProperties, includes) + var libraryModel *types.CodeModelLibrary + if codeModel != nil { + libraryModel = new(types.CodeModelLibrary) + libraryModel.Name = library.Name + libraryModel.SourceDirectory = library.SrcFolder + codeModel.Libraries = append(codeModel.Libraries, libraryModel) + } + + var effectiveProperties = buildProperties + if unoptimize && library.Properties["supports_unoptimized_builds"] != "false" { + effectiveProperties = unoptimizedProperties + } + + effectiveProperties = builder_utils.ExpandSysprogsExtensionProperties(effectiveProperties) + + libraryObjectFiles, err := compileLibrary(ctx, library, buildPath, effectiveProperties, includes, libraryModel) if err != nil { return nil, i18n.WrapError(err) } @@ -111,7 +127,7 @@ func compileLibraries(ctx *types.Context, libraries libraries.List, buildPath *p return objectFiles, nil } -func compileLibrary(ctx *types.Context, library *libraries.Library, buildPath *paths.Path, buildProperties *properties.Map, includes []string) (paths.PathList, error) { +func compileLibrary(ctx *types.Context, library *libraries.Library, buildPath *paths.Path, buildProperties *properties.Map, includes []string, libraryModel *types.CodeModelLibrary) (paths.PathList, error) { logger := ctx.GetLogger() if ctx.Verbose { logger.Println(constants.LOG_LEVEL_INFO, "Compiling library \"{0}\"", library.Name) @@ -142,12 +158,12 @@ func compileLibrary(ctx *types.Context, library *libraries.Library, buildPath *p } if library.Layout == libraries.RecursiveLayout { - libObjectFiles, err := builder_utils.CompileFilesRecursive(ctx, library.SourceDir, libraryBuildPath, buildProperties, includes) + libObjectFiles, err := builder_utils.CompileFilesRecursive(ctx, library.SourceDir, libraryBuildPath, buildProperties, includes, libraryModel) if err != nil { return nil, i18n.WrapError(err) } if library.DotALinkage { - archiveFile, err := builder_utils.ArchiveCompiledFiles(ctx, libraryBuildPath, paths.New(library.Name+".a"), libObjectFiles, buildProperties) + archiveFile, err := builder_utils.ArchiveCompiledFiles(ctx, libraryBuildPath, paths.New(library.Name+".a"), libObjectFiles, buildProperties, libraryModel) if err != nil { return nil, i18n.WrapError(err) } @@ -159,7 +175,7 @@ func compileLibrary(ctx *types.Context, library *libraries.Library, buildPath *p if library.UtilityDir != nil { includes = append(includes, utils.WrapWithHyphenI(library.UtilityDir.String())) } - libObjectFiles, err := builder_utils.CompileFiles(ctx, library.SourceDir, false, libraryBuildPath, buildProperties, includes) + libObjectFiles, err := builder_utils.CompileFiles(ctx, library.SourceDir, false, libraryBuildPath, buildProperties, includes, libraryModel) if err != nil { return nil, i18n.WrapError(err) } @@ -167,7 +183,7 @@ func compileLibrary(ctx *types.Context, library *libraries.Library, buildPath *p if library.UtilityDir != nil { utilityBuildPath := libraryBuildPath.Join("utility") - utilityObjectFiles, err := builder_utils.CompileFiles(ctx, library.UtilityDir, false, utilityBuildPath, buildProperties, includes) + utilityObjectFiles, err := builder_utils.CompileFiles(ctx, library.UtilityDir, false, utilityBuildPath, buildProperties, includes, libraryModel) if err != nil { return nil, i18n.WrapError(err) } diff --git a/legacy/builder/phases/linker.go b/legacy/builder/phases/linker.go index fc64c27d370..4b78c3b90cd 100644 --- a/legacy/builder/phases/linker.go +++ b/legacy/builder/phases/linker.go @@ -61,6 +61,14 @@ func (s *Linker) Run(ctx *types.Context) error { } buildProperties := ctx.BuildProperties + + if ctx.CodeModelBuilder != nil { + //Just compute the linker command line (even without the full object list), we are not actually linking and are only interested in the output file name + pattern := buildProperties[constants.RECIPE_C_COMBINE_PATTERN] + commandLine := buildProperties.ExpandPropsInString(pattern) + ctx.CodeModelBuilder.LinkerCommandLine = commandLine + return nil + } err = link(ctx, objectFiles, coreDotARelPath, coreArchiveFilePath, buildProperties) if err != nil { diff --git a/legacy/builder/phases/sizer.go b/legacy/builder/phases/sizer.go index 271d8d147c9..8fbd260f33a 100644 --- a/legacy/builder/phases/sizer.go +++ b/legacy/builder/phases/sizer.go @@ -48,7 +48,7 @@ type Sizer struct { func (s *Sizer) Run(ctx *types.Context) error { - if s.SketchError { + if s.SketchError || ctx.CodeModelBuilder != nil { return nil } diff --git a/legacy/builder/phases/sketch_builder.go b/legacy/builder/phases/sketch_builder.go index 929d4c36e59..004ce28c13f 100644 --- a/legacy/builder/phases/sketch_builder.go +++ b/legacy/builder/phases/sketch_builder.go @@ -30,6 +30,8 @@ package phases import ( + "os" + "path/filepath" "github.com/arduino/arduino-cli/legacy/builder/builder_utils" "github.com/arduino/arduino-cli/legacy/builder/constants" "github.com/arduino/arduino-cli/legacy/builder/i18n" @@ -41,14 +43,28 @@ type SketchBuilder struct{} func (s *SketchBuilder) Run(ctx *types.Context) error { sketchBuildPath := ctx.SketchBuildPath - buildProperties := ctx.BuildProperties + var buildProperties = ctx.BuildProperties includes := utils.Map(ctx.IncludeFolders.AsStrings(), utils.WrapWithHyphenI) if err := sketchBuildPath.MkdirAll(); err != nil { return i18n.WrapError(err) } + + var sketchModel *types.CodeModelLibrary + if ctx.CodeModelBuilder != nil { + sketchModel = new(types.CodeModelLibrary) + ctx.CodeModelBuilder.Sketch = sketchModel + } else { + sketchModel = nil + } + + if ctx.UnoptimizeSketch { + buildProperties = builder_utils.RemoveOptimizationFromBuildProperties(buildProperties) + } + + buildProperties = builder_utils.ExpandSysprogsExtensionProperties(buildProperties) - objectFiles, err := builder_utils.CompileFiles(ctx, sketchBuildPath, false, sketchBuildPath, buildProperties, includes) + objectFiles, err := builder_utils.CompileFiles(ctx, sketchBuildPath, false, sketchBuildPath, buildProperties, includes, sketchModel) if err != nil { return i18n.WrapError(err) } @@ -56,7 +72,7 @@ func (s *SketchBuilder) Run(ctx *types.Context) error { // The "src/" subdirectory of a sketch is compiled recursively sketchSrcPath := sketchBuildPath.Join(constants.SKETCH_FOLDER_SRC) if sketchSrcPath.IsDir() { - srcObjectFiles, err := builder_utils.CompileFiles(ctx, sketchSrcPath, true, sketchSrcPath, buildProperties, includes) + srcObjectFiles, err := builder_utils.CompileFiles(ctx, sketchSrcPath, true, sketchSrcPath, buildProperties, includes, sketchModel) if err != nil { return i18n.WrapError(err) } diff --git a/legacy/builder/recipe_runner.go b/legacy/builder/recipe_runner.go index b236d6b1f7d..a63c0eb6e3b 100644 --- a/legacy/builder/recipe_runner.go +++ b/legacy/builder/recipe_runner.go @@ -55,6 +55,10 @@ func (s *RecipeByPrefixSuffixRunner) Run(ctx *types.Context) error { buildProperties := ctx.BuildProperties.Clone() recipes := findRecipes(buildProperties, s.Prefix, s.Suffix) + + if ctx.CodeModelBuilder != nil { + return nil + } properties := buildProperties.Clone() for _, recipe := range recipes { diff --git a/legacy/builder/types/CodeModelBuilder.go b/legacy/builder/types/CodeModelBuilder.go new file mode 100644 index 00000000000..aa56f8a5749 --- /dev/null +++ b/legacy/builder/types/CodeModelBuilder.go @@ -0,0 +1,49 @@ +package types + +type CodeModelGCCInvocation struct { + GCC string + InputFile string + ObjectFile string + Arguments []string +} + +type CodeModelLibrary struct { + Name string + SourceDirectory string + ArchiveFile string + Invocations []*CodeModelGCCInvocation +} + +type KnownLibrary struct { + Folder string + SrcFolder string + UtilityFolder string + Layout LibraryLayout + Name string + RealName string + IsLegacy bool + Version string + Author string + Maintainer string + Sentence string + Paragraph string + URL string + Category string + License string +} + +type KnownHeader struct { + Name string + LibraryDirectories []string +} + +type CodeModelBuilder struct { + Core *CodeModelLibrary + Sketch *CodeModelLibrary + Libraries []*CodeModelLibrary + KnownHeaders []*KnownHeader + Prototypes []*Prototype + KnownLibraries []*KnownLibrary + LinkerCommandLine string + BuildProperties []KeyValuePair +} diff --git a/legacy/builder/types/context.go b/legacy/builder/types/context.go index 8238ed98c3f..7baca415990 100644 --- a/legacy/builder/types/context.go +++ b/legacy/builder/types/context.go @@ -89,6 +89,12 @@ type Context struct { PrototypesSection string PrototypesLineWhereToInsert int Prototypes []*Prototype + + CodeModelBuilder *CodeModelBuilder + CodeModelBuilderFile string + UnoptimizeSketch bool + UnoptimizeCore bool + UnoptimizeLibraries bool // Verbosity settings Verbose bool From 6b7902c08c65524d37f92e5997dc56d89bc189c5 Mon Sep 17 00:00:00 2001 From: Sysprogs Date: Mon, 2 Dec 2019 14:02:37 -0800 Subject: [PATCH 2/7] Ported Sysprogs extensions to arduino-builder 1.5.0 --- arduino/libraries/librariesresolver/cpp.go | 5 ++++ legacy/builder/builder.go | 21 +++++++------- legacy/builder/builder_utils/utils.go | 33 +++++++++------------- legacy/builder/phases/core_builder.go | 4 +-- legacy/builder/phases/libraries_builder.go | 4 +-- legacy/builder/phases/linker.go | 2 +- legacy/builder/phases/sketch_builder.go | 2 -- legacy/builder/types/CodeModelBuilder.go | 11 +++++++- 8 files changed, 44 insertions(+), 38 deletions(-) diff --git a/arduino/libraries/librariesresolver/cpp.go b/arduino/libraries/librariesresolver/cpp.go index 6870959fb04..79ce25b9c97 100644 --- a/arduino/libraries/librariesresolver/cpp.go +++ b/arduino/libraries/librariesresolver/cpp.go @@ -73,6 +73,11 @@ func (resolver *Cpp) AlternativesFor(header string) libraries.List { return resolver.headers[header] } +func (resolver *Cpp) ExportMap() map[string]libraries.List { + return resolver.headers; +} + + // ResolveFor finds the most suitable library for the specified combination of // header and architecture. If no libraries provides the requested header, nil is returned func (resolver *Cpp) ResolveFor(header, architecture string) *libraries.Library { diff --git a/legacy/builder/builder.go b/legacy/builder/builder.go index f6fd35d9adc..dcf890f7aaa 100644 --- a/legacy/builder/builder.go +++ b/legacy/builder/builder.go @@ -45,6 +45,7 @@ import ( "github.com/arduino/arduino-cli/legacy/builder/phases" "github.com/arduino/arduino-cli/legacy/builder/types" "github.com/arduino/arduino-cli/legacy/builder/utils" + "github.com/arduino/arduino-cli/arduino/libraries" ) var MAIN_FILE_VALID_EXTENSIONS = map[string]bool{".ino": true, ".pde": true} @@ -118,15 +119,15 @@ func (s *Builder) Run(ctx *types.Context) error { mainErr := runCommands(ctx, commands, true) if ctx.CodeModelBuilder != nil { - var librariesByLocation = map[string]*types.Library{} + var librariesByLocation = map[string]*libraries.Library{} - for header, libraries := range ctx.HeaderToLibraries { + for header, libraries := range ctx.LibrariesResolver.ExportMap() { var knownHeader = new(types.KnownHeader) knownHeader.Name = header for _, library := range libraries { - knownHeader.LibraryDirectories = append(knownHeader.LibraryDirectories, library.SrcFolder) - librariesByLocation[library.Folder] = library + knownHeader.LibraryDirectories = append(knownHeader.LibraryDirectories, library.SourceDir.String()) + librariesByLocation[library.InstallDir.String()] = library } ctx.CodeModelBuilder.Prototypes = ctx.Prototypes @@ -136,26 +137,26 @@ func (s *Builder) Run(ctx *types.Context) error { for _, library := range librariesByLocation { var knownLib = new(types.KnownLibrary) - knownLib.Folder = library.Folder - knownLib.SrcFolder = library.SrcFolder - knownLib.UtilityFolder = library.UtilityFolder + knownLib.Folder = library.InstallDir.String() + knownLib.SrcFolder = library.SourceDir.String() + knownLib.UtilityFolder = library.UtilityDir.String() knownLib.Layout = library.Layout knownLib.Name = library.Name knownLib.RealName = library.RealName knownLib.IsLegacy = library.IsLegacy - knownLib.Version = library.Version + knownLib.Version = library.Version.String() knownLib.Author = library.Author knownLib.Maintainer = library.Maintainer knownLib.Sentence = library.Sentence knownLib.Paragraph = library.Paragraph - knownLib.URL = library.URL + knownLib.URL = library.Website knownLib.Category = library.Category knownLib.License = library.License ctx.CodeModelBuilder.KnownLibraries = append(ctx.CodeModelBuilder.KnownLibraries, knownLib) } - for key, value := range ctx.BuildProperties { + for key, value := range ctx.BuildProperties.AsMap() { var kv = new(types.KeyValuePair) kv.Key = key kv.Value = value diff --git a/legacy/builder/builder_utils/utils.go b/legacy/builder/builder_utils/utils.go index 42c1bcc6297..0d737d8db30 100644 --- a/legacy/builder/builder_utils/utils.go +++ b/legacy/builder/builder_utils/utils.go @@ -40,7 +40,6 @@ import ( "github.com/arduino/arduino-cli/legacy/builder/constants" "github.com/arduino/arduino-cli/legacy/builder/i18n" - "github.com/arduino/arduino-builder/types" "github.com/arduino/arduino-cli/legacy/builder/types" "github.com/arduino/arduino-cli/legacy/builder/utils" "github.com/arduino/go-paths-helper" @@ -115,25 +114,19 @@ func ReplaceOptimizationFlags(str string) string { return strings.Join(tmp, " ") } -func RemoveOptimizationFromBuildProperties(properties properties.Map) properties.Map { - var result = make(map[string]string) - for k, v := range properties { - result[k] = v - } +func RemoveOptimizationFromBuildProperties(properties *properties.Map) *properties.Map { + var result = properties.Clone() - result["compiler.c.flags"] = ReplaceOptimizationFlags(result["compiler.c.flags"]) - result["compiler.cpp.flags"] = ReplaceOptimizationFlags(result["compiler.cpp.flags"]) + result.Set("compiler.c.flags", ReplaceOptimizationFlags(result.Get("compiler.c.flags"))) + result.Set("compiler.cpp.flags", ReplaceOptimizationFlags(result.Get("compiler.cpp.flags"))) return result } -func ExpandSysprogsExtensionProperties(properties properties.Map) properties.Map { - var result = make(map[string]string) - for k, v := range properties { - result[k] = v - } +func ExpandSysprogsExtensionProperties(properties *properties.Map) *properties.Map { + var result = properties.Clone() - result["compiler.c.flags"] += " " + result["com.sysprogs.extraflags"] - result["compiler.cpp.flags"] += " " + result["com.sysprogs.extraflags"] + result.Set("compiler.c.flags", result.Get("compiler.c.flags") + " " + result.Get("com.sysprogs.extraflags")) + result.Set("compiler.cpp.flags", result.Get("compiler.cpp.flags") + " " + result.Get("com.sysprogs.extraflags")) return result } @@ -287,15 +280,15 @@ func compileFileWithRecipe(ctx *types.Context, sourcePath *paths.Path, source *p if libraryModel != nil { //We are not actually building, just dumping the model - command, err := PrepareCommandForRecipe(properties, recipe, false, false, false, logger) + command, err := PrepareCommandForRecipe(ctx, properties, recipe, false) if err != nil { - return "", i18n.WrapError(err) + return nil, i18n.WrapError(err) } var invocation = new(types.CodeModelGCCInvocation) invocation.GCC = command.Path - invocation.InputFile = source - invocation.ObjectFile = properties[constants.BUILD_PROPERTIES_OBJECT_FILE] + invocation.InputFile = source.String() + invocation.ObjectFile = properties.Get(constants.BUILD_PROPERTIES_OBJECT_FILE) invocation.Arguments = command.Args[1:] libraryModel.Invocations = append(libraryModel.Invocations, invocation) } else { @@ -506,7 +499,7 @@ func ArchiveCompiledFiles(ctx *types.Context, buildPath *paths.Path, archiveFile rebuildArchive := false if libraryModel != nil { - libraryModel.ArchiveFile = archiveFilePath + libraryModel.ArchiveFile = archiveFilePath.String() } else { if archiveFileStat, err := archiveFilePath.Stat(); err == nil { diff --git a/legacy/builder/phases/core_builder.go b/legacy/builder/phases/core_builder.go index b6b8ba3e0cc..4c9e982d394 100644 --- a/legacy/builder/phases/core_builder.go +++ b/legacy/builder/phases/core_builder.go @@ -95,8 +95,8 @@ func compileCore(ctx *types.Context, buildPath *paths.Path, buildCachePath *path targetCoreFolder := buildProperties.GetPath(constants.BUILD_PROPERTIES_RUNTIME_PLATFORM_PATH) if coreModel != nil { - coreModel.SourceDirectory = coreFolder - coreModel.Name = buildProperties[constants.LIBRARY_NAME] + coreModel.SourceDirectory = coreFolder.String() + coreModel.Name = buildProperties.Get("name") } includes := []string{} diff --git a/legacy/builder/phases/libraries_builder.go b/legacy/builder/phases/libraries_builder.go index 1f1e6556be4..9851eef372f 100644 --- a/legacy/builder/phases/libraries_builder.go +++ b/legacy/builder/phases/libraries_builder.go @@ -106,12 +106,12 @@ func compileLibraries(ctx *types.Context, libraries libraries.List, buildPath *p if codeModel != nil { libraryModel = new(types.CodeModelLibrary) libraryModel.Name = library.Name - libraryModel.SourceDirectory = library.SrcFolder + libraryModel.SourceDirectory = library.SourceDir.String() codeModel.Libraries = append(codeModel.Libraries, libraryModel) } var effectiveProperties = buildProperties - if unoptimize && library.Properties["supports_unoptimized_builds"] != "false" { + if unoptimize && library.Properties.Get("supports_unoptimized_builds") != "false" { effectiveProperties = unoptimizedProperties } diff --git a/legacy/builder/phases/linker.go b/legacy/builder/phases/linker.go index 4b78c3b90cd..4d1e8581e70 100644 --- a/legacy/builder/phases/linker.go +++ b/legacy/builder/phases/linker.go @@ -64,7 +64,7 @@ func (s *Linker) Run(ctx *types.Context) error { if ctx.CodeModelBuilder != nil { //Just compute the linker command line (even without the full object list), we are not actually linking and are only interested in the output file name - pattern := buildProperties[constants.RECIPE_C_COMBINE_PATTERN] + pattern := buildProperties.Get(constants.RECIPE_C_COMBINE_PATTERN) commandLine := buildProperties.ExpandPropsInString(pattern) ctx.CodeModelBuilder.LinkerCommandLine = commandLine return nil diff --git a/legacy/builder/phases/sketch_builder.go b/legacy/builder/phases/sketch_builder.go index 004ce28c13f..30004404dc6 100644 --- a/legacy/builder/phases/sketch_builder.go +++ b/legacy/builder/phases/sketch_builder.go @@ -30,8 +30,6 @@ package phases import ( - "os" - "path/filepath" "github.com/arduino/arduino-cli/legacy/builder/builder_utils" "github.com/arduino/arduino-cli/legacy/builder/constants" "github.com/arduino/arduino-cli/legacy/builder/i18n" diff --git a/legacy/builder/types/CodeModelBuilder.go b/legacy/builder/types/CodeModelBuilder.go index aa56f8a5749..bca854d78af 100644 --- a/legacy/builder/types/CodeModelBuilder.go +++ b/legacy/builder/types/CodeModelBuilder.go @@ -1,5 +1,9 @@ package types +import ( + "github.com/arduino/arduino-cli/arduino/libraries" +) + type CodeModelGCCInvocation struct { GCC string InputFile string @@ -18,7 +22,7 @@ type KnownLibrary struct { Folder string SrcFolder string UtilityFolder string - Layout LibraryLayout + Layout libraries.LibraryLayout Name string RealName string IsLegacy bool @@ -37,6 +41,11 @@ type KnownHeader struct { LibraryDirectories []string } +type KeyValuePair struct { + Key string + Value string +} + type CodeModelBuilder struct { Core *CodeModelLibrary Sketch *CodeModelLibrary From 0bd772f213631ee4833026366a2e78213fbb2564 Mon Sep 17 00:00:00 2001 From: Sysprogs Date: Mon, 2 Dec 2019 15:00:20 -0800 Subject: [PATCH 3/7] Added nil checks --- legacy/builder/builder.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/legacy/builder/builder.go b/legacy/builder/builder.go index dcf890f7aaa..c7fb61c339c 100644 --- a/legacy/builder/builder.go +++ b/legacy/builder/builder.go @@ -137,14 +137,26 @@ func (s *Builder) Run(ctx *types.Context) error { for _, library := range librariesByLocation { var knownLib = new(types.KnownLibrary) - knownLib.Folder = library.InstallDir.String() - knownLib.SrcFolder = library.SourceDir.String() - knownLib.UtilityFolder = library.UtilityDir.String() + if (library.InstallDir != nil) { + knownLib.Folder = library.InstallDir.String() + } + + if (library.SourceDir != nil) { + knownLib.SrcFolder = library.SourceDir.String() + } + + if library.UtilityDir != nil { + knownLib.UtilityFolder = library.UtilityDir.String() + } + knownLib.Layout = library.Layout knownLib.Name = library.Name knownLib.RealName = library.RealName knownLib.IsLegacy = library.IsLegacy - knownLib.Version = library.Version.String() + + if (library.Version != nil) { + knownLib.Version = library.Version.String() + } knownLib.Author = library.Author knownLib.Maintainer = library.Maintainer knownLib.Sentence = library.Sentence From 1a7c972ce799d9bf93247a2f7be5dfc8848b4d93 Mon Sep 17 00:00:00 2001 From: Sysprogs Date: Mon, 2 Dec 2019 15:30:20 -0800 Subject: [PATCH 4/7] Optimization flag substitution now works for STM32F4 targets --- legacy/builder/builder_utils/utils.go | 1 + 1 file changed, 1 insertion(+) diff --git a/legacy/builder/builder_utils/utils.go b/legacy/builder/builder_utils/utils.go index 0d737d8db30..e5f7d8a3f2f 100644 --- a/legacy/builder/builder_utils/utils.go +++ b/legacy/builder/builder_utils/utils.go @@ -119,6 +119,7 @@ func RemoveOptimizationFromBuildProperties(properties *properties.Map) *properti result.Set("compiler.c.flags", ReplaceOptimizationFlags(result.Get("compiler.c.flags"))) result.Set("compiler.cpp.flags", ReplaceOptimizationFlags(result.Get("compiler.cpp.flags"))) + result.Set("build.flags.optimize", ReplaceOptimizationFlags(result.Get("build.flags.optimize"))) return result } From db90f49c584cc3e9fdb70372e24a841db0ffba48 Mon Sep 17 00:00:00 2001 From: Sysprogs Date: Mon, 22 Nov 2021 19:06:19 -0800 Subject: [PATCH 5/7] Fixed compatibility with ESP32 Core 2.0.1 --- legacy/builder/recipe_runner.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/legacy/builder/recipe_runner.go b/legacy/builder/recipe_runner.go index 20a3d3ec558..e4e19fa3df0 100644 --- a/legacy/builder/recipe_runner.go +++ b/legacy/builder/recipe_runner.go @@ -43,7 +43,9 @@ func (s *RecipeByPrefixSuffixRunner) Run(ctx *types.Context) error { recipes := findRecipes(buildProperties, s.Prefix, s.Suffix) if ctx.CodeModelBuilder != nil { - return nil + if s.Prefix != constants.HOOKS_PREBUILD { + return nil + } } properties := buildProperties.Clone() From 79fb95b8461445d2547925130123e293fbe711ef Mon Sep 17 00:00:00 2001 From: Sysprogs Date: Thu, 27 Jan 2022 13:36:25 -0800 Subject: [PATCH 6/7] Added support for specifying extra cflags for sketch/core/libraries only --- legacy/builder/builder_utils/utils.go | 6 +++--- legacy/builder/phases/core_builder.go | 2 +- legacy/builder/phases/libraries_builder.go | 2 +- legacy/builder/phases/sketch_builder.go | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/legacy/builder/builder_utils/utils.go b/legacy/builder/builder_utils/utils.go index 1e7fd3e32ab..69e91e422a3 100644 --- a/legacy/builder/builder_utils/utils.go +++ b/legacy/builder/builder_utils/utils.go @@ -125,11 +125,11 @@ func RemoveOptimizationFromBuildProperties(properties *properties.Map) *properti return result } -func ExpandSysprogsExtensionProperties(properties *properties.Map) *properties.Map { +func ExpandSysprogsExtensionProperties(properties *properties.Map, subtype string) *properties.Map { var result = properties.Clone() - result.Set("compiler.c.flags", result.Get("compiler.c.flags") + " " + result.Get("com.sysprogs.extraflags")) - result.Set("compiler.cpp.flags", result.Get("compiler.cpp.flags") + " " + result.Get("com.sysprogs.extraflags")) + result.Set("compiler.c.flags", result.Get("compiler.c.flags") + " " + result.Get("com.sysprogs.extraflags") + " " + result.Get("com.sysprogs.extraflags." + subtype)) + result.Set("compiler.cpp.flags", result.Get("compiler.cpp.flags") + " " + result.Get("com.sysprogs.extraflags") + " " + result.Get("com.sysprogs.extraflags." + subtype)) return result } diff --git a/legacy/builder/phases/core_builder.go b/legacy/builder/phases/core_builder.go index 2bb11baa212..0ca2271d41e 100644 --- a/legacy/builder/phases/core_builder.go +++ b/legacy/builder/phases/core_builder.go @@ -61,7 +61,7 @@ func (s *CoreBuilder) Run(ctx *types.Context) error { buildProperties = builder_utils.RemoveOptimizationFromBuildProperties(buildProperties) } - buildProperties = builder_utils.ExpandSysprogsExtensionProperties(buildProperties) + buildProperties = builder_utils.ExpandSysprogsExtensionProperties(buildProperties, "core") archiveFile, objectFiles, err := compileCore(ctx, coreBuildPath, coreBuildCachePath, buildProperties, coreModel) if err != nil { diff --git a/legacy/builder/phases/libraries_builder.go b/legacy/builder/phases/libraries_builder.go index 9c069f7bddc..7146099539f 100644 --- a/legacy/builder/phases/libraries_builder.go +++ b/legacy/builder/phases/libraries_builder.go @@ -130,7 +130,7 @@ func compileLibraries(ctx *types.Context, libraries libraries.List, buildPath *p effectiveProperties = unoptimizedProperties } - effectiveProperties = builder_utils.ExpandSysprogsExtensionProperties(effectiveProperties) + effectiveProperties = builder_utils.ExpandSysprogsExtensionProperties(effectiveProperties, "lib") libraryObjectFiles, err := compileLibrary(ctx, library, buildPath, effectiveProperties, includes, libraryModel) if err != nil { diff --git a/legacy/builder/phases/sketch_builder.go b/legacy/builder/phases/sketch_builder.go index 5a187b836d0..4990dd5427b 100644 --- a/legacy/builder/phases/sketch_builder.go +++ b/legacy/builder/phases/sketch_builder.go @@ -45,7 +45,7 @@ func (s *SketchBuilder) Run(ctx *types.Context) error { buildProperties = builder_utils.RemoveOptimizationFromBuildProperties(buildProperties) } - buildProperties = builder_utils.ExpandSysprogsExtensionProperties(buildProperties) + buildProperties = builder_utils.ExpandSysprogsExtensionProperties(buildProperties, "sketch") objectFiles, err := builder_utils.CompileFiles(ctx, sketchBuildPath, false, sketchBuildPath, buildProperties, includes, sketchModel) if err != nil { From 9f472984d3a54152cbb3003ba76300b62480cf70 Mon Sep 17 00:00:00 2001 From: Sysprogs Date: Wed, 13 Sep 2023 11:22:13 -0700 Subject: [PATCH 7/7] Arduino projects can now change LDFLAGS, enabling relocation records --- legacy/builder/builder_utils/utils.go | 6 +++++- legacy/builder/phases/linker.go | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/legacy/builder/builder_utils/utils.go b/legacy/builder/builder_utils/utils.go index 69e91e422a3..19be850a4ee 100644 --- a/legacy/builder/builder_utils/utils.go +++ b/legacy/builder/builder_utils/utils.go @@ -133,7 +133,11 @@ func ExpandSysprogsExtensionProperties(properties *properties.Map, subtype strin return result } - +func ExpandSysprogsLinkerProperties(properties *properties.Map) *properties.Map { + var result = properties.Clone() + result.Set("compiler.ldflags", result.Get("compiler.ldflags") + " " + result.Get("com.sysprogs.extraflags.ld")) + return result +} func findFilesInFolder(sourcePath *paths.Path, extension string, recurse bool) (paths.PathList, error) { files, err := utils.ReadDirFiltered(sourcePath.String(), utils.FilterFilesWithExtensions(extension)) diff --git a/legacy/builder/phases/linker.go b/legacy/builder/phases/linker.go index 96be5fe2c0e..79c4f83c79d 100644 --- a/legacy/builder/phases/linker.go +++ b/legacy/builder/phases/linker.go @@ -54,6 +54,7 @@ func (s *Linker) Run(ctx *types.Context) error { } buildProperties := ctx.BuildProperties + buildProperties = builder_utils.ExpandSysprogsLinkerProperties(buildProperties) if ctx.CodeModelBuilder != nil { //Just compute the linker command line (even without the full object list), we are not actually linking and are only interested in the output file name