Files
llgo/internal/targets/resolver.go
Li Jie b80a54eb0f feat: implement target configuration system for issue #1176
Add comprehensive target configuration parsing and inheritance system:

- Create internal/targets package with config structures
- Support JSON configuration loading with inheritance resolution
- Implement multi-level inheritance (e.g., rp2040 → cortex-m0plus → cortex-m)
- Add 206 target configurations from TinyGo for embedded platforms
- Support core fields: name, llvm-target, cpu, features, build-tags, goos, goarch, cflags, ldflags
- Provide high-level resolver interface for target lookup
- Include comprehensive unit tests with 100% target parsing coverage

This foundation enables future -target parameter support for cross-compilation
to diverse embedded platforms beyond current GOOS/GOARCH limitations.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-29 15:12:58 +08:00

78 lines
2.1 KiB
Go

package targets
import (
"fmt"
"path/filepath"
"runtime"
)
// Resolver provides high-level interface for target configuration resolution
type Resolver struct {
loader *Loader
}
// NewResolver creates a new target resolver
func NewResolver(targetsDir string) *Resolver {
return &Resolver{
loader: NewLoader(targetsDir),
}
}
// NewDefaultResolver creates a resolver with default targets directory
func NewDefaultResolver() *Resolver {
// Assume targets directory is relative to this package
_, filename, _, _ := runtime.Caller(0)
projectRoot := filepath.Dir(filepath.Dir(filepath.Dir(filename)))
targetsDir := filepath.Join(projectRoot, "targets")
return NewResolver(targetsDir)
}
// Resolve resolves a target configuration by name
func (r *Resolver) Resolve(targetName string) (*Config, error) {
config, err := r.loader.Load(targetName)
if err != nil {
return nil, fmt.Errorf("failed to resolve target %s: %w", targetName, err)
}
// Validate required fields
if err := r.validateConfig(config); err != nil {
return nil, fmt.Errorf("invalid target config %s: %w", targetName, err)
}
return config, nil
}
// ResolveAll resolves all available target configurations
func (r *Resolver) ResolveAll() (map[string]*Config, error) {
return r.loader.LoadAll()
}
// ListAvailableTargets returns a list of all available target names
func (r *Resolver) ListAvailableTargets() ([]string, error) {
return r.loader.ListTargets()
}
// validateConfig validates that a resolved config has required fields
func (r *Resolver) validateConfig(config *Config) error {
if config.Name == "" {
return fmt.Errorf("target name is required")
}
// For now, we don't require any specific fields since different targets
// may have different requirements. This can be extended in the future.
return nil
}
// GetTargetsDirectory returns the path to the targets directory
func (r *Resolver) GetTargetsDirectory() string {
return r.loader.GetTargetsDir()
}
// HasTarget checks if a target with the given name exists
func (r *Resolver) HasTarget(name string) bool {
_, err := r.loader.LoadRaw(name)
return err == nil
}