Skip to content

Commit ef63c62

Browse files
matthijskooijmancmaglie
authored andcommitted
Fix handling of referenced cores (#467)
* Add tests for ResolveFQBN This adds tests for ResolveFQBN (which returns more details than the FindBoardWithFQBN that was already tested), but also adds an extra boards.txt with boards that are derived from another platform/core (i.e. have `build.core=package:core`. These new tests are currently failing, because of a bug and insufficient error handling, which will be fixed in subsequent commits. * Fix resolution of referenced cores A core is referenced by specifying `build.core=package:core` in board properties. However, the code used the second part (core) both for looking up the the package, as well as for the core to use from that package. The most commonly used core reference is `arduino:arduino` which works because both parts are identical, which is probably why this bug has not shown up before. This commit fixes the bug by simply using the right part to look up the package. * Improve error message when referencing missing package This used to say e.g. missing platform adafruit:referenced:avr required for build where two packagenames (adafruit and referenced) were joined together which makes no sense. Now, it just mentions the missing package, and the fqbn that references it. * Fix segfault when referenced platform is missing Before, when a platform was referenced through a `build.core` and the package was present by the platform/architecure was missing, a nullpointer was passed to GetInstalledPlatformRelease, which would segfault. Now, a proper error message is returned.
1 parent 292277f commit ef63c62

File tree

4 files changed

+196
-2
lines changed

4 files changed

+196
-2
lines changed

Diff for: arduino/cores/packagemanager/package_manager.go

+6-2
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,17 @@ func (pm *PackageManager) ResolveFQBN(fqbn *cores.FQBN) (
177177
buildPlatformRelease := platformRelease
178178
coreParts := strings.Split(buildProperties.Get("build.core"), ":")
179179
if len(coreParts) > 1 {
180-
referredPackage := coreParts[1]
180+
referredPackage := coreParts[0]
181181
buildPackage := pm.Packages[referredPackage]
182182
if buildPackage == nil {
183183
return targetPackage, platformRelease, board, buildProperties, nil,
184-
fmt.Errorf("missing package %s:%s required for build", referredPackage, platform)
184+
fmt.Errorf("missing package %s referenced by board %s", referredPackage, fqbn)
185185
}
186186
buildPlatform := buildPackage.Platforms[fqbn.PlatformArch]
187+
if buildPlatform == nil {
188+
return targetPackage, platformRelease, board, buildProperties, nil,
189+
fmt.Errorf("missing platform %s:%s referenced by board %s", referredPackage, fqbn.PlatformArch, fqbn)
190+
}
187191
buildPlatformRelease = pm.GetInstalledPlatformRelease(buildPlatform)
188192
}
189193

Diff for: arduino/cores/packagemanager/package_manager_test.go

+125
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ import (
3333
var customHardware = paths.New("testdata", "custom_hardware")
3434
var dataDir1 = paths.New("testdata", "data_dir_1")
3535

36+
// Intended to be used alongside dataDir1
37+
var extraHardware = paths.New("testdata", "extra_hardware")
38+
3639
func TestFindBoardWithFQBN(t *testing.T) {
3740
pm := packagemanager.NewPackageManager(customHardware, customHardware, customHardware, customHardware)
3841
pm.LoadHardwareFromDirectory(customHardware)
@@ -48,6 +51,128 @@ func TestFindBoardWithFQBN(t *testing.T) {
4851
require.Equal(t, board.Name(), "Arduino/Genuino Mega or Mega 2560")
4952
}
5053

54+
func TestResolveFQBN(t *testing.T) {
55+
// Pass nil, since these paths are only used for installing
56+
pm := packagemanager.NewPackageManager(nil, nil, nil, nil)
57+
// Hardware from main packages directory
58+
pm.LoadHardwareFromDirectory(dataDir1.Join("packages"))
59+
// This contains the arduino:avr core
60+
pm.LoadHardwareFromDirectory(customHardware)
61+
// This contains the referenced:avr core
62+
pm.LoadHardwareFromDirectory(extraHardware)
63+
64+
fqbn, err := cores.ParseFQBN("arduino:avr:uno")
65+
require.Nil(t, err)
66+
require.NotNil(t, fqbn)
67+
pkg, platformRelease, board, props, buildPlatformRelease, err := pm.ResolveFQBN(fqbn)
68+
require.Nil(t, err)
69+
require.Equal(t, pkg, platformRelease.Platform.Package)
70+
require.NotNil(t, platformRelease)
71+
require.NotNil(t, platformRelease.Platform)
72+
require.Equal(t, platformRelease.Platform.String(), "arduino:avr")
73+
require.NotNil(t, board)
74+
require.Equal(t, board.Name(), "Arduino/Genuino Uno")
75+
require.NotNil(t, props)
76+
require.Equal(t, platformRelease, buildPlatformRelease)
77+
78+
fqbn, err = cores.ParseFQBN("arduino:avr:mega")
79+
require.Nil(t, err)
80+
require.NotNil(t, fqbn)
81+
pkg, platformRelease, board, props, buildPlatformRelease, err = pm.ResolveFQBN(fqbn)
82+
require.Nil(t, err)
83+
require.Equal(t, pkg, platformRelease.Platform.Package)
84+
require.NotNil(t, platformRelease)
85+
require.NotNil(t, platformRelease.Platform)
86+
require.Equal(t, platformRelease.Platform.String(), "arduino:avr")
87+
require.NotNil(t, board)
88+
require.Equal(t, board.Name(), "Arduino/Genuino Mega or Mega 2560")
89+
require.NotNil(t, props)
90+
require.Equal(t, platformRelease, buildPlatformRelease)
91+
92+
// Test a board referenced from the main AVR arduino platform
93+
fqbn, err = cores.ParseFQBN("referenced:avr:uno")
94+
require.Nil(t, err)
95+
require.NotNil(t, fqbn)
96+
pkg, platformRelease, board, props, buildPlatformRelease, err = pm.ResolveFQBN(fqbn)
97+
require.Nil(t, err)
98+
require.Equal(t, pkg, platformRelease.Platform.Package)
99+
require.NotNil(t, platformRelease)
100+
require.NotNil(t, platformRelease.Platform)
101+
require.Equal(t, platformRelease.Platform.String(), "referenced:avr")
102+
require.NotNil(t, board)
103+
require.Equal(t, board.Name(), "Referenced Uno")
104+
require.NotNil(t, props)
105+
require.NotNil(t, buildPlatformRelease)
106+
require.NotNil(t, buildPlatformRelease.Platform)
107+
require.Equal(t, buildPlatformRelease.Platform.String(), "arduino:avr")
108+
109+
// Test a board referenced from the Adafruit SAMD core (this tests
110+
// deriving where the package and core name are different)
111+
fqbn, err = cores.ParseFQBN("referenced:samd:feather_m0")
112+
require.Nil(t, err)
113+
require.NotNil(t, fqbn)
114+
pkg, platformRelease, board, props, buildPlatformRelease, err = pm.ResolveFQBN(fqbn)
115+
require.Nil(t, err)
116+
require.Equal(t, pkg, platformRelease.Platform.Package)
117+
require.NotNil(t, platformRelease)
118+
require.NotNil(t, platformRelease.Platform)
119+
require.Equal(t, platformRelease.Platform.String(), "referenced:samd")
120+
require.NotNil(t, board)
121+
require.Equal(t, board.Name(), "Referenced Feather M0")
122+
require.NotNil(t, props)
123+
require.NotNil(t, buildPlatformRelease)
124+
require.NotNil(t, buildPlatformRelease.Platform)
125+
require.Equal(t, buildPlatformRelease.Platform.String(), "adafruit:samd")
126+
127+
// Test a board referenced from a non-existent package
128+
fqbn, err = cores.ParseFQBN("referenced:avr:dummy_invalid_package")
129+
require.Nil(t, err)
130+
require.NotNil(t, fqbn)
131+
pkg, platformRelease, board, props, buildPlatformRelease, err = pm.ResolveFQBN(fqbn)
132+
require.NotNil(t, err)
133+
require.Equal(t, pkg, platformRelease.Platform.Package)
134+
require.NotNil(t, platformRelease)
135+
require.NotNil(t, platformRelease.Platform)
136+
require.Equal(t, platformRelease.Platform.String(), "referenced:avr")
137+
require.NotNil(t, board)
138+
require.Equal(t, board.Name(), "Referenced dummy with invalid package")
139+
require.NotNil(t, props)
140+
require.Nil(t, buildPlatformRelease)
141+
142+
// Test a board referenced from a non-existent platform/architecture
143+
fqbn, err = cores.ParseFQBN("referenced:avr:dummy_invalid_platform")
144+
require.Nil(t, err)
145+
require.NotNil(t, fqbn)
146+
pkg, platformRelease, board, props, buildPlatformRelease, err = pm.ResolveFQBN(fqbn)
147+
require.NotNil(t, err)
148+
require.Equal(t, pkg, platformRelease.Platform.Package)
149+
require.NotNil(t, platformRelease)
150+
require.NotNil(t, platformRelease.Platform)
151+
require.Equal(t, platformRelease.Platform.String(), "referenced:avr")
152+
require.NotNil(t, board)
153+
require.Equal(t, board.Name(), "Referenced dummy with invalid platform")
154+
require.NotNil(t, props)
155+
require.Nil(t, buildPlatformRelease)
156+
157+
// Test a board referenced from a non-existent core
158+
// Note that ResolveFQBN does not actually check this currently
159+
fqbn, err = cores.ParseFQBN("referenced:avr:dummy_invalid_core")
160+
require.Nil(t, err)
161+
require.NotNil(t, fqbn)
162+
pkg, platformRelease, board, props, buildPlatformRelease, err = pm.ResolveFQBN(fqbn)
163+
require.Nil(t, err)
164+
require.Equal(t, pkg, platformRelease.Platform.Package)
165+
require.NotNil(t, platformRelease)
166+
require.NotNil(t, platformRelease.Platform)
167+
require.Equal(t, platformRelease.Platform.String(), "referenced:avr")
168+
require.NotNil(t, board)
169+
require.Equal(t, board.Name(), "Referenced dummy with invalid core")
170+
require.NotNil(t, props)
171+
require.NotNil(t, buildPlatformRelease)
172+
require.NotNil(t, buildPlatformRelease.Platform)
173+
require.Equal(t, buildPlatformRelease.Platform.String(), "arduino:avr")
174+
}
175+
51176
func TestBoardOptionsFunctions(t *testing.T) {
52177
pm := packagemanager.NewPackageManager(customHardware, customHardware, customHardware, customHardware)
53178
pm.LoadHardwareFromDirectory(customHardware)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
# Dummy board that is pretty much identical to the Uno, but defined in a
2+
# different package (to test using a core from a different package where
3+
# the package name and core name are the same).
4+
uno.name=Referenced Uno
5+
6+
uno.upload.tool=avrdude
7+
uno.upload.protocol=arduino
8+
uno.upload.maximum_size=32256
9+
uno.upload.maximum_data_size=2048
10+
uno.upload.speed=115200
11+
12+
uno.bootloader.tool=avrdude
13+
uno.bootloader.low_fuses=0xFF
14+
uno.bootloader.high_fuses=0xDE
15+
uno.bootloader.extended_fuses=0xFD
16+
uno.bootloader.unlock_bits=0x3F
17+
uno.bootloader.lock_bits=0x0F
18+
uno.bootloader.file=optiboot/optiboot_atmega328.hex
19+
20+
uno.build.mcu=atmega328p
21+
uno.build.f_cpu=16000000L
22+
uno.build.board=AVR_UNO
23+
uno.build.core=arduino:arduino
24+
uno.build.variant=standard
25+
26+
# Dummy board derived from a non-existent package
27+
dummy_invalid_package.name=Referenced dummy with invalid package
28+
dummy_invalid_package.build.core=nonexistent:arduino
29+
30+
# Dummy board derived from a non-existent core
31+
dummy_invalid_core.name=Referenced dummy with invalid core
32+
dummy_invalid_core.build.core=arduino:nonexistent
33+
34+
# Dummy board derived from a non-existent platform/architecture. The
35+
# platform is avr, which is implied by the directory this file is in. The
36+
# adafruit package in this test data only supplies a samd platform.
37+
dummy_invalid_platform.name=Referenced dummy with invalid platform
38+
dummy_invalid_platform.build.core=adafruit:arduino
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Dummy board that is pretty much identical to the feather m0, but
2+
# defined in a different package (to test using a core from a different
3+
# package where the package name and core name are different).
4+
feather_m0.name=Referenced Feather M0
5+
feather_m0.upload.tool=bossac
6+
feather_m0.upload.protocol=sam-ba
7+
feather_m0.upload.maximum_size=262144
8+
feather_m0.upload.offset=0x2000
9+
feather_m0.upload.use_1200bps_touch=true
10+
feather_m0.upload.wait_for_upload_port=true
11+
feather_m0.upload.native_usb=true
12+
feather_m0.build.mcu=cortex-m0plus
13+
feather_m0.build.f_cpu=48000000L
14+
feather_m0.build.usb_product="Feather M0"
15+
feather_m0.build.usb_manufacturer="Adafruit"
16+
feather_m0.build.board=SAMD_ZERO
17+
feather_m0.build.core=adafruit:arduino
18+
feather_m0.build.extra_flags=-DARDUINO_SAMD_ZERO -DARM_MATH_CM0PLUS -DADAFRUIT_FEATHER_M0 -D__SAMD21G18A__ {build.usb_flags}
19+
feather_m0.build.ldscript=linker_scripts/gcc/flash_with_bootloader.ld
20+
feather_m0.build.openocdscript=openocd_scripts/feather_m0.cfg
21+
feather_m0.build.variant=feather_m0
22+
feather_m0.build.variant_system_lib=
23+
feather_m0.build.vid=0x239A
24+
feather_m0.build.pid=0x800B
25+
feather_m0.bootloader.tool=openocd
26+
feather_m0.bootloader.file=featherM0/bootloader-feather_m0-v2.0.0-adafruit.5.bin
27+

0 commit comments

Comments
 (0)