You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mynewt.apache.org by cc...@apache.org on 2017/03/28 22:41:43 UTC
[46/67] [abbrv] [partial] incubator-mynewt-newtmgr git commit:
newtmgr - Remove newt code
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/e31a7d31/newt/symbol/symbol.go
----------------------------------------------------------------------
diff --git a/newt/symbol/symbol.go b/newt/symbol/symbol.go
deleted file mode 100644
index 9d155ca..0000000
--- a/newt/symbol/symbol.go
+++ /dev/null
@@ -1,322 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-/* this file maintains a list of all the symbols from a */
-
-package symbol
-
-import (
- "fmt"
- "sort"
- "strings"
-
- "mynewt.apache.org/newt/util"
-)
-
-type SymbolInfo struct {
- Bpkg string
- Name string
- Code string
- Section string
- Ext string
- Size int
- Loc int
-}
-
-type SymbolMap map[string]SymbolInfo
-
-func NewSymbolMap() *SymbolMap {
- val := &SymbolMap{}
- return val
-}
-
-func NewSymbolInfo() *SymbolInfo {
- val := &SymbolInfo{}
- return val
-}
-
-func NewElfSymbol(name string) *SymbolInfo {
- val := NewSymbolInfo()
- val.Name = name
- val.Ext = ".elf"
- return val
-}
-
-func (s *SymbolMap) Add(info SymbolInfo) {
- (*s)[info.Name] = info
-}
-
-func (s *SymbolMap) GlobalFunctionsOnly() *SymbolMap {
- s3 := NewSymbolMap()
-
- for _, info1 := range *s {
- if info1.IsFunction() && !info1.IsLocal() {
- s3.Add(info1)
- }
- }
- return s3
-}
-
-func (s *SymbolMap) GlobalDataOnly() *SymbolMap {
- s3 := NewSymbolMap()
-
- for _, info1 := range *s {
- if !info1.IsFunction() && !info1.IsLocal() {
- s3.Add(info1)
- }
- }
- return s3
-}
-
-func (s *SymbolMap) Packages() map[string]bool {
- pkg := make(map[string]bool)
- for _, info1 := range *s {
- pkg[info1.Bpkg] = true
- }
- return pkg
-}
-
-func IdenticalUnion(s1 *SymbolMap, s2 *SymbolMap, comparePkg bool,
- compareAddr bool) (error, *SymbolMap, *SymbolMap) {
- s3 := NewSymbolMap()
- s_no := NewSymbolMap()
- var err_str string
- var err error
- /* look through all symbols in S1 and if they are in s1,
- * add to new map s3 */
-
- for name, info1 := range *s1 {
- if info2, ok := (*s2)[name]; ok {
- var pkg bool
- var addr bool
-
- if comparePkg {
- pkg = info1.Bpkg == info2.Bpkg
- } else {
- pkg = true
- }
-
- if compareAddr {
- addr = info1.Loc == info2.Loc
- } else {
- addr = true
- }
-
- /* compare to info 1 */
- if info1.Code == info2.Code &&
- info1.Size == info2.Size && pkg && addr {
- s3.Add(info1)
- } else if !info1.IsLocal() && !info1.IsFunction() {
- /* Here is an unusual case. We have a global data
- * symbol (bss or data) with the same name that is used
- * in both apps. If code is linked against both of these
- * the code in the loader will call one while the code in
- * the app will call the other. If the intention was for
- * these to be the same, then things are bad. */
- if err_str == "" {
- err_str = "There are global symbols with the same name that " +
- "are access via the loader and split application. These " +
- "symbols are either different sizes or from different " +
- "packages. Reconcile this issue before buidling. If the " +
- "symbols are intended to be shared by both, move the " +
- "symbol to a package that is shared by both apps. If " +
- "the symbols are distict (not shared), then make them " +
- "static or rename them so they do not conflict" +
- "\nNon Matching Symbols:\n"
- }
-
- err_str = err_str + fmt.Sprintf("%s-%s\n", info1.Sprintf(), info2.Sprintf())
- } else {
- info1.Name = info1.Name + "(app)"
- info2.Name = info2.Name + "(loader)"
- s_no.Add(info1)
- s_no.Add(info2)
- }
- }
- }
-
- if err_str != "" {
- err = util.NewNewtError(err_str)
- }
- return err, s3, s_no
-}
-
-type SymbolMapIterator func(s *SymbolInfo)
-
-func sprintfSi(si *SymbolInfo) string {
- str := fmt.Sprintf(" %32s(%4s) (%8s) -- (%12s) %5d (0x%08x) from %s\n",
- (*si).Name, (*si).Ext, (*si).Code, (*si).Section,
- (*si).Size, (*si).Loc, (*si).Bpkg)
- return str
-}
-
-func dumpSi(si *SymbolInfo) {
- fmt.Printf(sprintfSi(si))
-}
-
-func (si *SymbolInfo) Dump() {
- dumpSi(si)
-}
-
-func (si *SymbolInfo) Sprintf() string {
- return sprintfSi(si)
-}
-
-func (si *SymbolInfo) IsLocal() bool {
- val := (*si).Code[:1]
-
- if val == "l" {
- return true
- }
- return false
-}
-
-func (si *SymbolInfo) IsWeak() bool {
- val := (*si).Code[1:2]
-
- if val == "w" {
- return true
- }
- return false
-}
-
-func (si *SymbolInfo) IsDebug() bool {
- val := (*si).Code[5:6]
-
- if val == "d" {
- return true
- }
- return false
-}
-
-func (si *SymbolInfo) IsSection(section string) bool {
- val := (*si).Section
- return strings.HasPrefix(val, section)
-}
-
-func (si *SymbolInfo) IsFile() bool {
- val := (*si).Code[6:7]
-
- if val == "f" {
- return true
- }
- return false
-}
-
-func (si *SymbolInfo) IsFunction() bool {
- val := (*si).Code[6:7]
-
- if val == "F" {
- return true
- }
- return false
-}
-
-func (s *SymbolMap) FilterPkg(pname string) *SymbolMap {
- sm := NewSymbolMap()
- for _, info1 := range *s {
- if pname != "" && pname == info1.Bpkg {
- sm.Add(info1)
- }
- }
- return sm
-}
-
-func (s *SymbolMap) String(name string) string {
- // To store the keys in slice in sorted order
- var keys []string
- for k := range *s {
- keys = append(keys, k)
- }
- sort.Strings(keys)
-
- // To perform the opertion you want
- out := fmt.Sprintf("Dumping symbols in file: %s\n", name)
- for _, k := range keys {
- info1 := (*s)[k]
- out += info1.Sprintf()
- }
- return out
-}
-
-func (s *SymbolMap) Dump(name string) {
-
- // To store the keys in slice in sorted order
- var keys []string
- for k := range *s {
- keys = append(keys, k)
- }
- sort.Strings(keys)
-
- // To perform the opertion you want
- fmt.Printf("Dumping symbols in file: %s\n", name)
- for _, k := range keys {
- info1 := (*s)[k]
- info1.Dump()
- }
-}
-
-// Merge - merges given maps into 1 map
-// values will be overridden by last matching key - value
-func (s1 *SymbolMap) Merge(s2 *SymbolMap) (*SymbolMap, error) {
-
- for k, v := range *s2 {
-
- if val, ok := (*s1)[k]; ok {
- /* We already have this in the MAP */
- if val.IsWeak() && !v.IsWeak() {
- (*s1)[k] = v
- } else if v.IsWeak() && !val.IsWeak() {
- /* nothing to do here as this is OK not to replace */
- } else if v.IsLocal() && val.IsLocal() {
- /* two locals that must conflict with name */
- /* have to have separate instances of these */
- util.StatusMessage(util.VERBOSITY_VERBOSE,
- "Local Symbol Conflict: %s from packages %s and %s \n",
- v.Name, v.Bpkg, val.Bpkg)
- (*s2).Remove(k)
- } else {
- util.StatusMessage(util.VERBOSITY_QUIET,
- "Global Symbol Conflict: %s from packages %s and %s \n",
- v.Name, v.Bpkg, val.Bpkg)
- return nil, util.NewNewtError("Global Symbol Conflict")
- }
- } else {
- (*s1)[k] = v
- }
-
- }
- return s1, nil
-}
-
-func (s *SymbolMap) Remove(name string) {
- delete(*s, name)
-}
-
-func (s *SymbolMap) RemoveMap(subset *SymbolMap) {
- for name, _ := range *subset {
- (*s).Remove(name)
- }
-}
-
-/* Returns true if the symbol is present in the symbol map */
-func (s *SymbolMap) Find(name string) (*SymbolInfo, bool) {
- val, ok := (*s)[name]
- return &val, ok
-}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/e31a7d31/newt/syscfg/restrict.go
----------------------------------------------------------------------
diff --git a/newt/syscfg/restrict.go b/newt/syscfg/restrict.go
deleted file mode 100644
index 5f9c0f7..0000000
--- a/newt/syscfg/restrict.go
+++ /dev/null
@@ -1,199 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package syscfg
-
-import (
- "fmt"
- "strings"
-
- "mynewt.apache.org/newt/util"
-)
-
-type CfgRestrictionCode int
-
-const (
- CFG_RESTRICTION_CODE_NOTNULL = iota
- CFG_RESTRICTION_CODE_EXPR
-)
-
-var cfgRestrictionNameCodeMap = map[string]CfgRestrictionCode{
- "$notnull": CFG_RESTRICTION_CODE_NOTNULL,
-}
-
-type CfgRestrictionExpr struct {
- ReqSetting string
- ReqVal bool
- BaseVal bool
-}
-type CfgRestriction struct {
- BaseSetting string
- Code CfgRestrictionCode
-
- // Only used if Code is CFG_RESTRICTION_CODE_EXPR
- Expr CfgRestrictionExpr
-}
-
-func parseRestrictionExprConsequent(field string) (string, bool) {
- var val bool
- var name string
-
- if strings.HasPrefix(field, "!") {
- val = false
- name = strings.TrimPrefix(field, "!")
- } else {
- val = true
- name = field
- }
-
- return name, val
-}
-
-// Parses a restriction value.
-//
-// Currently, two forms of restrictions are supported:
-// 1. "$notnull"
-// 2. expression
-//
-// The "$notnull" string indicates that the setting must be set to something
-// other than the empty string.
-//
-// An expression string indicates dependencies on other settings. It would be
-// better to have a real expression parser. For now, only very simple
-// expressions are supported. A restriction expression must be of the
-// following form:
-// [!]<req-setting> [if <base-val>]
-//
-// All setting values are interpreted as booleans. If a setting is "0", "",
-// or undefined, it is false; otherwise it is true.
-//
-// Examples:
-// # Can't enable this setting unless LOG_FCB is enabled.
-// pkg.restrictions:
-// LOG_FCB
-//
-// # Can't enable this setting unless LOG_FCB is disabled.
-// pkg.restrictions:
-// !LOG_FCB
-//
-// # Can't disable this setting unless LOG_FCB is enabled.
-// pkg.restrictions:
-// LOG_FCB if 0
-func readRestrictionExpr(text string) (CfgRestrictionExpr, error) {
- e := CfgRestrictionExpr{}
-
- fields := strings.Fields(text)
- switch len(fields) {
- case 1:
- e.ReqSetting, e.ReqVal = parseRestrictionExprConsequent(fields[0])
- e.BaseVal = true
-
- case 3:
- if fields[1] != "if" {
- return e, util.FmtNewtError("invalid restriction: %s", text)
- }
- e.ReqSetting, e.ReqVal = parseRestrictionExprConsequent(fields[0])
- e.BaseVal = ValueIsTrue(fields[2])
-
- default:
- return e, util.FmtNewtError("invalid restriction: %s", text)
- }
-
- return e, nil
-}
-
-func readRestriction(baseSetting string, text string) (CfgRestriction, error) {
- r := CfgRestriction{
- BaseSetting: baseSetting,
- }
-
- var ok bool
- if r.Code, ok = cfgRestrictionNameCodeMap[text]; !ok {
- // If the restriction text isn't a defined string, parse it as an
- // expression.
- r.Code = CFG_RESTRICTION_CODE_EXPR
-
- var err error
- if r.Expr, err = readRestrictionExpr(text); err != nil {
- return r, err
- }
- }
-
- return r, nil
-}
-
-func (cfg *Cfg) violationText(entry CfgEntry, r CfgRestriction) string {
- if r.Code == CFG_RESTRICTION_CODE_NOTNULL {
- return entry.Name + " must not be null"
- }
-
- str := fmt.Sprintf("%s=%s ", entry.Name, entry.Value)
- if r.Expr.ReqVal {
- str += fmt.Sprintf("requires %s be set", r.Expr.ReqSetting)
- } else {
- str += fmt.Sprintf("requires %s not be set", r.Expr.ReqSetting)
- }
-
- str += fmt.Sprintf(", but %s", r.Expr.ReqSetting)
- reqEntry, ok := cfg.Settings[r.Expr.ReqSetting]
- if !ok {
- str += "undefined"
- } else {
- str += fmt.Sprintf("=%s", reqEntry.Value)
- }
-
- return str
-}
-
-func (r *CfgRestriction) relevantSettingNames() []string {
- switch r.Code {
- case CFG_RESTRICTION_CODE_NOTNULL:
- return []string{r.BaseSetting}
-
- case CFG_RESTRICTION_CODE_EXPR:
- return []string{r.BaseSetting, r.Expr.ReqSetting}
-
- default:
- panic("Invalid restriction code: " + string(r.Code))
- }
-}
-
-func (cfg *Cfg) restrictionMet(r CfgRestriction) bool {
- baseEntry := cfg.Settings[r.BaseSetting]
- baseVal := baseEntry.IsTrue()
-
- switch r.Code {
- case CFG_RESTRICTION_CODE_NOTNULL:
- return baseEntry.Value != ""
-
- case CFG_RESTRICTION_CODE_EXPR:
- if baseVal != r.Expr.BaseVal {
- // Restriction does not apply.
- return true
- }
-
- reqEntry, ok := cfg.Settings[r.Expr.ReqSetting]
- reqVal := ok && reqEntry.IsTrue()
-
- return reqVal == r.Expr.ReqVal
-
- default:
- panic("Invalid restriction code: " + string(r.Code))
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/e31a7d31/newt/syscfg/syscfg.go
----------------------------------------------------------------------
diff --git a/newt/syscfg/syscfg.go b/newt/syscfg/syscfg.go
deleted file mode 100644
index cac298e..0000000
--- a/newt/syscfg/syscfg.go
+++ /dev/null
@@ -1,1045 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package syscfg
-
-import (
- "bytes"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- "sort"
- "strconv"
- "strings"
-
- log "github.com/Sirupsen/logrus"
- "github.com/spf13/cast"
-
- "mynewt.apache.org/newt/newt/flash"
- "mynewt.apache.org/newt/newt/interfaces"
- "mynewt.apache.org/newt/newt/newtutil"
- "mynewt.apache.org/newt/newt/pkg"
- "mynewt.apache.org/newt/util"
-)
-
-const HEADER_PATH = "syscfg/syscfg.h"
-
-const SYSCFG_PREFIX_SETTING = "MYNEWT_VAL_"
-
-type CfgSettingType int
-
-const (
- CFG_SETTING_TYPE_RAW CfgSettingType = iota
- CFG_SETTING_TYPE_TASK_PRIO
- CFG_SETTING_TYPE_INTERRUPT_PRIO
- CFG_SETTING_TYPE_FLASH_OWNER
-)
-
-const SYSCFG_PRIO_ANY = "any"
-
-// Reserve last 16 priorities for the system (sanity, idle).
-const SYSCFG_TASK_PRIO_MAX = 0xef
-
-// The range of interrupt priorities is hardware dependent, so don't limit
-// these here.
-const SYSCFG_INTERRUPT_PRIO_MAX = 0xffffffff
-
-var cfgSettingNameTypeMap = map[string]CfgSettingType{
- "raw": CFG_SETTING_TYPE_RAW,
- "task_priority": CFG_SETTING_TYPE_TASK_PRIO,
- "interrupt_priority": CFG_SETTING_TYPE_INTERRUPT_PRIO,
- "flash_owner": CFG_SETTING_TYPE_FLASH_OWNER,
-}
-
-type CfgPoint struct {
- Value string
- Source *pkg.LocalPackage
-}
-
-type CfgEntry struct {
- Name string
- Value string
- Description string
- SettingType CfgSettingType
- Restrictions []CfgRestriction
- PackageDef *pkg.LocalPackage
- History []CfgPoint
-}
-
-type CfgPriority struct {
- SettingName string
- PackageDef *pkg.LocalPackage // package that define the setting.
- PackageSrc *pkg.LocalPackage // package overriding setting value.
-}
-
-type CfgFlashConflictCode int
-
-const (
- CFG_FLASH_CONFLICT_CODE_BAD_NAME CfgFlashConflictCode = iota
- CFG_FLASH_CONFLICT_CODE_NOT_UNIQUE
-)
-
-type CfgFlashConflict struct {
- SettingNames []string
- Code CfgFlashConflictCode
-}
-
-type Cfg struct {
- Settings map[string]CfgEntry
-
- //// Errors
- // Overrides of undefined settings.
- Orphans map[string][]CfgPoint
-
- // Two packages of equal priority override a setting with different
- // values; not overridden by higher priority package.
- Ambiguities map[string][]CfgPoint
-
- // Setting restrictions not met.
- Violations map[string][]CfgRestriction
-
- // Attempted override by bottom-priority packages (libraries).
- PriorityViolations []CfgPriority
-
- FlashConflicts []CfgFlashConflict
-}
-
-func NewCfg() Cfg {
- return Cfg{
- Settings: map[string]CfgEntry{},
- Orphans: map[string][]CfgPoint{},
- Ambiguities: map[string][]CfgPoint{},
- Violations: map[string][]CfgRestriction{},
- PriorityViolations: []CfgPriority{},
- FlashConflicts: []CfgFlashConflict{},
- }
-}
-
-func ValueIsTrue(val string) bool {
- if val == "" {
- return false
- }
-
- i, err := util.AtoiNoOct(val)
- if err == nil && i == 0 {
- return false
- }
-
- return true
-}
-
-func (cfg *Cfg) Features() map[string]bool {
- features := map[string]bool{}
- for k, v := range cfg.Settings {
- if v.IsTrue() {
- features[k] = true
- }
- }
-
- return features
-}
-
-func (cfg *Cfg) FeaturesForLpkg(lpkg *pkg.LocalPackage) map[string]bool {
- features := cfg.Features()
-
- for k, v := range lpkg.InjectedSettings() {
- _, ok := features[k]
- if ok {
- log.Warnf("Attempt to override syscfg setting %s with "+
- "injected feature from package %s", k, lpkg.Name())
- } else {
- if ValueIsTrue(v) {
- features[k] = true
- }
- }
- }
-
- return features
-}
-
-func (point CfgPoint) Name() string {
- if point.Source == nil {
- return "newt"
- } else {
- return point.Source.Name()
- }
-}
-
-func (point CfgPoint) IsInjected() bool {
- return point.Source == nil
-}
-
-func (entry *CfgEntry) IsTrue() bool {
- return ValueIsTrue(entry.Value)
-}
-
-func (entry *CfgEntry) appendValue(lpkg *pkg.LocalPackage, value interface{}) {
- strval := stringValue(value)
- point := CfgPoint{Value: strval, Source: lpkg}
- entry.History = append(entry.History, point)
- entry.Value = strval
-}
-
-func historyToString(history []CfgPoint) string {
- str := "["
- for i, _ := range history {
- if i != 0 {
- str += ", "
- }
- p := history[len(history)-i-1]
- str += fmt.Sprintf("%s:%s", p.Name(), p.Value)
- }
- str += "]"
-
- return str
-}
-
-func (entry *CfgEntry) ambiguities() []CfgPoint {
- diffVals := false
- var points []CfgPoint
-
- for i := 1; i < len(entry.History)-1; i++ {
- cur := entry.History[len(entry.History)-i-1]
- next := entry.History[len(entry.History)-i]
-
- // If either setting is injected, there is no ambiguity
- if cur.Source == nil || next.Source == nil {
- break
- }
-
- // If the two package have different priorities, there is no ambiguity.
- if normalizePkgType(cur.Source.Type()) !=
- normalizePkgType(next.Source.Type()) {
-
- break
- }
-
- if cur.Value != next.Value {
- diffVals = true
- }
-
- if len(points) == 0 {
- points = append(points, cur)
- }
- points = append(points, next)
- }
-
- // If all values are identical, there is no ambiguity
- if !diffVals {
- points = nil
- }
-
- return points
-}
-
-func (entry *CfgEntry) ambiguityText() string {
- points := entry.ambiguities()
- if len(points) == 0 {
- return ""
- }
-
- str := fmt.Sprintf("Setting: %s, Packages: [", entry.Name)
- for i, p := range points {
- if i > 0 {
- str += ", "
- }
-
- str += p.Source.Name()
- }
- str += "]"
-
- return str
-}
-
-func FeatureToCflag(featureName string) string {
- return fmt.Sprintf("-D%s=1", settingName(featureName))
-}
-
-func stringValue(val interface{}) string {
- return strings.TrimSpace(cast.ToString(val))
-}
-
-func readSetting(name string, lpkg *pkg.LocalPackage,
- vals map[interface{}]interface{}) (CfgEntry, error) {
-
- entry := CfgEntry{}
-
- entry.Name = name
- entry.PackageDef = lpkg
- entry.Description = stringValue(vals["description"])
-
- // The value field for setting definition is required.
- valueVal, valueExist := vals["value"]
- if valueExist {
- entry.Value = stringValue(valueVal)
- } else {
- return entry, util.FmtNewtError(
- "setting %s does not have required value field", name)
- }
-
- if vals["type"] == nil {
- entry.SettingType = CFG_SETTING_TYPE_RAW
- } else {
- var ok bool
- typename := stringValue(vals["type"])
- entry.SettingType, ok = cfgSettingNameTypeMap[typename]
- if !ok {
- return entry, util.FmtNewtError(
- "setting %s specifies invalid type: %s", name, typename)
- }
- }
- entry.appendValue(lpkg, entry.Value)
-
- entry.Restrictions = []CfgRestriction{}
- restrictionStrings := cast.ToStringSlice(vals["restrictions"])
- for _, rstring := range restrictionStrings {
- r, err := readRestriction(name, rstring)
- if err != nil {
- return entry,
- util.PreNewtError(err, "error parsing setting %s", name)
- }
- entry.Restrictions = append(entry.Restrictions, r)
- }
-
- return entry, nil
-}
-
-func (cfg *Cfg) readDefsOnce(lpkg *pkg.LocalPackage,
- features map[string]bool) error {
- v := lpkg.SyscfgV
-
- lfeatures := cfg.FeaturesForLpkg(lpkg)
- for k, _ := range features {
- lfeatures[k] = true
- }
-
- settings := newtutil.GetStringMapFeatures(v, lfeatures, "syscfg.defs")
- if settings != nil {
- for k, v := range settings {
- vals := v.(map[interface{}]interface{})
- entry, err := readSetting(k, lpkg, vals)
- if err != nil {
- return util.FmtNewtError("Config for package %s: %s",
- lpkg.Name(), err.Error())
- }
-
- if oldEntry, exists := cfg.Settings[k]; exists {
- // Setting already defined. Allow this only if the setting is
- // injected, in which case the injected value takes precedence.
- point := mostRecentPoint(oldEntry)
- if !point.IsInjected() {
- // XXX: Better error message.
- return util.FmtNewtError("setting %s redefined", k)
- }
-
- entry.History = append(entry.History, oldEntry.History...)
- entry.Value = oldEntry.Value
- }
- cfg.Settings[k] = entry
- }
- }
-
- return nil
-}
-
-func (cfg *Cfg) readValsOnce(lpkg *pkg.LocalPackage,
- features map[string]bool) error {
- v := lpkg.SyscfgV
-
- lfeatures := cfg.FeaturesForLpkg(lpkg)
- for k, _ := range features {
- lfeatures[k] = true
- }
-
- values := newtutil.GetStringMapFeatures(v, lfeatures, "syscfg.vals")
- for k, v := range values {
- entry, ok := cfg.Settings[k]
- if ok {
- sourcetype := normalizePkgType(lpkg.Type())
- deftype := normalizePkgType(entry.PackageDef.Type())
- if sourcetype <= deftype {
- // Overrides must come from a higher priority package.
- priority := CfgPriority{
- PackageDef: entry.PackageDef,
- PackageSrc: lpkg,
- SettingName: k,
- }
- cfg.PriorityViolations = append(cfg.PriorityViolations, priority)
- } else {
- entry.appendValue(lpkg, v)
- cfg.Settings[k] = entry
- }
- } else {
- orphan := CfgPoint{
- Value: stringValue(v),
- Source: lpkg,
- }
- cfg.Orphans[k] = append(cfg.Orphans[k], orphan)
- }
- }
-
- return nil
-}
-
-func (cfg *Cfg) Log() {
- keys := make([]string, len(cfg.Settings))
- i := 0
- for k, _ := range cfg.Settings {
- keys[i] = k
- i++
- }
- sort.Strings(keys)
-
- log.Debugf("syscfg settings (%d entries):", len(cfg.Settings))
- for _, k := range keys {
- entry := cfg.Settings[k]
-
- log.Debugf(" %s=%s %s", k, entry.Value,
- historyToString(entry.History))
- }
-}
-
-func (cfg *Cfg) settingsOfType(typ CfgSettingType) []CfgEntry {
- entries := []CfgEntry{}
-
- for _, entry := range cfg.Settings {
- if entry.SettingType == typ {
- entries = append(entries, entry)
- }
- }
-
- return entries
-}
-
-func (cfg *Cfg) detectViolations() {
- for _, entry := range cfg.Settings {
- var ev []CfgRestriction
- for _, r := range entry.Restrictions {
- if !cfg.restrictionMet(r) {
- ev = append(ev, r)
- }
- }
-
- if ev != nil {
- cfg.Violations[entry.Name] = ev
- }
- }
-}
-
-func (cfg *Cfg) detectFlashConflicts(flashMap flash.FlashMap) {
- entries := cfg.settingsOfType(CFG_SETTING_TYPE_FLASH_OWNER)
-
- areaEntryMap := map[string][]CfgEntry{}
-
- for _, entry := range entries {
- if entry.Value != "" {
- area, ok := flashMap.Areas[entry.Value]
- if !ok {
- conflict := CfgFlashConflict{
- SettingNames: []string{entry.Name},
- Code: CFG_FLASH_CONFLICT_CODE_BAD_NAME,
- }
- cfg.FlashConflicts = append(cfg.FlashConflicts, conflict)
- } else {
- areaEntryMap[area.Name] =
- append(areaEntryMap[area.Name], entry)
- }
- }
- }
-
- // Settings with type flash_owner must have unique values.
- for _, entries := range areaEntryMap {
- if len(entries) > 1 {
- conflict := CfgFlashConflict{
- SettingNames: []string{},
- Code: CFG_FLASH_CONFLICT_CODE_NOT_UNIQUE,
- }
-
- for _, entry := range entries {
- conflict.SettingNames =
- append(conflict.SettingNames, entry.Name)
- }
-
- cfg.FlashConflicts = append(cfg.FlashConflicts, conflict)
- }
- }
-}
-
-func (cfg *Cfg) flashConflictErrorText(conflict CfgFlashConflict) string {
- entry := cfg.Settings[conflict.SettingNames[0]]
-
- switch conflict.Code {
- case CFG_FLASH_CONFLICT_CODE_BAD_NAME:
- return fmt.Sprintf("Setting %s specifies unknown flash area: %s\n",
- entry.Name, entry.Value)
-
- case CFG_FLASH_CONFLICT_CODE_NOT_UNIQUE:
- return fmt.Sprintf(
- "Multiple flash_owner settings specify the same flash area\n"+
- " settings: %s\n"+
- " flash area: %s\n",
- strings.Join(conflict.SettingNames, ", "),
- entry.Value)
-
- default:
- panic("Invalid flash conflict code: " + string(conflict.Code))
- }
-}
-
-func historyTextOnce(settingName string, points []CfgPoint) string {
- return fmt.Sprintf(" %s: %s\n", settingName, historyToString(points))
-}
-
-func historyText(historyMap map[string][]CfgPoint) string {
- if len(historyMap) == 0 {
- return ""
- }
-
- str := "Setting history (newest -> oldest):\n"
- names := make([]string, 0, len(historyMap))
- for name, _ := range historyMap {
- names = append(names, name)
- }
- sort.Strings(names)
-
- for _, name := range names {
- points := historyMap[name]
- str += historyTextOnce(name, points)
- }
-
- return str
-}
-
-func (cfg *Cfg) ErrorText() string {
- str := ""
-
- historyMap := map[string][]CfgPoint{}
-
- if len(cfg.Violations) > 0 {
- str += "Syscfg restriction violations detected:\n"
- for settingName, rslice := range cfg.Violations {
- baseEntry := cfg.Settings[settingName]
- historyMap[settingName] = baseEntry.History
- for _, r := range rslice {
- for _, name := range r.relevantSettingNames() {
- reqEntry := cfg.Settings[name]
- historyMap[name] = reqEntry.History
- }
- str += " " + cfg.violationText(baseEntry, r) + "\n"
- }
- }
- }
-
- if len(cfg.Ambiguities) > 0 {
- str += "Syscfg ambiguities detected:\n"
-
- settingNames := make([]string, 0, len(cfg.Ambiguities))
- for k, _ := range cfg.Ambiguities {
- settingNames = append(settingNames, k)
- }
- sort.Strings(settingNames)
-
- for _, name := range settingNames {
- entry := cfg.Settings[name]
- historyMap[entry.Name] = entry.History
- str += " " + entry.ambiguityText()
- }
- }
-
- if len(cfg.PriorityViolations) > 0 {
- str += "Priority violations detected (Packages can only override " +
- "settings defined by packages of lower priority):\n"
- for _, priority := range cfg.PriorityViolations {
- entry := cfg.Settings[priority.SettingName]
- historyMap[priority.SettingName] = entry.History
-
- str += fmt.Sprintf(" Package: %s overriding setting: %s defined by %s\n",
- priority.PackageSrc.Name(), priority.SettingName, priority.PackageDef.Name())
- }
- }
-
- if len(cfg.FlashConflicts) > 0 {
- str += "Flash errors detected:\n"
- for _, conflict := range cfg.FlashConflicts {
- for _, name := range conflict.SettingNames {
- entry := cfg.Settings[name]
- historyMap[name] = entry.History
- }
-
- str += " " + cfg.flashConflictErrorText(conflict)
- }
- }
-
- if str == "" {
- return ""
- }
-
- str += "\n" + historyText(historyMap)
-
- return strings.TrimSpace(str)
-}
-
-func (cfg *Cfg) WarningText() string {
- str := ""
-
- historyMap := map[string][]CfgPoint{}
-
- if len(cfg.Orphans) > 0 {
- settingNames := make([]string, len(cfg.Orphans))
- i := 0
- for k, _ := range cfg.Orphans {
- settingNames[i] = k
- i++
- }
- sort.Strings(settingNames)
-
- str += "Ignoring override of undefined settings:"
- for _, n := range settingNames {
- historyMap[n] = cfg.Orphans[n]
- str += fmt.Sprintf("\n %s", n)
- }
- }
-
- if str == "" {
- return ""
- }
-
- str += "\n" + historyText(historyMap)
-
- return str
-}
-
-func escapeStr(s string) string {
- return strings.ToUpper(util.CIdentifier(s))
-}
-
-func settingName(setting string) string {
- return SYSCFG_PREFIX_SETTING + escapeStr(setting)
-}
-
-func normalizePkgType(typ interfaces.PackageType) interfaces.PackageType {
- switch typ {
- case pkg.PACKAGE_TYPE_TARGET:
- return pkg.PACKAGE_TYPE_TARGET
- case pkg.PACKAGE_TYPE_APP:
- return pkg.PACKAGE_TYPE_APP
- case pkg.PACKAGE_TYPE_UNITTEST:
- return pkg.PACKAGE_TYPE_UNITTEST
- case pkg.PACKAGE_TYPE_BSP:
- return pkg.PACKAGE_TYPE_BSP
- default:
- return pkg.PACKAGE_TYPE_LIB
- }
-}
-
-func categorizePkgs(
- lpkgs []*pkg.LocalPackage) map[interfaces.PackageType][]*pkg.LocalPackage {
-
- pmap := map[interfaces.PackageType][]*pkg.LocalPackage{
- pkg.PACKAGE_TYPE_TARGET: []*pkg.LocalPackage{},
- pkg.PACKAGE_TYPE_APP: []*pkg.LocalPackage{},
- pkg.PACKAGE_TYPE_UNITTEST: []*pkg.LocalPackage{},
- pkg.PACKAGE_TYPE_BSP: []*pkg.LocalPackage{},
- pkg.PACKAGE_TYPE_LIB: []*pkg.LocalPackage{},
- }
-
- for _, lpkg := range lpkgs {
- typ := normalizePkgType(lpkg.Type())
- pmap[typ] = append(pmap[typ], lpkg)
- }
-
- for k, v := range pmap {
- pmap[k] = pkg.SortLclPkgs(v)
- }
-
- return pmap
-}
-
-func (cfg *Cfg) readDefsForPkgType(lpkgs []*pkg.LocalPackage,
- features map[string]bool) error {
-
- for _, lpkg := range lpkgs {
- if err := cfg.readDefsOnce(lpkg, features); err != nil {
- return err
- }
- }
- return nil
-}
-func (cfg *Cfg) readValsForPkgType(lpkgs []*pkg.LocalPackage,
- features map[string]bool) error {
-
- for _, lpkg := range lpkgs {
- if err := cfg.readValsOnce(lpkg, features); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (cfg *Cfg) detectAmbiguities() {
- for _, entry := range cfg.Settings {
- if points := entry.ambiguities(); len(points) > 0 {
- cfg.Ambiguities[entry.Name] = points
- }
- }
-}
-
-func Read(lpkgs []*pkg.LocalPackage, apis []string,
- injectedSettings map[string]string, features map[string]bool,
- flashMap flash.FlashMap) (Cfg, error) {
-
- cfg := NewCfg()
- for k, v := range injectedSettings {
- cfg.Settings[k] = CfgEntry{
- Name: k,
- Description: "Injected setting",
- Value: v,
- History: []CfgPoint{{
- Value: v,
- Source: nil,
- }},
- }
-
- if ValueIsTrue(v) {
- features[k] = true
- }
- }
-
- // Read system configuration files. In case of conflicting settings, the
- // higher priority pacakge's setting wins. Package priorities are assigned
- // as follows (highest priority first):
- // * target
- // * app (if present)
- // * unittest (if no app)
- // * bsp
- // * everything else (lib, sdk, compiler)
-
- lpkgMap := categorizePkgs(lpkgs)
-
- for _, ptype := range []interfaces.PackageType{
- pkg.PACKAGE_TYPE_LIB,
- pkg.PACKAGE_TYPE_BSP,
- pkg.PACKAGE_TYPE_UNITTEST,
- pkg.PACKAGE_TYPE_APP,
- pkg.PACKAGE_TYPE_TARGET,
- } {
- if err := cfg.readDefsForPkgType(lpkgMap[ptype], features); err != nil {
- return cfg, err
- }
- }
-
- for _, ptype := range []interfaces.PackageType{
- pkg.PACKAGE_TYPE_LIB,
- pkg.PACKAGE_TYPE_BSP,
- pkg.PACKAGE_TYPE_UNITTEST,
- pkg.PACKAGE_TYPE_APP,
- pkg.PACKAGE_TYPE_TARGET,
- } {
- if err := cfg.readValsForPkgType(lpkgMap[ptype], features); err != nil {
- return cfg, err
- }
- }
-
- cfg.detectAmbiguities()
- cfg.detectViolations()
- cfg.detectFlashConflicts(flashMap)
-
- return cfg, nil
-}
-
-func mostRecentPoint(entry CfgEntry) CfgPoint {
- if len(entry.History) == 0 {
- panic("invalid cfg entry; len(history) == 0")
- }
-
- return entry.History[len(entry.History)-1]
-}
-
-func calcPriorities(cfg Cfg, settingType CfgSettingType, max int,
- allowDups bool) error {
-
- // setting-name => entry
- anyEntries := map[string]CfgEntry{}
-
- // priority-value => entry
- valEntries := map[int]CfgEntry{}
-
- for name, entry := range cfg.Settings {
- if entry.SettingType == settingType {
- if entry.Value == SYSCFG_PRIO_ANY {
- anyEntries[name] = entry
- } else {
- prio, err := util.AtoiNoOct(entry.Value)
- if err != nil {
- return util.FmtNewtError(
- "invalid priority value: setting=%s value=%s pkg=%s",
- name, entry.Value, entry.History[0].Name())
- }
-
- if prio > max {
- return util.FmtNewtError(
- "invalid priority value: value too great (> %d); "+
- "setting=%s value=%s pkg=%s",
- max, entry.Name, entry.Value,
- mostRecentPoint(entry).Name())
- }
-
- if !allowDups {
- if oldEntry, ok := valEntries[prio]; ok {
- return util.FmtNewtError(
- "duplicate priority value: setting1=%s "+
- "setting2=%s pkg1=%s pkg2=%s value=%s",
- oldEntry.Name, entry.Name, entry.Value,
- oldEntry.History[0].Name(),
- entry.History[0].Name())
- }
- }
-
- valEntries[prio] = entry
- }
- }
- }
-
- greatest := 0
- for prio, _ := range valEntries {
- if prio > greatest {
- greatest = prio
- }
- }
-
- anyNames := make([]string, 0, len(anyEntries))
- for name, _ := range anyEntries {
- anyNames = append(anyNames, name)
- }
- sort.Strings(anyNames)
-
- for _, name := range anyNames {
- entry := anyEntries[name]
-
- greatest++
- if greatest > max {
- return util.FmtNewtError("could not assign 'any' priority: "+
- "value too great (> %d); setting=%s value=%s pkg=%s",
- max, name, greatest,
- mostRecentPoint(entry).Name())
- }
-
- entry.Value = strconv.Itoa(greatest)
- cfg.Settings[name] = entry
- }
-
- return nil
-}
-
-func writeCheckMacros(w io.Writer) {
- s := `/**
- * This macro exists to ensure code includes this header when needed. If code
- * checks the existence of a setting directly via ifdef without including this
- * header, the setting macro will silently evaluate to 0. In contrast, an
- * attempt to use these macros without including this header will result in a
- * compiler error.
- */
-#define MYNEWT_VAL(x) MYNEWT_VAL_ ## x
-`
- fmt.Fprintf(w, "%s\n", s)
-}
-
-func writeComment(entry CfgEntry, w io.Writer) {
- if len(entry.History) > 1 {
- fmt.Fprintf(w, "/* Overridden by %s (defined by %s) */\n",
- mostRecentPoint(entry).Name(),
- entry.History[0].Name())
- }
-}
-
-func writeDefine(key string, value string, w io.Writer) {
- if value == "" {
- fmt.Fprintf(w, "#undef %s\n", key)
- } else {
- fmt.Fprintf(w, "#ifndef %s\n", key)
- fmt.Fprintf(w, "#define %s (%s)\n", key, value)
- fmt.Fprintf(w, "#endif\n")
- }
-}
-
-func EntriesByPkg(cfg Cfg) map[string][]CfgEntry {
- pkgEntries := map[string][]CfgEntry{}
- for _, v := range cfg.Settings {
- name := v.History[0].Name()
- pkgEntries[name] = append(pkgEntries[name], v)
- }
- return pkgEntries
-}
-
-func writeSettingsOnePkg(cfg Cfg, pkgName string, pkgEntries []CfgEntry,
- w io.Writer) {
-
- names := make([]string, len(pkgEntries), len(pkgEntries))
- for i, entry := range pkgEntries {
- names[i] = entry.Name
- }
-
- if len(names) == 0 {
- return
- }
- sort.Strings(names)
-
- fmt.Fprintf(w, "/*** %s */\n", pkgName)
-
- first := true
- for _, n := range names {
- entry := cfg.Settings[n]
- if first {
- first = false
- } else {
- fmt.Fprintf(w, "\n")
- }
-
- writeComment(entry, w)
- writeDefine(settingName(n), entry.Value, w)
- }
-}
-
-func writeSettings(cfg Cfg, w io.Writer) {
- // Group settings by package name so that the generated header file is
- // easier to read.
- pkgEntries := EntriesByPkg(cfg)
-
- pkgNames := make([]string, 0, len(pkgEntries))
- for name, _ := range pkgEntries {
- pkgNames = append(pkgNames, name)
- }
- sort.Strings(pkgNames)
-
- for _, name := range pkgNames {
- fmt.Fprintf(w, "\n")
- entries := pkgEntries[name]
- writeSettingsOnePkg(cfg, name, entries, w)
- }
-}
-
-func write(cfg Cfg, w io.Writer) {
- fmt.Fprintf(w, newtutil.GeneratedPreamble())
-
- fmt.Fprintf(w, "#ifndef H_MYNEWT_SYSCFG_\n")
- fmt.Fprintf(w, "#define H_MYNEWT_SYSCFG_\n\n")
-
- writeCheckMacros(w)
- fmt.Fprintf(w, "\n")
-
- writeSettings(cfg, w)
- fmt.Fprintf(w, "\n")
-
- fmt.Fprintf(w, "#endif\n")
-}
-
-func EnsureWritten(cfg Cfg, includeDir string) error {
- // XXX: Detect these problems at error text generation time.
- if err := calcPriorities(cfg, CFG_SETTING_TYPE_TASK_PRIO,
- SYSCFG_TASK_PRIO_MAX, false); err != nil {
-
- return err
- }
-
- // XXX: Detect these problems at error text generation time.
- if err := calcPriorities(cfg, CFG_SETTING_TYPE_INTERRUPT_PRIO,
- SYSCFG_INTERRUPT_PRIO_MAX, true); err != nil {
-
- return err
- }
-
- buf := bytes.Buffer{}
- write(cfg, &buf)
-
- path := includeDir + "/" + HEADER_PATH
-
- writeReqd, err := util.FileContentsChanged(path, buf.Bytes())
- if err != nil {
- return err
- }
- if !writeReqd {
- log.Debugf("syscfg unchanged; not writing header file (%s).", path)
- return nil
- }
-
- log.Debugf("syscfg changed; writing header file (%s).", path)
-
- if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
- return util.NewNewtError(err.Error())
- }
-
- if err := ioutil.WriteFile(path, buf.Bytes(), 0644); err != nil {
- return util.NewNewtError(err.Error())
- }
-
- return nil
-}
-
-func KeyValueFromStr(str string) (map[string]string, error) {
- vals := map[string]string{}
-
- if strings.TrimSpace(str) == "" {
- return vals, nil
- }
-
- // Separate syscfg vals are delimited by ':'.
- fields := strings.Split(str, ":")
-
- // Key-value pairs are delimited by '='. If no '=' is present, assume the
- // string is the key name and the value is 1.
- for _, f := range fields {
- if _, err := util.AtoiNoOct(f); err == nil {
- return nil, util.FmtNewtError(
- "Invalid setting name \"%s\"; must not be a number", f)
- }
-
- kv := strings.SplitN(f, "=", 2)
- switch len(kv) {
- case 1:
- vals[f] = "1"
- case 2:
- vals[kv[0]] = kv[1]
- }
- }
-
- return vals, nil
-}
-
-func KeyValueToStr(syscfgKv map[string]string) string {
- str := ""
-
- names := make([]string, 0, len(syscfgKv))
- for k, _ := range syscfgKv {
- names = append(names, k)
- }
- sort.Strings(names)
-
- for i, name := range names {
- if i != 0 {
- str += ":"
- }
-
- str += fmt.Sprintf("%s=%s", name, syscfgKv[name])
- }
-
- return str
-}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/e31a7d31/newt/sysinit/sysinit.go
----------------------------------------------------------------------
diff --git a/newt/sysinit/sysinit.go b/newt/sysinit/sysinit.go
deleted file mode 100644
index 29dc082..0000000
--- a/newt/sysinit/sysinit.go
+++ /dev/null
@@ -1,170 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package sysinit
-
-import (
- "bytes"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "path/filepath"
- "sort"
-
- log "github.com/Sirupsen/logrus"
-
- "mynewt.apache.org/newt/newt/newtutil"
- "mynewt.apache.org/newt/newt/pkg"
- "mynewt.apache.org/newt/util"
-)
-
-type initFunc struct {
- stage int
- name string
- pkg *pkg.LocalPackage
-}
-
-func buildStageMap(pkgs []*pkg.LocalPackage) map[int][]*initFunc {
- sm := map[int][]*initFunc{}
-
- for _, p := range pkgs {
- for name, stage := range p.Init() {
- initFunc := &initFunc{
- stage: stage,
- name: name,
- pkg: p,
- }
- sm[stage] = append(sm[stage], initFunc)
- }
- }
-
- return sm
-}
-
-func writePrototypes(pkgs []*pkg.LocalPackage, w io.Writer) {
- sorted := pkg.SortLclPkgs(pkgs)
- for _, p := range sorted {
- init := p.Init()
- for name, _ := range init {
- fmt.Fprintf(w, "void %s(void);\n", name)
- }
- }
-}
-
-func writeStage(stage int, initFuncs []*initFunc, w io.Writer) {
- fmt.Fprintf(w, " /*** Stage %d */\n", stage)
- for i, initFunc := range initFuncs {
- fmt.Fprintf(w, " /* %d.%d: %s */\n", stage, i, initFunc.pkg.Name())
- fmt.Fprintf(w, " %s();\n", initFunc.name)
- }
-}
-
-func write(pkgs []*pkg.LocalPackage, isLoader bool,
- w io.Writer) {
-
- stageMap := buildStageMap(pkgs)
-
- i := 0
- stages := make([]int, len(stageMap))
- for k, _ := range stageMap {
- stages[i] = k
- i++
- }
- sort.Ints(stages)
-
- fmt.Fprintf(w, newtutil.GeneratedPreamble())
-
- if isLoader {
- fmt.Fprintf(w, "#if SPLIT_LOADER\n\n")
- } else {
- fmt.Fprintf(w, "#if !SPLIT_LOADER\n\n")
- }
-
- writePrototypes(pkgs, w)
-
- var fnName string
- if isLoader {
- fnName = "sysinit_loader"
- } else {
- fnName = "sysinit_app"
- }
-
- fmt.Fprintf(w, "\n")
- fmt.Fprintf(w, "void\n%s(void)\n{\n", fnName)
-
- for _, s := range stages {
- fmt.Fprintf(w, "\n")
- writeStage(s, stageMap[s], w)
- }
-
- fmt.Fprintf(w, "}\n\n")
- fmt.Fprintf(w, "#endif\n")
-}
-
-func writeRequired(contents []byte, path string) (bool, error) {
- oldSrc, err := ioutil.ReadFile(path)
- if err != nil {
- if os.IsNotExist(err) {
- // File doesn't exist; write required.
- return true, nil
- }
-
- return true, util.NewNewtError(err.Error())
- }
-
- rc := bytes.Compare(oldSrc, contents)
- return rc != 0, nil
-}
-
-func EnsureWritten(pkgs []*pkg.LocalPackage, srcDir string, targetName string,
- isLoader bool) error {
-
- buf := bytes.Buffer{}
- write(pkgs, isLoader, &buf)
-
- var path string
- if isLoader {
- path = fmt.Sprintf("%s/%s-sysinit-loader.c", srcDir, targetName)
- } else {
- path = fmt.Sprintf("%s/%s-sysinit-app.c", srcDir, targetName)
- }
-
- writeReqd, err := writeRequired(buf.Bytes(), path)
- if err != nil {
- return err
- }
-
- if !writeReqd {
- log.Debugf("sysinit unchanged; not writing src file (%s).", path)
- return nil
- }
-
- log.Debugf("sysinit changed; writing src file (%s).", path)
-
- if err := os.MkdirAll(filepath.Dir(path), 0755); err != nil {
- return util.NewNewtError(err.Error())
- }
-
- if err := ioutil.WriteFile(path, buf.Bytes(), 0644); err != nil {
- return util.NewNewtError(err.Error())
- }
-
- return nil
-}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/e31a7d31/newt/target/target.go
----------------------------------------------------------------------
diff --git a/newt/target/target.go b/newt/target/target.go
deleted file mode 100644
index 26ca4cf..0000000
--- a/newt/target/target.go
+++ /dev/null
@@ -1,293 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package target
-
-import (
- "os"
- "path/filepath"
- "sort"
- "strings"
-
- "mynewt.apache.org/newt/newt/pkg"
- "mynewt.apache.org/newt/newt/project"
- "mynewt.apache.org/newt/newt/repo"
- "mynewt.apache.org/newt/util"
- "mynewt.apache.org/newt/yaml"
-)
-
-const TARGET_FILENAME string = "target.yml"
-const DEFAULT_BUILD_PROFILE string = "default"
-
-var globalTargetMap map[string]*Target
-
-type Target struct {
- basePkg *pkg.LocalPackage
-
- BspName string
- AppName string
- LoaderName string
- BuildProfile string
-
- // target.yml configuration structure
- Vars map[string]string
-}
-
-func NewTarget(basePkg *pkg.LocalPackage) *Target {
- target := &Target{}
- target.Init(basePkg)
- return target
-}
-
-func LoadTarget(basePkg *pkg.LocalPackage) (*Target, error) {
- target := NewTarget(basePkg)
- if err := target.Load(basePkg); err != nil {
- return nil, err
- }
-
- return target, nil
-}
-
-func (target *Target) Init(basePkg *pkg.LocalPackage) {
- target.basePkg = basePkg
-}
-
-func (target *Target) Load(basePkg *pkg.LocalPackage) error {
- v, err := util.ReadConfig(basePkg.BasePath(),
- strings.TrimSuffix(TARGET_FILENAME, ".yml"))
- if err != nil {
- return err
- }
-
- target.Vars = map[string]string{}
-
- settings := v.AllSettings()
- for k, v := range settings {
- target.Vars[k] = v.(string)
- }
-
- target.BspName = target.Vars["target.bsp"]
- target.AppName = target.Vars["target.app"]
- target.LoaderName = target.Vars["target.loader"]
- target.BuildProfile = target.Vars["target.build_profile"]
-
- if target.BuildProfile == "" {
- target.BuildProfile = DEFAULT_BUILD_PROFILE
- }
-
- // Note: App not required in the case of unit tests.
-
- // Remember the name of the configuration file so that it can be specified
- // as a dependency to the compiler.
- target.basePkg.AddCfgFilename(basePkg.BasePath() + TARGET_FILENAME)
-
- return nil
-}
-
-func (target *Target) Validate(appRequired bool) error {
- if target.BspName == "" {
- return util.NewNewtError("Target does not specify a BSP package " +
- "(target.bsp)")
- }
- bsp := target.resolvePackageName(target.BspName)
- if bsp == nil {
- return util.FmtNewtError("Could not resolve BSP package: %s",
- target.BspName)
- }
-
- if bsp.Type() != pkg.PACKAGE_TYPE_BSP {
- return util.FmtNewtError("bsp package (%s) is not of "+
- "type bsp; type is: %s\n", bsp.Name(),
- pkg.PackageTypeNames[bsp.Type()])
- }
-
- if appRequired {
- if target.AppName == "" {
- return util.NewNewtError("Target does not specify an app " +
- "package (target.app)")
- }
- app := target.resolvePackageName(target.AppName)
- if app == nil {
- return util.FmtNewtError("Could not resolve app package: %s",
- target.AppName)
- }
-
- if app.Type() != pkg.PACKAGE_TYPE_APP {
- return util.FmtNewtError("target.app package (%s) is not of "+
- "type app; type is: %s\n", app.Name(),
- pkg.PackageTypeNames[app.Type()])
- }
-
- if target.LoaderName != "" {
- loader := target.resolvePackageName(target.LoaderName)
- if loader == nil {
- return util.FmtNewtError(
- "Could not resolve loader package: %s", target.LoaderName)
- }
-
- if loader.Type() != pkg.PACKAGE_TYPE_APP {
- return util.FmtNewtError(
- "target.loader package (%s) is not of type app; type "+
- "is: %s\n", loader.Name(),
- pkg.PackageTypeNames[loader.Type()])
- }
- }
- }
-
- return nil
-}
-
-func (target *Target) Package() *pkg.LocalPackage {
- return target.basePkg
-}
-
-func (target *Target) Name() string {
- return target.basePkg.Name()
-}
-
-func (target *Target) FullName() string {
- return target.basePkg.FullName()
-}
-
-func (target *Target) ShortName() string {
- return filepath.Base(target.Name())
-}
-
-func (target *Target) Clone(newRepo *repo.Repo, newName string) *Target {
- // Clone the target.
- newTarget := *target
- newTarget.basePkg = target.basePkg.Clone(newRepo, newName)
-
- // Insert the clone into the global target map.
- GetTargets()[newTarget.FullName()] = &newTarget
-
- return &newTarget
-}
-
-func (target *Target) resolvePackageName(name string) *pkg.LocalPackage {
- dep, err := pkg.NewDependency(target.basePkg.Repo(), name)
- if err != nil {
- return nil
- }
-
- pack, ok := project.GetProject().ResolveDependency(dep).(*pkg.LocalPackage)
- if !ok {
- return nil
- }
-
- return pack
-}
-
-func (target *Target) App() *pkg.LocalPackage {
- return target.resolvePackageName(target.AppName)
-}
-
-func (target *Target) Loader() *pkg.LocalPackage {
- return target.resolvePackageName(target.LoaderName)
-}
-
-func (target *Target) Bsp() *pkg.LocalPackage {
- return target.resolvePackageName(target.BspName)
-}
-
-func (target *Target) BinBasePath() string {
- appPkg := target.App()
- if appPkg == nil {
- return ""
- }
-
- return appPkg.BasePath() + "/bin/" + target.Name() + "/" +
- appPkg.Name()
-}
-
-func (target *Target) ElfPath() string {
- return target.BinBasePath() + ".elf"
-}
-
-func (target *Target) ImagePath() string {
- return target.BinBasePath() + ".img"
-}
-
-// Save the target's configuration elements
-func (t *Target) Save() error {
- if err := t.basePkg.Save(); err != nil {
- return err
- }
-
- dirpath := t.basePkg.BasePath()
- filepath := dirpath + "/" + TARGET_FILENAME
- file, err := os.Create(filepath)
- if err != nil {
- return util.NewNewtError(err.Error())
- }
- defer file.Close()
-
- file.WriteString("### Target: " + t.Name() + "\n")
-
- keys := []string{}
- for k, _ := range t.Vars {
- keys = append(keys, k)
- }
- sort.Strings(keys)
-
- for _, k := range keys {
- file.WriteString(k + ": " + yaml.EscapeString(t.Vars[k]) + "\n")
- }
-
- if err := t.basePkg.SaveSyscfgVals(); err != nil {
- return err
- }
-
- return nil
-}
-
-func buildTargetMap() error {
- globalTargetMap = map[string]*Target{}
-
- packs := project.GetProject().PackagesOfType(pkg.PACKAGE_TYPE_TARGET)
- for _, packItf := range packs {
- pack := packItf.(*pkg.LocalPackage)
- target, err := LoadTarget(pack)
- if err != nil {
- nerr := err.(*util.NewtError)
- util.ErrorMessage(util.VERBOSITY_QUIET,
- "Warning: failed to load target \"%s\": %s\n", pack.Name(),
- nerr.Text)
- } else {
- globalTargetMap[pack.FullName()] = target
- }
- }
-
- return nil
-}
-
-func ResetTargets() {
- globalTargetMap = nil
-}
-
-func GetTargets() map[string]*Target {
- if globalTargetMap == nil {
- err := buildTargetMap()
- if err != nil {
- panic(err.Error())
- }
- }
-
- return globalTargetMap
-}
http://git-wip-us.apache.org/repos/asf/incubator-mynewt-newtmgr/blob/e31a7d31/newt/toolchain/compiler.go
----------------------------------------------------------------------
diff --git a/newt/toolchain/compiler.go b/newt/toolchain/compiler.go
deleted file mode 100644
index d2e484c..0000000
--- a/newt/toolchain/compiler.go
+++ /dev/null
@@ -1,1286 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package toolchain
-
-import (
- "fmt"
- "io/ioutil"
- "os"
- "path"
- "path/filepath"
- "regexp"
- "runtime"
- "sort"
- "strconv"
- "strings"
- "sync"
- "time"
-
- log "github.com/Sirupsen/logrus"
-
- "mynewt.apache.org/newt/newt/newtutil"
- "mynewt.apache.org/newt/newt/project"
- "mynewt.apache.org/newt/newt/symbol"
- "mynewt.apache.org/newt/util"
- "mynewt.apache.org/newt/viper"
-)
-
-const COMPILER_FILENAME string = "compiler.yml"
-
-const (
- COMPILER_TYPE_C = 0
- COMPILER_TYPE_ASM = 1
- COMPILER_TYPE_CPP = 2
- COMPILER_TYPE_ARCHIVE = 3
-)
-
-type CompilerInfo struct {
- Includes []string
- Cflags []string
- Lflags []string
- Aflags []string
- IgnoreFiles []*regexp.Regexp
- IgnoreDirs []*regexp.Regexp
-}
-
-type Compiler struct {
- objPathList map[string]bool
- LinkerScripts []string
-
- // Needs to be locked whenever a mutable field in this struct is accessed
- // during a build. Currently, objPathList is the only such member.
- mutex *sync.Mutex
-
- depTracker DepTracker
- ccPath string
- cppPath string
- asPath string
- arPath string
- odPath string
- osPath string
- ocPath string
- ldResolveCircularDeps bool
- ldMapFile bool
- ldBinFile bool
- baseDir string
- srcDir string
- dstDir string
-
- // The info to be applied during compilation.
- info CompilerInfo
-
- // Info read from the compiler package itself. This is kept separate from
- // the rest of the info because it has the lowest priority; it can only be
- // added immediately before compiling beings.
- lclInfo CompilerInfo
-
- // Indicates whether the local compiler info has been appended to the
- // common info set. Ensures the local info only gets added once.
- lclInfoAdded bool
-
- extraDeps []string
-}
-
-type CompilerJob struct {
- Filename string
- Compiler *Compiler
- CompilerType int
-}
-
-func NewCompilerInfo() *CompilerInfo {
- ci := &CompilerInfo{}
- ci.Includes = []string{}
- ci.Cflags = []string{}
- ci.Lflags = []string{}
- ci.Aflags = []string{}
- ci.IgnoreFiles = []*regexp.Regexp{}
- ci.IgnoreDirs = []*regexp.Regexp{}
-
- return ci
-}
-
-// Extracts the base of a flag string. A flag base is used when detecting flag
-// conflicts. If two flags have identicial bases, then they are in conflict.
-func flagsBase(cflags string) string {
- eqIdx := strings.IndexByte(cflags, '=')
- if eqIdx == -1 {
- return cflags
- } else {
- return cflags[:eqIdx]
- }
-}
-
-// Creates a map of flag bases to flag values, i.e.,
-// [flag-base] => flag
-//
-// This is used to make flag conflict detection more efficient.
-func flagsMap(cflags []string) map[string]string {
- hash := map[string]string{}
- for _, cf := range cflags {
- hash[flagsBase(cf)] = cf
- }
-
- return hash
-}
-
-// Appends a new set of flags to an original set. If a new flag conflicts with
-// an original, the new flag is discarded. The assumption is that flags from
-// higher priority packages get added first.
-//
-// This is not terribly efficient: it results in flag maps being generated
-// repeatedly when they could be cached. Any inefficiencies here are probably
-// negligible compared to the time spent compiling and linking. If this
-// assumption turns out to be incorrect, we should cache the flag maps.
-func addFlags(flagType string, orig []string, new []string) []string {
- origMap := flagsMap(orig)
-
- combined := orig
- for _, c := range new {
- newBase := flagsBase(c)
- origVal := origMap[newBase]
- if origVal == "" {
- // New flag; add it.
- combined = append(combined, c)
- } else {
- // Flag already present from a higher priority package; discard the
- // new one.
- if origVal != c {
- log.Debugf("Discarding %s %s in favor of %s", flagType, c,
- origVal)
- }
- }
- }
-
- return combined
-}
-
-func (ci *CompilerInfo) AddCflags(cflags []string) {
- ci.Cflags = addFlags("cflag", ci.Cflags, cflags)
-}
-
-func (ci *CompilerInfo) AddCompilerInfo(newCi *CompilerInfo) {
- ci.Includes = append(ci.Includes, newCi.Includes...)
- ci.Cflags = addFlags("cflag", ci.Cflags, newCi.Cflags)
- ci.Lflags = addFlags("lflag", ci.Lflags, newCi.Lflags)
- ci.Aflags = addFlags("aflag", ci.Aflags, newCi.Aflags)
- ci.IgnoreFiles = append(ci.IgnoreFiles, newCi.IgnoreFiles...)
- ci.IgnoreDirs = append(ci.IgnoreDirs, newCi.IgnoreDirs...)
-}
-
-func NewCompiler(compilerDir string, dstDir string,
- buildProfile string) (*Compiler, error) {
-
- c := &Compiler{
- mutex: &sync.Mutex{},
- objPathList: map[string]bool{},
- baseDir: project.GetProject().BasePath,
- srcDir: "",
- dstDir: dstDir,
- extraDeps: []string{},
- }
-
- c.depTracker = NewDepTracker(c)
-
- util.StatusMessage(util.VERBOSITY_VERBOSE,
- "Loading compiler %s, buildProfile %s\n", compilerDir,
- buildProfile)
- err := c.load(compilerDir, buildProfile)
- if err != nil {
- return nil, err
- }
-
- return c, nil
-}
-
-func loadFlags(v *viper.Viper, features map[string]bool,
- key string) []string {
-
- flags := []string{}
-
- rawFlags := newtutil.GetStringSliceFeatures(v, features, key)
- for _, rawFlag := range rawFlags {
- if strings.HasPrefix(rawFlag, key) {
- expandedFlags := newtutil.GetStringSliceFeatures(v, features,
- rawFlag)
-
- flags = append(flags, expandedFlags...)
- } else {
- flags = append(flags, strings.Trim(rawFlag, "\n"))
- }
- }
-
- return flags
-}
-
-func (c *Compiler) load(compilerDir string, buildProfile string) error {
- v, err := util.ReadConfig(compilerDir, "compiler")
- if err != nil {
- return err
- }
-
- features := map[string]bool{
- buildProfile: true,
- strings.ToUpper(runtime.GOOS): true,
- }
-
- c.ccPath = newtutil.GetStringFeatures(v, features, "compiler.path.cc")
- c.cppPath = newtutil.GetStringFeatures(v, features, "compiler.path.cpp")
- c.asPath = newtutil.GetStringFeatures(v, features, "compiler.path.as")
- c.arPath = newtutil.GetStringFeatures(v, features, "compiler.path.archive")
- c.odPath = newtutil.GetStringFeatures(v, features, "compiler.path.objdump")
- c.osPath = newtutil.GetStringFeatures(v, features, "compiler.path.objsize")
- c.ocPath = newtutil.GetStringFeatures(v, features, "compiler.path.objcopy")
-
- c.lclInfo.Cflags = loadFlags(v, features, "compiler.flags")
- c.lclInfo.Lflags = loadFlags(v, features, "compiler.ld.flags")
- c.lclInfo.Aflags = loadFlags(v, features, "compiler.as.flags")
-
- c.ldResolveCircularDeps, err = newtutil.GetBoolFeatures(v, features,
- "compiler.ld.resolve_circular_deps")
- if err != nil {
- return err
- }
-
- c.ldMapFile, err = newtutil.GetBoolFeatures(v, features,
- "compiler.ld.mapfile")
- if err != nil {
- return err
- }
-
- c.ldBinFile, err = newtutil.GetBoolFeaturesDflt(v, features,
- "compiler.ld.binfile", true)
- if err != nil {
- return err
- }
-
- if len(c.lclInfo.Cflags) == 0 {
- // Assume no Cflags implies an unsupported build profile.
- return util.FmtNewtError("Compiler doesn't support build profile "+
- "specified by target on this OS (build_profile=\"%s\" OS=\"%s\")",
- buildProfile, runtime.GOOS)
- }
-
- return nil
-}
-
-func (c *Compiler) AddInfo(info *CompilerInfo) {
- c.info.AddCompilerInfo(info)
-}
-
-func (c *Compiler) DstDir() string {
- return c.dstDir
-}
-
-func (c *Compiler) SetSrcDir(srcDir string) {
- c.srcDir = filepath.ToSlash(filepath.Clean(srcDir))
-}
-
-func (c *Compiler) AddDeps(depFilenames ...string) {
- c.extraDeps = append(c.extraDeps, depFilenames...)
-}
-
-// Skips compilation of the specified C or assembly file, but adds the name of
-// the object file that would have been generated to the compiler's list of
-// object files. This function is used when the object file is already up to
-// date, so no compilation is necessary. The name of the object file should
-// still be remembered so that it gets linked in to the final library or
-// executable.
-func (c *Compiler) SkipSourceFile(srcFile string) error {
- objPath := c.dstFilePath(srcFile) + ".o"
-
- c.mutex.Lock()
- c.objPathList[filepath.ToSlash(objPath)] = true
- c.mutex.Unlock()
-
- // Update the dependency tracker with the object file's modification time.
- // This is necessary later for determining if the library / executable
- // needs to be rebuilt.
- err := c.depTracker.ProcessFileTime(objPath)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// Generates a string consisting of all the necessary include path (-I)
-// options. The result is sorted and contains no duplicate paths.
-func (c *Compiler) includesStrings() []string {
- if len(c.info.Includes) == 0 {
- return nil
- }
-
- includes := util.SortFields(c.info.Includes...)
-
- tokens := make([]string, len(includes))
- for i, s := range includes {
- s = strings.TrimPrefix(filepath.ToSlash(filepath.Clean(s)), c.baseDir+"/")
- tokens[i] = "-I" + s
- }
-
- return tokens
-}
-
-func (c *Compiler) cflagsStrings() []string {
- cflags := util.SortFields(c.info.Cflags...)
- return cflags
-}
-
-func (c *Compiler) aflagsStrings() []string {
- aflags := util.SortFields(c.info.Aflags...)
- return aflags
-}
-
-func (c *Compiler) lflagsStrings() []string {
- lflags := util.SortFields(c.info.Lflags...)
- return lflags
-}
-
-func (c *Compiler) depsString() string {
- extraDeps := util.SortFields(c.extraDeps...)
- return strings.Join(extraDeps, " ") + "\n"
-}
-
-func (c *Compiler) dstFilePath(srcPath string) string {
- relSrcPath := strings.TrimPrefix(filepath.ToSlash(srcPath), c.baseDir+"/")
- relDstPath := strings.TrimSuffix(relSrcPath, filepath.Ext(srcPath))
- dstPath := fmt.Sprintf("%s/%s", c.dstDir, relDstPath)
- return dstPath
-}
-
-// Calculates the command-line invocation necessary to compile the specified C
-// or assembly file.
-//
-// @param file The filename of the source file to compile.
-// @param compilerType One of the COMPILER_TYPE_[...] constants.
-//
-// @return (success) The command arguments.
-func (c *Compiler) CompileFileCmd(file string, compilerType int) (
- []string, error) {
-
- objPath := c.dstFilePath(file) + ".o"
-
- var cmdName string
- var flags []string
- switch compilerType {
- case COMPILER_TYPE_C:
- cmdName = c.ccPath
- flags = c.cflagsStrings()
- case COMPILER_TYPE_ASM:
- cmdName = c.asPath
-
- // Include both the compiler flags and the assembler flags.
- // XXX: This is not great. We don't have a way of specifying compiler
- // flags without also passing them to the assembler.
- flags = append(c.cflagsStrings(), c.aflagsStrings()...)
- case COMPILER_TYPE_CPP:
- cmdName = c.cppPath
- flags = c.cflagsStrings()
- default:
- return nil, util.NewNewtError("Unknown compiler type")
- }
-
- srcPath := strings.TrimPrefix(file, c.baseDir+"/")
- cmd := []string{cmdName}
- cmd = append(cmd, flags...)
- cmd = append(cmd, c.includesStrings()...)
- cmd = append(cmd, []string{
- "-c",
- "-o",
- objPath,
- srcPath,
- }...)
-
- return cmd, nil
-}
-
-// Generates a dependency Makefile (.d) for the specified source C file.
-//
-// @param file The name of the source file.
-func (c *Compiler) GenDepsForFile(file string) error {
- depPath := c.dstFilePath(file) + ".d"
- depDir := filepath.Dir(depPath)
- if util.NodeNotExist(depDir) {
- os.MkdirAll(depDir, 0755)
- }
-
- srcPath := strings.TrimPrefix(file, c.baseDir+"/")
- cmd := []string{c.ccPath}
- cmd = append(cmd, c.cflagsStrings()...)
- cmd = append(cmd, c.includesStrings()...)
- cmd = append(cmd, []string{"-MM", "-MG", srcPath}...)
-
- o, err := util.ShellCommandLimitDbgOutput(cmd, nil, 0)
- if err != nil {
- return err
- }
-
- // Write the compiler output to a dependency file.
- f, err := os.OpenFile(depPath, os.O_CREATE|os.O_WRONLY|os.O_TRUNC, 0666)
- if err != nil {
- return util.ChildNewtError(err)
- }
- defer f.Close()
-
- if _, err := f.Write(o); err != nil {
- return util.ChildNewtError(err)
- }
-
- // Append the extra dependencies (.yml files) to the .d file.
- objFile := strings.TrimSuffix(file, filepath.Ext(file)) + ".o"
- if _, err := f.WriteString(objFile + ": " + c.depsString()); err != nil {
- return util.NewNewtError(err.Error())
- }
-
- return nil
-}
-
-func serializeCommand(cmd []string) []byte {
- // Use a newline as the separator rather than a space to disambiguate cases
- // where arguments contain spaces.
- return []byte(strings.Join(cmd, "\n"))
-}
-
-// Writes a file containing the command-line invocation used to generate the
-// specified file. The file that this function writes can be used later to
-// determine if the set of compiler options has changed.
-//
-// @param dstFile The output file whose build invocation is being
-// recorded.
-// @param cmd The command strings to write.
-func writeCommandFile(dstFile string, cmd []string) error {
- cmdPath := dstFile + ".cmd"
- content := serializeCommand(cmd)
- err := ioutil.WriteFile(cmdPath, content, 0644)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// Adds the info from the compiler package to the common set if it hasn't
-// already been added. The compiler package's info needs to be added last
-// because the compiler is the lowest priority package.
-func (c *Compiler) ensureLclInfoAdded() {
- if !c.lclInfoAdded {
- log.Debugf("Generating build flags for compiler")
- c.AddInfo(&c.lclInfo)
- c.lclInfoAdded = true
- }
-}
-
-// Compile the specified C or assembly file.
-//
-// @param file The filename of the source file to compile.
-// @param compilerType One of the COMPILER_TYPE_[...] constants.
-func (c *Compiler) CompileFile(file string, compilerType int) error {
- objPath := c.dstFilePath(file) + ".o"
- objDir := filepath.Dir(objPath)
- if util.NodeNotExist(objDir) {
- os.MkdirAll(objDir, 0755)
- }
-
- c.mutex.Lock()
- c.objPathList[filepath.ToSlash(objPath)] = true
- c.mutex.Unlock()
-
- cmd, err := c.CompileFileCmd(file, compilerType)
- if err != nil {
- return err
- }
-
- srcPath := strings.TrimPrefix(file, c.baseDir+"/")
- switch compilerType {
- case COMPILER_TYPE_C:
- util.StatusMessage(util.VERBOSITY_DEFAULT, "Compiling %s\n", srcPath)
- case COMPILER_TYPE_CPP:
- util.StatusMessage(util.VERBOSITY_DEFAULT, "Compiling %s\n", srcPath)
- case COMPILER_TYPE_ASM:
- util.StatusMessage(util.VERBOSITY_DEFAULT, "Assembling %s\n", srcPath)
- default:
- return util.NewNewtError("Unknown compiler type")
- }
-
- _, err = util.ShellCommand(cmd, nil)
- if err != nil {
- return err
- }
-
- err = writeCommandFile(objPath, cmd)
- if err != nil {
- return err
- }
-
- // Tell the dependency tracker that an object file was just rebuilt.
- c.depTracker.MostRecent = time.Now()
-
- return nil
-}
-
-func (c *Compiler) shouldIgnoreFile(file string) bool {
- file = strings.TrimPrefix(file, c.srcDir)
- for _, re := range c.info.IgnoreFiles {
- if match := re.MatchString(file); match {
- return true
- }
- }
-
- return false
-}
-
-func compilerTypeToExts(compilerType int) ([]string, error) {
- switch compilerType {
- case COMPILER_TYPE_C:
- return []string{"c"}, nil
- case COMPILER_TYPE_ASM:
- return []string{"s", "S"}, nil
- case COMPILER_TYPE_CPP:
- return []string{"cc", "cpp", "cxx"}, nil
- case COMPILER_TYPE_ARCHIVE:
- return []string{"a"}, nil
- default:
- return nil, util.NewNewtError("Wrong compiler type specified to " +
- "compilerTypeToExts")
- }
-}
-
-// Compiles all C files matching the specified file glob.
-func (c *Compiler) CompileC(filename string) error {
- filename = filepath.ToSlash(filename)
-
- if c.shouldIgnoreFile(filename) {
- log.Infof("Ignoring %s because package dictates it.", filename)
- return nil
- }
-
- compileRequired, err := c.depTracker.CompileRequired(filename,
- COMPILER_TYPE_C)
- if err != nil {
- return err
- }
- if compileRequired {
- err = c.CompileFile(filename, COMPILER_TYPE_C)
- } else {
- err = c.SkipSourceFile(filename)
- }
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// Compiles all CPP files
-func (c *Compiler) CompileCpp(filename string) error {
- filename = filepath.ToSlash(filename)
-
- if c.shouldIgnoreFile(filename) {
- log.Infof("Ignoring %s because package dictates it.", filename)
- return nil
- }
-
- compileRequired, err := c.depTracker.CompileRequired(filename,
- COMPILER_TYPE_CPP)
- if err != nil {
- return err
- }
-
- if compileRequired {
- err = c.CompileFile(filename, COMPILER_TYPE_CPP)
- } else {
- err = c.SkipSourceFile(filename)
- }
-
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// Compiles all assembly files matching the specified file glob.
-//
-// @param match The file glob specifying which assembly files
-// to compile.
-func (c *Compiler) CompileAs(filename string) error {
- filename = filepath.ToSlash(filename)
-
- if c.shouldIgnoreFile(filename) {
- log.Infof("Ignoring %s because package dictates it.", filename)
- return nil
- }
-
- compileRequired, err := c.depTracker.CompileRequired(filename,
- COMPILER_TYPE_ASM)
- if err != nil {
- return err
- }
- if compileRequired {
- err = c.CompileFile(filename, COMPILER_TYPE_ASM)
- } else {
- err = c.SkipSourceFile(filename)
- }
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// Copies all archive files matching the specified file glob.
-//
-// @param match The file glob specifying which assembly files
-// to compile.
-func (c *Compiler) CopyArchive(filename string) error {
- filename = filepath.ToSlash(filename)
-
- if c.shouldIgnoreFile(filename) {
- log.Infof("Ignoring %s because package dictates it.", filename)
- return nil
- }
-
- tgtFile := c.dstFilePath(filename) + ".a"
- copyRequired, err := c.depTracker.CopyRequired(filename)
- if err != nil {
- return err
- }
- if copyRequired {
- err = util.CopyFile(filename, tgtFile)
- util.StatusMessage(util.VERBOSITY_DEFAULT, "copying %s\n",
- filepath.ToSlash(tgtFile))
- }
-
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func (c *Compiler) processEntry(node os.FileInfo, cType int,
- ignDirs []string) ([]CompilerJob, error) {
-
- // check to see if we ignore this element
- for _, dir := range ignDirs {
- if dir == node.Name() {
- return nil, nil
- }
- }
-
- // Check in the user specified ignore directories
- for _, dir := range c.info.IgnoreDirs {
- if dir.MatchString(node.Name()) {
- return nil, nil
- }
- }
-
- // If not, recurse into the directory. Make the output directory
- // structure mirror that of the source tree.
- prevSrcDir := c.srcDir
- prevDstDir := c.dstDir
-
- c.srcDir += "/" + node.Name()
- c.dstDir += "/" + node.Name()
-
- entries, err := c.RecursiveCollectEntries(cType, ignDirs)
-
- // Restore the compiler destination directory now that the child
- // directory has been fully built.
- c.srcDir = prevSrcDir
- c.dstDir = prevDstDir
-
- return entries, err
-}
-
-func (c *Compiler) RecursiveCollectEntries(cType int,
- ignDirs []string) ([]CompilerJob, error) {
-
- // Make sure the compiler package info is added to the global set.
- c.ensureLclInfoAdded()
-
- if err := os.Chdir(c.baseDir); err != nil {
- return nil, util.ChildNewtError(err)
- }
-
- // Get a list of files in the current directory, and if they are a
- // directory, and that directory is not in the ignDirs variable, then
- // recurse into that directory and compile the files in there
-
- ls, err := ioutil.ReadDir(c.srcDir)
- if err != nil {
- return nil, util.NewNewtError(err.Error())
- }
-
- entries := []CompilerJob{}
- for _, node := range ls {
- if node.IsDir() {
- subEntries, err := c.processEntry(node, cType, ignDirs)
- if err != nil {
- return nil, err
- }
-
- entries = append(entries, subEntries...)
- }
- }
-
- exts, err := compilerTypeToExts(cType)
- if err != nil {
- return nil, err
- }
-
- for _, ext := range exts {
- files, _ := filepath.Glob(c.srcDir + "/*." + ext)
- for _, file := range files {
- entries = append(entries, CompilerJob{
- Filename: file,
- Compiler: c,
- CompilerType: cType,
- })
- }
- }
-
- return entries, nil
-}
-
-func RunJob(record CompilerJob) error {
- switch record.CompilerType {
- case COMPILER_TYPE_C:
- return record.Compiler.CompileC(record.Filename)
- case COMPILER_TYPE_ASM:
- return record.Compiler.CompileAs(record.Filename)
- case COMPILER_TYPE_CPP:
- return record.Compiler.CompileCpp(record.Filename)
- case COMPILER_TYPE_ARCHIVE:
- return record.Compiler.CopyArchive(record.Filename)
- default:
- return util.NewNewtError("Wrong compiler type specified to " +
- "RunJob")
- }
-}
-
-func (c *Compiler) getObjFiles(baseObjFiles []string) []string {
- c.mutex.Lock()
- for objName, _ := range c.objPathList {
- baseObjFiles = append(baseObjFiles, objName)
- }
- c.mutex.Unlock()
-
- sort.Strings(baseObjFiles)
- return baseObjFiles
-}
-
-// Calculates the command-line invocation necessary to link the specified elf
-// file.
-//
-// @param dstFile The filename of the destination elf file to
-// link.
-// @param options Some build options specifying how the elf file
-// gets generated.
-// @param objFiles An array of the source .o and .a filenames.
-//
-// @return (success) The command tokens.
-func (c *Compiler) CompileBinaryCmd(dstFile string, options map[string]bool,
- objFiles []string, keepSymbols []string, elfLib string) []string {
-
- objList := c.getObjFiles(util.UniqueStrings(objFiles))
-
- cmd := []string{
- c.ccPath,
- "-o",
- dstFile,
- }
- cmd = append(cmd, c.cflagsStrings()...)
-
- if elfLib != "" {
- cmd = append(cmd, "-Wl,--just-symbols="+elfLib)
- }
-
- if c.ldResolveCircularDeps {
- cmd = append(cmd, "-Wl,--start-group")
- cmd = append(cmd, objList...)
- cmd = append(cmd, "-Wl,--end-group")
- } else {
- cmd = append(cmd, objList...)
- }
-
- if keepSymbols != nil {
- for _, name := range keepSymbols {
- cmd = append(cmd, "-Wl,--undefined="+name)
- }
- }
-
- cmd = append(cmd, c.lflagsStrings()...)
-
- /* so we don't get multiple global definitions of the same vartiable */
- //cmd += " -Wl,--warn-common "
-
- for _, ls := range c.LinkerScripts {
- cmd = append(cmd, "-T")
- cmd = append(cmd, ls)
- }
- if options["mapFile"] {
- cmd = append(cmd, "-Wl,-Map="+dstFile+".map")
- }
-
- return cmd
-}
-
-// Links the specified elf file.
-//
-// @param dstFile The filename of the destination elf file to
-// link.
-// @param options Some build options specifying how the elf file
-// gets generated.
-// @param objFiles An array of the source .o and .a filenames.
-func (c *Compiler) CompileBinary(dstFile string, options map[string]bool,
- objFiles []string, keepSymbols []string, elfLib string) error {
-
- // Make sure the compiler package info is added to the global set.
- c.ensureLclInfoAdded()
-
- objList := c.getObjFiles(util.UniqueStrings(objFiles))
-
- util.StatusMessage(util.VERBOSITY_DEFAULT, "Linking %s\n", dstFile)
- util.StatusMessage(util.VERBOSITY_VERBOSE, "Linking %s with input files %s\n",
- dstFile, objList)
-
- if elfLib != "" {
- util.StatusMessage(util.VERBOSITY_VERBOSE, "Linking %s with rom image %s\n",
- dstFile, elfLib)
- }
-
- cmd := c.CompileBinaryCmd(dstFile, options, objFiles, keepSymbols, elfLib)
- _, err := util.ShellCommand(cmd, nil)
- if err != nil {
- return err
- }
-
- err = writeCommandFile(dstFile, cmd)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-// Generates the following build artifacts:
-// * lst file
-// * map file
-// * bin file
-//
-// @param elfFilename The filename of the elf file corresponding to
-// the artifacts to be generated.
-// @param options Some build options specifying which artifacts
-// get generated.
-func (c *Compiler) generateExtras(elfFilename string,
- options map[string]bool) error {
-
- if options["binFile"] {
- binFile := elfFilename + ".bin"
- cmd := []string{
- c.ocPath,
- "-R",
- ".bss",
- "-R",
- ".bss.core",
- "-R",
- ".bss.core.nz",
- "-O",
- "binary",
- elfFilename,
- binFile,
- }
- _, err := util.ShellCommand(cmd, nil)
- if err != nil {
- return err
- }
- }
-
- if options["listFile"] {
- listFile := elfFilename + ".lst"
- f, err := os.OpenFile(listFile, os.O_CREATE|os.O_WRONLY|os.O_TRUNC,
- 0666)
- if err != nil {
- return util.NewNewtError(err.Error())
- }
- defer f.Close()
-
- cmd := []string{
- c.odPath,
- "-wxdS",
- elfFilename,
- }
- o, err := util.ShellCommandLimitDbgOutput(cmd, nil, 0)
- if err != nil {
- // XXX: gobjdump appears to always crash. Until we get that sorted
- // out, don't fail the link process if lst generation fails.
- return nil
- }
-
- if _, err := f.Write(o); err != nil {
- return util.ChildNewtError(err)
- }
-
- sects := []string{".text", ".rodata", ".data"}
- for _, sect := range sects {
- cmd := []string{
- c.odPath,
- "-s",
- "-j",
- sect,
- elfFilename,
- }
- o, err := util.ShellCommandLimitDbgOutput(cmd, nil, 0)
- if err != nil {
- if _, err := f.Write(o); err != nil {
- return util.NewNewtError(err.Error())
- }
- }
- }
-
- cmd = []string{
- c.osPath,
- elfFilename,
- }
- o, err = util.ShellCommandLimitDbgOutput(cmd, nil, 0)
- if err != nil {
- return err
- }
- if _, err := f.Write(o); err != nil {
- return util.NewNewtError(err.Error())
- }
- }
-
- return nil
-}
-
-func (c *Compiler) PrintSize(elfFilename string) (string, error) {
- cmd := []string{
- c.osPath,
- elfFilename,
- }
- o, err := util.ShellCommand(cmd, nil)
- if err != nil {
- return "", err
- }
- return string(o), nil
-}
-
-// Links the specified elf file and generates some associated artifacts (lst,
-// bin, and map files).
-//
-// @param binFile The filename of the destination elf file to
-// link.
-// @param options Some build options specifying how the elf file
-// gets generated.
-// @param objFiles An array of the source .o and .a filenames.
-func (c *Compiler) CompileElf(binFile string, objFiles []string,
- keepSymbols []string, elfLib string) error {
- options := map[string]bool{"mapFile": c.ldMapFile,
- "listFile": true, "binFile": c.ldBinFile}
-
- // Make sure the compiler package info is added to the global set.
- c.ensureLclInfoAdded()
-
- linkRequired, err := c.depTracker.LinkRequired(binFile, options,
- objFiles, keepSymbols, elfLib)
- if err != nil {
- return err
- }
- if linkRequired {
- if err := os.MkdirAll(filepath.Dir(binFile), 0755); err != nil {
- return util.NewNewtError(err.Error())
- }
- err := c.CompileBinary(binFile, options, objFiles, keepSymbols, elfLib)
- if err != nil {
- return err
- }
- }
-
- err = c.generateExtras(binFile, options)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func (c *Compiler) RenameSymbolsCmd(
- sm *symbol.SymbolMap, libraryFile string, ext string) []string {
-
- cmd := []string{c.ocPath}
- for s, _ := range *sm {
- cmd = append(cmd, "--redefine-sym")
- cmd = append(cmd, s+"="+s+ext)
- }
-
- cmd = append(cmd, libraryFile)
- return cmd
-}
-
-func (c *Compiler) ParseLibraryCmd(libraryFile string) []string {
- return []string{
- c.odPath,
- "-t",
- libraryFile,
- }
-}
-
-func (c *Compiler) CopySymbolsCmd(infile string, outfile string, sm *symbol.SymbolMap) []string {
-
- cmd := []string{c.ocPath, "-S"}
- for symbol, _ := range *sm {
- cmd = append(cmd, "-K")
- cmd = append(cmd, symbol)
- }
-
- cmd = append(cmd, infile)
- cmd = append(cmd, outfile)
-
- return cmd
-}
-
-// Calculates the command-line invocation necessary to archive the specified
-// static library.
-//
-// @param archiveFile The filename of the library to archive.
-// @param objFiles An array of the source .o filenames.
-//
-// @return The command string.
-func (c *Compiler) CompileArchiveCmd(archiveFile string,
- objFiles []string) []string {
-
- cmd := []string{
- c.arPath,
- "rcs",
- archiveFile,
- }
- cmd = append(cmd, c.getObjFiles(objFiles)...)
- return cmd
-}
-
-func linkerScriptFileName(archiveFile string) string {
- ar_script_name := strings.TrimSuffix(archiveFile, filepath.Ext(archiveFile)) + "_ar.mri"
- return ar_script_name
-}
-
-/* this create a new library combining all of the other libraries */
-func createSplitArchiveLinkerFile(archiveFile string,
- archFiles []string) error {
-
- /* create a name for this script */
- ar_script_name := linkerScriptFileName(archiveFile)
-
- // open the file and write out the script
- f, err := os.OpenFile(ar_script_name, os.O_CREATE|os.O_WRONLY|os.O_TRUNC,
- 0666)
- if err != nil {
- return util.NewNewtError(err.Error())
- }
- defer f.Close()
-
- if _, err := f.WriteString("CREATE " + archiveFile + "\n"); err != nil {
- return util.NewNewtError(err.Error())
- }
-
- for _, arch := range archFiles {
- if _, err := f.WriteString("ADDLIB " + arch + "\n"); err != nil {
- return util.NewNewtError(err.Error())
- }
- }
-
- if _, err := f.WriteString("SAVE\n"); err != nil {
- return util.NewNewtError(err.Error())
- }
-
- if _, err := f.WriteString("END\n"); err != nil {
- return util.NewNewtError(err.Error())
- }
-
- return nil
-}
-
-// calculates the command-line invocation necessary to build a split all
-// archive from the collection of archive files
-func (c *Compiler) BuildSplitArchiveCmd(archiveFile string) string {
-
- str := c.arPath + " -M < " + linkerScriptFileName(archiveFile)
- return str
-}
-
-// Archives the specified static library.
-//
-// @param archiveFile The filename of the library to archive.
-// @param objFiles An array of the source .o filenames.
-func (c *Compiler) CompileArchive(archiveFile string) error {
- objFiles := []string{}
-
- // Make sure the compiler package info is added to the global set.
- c.ensureLclInfoAdded()
-
- arRequired, err := c.depTracker.ArchiveRequired(archiveFile, objFiles)
- if err != nil {
- return err
- }
- if !arRequired {
- return nil
- }
-
- if err := os.MkdirAll(filepath.Dir(archiveFile), 0755); err != nil {
- return util.NewNewtError(err.Error())
- }
-
- // Delete the old archive, if it exists.
- os.Remove(archiveFile)
-
- objList := c.getObjFiles([]string{})
- if objList == nil {
- return nil
- }
-
- if len(objList) == 0 {
- util.StatusMessage(util.VERBOSITY_VERBOSE,
- "Not archiving %s; no object files\n", archiveFile)
- return nil
- }
-
- util.StatusMessage(util.VERBOSITY_DEFAULT, "Archiving %s",
- path.Base(archiveFile))
- util.StatusMessage(util.VERBOSITY_VERBOSE, " with object files %s",
- strings.Join(objList, " "))
- util.StatusMessage(util.VERBOSITY_DEFAULT, "\n")
-
- if err != nil && !os.IsNotExist(err) {
- return util.NewNewtError(err.Error())
- }
-
- cmd := c.CompileArchiveCmd(archiveFile, objFiles)
- _, err = util.ShellCommand(cmd, nil)
- if err != nil {
- return err
- }
-
- err = writeCommandFile(archiveFile, cmd)
- if err != nil {
- return err
- }
-
- return nil
-}
-
-func getParseRexeg() (error, *regexp.Regexp) {
- r, err := regexp.Compile("^([0-9A-Fa-f]+)[\t ]+([lgu! ][w ][C ][W ][Ii ][Dd ][FfO ])[\t ]+([^\t\n\f\r ]+)[\t ]+([0-9a-fA-F]+)[\t ]([^\t\n\f\r ]+)")
-
- if err != nil {
- return err, nil
- }
-
- return nil, r
-}
-
-/* This is a tricky thing to parse. Right now, I keep all the
- * flags together and just store the offset, size, name and flags.
-* 00012970 l .bss 00000000 _end
-* 00011c60 l .init_array 00000000 __init_array_start
-* 00011c60 l .init_array 00000000 __preinit_array_start
-* 000084b0 g F .text 00000034 os_arch_start
-* 00000000 g .debug_aranges 00000000 __HeapBase
-* 00011c88 g O .data 00000008 g_os_task_list
-* 000082cc g F .text 0000004c os_idle_task
-* 000094e0 g F .text 0000002e .hidden __gnu_uldivmod_helper
-* 00000000 g .svc_table 00000000 SVC_Count
-* 000125e4 g O .bss 00000004 g_console_is_init
-* 00009514 g F .text 0000029c .hidden __divdi3
-* 000085a8 g F .text 00000054 os_eventq_put
-*/
-func ParseObjectLine(line string, r *regexp.Regexp) (error, *symbol.SymbolInfo) {
-
- answer := r.FindAllStringSubmatch(line, 11)
-
- if len(answer) == 0 {
- return nil, nil
- }
-
- data := answer[0]
-
- if len(data) != 6 {
- util.StatusMessage(util.VERBOSITY_DEFAULT,
- "Not enough content in object file line --- %s", line)
- return nil, nil
- }
-
- si := symbol.NewSymbolInfo()
-
- si.Name = data[5]
-
- v, err := strconv.ParseUint(data[1], 16, 32)
-
- if err != nil {
- util.StatusMessage(util.VERBOSITY_DEFAULT,
- "Could not convert location from object file line --- %s", line)
- return nil, nil
- }
-
- si.Loc = int(v)
-
- v, err = strconv.ParseUint(data[4], 16, 32)
-
- if err != nil {
- util.StatusMessage(util.VERBOSITY_DEFAULT,
- "Could not convert size form object file line --- %s", line)
- return nil, nil
- }
-
- si.Size = int(v)
- si.Code = data[2]
- si.Section = data[3]
-
- return nil, si
-}
-
-func (c *Compiler) RenameSymbols(sm *symbol.SymbolMap, libraryFile string, ext string) error {
-
- cmd := c.RenameSymbolsCmd(sm, libraryFile, ext)
-
- _, err := util.ShellCommand(cmd, nil)
-
- return err
-}
-
-func (c *Compiler) ParseLibrary(libraryFile string) (error, []byte) {
- cmd := c.ParseLibraryCmd(libraryFile)
-
- out, err := util.ShellCommand(cmd, nil)
- if err != nil {
- return err, nil
- }
- return err, out
-}
-
-func (c *Compiler) CopySymbols(infile string, outfile string, sm *symbol.SymbolMap) error {
- cmd := c.CopySymbolsCmd(infile, outfile, sm)
-
- _, err := util.ShellCommand(cmd, nil)
- if err != nil {
- return err
- }
- return err
-}