diff --git a/src/arduino.cc/builder/constants/constants.go b/src/arduino.cc/builder/constants/constants.go index cdbdb72b..dcbf7063 100644 --- a/src/arduino.cc/builder/constants/constants.go +++ b/src/arduino.cc/builder/constants/constants.go @@ -48,6 +48,7 @@ const BUILD_PROPERTIES_BUILD_SYSTEM_PATH = "build.system.path" const BUILD_PROPERTIES_BUILD_VARIANT = "build.variant" const BUILD_PROPERTIES_BUILD_VARIANT_PATH = "build.variant.path" const BUILD_PROPERTIES_COMPILER_C_ELF_FLAGS = "compiler.c.elf.flags" +const BUILD_PROPERTIES_COMPILER_C_ELF_EXTRAFLAGS = "compiler.c.elf.extra_flags" const BUILD_PROPERTIES_COMPILER_CPP_FLAGS = "compiler.cpp.flags" const BUILD_PROPERTIES_COMPILER_PATH = "compiler.path" const BUILD_PROPERTIES_COMPILER_WARNING_FLAGS = "compiler.warning_flags" @@ -137,6 +138,8 @@ const LIBRARY_LICENSE = "license" const LIBRARY_MAINTAINER = "maintainer" const LIBRARY_NAME = "name" const LIBRARY_PARAGRAPH = "paragraph" +const LIBRARY_PRECOMPILED = "precompiled" +const LIBRARY_LDFLAGS = "ldflags" const LIBRARY_PROPERTIES = "library.properties" const LIBRARY_SENTENCE = "sentence" const LIBRARY_URL = "url" diff --git a/src/arduino.cc/builder/libraries_loader.go b/src/arduino.cc/builder/libraries_loader.go index 1e4b70e5..0fd3bfd9 100644 --- a/src/arduino.cc/builder/libraries_loader.go +++ b/src/arduino.cc/builder/libraries_loader.go @@ -184,6 +184,7 @@ func makeNewLibrary(libraryFolder string, debugLevel int, logger i18n.Logger) (* library.License = libProperties[constants.LIBRARY_LICENSE] library.Name = filepath.Base(libraryFolder) + library.RealName = strings.TrimSpace(libProperties[constants.LIBRARY_NAME]) library.Version = strings.TrimSpace(libProperties[constants.LIBRARY_VERSION]) library.Author = strings.TrimSpace(libProperties[constants.LIBRARY_AUTHOR]) library.Maintainer = strings.TrimSpace(libProperties[constants.LIBRARY_MAINTAINER]) @@ -192,6 +193,8 @@ func makeNewLibrary(libraryFolder string, debugLevel int, logger i18n.Logger) (* library.URL = strings.TrimSpace(libProperties[constants.LIBRARY_URL]) library.IsLegacy = false library.DotALinkage = strings.TrimSpace(libProperties[constants.LIBRARY_DOT_A_LINKAGE]) == "true" + library.Precompiled = strings.TrimSpace(libProperties[constants.LIBRARY_PRECOMPILED]) == "true" + library.LDflags = strings.TrimSpace(libProperties[constants.LIBRARY_LDFLAGS]) library.Properties = libProperties return library, nil diff --git a/src/arduino.cc/builder/phases/libraries_builder.go b/src/arduino.cc/builder/phases/libraries_builder.go index 816c512f..34c832a3 100644 --- a/src/arduino.cc/builder/phases/libraries_builder.go +++ b/src/arduino.cc/builder/phases/libraries_builder.go @@ -31,6 +31,7 @@ package phases import ( "path/filepath" + "strings" "arduino.cc/builder/builder_utils" "arduino.cc/builder/constants" @@ -40,6 +41,9 @@ import ( "arduino.cc/properties" ) +var PRECOMPILED_LIBRARIES_VALID_EXTENSIONS_STATIC = map[string]bool{".a": true} +var PRECOMPILED_LIBRARIES_VALID_EXTENSIONS_DYNAMIC = map[string]bool{".so": true} + type LibrariesBuilder struct{} func (s *LibrariesBuilder) Run(ctx *types.Context) error { @@ -64,6 +68,34 @@ func (s *LibrariesBuilder) Run(ctx *types.Context) error { ctx.LibrariesObjectFiles = objectFiles + // Search for precompiled libraries + fixLDFLAGforPrecompiledLibraries(ctx, libraries) + + return nil +} + +func fixLDFLAGforPrecompiledLibraries(ctx *types.Context, libraries []*types.Library) error { + + for _, library := range libraries { + if library.Precompiled { + // add library src path to compiler.c.elf.extra_flags + // use library.Name as lib name and srcPath/{mcpu} as location + mcu := ctx.BuildProperties[constants.BUILD_PROPERTIES_BUILD_MCU] + path := filepath.Join(library.SrcFolder, mcu) + // find all library names in the folder and prepend -l + filePaths := []string{} + libs_cmd := library.LDflags + " " + extensions := func(ext string) bool { return PRECOMPILED_LIBRARIES_VALID_EXTENSIONS_DYNAMIC[ext] } + utils.FindFilesInFolder(&filePaths, path, extensions, true) + for _, lib := range filePaths { + name := strings.TrimSuffix(filepath.Base(lib), filepath.Ext(lib)) + // strip "lib" first occurrence + name = strings.Replace(name, "lib", "", 1) + libs_cmd += "-l" + name + " " + } + ctx.BuildProperties[constants.BUILD_PROPERTIES_COMPILER_C_ELF_EXTRAFLAGS] += "\"-L" + path + "\" " + libs_cmd + } + } return nil } @@ -93,6 +125,24 @@ func compileLibrary(library *types.Library, buildPath string, buildProperties pr } objectFiles := []string{} + + if library.Precompiled { + // search for files with PRECOMPILED_LIBRARIES_VALID_EXTENSIONS + extensions := func(ext string) bool { return PRECOMPILED_LIBRARIES_VALID_EXTENSIONS_STATIC[ext] } + + filePaths := []string{} + mcu := buildProperties[constants.BUILD_PROPERTIES_BUILD_MCU] + err := utils.FindFilesInFolder(&filePaths, filepath.Join(library.SrcFolder, mcu), extensions, true) + if err != nil { + return nil, i18n.WrapError(err) + } + for _, path := range filePaths { + if strings.Contains(filepath.Base(path), library.RealName) { + objectFiles = append(objectFiles, path) + } + } + } + if library.Layout == types.LIBRARY_RECURSIVE { objectFiles, err = builder_utils.CompileFilesRecursive(objectFiles, library.SrcFolder, libraryBuildPath, buildProperties, includes, verbose, warningsLevel, logger) if err != nil { diff --git a/src/arduino.cc/builder/types/types.go b/src/arduino.cc/builder/types/types.go index eac16891..e7063450 100644 --- a/src/arduino.cc/builder/types/types.go +++ b/src/arduino.cc/builder/types/types.go @@ -168,8 +168,11 @@ type Library struct { UtilityFolder string Layout LibraryLayout Name string + RealName string Archs []string DotALinkage bool + Precompiled bool + LDflags string IsLegacy bool Version string Author string