Skip to content

Commit

Permalink
Implemented --show-properties in board details command (#2151)
Browse files Browse the repository at this point in the history
* Renaming some variables for clarity

* Moved 'build.board' property generation out of legacy package

* Moved unit tests related to build properties out of legacy package

* Removed legacy TargetBoardResolver and refactored unit-tests

* Removed legacy HardwareLoader

* Factored sketch-related build properties creation

* Moved SetupBuildProperties into proper package

* Removed SetCustomBuildProperties from legacy

* Factored --show-properties cli flag parser

* Made 'board ...' command arguments variables local

* Implemented --show-properties in 'board details'

* Fixed integration test
  • Loading branch information
cmaglie authored Apr 19, 2023
1 parent bfb5f3f commit 7b774e1
Show file tree
Hide file tree
Showing 50 changed files with 2,743 additions and 1,730 deletions.
27 changes: 27 additions & 0 deletions arduino/builder/sketch.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/arduino/arduino-cli/arduino/sketch"
"github.com/arduino/arduino-cli/i18n"
"github.com/arduino/go-paths-helper"
"github.com/arduino/go-properties-orderedmap"

"github.com/pkg/errors"
)
Expand Down Expand Up @@ -169,3 +170,29 @@ func writeIfDifferent(source []byte, destPath *paths.Path) error {
// Source and destination are the same, don't write anything
return nil
}

// SetupBuildProperties adds the build properties related to the sketch to the
// default board build properties map.
func SetupBuildProperties(boardBuildProperties *properties.Map, buildPath *paths.Path, sketch *sketch.Sketch, optimizeForDebug bool) *properties.Map {
buildProperties := properties.NewMap()
buildProperties.Merge(boardBuildProperties)

if buildPath != nil {
buildProperties.SetPath("build.path", buildPath)
}
if sketch != nil {
buildProperties.Set("build.project_name", sketch.MainFile.Base())
buildProperties.SetPath("build.source.path", sketch.FullPath)
}
if optimizeForDebug {
if debugFlags, ok := buildProperties.GetOk("compiler.optimization_flags.debug"); ok {
buildProperties.Set("compiler.optimization_flags", debugFlags)
}
} else {
if releaseFlags, ok := buildProperties.GetOk("compiler.optimization_flags.release"); ok {
buildProperties.Set("compiler.optimization_flags", releaseFlags)
}
}

return buildProperties
}
7 changes: 7 additions & 0 deletions arduino/cores/packagemanager/package_manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,13 @@ func (pme *Explorer) ResolveFQBN(fqbn *cores.FQBN) (
}
buildProperties.Set("runtime.os", properties.GetOSSuffix())
buildProperties.Set("build.library_discovery_phase", "0")

if buildProperties.Get("build.board") == "" {
architecture := board.PlatformRelease.Platform.Architecture
defaultBuildBoard := strings.ToUpper(architecture + "_" + board.BoardID)
buildProperties.Set("build.board", defaultBuildBoard)
}

