@@ -32,6 +32,7 @@ package builder_utils
32
32
import (
33
33
"bytes"
34
34
"fmt"
35
+ "io"
35
36
"os"
36
37
"os/exec"
37
38
"path/filepath"
@@ -116,6 +117,34 @@ func findFilesInFolder(sourcePath string, extension string, recurse bool) ([]str
116
117
return sources , nil
117
118
}
118
119
120
+ func findAllFilesInFolder (sourcePath string , recurse bool ) ([]string , error ) {
121
+ files , err := utils .ReadDirFiltered (sourcePath , utils .FilterFiles ())
122
+ if err != nil {
123
+ return nil , i18n .WrapError (err )
124
+ }
125
+ var sources []string
126
+ for _ , file := range files {
127
+ sources = append (sources , filepath .Join (sourcePath , file .Name ()))
128
+ }
129
+
130
+ if recurse {
131
+ folders , err := utils .ReadDirFiltered (sourcePath , utils .FilterDirs )
132
+ if err != nil {
133
+ return nil , i18n .WrapError (err )
134
+ }
135
+
136
+ for _ , folder := range folders {
137
+ otherSources , err := findAllFilesInFolder (filepath .Join (sourcePath , folder .Name ()), recurse )
138
+ if err != nil {
139
+ return nil , i18n .WrapError (err )
140
+ }
141
+ sources = append (sources , otherSources ... )
142
+ }
143
+ }
144
+
145
+ return sources , nil
146
+ }
147
+
119
148
func compileFilesWithRecipe (objectFiles []string , sourcePath string , sources []string , buildPath string , buildProperties properties.Map , includes []string , recipe string , verbose bool , warningsLevel string , logger i18n.Logger ) ([]string , error ) {
120
149
for _ , source := range sources {
121
150
objectFile , err := compileFileWithRecipe (sourcePath , source , buildPath , buildProperties , includes , recipe , verbose , warningsLevel , logger )
@@ -258,6 +287,28 @@ func nonEmptyString(s string) bool {
258
287
return s != constants .EMPTY_STRING
259
288
}
260
289
290
+ func CoreOrReferencedCoreHasChanged (corePath , targetCorePath , targetFile string ) bool {
291
+
292
+ targetFileStat , err := os .Stat (targetFile )
293
+ if err == nil {
294
+ files , err := findAllFilesInFolder (corePath , true )
295
+ if err != nil {
296
+ return true
297
+ }
298
+ for _ , file := range files {
299
+ fileStat , err := os .Stat (file )
300
+ if err != nil || fileStat .ModTime ().After (targetFileStat .ModTime ()) {
301
+ return true
302
+ }
303
+ }
304
+ if targetCorePath != constants .EMPTY_STRING && ! strings .EqualFold (corePath , targetCorePath ) {
305
+ return CoreOrReferencedCoreHasChanged (targetCorePath , constants .EMPTY_STRING , targetFile )
306
+ }
307
+ return false
308
+ }
309
+ return true
310
+ }
311
+
261
312
func ArchiveCompiledFiles (buildPath string , archiveFile string , objectFiles []string , buildProperties properties.Map , verbose bool , logger i18n.Logger ) (string , error ) {
262
313
archiveFilePath := filepath .Join (buildPath , archiveFile )
263
314
@@ -366,3 +417,59 @@ func ExecRecipeCollectStdErr(buildProperties properties.Map, recipe string, remo
366
417
func RemoveHyphenMDDFlagFromGCCCommandLine (buildProperties properties.Map ) {
367
418
buildProperties [constants .BUILD_PROPERTIES_COMPILER_CPP_FLAGS ] = strings .Replace (buildProperties [constants .BUILD_PROPERTIES_COMPILER_CPP_FLAGS ], "-MMD" , "" , - 1 )
368
419
}
420
+
421
+ // CopyFile copies the contents of the file named src to the file named
422
+ // by dst. The file will be created if it does not already exist. If the
423
+ // destination file exists, all it's contents will be replaced by the contents
424
+ // of the source file. The file mode will be copied from the source and
425
+ // the copied data is synced/flushed to stable storage.
426
+ func CopyFile (src , dst string ) (err error ) {
427
+ in , err := os .Open (src )
428
+ if err != nil {
429
+ return
430
+ }
431
+ defer in .Close ()
432
+
433
+ out , err := os .Create (dst )
434
+ if err != nil {
435
+ return
436
+ }
437
+ defer func () {
438
+ if e := out .Close (); e != nil {
439
+ err = e
440
+ }
441
+ }()
442
+
443
+ _ , err = io .Copy (out , in )
444
+ if err != nil {
445
+ return
446
+ }
447
+
448
+ err = out .Sync ()
449
+ if err != nil {
450
+ return
451
+ }
452
+
453
+ si , err := os .Stat (src )
454
+ if err != nil {
455
+ return
456
+ }
457
+ err = os .Chmod (dst , si .Mode ())
458
+ if err != nil {
459
+ return
460
+ }
461
+
462
+ return
463
+ }
464
+
465
+ // GetCachedCoreArchiveFileName returns the filename to be used to store
466
+ // the global cached core.a.
467
+ func GetCachedCoreArchiveFileName (fqbn , coreFolder string ) string {
468
+ fqbnToUnderscore := strings .Replace (fqbn , ":" , "_" , - 1 )
469
+ fqbnToUnderscore = strings .Replace (fqbnToUnderscore , "=" , "_" , - 1 )
470
+ if absCoreFolder , err := filepath .Abs (coreFolder ); err == nil {
471
+ coreFolder = absCoreFolder
472
+ } // silently continue if absolute path can't be detected
473
+ hash := utils .MD5Sum ([]byte (coreFolder ))
474
+ return "core_" + fqbnToUnderscore + "_" + hash + ".a"
475
+ }
0 commit comments