mirror of
https://github.com/tinygo-org/tinygo.git
synced 2026-07-26 06:38:42 +00:00
feat: add inheritable-only field to filter processor-level targets (#5270)
* feat: add inheritable-only field to hide processor-level targets from listing Processor-level targets like esp32, rp2040, etc. have flash-method set so they leak through the existing heuristic filter in GetTargetSpecs and appear in `tinygo targets` output. Add an "inheritable-only" JSON field that is checked on raw JSON before inheritance resolution, preventing these non-board targets from being listed while keeping them loadable for direct builds and inheritance. Ref: tinygo-org/tinygo#5178 * fix: prevent inheritable-only from propagating to child targets The InheritableOnly bool field was propagating from parent to child targets through overrideProperties, which would hide board targets from GetTargetSpecs. Fix by preserving/restoring the field across resolveInherits. Also simplify GetTargetSpecs by removing the raw JSON pre-check workaround and remove nonexistent esp32c6 from tests. * prevent build commands to use inheritable only targets
This commit is contained in:
committed by
deadprogram
parent
f176b3a480
commit
410bb9c103
@@ -24,6 +24,7 @@ import (
|
|||||||
// https://github.com/shepmaster/rust-arduino-blink-led-no-core-with-cargo/blob/master/blink/arduino.json
|
// https://github.com/shepmaster/rust-arduino-blink-led-no-core-with-cargo/blob/master/blink/arduino.json
|
||||||
type TargetSpec struct {
|
type TargetSpec struct {
|
||||||
Inherits []string `json:"inherits,omitempty"`
|
Inherits []string `json:"inherits,omitempty"`
|
||||||
|
InheritableOnly bool `json:"inheritable-only"` // this target is only meant to be inherited from, not used directly
|
||||||
Triple string `json:"llvm-target,omitempty"`
|
Triple string `json:"llvm-target,omitempty"`
|
||||||
CPU string `json:"cpu,omitempty"`
|
CPU string `json:"cpu,omitempty"`
|
||||||
ABI string `json:"target-abi,omitempty"` // roughly equivalent to -mabi= flag
|
ABI string `json:"target-abi,omitempty"` // roughly equivalent to -mabi= flag
|
||||||
@@ -148,6 +149,11 @@ func (spec *TargetSpec) loadFromGivenStr(str string) error {
|
|||||||
|
|
||||||
// resolveInherits loads inherited targets, recursively.
|
// resolveInherits loads inherited targets, recursively.
|
||||||
func (spec *TargetSpec) resolveInherits() error {
|
func (spec *TargetSpec) resolveInherits() error {
|
||||||
|
// Save InheritableOnly before resolving, since it must not propagate
|
||||||
|
// from parent to child (a board target should not become inheritable-only
|
||||||
|
// just because its parent processor target is).
|
||||||
|
inheritableOnly := spec.InheritableOnly
|
||||||
|
|
||||||
// First create a new spec with all the inherited properties.
|
// First create a new spec with all the inherited properties.
|
||||||
newSpec := &TargetSpec{}
|
newSpec := &TargetSpec{}
|
||||||
for _, name := range spec.Inherits {
|
for _, name := range spec.Inherits {
|
||||||
@@ -173,6 +179,9 @@ func (spec *TargetSpec) resolveInherits() error {
|
|||||||
}
|
}
|
||||||
*spec = *newSpec
|
*spec = *newSpec
|
||||||
|
|
||||||
|
// Restore InheritableOnly from the original spec, not from parents.
|
||||||
|
spec.InheritableOnly = inheritableOnly
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,10 +248,17 @@ func GetTargetSpecs() (map[string]*TargetSpec, error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
path := filepath.Join(dir, entry.Name())
|
path := filepath.Join(dir, entry.Name())
|
||||||
|
|
||||||
spec, err := LoadTarget(&Options{Target: path})
|
spec, err := LoadTarget(&Options{Target: path})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("could not list target: %w", err)
|
return nil, fmt.Errorf("could not list target: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if spec.InheritableOnly {
|
||||||
|
// Skip targets that are only meant to be inherited from, not used directly.
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
if spec.FlashMethod == "" && spec.FlashCommand == "" && spec.Emulator == "" {
|
if spec.FlashMethod == "" && spec.FlashCommand == "" && spec.Emulator == "" {
|
||||||
// This doesn't look like a regular target file, but rather like
|
// This doesn't look like a regular target file, but rather like
|
||||||
// a parent target (such as targets/cortex-m.json).
|
// a parent target (such as targets/cortex-m.json).
|
||||||
|
|||||||
@@ -23,6 +23,37 @@ func TestLoadTarget(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestGetTargetSpecs_InheritableOnlyTargetsExcluded(t *testing.T) {
|
||||||
|
specs, err := GetTargetSpecs()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("GetTargetSpecs failed:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Inheritable-only processor-level targets should not appear in the listing.
|
||||||
|
inheritableOnlyTargets := []string{"esp32", "esp32c3", "esp32s3", "esp8266", "rp2040", "rp2350", "rp2350b"}
|
||||||
|
for _, name := range inheritableOnlyTargets {
|
||||||
|
if _, ok := specs[name]; ok {
|
||||||
|
t.Errorf("inheritable-only target %q should not appear in GetTargetSpecs", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Board targets that inherit from inheritable-only targets should still appear.
|
||||||
|
boardTargets := []string{"esp32-coreboard-v2", "pico"}
|
||||||
|
for _, name := range boardTargets {
|
||||||
|
if _, ok := specs[name]; !ok {
|
||||||
|
t.Errorf("board target %q should appear in GetTargetSpecs", name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestLoadTarget_InheritableOnlyTargetStillLoadable(t *testing.T) {
|
||||||
|
// Inheritable-only targets should still be loadable directly (for building).
|
||||||
|
_, err := LoadTarget(&Options{Target: "esp32"})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("LoadTarget should still load inheritable-only target esp32: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestOverrideProperties(t *testing.T) {
|
func TestOverrideProperties(t *testing.T) {
|
||||||
baseAutoStackSize := true
|
baseAutoStackSize := true
|
||||||
base := &TargetSpec{
|
base := &TargetSpec{
|
||||||
|
|||||||
@@ -39,6 +39,8 @@ import (
|
|||||||
"go.bug.st/serial/enumerator"
|
"go.bug.st/serial/enumerator"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var errInheritableOnly = errors.New("target is inheritable-only, which means it cannot be used directly for building or flashing")
|
||||||
|
|
||||||
// commandError is an error type to wrap os/exec.Command errors. This provides
|
// commandError is an error type to wrap os/exec.Command errors. This provides
|
||||||
// some more information regarding what went wrong while running a command.
|
// some more information regarding what went wrong while running a command.
|
||||||
type commandError struct {
|
type commandError struct {
|
||||||
@@ -140,6 +142,10 @@ func printCommand(cmd string, args ...string) {
|
|||||||
|
|
||||||
// Build compiles and links the given package and writes it to outpath.
|
// Build compiles and links the given package and writes it to outpath.
|
||||||
func Build(pkgName, outpath string, config *compileopts.Config) error {
|
func Build(pkgName, outpath string, config *compileopts.Config) error {
|
||||||
|
if config.Target != nil && config.Target.InheritableOnly {
|
||||||
|
return errInheritableOnly
|
||||||
|
}
|
||||||
|
|
||||||
// Create a temporary directory for intermediary files.
|
// Create a temporary directory for intermediary files.
|
||||||
tmpdir, err := os.MkdirTemp("", "tinygo")
|
tmpdir, err := os.MkdirTemp("", "tinygo")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -357,6 +363,10 @@ func Flash(pkgName, port, outpath string, options *compileopts.Options) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.Target != nil && config.Target.InheritableOnly {
|
||||||
|
return errInheritableOnly
|
||||||
|
}
|
||||||
|
|
||||||
// determine the type of file to compile
|
// determine the type of file to compile
|
||||||
var fileExt string
|
var fileExt string
|
||||||
|
|
||||||
@@ -786,6 +796,10 @@ func Run(pkgName string, options *compileopts.Options, cmdArgs []string) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if config.Target != nil && config.Target.InheritableOnly {
|
||||||
|
return errInheritableOnly
|
||||||
|
}
|
||||||
|
|
||||||
_, err = buildAndRun(pkgName, config, os.Stdout, cmdArgs, nil, 0, func(cmd *exec.Cmd, result builder.BuildResult) error {
|
_, err = buildAndRun(pkgName, config, os.Stdout, cmdArgs, nil, 0, func(cmd *exec.Cmd, result builder.BuildResult) error {
|
||||||
return cmd.Run()
|
return cmd.Run()
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"inherits": ["xtensa"],
|
"inherits": ["xtensa"],
|
||||||
|
"inheritable-only": true,
|
||||||
"cpu": "esp32",
|
"cpu": "esp32",
|
||||||
"features": "+atomctl,+bool,+clamps,+coprocessor,+debug,+density,+dfpaccel,+div32,+exception,+fp,+highpriinterrupts,+interrupt,+loop,+mac16,+memctl,+minmax,+miscsr,+mul32,+mul32high,+nsa,+prid,+regprotect,+rvector,+s32c1i,+sext,+threadptr,+timerint,+windowed",
|
"features": "+atomctl,+bool,+clamps,+coprocessor,+debug,+density,+dfpaccel,+div32,+exception,+fp,+highpriinterrupts,+interrupt,+loop,+mac16,+memctl,+minmax,+miscsr,+mul32,+mul32high,+nsa,+prid,+regprotect,+rvector,+s32c1i,+sext,+threadptr,+timerint,+windowed",
|
||||||
"build-tags": ["esp32", "esp"],
|
"build-tags": ["esp32", "esp"],
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"inherits": ["riscv32"],
|
"inherits": ["riscv32"],
|
||||||
|
"inheritable-only": true,
|
||||||
"features": "+32bit,+c,+m,+zmmul,-a,-b,-d,-e,-experimental-sdext,-experimental-sdtrig,-experimental-smctr,-experimental-ssctr,-experimental-svukte,-experimental-xqcia,-experimental-xqciac,-experimental-xqcicli,-experimental-xqcicm,-experimental-xqcics,-experimental-xqcicsr,-experimental-xqciint,-experimental-xqcilo,-experimental-xqcilsm,-experimental-xqcisls,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-experimental-zvbc32e,-experimental-zvkgs,-f,-h,-relax,-sha,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smdbltrp,-smepmp,-smmpm,-smnpm,-smrnmi,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssdbltrp,-ssnpm,-sspm,-ssqosid,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-supm,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-svvptc,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xesppie,-xmipscmove,-xmipslsp,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zaamo,-zabha,-zacas,-zalrsc,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-ztso,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b",
|
"features": "+32bit,+c,+m,+zmmul,-a,-b,-d,-e,-experimental-sdext,-experimental-sdtrig,-experimental-smctr,-experimental-ssctr,-experimental-svukte,-experimental-xqcia,-experimental-xqciac,-experimental-xqcicli,-experimental-xqcicm,-experimental-xqcics,-experimental-xqcicsr,-experimental-xqciint,-experimental-xqcilo,-experimental-xqcilsm,-experimental-xqcisls,-experimental-zalasr,-experimental-zicfilp,-experimental-zicfiss,-experimental-zvbc32e,-experimental-zvkgs,-f,-h,-relax,-sha,-shcounterenw,-shgatpa,-shtvala,-shvsatpa,-shvstvala,-shvstvecd,-smaia,-smcdeleg,-smcsrind,-smdbltrp,-smepmp,-smmpm,-smnpm,-smrnmi,-smstateen,-ssaia,-ssccfg,-ssccptr,-sscofpmf,-sscounterenw,-sscsrind,-ssdbltrp,-ssnpm,-sspm,-ssqosid,-ssstateen,-ssstrict,-sstc,-sstvala,-sstvecd,-ssu64xl,-supm,-svade,-svadu,-svbare,-svinval,-svnapot,-svpbmt,-svvptc,-v,-xcvalu,-xcvbi,-xcvbitmanip,-xcvelw,-xcvmac,-xcvmem,-xcvsimd,-xesppie,-xmipscmove,-xmipslsp,-xsfcease,-xsfvcp,-xsfvfnrclipxfqf,-xsfvfwmaccqqq,-xsfvqmaccdod,-xsfvqmaccqoq,-xsifivecdiscarddlone,-xsifivecflushdlone,-xtheadba,-xtheadbb,-xtheadbs,-xtheadcmo,-xtheadcondmov,-xtheadfmemidx,-xtheadmac,-xtheadmemidx,-xtheadmempair,-xtheadsync,-xtheadvdot,-xventanacondops,-xwchc,-za128rs,-za64rs,-zaamo,-zabha,-zacas,-zalrsc,-zama16b,-zawrs,-zba,-zbb,-zbc,-zbkb,-zbkc,-zbkx,-zbs,-zca,-zcb,-zcd,-zce,-zcf,-zcmop,-zcmp,-zcmt,-zdinx,-zfa,-zfbfmin,-zfh,-zfhmin,-zfinx,-zhinx,-zhinxmin,-zic64b,-zicbom,-zicbop,-zicboz,-ziccamoa,-ziccif,-zicclsm,-ziccrse,-zicntr,-zicond,-zicsr,-zifencei,-zihintntl,-zihintpause,-zihpm,-zimop,-zk,-zkn,-zknd,-zkne,-zknh,-zkr,-zks,-zksed,-zksh,-zkt,-ztso,-zvbb,-zvbc,-zve32f,-zve32x,-zve64d,-zve64f,-zve64x,-zvfbfmin,-zvfbfwma,-zvfh,-zvfhmin,-zvkb,-zvkg,-zvkn,-zvknc,-zvkned,-zvkng,-zvknha,-zvknhb,-zvks,-zvksc,-zvksed,-zvksg,-zvksh,-zvkt,-zvl1024b,-zvl128b,-zvl16384b,-zvl2048b,-zvl256b,-zvl32768b,-zvl32b,-zvl4096b,-zvl512b,-zvl64b,-zvl65536b,-zvl8192b",
|
||||||
"build-tags": ["esp32c3", "esp"],
|
"build-tags": ["esp32c3", "esp"],
|
||||||
"serial": "usb",
|
"serial": "usb",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"inherits": ["xtensa"],
|
"inherits": ["xtensa"],
|
||||||
|
"inheritable-only": true,
|
||||||
"cpu": "esp32s3",
|
"cpu": "esp32s3",
|
||||||
"features": "+atomctl,+bool,+clamps,+coprocessor,+debug,+density,+div32,+esp32s3,+exception,+fp,+highpriinterrupts,+interrupt,+loop,+mac16,+memctl,+minmax,+miscsr,+mul32,+mul32high,+nsa,+prid,+regprotect,+rvector,+s32c1i,+sext,+threadptr,+timerint,+windowed",
|
"features": "+atomctl,+bool,+clamps,+coprocessor,+debug,+density,+div32,+esp32s3,+exception,+fp,+highpriinterrupts,+interrupt,+loop,+mac16,+memctl,+minmax,+miscsr,+mul32,+mul32high,+nsa,+prid,+regprotect,+rvector,+s32c1i,+sext,+threadptr,+timerint,+windowed",
|
||||||
"build-tags": ["esp32s3", "esp"],
|
"build-tags": ["esp32s3", "esp"],
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"inherits": ["xtensa"],
|
"inherits": ["xtensa"],
|
||||||
|
"inheritable-only": true,
|
||||||
"cpu": "esp8266",
|
"cpu": "esp8266",
|
||||||
"features": "+debug,+density,+exception,+extendedl32r,+highpriinterrupts,+interrupt,+mul32,+nsa,+prid,+regprotect,+rvector,+timerint",
|
"features": "+debug,+density,+exception,+extendedl32r,+highpriinterrupts,+interrupt,+mul32,+nsa,+prid,+regprotect,+rvector,+timerint",
|
||||||
"build-tags": ["esp8266", "esp"],
|
"build-tags": ["esp8266", "esp"],
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"inherits": ["cortex-m0plus"],
|
"inherits": ["cortex-m0plus"],
|
||||||
|
"inheritable-only": true,
|
||||||
"build-tags": ["rp2040", "rp"],
|
"build-tags": ["rp2040", "rp"],
|
||||||
"scheduler": "tasks",
|
"scheduler": "tasks",
|
||||||
"flash-1200-bps-reset": "true",
|
"flash-1200-bps-reset": "true",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"inherits": ["cortex-m33"],
|
"inherits": ["cortex-m33"],
|
||||||
|
"inheritable-only": true,
|
||||||
"build-tags": ["rp2350", "rp"],
|
"build-tags": ["rp2350", "rp"],
|
||||||
"scheduler": "tasks",
|
"scheduler": "tasks",
|
||||||
"flash-1200-bps-reset": "true",
|
"flash-1200-bps-reset": "true",
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
{
|
{
|
||||||
"inherits": ["rp2350"],
|
"inherits": ["rp2350"],
|
||||||
|
"inheritable-only": true,
|
||||||
"build-tags": ["rp2350b"],
|
"build-tags": ["rp2350b"],
|
||||||
"serial-port": ["2e8a:000f"]
|
"serial-port": ["2e8a:000f"]
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user