// Deprecated properties
buildProperties.Set("tools.avrdude.path", "{runtime.tools.avrdude.path}")
buildProperties.Set("ide_version", "10607")
Expand Down
155 changes: 139 additions & 16 deletions arduino/cores/packagemanager/package_manager_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ func TestResolveFQBN(t *testing.T) {
pme, release := pm.NewExplorer()
defer release()

{
t.Run("NormalizeFQBN", func(t *testing.T) {
testNormalization := func(in, expected string) {
fqbn, err := cores.ParseFQBN(in)
require.Nil(t, err)
Expand All @@ -89,9 +89,9 @@ func TestResolveFQBN(t *testing.T) {
testNormalization("esp8266:esp8266:generic:baud=115200,wipe=sdk", "esp8266:esp8266:generic:wipe=sdk")
testNormalization("arduino:avr:mega:cpu=nonexistent", "ERROR")
testNormalization("arduino:avr:mega:nonexistent=blah", "ERROR")
}
})

{
t.Run("BoardAndBuildPropertiesArduinoUno", func(t *testing.T) {
fqbn, err := cores.ParseFQBN("arduino:avr:uno")
require.Nil(t, err)
require.NotNil(t, fqbn)
Expand All @@ -105,9 +105,14 @@ func TestResolveFQBN(t *testing.T) {
require.Equal(t, board.Name(), "Arduino Uno")
require.NotNil(t, props)
require.Equal(t, platformRelease, buildPlatformRelease)
}

{
require.Equal(t, "arduino", pkg.Name)
require.Equal(t, "avr", platformRelease.Platform.Architecture)
require.Equal(t, "uno", board.BoardID)
require.Equal(t, "atmega328p", props.Get("build.mcu"))
})

t.Run("BoardAndBuildPropertiesArduinoMega", func(t *testing.T) {
fqbn, err := cores.ParseFQBN("arduino:avr:mega")
require.Nil(t, err)
require.NotNil(t, fqbn)
Expand All @@ -121,9 +126,46 @@ func TestResolveFQBN(t *testing.T) {
require.Equal(t, board.Name(), "Arduino Mega or Mega 2560")
require.NotNil(t, props)
require.Equal(t, platformRelease, buildPlatformRelease)
}
})

{
t.Run("BoardAndBuildPropertiesArduinoMegaWithNonDefaultCpuOption", func(t *testing.T) {
fqbn, err := cores.ParseFQBN("arduino:avr:mega:cpu=atmega1280")
require.Nil(t, err)
require.NotNil(t, fqbn)
pkg, platformRelease, board, props, buildPlatformRelease, err := pme.ResolveFQBN(fqbn)
require.Nil(t, err)
require.Equal(t, pkg, platformRelease.Platform.Package)
require.NotNil(t, platformRelease)
require.NotNil(t, platformRelease.Platform)
require.Equal(t, platformRelease, buildPlatformRelease)

require.Equal(t, "arduino", pkg.Name)
require.Equal(t, "avr", platformRelease.Platform.Architecture)
require.Equal(t, "mega", board.BoardID)
require.Equal(t, "atmega1280", props.Get("build.mcu"))
require.Equal(t, "AVR_MEGA", props.Get("build.board"))
})

t.Run("BoardAndBuildPropertiesArduinoMegaWithDefaultCpuOption", func(t *testing.T) {
fqbn, err := cores.ParseFQBN("arduino:avr:mega:cpu=atmega2560")
require.Nil(t, err)
require.NotNil(t, fqbn)
pkg, platformRelease, board, props, buildPlatformRelease, err := pme.ResolveFQBN(fqbn)
require.Nil(t, err)
require.Equal(t, pkg, platformRelease.Platform.Package)
require.NotNil(t, platformRelease)
require.NotNil(t, platformRelease.Platform)
require.Equal(t, platformRelease, buildPlatformRelease)

require.Equal(t, "arduino", pkg.Name)
require.Equal(t, "avr", platformRelease.Platform.Architecture)
require.Equal(t, "mega", board.BoardID)
require.Equal(t, "atmega2560", props.Get("build.mcu"))
require.Equal(t, "AVR_MEGA2560", props.Get("build.board"))

})

t.Run("BoardAndBuildPropertiesForReferencedArduinoUno", func(t *testing.T) {
// Test a board referenced from the main AVR arduino platform
fqbn, err := cores.ParseFQBN("referenced:avr:uno")
require.Nil(t, err)
Expand All @@ -140,9 +182,56 @@ func TestResolveFQBN(t *testing.T) {
require.NotNil(t, buildPlatformRelease)
require.NotNil(t, buildPlatformRelease.Platform)
require.Equal(t, buildPlatformRelease.Platform.String(), "arduino:avr")
}
})

{
t.Run("BoardAndBuildPropertiesForArduinoDue", func(t *testing.T) {
fqbn, err := cores.ParseFQBN("arduino:sam:arduino_due_x")
require.Nil(t, err)
require.NotNil(t, fqbn)
pkg, platformRelease, board, props, buildPlatformRelease, err := pme.ResolveFQBN(fqbn)
require.Nil(t, err)
require.Equal(t, pkg, platformRelease.Platform.Package)
require.Equal(t, platformRelease, buildPlatformRelease)

require.Equal(t, "arduino", pkg.Name)
require.Equal(t, "sam", platformRelease.Platform.Architecture)
require.Equal(t, "arduino_due_x", board.BoardID)
require.Equal(t, "cortex-m3", props.Get("build.mcu"))
})

t.Run("BoardAndBuildPropertiesForCustomArduinoYun", func(t *testing.T) {
fqbn, err := cores.ParseFQBN("my_avr_platform:avr:custom_yun")
require.Nil(t, err)
require.NotNil(t, fqbn)
pkg, platformRelease, board, props, buildPlatformRelease, err := pme.ResolveFQBN(fqbn)
require.Nil(t, err)
require.Equal(t, pkg, platformRelease.Platform.Package)
require.NotEqual(t, platformRelease, buildPlatformRelease)

require.Equal(t, "my_avr_platform", pkg.Name)
require.Equal(t, "avr", platformRelease.Platform.Architecture)
require.Equal(t, "custom_yun", board.BoardID)
require.Equal(t, "atmega32u4", props.Get("build.mcu"))
require.Equal(t, "AVR_YUN", props.Get("build.board"))
})

t.Run("BoardAndBuildPropertiesForWatterotCore", func(t *testing.T) {
fqbn, err := cores.ParseFQBN("watterott:avr:attiny841:core=spencekonde,info=info")
require.Nil(t, err)
require.NotNil(t, fqbn)
pkg, platformRelease, board, props, buildPlatformRelease, err := pme.ResolveFQBN(fqbn)
require.Nil(t, err)
require.Equal(t, pkg, platformRelease.Platform.Package)
require.Equal(t, platformRelease, buildPlatformRelease)

require.Equal(t, "watterott", pkg.Name)
require.Equal(t, "avr", platformRelease.Platform.Architecture)
require.Equal(t, "attiny841", board.BoardID)
require.Equal(t, "tiny841", props.Get("build.core"))
require.Equal(t, "tiny14", props.Get("build.variant"))
})

t.Run("BoardAndBuildPropertiesForReferencedFeatherM0", func(t *testing.T) {
// Test a board referenced from the Adafruit SAMD core (this tests
// deriving where the package and core name are different)
fqbn, err := cores.ParseFQBN("referenced:samd:feather_m0")
Expand All @@ -160,9 +249,9 @@ func TestResolveFQBN(t *testing.T) {
require.NotNil(t, buildPlatformRelease)
require.NotNil(t, buildPlatformRelease.Platform)
require.Equal(t, buildPlatformRelease.Platform.String(), "adafruit:samd")
}
})

{
t.Run("BoardAndBuildPropertiesForNonExistentPackage", func(t *testing.T) {
// Test a board referenced from a non-existent package
fqbn, err := cores.ParseFQBN("referenced:avr:dummy_invalid_package")
require.Nil(t, err)
Expand All @@ -177,9 +266,9 @@ func TestResolveFQBN(t *testing.T) {
require.Equal(t, board.Name(), "Referenced dummy with invalid package")
require.Nil(t, props)
require.Nil(t, buildPlatformRelease)
}
})

{
t.Run("BoardAndBuildPropertiesForNonExistentArchitecture", func(t *testing.T) {
// Test a board referenced from a non-existent platform/architecture
fqbn, err := cores.ParseFQBN("referenced:avr:dummy_invalid_platform")
require.Nil(t, err)
Expand All @@ -194,9 +283,9 @@ func TestResolveFQBN(t *testing.T) {
require.Equal(t, board.Name(), "Referenced dummy with invalid platform")
require.Nil(t, props)
require.Nil(t, buildPlatformRelease)
}
})

{
t.Run("BoardAndBuildPropertiesForNonExistentCore", func(t *testing.T) {
// Test a board referenced from a non-existent core
// Note that ResolveFQBN does not actually check this currently
fqbn, err := cores.ParseFQBN("referenced:avr:dummy_invalid_core")
Expand All @@ -214,7 +303,41 @@ func TestResolveFQBN(t *testing.T) {
require.NotNil(t, buildPlatformRelease)
require.NotNil(t, buildPlatformRelease.Platform)
require.Equal(t, buildPlatformRelease.Platform.String(), "arduino:avr")
}
})

t.Run("AddBuildBoardPropertyIfMissing", func(t *testing.T) {
fqbn, err := cores.ParseFQBN("my_avr_platform:avr:mymega")
require.Nil(t, err)
require.NotNil(t, fqbn)
pkg, platformRelease, board, props, buildPlatformRelease, err := pme.ResolveFQBN(fqbn)
require.Nil(t, err)
require.Equal(t, pkg, platformRelease.Platform.Package)
require.Equal(t, platformRelease, buildPlatformRelease)

require.Equal(t, "my_avr_platform", pkg.Name)
require.NotNil(t, platformRelease)
require.NotNil(t, platformRelease.Platform)
require.Equal(t, "avr", platformRelease.Platform.Architecture)
require.Equal(t, "mymega", board.BoardID)
require.Equal(t, "atmega2560", props.Get("build.mcu"))
require.Equal(t, "AVR_MYMEGA", props.Get("build.board"))
})

t.Run("AddBuildBoardPropertyIfNotMissing", func(t *testing.T) {
fqbn, err := cores.ParseFQBN("my_avr_platform:avr:mymega:cpu=atmega1280")
require.Nil(t, err)
require.NotNil(t, fqbn)
pkg, platformRelease, board, props, buildPlatformRelease, err := pme.ResolveFQBN(fqbn)
require.Nil(t, err)
require.Equal(t, pkg, platformRelease.Platform.Package)
require.Equal(t, platformRelease, buildPlatformRelease)

require.Equal(t, "my_avr_platform", pkg.Name)
require.Equal(t, "avr", platformRelease.Platform.Architecture)
require.Equal(t, "mymega", board.BoardID)
require.Equal(t, "atmega1280", props.Get("build.mcu"))
require.Equal(t, "MYMEGA1280", props.Get("build.board"))
})
}

func TestBoardOptionsFunctions(t *testing.T) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@

arduino_due_x_dbg.name=Arduino Due (Programming Port)
arduino_due_x_dbg.vid.0=0x2341
arduino_due_x_dbg.pid.0=0x003d
arduino_due_x_dbg.vid.1=0x2A03
arduino_due_x_dbg.pid.1=0x003d
arduino_due_x_dbg.upload.tool=bossac
arduino_due_x_dbg.upload.protocol=sam-ba
arduino_due_x_dbg.upload.maximum_size=524288
arduino_due_x_dbg.upload.use_1200bps_touch=true
arduino_due_x_dbg.upload.wait_for_upload_port=false
arduino_due_x_dbg.upload.native_usb=false
arduino_due_x_dbg.build.mcu=cortex-m3
arduino_due_x_dbg.build.f_cpu=84000000L
arduino_due_x_dbg.build.usb_manufacturer="Arduino LLC"
arduino_due_x_dbg.build.usb_product="Arduino Due"
arduino_due_x_dbg.build.board=SAM_DUE
arduino_due_x_dbg.build.core=arduino
arduino_due_x_dbg.build.extra_flags=-D__SAM3X8E__ -mthumb {build.usb_flags}
arduino_due_x_dbg.build.ldscript=linker_scripts/gcc/flash.ld
arduino_due_x_dbg.build.variant=arduino_due_x
arduino_due_x_dbg.build.variant_system_lib=libsam_sam3x8e_gcc_rel.a
arduino_due_x_dbg.build.vid=0x2341
arduino_due_x_dbg.build.pid=0x003e

arduino_due_x.name=Arduino Due (Native USB Port)
arduino_due_x.vid.0=0x2341
arduino_due_x.pid.0=0x003e
arduino_due_x.vid.1=0x2A03
arduino_due_x.pid.1=0x003e
arduino_due_x.upload.tool=bossac
arduino_due_x.upload.protocol=sam-ba
arduino_due_x.upload.maximum_size=524288
arduino_due_x.upload.use_1200bps_touch=true
arduino_due_x.upload.wait_for_upload_port=true
arduino_due_x.upload.native_usb=true
arduino_due_x.build.mcu=cortex-m3
arduino_due_x.build.f_cpu=84000000L
arduino_due_x.build.usb_manufacturer="Arduino LLC"
arduino_due_x.build.usb_product="Arduino Due"
arduino_due_x.build.board=SAM_DUE
arduino_due_x.build.core=arduino
arduino_due_x.build.extra_flags=-D__SAM3X8E__ -mthumb {build.usb_flags}
arduino_due_x.build.ldscript=linker_scripts/gcc/flash.ld
arduino_due_x.build.variant=arduino_due_x
arduino_due_x.build.variant_system_lib=libsam_sam3x8e_gcc_rel.a
arduino_due_x.build.vid=0x2341
arduino_due_x.build.pid=0x003e

Loading

0 comments on commit 7b774e1

Please sign in to comment.