@@ -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,36 @@ 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+ fmt .Println (sources )
146+
147+ return sources , nil
148+ }
149+
119150func 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 ) {
120151 for _ , source := range sources {
121152 objectFile , err := compileFileWithRecipe (sourcePath , source , buildPath , buildProperties , includes , recipe , verbose , warningsLevel , logger )
@@ -258,6 +289,24 @@ func nonEmptyString(s string) bool {
258289 return s != constants .EMPTY_STRING
259290}
260291
292+ func CheckIfRecompileIsAvoidable (corePath string , archiveFile string ) bool {
293+ archiveFileStat , err := os .Stat (archiveFile )
294+ if err == nil {
295+ files , err := findAllFilesInFolder (corePath , true )
296+ if err != nil {
297+ return false
298+ }
299+ for _ , file := range files {
300+ fileStat , err := os .Stat (file )
301+ if err != nil || fileStat .ModTime ().After (archiveFileStat .ModTime ()) {
302+ return false
303+ }
304+ }
305+ return true
306+ }
307+ return false
308+ }
309+
261310func ArchiveCompiledFiles (buildPath string , archiveFile string , objectFiles []string , buildProperties properties.Map , verbose bool , logger i18n.Logger ) (string , error ) {
262311 archiveFilePath := filepath .Join (buildPath , archiveFile )
263312
@@ -366,3 +415,67 @@ func ExecRecipeCollectStdErr(buildProperties properties.Map, recipe string, remo
366415func RemoveHyphenMDDFlagFromGCCCommandLine (buildProperties properties.Map ) {
367416 buildProperties [constants .BUILD_PROPERTIES_COMPILER_CPP_FLAGS ] = strings .Replace (buildProperties [constants .BUILD_PROPERTIES_COMPILER_CPP_FLAGS ], "-MMD" , "" , - 1 )
368417}
418+
419+ // CopyFile copies a file from src to dst. If src and dst files exist, and are
420+ // the same, then return success. Otherise, attempt to create a hard link
421+ // between the two files. If that fail, copy the file contents from src to dst.
422+ func CopyFile (src , dst string ) (err error ) {
423+ sfi , err := os .Stat (src )
424+ if err != nil {
425+ return
426+ }
427+ if ! sfi .Mode ().IsRegular () {
428+ // cannot copy non-regular files (e.g., directories,
429+ // symlinks, devices, etc.)
430+ return fmt .Errorf ("CopyFile: non-regular source file %s (%q)" , sfi .Name (), sfi .Mode ().String ())
431+ }
432+ dfi , err := os .Stat (dst )
433+ if err != nil {
434+ if ! os .IsNotExist (err ) {
435+ return
436+ }
437+ } else {
438+ if ! (dfi .Mode ().IsRegular ()) {
439+ return fmt .Errorf ("CopyFile: non-regular destination file %s (%q)" , dfi .Name (), dfi .Mode ().String ())
440+ }
441+ if os .SameFile (sfi , dfi ) {
442+ return
443+ }
444+ }
445+ if err = os .Link (src , dst ); err == nil {
446+ return
447+ }
448+ err = copyFileContents (src , dst )
449+ return
450+ }
451+
452+ // copyFileContents copies the contents of the file named src to the file named
453+ // by dst. The file will be created if it does not already exist. If the
454+ // destination file exists, all it's contents will be replaced by the contents
455+ // of the source file.
456+ func copyFileContents (src , dst string ) (err error ) {
457+ in , err := os .Open (src )
458+ if err != nil {
459+ return
460+ }
461+ defer in .Close ()
462+ out , err := os .Create (dst )
463+ if err != nil {
464+ return
465+ }
466+ defer func () {
467+ cerr := out .Close ()
468+ if err == nil {
469+ err = cerr
470+ }
471+ }()
472+ if _ , err = io .Copy (out , in ); err != nil {
473+ return
474+ }
475+ err = out .Sync ()
476+ return
477+ }
478+
479+ func GetCoreArchivePath (fqbnToUnderscore string ) string {
480+ return os .TempDir () + "/core_" + fqbnToUnderscore + ".a"
481+ }
0 commit comments