diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go index 6403612d7..99008d1c2 100644 --- a/mk2rbc/mk2rbc.go +++ b/mk2rbc/mk2rbc.go @@ -40,7 +40,8 @@ import ( ) const ( - baseUri = "//build/make/core:product_config.rbc" + annotationCommentPrefix = "RBC#" + baseUri = "//build/make/core:product_config.rbc" // The name of the struct exported by the product_config.rbc // that contains the functions and variables available to // product configuration Starlark files. @@ -407,6 +408,7 @@ type parseContext struct { outputDir string dependentModules map[string]*moduleInfo soongNamespaces map[string]map[string]bool + includeTops []string } func newParseContext(ss *StarlarkScript, nodes []mkparser.Node) *parseContext { @@ -452,6 +454,7 @@ func newParseContext(ss *StarlarkScript, nodes []mkparser.Node) *parseContext { variables: make(map[string]variable), dependentModules: make(map[string]*moduleInfo), soongNamespaces: make(map[string]map[string]bool), + includeTops: []string{"vendor/google-devices"}, } ctx.pushVarAssignments() for _, item := range predefined { @@ -810,21 +813,15 @@ func (ctx *parseContext) handleSubConfig( pathPattern = append(pathPattern, chunk) } } - if pathPattern[0] != "" { - matchingPaths = ctx.findMatchingPaths(pathPattern) - } else { - // Heuristics -- if pattern starts from top, restrict it to the directories where - // we know inherit-product uses dynamically calculated path. Restrict it even further - // for certain path which would yield too many useless matches - if len(varPath.chunks) == 2 && varPath.chunks[1] == "/BoardConfigVendor.mk" { - pathPattern[0] = "vendor/google_devices" - matchingPaths = ctx.findMatchingPaths(pathPattern) - } else { - for _, t := range []string{"vendor/qcom", "vendor/google_devices"} { - pathPattern[0] = t - matchingPaths = append(matchingPaths, ctx.findMatchingPaths(pathPattern)...) - } + if pathPattern[0] == "" { + // If pattern starts from the top. restrict it to the directories where + // we know inherit-product uses dynamically calculated path. + for _, p := range ctx.includeTops { + pathPattern[0] = p + matchingPaths = append(matchingPaths, ctx.findMatchingPaths(pathPattern)...) } + } else { + matchingPaths = ctx.findMatchingPaths(pathPattern) } // Safeguard against $(call inherit-product,$(PRODUCT_PATH)) const maxMatchingFiles = 150 @@ -1453,6 +1450,7 @@ func (ctx *parseContext) handleSimpleStatement(node mkparser.Node) bool { handled := true switch x := node.(type) { case *mkparser.Comment: + ctx.maybeHandleAnnotation(x) ctx.insertComment("#" + x.Comment) case *mkparser.Assignment: ctx.handleAssignment(x) @@ -1473,6 +1471,28 @@ func (ctx *parseContext) handleSimpleStatement(node mkparser.Node) bool { return handled } +// Processes annotation. An annotation is a comment that starts with #RBC# and provides +// a conversion hint -- say, where to look for the dynamically calculated inherit/include +// paths. +func (ctx *parseContext) maybeHandleAnnotation(cnode *mkparser.Comment) { + maybeTrim := func(s, prefix string) (string, bool) { + if strings.HasPrefix(s, prefix) { + return strings.TrimSpace(strings.TrimPrefix(s, prefix)), true + } + return s, false + } + annotation, ok := maybeTrim(cnode.Comment, annotationCommentPrefix) + if !ok { + return + } + if p, ok := maybeTrim(annotation, "include_top"); ok { + ctx.includeTops = append(ctx.includeTops, p) + return + } + ctx.errorf(cnode, "unsupported annotation %s", cnode.Comment) + +} + func (ctx *parseContext) insertComment(s string) { ctx.receiver.newNode(&commentNode{strings.TrimSpace(s)}) } diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go index fc4a4a733..b657e7619 100644 --- a/mk2rbc/mk2rbc_test.go +++ b/mk2rbc/mk2rbc_test.go @@ -919,7 +919,7 @@ def init(g, handle): desc: "Dynamic inherit path", mkname: "product.mk", in: ` -MY_PATH=foo +MY_PATH:=foo $(call inherit-product,vendor/$(MY_PATH)/cfg.mk) `, expected: `load("//build/make/core:product_config.rbc", "rblf") @@ -937,6 +937,30 @@ def init(g, handle): if not _varmod_init: rblf.mkerror("cannot") rblf.inherit(handle, _varmod, _varmod_init) +`, + }, + { + desc: "Dynamic inherit with hint", + mkname: "product.mk", + in: ` +MY_PATH:=foo +#RBC# include_top vendor/foo1 +$(call inherit-product,$(MY_PATH)/cfg.mk) +`, + expected: `load("//build/make/core:product_config.rbc", "rblf") +load("//vendor/foo1:cfg.star|init", _cfg_init = "init") + +def init(g, handle): + cfg = rblf.cfg(handle) + g["MY_PATH"] = "foo" + #RBC# include_top vendor/foo1 + _entry = { + "vendor/foo1/cfg.mk": ("_cfg", _cfg_init), + }.get("%s/cfg.mk" % g["MY_PATH"]) + (_varmod, _varmod_init) = _entry if _entry else (None, None) + if not _varmod_init: + rblf.mkerror("cannot") + rblf.inherit(handle, _varmod, _varmod_init) `, }, }