@@ -35,14 +35,16 @@ import (
35
35
"path/filepath"
36
36
"strings"
37
37
38
+ "github.com/arduino/go-properties-map"
39
+
38
40
"github.com/arduino/arduino-builder/builder_utils"
39
41
"github.com/arduino/arduino-builder/constants"
40
42
"github.com/arduino/arduino-builder/i18n"
41
43
"github.com/arduino/arduino-builder/types"
42
44
"github.com/arduino/arduino-builder/utils"
43
45
)
44
46
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 }
46
48
var DOTHEXTENSION = map [string ]bool {".h" : true , ".hh" : true , ".hpp" : true }
47
49
var DOTAEXTENSION = map [string ]bool {".a" : true }
48
50
@@ -76,23 +78,39 @@ func (s *ExportProjectCMake) Run(ctx *types.Context) error {
76
78
coreFolder := filepath .Join (cmakeFolder , "core" )
77
79
cmakeFile := filepath .Join (cmakeFolder , "CMakeLists.txt" )
78
80
79
- // Copy used libraries in the correct folder
81
+ dynamicLibsFromPkgConfig := map [ string ] bool {}
80
82
extensions := func (ext string ) bool { return VALID_EXPORT_EXTENSIONS [ext ] }
83
+ staticLibsExtensions := func (ext string ) bool { return DOTAEXTENSION [ext ] }
81
84
for _ , library := range ctx .ImportedLibraries {
85
+ // Copy used libraries in the correct folder
82
86
libFolder := filepath .Join (libBaseFolder , library .Name )
87
+ mcu := ctx .BuildProperties [constants .BUILD_PROPERTIES_BUILD_MCU ]
83
88
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
+
84
102
// Remove examples folder
85
103
if _ , err := os .Stat (filepath .Join (libFolder , "examples" )); err == nil {
86
104
os .RemoveAll (filepath .Join (libFolder , "examples" ))
87
105
}
88
- // Remove stray folders contining incompatible libraries
89
- staticLibsExtensions := func (ext string ) bool { return DOTAEXTENSION [ext ] }
90
- mcu := ctx .BuildProperties [constants .BUILD_PROPERTIES_BUILD_MCU ]
106
+
107
+ // Remove stray folders contining incompatible or not needed libraries archives
91
108
var files []string
92
109
utils .FindFilesInFolder (& files , filepath .Join (libFolder , "src" ), staticLibsExtensions , true )
93
110
for _ , file := range files {
94
- if ! strings .Contains (filepath .Dir (file ), mcu ) {
95
- os .RemoveAll (filepath .Dir (file ))
111
+ staticLibDir := filepath .Dir (file )
112
+ if ! isStaticLib || ! strings .Contains (staticLibDir , mcu ) {
113
+ os .RemoveAll (staticLibDir )
96
114
}
97
115
}
98
116
}
@@ -109,10 +127,10 @@ func (s *ExportProjectCMake) Run(ctx *types.Context) error {
109
127
110
128
// Use old ctags method to generate export file
111
129
commands := []types.Command {
112
- & ContainerMergeCopySketchFiles {},
130
+ // &ContainerMergeCopySketchFiles{},
113
131
& ContainerAddPrototypes {},
114
- & FilterSketchSource {Source : & ctx .Source , RemoveLineMarkers : true },
115
- & SketchSaver {},
132
+ // &FilterSketchSource{Source: &ctx.Source, RemoveLineMarkers: true},
133
+ // &SketchSaver{},
116
134
}
117
135
118
136
for _ , command := range commands {
@@ -127,12 +145,12 @@ func (s *ExportProjectCMake) Run(ctx *types.Context) error {
127
145
// Extract CFLAGS, CPPFLAGS and LDFLAGS
128
146
var defines []string
129
147
var linkerflags []string
130
- var libs []string
148
+ var dynamicLibsFromGccMinusL []string
131
149
var linkDirectories []string
132
150
133
- extractCompileFlags (ctx , constants .RECIPE_C_COMBINE_PATTERN , & defines , & libs , & linkerflags , & linkDirectories , logger )
134
- extractCompileFlags (ctx , constants .RECIPE_C_PATTERN , & defines , & libs , & linkerflags , & linkDirectories , logger )
135
- extractCompileFlags (ctx , constants .RECIPE_CPP_PATTERN , & defines , & libs , & linkerflags , & linkDirectories , logger )
151
+ extractCompileFlags (ctx , constants .RECIPE_C_COMBINE_PATTERN , & defines , & dynamicLibsFromGccMinusL , & linkerflags , & linkDirectories , logger )
152
+ extractCompileFlags (ctx , constants .RECIPE_C_PATTERN , & defines , & dynamicLibsFromGccMinusL , & linkerflags , & linkDirectories , logger )
153
+ extractCompileFlags (ctx , constants .RECIPE_CPP_PATTERN , & defines , & dynamicLibsFromGccMinusL , & linkerflags , & linkDirectories , logger )
136
154
137
155
// Extract folders with .h in them for adding in include list
138
156
var headerFiles []string
@@ -141,9 +159,8 @@ func (s *ExportProjectCMake) Run(ctx *types.Context) error {
141
159
foldersContainingDotH := findUniqueFoldersRelative (headerFiles , cmakeFolder )
142
160
143
161
// Extract folders with .a in them for adding in static libs paths list
144
- var staticLibsFiles []string
145
- isStaticLib := func (ext string ) bool { return DOTAEXTENSION [ext ] }
146
- utils .FindFilesInFolder (& staticLibsFiles , cmakeFolder , isStaticLib , true )
162
+ var staticLibs []string
163
+ utils .FindFilesInFolder (& staticLibs , cmakeFolder , staticLibsExtensions , true )
147
164
148
165
// Generate the CMakeLists global file
149
166
@@ -168,33 +185,39 @@ func (s *ExportProjectCMake) Run(ctx *types.Context) error {
168
185
// Add SO_PATHS option for libraries not getting found by pkg_config
169
186
cmakelist += "set(EXTRA_LIBS_DIRS \" \" CACHE STRING \" Additional paths for dynamic libraries\" )\n "
170
187
171
- for i , lib := range libs {
188
+ linkGroup := ""
189
+ for _ , lib := range dynamicLibsFromGccMinusL {
172
190
// Dynamic libraries should be discovered by pkg_config
173
- lib = strings .TrimPrefix (lib , "-l" )
174
- libs [i ] = lib
175
191
cmakelist += "pkg_search_module (" + strings .ToUpper (lib ) + " " + lib + ")\n "
176
192
relLinkDirectories = append (relLinkDirectories , "${" + strings .ToUpper (lib )+ "_LIBRARY_DIRS}" )
193
+ linkGroup += " " + lib
194
+ }
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}"
177
199
}
178
200
cmakelist += "link_directories (" + strings .Join (relLinkDirectories , " " ) + " ${EXTRA_LIBS_DIRS})\n "
179
- for _ , staticLibsFile := range staticLibsFiles {
201
+ for _ , staticLib := range staticLibs {
180
202
// Static libraries are fully configured
181
- lib := filepath .Base (staticLibsFile )
203
+ lib := filepath .Base (staticLib )
182
204
lib = strings .TrimPrefix (lib , "lib" )
183
205
lib = strings .TrimSuffix (lib , ".a" )
184
- if ! utils .SliceContains (libs , lib ) {
185
- libs = append ( libs , lib )
206
+ if ! utils .SliceContains (dynamicLibsFromGccMinusL , lib ) {
207
+ linkGroup += " " + lib
186
208
cmakelist += "add_library (" + lib + " STATIC IMPORTED)\n "
187
- location := strings .TrimPrefix (staticLibsFile , cmakeFolder )
209
+ location := strings .TrimPrefix (staticLib , cmakeFolder )
188
210
cmakelist += "set_property(TARGET " + lib + " PROPERTY IMPORTED_LOCATION " + "${PROJECT_SOURCE_DIR}" + location + " )\n "
189
211
}
190
212
}
213
+
191
214
// Include source files
192
215
// TODO: remove .cpp and .h from libraries example folders
193
216
cmakelist += "file (GLOB_RECURSE SOURCES core/*.c* lib/*.c* sketch/*.c*)\n "
194
217
195
218
// Compile and link project
196
219
cmakelist += "add_executable (" + projectName + " ${SOURCES} ${SOURCES_LIBS})\n "
197
- cmakelist += "target_link_libraries( " + projectName + " -Wl,--as-needed -Wl,--start-group " + strings . Join ( libs , " " ) + " -Wl,--end-group)\n "
220
+ cmakelist += "target_link_libraries( " + projectName + " -Wl,--as-needed -Wl,--start-group " + linkGroup + " -Wl,--end-group)\n "
198
221
199
222
utils .WriteFile (cmakeFile , cmakelist )
200
223
@@ -205,26 +228,26 @@ func canExportCmakeProject(ctx *types.Context) bool {
205
228
return ctx .BuildProperties [constants .BUILD_PROPERTIES_COMPILER_EXPORT_CMAKE_FLAGS ] != ""
206
229
}
207
230
208
- func extractCompileFlags (ctx * types.Context , receipe string , defines , libs , linkerflags , linkDirectories * []string , logger i18n.Logger ) {
231
+ func extractCompileFlags (ctx * types.Context , receipe string , defines , dynamicLibs , linkerflags , linkDirectories * []string , logger i18n.Logger ) {
209
232
command , _ := builder_utils .PrepareCommandForRecipe (ctx , ctx .BuildProperties , receipe , true )
210
233
211
234
for _ , arg := range command .Args {
212
235
if strings .HasPrefix (arg , "-D" ) {
213
- * defines = appendIfUnique (* defines , arg )
236
+ * defines = utils . AppendIfNotPresent (* defines , arg )
214
237
continue
215
238
}
216
239
if strings .HasPrefix (arg , "-l" ) {
217
- * libs = appendIfUnique ( * libs , arg )
240
+ * dynamicLibs = utils . AppendIfNotPresent ( * dynamicLibs , arg [ 2 :] )
218
241
continue
219
242
}
220
243
if strings .HasPrefix (arg , "-L" ) {
221
- * linkDirectories = appendIfUnique (* linkDirectories , strings . TrimPrefix ( arg , "-L" ) )
244
+ * linkDirectories = utils . AppendIfNotPresent (* linkDirectories , arg [ 2 :] )
222
245
continue
223
246
}
224
247
if strings .HasPrefix (arg , "-" ) && ! strings .HasPrefix (arg , "-I" ) && ! strings .HasPrefix (arg , "-o" ) {
225
248
// HACK : from linkerflags remove MMD (no cache is produced)
226
249
if ! strings .HasPrefix (arg , "-MMD" ) {
227
- * linkerflags = appendIfUnique (* linkerflags , arg )
250
+ * linkerflags = utils . AppendIfNotPresent (* linkerflags , arg )
228
251
}
229
252
}
230
253
}
@@ -241,10 +264,3 @@ func findUniqueFoldersRelative(slice []string, base string) string {
241
264
}
242
265
return strings .Join (out , " " )
243
266
}
244
-
245
- func appendIfUnique (slice []string , element string ) []string {
246
- if ! utils .SliceContains (slice , element ) {
247
- slice = append (slice , element )
248
- }
249
- return slice
250
- }
0 commit comments