Skip to content

Commit 2ca23f1

Browse files
cmagliefacchinm
authored andcommitted
cmake: Allow dynamic linking of libraries
This commit introduce a way for library authors to force the builder to output a cmake build script with a library linked dynamically. The trick is to add a file named arduino_builder.properties with the following key: cmake.pkg_config=lib1 lib2 lib3 ... By doing so, the lib archives (.a) in the library are ignored and a bunch of "pkg_search_module" rows are added to the CMakeList.txt for the specified "lib1" "lib2" "lib3". The corresponding flags in "link_directories" and "target_link_libraries" directives are added as well. The above trick does affect only the cmake export, the normal build of the arduino-builder is unchanged.
1 parent 930e980 commit 2ca23f1

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

create_cmake_rule.go

+25-3
Original file line numberDiff line numberDiff line change
@@ -35,14 +35,16 @@ import (
3535
"path/filepath"
3636
"strings"
3737

38+
"github.com/arduino/go-properties-map"
39+
3840
"github.com/arduino/arduino-builder/builder_utils"
3941
"github.com/arduino/arduino-builder/constants"
4042
"github.com/arduino/arduino-builder/i18n"
4143
"github.com/arduino/arduino-builder/types"
4244
"github.com/arduino/arduino-builder/utils"
4345
)
4446

45-
var VALID_EXPORT_EXTENSIONS = map[string]bool{".h": true, ".c": true, ".hpp": true, ".hh": true, ".cpp": true, ".s": true, ".a": true}
47+
var VALID_EXPORT_EXTENSIONS = map[string]bool{".h": true, ".c": true, ".hpp": true, ".hh": true, ".cpp": true, ".s": true, ".a": true, ".properties": true}
4648
var DOTHEXTENSION = map[string]bool{".h": true, ".hh": true, ".hpp": true}
4749
var DOTAEXTENSION = map[string]bool{".a": true}
4850

@@ -76,13 +78,27 @@ func (s *ExportProjectCMake) Run(ctx *types.Context) error {
7678
coreFolder := filepath.Join(cmakeFolder, "core")
7779
cmakeFile := filepath.Join(cmakeFolder, "CMakeLists.txt")
7880

81+
dynamicLibsFromPkgConfig := map[string]bool{}
7982
extensions := func(ext string) bool { return VALID_EXPORT_EXTENSIONS[ext] }
8083
staticLibsExtensions := func(ext string) bool { return DOTAEXTENSION[ext] }
8184
for _, library := range ctx.ImportedLibraries {
8285
// Copy used libraries in the correct folder
8386
libFolder := filepath.Join(libBaseFolder, library.Name)
8487
mcu := ctx.BuildProperties[constants.BUILD_PROPERTIES_BUILD_MCU]
8588
utils.CopyDir(library.Folder, libFolder, extensions)
89+
90+
// Read cmake options if available
91+
isStaticLib := true
92+
if cmakeOptions, err := properties.Load(filepath.Join(libFolder, "src", mcu, "arduino_builder.properties")); err == nil {
93+
// If the library can be linked dynamically do not copy the library folder
94+
if pkgs, ok := cmakeOptions["cmake.pkg_config"]; ok {
95+
isStaticLib = false
96+
for _, pkg := range strings.Split(pkgs, " ") {
97+
dynamicLibsFromPkgConfig[pkg] = true
98+
}
99+
}
100+
}
101+
86102
// Remove examples folder
87103
if _, err := os.Stat(filepath.Join(libFolder, "examples")); err == nil {
88104
os.RemoveAll(filepath.Join(libFolder, "examples"))
@@ -92,8 +108,9 @@ func (s *ExportProjectCMake) Run(ctx *types.Context) error {
92108
var files []string
93109
utils.FindFilesInFolder(&files, filepath.Join(libFolder, "src"), staticLibsExtensions, true)
94110
for _, file := range files {
95-
if !strings.Contains(filepath.Dir(file), mcu) {
96-
os.RemoveAll(filepath.Dir(file))
111+
staticLibDir := filepath.Dir(file)
112+
if !isStaticLib || !strings.Contains(staticLibDir, mcu) {
113+
os.RemoveAll(staticLibDir)
97114
}
98115
}
99116
}
@@ -175,6 +192,11 @@ func (s *ExportProjectCMake) Run(ctx *types.Context) error {
175192
relLinkDirectories = append(relLinkDirectories, "${"+strings.ToUpper(lib)+"_LIBRARY_DIRS}")
176193
linkGroup += " " + lib
177194
}
195+
for lib := range dynamicLibsFromPkgConfig {
196+
cmakelist += "pkg_search_module (" + strings.ToUpper(lib) + " " + lib + ")\n"
197+
relLinkDirectories = append(relLinkDirectories, "${"+strings.ToUpper(lib)+"_LIBRARY_DIRS}")
198+
linkGroup += " ${" + strings.ToUpper(lib) + "_LIBRARIES}"
199+
}
178200
cmakelist += "link_directories (" + strings.Join(relLinkDirectories, " ") + " ${EXTRA_LIBS_DIRS})\n"
179201
for _, staticLib := range staticLibs {
180202
// Static libraries are fully configured

0 commit comments

Comments
 (0)