@@ -17,6 +17,8 @@ package builder
17
17
18
18
import (
19
19
"fmt"
20
+ "io"
21
+ "os"
20
22
"path/filepath"
21
23
"regexp"
22
24
"strings"
@@ -39,6 +41,130 @@ type ExportProjectCMake struct {
39
41
var lineMatcher = regexp .MustCompile (`^#line\s\d+\s"` )
40
42
41
43
func (s * ExportProjectCMake ) Run (ctx * types.Context ) error {
44
+ // copies the contents of the file named src to the file named
45
+ // by dst. The file will be created if it does not already exist. If the
46
+ // destination file exists, all it's contents will be replaced by the contents
47
+ // of the source file. The file mode will be copied from the source and
48
+ // the copied data is synced/flushed to stable storage.
49
+ // TODO: Replace with call to go-paths-helper...
50
+ copyFile := func (src , dst string ) (err error ) {
51
+ in , err := os .Open (src )
52
+ if err != nil {
53
+ return
54
+ }
55
+ defer in .Close ()
56
+
57
+ out , err := os .Create (dst )
58
+ if err != nil {
59
+ return
60
+ }
61
+ defer func () {
62
+ if e := out .Close (); e != nil {
63
+ err = e
64
+ }
65
+ }()
66
+
67
+ _ , err = io .Copy (out , in )
68
+ if err != nil {
69
+ return
70
+ }
71
+
72
+ err = out .Sync ()
73
+ if err != nil {
74
+ return
75
+ }
76
+
77
+ si , err := os .Stat (src )
78
+ if err != nil {
79
+ return
80
+ }
81
+ err = os .Chmod (dst , si .Mode ())
82
+ if err != nil {
83
+ return
84
+ }
85
+
86
+ return
87
+ }
88
+
89
+ // recursively copies a directory tree, attempting to preserve permissions.
90
+ // Source directory must exist, destination directory must *not* exist.
91
+ // Symlinks are ignored and skipped.
92
+ // TODO: Replace with call to go-paths-helper...
93
+ var copyDir func (src string , dst string , extensions []string ) (err error )
94
+ copyDir = func (src string , dst string , extensions []string ) (err error ) {
95
+ isAcceptedExtension := func (ext string ) bool {
96
+ ext = strings .ToLower (ext )
97
+ for _ , valid := range extensions {
98
+ if ext == valid {
99
+ return true
100
+ }
101
+ }
102
+ return false
103
+ }
104
+
105
+ src = filepath .Clean (src )
106
+ dst = filepath .Clean (dst )
107
+
108
+ si , err := os .Stat (src )
109
+ if err != nil {
110
+ return err
111
+ }
112
+ if ! si .IsDir () {
113
+ return fmt .Errorf (tr ("source is not a directory" ))
114
+ }
115
+
116
+ _ , err = os .Stat (dst )
117
+ if err != nil && ! os .IsNotExist (err ) {
118
+ return
119
+ }
120
+ if err == nil {
121
+ return fmt .Errorf (tr ("destination already exists" ))
122
+ }
123
+
124
+ err = os .MkdirAll (dst , si .Mode ())
125
+ if err != nil {
126
+ return
127
+ }
128
+
129
+ entries , err := os .ReadDir (src )
130
+ if err != nil {
131
+ return
132
+ }
133
+
134
+ for _ , dirEntry := range entries {
135
+ entry , scopeErr := dirEntry .Info ()
136
+ if scopeErr != nil {
137
+ return
138
+ }
139
+
140
+ srcPath := filepath .Join (src , entry .Name ())
141
+ dstPath := filepath .Join (dst , entry .Name ())
142
+
143
+ if entry .IsDir () {
144
+ err = copyDir (srcPath , dstPath , extensions )
145
+ if err != nil {
146
+ return
147
+ }
148
+ } else {
149
+ // Skip symlinks.
150
+ if entry .Mode ()& os .ModeSymlink != 0 {
151
+ continue
152
+ }
153
+
154
+ if ! isAcceptedExtension (filepath .Ext (srcPath )) {
155
+ continue
156
+ }
157
+
158
+ err = copyFile (srcPath , dstPath )
159
+ if err != nil {
160
+ return
161
+ }
162
+ }
163
+ }
164
+
165
+ return
166
+ }
167
+
42
168
var validExportExtensions = []string {".a" , ".properties" }
43
169
for ext := range globals .SourceFilesValidExtensions {
44
170
validExportExtensions = append (validExportExtensions , ext )
@@ -76,7 +202,7 @@ func (s *ExportProjectCMake) Run(ctx *types.Context) error {
76
202
// Copy used libraries in the correct folder
77
203
libDir := libBaseFolder .Join (library .DirName )
78
204
mcu := ctx .BuildProperties .Get (constants .BUILD_PROPERTIES_BUILD_MCU )
79
- utils . CopyDir (library .InstallDir .String (), libDir .String (), validExportExtensions )
205
+ copyDir (library .InstallDir .String (), libDir .String (), validExportExtensions )
80
206
81
207
// Read cmake options if available
82
208
isStaticLib := true
@@ -96,7 +222,7 @@ func (s *ExportProjectCMake) Run(ctx *types.Context) error {
96
222
}
97
223
98
224
// Remove stray folders contining incompatible or not needed libraries archives
99
- files , _ := utils .FindFilesInFolder (libDir .Join ("src" ), true , validStaticLibExtensions )
225
+ files , _ := utils .FindFilesInFolder (libDir .Join ("src" ), true , validStaticLibExtensions ... )
100
226
for _ , file := range files {
101
227
staticLibDir := file .Parent ()
102
228
if ! isStaticLib || ! strings .Contains (staticLibDir .String (), mcu ) {
@@ -106,11 +232,11 @@ func (s *ExportProjectCMake) Run(ctx *types.Context) error {
106
232
}
107
233
108
234
// Copy core + variant in use + preprocessed sketch in the correct folders
109
- err := utils . CopyDir (ctx .BuildProperties .Get ("build.core.path" ), coreFolder .String (), validExportExtensions )
235
+ err := copyDir (ctx .BuildProperties .Get ("build.core.path" ), coreFolder .String (), validExportExtensions )
110
236
if err != nil {
111
237
fmt .Println (err )
112
238
}
113
- err = utils . CopyDir (ctx .BuildProperties .Get ("build.variant.path" ), coreFolder .Join ("variant" ).String (), validExportExtensions )
239
+ err = copyDir (ctx .BuildProperties .Get ("build.variant.path" ), coreFolder .Join ("variant" ).String (), validExportExtensions )
114
240
if err != nil {
115
241
fmt .Println (err )
116
242
}
@@ -119,13 +245,13 @@ func (s *ExportProjectCMake) Run(ctx *types.Context) error {
119
245
return err
120
246
}
121
247
122
- err = utils . CopyDir (ctx .SketchBuildPath .String (), cmakeFolder .Join ("sketch" ).String (), validExportExtensions )
248
+ err = copyDir (ctx .SketchBuildPath .String (), cmakeFolder .Join ("sketch" ).String (), validExportExtensions )
123
249
if err != nil {
124
250
fmt .Println (err )
125
251
}
126
252
127
253
// remove "#line 1 ..." from exported c_make folder sketch
128
- sketchFiles , _ := utils .FindFilesInFolder (cmakeFolder .Join ("sketch" ), false , validExportExtensions )
254
+ sketchFiles , _ := utils .FindFilesInFolder (cmakeFolder .Join ("sketch" ), false , validExportExtensions ... )
129
255
130
256
for _ , file := range sketchFiles {
131
257
input , err := file .ReadFile ()
@@ -159,11 +285,11 @@ func (s *ExportProjectCMake) Run(ctx *types.Context) error {
159
285
extractCompileFlags (ctx , "recipe.cpp.o.pattern" , & defines , & dynamicLibsFromGccMinusL , & linkerflags , & linkDirectories )
160
286
161
287
// Extract folders with .h in them for adding in include list
162
- headerFiles , _ := utils .FindFilesInFolder (cmakeFolder , true , validHeaderExtensions )
288
+ headerFiles , _ := utils .FindFilesInFolder (cmakeFolder , true , validHeaderExtensions ... )
163
289
foldersContainingHeaders := findUniqueFoldersRelative (headerFiles .AsStrings (), cmakeFolder .String ())
164
290
165
291
// Extract folders with .a in them for adding in static libs paths list
166
- staticLibs , _ := utils .FindFilesInFolder (cmakeFolder , true , validStaticLibExtensions )
292
+ staticLibs , _ := utils .FindFilesInFolder (cmakeFolder , true , validStaticLibExtensions ... )
167
293
168
294
// Generate the CMakeLists global file
169
295
@@ -232,25 +358,34 @@ func canExportCmakeProject(ctx *types.Context) bool {
232
358
}
233
359
234
360
func extractCompileFlags (ctx * types.Context , recipe string , defines , dynamicLibs , linkerflags , linkDirectories * []string ) {
361
+ appendIfNotPresent := func (target []string , elements ... string ) []string {
362
+ for _ , element := range elements {
363
+ if ! slices .Contains (target , element ) {
364
+ target = append (target , element )
365
+ }
366
+ }
367
+ return target
368
+ }
369
+
235
370
command , _ := builder_utils .PrepareCommandForRecipe (ctx .BuildProperties , recipe , true , ctx .PackageManager .GetEnvVarsForSpawnedProcess ())
236
371
237
372
for _ , arg := range command .Args {
238
373
if strings .HasPrefix (arg , "-D" ) {
239
- * defines = utils . AppendIfNotPresent (* defines , arg )
374
+ * defines = appendIfNotPresent (* defines , arg )
240
375
continue
241
376
}
242
377
if strings .HasPrefix (arg , "-l" ) {
243
- * dynamicLibs = utils . AppendIfNotPresent (* dynamicLibs , arg [2 :])
378
+ * dynamicLibs = appendIfNotPresent (* dynamicLibs , arg [2 :])
244
379
continue
245
380
}
246
381
if strings .HasPrefix (arg , "-L" ) {
247
- * linkDirectories = utils . AppendIfNotPresent (* linkDirectories , arg [2 :])
382
+ * linkDirectories = appendIfNotPresent (* linkDirectories , arg [2 :])
248
383
continue
249
384
}
250
385
if strings .HasPrefix (arg , "-" ) && ! strings .HasPrefix (arg , "-I" ) && ! strings .HasPrefix (arg , "-o" ) {
251
386
// HACK : from linkerflags remove MMD (no cache is produced)
252
387
if ! strings .HasPrefix (arg , "-MMD" ) {
253
- * linkerflags = utils . AppendIfNotPresent (* linkerflags , arg )
388
+ * linkerflags = appendIfNotPresent (* linkerflags , arg )
254
389
}
255
390
}
256
391
}
0 commit comments