Skip to content

Commit 469b339

Browse files
authored
Improve precompiled libraries handling (arduino#512)
General change: - library compilation bails out if the precompiled object is found. This allows mixed libraries that fallback using sources if no suitable precompiled object is found ARM float specification change: - Cortex M4+ allows specifying different flags for floating point ABI This patch introduces a second level of subfolder that MUST be used is -mfpu or -mfloat-abi are specified on the commandline Since there's no clear specification (unlike build.mcu), the values are extracted from c++ recipe For example, for a target which commandline contains `-mfloat-abi=hard -mfpu=fpv4-sp-d16` , the precompiled search path will be `$libfolder/cortex-m4/fpv4-sp-d16-hard` If that folder doesn't exist the library will be compiled from sources Fixes arduino/arduino-builder#256
1 parent fe48668 commit 469b339

File tree

2 files changed

+80
-15
lines changed

2 files changed

+80
-15
lines changed

legacy/builder/constants/constants.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,7 @@ const MSG_FIND_INCLUDES_FAILED = "Error while detecting libraries included by {0
9898
const MSG_INVALID_QUOTING = "Invalid quoting: no closing [{0}] char found."
9999
const MSG_LIB_LEGACY = "(legacy)"
100100
const MSG_LIBRARIES_MULTIPLE_LIBS_FOUND_FOR = "Multiple libraries were found for \"{0}\""
101+
const MSG_PRECOMPILED_LIBRARY_NOT_FOUND_FOR = "Library \"{0}\" declared precompiled but folder \"{1}\" does not exist"
101102
const MSG_LIBRARIES_NOT_USED = " Not used: {0}"
102103
const MSG_LIBRARIES_USED = " Used: {0}"
103104
const MSG_LIBRARY_CAN_USE_SRC_AND_UTILITY_FOLDERS = "Library can't use both 'src' and 'utility' folders. Double check {0}"

legacy/builder/phases/libraries_builder.go

Lines changed: 79 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
package phases
1717

1818
import (
19+
"os"
1920
"path/filepath"
2021
"strings"
2122

@@ -31,6 +32,8 @@ import (
3132

3233
var PRECOMPILED_LIBRARIES_VALID_EXTENSIONS_STATIC = map[string]bool{".a": true}
3334
var PRECOMPILED_LIBRARIES_VALID_EXTENSIONS_DYNAMIC = map[string]bool{".so": true}
35+
var FLOAT_ABI_CFLAG = "float-abi"
36+
var FPU_CFLAG = "fpu"
3437

3538
type LibrariesBuilder struct{}
3639

@@ -57,28 +60,83 @@ func (s *LibrariesBuilder) Run(ctx *types.Context) error {
5760
return nil
5861
}
5962

63+
func findExpectedPrecompiledLibFolder(ctx *types.Context, library *libraries.Library) *paths.Path {
64+
mcu := ctx.BuildProperties.Get(constants.BUILD_PROPERTIES_BUILD_MCU)
65+
// Add fpu specifications if they exist
66+
// To do so, resolve recipe.cpp.o.pattern,
67+
// search for -mfpu=xxx -mfloat-abi=yyy and add to a subfolder
68+
command, _ := builder_utils.PrepareCommandForRecipe(ctx, ctx.BuildProperties, constants.RECIPE_CPP_PATTERN, true)
69+
fpuSpecs := ""
70+
for _, el := range strings.Split(command.String(), " ") {
71+
if strings.Contains(el, FPU_CFLAG) {
72+
toAdd := strings.Split(el, "=")
73+
if len(toAdd) > 1 {
74+
fpuSpecs += strings.TrimSpace(toAdd[1]) + "-"
75+
break
76+
}
77+
}
78+
}
79+
for _, el := range strings.Split(command.String(), " ") {
80+
if strings.Contains(el, FLOAT_ABI_CFLAG) {
81+
toAdd := strings.Split(el, "=")
82+
if len(toAdd) > 1 {
83+
fpuSpecs += strings.TrimSpace(toAdd[1]) + "-"
84+
break
85+
}
86+
}
87+
}
88+
89+
logger := ctx.GetLogger()
90+
if len(fpuSpecs) > 0 {
91+
fpuSpecs = strings.TrimRight(fpuSpecs, "-")
92+
if library.SourceDir.Join(mcu).Join(fpuSpecs).Exist() {
93+
return library.SourceDir.Join(mcu).Join(fpuSpecs)
94+
} else {
95+
// we are unsure, compile from sources
96+
logger.Fprintln(os.Stdout, constants.LOG_LEVEL_INFO,
97+
constants.MSG_PRECOMPILED_LIBRARY_NOT_FOUND_FOR, library.Name, library.SourceDir.Join(mcu).Join(fpuSpecs))
98+
return nil
99+
}
100+
}
101+
102+
if library.SourceDir.Join(mcu).Exist() {
103+
return library.SourceDir.Join(mcu)
104+
}
105+
106+
logger.Fprintln(os.Stdout, constants.LOG_LEVEL_INFO,
107+
constants.MSG_PRECOMPILED_LIBRARY_NOT_FOUND_FOR, library.Name, library.SourceDir.Join(mcu))
108+
109+
return nil
110+
}
111+
60112
func fixLDFLAGforPrecompiledLibraries(ctx *types.Context, libs libraries.List) error {
61113

62114
for _, library := range libs {
63115
if library.Precompiled {
64116
// add library src path to compiler.c.elf.extra_flags
65117
// use library.Name as lib name and srcPath/{mcpu} as location
66-
mcu := ctx.BuildProperties.Get(constants.BUILD_PROPERTIES_BUILD_MCU)
67-
path := library.SourceDir.Join(mcu).String()
118+
path := findExpectedPrecompiledLibFolder(ctx, library)
119+
if path == nil {
120+
break
121+
}
68122
// find all library names in the folder and prepend -l
69123
filePaths := []string{}
70124
libs_cmd := library.LDflags + " "
71-
extensions := func(ext string) bool { return PRECOMPILED_LIBRARIES_VALID_EXTENSIONS_DYNAMIC[ext] }
72-
utils.FindFilesInFolder(&filePaths, path, extensions, true)
125+
extensions := func(ext string) bool {
126+
return PRECOMPILED_LIBRARIES_VALID_EXTENSIONS_DYNAMIC[ext] || PRECOMPILED_LIBRARIES_VALID_EXTENSIONS_STATIC[ext]
127+
}
128+
utils.FindFilesInFolder(&filePaths, path.String(), extensions, false)
73129
for _, lib := range filePaths {
74130
name := strings.TrimSuffix(filepath.Base(lib), filepath.Ext(lib))
75131
// strip "lib" first occurrence
76-
name = strings.Replace(name, "lib", "", 1)
77-
libs_cmd += "-l" + name + " "
132+
if strings.HasPrefix(name, "lib") {
133+
name = strings.Replace(name, "lib", "", 1)
134+
libs_cmd += "-l" + name + " "
135+
}
78136
}
79137

80138
currLDFlags := ctx.BuildProperties.Get(constants.BUILD_PROPERTIES_COMPILER_LIBRARIES_LDFLAGS)
81-
ctx.BuildProperties.Set(constants.BUILD_PROPERTIES_COMPILER_LIBRARIES_LDFLAGS, currLDFlags+"\"-L"+path+"\" "+libs_cmd+" ")
139+
ctx.BuildProperties.Set(constants.BUILD_PROPERTIES_COMPILER_LIBRARIES_LDFLAGS, currLDFlags+"\"-L"+path.String()+"\" "+libs_cmd+" ")
82140
}
83141
}
84142
return nil
@@ -115,15 +173,21 @@ func compileLibrary(ctx *types.Context, library *libraries.Library, buildPath *p
115173
extensions := func(ext string) bool { return PRECOMPILED_LIBRARIES_VALID_EXTENSIONS_STATIC[ext] }
116174

117175
filePaths := []string{}
118-
mcu := buildProperties.Get(constants.BUILD_PROPERTIES_BUILD_MCU)
119-
err := utils.FindFilesInFolder(&filePaths, library.SourceDir.Join(mcu).String(), extensions, true)
120-
if err != nil {
121-
return nil, i18n.WrapError(err)
122-
}
123-
for _, path := range filePaths {
124-
if strings.Contains(filepath.Base(path), library.RealName) {
125-
objectFiles.Add(paths.New(path))
176+
precompiledPath := findExpectedPrecompiledLibFolder(ctx, library)
177+
if precompiledPath != nil {
178+
// TODO: This codepath is just taken for .a with unusual names that would
179+
// be ignored by -L / -l methods.
180+
// Should we force precompiled libraries to start with "lib" ?
181+
err := utils.FindFilesInFolder(&filePaths, precompiledPath.String(), extensions, false)
182+
if err != nil {
183+
return nil, i18n.WrapError(err)
184+
}
185+
for _, path := range filePaths {
186+
if !strings.HasPrefix(filepath.Base(path), "lib") {
187+
objectFiles.Add(paths.New(path))
188+
}
126189
}
190+
return objectFiles, nil
127191
}
128192
}
129193

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy