@@ -614,29 +614,58 @@ func (pme *Explorer) GetTool(toolID string) *cores.Tool {
614
614
}
615
615
}
616
616
617
- // FindToolsRequiredForBoard FIXMEDOC
618
- func (pme * Explorer ) FindToolsRequiredForBoard (board * cores.Board ) ([]* cores.ToolRelease , error ) {
619
- pme .log .Infof ("Searching tools required for board %s" , board )
620
-
621
- // core := board.Properties["build.core"]
622
- platform := board .PlatformRelease
623
-
624
- // maps "PACKAGER:TOOL" => ToolRelease
625
- foundTools := map [string ]* cores.ToolRelease {}
626
-
627
- // a Platform may not specify required tools (because it's a platform that comes from a
628
- // user/hardware dir without a package_index.json) then add all available tools
629
- for _ , targetPackage := range pme .packages {
630
- for _ , tool := range targetPackage .Tools {
631
- rel := tool .GetLatestInstalled ()
632
- if rel != nil {
633
- foundTools [rel .Tool .Name ] = rel
617
+ // FindToolsRequiredForBuild returns the list of ToolReleases needed to build for the specified
618
+ // plaftorm. The buildPlatform may be different depending on the selected board.
619
+ func (pme * Explorer ) FindToolsRequiredForBuild (platform , buildPlatform * cores.PlatformRelease ) ([]* cores.ToolRelease , error ) {
620
+
621
+ // maps tool name => all available ToolRelease
622
+ allToolsAlternatives := map [string ][]* cores.ToolRelease {}
623
+ for _ , tool := range pme .GetAllInstalledToolsReleases () {
624
+ alternatives := allToolsAlternatives [tool .Tool .Name ]
625
+ alternatives = append (alternatives , tool )
626
+ allToolsAlternatives [tool .Tool .Name ] = alternatives
627
+ }
628
+
629
+ // selectBest select the tool with best matching, applying the following rules
630
+ // in order of priority:
631
+ // - the tool comes from the requested packager
632
+ // - the tool comes from the build platform packager
633
+ // - the tool has the greatest version
634
+ // - the tool packager comes first in alphabetic order
635
+ packagerPriority := map [string ]int {}
636
+ packagerPriority [platform .Platform .Package .Name ] = 2
637
+ if buildPlatform != nil {
638
+ packagerPriority [buildPlatform .Platform .Package .Name ] = 1
639
+ }
640
+ selectBest := func (tools []* cores.ToolRelease ) * cores.ToolRelease {
641
+ selected := tools [0 ]
642
+ for _ , tool := range tools [1 :] {
643
+ if packagerPriority [tool .Tool .Package .Name ] != packagerPriority [selected .Tool .Package .Name ] {
644
+ if packagerPriority [tool .Tool .Package .Name ] > packagerPriority [selected .Tool .Package .Name ] {
645
+ selected = tool
646
+ }
647
+ continue
648
+ }
649
+ if ! tool .Version .Equal (selected .Version ) {
650
+ if tool .Version .GreaterThan (selected .Version ) {
651
+ selected = tool
652
+ }
653
+ continue
654
+ }
655
+ if tool .Tool .Package .Name < selected .Tool .Package .Name {
656
+ selected = tool
634
657
}
635
658
}
659
+ return selected
636
660
}
637
661
638
- // replace the default tools above with the specific required by the current platform
662
+ // First select the specific tools required by the current platform
639
663
requiredTools := []* cores.ToolRelease {}
664
+ // The Sorting of the tool dependencies is required because some platforms may depends
665
+ // on more than one version of the same tool. For example adafruit:samd has both
666
+ // [email protected] and [email protected] . To allow the runtime property
667
+ // {runtime.tools.bossac.path} to be correctly set to the 1.8.0 version we must ensure
668
+ // that the returned array is sorted by version.
640
669
platform .ToolDependencies .Sort ()
641
670
for _ , toolDep := range platform .ToolDependencies {
642
671
pme .log .WithField ("tool" , toolDep ).Infof ("Required tool" )
@@ -645,11 +674,15 @@ func (pme *Explorer) FindToolsRequiredForBoard(board *cores.Board) ([]*cores.Too
645
674
return nil , fmt .Errorf (tr ("tool release not found: %s" ), toolDep )
646
675
}
647
676
requiredTools = append (requiredTools , tool )
648
- delete (foundTools , tool .Tool .Name )
677
+ delete (allToolsAlternatives , tool .Tool .Name )
649
678
}
650
679
651
- for _ , toolRel := range foundTools {
652
- requiredTools = append (requiredTools , toolRel )
680
+ // Since a Platform may not specify the required tools (because it's a platform that comes
681
+ // from a user/hardware dir without a package_index.json) then add all available tools giving
682
+ // priority to tools coming from the same packager or referenced packager
683
+ for _ , tools := range allToolsAlternatives {
684
+ tool := selectBest (tools )
685
+ requiredTools = append (requiredTools , tool )
653
686
}
654
687
return requiredTools , nil
655
688
}
0 commit comments