github.com/metux/go-metabuild@v0.0.0-20240118143255-d9ed5ab697f9/spec/target/targetobject.go (about)

     1  package target
     2  
     3  import (
     4  	"os"
     5  	"path/filepath"
     6  	"regexp"
     7  
     8  	"github.com/metux/go-metabuild/spec/buildconf"
     9  	"github.com/metux/go-metabuild/spec/cache"
    10  	"github.com/metux/go-metabuild/util"
    11  	"github.com/metux/go-metabuild/util/fileutil"
    12  	"github.com/metux/go-metabuild/util/specobj"
    13  )
    14  
    15  var (
    16  	reWithType = regexp.MustCompile(`(.*)\{([\w/_\-\.\+]+)\}$`)
    17  )
    18  
    19  type TargetObject struct {
    20  	specobj.SpecObj
    21  	BuildConf buildconf.BuildConf
    22  	Cache     cache.Cache
    23  }
    24  
    25  func (o TargetObject) FeaturedStrList(k Key) []string {
    26  	ret := o.EntryStrList(k)
    27  	for _, f := range o.BuildConf.Features.All() {
    28  		k2 := Key(string(k) + "@feature/" + string(f.Id) + "=" + f.ValueYN())
    29  		ret = append(ret, o.EntryStrList(k2)...)
    30  	}
    31  	return ret
    32  }
    33  
    34  func (o TargetObject) Sources() []string {
    35  	res := []string{}
    36  	for _, f := range util.StrDirPrefix(o.EntryStr(KeySourceDir), o.FeaturedStrList(KeySource)) {
    37  		files, err := filepath.Glob(f)
    38  		util.ErrPanicf(err, "file glob error")
    39  		if len(files) == 0 {
    40  			panic("broken source glob: " + f)
    41  		}
    42  		res = append(res, files...)
    43  	}
    44  	return res
    45  }
    46  
    47  func (o TargetObject) RequiredSources() []string {
    48  	s := util.StrDirPrefix(o.EntryStr(KeySourceDir), o.FeaturedStrList(KeySource))
    49  	if len(s) == 0 {
    50  		panic("source attribute required")
    51  	}
    52  	return s
    53  }
    54  
    55  func (o TargetObject) RequiredSourceAbs() string {
    56  	s := o.RequiredSources()
    57  	if len(s) != 1 {
    58  		panic("only exactly one source file required")
    59  	}
    60  	a, err := filepath.Abs(s[0])
    61  	util.ErrPanicf(err, "failed retrieving absolute path of %s", s[0])
    62  	return a
    63  }
    64  
    65  func (o TargetObject) ForBuild() bool {
    66  	return o.EntryBoolDef(Key("build"), false)
    67  }
    68  
    69  func (o TargetObject) MyId() string {
    70  	return o.EntryStr(KeyInternId)
    71  }
    72  
    73  func (o TargetObject) loadTargetType(t Key) {
    74  	if !t.Empty() {
    75  		k := buildconf.KeyTargetPlatform.Append("targets").Append(t).MagicLiteralPost()
    76  		o.CopyDefaultsFrom(o.BuildConf.EntrySpec(k))
    77  	}
    78  }
    79  
    80  func (o TargetObject) setId(id string) {
    81  	o.EntryPutStr(KeyInternId, id)
    82  	if ext := filepath.Ext(id); ext != "" {
    83  		o.DefaultPutStr(KeyInternIdSuffix, ext[1:])
    84  	}
    85  
    86  	o.DefaultPutStr(KeyInternBasename, filepath.Base(id))
    87  
    88  	if dn := filepath.Dir(id); dn != "" {
    89  		o.DefaultPutStr(KeyInternDirname, dn)
    90  	}
    91  }
    92  
    93  func (o TargetObject) LoadTargetDefaults() {
    94  	id := o.MyKey()
    95  
    96  	if match := reWithType.FindStringSubmatch(string(id)); len(match) == 3 {
    97  		o.setId(match[1])
    98  		o.EntryPutStr(KeyInternType, match[2])
    99  		o.loadTargetType(Key(match[2]))
   100  	} else {
   101  		o.setId(string(id))
   102  	}
   103  
   104  	o.loadTargetType(o.Type())
   105  }
   106  
   107  func (o TargetObject) CDefines() []string {
   108  	return o.FeaturedStrList(KeyCDefines)
   109  }
   110  
   111  func (o TargetObject) CFlags() []string {
   112  	return o.FeaturedStrList(KeyCCflags)
   113  }
   114  
   115  func (o TargetObject) GetFMode(k Key) os.FileMode {
   116  	n, _ := fileutil.FileModeParse(o.EntryStr(k))
   117  	return n
   118  }
   119  
   120  func (o TargetObject) InstallPerm() os.FileMode {
   121  	m, err := fileutil.FileModeParse(o.RequiredEntryStr(KeyInstallPerm))
   122  	if m == 0 || err != nil {
   123  		util.Panicf("config error: target's mode=0 or error %s", err)
   124  	}
   125  	return m
   126  }
   127  
   128  func (o TargetObject) InstallDir() string {
   129  	return o.RequiredEntryStr(KeyInstallDir) + "/" + o.EntryStr(KeyInstallSubdir)
   130  }
   131  
   132  func (o TargetObject) PackageId(scope string) string {
   133  	k := Key(scope + string(KeyInstallPackage))
   134  	id := o.EntryStr(k)
   135  	if id == "" {
   136  		panic("config error: PackageId empty")
   137  	}
   138  	return id
   139  }
   140  
   141  func (o TargetObject) CompilerLang() string {
   142  	return o.RequiredEntryStr(KeyCompilerLang)
   143  }
   144  
   145  func (o TargetObject) Type() Key {
   146  	if s := o.EntryStr(KeyInternType); s != "" {
   147  		return Key(s)
   148  	}
   149  	return Key(o.EntryStr(KeyType))
   150  }
   151  
   152  func (o TargetObject) SetType(k Key) {
   153  	o.EntryPutStr(KeyType, string(k))
   154  }
   155  
   156  func (o TargetObject) SubTarget(k specobj.Key) TargetObject {
   157  	return MakeTargetObject(o.EntrySpec(k), k, o.BuildConf, o.Cache)
   158  }
   159  
   160  func (o TargetObject) WantInstall() bool {
   161  	return o.EntryBoolDef(KeyInstall, true)
   162  }
   163  
   164  func (b TargetObject) EntryPathList(k Key) []string {
   165  	list := b.EntryStrList(k)
   166  	for idx, ent := range list {
   167  		d, err := filepath.Abs(ent)
   168  		util.ErrPanicf(err, "error retrieving abspath for %s", d)
   169  		list[idx] = d
   170  	}
   171  	return list
   172  }
   173  
   174  func (o TargetObject) Skipped() bool {
   175  	if o.EntryBoolDef(KeySkip, false) {
   176  		return true
   177  	}
   178  
   179  	for _, opt := range o.EntryStrList(KeyOptional) {
   180  		f := o.BuildConf.Features.Get(Key(opt))
   181  		if !f.IsOn() {
   182  			return true
   183  		}
   184  	}
   185  
   186  	return false
   187  }
   188  
   189  func MakeTargetObject(spec specobj.SpecObj, k Key, bc buildconf.BuildConf, c cache.Cache) TargetObject {
   190  	obj := TargetObject{
   191  		SpecObj:   spec,
   192  		Cache:     c,
   193  		BuildConf: bc,
   194  	}
   195  	return obj
   196  }