Skip to content

Commit 48e453a

Browse files
committed
Improve precompiled libraries handling
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 4f3fec6 commit 48e453a

File tree

2 files changed

+80
-15
lines changed

2 files changed

+80
-15
lines changed

Diff for: legacy/builder/constants/constants.go

+1
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ const MSG_FIND_INCLUDES_FAILED = "Error while detecting libraries included by {0
112112
const MSG_INVALID_QUOTING = "Invalid quoting: no closing [{0}] char found."
113113
const MSG_LIB_LEGACY = "(legacy)"
114114
const MSG_LIBRARIES_MULTIPLE_LIBS_FOUND_FOR = "Multiple libraries were found for \"{0}\""
115+
const MSG_PRECOMPILED_LIBRARY_NOT_FOUND_FOR = "Library \"{0}\" declared precompiled but folder \"{1}\" does not exist"
115116
const MSG_LIBRARIES_NOT_USED = " Not used: {0}"
116117
const MSG_LIBRARIES_USED = " Used: {0}"
117118
const MSG_LIBRARY_CAN_USE_SRC_AND_UTILITY_FOLDERS = "Library can't use both 'src' and 'utility' folders. Double check {0}"

Diff for: legacy/builder/phases/libraries_builder.go

+79-15
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
package phases
3131

3232
import (
33+
"os"
3334
"path/filepath"
3435
"strings"
3536

@@ -45,6 +46,8 @@ import (
4546

4647
var PRECOMPILED_LIBRARIES_VALID_EXTENSIONS_STATIC = map[string]bool{".a": true}
4748
var PRECOMPILED_LIBRARIES_VALID_EXTENSIONS_DYNAMIC = map[string]bool{".so": true}
49+
var FLOAT_ABI_CFLAG = "float-abi"
50+
var FPU_CFLAG = "fpu"
4851

4952
type LibrariesBuilder struct{}
5053

@@ -71,28 +74,83 @@ func (s *LibrariesBuilder) Run(ctx *types.Context) error {
7174
return nil
7275
}
7376

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

76128
for _, library := range libs {
77129
if library.Precompiled {
78130
// add library src path to compiler.c.elf.extra_flags
79131
// use library.Name as lib name and srcPath/{mcpu} as location
80-
mcu := ctx.BuildProperties.Get(constants.BUILD_PROPERTIES_BUILD_MCU)
81-
path := library.SourceDir.Join(mcu).String()
132+
path := findExpectedPrecompiledLibFolder(ctx, library)
133+
if path == nil {
134+
break
135+
}
82136
// find all library names in the folder and prepend -l
83137
filePaths := []string{}
84138
libs_cmd := library.LDflags + " "
85-
extensions := func(ext string) bool { return PRECOMPILED_LIBRARIES_VALID_EXTENSIONS_DYNAMIC[ext] }
86-
utils.FindFilesInFolder(&filePaths, path, extensions, true)
139+
extensions := func(ext string) bool {
140+
return PRECOMPILED_LIBRARIES_VALID_EXTENSIONS_DYNAMIC[ext] || PRECOMPILED_LIBRARIES_VALID_EXTENSIONS_STATIC[ext]
141+
}
142+
utils.FindFilesInFolder(&filePaths, path.String(), extensions, false)
87143
for _, lib := range filePaths {
88144
name := strings.TrimSuffix(filepath.Base(lib), filepath.Ext(lib))
89145
// strip "lib" first occurrence
90-
name = strings.Replace(name, "lib", "", 1)
91-
libs_cmd += "-l" + name + " "
146+
if strings.HasPrefix(name, "lib") {
147+
name = strings.Replace(name, "lib", "", 1)
148+
libs_cmd += "-l" + name + " "
149+
}
92150
}
93151

94152
currLDFlags := ctx.BuildProperties.Get(constants.BUILD_PROPERTIES_COMPILER_LIBRARIES_LDFLAGS)
95-
ctx.BuildProperties.Set(constants.BUILD_PROPERTIES_COMPILER_LIBRARIES_LDFLAGS, currLDFlags+"\"-L"+path+"\" "+libs_cmd+" ")
153+
ctx.BuildProperties.Set(constants.BUILD_PROPERTIES_COMPILER_LIBRARIES_LDFLAGS, currLDFlags+"\"-L"+path.String()+"\" "+libs_cmd+" ")
96154
}
97155
}
98156
return nil
@@ -129,15 +187,21 @@ func compileLibrary(ctx *types.Context, library *libraries.Library, buildPath *p
129187
extensions := func(ext string) bool { return PRECOMPILED_LIBRARIES_VALID_EXTENSIONS_STATIC[ext] }
130188

131189
filePaths := []string{}
132-
mcu := buildProperties.Get(constants.BUILD_PROPERTIES_BUILD_MCU)
133-
err := utils.FindFilesInFolder(&filePaths, library.SourceDir.Join(mcu).String(), extensions, true)
134-
if err != nil {
135-
return nil, i18n.WrapError(err)
136-
}
137-
for _, path := range filePaths {
138-
if strings.Contains(filepath.Base(path), library.RealName) {
139-
objectFiles.Add(paths.New(path))
190+
precompiledPath := findExpectedPrecompiledLibFolder(ctx, library)
191+
if precompiledPath != nil {
192+
// TODO: This codepath is just taken for .a with unusual names that would
193+
// be ignored by -L / -l methods.
194+
// Should we force precompiled libraries to start with "lib" ?
195+
err := utils.FindFilesInFolder(&filePaths, precompiledPath.String(), extensions, false)
196+
if err != nil {
197+
return nil, i18n.WrapError(err)
198+
}
199+
for _, path := range filePaths {
200+
if !strings.HasPrefix(filepath.Base(path), "lib") {
201+
objectFiles.Add(paths.New(path))
202+
}
140203
}
204+
return objectFiles, nil
141205
}
142206
}
143207

0 commit comments

Comments
 (0)