diff options
| -rw-r--r-- | cc/libbuildversion/tests/Android.bp | 10 | ||||
| -rw-r--r-- | dexpreopt/class_loader_context.go | 3 | ||||
| -rw-r--r-- | dexpreopt/class_loader_context_test.go | 32 | ||||
| -rw-r--r-- | java/config/config.go | 22 | ||||
| -rw-r--r-- | java/config/makevars.go | 10 | ||||
| -rw-r--r-- | mk2rbc/mk2rbc.go | 103 | ||||
| -rw-r--r-- | mk2rbc/mk2rbc_test.go | 50 | ||||
| -rw-r--r-- | mk2rbc/node.go | 4 | ||||
| -rw-r--r-- | ui/build/config.go | 15 | ||||
| -rw-r--r-- | ui/build/rbe.go | 10 |
10 files changed, 195 insertions, 64 deletions
diff --git a/cc/libbuildversion/tests/Android.bp b/cc/libbuildversion/tests/Android.bp index 0e97fedff..c616a3351 100644 --- a/cc/libbuildversion/tests/Android.bp +++ b/cc/libbuildversion/tests/Android.bp @@ -35,6 +35,16 @@ cc_defaults { dir: "host/", }, }, + linux_musl_x86: { + dist: { + dir: "host32/", + }, + }, + linux_musl_x86_64: { + dist: { + dir: "host/", + }, + }, linux_glibc_x86: { dist: { dir: "host32/", diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go index 36513b64b..d0a6a39df 100644 --- a/dexpreopt/class_loader_context.go +++ b/dexpreopt/class_loader_context.go @@ -678,6 +678,9 @@ func toJsonClassLoaderContext(clcMap ClassLoaderContextMap) jsonClassLoaderConte jClcMap := make(jsonClassLoaderContextMap) for sdkVer, clcs := range clcMap { sdkVerStr := fmt.Sprintf("%d", sdkVer) + if sdkVer == AnySdkVersion { + sdkVerStr = "any" + } jClcMap[sdkVerStr] = toJsonClassLoaderContextRec(clcs) } return jClcMap diff --git a/dexpreopt/class_loader_context_test.go b/dexpreopt/class_loader_context_test.go index 5d3a9d943..614681f50 100644 --- a/dexpreopt/class_loader_context_test.go +++ b/dexpreopt/class_loader_context_test.go @@ -389,6 +389,38 @@ func TestCLCMExcludeLibs(t *testing.T) { }) } +// Test that CLC is correctly serialized to JSON. +func TestCLCtoJSON(t *testing.T) { + ctx := testContext() + optional := false + implicit := true + m := make(ClassLoaderContextMap) + m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil) + m.AddContext(ctx, AnySdkVersion, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil) + android.AssertStringEquals(t, "output CLCM ", `{ + "28": [ + { + "Name": "a", + "Optional": false, + "Implicit": true, + "Host": "out/soong/a.jar", + "Device": "/system/a.jar", + "Subcontexts": [] + } + ], + "any": [ + { + "Name": "b", + "Optional": false, + "Implicit": true, + "Host": "out/soong/b.jar", + "Device": "/system/b.jar", + "Subcontexts": [] + } + ] +}`, m.Dump()) +} + func checkError(t *testing.T, have error, want string) { if have == nil { t.Errorf("\nwant error: '%s'\nhave: none", want) diff --git a/java/config/config.go b/java/config/config.go index 46c91a2f6..d7440022f 100644 --- a/java/config/config.go +++ b/java/config/config.go @@ -68,6 +68,11 @@ var ( "-J-XX:+TieredCompilation", "-J-XX:TieredStopAtLevel=1", } + dexerJavaVmFlagsList = []string{ + `-JXX:OnError="cat hs_err_pid%p.log"`, + "-JXX:CICompilerCount=6", + "-JXX:+UseDynamicNumberOfGCThreads", + } ) func init() { @@ -83,19 +88,14 @@ func init() { // D8 invocations are shorter lived, so we restrict their JIT tiering relative to R8. // Note that the `-JXX` prefix syntax is specific to the R8/D8 invocation wrappers. - exportedVars.ExportStringListStaticVariable("D8Flags", []string{ - `-JXX:OnError="cat hs_err_pid%p.log"`, - "-JXX:CICompilerCount=6", - "-JXX:+UseDynamicNumberOfGCThreads", + exportedVars.ExportStringListStaticVariable("D8Flags", append([]string{ + "-JXmx2048M", "-JXX:+TieredCompilation", "-JXX:TieredStopAtLevel=1", - }) - - exportedVars.ExportStringListStaticVariable("R8Flags", []string{ - `-JXX:OnError="cat hs_err_pid%p.log"`, - "-JXX:CICompilerCount=6", - "-JXX:+UseDynamicNumberOfGCThreads", - }) + }, dexerJavaVmFlagsList...)) + exportedVars.ExportStringListStaticVariable("R8Flags", append([]string{ + "-JXmx2048M", + }, dexerJavaVmFlagsList...)) exportedVars.ExportStringListStaticVariable("CommonJdkFlags", []string{ `-Xmaxerrs 9999999`, diff --git a/java/config/makevars.go b/java/config/makevars.go index bc6848fc3..273aca0b4 100644 --- a/java/config/makevars.go +++ b/java/config/makevars.go @@ -43,9 +43,10 @@ func makeVarsProvider(ctx android.MakeVarsContext) { ctx.Strict("JAVADOC", "${JavadocCmd}") ctx.Strict("COMMON_JDK_FLAGS", "${CommonJdkFlags}") - ctx.Strict("DX", "${D8Cmd}") - ctx.Strict("DX_COMMAND", "${D8Cmd} -JXms16M -JXmx2048M") - ctx.Strict("R8_COMPAT_PROGUARD", "${R8Cmd}") + ctx.Strict("D8", "${D8Cmd}") + ctx.Strict("R8", "${R8Cmd}") + ctx.Strict("D8_COMMAND", "${D8Cmd} ${D8Flags}") + ctx.Strict("R8_COMMAND", "${R8Cmd} ${R8Flags}") ctx.Strict("TURBINE", "${TurbineJar}") @@ -78,9 +79,6 @@ func makeVarsProvider(ctx android.MakeVarsContext) { ctx.Strict("CLASS2NONSDKLIST", "${Class2NonSdkList}") ctx.Strict("HIDDENAPI", "${HiddenAPI}") - ctx.Strict("D8_FLAGS", "${D8Flags}") - ctx.Strict("R8_FLAGS", "${R8Flags}") - ctx.Strict("AIDL", "${AidlCmd}") ctx.Strict("AAPT2", "${Aapt2Cmd}") ctx.Strict("ZIPALIGN", "${ZipAlign}") diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go index 02b3d0859..ada8d2cff 100644 --- a/mk2rbc/mk2rbc.go +++ b/mk2rbc/mk2rbc.go @@ -817,35 +817,40 @@ func (ctx *parseContext) handleSubConfig( // rblf.inherit(handle, _e[0], _e[1]) // var matchingPaths []string - varPath, ok := pathExpr.(*interpolateExpr) - if !ok { - return []starlarkNode{ctx.newBadNode(v, "inherit-product/include argument is too complex")} - } - - pathPattern := []string{varPath.chunks[0]} - for _, chunk := range varPath.chunks[1:] { - if chunk != "" { - pathPattern = append(pathPattern, chunk) + var needsWarning = false + if interpolate, ok := pathExpr.(*interpolateExpr); ok { + pathPattern := []string{interpolate.chunks[0]} + for _, chunk := range interpolate.chunks[1:] { + if chunk != "" { + pathPattern = append(pathPattern, chunk) + } } - } - if pathPattern[0] == "" && len(ctx.includeTops) > 0 { - // If pattern starts from the top. restrict it to the directories where - // we know inherit-product uses dynamically calculated path. + if pathPattern[0] == "" && len(ctx.includeTops) > 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) + } + needsWarning = pathPattern[0] == "" && len(ctx.includeTops) == 0 + } else if len(ctx.includeTops) > 0 { for _, p := range ctx.includeTops { - pathPattern[0] = p - matchingPaths = append(matchingPaths, ctx.findMatchingPaths(pathPattern)...) + matchingPaths = append(matchingPaths, ctx.findMatchingPaths([]string{p, ""})...) } } else { - matchingPaths = ctx.findMatchingPaths(pathPattern) + return []starlarkNode{ctx.newBadNode(v, "inherit-product/include argument is too complex")} } + // Safeguard against $(call inherit-product,$(PRODUCT_PATH)) const maxMatchingFiles = 150 if len(matchingPaths) > maxMatchingFiles { return []starlarkNode{ctx.newBadNode(v, "there are >%d files matching the pattern, please rewrite it", maxMatchingFiles)} } - needsWarning := pathPattern[0] == "" && len(ctx.includeTops) == 0 - res := inheritedDynamicModule{*varPath, []*moduleInfo{}, loadAlways, ctx.errorLocation(v), needsWarning} + res := inheritedDynamicModule{pathExpr, []*moduleInfo{}, loadAlways, ctx.errorLocation(v), needsWarning} for _, p := range matchingPaths { // A product configuration files discovered dynamically may attempt to inherit // from another one which does not exist in this source tree. Prevent load errors @@ -895,8 +900,9 @@ func (p *inheritProductCallParser) parse(ctx *parseContext, v mkparser.Node, arg }) } -func (ctx *parseContext) handleInclude(v mkparser.Node, pathExpr starlarkExpr, loadAlways bool) []starlarkNode { - return ctx.handleSubConfig(v, pathExpr, loadAlways, func(im inheritedModule) starlarkNode { +func (ctx *parseContext) handleInclude(v *mkparser.Directive) []starlarkNode { + loadAlways := v.Name[0] != '-' + return ctx.handleSubConfig(v, ctx.parseMakeString(v, v.Args), loadAlways, func(im inheritedModule) starlarkNode { return &includeNode{im, loadAlways} }) } @@ -1074,6 +1080,18 @@ func (ctx *parseContext) parseCompare(cond *mkparser.Directive) starlarkExpr { return otherOperand } } + if otherOperand.typ() == starlarkTypeList { + fields := strings.Fields(stringOperand) + elements := make([]starlarkExpr, len(fields)) + for i, s := range fields { + elements[i] = &stringLiteralExpr{literal: s} + } + return &eqExpr{ + left: otherOperand, + right: &listExpr{elements}, + isEq: isEq, + } + } if intOperand, err := strconv.Atoi(strings.TrimSpace(stringOperand)); err == nil && otherOperand.typ() == starlarkTypeInt { return &eqExpr{ left: otherOperand, @@ -1119,8 +1137,6 @@ func (ctx *parseContext) parseCompareSpecialCases(directive *mkparser.Directive, switch call.name { case baseName + ".filter": return ctx.parseCompareFilterFuncResult(directive, call, value, isEq) - case baseName + ".expand_wildcard": - return ctx.parseCompareWildcardFuncResult(directive, call, value, !isEq), true case baseName + ".findstring": return ctx.parseCheckFindstringFuncResult(directive, call, value, !isEq), true case baseName + ".strip": @@ -1165,22 +1181,6 @@ func (ctx *parseContext) parseCompareFilterFuncResult(cond *mkparser.Directive, } } -func (ctx *parseContext) parseCompareWildcardFuncResult(directive *mkparser.Directive, - xCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr { - if !isEmptyString(xValue) { - return ctx.newBadExpr(directive, "wildcard result can be compared only to empty: %s", xValue) - } - callFunc := baseName + ".file_wildcard_exists" - if s, ok := xCall.args[0].(*stringLiteralExpr); ok && !strings.ContainsAny(s.literal, "*?{[") { - callFunc = baseName + ".file_exists" - } - var cc starlarkExpr = &callExpr{name: callFunc, args: xCall.args, returnType: starlarkTypeBool} - if !negate { - cc = ¬Expr{cc} - } - return cc -} - func (ctx *parseContext) parseCheckFindstringFuncResult(directive *mkparser.Directive, xCall *callExpr, xValue starlarkExpr, negate bool) starlarkExpr { if isEmptyString(xValue) { @@ -1593,6 +1593,16 @@ func transformNode(node starlarkNode, transformer func(expr starlarkExpr) starla for _, n := range a.actions { transformNode(n, transformer) } + case *inheritNode: + if b, ok := a.module.(inheritedDynamicModule); ok { + b.path = b.path.transform(transformer) + a.module = b + } + case *includeNode: + if b, ok := a.module.(inheritedDynamicModule); ok { + b.path = b.path.transform(transformer) + a.module = b + } } } @@ -1765,10 +1775,23 @@ func (p *evalNodeParser) parse(ctx *parseContext, node mkparser.Node, args *mkpa } case *mkparser.Comment: return []starlarkNode{&commentNode{strings.TrimSpace("#" + n.Comment)}} + case *mkparser.Directive: + if n.Name == "include" || n.Name == "-include" { + return ctx.handleInclude(n) + } + case *mkparser.Variable: + // Technically inherit-product(-if-exists) don't need to be put inside + // an eval, but some makefiles do it, presumably because they copy+pasted + // from a $(eval include ...) + if name, _, ok := ctx.maybeParseFunctionCall(n, n.Name); ok { + if name == "inherit-product" || name == "inherit-product-if-exists" { + return ctx.handleVariable(n) + } + } } } - return []starlarkNode{ctx.newBadNode(node, "Eval expression too complex; only assignments and comments are supported")} + return []starlarkNode{ctx.newBadNode(node, "Eval expression too complex; only assignments, comments, includes, and inherit-products are supported")} } func (ctx *parseContext) parseMakeString(node mkparser.Node, mk *mkparser.MakeString) starlarkExpr { @@ -1828,7 +1851,7 @@ func (ctx *parseContext) handleSimpleStatement(node mkparser.Node) []starlarkNod result = []starlarkNode{res} } case "include", "-include": - result = ctx.handleInclude(node, ctx.parseMakeString(node, x.Args), x.Name[0] != '-') + result = ctx.handleInclude(x) case "ifeq", "ifneq", "ifdef", "ifndef": result = []starlarkNode{ctx.handleIfBlock(x)} default: diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go index 9485a42fc..be04c0412 100644 --- a/mk2rbc/mk2rbc_test.go +++ b/mk2rbc/mk2rbc_test.go @@ -568,14 +568,18 @@ ifeq (,$(wildcard foo.mk)) endif ifneq (,$(wildcard foo*.mk)) endif +ifeq (foo1.mk foo2.mk barxyz.mk,$(wildcard foo*.mk bar*.mk)) +endif `, expected: `load("//build/make/core:product_config.rbc", "rblf") def init(g, handle): cfg = rblf.cfg(handle) - if not rblf.file_exists("foo.mk"): + if not rblf.expand_wildcard("foo.mk"): + pass + if rblf.expand_wildcard("foo*.mk"): pass - if rblf.file_wildcard_exists("foo*.mk"): + if rblf.expand_wildcard("foo*.mk bar*.mk") == ["foo1.mk", "foo2.mk", "barxyz.mk"]: pass `, }, @@ -1142,6 +1146,11 @@ def init(g, handle): MY_PATH:=foo #RBC# include_top vendor/foo1 $(call inherit-product,$(MY_PATH)/cfg.mk) +#RBC# include_top vendor/foo1 +$(call inherit-product,$(MY_OTHER_PATH)) +#RBC# include_top vendor/foo1 +$(foreach f,$(MY_MAKEFILES), \ + $(call inherit-product,$(f))) `, expected: `load("//build/make/core:product_config.rbc", "rblf") load("//vendor/foo1:cfg.star|init", _cfg_init = "init") @@ -1156,6 +1165,21 @@ def init(g, handle): if not _varmod_init: rblf.mkerror("product.mk", "Cannot find %s" % ("%s/cfg.mk" % g["MY_PATH"])) rblf.inherit(handle, _varmod, _varmod_init) + _entry = { + "vendor/foo1/cfg.mk": ("vendor/foo1/cfg", _cfg_init), + }.get(g.get("MY_OTHER_PATH", "")) + (_varmod, _varmod_init) = _entry if _entry else (None, None) + if not _varmod_init: + rblf.mkerror("product.mk", "Cannot find %s" % (g.get("MY_OTHER_PATH", ""))) + rblf.inherit(handle, _varmod, _varmod_init) + for f in rblf.words(g.get("MY_MAKEFILES", "")): + _entry = { + "vendor/foo1/cfg.mk": ("vendor/foo1/cfg", _cfg_init), + }.get(f) + (_varmod, _varmod_init) = _entry if _entry else (None, None) + if not _varmod_init: + rblf.mkerror("product.mk", "Cannot find %s" % (f)) + rblf.inherit(handle, _varmod, _varmod_init) `, }, { @@ -1511,24 +1535,40 @@ $(eval) $(eval MY_VAR := foo) $(eval # This is a test of eval functions) $(eval $(TOO_COMPLICATED) := bar) +$(eval include foo/font.mk) +$(eval $(call inherit-product,vendor/foo1/cfg.mk)) + $(foreach x,$(MY_LIST_VAR), \ $(eval PRODUCT_COPY_FILES += foo/bar/$(x):$(TARGET_COPY_OUT_VENDOR)/etc/$(x)) \ - $(if $(MY_OTHER_VAR),$(eval PRODUCT_COPY_FILES += $(MY_OTHER_VAR):foo/bar/$(x))) \ -) + $(if $(MY_OTHER_VAR),$(eval PRODUCT_COPY_FILES += $(MY_OTHER_VAR):foo/bar/$(x)))) +$(foreach x,$(MY_LIST_VAR), \ + $(eval include foo/$(x).mk)) `, expected: `load("//build/make/core:product_config.rbc", "rblf") +load("//foo:font.star", _font_init = "init") +load("//vendor/foo1:cfg.star", _cfg_init = "init") def init(g, handle): cfg = rblf.cfg(handle) g["MY_VAR"] = "foo" # This is a test of eval functions - rblf.mk2rbc_error("product.mk:5", "Eval expression too complex; only assignments and comments are supported") + rblf.mk2rbc_error("product.mk:5", "Eval expression too complex; only assignments, comments, includes, and inherit-products are supported") + _font_init(g, handle) + rblf.inherit(handle, "vendor/foo1/cfg", _cfg_init) for x in rblf.words(g.get("MY_LIST_VAR", "")): rblf.setdefault(handle, "PRODUCT_COPY_FILES") cfg["PRODUCT_COPY_FILES"] += ("foo/bar/%s:%s/etc/%s" % (x, g.get("TARGET_COPY_OUT_VENDOR", ""), x)).split() if g.get("MY_OTHER_VAR", ""): cfg["PRODUCT_COPY_FILES"] += ("%s:foo/bar/%s" % (g.get("MY_OTHER_VAR", ""), x)).split() + for x in rblf.words(g.get("MY_LIST_VAR", "")): + _entry = { + "foo/font.mk": ("foo/font", _font_init), + }.get("foo/%s.mk" % _x) + (_varmod, _varmod_init) = _entry if _entry else (None, None) + if not _varmod_init: + rblf.mkerror("product.mk", "Cannot find %s" % ("foo/%s.mk" % _x)) + _varmod_init(g, handle) `, }, { diff --git a/mk2rbc/node.go b/mk2rbc/node.go index 7c39b9ead..a01abd8ac 100644 --- a/mk2rbc/node.go +++ b/mk2rbc/node.go @@ -83,7 +83,7 @@ func (im inheritedStaticModule) needsLoadCheck() bool { } type inheritedDynamicModule struct { - path interpolateExpr + path starlarkExpr candidateModules []*moduleInfo loadAlways bool location ErrorLocation @@ -120,7 +120,7 @@ func (i inheritedDynamicModule) emitSelect(gctx *generationContext) { } func (i inheritedDynamicModule) pathExpr() starlarkExpr { - return &i.path + return i.path } func (i inheritedDynamicModule) needsLoadCheck() bool { diff --git a/ui/build/config.go b/ui/build/config.go index e271bfca2..0092ff1ca 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -1223,6 +1223,21 @@ func (c *configImpl) rbeAuth() (string, string) { return "RBE_use_application_default_credentials", "true" } +func (c *configImpl) IsGooglerEnvironment() bool { + cf := "ANDROID_BUILD_ENVIRONMENT_CONFIG" + if v, ok := c.environ.Get(cf); ok { + return v == "googler" + } + return false +} + +func (c *configImpl) GoogleProdCredsExist() bool { + if _, err := exec.Command("/usr/bin/prodcertstatus", "--simple_output", "--nocheck_loas").Output(); err != nil { + return false + } + return true +} + func (c *configImpl) UseRemoteBuild() bool { return c.UseGoma() || c.UseRBE() } diff --git a/ui/build/rbe.go b/ui/build/rbe.go index 8f9a69991..78d37b4c7 100644 --- a/ui/build/rbe.go +++ b/ui/build/rbe.go @@ -119,6 +119,7 @@ func startRBE(ctx Context, config Config) { } func stopRBE(ctx Context, config Config) { + defer checkProdCreds(ctx, config) cmd := Command(ctx, config, "stopRBE bootstrap", rbeCommand(ctx, config, bootstrapCmd), "-shutdown") output, err := cmd.CombinedOutput() if err != nil { @@ -131,6 +132,15 @@ func stopRBE(ctx Context, config Config) { } } +func checkProdCreds(ctx Context, config Config) { + if !config.IsGooglerEnvironment() || config.GoogleProdCredsExist() { + return + } + fmt.Fprintln(ctx.Writer, "") + fmt.Fprintln(ctx.Writer, "\033[33mWARNING: Missing LOAS credentials, please run `gcert`. This will result in failing RBE builds in the future, see go/build-fast#authentication.\033[0m") + fmt.Fprintln(ctx.Writer, "") +} + // DumpRBEMetrics creates a metrics protobuf file containing RBE related metrics. // The protobuf file is created if RBE is enabled and the proxy service has // started. The proxy service is shutdown in order to dump the RBE metrics to the |