Handle substitution references in mk2rbc
Bug: 201700692
Test: go test
Change-Id: I5ba5e51848e795e39f1f65dc153e4c1530066860
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index d1140fa..d5ff181 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -1332,6 +1332,34 @@
// TODO (asmundak): if we find many, maybe handle them.
return ctx.newBadExpr(node, "SOONG_CONFIG_ variables cannot be referenced, use soong_config_get instead: %s", refDump)
}
+ // Handle substitution references: https://www.gnu.org/software/make/manual/html_node/Substitution-Refs.html
+ if strings.Contains(refDump, ":") {
+ parts := strings.SplitN(refDump, ":", 2)
+ substParts := strings.SplitN(parts[1], "=", 2)
+ if len(substParts) < 2 || strings.Count(substParts[0], "%") > 1 {
+ return ctx.newBadExpr(node, "Invalid substitution reference")
+ }
+ if !strings.Contains(substParts[0], "%") {
+ if strings.Contains(substParts[1], "%") {
+ return ctx.newBadExpr(node, "A substitution reference must have a %% in the \"before\" part of the substitution if it has one in the \"after\" part.")
+ }
+ substParts[0] = "%" + substParts[0]
+ substParts[1] = "%" + substParts[1]
+ }
+ v := ctx.addVariable(parts[0])
+ if v == nil {
+ return ctx.newBadExpr(node, "unknown variable %s", refDump)
+ }
+ return &callExpr{
+ name: "patsubst",
+ returnType: knownFunctions["patsubst"].returnType,
+ args: []starlarkExpr{
+ &stringLiteralExpr{literal: substParts[0]},
+ &stringLiteralExpr{literal: substParts[1]},
+ &variableRefExpr{v, ctx.lastAssignment(v.name()) != nil},
+ },
+ }
+ }
if v := ctx.addVariable(refDump); v != nil {
return &variableRefExpr{v, ctx.lastAssignment(v.name()) != nil}
}
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index 0048ad1..78444c9 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -1114,6 +1114,23 @@
g["TEST_VAR_3"] = (g["TEST_VAR_LIST"] if g["TEST_VAR"] else [])
`,
},
+ {
+ desc: "substitution references",
+ mkname: "product.mk",
+ in: `
+SOURCES := foo.c bar.c
+OBJECTS := $(SOURCES:.c=.o)
+OBJECTS2 := $(SOURCES:%.c=%.o)
+`,
+ expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+ cfg = rblf.cfg(handle)
+ g["SOURCES"] = "foo.c bar.c"
+ g["OBJECTS"] = rblf.mkpatsubst("%.c", "%.o", g["SOURCES"])
+ g["OBJECTS2"] = rblf.mkpatsubst("%.c", "%.o", g["SOURCES"])
+`,
+ },
}
var known_variables = []struct {