@@ -32,6 +32,7 @@ package builder_utils
3232import (
3333 "bytes"
3434 "fmt"
35+ "io"
3536 "os"
3637 "os/exec"
3738 "path/filepath"
@@ -116,6 +117,34 @@ func findFilesInFolder(sourcePath string, extension string, recurse bool) ([]str
116117 return sources , nil
117118}
118119
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+
119148func 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 ) {
120149 for _ , source := range sources {
121150 objectFile , err := compileFileWithRecipe (sourcePath , source , buildPath , buildProperties , includes , recipe , verbose , warningsLevel , logger )
@@ -258,6 +287,24 @@ func nonEmptyString(s string) bool {
258287 return s != constants .EMPTY_STRING
259288}
260289
290+ func CheckIfRecompileIsAvoidable (corePath string , archiveFile string ) bool {
291+ archiveFileStat , err := os .Stat (archiveFile )
292+ if err == nil {
293+ files , err := findAllFilesInFolder (corePath , true )
294+ if err != nil {
295+ return false
296+ }
297+ for _ , file := range files {
298+ fileStat , err := os .Stat (file )
299+ if err != nil || fileStat .ModTime ().After (archiveFileStat .ModTime ()) {
300+ return false
301+ }
302+ }
303+ return true
304+ }
305+ return false
306+ }
307+
261308func ArchiveCompiledFiles (buildPath string , archiveFile string , objectFiles []string , buildProperties properties.Map , verbose bool , logger i18n.Logger ) (string , error ) {
262309 archiveFilePath := filepath .Join (buildPath , archiveFile )
263310
@@ -367,6 +414,50 @@ func RemoveHyphenMDDFlagFromGCCCommandLine(buildProperties properties.Map) {
367414 buildProperties [constants .BUILD_PROPERTIES_COMPILER_CPP_FLAGS ] = strings .Replace (buildProperties [constants .BUILD_PROPERTIES_COMPILER_CPP_FLAGS ], "-MMD" , "" , - 1 )
368415}
369416
417+ // CopyFile copies the contents of the file named src to the file named
418+ // by dst. The file will be created if it does not already exist. If the
419+ // destination file exists, all it's contents will be replaced by the contents
420+ // of the source file. The file mode will be copied from the source and
421+ // the copied data is synced/flushed to stable storage.
422+ func CopyFile (src , dst string ) (err error ) {
423+ in , err := os .Open (src )
424+ if err != nil {
425+ return
426+ }
427+ defer in .Close ()
428+
429+ out , err := os .Create (dst )
430+ if err != nil {
431+ return
432+ }
433+ defer func () {
434+ if e := out .Close (); e != nil {
435+ err = e
436+ }
437+ }()
438+
439+ _ , err = io .Copy (out , in )
440+ if err != nil {
441+ return
442+ }
443+
444+ err = out .Sync ()
445+ if err != nil {
446+ return
447+ }
448+
449+ si , err := os .Stat (src )
450+ if err != nil {
451+ return
452+ }
453+ err = os .Chmod (dst , si .Mode ())
454+ if err != nil {
455+ return
456+ }
457+
458+ return
459+ }
460+
370461func GetCoreArchivePath (fqbn string ) string {
371462 fqbnToUnderscore := strings .Replace (fqbn , ":" , "_" , - 1 )
372463 fqbnToUnderscore = strings .Replace (fqbnToUnderscore , "=" , "_" , - 1 )
0 commit comments