@@ -18,9 +18,13 @@ package packagemanager
1818import (
1919 "fmt"
2020 "net/url"
21+ "os"
2122 "path"
23+ "path/filepath"
24+ "strconv"
2225 "strings"
2326 "sync"
27+ "time"
2428
2529 "github.com/arduino/arduino-cli/arduino/cores"
2630 "github.com/arduino/arduino-cli/arduino/cores/packageindex"
@@ -29,6 +33,7 @@ import (
2933 "github.com/arduino/arduino-cli/i18n"
3034 paths "github.com/arduino/go-paths-helper"
3135 properties "github.com/arduino/go-properties-orderedmap"
36+ "github.com/arduino/go-timeutils"
3237 "github.com/sirupsen/logrus"
3338 semver "go.bug.st/relaxed-semver"
3439)
@@ -275,50 +280,141 @@ func (pme *Explorer) ResolveFQBN(fqbn *cores.FQBN) (
275280 return targetPackage , nil , nil , nil , nil ,
276281 fmt .Errorf (tr ("unknown platform %s:%s" ), targetPackage , fqbn .PlatformArch )
277282 }
278- platformRelease := pme .GetInstalledPlatformRelease (platform )
279- if platformRelease == nil {
283+ boardPlatformRelease := pme .GetInstalledPlatformRelease (platform )
284+ if boardPlatformRelease == nil {
280285 return targetPackage , nil , nil , nil , nil ,
281286 fmt .Errorf (tr ("platform %s is not installed" ), platform )
282287 }
283288
284289 // Find board
285- board := platformRelease .Boards [fqbn .BoardID ]
290+ board := boardPlatformRelease .Boards [fqbn .BoardID ]
286291 if board == nil {
287- return targetPackage , platformRelease , nil , nil , nil ,
292+ return targetPackage , boardPlatformRelease , nil , nil , nil ,
288293 fmt .Errorf (tr ("board %s not found" ), fqbn .StringWithoutConfig ())
289294 }
290295
291- buildProperties , err := board .GetBuildProperties (fqbn .Configs )
296+ boardBuildProperties , err := board .GetBuildProperties (fqbn .Configs )
292297 if err != nil {
293- return targetPackage , platformRelease , board , nil , nil ,
298+ return targetPackage , boardPlatformRelease , board , nil , nil ,
294299 fmt .Errorf (tr ("getting build properties for board %[1]s: %[2]s" ), board , err )
295300 }
296301
297- // Determine the platform used for the build (in case the board refers
302+ // Determine the platform used for the build and the variant (in case the board refers
298303 // to a core contained in another platform)
299- buildPlatformRelease := platformRelease
300- coreParts := strings .Split (buildProperties .Get ("build.core" ), ":" )
301- if len (coreParts ) > 1 {
302- referredPackage := coreParts [0 ]
303- buildPackage := pme .packages [referredPackage ]
304- if buildPackage == nil {
305- return targetPackage , platformRelease , board , buildProperties , nil ,
306- fmt .Errorf (tr ("missing package %[1]s referenced by board %[2]s" ), referredPackage , fqbn )
304+ core , corePlatformRelease , variant , variantPlatformRelease , err := pme .determineReferencedPlatformRelease (boardBuildProperties , boardPlatformRelease , fqbn )
305+ if err != nil {
306+ return targetPackage , boardPlatformRelease , board , nil , nil , err
307+ }
308+
309+ // Create the build properties map by overlaying the properties of the
310+ // referenced platform propeties, the board platform properties and the
311+ // board specific properties.
312+ buildProperties := properties .NewMap ()
313+ buildProperties .Merge (variantPlatformRelease .Properties )
314+ buildProperties .Merge (corePlatformRelease .Properties )
315+ buildProperties .Merge (boardPlatformRelease .Properties )
316+ buildProperties .Merge (boardBuildProperties )
317+
318+ // Add runtime build properties
319+ buildProperties .Merge (boardPlatformRelease .RuntimeProperties ())
320+ buildProperties .SetPath ("build.core.path" , corePlatformRelease .InstallDir .Join ("cores" , core ))
321+ buildProperties .SetPath ("build.system.path" , corePlatformRelease .InstallDir .Join ("system" ))
322+ buildProperties .Set ("build.variant.path" , "" )
323+ if variant != "" {
324+ buildProperties .SetPath ("build.variant.path" , variantPlatformRelease .InstallDir .Join ("variants" , variant ))
325+ }
326+
327+ for _ , tool := range pme .GetAllInstalledToolsReleases () {
328+ buildProperties .Merge (tool .RuntimeProperties ())
329+ }
330+ requiredTools , err := pme .FindToolsRequiredForBuild (boardPlatformRelease , corePlatformRelease )
331+ if err != nil {
332+ return targetPackage , boardPlatformRelease , board , buildProperties , corePlatformRelease , err
333+ }
334+ for _ , tool := range requiredTools {
335+ buildProperties .Merge (tool .RuntimeProperties ())
336+ }
337+ now := time .Now ()
338+ buildProperties .Set ("extra.time.utc" , strconv .FormatInt (now .Unix (), 10 ))
339+ buildProperties .Set ("extra.time.local" , strconv .FormatInt (timeutils .LocalUnix (now ), 10 ))
340+ buildProperties .Set ("extra.time.zone" , strconv .Itoa (timeutils .TimezoneOffsetNoDST (now )))
341+ buildProperties .Set ("extra.time.dst" , strconv .Itoa (timeutils .DaylightSavingsOffset (now )))
342+
343+ if ! buildProperties .ContainsKey ("runtime.ide.path" ) {
344+ if ex , err := os .Executable (); err == nil {
345+ buildProperties .Set ("runtime.ide.path" , filepath .Dir (ex ))
346+ } else {
347+ buildProperties .Set ("runtime.ide.path" , "" )
307348 }
308- buildPlatform := buildPackage .Platforms [fqbn .PlatformArch ]
309- if buildPlatform == nil {
310- return targetPackage , platformRelease , board , buildProperties , nil ,
311- fmt .Errorf (tr ("missing platform %[1]s:%[2]s referenced by board %[3]s" ), referredPackage , fqbn .PlatformArch , fqbn )
349+ }
350+ buildProperties .Set ("runtime.os" , properties .GetOSSuffix ())
351+ buildProperties .Set ("build.library_discovery_phase" , "0" )
352+ // Deprecated properties
353+ buildProperties .Set ("ide_version" , "10607" )
354+ buildProperties .Set ("runtime.ide.version" , "10607" )
355+ if ! buildProperties .ContainsKey ("software" ) {
356+ buildProperties .Set ("software" , "ARDUINO" )
357+ }
358+
359+ buildProperties .Merge (pme .GetCustomGlobalProperties ())
360+
361+ return targetPackage , boardPlatformRelease , board , buildProperties , corePlatformRelease , nil
362+ }
363+
364+ func (pme * Explorer ) determineReferencedPlatformRelease (boardBuildProperties * properties.Map , boardPlatformRelease * cores.PlatformRelease , fqbn * cores.FQBN ) (string , * cores.PlatformRelease , string , * cores.PlatformRelease , error ) {
365+ core := boardBuildProperties .Get ("build.core" )
366+ referredCore := ""
367+ if split := strings .Split (core , ":" ); len (split ) > 1 {
368+ referredCore , core = split [0 ], split [1 ]
369+ }
370+
371+ variant := boardBuildProperties .Get ("build.variant" )
372+ referredVariant := ""
373+ if split := strings .Split (variant , ":" ); len (split ) > 1 {
374+ referredVariant , variant = split [0 ], split [1 ]
375+ }
376+
377+ // core and variant cannot refer to two different platforms
378+ if referredCore != "" && referredVariant != "" && referredCore != referredVariant {
379+ return "" , nil , "" , nil ,
380+ fmt .Errorf (tr ("'build.core' and 'build.variant' refer to different platforms: %[1]s and %[2]s" ), referredCore + ":" + core , referredVariant + ":" + variant )
381+ }
382+
383+ // extract the referred platform
384+ var referredPlatformRelease * cores.PlatformRelease
385+ referredPackageName := referredCore
386+ if referredPackageName == "" {
387+ referredPackageName = referredVariant
388+ }
389+ if referredPackageName != "" {
390+ referredPackage := pme .packages [referredPackageName ]
391+ if referredPackage == nil {
392+ return "" , nil , "" , nil ,
393+ fmt .Errorf (tr ("missing package %[1]s referenced by board %[2]s" ), referredPackageName , fqbn )
394+ }
395+ referredPlatform := referredPackage .Platforms [fqbn .PlatformArch ]
396+ if referredPlatform == nil {
397+ return "" , nil , "" , nil ,
398+ fmt .Errorf (tr ("missing platform %[1]s:%[2]s referenced by board %[3]s" ), referredPackageName , fqbn .PlatformArch , fqbn )
312399 }
313- buildPlatformRelease = pme .GetInstalledPlatformRelease (buildPlatform )
314- if buildPlatformRelease == nil {
315- return targetPackage , platformRelease , board , buildProperties , nil ,
316- fmt .Errorf (tr ("missing platform release %[1]s:%[2]s referenced by board %[3]s" ), referredPackage , fqbn .PlatformArch , fqbn )
400+ referredPlatformRelease = pme .GetInstalledPlatformRelease (referredPlatform )
401+ if referredPlatformRelease == nil {
402+ return "" , nil , "" , nil ,
403+ fmt .Errorf (tr ("missing platform release %[1]s:%[2]s referenced by board %[3]s" ), referredPackageName , fqbn .PlatformArch , fqbn )
317404 }
318405 }
319406
320- // No errors... phew!
321- return targetPackage , platformRelease , board , buildProperties , buildPlatformRelease , nil
407+ corePlatformRelease := boardPlatformRelease
408+ if referredCore != "" {
409+ corePlatformRelease = referredPlatformRelease
410+ }
411+
412+ variantPlatformRelease := boardPlatformRelease
413+ if referredVariant != "" {
414+ variantPlatformRelease = referredPlatformRelease
415+ }
416+
417+ return core , corePlatformRelease , variant , variantPlatformRelease , nil
322418}
323419
324420// LoadPackageIndex loads a package index by looking up the local cached file from the specified URL
0 commit comments