diff options
67 files changed, 1868 insertions, 712 deletions
@@ -1,17 +1,22 @@ # This file is included by several other projects as the list of people # approving build related projects. +# AMER ahumesky@google.com asmundak@google.com ccross@android.com cparsons@google.com dwillemsen@google.com eakammer@google.com -jingwen@google.com joeo@google.com -lberki@google.com +spandandas@google.com +yuntaoxu@google.com + +# APAC +jingwen@google.com ruperts@google.com -# To expedite LON reviews +# EMEA hansson@google.com +lberki@google.com paulduffin@google.com diff --git a/android/arch.go b/android/arch.go index 340f136c7..cc70eee9c 100644 --- a/android/arch.go +++ b/android/arch.go @@ -1987,6 +1987,10 @@ func (m *ModuleBase) GetArchVariantProperties(ctx ArchVariantContext, propertySe axisToProps[bazel.OsConfigurationAxis] = osToProp axisToProps[bazel.OsArchConfigurationAxis] = archOsToProp + axisToProps[bazel.BionicConfigurationAxis] = map[string]interface{}{ + "bionic": getTargetStruct(ctx, propertySet, archProperties, "Bionic"), + } + return axisToProps } diff --git a/android/bazel.go b/android/bazel.go index 992d8aa27..46212dc33 100644 --- a/android/bazel.go +++ b/android/bazel.go @@ -129,7 +129,7 @@ var ( // Keep any existing BUILD files (and do not generate new BUILD files) for these directories bp2buildKeepExistingBuildFile = map[string]bool{ // This is actually build/bazel/build.BAZEL symlinked to ./BUILD - ".":/*recrusive = */ false, + ".":/*recursive = */ false, "build/bazel":/* recursive = */ true, "build/pesto":/* recursive = */ true, @@ -144,9 +144,10 @@ var ( // Configure modules in these directories to enable bp2build_available: true or false by default. bp2buildDefaultConfig = Bp2BuildConfig{ - "bionic": Bp2BuildDefaultTrueRecursively, - "external/gwp_asan": Bp2BuildDefaultTrueRecursively, - "system/core/libcutils": Bp2BuildDefaultTrueRecursively, + "bionic": Bp2BuildDefaultTrueRecursively, + "build/bazel/examples/apex/minimal": Bp2BuildDefaultTrueRecursively, + "external/gwp_asan": Bp2BuildDefaultTrueRecursively, + "system/core/libcutils": Bp2BuildDefaultTrueRecursively, "system/core/property_service/libpropertyinfoparser": Bp2BuildDefaultTrueRecursively, "system/libbase": Bp2BuildDefaultTrueRecursively, "system/logging/liblog": Bp2BuildDefaultTrueRecursively, @@ -180,7 +181,6 @@ var ( // also depends on //system/logging/liblog:liblog (http://b/186822772) "libc_ndk", // http://b/187013218, cc_library_static, depends on //bionic/libm:libm (http://b/183064661) "libc_malloc_hooks", // http://b/187016307, cc_library, ld.lld: error: undefined symbol: __malloc_hook - "libm", // http://b/183064661, cc_library, math.h:25:16: error: unexpected token in argument list // http://b/186823769: Needs C++ STL support, includes from unconverted standard libraries in //external/libcxx // c++_static @@ -189,7 +189,7 @@ var ( "libBionicBenchmarksUtils", // cc_library_static, fatal error: 'map' file not found, from libcxx "fmtlib", // cc_library_static, fatal error: 'cassert' file not found, from libcxx "fmtlib_ndk", // cc_library_static, fatal error: 'cassert' file not found - "libbase", // http://b/186826479, cc_library, fatal error: 'memory' file not found, from libcxx + "libbase", // Requires liblog. http://b/186826479, cc_library, fatal error: 'memory' file not found, from libcxx. // http://b/186024507: Includes errors because of the system_shared_libs default value. // Missing -isystem bionic/libc/include through the libc/libm/libdl diff --git a/android/config.go b/android/config.go index ed90c3181..396b1a66b 100644 --- a/android/config.go +++ b/android/config.go @@ -821,6 +821,12 @@ func (c *config) UnbundledBuildApps() bool { return Bool(c.productVariables.Unbundled_build_apps) } +// Returns true if building image that aren't bundled with the platform. +// UnbundledBuild() is always true when this is true. +func (c *config) UnbundledBuildImage() bool { + return Bool(c.productVariables.Unbundled_build_image) +} + // Returns true if building modules against prebuilt SDKs. func (c *config) AlwaysUsePrebuiltSdks() bool { return Bool(c.productVariables.Always_use_prebuilt_sdks) diff --git a/android/module.go b/android/module.go index 196b095dd..11f63bd49 100644 --- a/android/module.go +++ b/android/module.go @@ -2812,44 +2812,85 @@ func (m *moduleContext) blueprintModuleContext() blueprint.ModuleContext { return m.bp } -// SrcIsModule decodes module references in the format ":name" into the module name, or empty string if the input -// was not a module reference. +// SrcIsModule decodes module references in the format ":unqualified-name" or "//namespace:name" +// into the module name, or empty string if the input was not a module reference. func SrcIsModule(s string) (module string) { - if len(s) > 1 && s[0] == ':' { - return s[1:] + if len(s) > 1 { + if s[0] == ':' { + module = s[1:] + if !isUnqualifiedModuleName(module) { + // The module name should be unqualified but is not so do not treat it as a module. + module = "" + } + } else if s[0] == '/' && s[1] == '/' { + module = s + } } - return "" + return module } -// SrcIsModule decodes module references in the format ":name{.tag}" into the module name and tag, ":name" into the -// module name and an empty string for the tag, or empty strings if the input was not a module reference. +// SrcIsModuleWithTag decodes module references in the format ":unqualified-name{.tag}" or +// "//namespace:name{.tag}" into the module name and tag, ":unqualified-name" or "//namespace:name" +// into the module name and an empty string for the tag, or empty strings if the input was not a +// module reference. func SrcIsModuleWithTag(s string) (module, tag string) { - if len(s) > 1 && s[0] == ':' { - module = s[1:] - if tagStart := strings.IndexByte(module, '{'); tagStart > 0 { - if module[len(module)-1] == '}' { - tag = module[tagStart+1 : len(module)-1] - module = module[:tagStart] - return module, tag + if len(s) > 1 { + if s[0] == ':' { + module = s[1:] + } else if s[0] == '/' && s[1] == '/' { + module = s + } + + if module != "" { + if tagStart := strings.IndexByte(module, '{'); tagStart > 0 { + if module[len(module)-1] == '}' { + tag = module[tagStart+1 : len(module)-1] + module = module[:tagStart] + } + } + + if s[0] == ':' && !isUnqualifiedModuleName(module) { + // The module name should be unqualified but is not so do not treat it as a module. + module = "" + tag = "" } } - return module, "" } - return "", "" + + return module, tag +} + +// isUnqualifiedModuleName makes sure that the supplied module is an unqualified module name, i.e. +// does not contain any /. +func isUnqualifiedModuleName(module string) bool { + return strings.IndexByte(module, '/') == -1 } +// sourceOrOutputDependencyTag is the dependency tag added automatically by pathDepsMutator for any +// module reference in a property annotated with `android:"path"` or passed to ExtractSourceDeps +// or ExtractSourcesDeps. +// +// If uniquely identifies the dependency that was added as it contains both the module name used to +// add the dependency as well as the tag. That makes it very simple to find the matching dependency +// in GetModuleFromPathDep as all it needs to do is find the dependency whose tag matches the tag +// used to add it. It does not need to check that the module name as returned by one of +// Module.Name(), BaseModuleContext.OtherModuleName() or ModuleBase.BaseModuleName() matches the +// name supplied in the tag. That means it does not need to handle differences in module names +// caused by prebuilt_ prefix, or fully qualified module names. type sourceOrOutputDependencyTag struct { blueprint.BaseDependencyTag + + // The name of the module. + moduleName string + + // The tag that will be passed to the module's OutputFileProducer.OutputFiles(tag) method. tag string } -func sourceOrOutputDepTag(tag string) blueprint.DependencyTag { - return sourceOrOutputDependencyTag{tag: tag} +func sourceOrOutputDepTag(moduleName, tag string) blueprint.DependencyTag { + return sourceOrOutputDependencyTag{moduleName: moduleName, tag: tag} } -// Deprecated, use IsSourceDepTagWithOutputTag(tag, "") instead. -var SourceDepTag = sourceOrOutputDepTag("") - // IsSourceDepTag returns true if the supplied blueprint.DependencyTag is one that was used to add // dependencies by either ExtractSourceDeps, ExtractSourcesDeps or automatically for properties // tagged with `android:"path"`. @@ -2880,7 +2921,7 @@ func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) { ctx.ModuleErrorf("found source dependency duplicate: %q!", s) } else { set[s] = true - ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m) + ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m) } } } @@ -2893,7 +2934,7 @@ func ExtractSourcesDeps(ctx BottomUpMutatorContext, srcFiles []string) { func ExtractSourceDeps(ctx BottomUpMutatorContext, s *string) { if s != nil { if m, t := SrcIsModuleWithTag(*s); m != "" { - ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m) + ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m) } } } diff --git a/android/module_test.go b/android/module_test.go index 9ac929179..9e2b0ca29 100644 --- a/android/module_test.go +++ b/android/module_test.go @@ -55,6 +55,27 @@ func TestSrcIsModule(t *testing.T) { }, wantModule: "foo:bar", }, + { + name: "fully qualified", + args: args{ + s: "//foo:bar", + }, + wantModule: "//foo:bar", + }, + { + name: "fully qualified with tag", + args: args{ + s: "//foo:bar{.tag}", + }, + wantModule: "//foo:bar{.tag}", + }, + { + name: "invalid unqualified name", + args: args{ + s: ":foo/bar", + }, + wantModule: "", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -128,6 +149,35 @@ func TestSrcIsModuleWithTag(t *testing.T) { }, wantModule: "foo.bar}", }, + { + name: "fully qualified", + args: args{ + s: "//foo:bar", + }, + wantModule: "//foo:bar", + }, + { + name: "fully qualified with tag", + args: args{ + s: "//foo:bar{.tag}", + }, + wantModule: "//foo:bar", + wantTag: ".tag", + }, + { + name: "invalid unqualified name", + args: args{ + s: ":foo/bar", + }, + wantModule: "", + }, + { + name: "invalid unqualified name with tag", + args: args{ + s: ":foo/bar{.tag}", + }, + wantModule: "", + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/android/path_properties.go b/android/path_properties.go index 44467730d..397688064 100644 --- a/android/path_properties.go +++ b/android/path_properties.go @@ -51,7 +51,7 @@ func addPathDepsForProps(ctx BottomUpMutatorContext, props []interface{}) { // Add dependencies to anything that is a module reference. for _, s := range pathProperties { if m, t := SrcIsModuleWithTag(s); m != "" { - ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(t), m) + ctx.AddDependency(ctx.Module(), sourceOrOutputDepTag(m, t), m) } } } diff --git a/android/paths.go b/android/paths.go index c5e4806cf..bec8a51a2 100644 --- a/android/paths.go +++ b/android/paths.go @@ -88,7 +88,8 @@ func GlobFiles(ctx EarlyModulePathContext, globPattern string, excludes []string // the Path methods that rely on module dependencies having been resolved. type ModuleWithDepsPathContext interface { EarlyModulePathContext - GetDirectDepWithTag(name string, tag blueprint.DependencyTag) blueprint.Module + VisitDirectDepsBlueprint(visit func(blueprint.Module)) + OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag } // ModuleMissingDepsPathContext is a subset of *ModuleContext methods required by @@ -484,10 +485,27 @@ func getPathsFromModuleDep(ctx ModuleWithDepsPathContext, path, moduleName, tag // // If tag is "" then the returned module will be the dependency that was added for ":moduleName". // Otherwise, it is the dependency that was added for ":moduleName{tag}". -// -// TODO(b/193228441) Make this handle fully qualified names, e.g. //namespace:moduleName. func GetModuleFromPathDep(ctx ModuleWithDepsPathContext, moduleName, tag string) blueprint.Module { - return ctx.GetDirectDepWithTag(moduleName, sourceOrOutputDepTag(tag)) + var found blueprint.Module + // The sourceOrOutputDepTag uniquely identifies the module dependency as it contains both the + // module name and the tag. Dependencies added automatically for properties tagged with + // `android:"path"` are deduped so are guaranteed to be unique. It is possible for duplicate + // dependencies to be added manually using ExtractSourcesDeps or ExtractSourceDeps but even then + // it will always be the case that the dependencies will be identical, i.e. the same tag and same + // moduleName referring to the same dependency module. + // + // It does not matter whether the moduleName is a fully qualified name or if the module + // dependency is a prebuilt module. All that matters is the same information is supplied to + // create the tag here as was supplied to create the tag when the dependency was added so that + // this finds the matching dependency module. + expectedTag := sourceOrOutputDepTag(moduleName, tag) + ctx.VisitDirectDepsBlueprint(func(module blueprint.Module) { + depTag := ctx.OtherModuleDependencyTag(module) + if depTag == expectedTag { + found = module + } + }) + return found } // PathsAndMissingDepsForModuleSrcExcludes returns a Paths{} containing the resolved references in @@ -1268,10 +1286,11 @@ var _ resPathProvider = SourcePath{} // PathForModuleSrc returns a Path representing the paths... under the // module's local source directory. func PathForModuleSrc(ctx ModuleMissingDepsPathContext, pathComponents ...string) Path { - p, err := validatePath(pathComponents...) - if err != nil { - reportPathError(ctx, err) - } + // Just join the components textually just to make sure that it does not corrupt a fully qualified + // module reference, e.g. if the pathComponents is "://other:foo" then using filepath.Join() or + // validatePath() will corrupt it, e.g. replace "//" with "/". If the path is not a module + // reference then it will be validated by expandOneSrcPath anyway when it calls expandOneSrcPath. + p := strings.Join(pathComponents, string(filepath.Separator)) paths, err := expandOneSrcPath(ctx, p, nil) if err != nil { if depErr, ok := err.(missingDependencyError); ok { diff --git a/android/paths_test.go b/android/paths_test.go index 6f5d79e7e..f4e4ce16e 100644 --- a/android/paths_test.go +++ b/android/paths_test.go @@ -1125,6 +1125,12 @@ type pathForModuleSrcTestCase struct { rels []string src string rel string + + // Make test specific preparations to the test fixture. + preparer FixturePreparer + + // A test specific error handler. + errorHandler FixtureErrorHandler } func testPathForModuleSrc(t *testing.T, tests []pathForModuleSrcTestCase) { @@ -1157,14 +1163,23 @@ func testPathForModuleSrc(t *testing.T, tests []pathForModuleSrcTestCase) { "foo/src_special/$": nil, } + errorHandler := test.errorHandler + if errorHandler == nil { + errorHandler = FixtureExpectsNoErrors + } + result := GroupFixturePreparers( FixtureRegisterWithContext(func(ctx RegistrationContext) { ctx.RegisterModuleType("test", pathForModuleSrcTestModuleFactory) ctx.RegisterModuleType("output_file_provider", pathForModuleSrcOutputFileProviderModuleFactory) - ctx.RegisterModuleType("filegroup", FileGroupFactory) }), + PrepareForTestWithFilegroup, + PrepareForTestWithNamespace, mockFS.AddToFixture(), - ).RunTest(t) + OptionalFixturePreparer(test.preparer), + ). + ExtendWithErrorHandler(errorHandler). + RunTest(t) m := result.ModuleForTests("foo", "").Module().(*pathForModuleSrcTestModule) @@ -1333,6 +1348,73 @@ func TestPathForModuleSrc(t *testing.T) { src: "foo/src_special/$", rel: "src_special/$", }, + { + // This test makes sure that an unqualified module name cannot contain characters that make + // it appear as a qualified module name. + name: "output file provider, invalid fully qualified name", + bp: ` + test { + name: "foo", + src: "://other:b", + srcs: ["://other:c"], + }`, + preparer: FixtureAddTextFile("other/Android.bp", ` + soong_namespace {} + + output_file_provider { + name: "b", + outs: ["gen/b"], + } + + output_file_provider { + name: "c", + outs: ["gen/c"], + } + `), + src: "foo/:/other:b", + rel: ":/other:b", + srcs: []string{"foo/:/other:c"}, + rels: []string{":/other:c"}, + }, + { + name: "output file provider, missing fully qualified name", + bp: ` + test { + name: "foo", + src: "//other:b", + srcs: ["//other:c"], + }`, + errorHandler: FixtureExpectsAllErrorsToMatchAPattern([]string{ + `"foo" depends on undefined module "//other:b"`, + `"foo" depends on undefined module "//other:c"`, + }), + }, + { + name: "output file provider, fully qualified name", + bp: ` + test { + name: "foo", + src: "//other:b", + srcs: ["//other:c"], + }`, + src: "out/soong/.intermediates/other/b/gen/b", + rel: "gen/b", + srcs: []string{"out/soong/.intermediates/other/c/gen/c"}, + rels: []string{"gen/c"}, + preparer: FixtureAddTextFile("other/Android.bp", ` + soong_namespace {} + + output_file_provider { + name: "b", + outs: ["gen/b"], + } + + output_file_provider { + name: "c", + outs: ["gen/c"], + } + `), + }, } testPathForModuleSrc(t, tests) diff --git a/android/prebuilt.go b/android/prebuilt.go index f3493bd5a..e61150243 100644 --- a/android/prebuilt.go +++ b/android/prebuilt.go @@ -61,6 +61,16 @@ type PrebuiltProperties struct { // a matching name. Prefer *bool `android:"arch_variant"` + // When specified this names a Soong config variable that controls the prefer property. + // + // If the value of the named Soong config variable is true then prefer is set to false and vice + // versa. If the Soong config variable is not set then it defaults to false, so prefer defaults + // to true. + // + // If specified then the prefer property is ignored in favor of the value of the Soong config + // variable. + Use_source_config_var *ConfigVarProperties + SourceExists bool `blueprint:"mutated"` UsePrebuilt bool `blueprint:"mutated"` @@ -68,6 +78,22 @@ type PrebuiltProperties struct { PrebuiltRenamedToSource bool `blueprint:"mutated"` } +// Properties that can be used to select a Soong config variable. +type ConfigVarProperties struct { + // Allow instances of this struct to be used as a property value in a BpPropertySet. + BpPrintableBase + + // The name of the configuration namespace. + // + // As passed to add_soong_config_namespace in Make. + Config_namespace *string + + // The name of the configuration variable. + // + // As passed to add_soong_config_var_value in Make. + Var_name *string +} + type Prebuilt struct { properties PrebuiltProperties @@ -364,12 +390,18 @@ func (p *Prebuilt) usePrebuilt(ctx TopDownMutatorContext, source Module, prebuil return false } - // TODO: use p.Properties.Name and ctx.ModuleDir to override preference - if Bool(p.properties.Prefer) { + // If source is not available or is disabled then always use the prebuilt. + if source == nil || !source.Enabled() { return true } - return source == nil || !source.Enabled() + // If the use_source_config_var property is set then it overrides the prefer property setting. + if configVar := p.properties.Use_source_config_var; configVar != nil { + return !ctx.Config().VendorConfig(proptools.String(configVar.Config_namespace)).Bool(proptools.String(configVar.Var_name)) + } + + // TODO: use p.Properties.Name and ctx.ModuleDir to override preference + return Bool(p.properties.Prefer) } func (p *Prebuilt) SourceExists() bool { diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go index 23524a533..dcd77ea46 100644 --- a/android/prebuilt_test.go +++ b/android/prebuilt_test.go @@ -26,6 +26,7 @@ var prebuiltsTests = []struct { replaceBp bool // modules is added to default bp boilerplate if false. modules string prebuilt []OsType + preparer FixturePreparer }{ { name: "no prebuilt", @@ -291,6 +292,86 @@ var prebuiltsTests = []struct { }`, prebuilt: []OsType{Android, BuildOs}, }, + { + name: "prebuilt use_source_config_var={acme, use_source} - no var specified", + modules: ` + source { + name: "bar", + } + + prebuilt { + name: "bar", + use_source_config_var: {config_namespace: "acme", var_name: "use_source"}, + srcs: ["prebuilt_file"], + }`, + // When use_source_env is specified then it will use the prebuilt by default if the environment + // variable is not set. + prebuilt: []OsType{Android, BuildOs}, + }, + { + name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=false", + modules: ` + source { + name: "bar", + } + + prebuilt { + name: "bar", + use_source_config_var: {config_namespace: "acme", var_name: "use_source"}, + srcs: ["prebuilt_file"], + }`, + preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) { + variables.VendorVars = map[string]map[string]string{ + "acme": { + "use_source": "false", + }, + } + }), + // Setting the environment variable named in use_source_env to false will cause the prebuilt to + // be used. + prebuilt: []OsType{Android, BuildOs}, + }, + { + name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=true", + modules: ` + source { + name: "bar", + } + + prebuilt { + name: "bar", + use_source_config_var: {config_namespace: "acme", var_name: "use_source"}, + srcs: ["prebuilt_file"], + }`, + preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) { + variables.VendorVars = map[string]map[string]string{ + "acme": { + "use_source": "true", + }, + } + }), + // Setting the environment variable named in use_source_env to true will cause the source to be + // used. + prebuilt: nil, + }, + { + name: "prebuilt use_source_config_var={acme, use_source} - acme_use_source=true, no source", + modules: ` + prebuilt { + name: "bar", + use_source_config_var: {config_namespace: "acme", var_name: "use_source"}, + srcs: ["prebuilt_file"], + }`, + preparer: FixtureModifyProductVariables(func(variables FixtureProductVariables) { + variables.VendorVars = map[string]map[string]string{ + "acme": { + "use_source": "true", + }, + } + }), + // Although the environment variable says to use source there is no source available. + prebuilt: []OsType{Android, BuildOs}, + }, } func TestPrebuilts(t *testing.T) { @@ -329,6 +410,7 @@ func TestPrebuilts(t *testing.T) { }), fs.AddToFixture(), FixtureRegisterWithContext(registerTestPrebuiltModules), + OptionalFixturePreparer(test.preparer), ).RunTestWithBp(t, bp) for _, variant := range result.ModuleVariantsForTests("foo") { diff --git a/android/sdk.go b/android/sdk.go index e70003144..da740f3cd 100644 --- a/android/sdk.go +++ b/android/sdk.go @@ -239,6 +239,12 @@ type SnapshotBuilder interface { // to the zip CopyToSnapshot(src Path, dest string) + // Return the path to an empty file. + // + // This can be used by sdk member types that need to create an empty file in the snapshot, simply + // pass the value returned from this to the CopyToSnapshot() method. + EmptyFile() Path + // Unzip the supplied zip into the snapshot relative directory destDir. UnzipToSnapshot(zipPath Path, destDir string) diff --git a/android/soong_config_modules_test.go b/android/soong_config_modules_test.go index 8f252d944..b2f8eaad8 100644 --- a/android/soong_config_modules_test.go +++ b/android/soong_config_modules_test.go @@ -313,6 +313,51 @@ func TestSoongConfigModule(t *testing.T) { }) } +func TestNonExistentPropertyInSoongConfigModule(t *testing.T) { + bp := ` + soong_config_module_type { + name: "acme_test", + module_type: "test", + config_namespace: "acme", + bool_variables: ["feature1"], + properties: ["made_up_property"], + } + + acme_test { + name: "foo", + cflags: ["-DGENERIC"], + soong_config_variables: { + feature1: { + made_up_property: true, + }, + }, + } + ` + + fixtureForVendorVars := func(vars map[string]map[string]string) FixturePreparer { + return FixtureModifyProductVariables(func(variables FixtureProductVariables) { + variables.VendorVars = vars + }) + } + + GroupFixturePreparers( + fixtureForVendorVars(map[string]map[string]string{"acme": {"feature1": "1"}}), + PrepareForTestWithDefaults, + FixtureRegisterWithContext(func(ctx RegistrationContext) { + ctx.RegisterModuleType("soong_config_module_type_import", soongConfigModuleTypeImportFactory) + ctx.RegisterModuleType("soong_config_module_type", soongConfigModuleTypeFactory) + ctx.RegisterModuleType("soong_config_string_variable", soongConfigStringVariableDummyFactory) + ctx.RegisterModuleType("soong_config_bool_variable", soongConfigBoolVariableDummyFactory) + ctx.RegisterModuleType("test_defaults", soongConfigTestDefaultsModuleFactory) + ctx.RegisterModuleType("test", soongConfigTestModuleFactory) + }), + FixtureWithRootAndroidBp(bp), + ).ExtendWithErrorHandler(FixtureExpectsAllErrorsToMatchAPattern([]string{ + // TODO(b/171232169): improve the error message for non-existent properties + `unrecognized property "soong_config_variables`, + })).RunTest(t) +} + func testConfigWithVendorVars(buildDir, bp string, fs map[string][]byte, vendorVars map[string]map[string]string) Config { config := TestConfig(buildDir, nil, bp, fs) diff --git a/android/variable.go b/android/variable.go index b6e168cbc..bbb98688f 100644 --- a/android/variable.go +++ b/android/variable.go @@ -225,6 +225,7 @@ type productVariables struct { Allow_missing_dependencies *bool `json:",omitempty"` Unbundled_build *bool `json:",omitempty"` Unbundled_build_apps *bool `json:",omitempty"` + Unbundled_build_image *bool `json:",omitempty"` Always_use_prebuilt_sdks *bool `json:",omitempty"` Skip_boot_jars_check *bool `json:",omitempty"` Malloc_not_svelte *bool `json:",omitempty"` diff --git a/apex/apex.go b/apex/apex.go index 11df288a3..d385ac1c3 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -2240,6 +2240,7 @@ func newApexBundle() *apexBundle { android.InitDefaultableModule(module) android.InitSdkAwareModule(module) android.InitOverridableModule(module, &module.overridableProperties.Overrides) + android.InitBazelModule(module) return module } diff --git a/apex/apex_test.go b/apex/apex_test.go index b5b1d4401..422e46c4d 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -4687,16 +4687,26 @@ func TestPrebuiltExportDexImplementationJars(t *testing.T) { p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency) dexJarBuildPath := p.DexJarBuildPath() stem := android.RemoveOptionalPrebuiltPrefix(name) - if expected, actual := ".intermediates/myapex.deapexer/android_common/deapexer/javalib/"+stem+".jar", android.NormalizePathForTesting(dexJarBuildPath); actual != expected { - t.Errorf("Incorrect DexJarBuildPath value '%s', expected '%s'", actual, expected) - } + android.AssertStringEquals(t, "DexJarBuildPath should be apex-related path.", + ".intermediates/myapex.deapexer/android_common/deapexer/javalib/"+stem+".jar", + android.NormalizePathForTesting(dexJarBuildPath)) + } + + checkDexJarInstallPath := func(t *testing.T, ctx *android.TestContext, name string) { + // Make sure the import has been given the correct path to the dex jar. + p := ctx.ModuleForTests(name, "android_common_myapex").Module().(java.UsesLibraryDependency) + dexJarBuildPath := p.DexJarInstallPath() + stem := android.RemoveOptionalPrebuiltPrefix(name) + android.AssertStringEquals(t, "DexJarInstallPath should be apex-related path.", + "target/product/test_device/apex/myapex/javalib/"+stem+".jar", + android.NormalizePathForTesting(dexJarBuildPath)) } ensureNoSourceVariant := func(t *testing.T, ctx *android.TestContext, name string) { // Make sure that an apex variant is not created for the source module. - if expected, actual := []string{"android_common"}, ctx.ModuleVariantsForTests(name); !reflect.DeepEqual(expected, actual) { - t.Errorf("invalid set of variants for %q: expected %q, found %q", "libfoo", expected, actual) - } + android.AssertArrayString(t, "Check if there is no source variant", + []string{"android_common"}, + ctx.ModuleVariantsForTests(name)) } t.Run("prebuilt only", func(t *testing.T) { @@ -4745,8 +4755,10 @@ func TestPrebuiltExportDexImplementationJars(t *testing.T) { } checkDexJarBuildPath(t, ctx, "libfoo") + checkDexJarInstallPath(t, ctx, "libfoo") checkDexJarBuildPath(t, ctx, "libbar") + checkDexJarInstallPath(t, ctx, "libbar") }) t.Run("prebuilt with source preferred", func(t *testing.T) { @@ -4792,9 +4804,11 @@ func TestPrebuiltExportDexImplementationJars(t *testing.T) { ctx := testDexpreoptWithApexes(t, bp, "", transform) checkDexJarBuildPath(t, ctx, "prebuilt_libfoo") + checkDexJarInstallPath(t, ctx, "prebuilt_libfoo") ensureNoSourceVariant(t, ctx, "libfoo") checkDexJarBuildPath(t, ctx, "prebuilt_libbar") + checkDexJarInstallPath(t, ctx, "prebuilt_libbar") ensureNoSourceVariant(t, ctx, "libbar") }) @@ -4842,9 +4856,11 @@ func TestPrebuiltExportDexImplementationJars(t *testing.T) { ctx := testDexpreoptWithApexes(t, bp, "", transform) checkDexJarBuildPath(t, ctx, "prebuilt_libfoo") + checkDexJarInstallPath(t, ctx, "prebuilt_libfoo") ensureNoSourceVariant(t, ctx, "libfoo") checkDexJarBuildPath(t, ctx, "prebuilt_libbar") + checkDexJarInstallPath(t, ctx, "prebuilt_libbar") ensureNoSourceVariant(t, ctx, "libbar") }) } diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go index 279cf54de..7209c0275 100644 --- a/apex/platform_bootclasspath_test.go +++ b/apex/platform_bootclasspath_test.go @@ -398,6 +398,7 @@ func TestPlatformBootclasspath_AlwaysUsePrebuiltSdks(t *testing.T) { name: "foo", prefer: false, shared_library: false, + permitted_packages: ["foo"], public: { jars: ["sdk_library/public/foo-stubs.jar"], stub_srcs: ["sdk_library/public/foo_stub_sources"], diff --git a/bazel/configurability.go b/bazel/configurability.go index 282c6061a..35f194dfe 100644 --- a/bazel/configurability.go +++ b/bazel/configurability.go @@ -91,6 +91,11 @@ var ( conditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map. } + platformBionicMap = map[string]string{ + "bionic": "//build/bazel/platforms/os:bionic", + conditionsDefault: ConditionsDefaultSelectKey, // The default condition of an os select map. + } + platformOsArchMap = map[string]string{ osArchAndroidArm: "//build/bazel/platforms/os_arch:android_arm", osArchAndroidArm64: "//build/bazel/platforms/os_arch:android_arm64", @@ -117,6 +122,7 @@ const ( arch os osArch + bionic productVariables ) @@ -126,6 +132,7 @@ func (ct configurationType) String() string { arch: "arch", os: "os", osArch: "arch_os", + bionic: "bionic", productVariables: "product_variables", }[ct] } @@ -148,6 +155,10 @@ func (ct configurationType) validateConfig(config string) { if _, ok := platformOsArchMap[config]; !ok { panic(fmt.Errorf("Unknown os+arch: %s", config)) } + case bionic: + if _, ok := platformBionicMap[config]; !ok { + panic(fmt.Errorf("Unknown for %s: %s", ct.String(), config)) + } case productVariables: // do nothing default: @@ -167,6 +178,8 @@ func (ct configurationType) SelectKey(config string) string { return platformOsMap[config] case osArch: return platformOsArchMap[config] + case bionic: + return platformBionicMap[config] case productVariables: if config == conditionsDefault { return ConditionsDefaultSelectKey @@ -186,6 +199,8 @@ var ( OsConfigurationAxis = ConfigurationAxis{configurationType: os} // An axis for arch+os-specific configurations OsArchConfigurationAxis = ConfigurationAxis{configurationType: osArch} + // An axis for bionic os-specific configurations + BionicConfigurationAxis = ConfigurationAxis{configurationType: bionic} ) // ProductVariableConfigurationAxis returns an axis for the given product variable diff --git a/bazel/properties.go b/bazel/properties.go index 0dd47da73..2656badb5 100644 --- a/bazel/properties.go +++ b/bazel/properties.go @@ -321,7 +321,7 @@ func (la *LabelAttribute) SetSelectValue(axis ConfigurationAxis, config string, switch axis.configurationType { case noConfig: la.Value = &value - case arch, os, osArch, productVariables: + case arch, os, osArch, bionic, productVariables: if la.ConfigurableValues == nil { la.ConfigurableValues = make(configurableLabels) } @@ -337,7 +337,7 @@ func (la *LabelAttribute) SelectValue(axis ConfigurationAxis, config string) Lab switch axis.configurationType { case noConfig: return *la.Value - case arch, os, osArch, productVariables: + case arch, os, osArch, bionic, productVariables: return *la.ConfigurableValues[axis][config] default: panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis)) @@ -394,7 +394,7 @@ func (ba *BoolAttribute) SetSelectValue(axis ConfigurationAxis, config string, v switch axis.configurationType { case noConfig: ba.Value = value - case arch, os, osArch, productVariables: + case arch, os, osArch, bionic, productVariables: if ba.ConfigurableValues == nil { ba.ConfigurableValues = make(configurableBools) } @@ -410,7 +410,7 @@ func (ba BoolAttribute) SelectValue(axis ConfigurationAxis, config string) *bool switch axis.configurationType { case noConfig: return ba.Value - case arch, os, osArch, productVariables: + case arch, os, osArch, bionic, productVariables: if v, ok := ba.ConfigurableValues[axis][config]; ok { return &v } else { @@ -509,7 +509,7 @@ func (lla *LabelListAttribute) SetSelectValue(axis ConfigurationAxis, config str switch axis.configurationType { case noConfig: lla.Value = list - case arch, os, osArch, productVariables: + case arch, os, osArch, bionic, productVariables: if lla.ConfigurableValues == nil { lla.ConfigurableValues = make(configurableLabelLists) } @@ -525,7 +525,7 @@ func (lla *LabelListAttribute) SelectValue(axis ConfigurationAxis, config string switch axis.configurationType { case noConfig: return lla.Value - case arch, os, osArch, productVariables: + case arch, os, osArch, bionic, productVariables: return lla.ConfigurableValues[axis][config] default: panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis)) @@ -558,6 +558,19 @@ func (lla LabelListAttribute) HasConfigurableValues() bool { return len(lla.ConfigurableValues) > 0 } +// IsEmpty returns true if the attribute has no values under any configuration. +func (lla LabelListAttribute) IsEmpty() bool { + if len(lla.Value.Includes) > 0 { + return false + } + for axis, _ := range lla.ConfigurableValues { + if lla.ConfigurableValues[axis].HasConfigurableValues() { + return false + } + } + return true +} + // ResolveExcludes handles excludes across the various axes, ensuring that items are removed from // the base value and included in default values as appropriate. func (lla *LabelListAttribute) ResolveExcludes() { @@ -669,7 +682,7 @@ func (sla *StringListAttribute) SetSelectValue(axis ConfigurationAxis, config st switch axis.configurationType { case noConfig: sla.Value = list - case arch, os, osArch, productVariables: + case arch, os, osArch, bionic, productVariables: if sla.ConfigurableValues == nil { sla.ConfigurableValues = make(configurableStringLists) } @@ -685,7 +698,7 @@ func (sla *StringListAttribute) SelectValue(axis ConfigurationAxis, config strin switch axis.configurationType { case noConfig: return sla.Value - case arch, os, osArch, productVariables: + case arch, os, osArch, bionic, productVariables: return sla.ConfigurableValues[axis][config] default: panic(fmt.Errorf("Unrecognized ConfigurationAxis %s", axis)) diff --git a/bp2build/apex_conversion_test.go b/bp2build/apex_conversion_test.go index fbf6fa289..f4a1016bc 100644 --- a/bp2build/apex_conversion_test.go +++ b/bp2build/apex_conversion_test.go @@ -46,3 +46,23 @@ apex { manifest = "manifest.json", )`}}) } + +func TestApexBundleHasBazelModuleProps(t *testing.T) { + runApexTestCase(t, bp2buildTestCase{ + description: "apex - has bazel module props", + moduleTypeUnderTest: "apex", + moduleTypeUnderTestFactory: apex.BundleFactory, + moduleTypeUnderTestBp2BuildMutator: apex.ApexBundleBp2Build, + filesystem: map[string]string{}, + blueprint: ` +apex { + name: "apogee", + manifest: "manifest.json", + bazel_module: { bp2build_available: true }, +} +`, + expectedBazelTargets: []string{`apex( + name = "apogee", + manifest = "manifest.json", +)`}}) +} diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index 285677a1c..662d9d11a 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -118,6 +118,7 @@ func TestCcLibrarySimple(t *testing.T) { moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryBp2Build, filesystem: map[string]string{ "android.cpp": "", + "bionic.cpp": "", "darwin.cpp": "", // Refer to cc.headerExts for the supported header extensions in Soong. "header.h": "", @@ -164,6 +165,9 @@ cc_library { darwin: { srcs: ["darwin.cpp"], }, + bionic: { + srcs: ["bionic.cpp"] + }, }, } `, @@ -190,6 +194,9 @@ cc_library { "//build/bazel/platforms/os:darwin": ["darwin.cpp"], "//build/bazel/platforms/os:linux": ["linux.cpp"], "//conditions:default": [], + }) + select({ + "//build/bazel/platforms/os:bionic": ["bionic.cpp"], + "//conditions:default": [], }), )`}}) } @@ -674,6 +681,10 @@ filegroup { blueprint: soongCcLibraryPreamble, expectedBazelTargets: []string{`cc_library( name = "a", + asflags = [ + "-Ifoo/bar", + "-I$(BINDIR)/foo/bar", + ], copts = [ "-Ifoo/bar", "-I$(BINDIR)/foo/bar", diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go index 40edec80b..c33889fc8 100644 --- a/bp2build/cc_library_static_conversion_test.go +++ b/bp2build/cc_library_static_conversion_test.go @@ -1413,7 +1413,7 @@ cc_library_static { func TestCcLibraryStaticProductVariableStringReplacement(t *testing.T) { runCcLibraryStaticTestCase(t, bp2buildTestCase{ - description: "cc_library_static product variable selects", + description: "cc_library_static product variable string replacement", moduleTypeUnderTest: "cc_library_static", moduleTypeUnderTestFactory: cc.LibraryStaticFactory, moduleTypeUnderTestBp2BuildMutator: cc.CcLibraryStaticBp2Build, @@ -1422,7 +1422,7 @@ func TestCcLibraryStaticProductVariableStringReplacement(t *testing.T) { blueprint: soongCcLibraryStaticPreamble + ` cc_library_static { name: "foo_static", - srcs: ["common.c"], + srcs: ["common.S"], product_variables: { platform_sdk_version: { asflags: ["-DPLATFORM_SDK_VERSION=%d"], @@ -1431,7 +1431,10 @@ cc_library_static { } `, expectedBazelTargets: []string{`cc_library_static( name = "foo_static", - asflags = select({ + asflags = [ + "-I.", + "-I$(BINDIR)/.", + ] + select({ "//build/bazel/product_variables:platform_sdk_version": ["-DPLATFORM_SDK_VERSION=$(Platform_sdk_version)"], "//conditions:default": [], }), @@ -1440,7 +1443,7 @@ cc_library_static { "-I$(BINDIR)/.", ], linkstatic = True, - srcs_c = ["common.c"], + srcs_as = ["common.S"], )`}, }) } diff --git a/bp2build/cc_object_conversion_test.go b/bp2build/cc_object_conversion_test.go index 8ede2267d..df4924bfe 100644 --- a/bp2build/cc_object_conversion_test.go +++ b/bp2build/cc_object_conversion_test.go @@ -211,6 +211,7 @@ func TestCcObjectProductVariable(t *testing.T) { asflags: ["-DPLATFORM_SDK_VERSION=%d"], }, }, + srcs: ["src.S"], } `, expectedBazelTargets: []string{`cc_object( @@ -220,6 +221,7 @@ func TestCcObjectProductVariable(t *testing.T) { "//conditions:default": [], }), copts = ["-fno-addrsig"], + srcs_as = ["src.S"], )`, }, }) @@ -240,7 +242,7 @@ func TestCcObjectCflagsOneArch(t *testing.T) { cflags: ["-fPIC"], // string list }, arm: { - srcs: ["arch/arm/file.S"], // label list + srcs: ["arch/arm/file.cpp"], // label list }, }, } @@ -257,7 +259,7 @@ func TestCcObjectCflagsOneArch(t *testing.T) { "//conditions:default": [], }), srcs = ["a.cpp"] + select({ - "//build/bazel/platforms/arch:arm": ["arch/arm/file.S"], + "//build/bazel/platforms/arch:arm": ["arch/arm/file.cpp"], "//conditions:default": [], }), )`, diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go index adb0a7bb9..a60863036 100644 --- a/bpfix/bpfix/bpfix.go +++ b/bpfix/bpfix/bpfix.go @@ -136,6 +136,10 @@ var fixSteps = []FixStep{ Name: "removeScudoProperty", Fix: runPatchListMod(removeObsoleteProperty("sanitize.scudo")), }, + { + Name: "formatFlagProperties", + Fix: runPatchListMod(formatFlagProperties), + }, } func NewFixRequest() FixRequest { @@ -1343,3 +1347,69 @@ func inList(s string, list []string) bool { } return false } + +func formatFlagProperty(mod *parser.Module, field string, buf []byte, patchlist *parser.PatchList) error { + // the comment or empty lines in the value of the field are skipped + listValue, ok := getLiteralListProperty(mod, field) + if !ok { + // if do not find + return nil + } + for i := 0; i < len(listValue.Values); i++ { + curValue, ok := listValue.Values[i].(*parser.String) + if !ok { + return fmt.Errorf("Expecting string for %s.%s fields", mod.Type, field) + } + if !strings.HasPrefix(curValue.Value, "-") { + return fmt.Errorf("Expecting the string `%s` starting with '-'", curValue.Value) + } + if i+1 < len(listValue.Values) { + nextValue, ok := listValue.Values[i+1].(*parser.String) + if !ok { + return fmt.Errorf("Expecting string for %s.%s fields", mod.Type, field) + } + if !strings.HasPrefix(nextValue.Value, "-") { + // delete the line + err := patchlist.Add(curValue.Pos().Offset, curValue.End().Offset+2, "") + if err != nil { + return err + } + // replace the line + value := "\"" + curValue.Value + " " + nextValue.Value + "\"," + err = patchlist.Add(nextValue.Pos().Offset, nextValue.End().Offset+1, value) + if err != nil { + return err + } + // combined two lines to one + i++ + } + } + } + return nil +} + +func formatFlagProperties(mod *parser.Module, buf []byte, patchlist *parser.PatchList) error { + relevantFields := []string{ + // cc flags + "asflags", + "cflags", + "clang_asflags", + "clang_cflags", + "conlyflags", + "cppflags", + "ldflags", + "tidy_flags", + // java flags + "aaptflags", + "dxflags", + "javacflags", + "kotlincflags", + } + for _, field := range relevantFields { + err := formatFlagProperty(mod, field, buf, patchlist) + if err != nil { + return err + } + } + return nil +} diff --git a/bpfix/bpfix/bpfix_test.go b/bpfix/bpfix/bpfix_test.go index b994e2547..d8772c10d 100644 --- a/bpfix/bpfix/bpfix_test.go +++ b/bpfix/bpfix/bpfix_test.go @@ -1336,3 +1336,275 @@ func TestRewriteTestModuleTypes(t *testing.T) { }) } } + +func TestFormatFlagProperty(t *testing.T) { + tests := []struct { + name string + in string + out string + }{ + { + name: "group options and values for apptflags, dxflags, javacflags, and kotlincflags", + in: ` + android_test { + name: "foo", + aaptflags: [ + // comment1_1 + "--flag1", + // comment1_2 + "1", + // comment2_1 + // comment2_2 + "--flag2", + // comment3_1 + // comment3_2 + // comment3_3 + "--flag3", + // comment3_4 + // comment3_5 + // comment3_6 + "3", + // other comment1_1 + // other comment1_2 + ], + dxflags: [ + "--flag1", + // comment1_1 + "1", + // comment2_1 + "--flag2", + // comment3_1 + "--flag3", + // comment3_2 + "3", + ], + javacflags: [ + "--flag1", + + "1", + "--flag2", + "--flag3", + "3", + ], + kotlincflags: [ + + "--flag1", + "1", + + "--flag2", + "--flag3", + "3", + + ], + } + `, + out: ` + android_test { + name: "foo", + aaptflags: [ + // comment1_1 + // comment1_2 + "--flag1 1", + // comment2_1 + // comment2_2 + "--flag2", + // comment3_1 + // comment3_2 + // comment3_3 + // comment3_4 + // comment3_5 + // comment3_6 + "--flag3 3", + // other comment1_1 + // other comment1_2 + ], + dxflags: [ + // comment1_1 + "--flag1 1", + // comment2_1 + "--flag2", + // comment3_1 + // comment3_2 + "--flag3 3", + ], + javacflags: [ + + "--flag1 1", + "--flag2", + "--flag3 3", + ], + kotlincflags: [ + + "--flag1 1", + + "--flag2", + "--flag3 3", + + ], + } + `, + }, + { + name: "group options and values for asflags, cflags, clang_asflags, clang_cflags, conlyflags, cppflags, ldflags, and tidy_flags", + in: ` + cc_test { + name: "foo", + asflags: [ + // comment1_1 + "--flag1", + "1", + // comment2_1 + // comment2_2 + "--flag2", + // comment2_3 + "2", + // comment3_1 + // comment3_2 + "--flag3", + // comment3_3 + // comment3_4 + // comment3_4 + "3", + // comment4_1 + // comment4_2 + // comment4_3 + "--flag4", + ], + cflags: [ + "--flag1", + "1", + "--flag2", + "2", + "--flag3", + "3", + "--flag4", + ], + clang_asflags: [ + "--flag1", + "1", + "--flag2", + "2", + "--flag3", + "3", + "--flag4", + ], + clang_cflags: [ + "--flag1", + "1", + "--flag2", + "2", + "--flag3", + "3", + "--flag4", + ], + conlyflags: [ + "--flag1", + "1", + "--flag2", + "2", + "--flag3", + "3", + "--flag4", + ], + cppflags: [ + "--flag1", + "1", + "--flag2", + "2", + "--flag3", + "3", + "--flag4", + ], + ldflags: [ + "--flag1", + "1", + "--flag2", + "2", + "--flag3", + "3", + "--flag4", + ], + tidy_flags: [ + "--flag1", + "1", + "--flag2", + "2", + "--flag3", + "3", + "--flag4", + ], + } + `, + out: ` + cc_test { + name: "foo", + asflags: [ + // comment1_1 + "--flag1 1", + // comment2_1 + // comment2_2 + // comment2_3 + "--flag2 2", + // comment3_1 + // comment3_2 + // comment3_3 + // comment3_4 + // comment3_4 + "--flag3 3", + // comment4_1 + // comment4_2 + // comment4_3 + "--flag4", + ], + cflags: [ + "--flag1 1", + "--flag2 2", + "--flag3 3", + "--flag4", + ], + clang_asflags: [ + "--flag1 1", + "--flag2 2", + "--flag3 3", + "--flag4", + ], + clang_cflags: [ + "--flag1 1", + "--flag2 2", + "--flag3 3", + "--flag4", + ], + conlyflags: [ + "--flag1 1", + "--flag2 2", + "--flag3 3", + "--flag4", + ], + cppflags: [ + "--flag1 1", + "--flag2 2", + "--flag3 3", + "--flag4", + ], + ldflags: [ + "--flag1 1", + "--flag2 2", + "--flag3 3", + "--flag4", + ], + tidy_flags: [ + "--flag1 1", + "--flag2 2", + "--flag3 3", + "--flag4", + ], + } + `, + }, + } + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + runPass(t, test.in, test.out, runPatchListMod(formatFlagProperties)) + }) + } +} diff --git a/cc/Android.bp b/cc/Android.bp index 46740dcf2..4b750ff25 100644 --- a/cc/Android.bp +++ b/cc/Android.bp @@ -58,6 +58,7 @@ bootstrap_go_package { "binary.go", "binary_sdk_member.go", "fuzz.go", + "fuzz_common.go", "library.go", "library_headers.go", "library_sdk_member.go", diff --git a/cc/androidmk.go b/cc/androidmk.go index e58d166a3..bda10067b 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -401,24 +401,24 @@ func (fuzz *fuzzBinary) AndroidMkEntries(ctx AndroidMkContext, entries *android. ctx.subAndroidMk(entries, fuzz.binaryDecorator) var fuzzFiles []string - for _, d := range fuzz.corpus { + for _, d := range fuzz.fuzzPackagedModule.Corpus { fuzzFiles = append(fuzzFiles, - filepath.Dir(fuzz.corpusIntermediateDir.String())+":corpus/"+d.Base()) + filepath.Dir(fuzz.fuzzPackagedModule.CorpusIntermediateDir.String())+":corpus/"+d.Base()) } - for _, d := range fuzz.data { + for _, d := range fuzz.fuzzPackagedModule.Data { fuzzFiles = append(fuzzFiles, - filepath.Dir(fuzz.dataIntermediateDir.String())+":data/"+d.Rel()) + filepath.Dir(fuzz.fuzzPackagedModule.DataIntermediateDir.String())+":data/"+d.Rel()) } - if fuzz.dictionary != nil { + if fuzz.fuzzPackagedModule.Dictionary != nil { fuzzFiles = append(fuzzFiles, - filepath.Dir(fuzz.dictionary.String())+":"+fuzz.dictionary.Base()) + filepath.Dir(fuzz.fuzzPackagedModule.Dictionary.String())+":"+fuzz.fuzzPackagedModule.Dictionary.Base()) } - if fuzz.config != nil { + if fuzz.fuzzPackagedModule.Config != nil { fuzzFiles = append(fuzzFiles, - filepath.Dir(fuzz.config.String())+":config.json") + filepath.Dir(fuzz.fuzzPackagedModule.Config.String())+":config.json") } entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { diff --git a/cc/bp2build.go b/cc/bp2build.go index 76c5f3be9..536f1125d 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -90,8 +90,11 @@ func depsBp2BuildMutator(ctx android.BottomUpMutatorContext) { // TODO(b/186024507, b/186489250): Temporarily exclude adding // system_shared_libs deps until libc and libm builds. - // allDeps = append(allDeps, lib.SharedProperties.Shared.System_shared_libs...) - // allDeps = append(allDeps, lib.StaticProperties.Static.System_shared_libs...) + if lib.static() { + allDeps = append(allDeps, lib.StaticProperties.Static.System_shared_libs...) + } else if lib.shared() { + allDeps = append(allDeps, lib.SharedProperties.Shared.System_shared_libs...) + } // Deps in the target/arch nested static: { .. } and shared: { .. } props of a cc_library. // target: { <target>: shared: { ... } } @@ -253,7 +256,7 @@ func bp2buildParseStaticOrSharedProps(ctx android.TopDownMutatorContext, module Copts: bazel.StringListAttribute{Value: props.Cflags}, Srcs: bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, props.Srcs)), Static_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Static_libs)), - Dynamic_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, props.Shared_libs)), + Dynamic_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleDeps(ctx, append(props.Shared_libs, props.System_shared_libs...))), Whole_archive_deps: bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDeps(ctx, props.Whole_static_libs)), } @@ -385,16 +388,6 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul return result } - // Parse the list of copts. - parseCopts := func(baseCompilerProps *BaseCompilerProperties) []string { - var copts []string - copts = append(copts, parseCommandLineFlags(baseCompilerProps.Cflags)...) - for _, dir := range parseLocalIncludeDirs(baseCompilerProps) { - copts = append(copts, includeFlags(dir)...) - } - return copts - } - // Parse srcs from an arch or OS's props value. parseSrcs := func(baseCompilerProps *BaseCompilerProperties) bazel.LabelList { // Add srcs-like dependencies such as generated files. @@ -410,11 +403,15 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul for _, props := range module.compiler.compilerProps() { if baseCompilerProps, ok := props.(*BaseCompilerProperties); ok { srcs.SetValue(parseSrcs(baseCompilerProps)) - copts.Value = parseCopts(baseCompilerProps) + copts.Value = parseCommandLineFlags(baseCompilerProps.Cflags) asFlags.Value = parseCommandLineFlags(baseCompilerProps.Asflags) conlyFlags.Value = parseCommandLineFlags(baseCompilerProps.Conlyflags) cppFlags.Value = parseCommandLineFlags(baseCompilerProps.Cppflags) + for _, dir := range parseLocalIncludeDirs(baseCompilerProps) { + copts.Value = append(copts.Value, includeFlags(dir)...) + asFlags.Value = append(asFlags.Value, includeFlags(dir)...) + } break } } @@ -424,8 +421,10 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul // "-I<module-dir>" in its copts. if c, ok := module.compiler.(*baseCompiler); ok && c.includeBuildDirectory() { copts.Value = append(copts.Value, includeFlags(".")...) + asFlags.Value = append(asFlags.Value, includeFlags(".")...) } else if c, ok := module.compiler.(*libraryDecorator); ok && c.includeBuildDirectory() { copts.Value = append(copts.Value, includeFlags(".")...) + asFlags.Value = append(asFlags.Value, includeFlags(".")...) } archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{}) @@ -440,8 +439,15 @@ func bp2BuildParseCompilerProps(ctx android.TopDownMutatorContext, module *Modul srcs.SetSelectValue(axis, config, srcsList) } - copts.SetSelectValue(axis, config, parseCopts(baseCompilerProps)) - asFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Asflags)) + archVariantCopts := parseCommandLineFlags(baseCompilerProps.Cflags) + archVariantAsflags := parseCommandLineFlags(baseCompilerProps.Asflags) + for _, dir := range parseLocalIncludeDirs(baseCompilerProps) { + archVariantCopts = append(archVariantCopts, includeFlags(dir)...) + archVariantAsflags = append(archVariantAsflags, includeFlags(dir)...) + } + + copts.SetSelectValue(axis, config, archVariantCopts) + asFlags.SetSelectValue(axis, config, archVariantAsflags) conlyFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Conlyflags)) cppFlags.SetSelectValue(axis, config, parseCommandLineFlags(baseCompilerProps.Cppflags)) } @@ -554,7 +560,9 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) staticDeps.Value = android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs) wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs) wholeArchiveDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs)) - sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs) + // TODO(b/186024507): Handle system_shared_libs as its own attribute, so that the appropriate default + // may be supported. + sharedLibs := android.FirstUniqueStrings(append(baseLinkerProps.Shared_libs, baseLinkerProps.System_shared_libs...)) dynamicDeps = bazel.MakeLabelListAttribute(android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs)) headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs) @@ -581,7 +589,7 @@ func bp2BuildParseLinkerProps(ctx android.TopDownMutatorContext, module *Module) staticDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, staticLibs, baseLinkerProps.Exclude_static_libs)) wholeArchiveLibs := android.FirstUniqueStrings(baseLinkerProps.Whole_static_libs) wholeArchiveDeps.SetSelectValue(axis, config, android.BazelLabelForModuleWholeDepsExcludes(ctx, wholeArchiveLibs, baseLinkerProps.Exclude_static_libs)) - sharedLibs := android.FirstUniqueStrings(baseLinkerProps.Shared_libs) + sharedLibs := android.FirstUniqueStrings(append(baseLinkerProps.Shared_libs, baseLinkerProps.System_shared_libs...)) dynamicDeps.SetSelectValue(axis, config, android.BazelLabelForModuleDepsExcludes(ctx, sharedLibs, baseLinkerProps.Exclude_shared_libs)) headerLibs := android.FirstUniqueStrings(baseLinkerProps.Header_libs) @@ -756,14 +756,13 @@ func IsTestPerSrcDepTag(depTag blueprint.DependencyTag) bool { // members of the cc.Module to this decorator. Thus, a cc_binary module has custom linker and // installer logic. type Module struct { - android.ModuleBase - android.DefaultableModuleBase - android.ApexModuleBase + FuzzModule + android.SdkBase android.BazelModuleBase - Properties BaseProperties VendorProperties VendorProperties + Properties BaseProperties // initialize before calling Init hod android.HostOrDeviceSupported @@ -2014,9 +2013,9 @@ func AddSharedLibDependenciesWithVersions(ctx android.BottomUpMutatorContext, mo } func GetSnapshot(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android.BottomUpMutatorContext) SnapshotInfo { - // Only modules with BOARD_VNDK_VERSION uses snapshot. Others use the zero value of + // Only device modules with BOARD_VNDK_VERSION uses snapshot. Others use the zero value of // SnapshotInfo, which provides no mappings. - if *snapshotInfo == nil { + if *snapshotInfo == nil && c.Device() { // Only retrieve the snapshot on demand in order to avoid circular dependencies // between the modules in the snapshot and the snapshot itself. var snapshotModule []blueprint.Module @@ -2025,16 +2024,16 @@ func GetSnapshot(c LinkableInterface, snapshotInfo **SnapshotInfo, actx android. } else if recoverySnapshotVersion := actx.DeviceConfig().RecoverySnapshotVersion(); recoverySnapshotVersion != "current" && recoverySnapshotVersion != "" && c.InRecovery() { snapshotModule = actx.AddVariationDependencies(nil, nil, "recovery_snapshot") } - if len(snapshotModule) > 0 { + if len(snapshotModule) > 0 && snapshotModule[0] != nil { snapshot := actx.OtherModuleProvider(snapshotModule[0], SnapshotInfoProvider).(SnapshotInfo) *snapshotInfo = &snapshot // republish the snapshot for use in later mutators on this module actx.SetProvider(SnapshotInfoProvider, snapshot) - } else { - *snapshotInfo = &SnapshotInfo{} } } - + if *snapshotInfo == nil { + *snapshotInfo = &SnapshotInfo{} + } return **snapshotInfo } diff --git a/cc/fuzz.go b/cc/fuzz.go index c780b6f97..8b0f93e0e 100644 --- a/cc/fuzz.go +++ b/cc/fuzz.go @@ -94,19 +94,14 @@ type fuzzBinary struct { *binaryDecorator *baseCompiler - Properties FuzzProperties - dictionary android.Path - corpus android.Paths - corpusIntermediateDir android.Path - config android.Path - data android.Paths - dataIntermediateDir android.Path - installedSharedDeps []string + fuzzPackagedModule FuzzPackagedModule + + installedSharedDeps []string } func (fuzz *fuzzBinary) linkerProps() []interface{} { props := fuzz.binaryDecorator.linkerProps() - props = append(props, &fuzz.Properties) + props = append(props, &fuzz.fuzzPackagedModule.FuzzProperties) return props } @@ -257,41 +252,41 @@ func (fuzz *fuzzBinary) install(ctx ModuleContext, file android.Path) { "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) fuzz.binaryDecorator.baseInstaller.install(ctx, file) - fuzz.corpus = android.PathsForModuleSrc(ctx, fuzz.Properties.Corpus) + fuzz.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Corpus) builder := android.NewRuleBuilder(pctx, ctx) intermediateDir := android.PathForModuleOut(ctx, "corpus") - for _, entry := range fuzz.corpus { + for _, entry := range fuzz.fuzzPackagedModule.Corpus { builder.Command().Text("cp"). Input(entry). Output(intermediateDir.Join(ctx, entry.Base())) } builder.Build("copy_corpus", "copy corpus") - fuzz.corpusIntermediateDir = intermediateDir + fuzz.fuzzPackagedModule.CorpusIntermediateDir = intermediateDir - fuzz.data = android.PathsForModuleSrc(ctx, fuzz.Properties.Data) + fuzz.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Data) builder = android.NewRuleBuilder(pctx, ctx) intermediateDir = android.PathForModuleOut(ctx, "data") - for _, entry := range fuzz.data { + for _, entry := range fuzz.fuzzPackagedModule.Data { builder.Command().Text("cp"). Input(entry). Output(intermediateDir.Join(ctx, entry.Rel())) } builder.Build("copy_data", "copy data") - fuzz.dataIntermediateDir = intermediateDir + fuzz.fuzzPackagedModule.DataIntermediateDir = intermediateDir - if fuzz.Properties.Dictionary != nil { - fuzz.dictionary = android.PathForModuleSrc(ctx, *fuzz.Properties.Dictionary) - if fuzz.dictionary.Ext() != ".dict" { + if fuzz.fuzzPackagedModule.FuzzProperties.Dictionary != nil { + fuzz.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzz.fuzzPackagedModule.FuzzProperties.Dictionary) + if fuzz.fuzzPackagedModule.Dictionary.Ext() != ".dict" { ctx.PropertyErrorf("dictionary", "Fuzzer dictionary %q does not have '.dict' extension", - fuzz.dictionary.String()) + fuzz.fuzzPackagedModule.Dictionary.String()) } } - if fuzz.Properties.Fuzz_config != nil { + if fuzz.fuzzPackagedModule.FuzzProperties.Fuzz_config != nil { configPath := android.PathForModuleOut(ctx, "config").Join(ctx, "config.json") - android.WriteFileRule(ctx, configPath, fuzz.Properties.Fuzz_config.String()) - fuzz.config = configPath + android.WriteFileRule(ctx, configPath, fuzz.fuzzPackagedModule.FuzzProperties.Fuzz_config.String()) + fuzz.fuzzPackagedModule.Config = configPath } // Grab the list of required shared libraries. @@ -359,32 +354,20 @@ func NewFuzz(hod android.HostOrDeviceSupported) *Module { // Responsible for generating GNU Make rules that package fuzz targets into // their architecture & target/host specific zip file. -type fuzzPackager struct { - packages android.Paths +type ccFuzzPackager struct { + FuzzPackager sharedLibInstallStrings []string - fuzzTargets map[string]bool } func fuzzPackagingFactory() android.Singleton { - return &fuzzPackager{} -} - -type fileToZip struct { - SourceFilePath android.Path - DestinationPathPrefix string -} - -type archOs struct { - hostOrTarget string - arch string - dir string + return &ccFuzzPackager{} } -func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { +func (s *ccFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { // Map between each architecture + host/device combination, and the files that // need to be packaged (in the tuple of {source file, destination folder in // archive}). - archDirs := make(map[archOs][]fileToZip) + archDirs := make(map[ArchOs][]FileToZip) // Map tracking whether each shared library has an install rule to avoid duplicate install rules from // multiple fuzzers that depend on the same shared library. @@ -392,29 +375,21 @@ func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { // List of individual fuzz targets, so that 'make fuzz' also installs the targets // to the correct output directories as well. - s.fuzzTargets = make(map[string]bool) + s.FuzzTargets = make(map[string]bool) ctx.VisitAllModules(func(module android.Module) { - // Discard non-fuzz targets. ccModule, ok := module.(*Module) - if !ok { + if !ok || ccModule.Properties.PreventInstall { return } - fuzzModule, ok := ccModule.compiler.(*fuzzBinary) - if !ok { - return - } - - // Discard ramdisk + vendor_ramdisk + recovery modules, they're duplicates of - // fuzz targets we're going to package anyway. - if !ccModule.Enabled() || ccModule.Properties.PreventInstall || - ccModule.InRamdisk() || ccModule.InVendorRamdisk() || ccModule.InRecovery() { + // Discard non-fuzz targets. + if ok := IsValid(ccModule.FuzzModule); !ok { return } - // Discard modules that are in an unavailable namespace. - if !ccModule.ExportedToMake() { + fuzzModule, ok := ccModule.compiler.(*fuzzBinary) + if !ok { return } @@ -425,42 +400,21 @@ func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { archString := ccModule.Arch().ArchType.String() archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString) - archOs := archOs{hostOrTarget: hostOrTargetString, arch: archString, dir: archDir.String()} + archOs := ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()} // Grab the list of required shared libraries. sharedLibraries := collectAllSharedDependencies(ctx, module) - var files []fileToZip + var files []FileToZip builder := android.NewRuleBuilder(pctx, ctx) - // Package the corpora into a zipfile. - if fuzzModule.corpus != nil { - corpusZip := archDir.Join(ctx, module.Name()+"_seed_corpus.zip") - command := builder.Command().BuiltTool("soong_zip"). - Flag("-j"). - FlagWithOutput("-o ", corpusZip) - rspFile := corpusZip.ReplaceExtension(ctx, "rsp") - command.FlagWithRspFileInputList("-r ", rspFile, fuzzModule.corpus) - files = append(files, fileToZip{corpusZip, ""}) - } - - // Package the data into a zipfile. - if fuzzModule.data != nil { - dataZip := archDir.Join(ctx, module.Name()+"_data.zip") - command := builder.Command().BuiltTool("soong_zip"). - FlagWithOutput("-o ", dataZip) - for _, f := range fuzzModule.data { - intermediateDir := strings.TrimSuffix(f.String(), f.Rel()) - command.FlagWithArg("-C ", intermediateDir) - command.FlagWithInput("-f ", f) - } - files = append(files, fileToZip{dataZip, ""}) - } + // Package the corpus, data, dict and config into a zipfile. + files = s.PackageArtifacts(ctx, module, fuzzModule.fuzzPackagedModule, archDir, builder) // Find and mark all the transiently-dependent shared libraries for // packaging. for _, library := range sharedLibraries { - files = append(files, fileToZip{library, "lib"}) + files = append(files, FileToZip{library, "lib"}) // For each architecture-specific shared library dependency, we need to // install it to the output directory. Setup the install destination here, @@ -492,83 +446,20 @@ func (s *fuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { } // The executable. - files = append(files, fileToZip{ccModule.UnstrippedOutputFile(), ""}) + files = append(files, FileToZip{ccModule.UnstrippedOutputFile(), ""}) - // The dictionary. - if fuzzModule.dictionary != nil { - files = append(files, fileToZip{fuzzModule.dictionary, ""}) - } - - // Additional fuzz config. - if fuzzModule.config != nil { - files = append(files, fileToZip{fuzzModule.config, ""}) - } - - fuzzZip := archDir.Join(ctx, module.Name()+".zip") - command := builder.Command().BuiltTool("soong_zip"). - Flag("-j"). - FlagWithOutput("-o ", fuzzZip) - for _, file := range files { - if file.DestinationPathPrefix != "" { - command.FlagWithArg("-P ", file.DestinationPathPrefix) - } else { - command.Flag("-P ''") - } - command.FlagWithInput("-f ", file.SourceFilePath) - } - - builder.Build("create-"+fuzzZip.String(), - "Package "+module.Name()+" for "+archString+"-"+hostOrTargetString) - - // Don't add modules to 'make haiku' that are set to not be exported to the - // fuzzing infrastructure. - if config := fuzzModule.Properties.Fuzz_config; config != nil { - if ccModule.Host() && !BoolDefault(config.Fuzz_on_haiku_host, true) { - return - } else if !BoolDefault(config.Fuzz_on_haiku_device, true) { - return - } + archDirs[archOs], ok = s.BuildZipFile(ctx, module, fuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs) + if !ok { + return } - - s.fuzzTargets[module.Name()] = true - archDirs[archOs] = append(archDirs[archOs], fileToZip{fuzzZip, ""}) }) - var archOsList []archOs - for archOs := range archDirs { - archOsList = append(archOsList, archOs) - } - sort.Slice(archOsList, func(i, j int) bool { return archOsList[i].dir < archOsList[j].dir }) + s.CreateFuzzPackage(ctx, archDirs, Cc) - for _, archOs := range archOsList { - filesToZip := archDirs[archOs] - arch := archOs.arch - hostOrTarget := archOs.hostOrTarget - builder := android.NewRuleBuilder(pctx, ctx) - outputFile := android.PathForOutput(ctx, "fuzz-"+hostOrTarget+"-"+arch+".zip") - s.packages = append(s.packages, outputFile) - - command := builder.Command().BuiltTool("soong_zip"). - Flag("-j"). - FlagWithOutput("-o ", outputFile). - Flag("-L 0") // No need to try and re-compress the zipfiles. - - for _, fileToZip := range filesToZip { - if fileToZip.DestinationPathPrefix != "" { - command.FlagWithArg("-P ", fileToZip.DestinationPathPrefix) - } else { - command.Flag("-P ''") - } - command.FlagWithInput("-f ", fileToZip.SourceFilePath) - } - - builder.Build("create-fuzz-package-"+arch+"-"+hostOrTarget, - "Create fuzz target packages for "+arch+"-"+hostOrTarget) - } } -func (s *fuzzPackager) MakeVars(ctx android.MakeVarsContext) { - packages := s.packages.Strings() +func (s *ccFuzzPackager) MakeVars(ctx android.MakeVarsContext) { + packages := s.Packages.Strings() sort.Strings(packages) sort.Strings(s.sharedLibInstallStrings) // TODO(mitchp): Migrate this to use MakeVarsContext::DistForGoal() when it's @@ -580,10 +471,5 @@ func (s *fuzzPackager) MakeVars(ctx android.MakeVarsContext) { strings.Join(s.sharedLibInstallStrings, " ")) // Preallocate the slice of fuzz targets to minimise memory allocations. - fuzzTargets := make([]string, 0, len(s.fuzzTargets)) - for target, _ := range s.fuzzTargets { - fuzzTargets = append(fuzzTargets, target) - } - sort.Strings(fuzzTargets) - ctx.Strict("ALL_FUZZ_TARGETS", strings.Join(fuzzTargets, " ")) + s.PreallocateSlice(ctx, "ALL_FUZZ_TARGETS") } diff --git a/cc/fuzz_common.go b/cc/fuzz_common.go new file mode 100644 index 000000000..98ed7f4bc --- /dev/null +++ b/cc/fuzz_common.go @@ -0,0 +1,201 @@ +// Copyright 2021 Google Inc. All rights reserved. +// +// Licensed 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 cc + +// This file contains the common code for compiling C/C++ and Rust fuzzers for Android. + +import ( + "sort" + "strings" + + "android/soong/android" +) + +type Lang string + +const ( + Cc Lang = "" + Rust Lang = "rust" +) + +type FuzzModule struct { + android.ModuleBase + android.DefaultableModuleBase + android.ApexModuleBase +} + +type FuzzPackager struct { + Packages android.Paths + FuzzTargets map[string]bool +} + +type FileToZip struct { + SourceFilePath android.Path + DestinationPathPrefix string +} + +type ArchOs struct { + HostOrTarget string + Arch string + Dir string +} + +type FuzzPackagedModule struct { + FuzzProperties FuzzProperties + Dictionary android.Path + Corpus android.Paths + CorpusIntermediateDir android.Path + Config android.Path + Data android.Paths + DataIntermediateDir android.Path +} + +func IsValid(fuzzModule FuzzModule) bool { + // Discard ramdisk + vendor_ramdisk + recovery modules, they're duplicates of + // fuzz targets we're going to package anyway. + if !fuzzModule.Enabled() || fuzzModule.InRamdisk() || fuzzModule.InVendorRamdisk() || fuzzModule.InRecovery() { + return false + } + + // Discard modules that are in an unavailable namespace. + if !fuzzModule.ExportedToMake() { + return false + } + + return true +} + +func (s *FuzzPackager) PackageArtifacts(ctx android.SingletonContext, module android.Module, fuzzModule FuzzPackagedModule, archDir android.OutputPath, builder *android.RuleBuilder) []FileToZip { + // Package the corpora into a zipfile. + var files []FileToZip + if fuzzModule.Corpus != nil { + corpusZip := archDir.Join(ctx, module.Name()+"_seed_corpus.zip") + command := builder.Command().BuiltTool("soong_zip"). + Flag("-j"). + FlagWithOutput("-o ", corpusZip) + rspFile := corpusZip.ReplaceExtension(ctx, "rsp") + command.FlagWithRspFileInputList("-r ", rspFile, fuzzModule.Corpus) + files = append(files, FileToZip{corpusZip, ""}) + } + + // Package the data into a zipfile. + if fuzzModule.Data != nil { + dataZip := archDir.Join(ctx, module.Name()+"_data.zip") + command := builder.Command().BuiltTool("soong_zip"). + FlagWithOutput("-o ", dataZip) + for _, f := range fuzzModule.Data { + intermediateDir := strings.TrimSuffix(f.String(), f.Rel()) + command.FlagWithArg("-C ", intermediateDir) + command.FlagWithInput("-f ", f) + } + files = append(files, FileToZip{dataZip, ""}) + } + + // The dictionary. + if fuzzModule.Dictionary != nil { + files = append(files, FileToZip{fuzzModule.Dictionary, ""}) + } + + // Additional fuzz config. + if fuzzModule.Config != nil { + files = append(files, FileToZip{fuzzModule.Config, ""}) + } + + return files +} + +func (s *FuzzPackager) BuildZipFile(ctx android.SingletonContext, module android.Module, fuzzModule FuzzPackagedModule, files []FileToZip, builder *android.RuleBuilder, archDir android.OutputPath, archString string, hostOrTargetString string, archOs ArchOs, archDirs map[ArchOs][]FileToZip) ([]FileToZip, bool) { + fuzzZip := archDir.Join(ctx, module.Name()+".zip") + + command := builder.Command().BuiltTool("soong_zip"). + Flag("-j"). + FlagWithOutput("-o ", fuzzZip) + + for _, file := range files { + if file.DestinationPathPrefix != "" { + command.FlagWithArg("-P ", file.DestinationPathPrefix) + } else { + command.Flag("-P ''") + } + command.FlagWithInput("-f ", file.SourceFilePath) + } + + builder.Build("create-"+fuzzZip.String(), + "Package "+module.Name()+" for "+archString+"-"+hostOrTargetString) + + // Don't add modules to 'make haiku-rust' that are set to not be + // exported to the fuzzing infrastructure. + if config := fuzzModule.FuzzProperties.Fuzz_config; config != nil { + if strings.Contains(hostOrTargetString, "host") && !BoolDefault(config.Fuzz_on_haiku_host, true) { + return archDirs[archOs], false + } else if !BoolDefault(config.Fuzz_on_haiku_device, true) { + return archDirs[archOs], false + } + } + + s.FuzzTargets[module.Name()] = true + archDirs[archOs] = append(archDirs[archOs], FileToZip{fuzzZip, ""}) + + return archDirs[archOs], true +} + +func (s *FuzzPackager) CreateFuzzPackage(ctx android.SingletonContext, archDirs map[ArchOs][]FileToZip, lang Lang) { + var archOsList []ArchOs + for archOs := range archDirs { + archOsList = append(archOsList, archOs) + } + sort.Slice(archOsList, func(i, j int) bool { return archOsList[i].Dir < archOsList[j].Dir }) + + for _, archOs := range archOsList { + filesToZip := archDirs[archOs] + arch := archOs.Arch + hostOrTarget := archOs.HostOrTarget + builder := android.NewRuleBuilder(pctx, ctx) + zipFileName := "fuzz-" + hostOrTarget + "-" + arch + ".zip" + if lang == Rust { + zipFileName = "fuzz-rust-" + hostOrTarget + "-" + arch + ".zip" + } + outputFile := android.PathForOutput(ctx, zipFileName) + + s.Packages = append(s.Packages, outputFile) + + command := builder.Command().BuiltTool("soong_zip"). + Flag("-j"). + FlagWithOutput("-o ", outputFile). + Flag("-L 0") // No need to try and re-compress the zipfiles. + + for _, fileToZip := range filesToZip { + + if fileToZip.DestinationPathPrefix != "" { + command.FlagWithArg("-P ", fileToZip.DestinationPathPrefix) + } else { + command.Flag("-P ''") + } + command.FlagWithInput("-f ", fileToZip.SourceFilePath) + + } + builder.Build("create-fuzz-package-"+arch+"-"+hostOrTarget, + "Create fuzz target packages for "+arch+"-"+hostOrTarget) + } +} + +func (s *FuzzPackager) PreallocateSlice(ctx android.MakeVarsContext, targets string) { + fuzzTargets := make([]string, 0, len(s.FuzzTargets)) + for target, _ := range s.FuzzTargets { + fuzzTargets = append(fuzzTargets, target) + } + sort.Strings(fuzzTargets) + ctx.Strict(targets, strings.Join(fuzzTargets, " ")) +} diff --git a/cc/library.go b/cc/library.go index 4fd7c7475..56c460c24 100644 --- a/cc/library.go +++ b/cc/library.go @@ -300,6 +300,12 @@ func CcLibraryBp2Build(ctx android.TopDownMutatorContext) { srcs := compilerAttrs.srcs + asFlags := compilerAttrs.asFlags + if compilerAttrs.asSrcs.IsEmpty() && sharedAttrs.Srcs_as.IsEmpty() && staticAttrs.Srcs_as.IsEmpty() { + // Skip asflags for BUILD file simplicity if there are no assembly sources. + asFlags = bazel.MakeStringListAttribute(nil) + } + attrs := &bazelCcLibraryAttributes{ Srcs: srcs, Srcs_c: compilerAttrs.cSrcs, @@ -308,7 +314,7 @@ func CcLibraryBp2Build(ctx android.TopDownMutatorContext) { Copts: compilerAttrs.copts, Cppflags: compilerAttrs.cppFlags, Conlyflags: compilerAttrs.conlyFlags, - Asflags: compilerAttrs.asFlags, + Asflags: asFlags, Implementation_deps: linkerAttrs.deps, Deps: linkerAttrs.exportedDeps, @@ -2370,6 +2376,12 @@ func ccLibraryStaticBp2BuildInternal(ctx android.TopDownMutatorContext, module * linkerAttrs := bp2BuildParseLinkerProps(ctx, module) exportedIncludes := bp2BuildParseExportedIncludes(ctx, module) + asFlags := compilerAttrs.asFlags + if compilerAttrs.asSrcs.IsEmpty() { + // Skip asflags for BUILD file simplicity if there are no assembly sources. + asFlags = bazel.MakeStringListAttribute(nil) + } + attrs := &bazelCcLibraryStaticAttributes{ Copts: compilerAttrs.copts, Srcs: compilerAttrs.srcs, @@ -2386,7 +2398,7 @@ func ccLibraryStaticBp2BuildInternal(ctx android.TopDownMutatorContext, module * Srcs_c: compilerAttrs.cSrcs, Conlyflags: compilerAttrs.conlyFlags, Srcs_as: compilerAttrs.asSrcs, - Asflags: compilerAttrs.asFlags, + Asflags: asFlags, } props := bazel.BazelTargetModuleProperties{ diff --git a/cc/linkable.go b/cc/linkable.go index 84141e298..6232efb95 100644 --- a/cc/linkable.go +++ b/cc/linkable.go @@ -125,6 +125,7 @@ type LinkableInterface interface { IsPrebuilt() bool Toc() android.OptionalPath + Device() bool Host() bool InRamdisk() bool diff --git a/cc/object.go b/cc/object.go index ac5e41d51..0f983c861 100644 --- a/cc/object.go +++ b/cc/object.go @@ -123,6 +123,7 @@ func ObjectFactory() android.Module { // For bp2build conversion. type bazelObjectAttributes struct { Srcs bazel.LabelListAttribute + Srcs_as bazel.LabelListAttribute Hdrs bazel.LabelListAttribute Deps bazel.LabelListAttribute Copts bazel.StringListAttribute @@ -179,13 +180,19 @@ func ObjectBp2Build(ctx android.TopDownMutatorContext) { // and this isn't typically done for cc_object. srcs := compilerAttrs.srcs srcs.Append(compilerAttrs.cSrcs) - srcs.Append(compilerAttrs.asSrcs) + + asFlags := compilerAttrs.asFlags + if compilerAttrs.asSrcs.IsEmpty() { + // Skip asflags for BUILD file simplicity if there are no assembly sources. + asFlags = bazel.MakeStringListAttribute(nil) + } attrs := &bazelObjectAttributes{ Srcs: srcs, + Srcs_as: compilerAttrs.asSrcs, Deps: deps, Copts: compilerAttrs.copts, - Asflags: compilerAttrs.asFlags, + Asflags: asFlags, } props := bazel.BazelTargetModuleProperties{ diff --git a/cc/snapshot_prebuilt.go b/cc/snapshot_prebuilt.go index fb89224f3..4f031ff96 100644 --- a/cc/snapshot_prebuilt.go +++ b/cc/snapshot_prebuilt.go @@ -264,6 +264,7 @@ var recoverySnapshotImageSingleton recoverySnapshotImage func init() { VendorSnapshotImageSingleton.Init(android.InitRegistrationContext) recoverySnapshotImageSingleton.init(android.InitRegistrationContext) + android.RegisterMakeVarsProvider(pctx, snapshotMakeVarsProvider) } const ( @@ -383,6 +384,24 @@ var SnapshotInfoProvider = blueprint.NewMutatorProvider(SnapshotInfo{}, "deps") var _ android.ImageInterface = (*snapshot)(nil) +func snapshotMakeVarsProvider(ctx android.MakeVarsContext) { + snapshotSet := map[string]struct{}{} + ctx.VisitAllModules(func(m android.Module) { + if s, ok := m.(*snapshot); ok { + if _, ok := snapshotSet[s.Name()]; ok { + // arch variant generates duplicated modules + // skip this as we only need to know the path of the module. + return + } + snapshotSet[s.Name()] = struct{}{} + imageNameVersion := strings.Split(s.image.imageVariantName(ctx.DeviceConfig()), ".") + ctx.Strict( + strings.Join([]string{strings.ToUpper(imageNameVersion[0]), s.baseSnapshot.Version(), "SNAPSHOT_DIR"}, "_"), + ctx.ModuleDir(s)) + } + }) +} + func vendorSnapshotFactory() android.Module { return snapshotFactory(VendorSnapshotImageSingleton) } diff --git a/cmd/extract_linker/main.go b/cmd/extract_linker/main.go index 2dcb8948e..f1f7bc74b 100644 --- a/cmd/extract_linker/main.go +++ b/cmd/extract_linker/main.go @@ -85,7 +85,7 @@ func main() { fmt.Fprintf(asm, ".globl %s\n%s:\n\n", symName, symName) - fmt.Fprintf(script, " %s %d : {\n", sectionName, baseLoadAddr+prog.Vaddr) + fmt.Fprintf(script, " %s 0x%x : {\n", sectionName, baseLoadAddr+prog.Vaddr) fmt.Fprintf(script, " KEEP(*(%s));\n", sectionName) fmt.Fprintln(script, " }") @@ -106,8 +106,10 @@ func main() { load += 1 } + fmt.Fprintln(asm, `.section .note.android.embedded_linker,"a",%note`) + fmt.Fprintln(script, "}") - fmt.Fprintln(script, "INSERT BEFORE .note.android.ident;") + fmt.Fprintln(script, "INSERT BEFORE .note.android.embedded_linker;") if asmPath != "" { if err := ioutil.WriteFile(asmPath, asm.Bytes(), 0777); err != nil { diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go index f76a205aa..245af2cea 100644 --- a/dexpreopt/class_loader_context.go +++ b/dexpreopt/class_loader_context.go @@ -15,6 +15,7 @@ package dexpreopt import ( + "encoding/json" "fmt" "sort" "strconv" @@ -257,6 +258,9 @@ const AnySdkVersion int = android.FutureApiLevelInt func (clcMap ClassLoaderContextMap) addContext(ctx android.ModuleInstallPathContext, sdkVer int, lib string, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) error { + // For prebuilts, library should have the same name as the source module. + lib = android.RemoveOptionalPrebuiltPrefix(lib) + devicePath := UnknownInstallLibraryPath if installPath == nil { if android.InList(lib, CompatUsesLibs) || android.InList(lib, OptionalCompatUsesLibs) { @@ -282,11 +286,19 @@ func (clcMap ClassLoaderContextMap) addContext(ctx android.ModuleInstallPathCont } subcontexts := nestedClcMap[AnySdkVersion] - // If the library with this name is already present as one of the unconditional top-level - // components, do not re-add it. + // Check if the library with this name is already present in unconditional top-level CLC. for _, clc := range clcMap[sdkVer] { - if clc.Name == lib { + if clc.Name != lib { + // Ok, a different library. + } else if clc.Host == hostPath && clc.Device == devicePath { + // Ok, the same library with the same paths. Don't re-add it, but don't raise an error + // either, as the same library may be reachable via different transitional dependencies. return nil + } else { + // Fail, as someone is trying to add the same library with different paths. This likely + // indicates an error somewhere else, like trying to add a stub library. + return fmt.Errorf("a <uses-library> named %q is already in class loader context,"+ + "but the library paths are different:\t\n", lib) } } @@ -360,6 +372,15 @@ func (clcMap ClassLoaderContextMap) UsesLibs() (ulibs []string) { return ulibs } +func (clcMap ClassLoaderContextMap) Dump() string { + jsonCLC := toJsonClassLoaderContext(clcMap) + bytes, err := json.MarshalIndent(jsonCLC, "", " ") + if err != nil { + panic(err) + } + return string(bytes) +} + // Now that the full unconditional context is known, reconstruct conditional context. // Apply filters for individual libraries, mirroring what the PackageManager does when it // constructs class loader context on device. diff --git a/java/app.go b/java/app.go index fc1ace07b..4e967ad45 100755 --- a/java/app.go +++ b/java/app.go @@ -1213,7 +1213,7 @@ func (u *usesLibrary) addLib(lib string, optional bool) { } func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, hasFrameworkLibs bool) { - if !ctx.Config().UnbundledBuild() { + if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() { ctx.AddVariationDependencies(nil, usesLibTag, u.usesLibraryProperties.Uses_libs...) ctx.AddVariationDependencies(nil, usesLibTag, u.presentOptionalUsesLibs(ctx)...) // Only add these extra dependencies if the module depends on framework libs. This avoids @@ -1245,36 +1245,52 @@ func replaceInList(list []string, oldstr, newstr string) { } } -// Returns a map of module names of shared library dependencies to the paths -// to their dex jars on host and on device. +// Returns a map of module names of shared library dependencies to the paths to their dex jars on +// host and on device. func (u *usesLibrary) classLoaderContextForUsesLibDeps(ctx android.ModuleContext) dexpreopt.ClassLoaderContextMap { clcMap := make(dexpreopt.ClassLoaderContextMap) - if !ctx.Config().UnbundledBuild() { - ctx.VisitDirectDeps(func(m android.Module) { - if tag, ok := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag); ok { - dep := ctx.OtherModuleName(m) - if lib, ok := m.(UsesLibraryDependency); ok { - libName := dep - if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil { - libName = *ulib.ProvidesUsesLib() - // Replace module name with library name in `uses_libs`/`optional_uses_libs` - // in order to pass verify_uses_libraries check (which compares these - // properties against library names written in the manifest). - replaceInList(u.usesLibraryProperties.Uses_libs, dep, libName) - replaceInList(u.usesLibraryProperties.Optional_uses_libs, dep, libName) - } - clcMap.AddContext(ctx, tag.sdkVersion, libName, - lib.DexJarBuildPath(), lib.DexJarInstallPath(), lib.ClassLoaderContexts()) - } else if ctx.Config().AllowMissingDependencies() { - ctx.AddMissingDependencies([]string{dep}) - } else { - ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep) - } - } - }) + // Skip when UnbundledBuild() is true, but UnbundledBuildImage() is false. With + // UnbundledBuildImage() it is necessary to generate dexpreopt.config for post-dexpreopting. + if ctx.Config().UnbundledBuild() && !ctx.Config().UnbundledBuildImage() { + return clcMap } + ctx.VisitDirectDeps(func(m android.Module) { + tag, isUsesLibTag := ctx.OtherModuleDependencyTag(m).(usesLibraryDependencyTag) + if !isUsesLibTag { + return + } + + dep := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(m)) + + // Skip stub libraries. A dependency on the implementation library has been added earlier, + // so it will be added to CLC, but the stub shouldn't be. Stub libraries can be distingushed + // from implementation libraries by their name, which is different as it has a suffix. + if comp, ok := m.(SdkLibraryComponentDependency); ok { + if impl := comp.OptionalSdkLibraryImplementation(); impl != nil && *impl != dep { + return + } + } + + if lib, ok := m.(UsesLibraryDependency); ok { + libName := dep + if ulib, ok := m.(ProvidesUsesLib); ok && ulib.ProvidesUsesLib() != nil { + libName = *ulib.ProvidesUsesLib() + // Replace module name with library name in `uses_libs`/`optional_uses_libs` in + // order to pass verify_uses_libraries check (which compares these properties + // against library names written in the manifest). + replaceInList(u.usesLibraryProperties.Uses_libs, dep, libName) + replaceInList(u.usesLibraryProperties.Optional_uses_libs, dep, libName) + } + clcMap.AddContext(ctx, tag.sdkVersion, libName, + lib.DexJarBuildPath(), lib.DexJarInstallPath(), lib.ClassLoaderContexts()) + } else if ctx.Config().AllowMissingDependencies() { + ctx.AddMissingDependencies([]string{dep}) + } else { + ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library", dep) + } + }) return clcMap } diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go index bdf0daeaf..503c31fd7 100644 --- a/java/bootclasspath_fragment.go +++ b/java/bootclasspath_fragment.go @@ -579,25 +579,9 @@ func (b *BootclasspathFragmentModule) generateHiddenAPIBuildActions(ctx android. // Create hidden API input structure. input := b.createHiddenAPIFlagInput(ctx, contents, fragments) - var output *HiddenAPIOutput - - // Hidden API processing is conditional as a temporary workaround as not all - // bootclasspath_fragments provide the appropriate information needed for hidden API processing - // which leads to breakages of the build. - // TODO(b/179354495): Stop hidden API processing being conditional once all bootclasspath_fragment - // modules have been updated to support it. - if input.canPerformHiddenAPIProcessing(ctx, b.properties) { - // Delegate the production of the hidden API all-flags.csv file to a module type specific method. - common := ctx.Module().(commonBootclasspathFragment) - output = common.produceHiddenAPIOutput(ctx, contents, input) - } else { - // As hidden API processing cannot be performed fall back to trying to retrieve the legacy - // encoded boot dex files, i.e. those files encoded by the individual libraries and returned - // from the DexJarBuildPath() method. - output = &HiddenAPIOutput{ - EncodedBootDexFilesByModule: retrieveLegacyEncodedBootDexFiles(ctx, contents), - } - } + // Delegate the production of the hidden API all-flags.csv file to a module type specific method. + common := ctx.Module().(commonBootclasspathFragment) + output := common.produceHiddenAPIOutput(ctx, contents, input) // Initialize a HiddenAPIInfo structure. hiddenAPIInfo := HiddenAPIInfo{ diff --git a/java/dexpreopt.go b/java/dexpreopt.go index 2e46d74fa..0faae36ba 100644 --- a/java/dexpreopt.go +++ b/java/dexpreopt.go @@ -141,10 +141,9 @@ func (d *dexpreopter) dexpreopt(ctx android.ModuleContext, dexJarFile android.Wr } } - // If it is neither app nor test, make config files regardless of its dexpreopt setting. + // If it is test, make config files regardless of its dexpreopt setting. // The config files are required for apps defined in make which depend on the lib. - // TODO(b/158843648): The config for apps should be generated as well regardless of setting. - if (d.isApp || d.isTest) && d.dexpreoptDisabled(ctx) { + if d.isTest && d.dexpreoptDisabled(ctx) { return } diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 19c65cac7..dff9543e4 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -154,12 +154,23 @@ import ( // PRODUCT_BOOT_JARS_EXTRA variables. The AOSP makefiles specify some common Framework libraries, // but more product-specific libraries can be added in the product makefiles. // -// Each component of the PRODUCT_BOOT_JARS and PRODUCT_BOOT_JARS_EXTRA variables is either a simple -// name (if the library is a part of the Platform), or a colon-separated pair <apex, name> (if the -// library is a part of a non-updatable APEX). +// Each component of the PRODUCT_BOOT_JARS and PRODUCT_BOOT_JARS_EXTRA variables is a +// colon-separated pair <apex>:<library>, where <apex> is the variant name of a non-updatable APEX, +// "platform" if the library is a part of the platform in the system partition, or "system_ext" if +// it's in the system_ext partition. +// +// In these variables APEXes are identified by their "variant names", i.e. the names they get +// mounted as in /apex on device. In Soong modules that is the name set in the "apex_name" +// properties, which default to the "name" values. For example, many APEXes have both +// com.android.xxx and com.google.android.xxx modules in Soong, but take the same place +// /apex/com.android.xxx at runtime. In these cases the variant name is always com.android.xxx, +// regardless which APEX goes into the product. See also android.ApexInfo.ApexVariationName and +// apex.apexBundleProperties.Apex_name. // // A related variable PRODUCT_UPDATABLE_BOOT_JARS contains bootclasspath libraries that are in -// updatable APEXes. They are not included in the boot image. +// APEXes. They are not included in the boot image. The only exception here is core-icu4j.jar that +// has been historically part of the boot image and is now in a non updatable apex; it is treated +// as being part of PRODUCT_BOOT_JARS and is in the boot image. // // One exception to the above rules are "coverage" builds (a special build flavor which requires // setting environment variable EMMA_INSTRUMENT_FRAMEWORK=true). In coverage builds the Java code in diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go index c4832d2f8..654ebb743 100644 --- a/java/hiddenapi_modular.go +++ b/java/hiddenapi_modular.go @@ -20,7 +20,6 @@ import ( "android/soong/android" "github.com/google/blueprint" - "github.com/google/blueprint/proptools" ) // Contains support for processing hiddenAPI in a modular fashion. @@ -712,42 +711,6 @@ func newHiddenAPIFlagInput() HiddenAPIFlagInput { return input } -// canPerformHiddenAPIProcessing determines whether hidden API processing should be performed. -// -// A temporary workaround to avoid existing bootclasspath_fragments that do not provide the -// appropriate information needed for hidden API processing breaking the build. -// TODO(b/179354495): Remove this workaround. -func (i *HiddenAPIFlagInput) canPerformHiddenAPIProcessing(ctx android.ModuleContext, properties bootclasspathFragmentProperties) bool { - // Performing hidden API processing without stubs is not supported and it is unlikely to ever be - // required as the whole point of adding something to the bootclasspath fragment is to add it to - // the bootclasspath in order to be used by something else in the system. Without any stubs it - // cannot do that. - if len(i.StubDexJarsByScope) == 0 { - return false - } - - // Hidden API processing is always enabled in tests. - if ctx.Config().TestProductVariables != nil { - return true - } - - // A module that has fragments should have access to the information it needs in order to perform - // hidden API processing. - if len(properties.Fragments) != 0 { - return true - } - - // The art bootclasspath fragment does not depend on any other fragments but already supports - // hidden API processing. - imageName := proptools.String(properties.Image_name) - if imageName == "art" { - return true - } - - // Disable it for everything else. - return false -} - // gatherStubLibInfo gathers information from the stub libs needed by hidden API processing from the // dependencies added in hiddenAPIAddStubLibDependencies. // diff --git a/java/java.go b/java/java.go index be1ad874f..e38a7143b 100644 --- a/java/java.go +++ b/java/java.go @@ -21,7 +21,6 @@ package java import ( "fmt" "path/filepath" - "strings" "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -131,11 +130,19 @@ var ( PropertyName: "java_boot_libs", SupportsSdk: true, }, - // Temporarily export implementation classes jar for java_boot_libs as it is required for the - // hiddenapi processing. - // TODO(b/179354495): Revert once hiddenapi processing has been modularized. - exportImplementationClassesJar, - sdkSnapshotFilePathForJar, + func(ctx android.SdkMemberContext, j *Library) android.Path { + // Java boot libs are only provided in the SDK to provide access to their dex implementation + // jar for use by dexpreopting and boot jars package check. They do not need to provide an + // actual implementation jar but the java_import will need a file that exists so just copy an + // empty file. Any attempt to use that file as a jar will cause a build error. + return ctx.SnapshotBuilder().EmptyFile() + }, + func(osPrefix, name string) string { + // Create a special name for the implementation jar to try and provide some useful information + // to a developer that attempts to compile against this. + // TODO(b/175714559): Provide a proper error message in Soong not ninja. + return filepath.Join(osPrefix, "java_boot_libs", "snapshot", "jars", "are", "invalid", name+jarFileSuffix) + }, onlyCopyJarToSnapshot, } @@ -581,6 +588,10 @@ type librarySdkMemberProperties struct { JarToExport android.Path `android:"arch_variant"` AidlIncludeDirs android.Paths + + // The list of permitted packages that need to be passed to the prebuilts as they are used to + // create the updatable-bcp-packages.txt file. + PermittedPackages []string } func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) { @@ -589,6 +600,8 @@ func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberCo p.JarToExport = ctx.MemberType().(*librarySdkMemberType).jarToExportGetter(ctx, j) p.AidlIncludeDirs = j.AidlIncludeDirs() + + p.PermittedPackages = j.PermittedPackagesForUpdatableBootJars() } func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { @@ -607,6 +620,10 @@ func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberConte propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath}) } + if len(p.PermittedPackages) > 0 { + propertySet.AddProperty("permitted_packages", p.PermittedPackages) + } + // Do not copy anything else to the snapshot. if memberType.onlyCopyJarToSnapshot { return @@ -1127,6 +1144,10 @@ type ImportProperties struct { Installable *bool + // If not empty, classes are restricted to the specified packages and their sub-packages. + // This information is used to generate the updatable-bcp-packages.txt file. + Permitted_packages []string + // List of shared java libs that this module has dependencies to Libs []string @@ -1166,7 +1187,8 @@ type Import struct { properties ImportProperties // output file containing classes.dex and resources - dexJarFile android.Path + dexJarFile android.Path + dexJarInstallFile android.Path combinedClasspathFile android.Path classLoaderContexts dexpreopt.ClassLoaderContextMap @@ -1178,6 +1200,12 @@ type Import struct { minSdkVersion android.SdkSpec } +var _ PermittedPackagesForUpdatableBootJars = (*Import)(nil) + +func (j *Import) PermittedPackagesForUpdatableBootJars() []string { + return j.properties.Permitted_packages +} + func (j *Import) SdkVersion(ctx android.EarlyModuleContext) android.SdkSpec { return android.SdkSpecFrom(ctx, String(j.properties.Sdk_version)) } @@ -1311,6 +1339,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo) if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(j.BaseModuleName())); dexOutputPath != nil { j.dexJarFile = dexOutputPath + j.dexJarInstallFile = android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(j.BaseModuleName())) // Initialize the hiddenapi structure. j.initHiddenAPI(ctx, dexOutputPath, outputFile, nil) @@ -1351,6 +1380,7 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { dexOutputFile = j.hiddenAPIEncodeDex(ctx, dexOutputFile) j.dexJarFile = dexOutputFile + j.dexJarInstallFile = android.PathForModuleInstall(ctx, "framework", jarName) } } @@ -1392,7 +1422,7 @@ func (j *Import) DexJarBuildPath() android.Path { } func (j *Import) DexJarInstallPath() android.Path { - return nil + return j.dexJarInstallFile } func (j *Import) ClassLoaderContexts() dexpreopt.ClassLoaderContextMap { @@ -1462,11 +1492,7 @@ func (j *Import) IDECustomizedModuleName() string { // TODO(b/113562217): Extract the base module name from the Import name, often the Import name // has a prefix "prebuilt_". Remove the prefix explicitly if needed until we find a better // solution to get the Import name. - name := j.Name() - if strings.HasPrefix(name, removedPrefix) { - name = strings.TrimPrefix(name, removedPrefix) - } - return name + return android.RemoveOptionalPrebuiltPrefix(j.Name()) } var _ android.PrebuiltInterface = (*Import)(nil) @@ -1768,22 +1794,16 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, return } - // Find out if the dependency is either an SDK library or an ordinary library that is disguised - // as an SDK library by the means of `provides_uses_lib` property. If yes, the library is itself - // a <uses-library> and should be added as a node in the CLC tree, and its CLC should be added - // as subtree of that node. Otherwise the library is not a <uses_library> and should not be - // added to CLC, but the transitive <uses-library> dependencies from its CLC should be added to - // the current CLC. - var implicitSdkLib *string - comp, isComp := depModule.(SdkLibraryComponentDependency) - if isComp { - implicitSdkLib = comp.OptionalImplicitSdkLibrary() - // OptionalImplicitSdkLibrary() may be nil so need to fall through to ProvidesUsesLib(). - } - if implicitSdkLib == nil { - if ulib, ok := depModule.(ProvidesUsesLib); ok { - implicitSdkLib = ulib.ProvidesUsesLib() - } + depName := android.RemoveOptionalPrebuiltPrefix(ctx.OtherModuleName(depModule)) + + var sdkLib *string + if lib, ok := depModule.(SdkLibraryDependency); ok && lib.sharedLibrary() { + // A shared SDK library. This should be added as a top-level CLC element. + sdkLib = &depName + } else if ulib, ok := depModule.(ProvidesUsesLib); ok { + // A non-SDK library disguised as an SDK library by the means of `provides_uses_lib` + // property. This should be handled in the same way as a shared SDK library. + sdkLib = ulib.ProvidesUsesLib() } depTag := ctx.OtherModuleDependencyTag(depModule) @@ -1793,7 +1813,7 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, // Propagate <uses-library> through static library dependencies, unless it is a component // library (such as stubs). Component libraries have a dependency on their SDK library, // which should not be pulled just because of a static component library. - if implicitSdkLib != nil { + if sdkLib != nil { return } } else { @@ -1801,11 +1821,14 @@ func addCLCFromDep(ctx android.ModuleContext, depModule android.Module, return } - if implicitSdkLib != nil { - clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *implicitSdkLib, + // If this is an SDK (or SDK-like) library, then it should be added as a node in the CLC tree, + // and its CLC should be added as subtree of that node. Otherwise the library is not a + // <uses_library> and should not be added to CLC, but the transitive <uses-library> dependencies + // from its CLC should be added to the current CLC. + if sdkLib != nil { + clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, dep.DexJarBuildPath(), dep.DexJarInstallPath(), dep.ClassLoaderContexts()) } else { - depName := ctx.OtherModuleName(depModule) clcMap.AddContextMap(dep.ClassLoaderContexts(), depName) } } diff --git a/java/lint.go b/java/lint.go index dd5e4fb13..fe3218e90 100644 --- a/java/lint.go +++ b/java/lint.go @@ -391,8 +391,9 @@ func (l *linter) lint(ctx android.ModuleContext) { rule.Command().Text("rm -f").Output(html).Output(text).Output(xml) var apiVersionsName, apiVersionsPrebuilt string - if l.compileSdkKind == android.SdkModule { - // When compiling an SDK module we use the filtered database because otherwise lint's + if l.compileSdkKind == android.SdkModule || l.compileSdkKind == android.SdkSystemServer { + // When compiling an SDK module (or system server) we use the filtered + // database because otherwise lint's // NewApi check produces too many false positives; This database excludes information // about classes created in mainline modules hence removing those false positives. apiVersionsName = "api_versions_public_filtered.xml" diff --git a/java/lint_test.go b/java/lint_test.go index 9cf1c33fe..456e6ba73 100644 --- a/java/lint_test.go +++ b/java/lint_test.go @@ -261,6 +261,9 @@ func TestJavaLintDatabaseSelectionFull(t *testing.T) { } func TestJavaLintDatabaseSelectionPublicFiltered(t *testing.T) { + testCases := []string{ + "module_current", "system_server_current", + } bp := ` java_library { name: "foo", @@ -274,17 +277,20 @@ func TestJavaLintDatabaseSelectionPublicFiltered(t *testing.T) { }, } ` - result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules). - RunTestWithBp(t, bp) + for _, testCase := range testCases { + thisBp := strings.Replace(bp, "XXX", testCase, 1) + result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules). + RunTestWithBp(t, thisBp) - foo := result.ModuleForTests("foo", "android_common") - sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto")) - if !strings.Contains(*sboxProto.Commands[0].Command, - "/api_versions_public_filtered.xml") { - t.Error("did not use public-filtered lint api database", *sboxProto.Commands[0].Command) - } - if strings.Contains(*sboxProto.Commands[0].Command, - "/api_versions.xml") { - t.Error("used full api database") + foo := result.ModuleForTests("foo", "android_common") + sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto")) + if !strings.Contains(*sboxProto.Commands[0].Command, + "/api_versions_public_filtered.xml") { + t.Error("did not use public-filtered lint api database for case", testCase) + } + if strings.Contains(*sboxProto.Commands[0].Command, + "/api_versions.xml") { + t.Error("used full api database for case", testCase) + } } } diff --git a/java/platform_bootclasspath.go b/java/platform_bootclasspath.go index c1e14b21e..8bed3e9e5 100644 --- a/java/platform_bootclasspath.go +++ b/java/platform_bootclasspath.go @@ -423,8 +423,13 @@ func (b *platformBootclasspathModule) generateBootImageBuildActions(ctx android. // Generate the framework profile rule bootFrameworkProfileRule(ctx, imageConfig) - // Generate the updatable bootclasspath packages rule. - generateUpdatableBcpPackagesRule(ctx, imageConfig, updatableModules) + // If always using prebuilt sdks then do not generate the updatable-bcp-packages.txt file as it + // will break because the prebuilts do not yet specify a permitted_packages property. + // TODO(b/193889859): Remove when the prebuilts have been updated. + if !ctx.Config().AlwaysUsePrebuiltSdks() { + // Generate the updatable bootclasspath packages rule. + generateUpdatableBcpPackagesRule(ctx, imageConfig, updatableModules) + } // Copy non-updatable module dex jars to their predefined locations. nonUpdatableBootDexJarsByModule := extractEncodedDexJarsFromModules(ctx, nonUpdatableModules) diff --git a/java/robolectric.go b/java/robolectric.go index 00f233ebf..a37a118f6 100644 --- a/java/robolectric.go +++ b/java/robolectric.go @@ -179,7 +179,7 @@ func (r *robolectricTest) GenerateAndroidBuildActions(ctx android.ModuleContext) continue } else if strings.HasSuffix(s, "/BaseRobolectricTest.java") { continue - } else if strings.HasPrefix(s, "src/") { + } else { s = strings.TrimPrefix(s, "src/") } r.tests = append(r.tests, s) diff --git a/java/sdk_library.go b/java/sdk_library.go index ed9aeffd4..268e7970d 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -981,13 +981,15 @@ func (e *EmbeddableSdkLibraryComponent) SdkLibraryName() *string { } // to satisfy SdkLibraryComponentDependency -func (e *EmbeddableSdkLibraryComponent) OptionalImplicitSdkLibrary() *string { - return e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack -} - -// to satisfy SdkLibraryComponentDependency func (e *EmbeddableSdkLibraryComponent) OptionalSdkLibraryImplementation() *string { - // Currently implementation library name is the same as the SDK library name. + // For shared libraries, this is the same as the SDK library name. If a Java library or app + // depends on a component library (e.g. a stub library) it still needs to know the name of the + // run-time library and the corresponding module that provides the implementation. This name is + // passed to manifest_fixer (to be added to AndroidManifest.xml) and added to CLC (to be used + // in dexpreopt). + // + // For non-shared SDK (component or not) libraries this returns `nil`, as they are not + // <uses-library> and should not be added to the manifest or to CLC. return e.sdkLibraryComponentProperties.SdkLibraryToImplicitlyTrack } @@ -999,12 +1001,6 @@ type SdkLibraryComponentDependency interface { // SdkLibraryName returns the name of the java_sdk_library/_import module. SdkLibraryName() *string - // The optional name of the sdk library that should be implicitly added to the - // AndroidManifest of an app that contains code which references the sdk library. - // - // Returns the name of the optional implicit SDK library or nil, if there isn't one. - OptionalImplicitSdkLibrary() *string - // The name of the implementation library for the optional SDK library or nil, if there isn't one. OptionalSdkLibraryImplementation() *string } @@ -1897,6 +1893,10 @@ type sdkLibraryImportProperties struct { // If set to true, compile dex files for the stubs. Defaults to false. Compile_dex *bool + + // If not empty, classes are restricted to the specified packages and their sub-packages. + // This information is used to generate the updatable-bcp-packages.txt file. + Permitted_packages []string } type SdkLibraryImport struct { @@ -1923,8 +1923,12 @@ type SdkLibraryImport struct { // Is nil if the source module does not exist. xmlPermissionsFileModule *sdkLibraryXml - // Path to the dex implementation jar obtained from the prebuilt_apex, if any. + // Build path to the dex implementation jar obtained from the prebuilt_apex, if any. dexJarFile android.Path + + // Expected install file path of the source module(sdk_library) + // or dex implementation jar obtained from the prebuilt_apex, if any. + installFile android.Path } var _ SdkLibraryDependency = (*SdkLibraryImport)(nil) @@ -1991,6 +1995,12 @@ func sdkLibraryImportFactory() android.Module { return module } +var _ PermittedPackagesForUpdatableBootJars = (*SdkLibraryImport)(nil) + +func (module *SdkLibraryImport) PermittedPackagesForUpdatableBootJars() []string { + return module.properties.Permitted_packages +} + func (module *SdkLibraryImport) Prebuilt() *android.Prebuilt { return &module.prebuilt } @@ -2136,6 +2146,9 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo var deapexerModule android.Module + // Assume that source module(sdk_library) is installed in /<sdk_library partition>/framework + module.installFile = android.PathForModuleInstall(ctx, "framework", module.Stem()+".jar") + // Record the paths to the prebuilt stubs library and stubs source. ctx.VisitDirectDeps(func(to android.Module) { tag := ctx.OtherModuleDependencyTag(to) @@ -2195,6 +2208,7 @@ func (module *SdkLibraryImport) GenerateAndroidBuildActions(ctx android.ModuleCo di := ctx.OtherModuleProvider(deapexerModule, android.DeapexerProvider).(android.DeapexerInfo) if dexOutputPath := di.PrebuiltExportPath(apexRootRelativePathToJavaLib(module.BaseModuleName())); dexOutputPath != nil { module.dexJarFile = dexOutputPath + module.installFile = android.PathForModuleInPartitionInstall(ctx, "apex", ai.ApexVariationName, apexRootRelativePathToJavaLib(module.BaseModuleName())) module.initHiddenAPI(ctx, dexOutputPath, module.findScopePaths(apiScopePublic).stubsImplPath[0], nil) } else { // This should never happen as a variant for a prebuilt_apex is only created if the @@ -2249,11 +2263,7 @@ func (module *SdkLibraryImport) DexJarBuildPath() android.Path { // to satisfy UsesLibraryDependency interface func (module *SdkLibraryImport) DexJarInstallPath() android.Path { - if module.implLibraryModule == nil { - return nil - } else { - return module.implLibraryModule.DexJarInstallPath() - } + return module.installFile } // to satisfy UsesLibraryDependency interface @@ -2506,6 +2516,8 @@ type sdkLibrarySdkMemberProperties struct { // The paths to the doctag files to add to the prebuilt. Doctag_paths android.Paths + + Permitted_packages []string } type scopeProperties struct { @@ -2546,6 +2558,7 @@ func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMembe s.Shared_library = proptools.BoolPtr(sdk.sharedLibrary()) s.Compile_dex = sdk.dexProperties.Compile_dex s.Doctag_paths = sdk.doctagPaths + s.Permitted_packages = sdk.PermittedPackagesForUpdatableBootJars() } func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { @@ -2558,6 +2571,9 @@ func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberCo if s.Compile_dex != nil { propertySet.AddProperty("compile_dex", *s.Compile_dex) } + if len(s.Permitted_packages) > 0 { + propertySet.AddProperty("permitted_packages", s.Permitted_packages) + } for _, apiScope := range allApiScopes { if properties, ok := s.Scopes[apiScope]; ok { diff --git a/rust/androidmk.go b/rust/androidmk.go index ea45ebd01..630805a85 100644 --- a/rust/androidmk.go +++ b/rust/androidmk.go @@ -205,24 +205,24 @@ func (fuzz *fuzzDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *andro ctx.SubAndroidMk(entries, fuzz.binaryDecorator) var fuzzFiles []string - for _, d := range fuzz.corpus { + for _, d := range fuzz.fuzzPackagedModule.Corpus { fuzzFiles = append(fuzzFiles, - filepath.Dir(fuzz.corpusIntermediateDir.String())+":corpus/"+d.Base()) + filepath.Dir(fuzz.fuzzPackagedModule.CorpusIntermediateDir.String())+":corpus/"+d.Base()) } - for _, d := range fuzz.data { + for _, d := range fuzz.fuzzPackagedModule.Data { fuzzFiles = append(fuzzFiles, - filepath.Dir(fuzz.dataIntermediateDir.String())+":data/"+d.Rel()) + filepath.Dir(fuzz.fuzzPackagedModule.DataIntermediateDir.String())+":data/"+d.Rel()) } - if fuzz.dictionary != nil { + if fuzz.fuzzPackagedModule.Dictionary != nil { fuzzFiles = append(fuzzFiles, - filepath.Dir(fuzz.dictionary.String())+":"+fuzz.dictionary.Base()) + filepath.Dir(fuzz.fuzzPackagedModule.Dictionary.String())+":"+fuzz.fuzzPackagedModule.Dictionary.Base()) } - if fuzz.config != nil { + if fuzz.fuzzPackagedModule.Config != nil { fuzzFiles = append(fuzzFiles, - filepath.Dir(fuzz.config.String())+":config.json") + filepath.Dir(fuzz.fuzzPackagedModule.Config.String())+":config.json") } entries.ExtraEntries = append(entries.ExtraEntries, func(ctx android.AndroidMkExtraEntriesContext, diff --git a/rust/benchmark.go b/rust/benchmark.go index b89f5cd9b..0e842435d 100644 --- a/rust/benchmark.go +++ b/rust/benchmark.go @@ -101,6 +101,7 @@ func (benchmark *benchmarkDecorator) compilerFlags(ctx ModuleContext, flags Flag func (benchmark *benchmarkDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { deps = benchmark.binaryDecorator.compilerDeps(ctx, deps) + deps.Rustlibs = append(deps.Rustlibs, "libtest") deps.Rustlibs = append(deps.Rustlibs, "libcriterion") return deps diff --git a/rust/config/global.go b/rust/config/global.go index 43b49d18b..1b56237b3 100644 --- a/rust/config/global.go +++ b/rust/config/global.go @@ -29,7 +29,6 @@ var ( DefaultEdition = "2018" Stdlibs = []string{ "libstd", - "libtest", } // Mapping between Soong internal arch types and std::env constants. diff --git a/rust/fuzz.go b/rust/fuzz.go index 7e1c55a50..18b25130f 100644 --- a/rust/fuzz.go +++ b/rust/fuzz.go @@ -32,13 +32,7 @@ func init() { type fuzzDecorator struct { *binaryDecorator - Properties cc.FuzzProperties - dictionary android.Path - corpus android.Paths - corpusIntermediateDir android.Path - config android.Path - data android.Paths - dataIntermediateDir android.Path + fuzzPackagedModule cc.FuzzPackagedModule } var _ compiler = (*binaryDecorator)(nil) @@ -88,7 +82,7 @@ func (fuzzer *fuzzDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { func (fuzzer *fuzzDecorator) compilerProps() []interface{} { return append(fuzzer.binaryDecorator.compilerProps(), - &fuzzer.Properties) + &fuzzer.fuzzPackagedModule.FuzzProperties) } func (fuzzer *fuzzDecorator) stdLinkage(ctx *depsContext) RustLinkage { @@ -102,32 +96,19 @@ func (fuzzer *fuzzDecorator) autoDep(ctx android.BottomUpMutatorContext) autoDep // Responsible for generating GNU Make rules that package fuzz targets into // their architecture & target/host specific zip file. type rustFuzzPackager struct { - packages android.Paths - fuzzTargets map[string]bool + cc.FuzzPackager } func rustFuzzPackagingFactory() android.Singleton { return &rustFuzzPackager{} } -type fileToZip struct { - SourceFilePath android.Path - DestinationPathPrefix string -} - -type archOs struct { - hostOrTarget string - arch string - dir string -} - func (s *rustFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { - // Map between each architecture + host/device combination. - archDirs := make(map[archOs][]fileToZip) + archDirs := make(map[cc.ArchOs][]cc.FileToZip) // List of individual fuzz targets. - s.fuzzTargets = make(map[string]bool) + s.FuzzTargets = make(map[string]bool) ctx.VisitAllModules(func(module android.Module) { // Discard non-fuzz targets. @@ -136,20 +117,12 @@ func (s *rustFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { return } - fuzzModule, ok := rustModule.compiler.(*fuzzDecorator) - if !ok { + if ok := cc.IsValid(rustModule.FuzzModule); !ok || rustModule.Properties.PreventInstall { return } - // Discard ramdisk + vendor_ramdisk + recovery modules, they're duplicates of - // fuzz targets we're going to package anyway. - if !rustModule.Enabled() || rustModule.Properties.PreventInstall || - rustModule.InRamdisk() || rustModule.InVendorRamdisk() || rustModule.InRecovery() { - return - } - - // Discard modules that are in an unavailable namespace. - if !rustModule.ExportedToMake() { + fuzzModule, ok := rustModule.compiler.(*fuzzDecorator) + if !ok { return } @@ -160,126 +133,34 @@ func (s *rustFuzzPackager) GenerateBuildActions(ctx android.SingletonContext) { archString := rustModule.Arch().ArchType.String() archDir := android.PathForIntermediates(ctx, "fuzz", hostOrTargetString, archString) - archOs := archOs{hostOrTarget: hostOrTargetString, arch: archString, dir: archDir.String()} + archOs := cc.ArchOs{HostOrTarget: hostOrTargetString, Arch: archString, Dir: archDir.String()} - var files []fileToZip + var files []cc.FileToZip builder := android.NewRuleBuilder(pctx, ctx) - // Package the corpora into a zipfile. - if fuzzModule.corpus != nil { - corpusZip := archDir.Join(ctx, module.Name()+"_seed_corpus.zip") - command := builder.Command().BuiltTool("soong_zip"). - Flag("-j"). - FlagWithOutput("-o ", corpusZip) - rspFile := corpusZip.ReplaceExtension(ctx, "rsp") - command.FlagWithRspFileInputList("-r ", rspFile, fuzzModule.corpus) - files = append(files, fileToZip{corpusZip, ""}) - } - - // Package the data into a zipfile. - if fuzzModule.data != nil { - dataZip := archDir.Join(ctx, module.Name()+"_data.zip") - command := builder.Command().BuiltTool("soong_zip"). - FlagWithOutput("-o ", dataZip) - for _, f := range fuzzModule.data { - intermediateDir := strings.TrimSuffix(f.String(), f.Rel()) - command.FlagWithArg("-C ", intermediateDir) - command.FlagWithInput("-f ", f) - } - files = append(files, fileToZip{dataZip, ""}) - } + // Package the artifacts (data, corpus, config and dictionary into a zipfile. + files = s.PackageArtifacts(ctx, module, fuzzModule.fuzzPackagedModule, archDir, builder) // The executable. - files = append(files, fileToZip{rustModule.unstrippedOutputFile.Path(), ""}) - - // The dictionary. - if fuzzModule.dictionary != nil { - files = append(files, fileToZip{fuzzModule.dictionary, ""}) - } + files = append(files, cc.FileToZip{rustModule.unstrippedOutputFile.Path(), ""}) - // Additional fuzz config. - if fuzzModule.config != nil { - files = append(files, fileToZip{fuzzModule.config, ""}) - } - - fuzzZip := archDir.Join(ctx, module.Name()+".zip") - - command := builder.Command().BuiltTool("soong_zip"). - Flag("-j"). - FlagWithOutput("-o ", fuzzZip) - - for _, file := range files { - if file.DestinationPathPrefix != "" { - command.FlagWithArg("-P ", file.DestinationPathPrefix) - } else { - command.Flag("-P ''") - } - command.FlagWithInput("-f ", file.SourceFilePath) - } - - builder.Build("create-"+fuzzZip.String(), - "Package "+module.Name()+" for "+archString+"-"+hostOrTargetString) - - // Don't add modules to 'make haiku-rust' that are set to not be - // exported to the fuzzing infrastructure. - if config := fuzzModule.Properties.Fuzz_config; config != nil { - if rustModule.Host() && !BoolDefault(config.Fuzz_on_haiku_host, true) { - return - } else if !BoolDefault(config.Fuzz_on_haiku_device, true) { - return - } + archDirs[archOs], ok = s.BuildZipFile(ctx, module, fuzzModule.fuzzPackagedModule, files, builder, archDir, archString, hostOrTargetString, archOs, archDirs) + if !ok { + return } - s.fuzzTargets[module.Name()] = true - archDirs[archOs] = append(archDirs[archOs], fileToZip{fuzzZip, ""}) }) - - var archOsList []archOs - for archOs := range archDirs { - archOsList = append(archOsList, archOs) - } - sort.Slice(archOsList, func(i, j int) bool { return archOsList[i].dir < archOsList[j].dir }) - - for _, archOs := range archOsList { - filesToZip := archDirs[archOs] - arch := archOs.arch - hostOrTarget := archOs.hostOrTarget - builder := android.NewRuleBuilder(pctx, ctx) - outputFile := android.PathForOutput(ctx, "fuzz-rust-"+hostOrTarget+"-"+arch+".zip") - s.packages = append(s.packages, outputFile) - - command := builder.Command().BuiltTool("soong_zip"). - Flag("-j"). - FlagWithOutput("-o ", outputFile). - Flag("-L 0") // No need to try and re-compress the zipfiles. - - for _, fileToZip := range filesToZip { - if fileToZip.DestinationPathPrefix != "" { - command.FlagWithArg("-P ", fileToZip.DestinationPathPrefix) - } else { - command.Flag("-P ''") - } - command.FlagWithInput("-f ", fileToZip.SourceFilePath) - } - builder.Build("create-fuzz-package-"+arch+"-"+hostOrTarget, - "Create fuzz target packages for "+arch+"-"+hostOrTarget) - } - + s.CreateFuzzPackage(ctx, archDirs, cc.Rust) } func (s *rustFuzzPackager) MakeVars(ctx android.MakeVarsContext) { - packages := s.packages.Strings() + packages := s.Packages.Strings() sort.Strings(packages) ctx.Strict("SOONG_RUST_FUZZ_PACKAGING_ARCH_MODULES", strings.Join(packages, " ")) - // Preallocate the slice of fuzz targets to minimise memory allocations. - fuzzTargets := make([]string, 0, len(s.fuzzTargets)) - for target, _ := range s.fuzzTargets { - fuzzTargets = append(fuzzTargets, target) - } - sort.Strings(fuzzTargets) - ctx.Strict("ALL_RUST_FUZZ_TARGETS", strings.Join(fuzzTargets, " ")) + // Preallocate the slice of fuzz targets to minimize memory allocations. + s.PreallocateSlice(ctx, "ALL_RUST_FUZZ_TARGETS") } func (fuzz *fuzzDecorator) install(ctx ModuleContext) { @@ -289,13 +170,13 @@ func (fuzz *fuzzDecorator) install(ctx ModuleContext) { "fuzz", ctx.Target().Arch.ArchType.String(), ctx.ModuleName()) fuzz.binaryDecorator.baseCompiler.install(ctx) - if fuzz.Properties.Corpus != nil { - fuzz.corpus = android.PathsForModuleSrc(ctx, fuzz.Properties.Corpus) + if fuzz.fuzzPackagedModule.FuzzProperties.Corpus != nil { + fuzz.fuzzPackagedModule.Corpus = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Corpus) } - if fuzz.Properties.Data != nil { - fuzz.data = android.PathsForModuleSrc(ctx, fuzz.Properties.Data) + if fuzz.fuzzPackagedModule.FuzzProperties.Data != nil { + fuzz.fuzzPackagedModule.Data = android.PathsForModuleSrc(ctx, fuzz.fuzzPackagedModule.FuzzProperties.Data) } - if fuzz.Properties.Dictionary != nil { - fuzz.dictionary = android.PathForModuleSrc(ctx, *fuzz.Properties.Dictionary) + if fuzz.fuzzPackagedModule.FuzzProperties.Dictionary != nil { + fuzz.fuzzPackagedModule.Dictionary = android.PathForModuleSrc(ctx, *fuzz.fuzzPackagedModule.FuzzProperties.Dictionary) } } diff --git a/rust/library.go b/rust/library.go index 747a29d72..5a36bd13f 100644 --- a/rust/library.go +++ b/rust/library.go @@ -431,6 +431,12 @@ func (library *libraryDecorator) sharedLibFilename(ctx ModuleContext) string { func (library *libraryDecorator) compilerFlags(ctx ModuleContext, flags Flags) Flags { flags.RustFlags = append(flags.RustFlags, "-C metadata="+ctx.ModuleName()) + if library.dylib() { + // We need to add a dependency on std in order to link crates as dylibs. + // The hack to add this dependency is guarded by the following cfg so + // that we don't force a dependency when it isn't needed. + library.baseCompiler.Properties.Cfgs = append(library.baseCompiler.Properties.Cfgs, "android_dylib") + } flags = library.baseCompiler.compilerFlags(ctx, flags) if library.shared() || library.static() { library.includeDirs = append(library.includeDirs, android.PathsForModuleSrc(ctx, library.Properties.Include_dirs)...) diff --git a/rust/library_test.go b/rust/library_test.go index 54cd2a5b3..cb4ef7eec 100644 --- a/rust/library_test.go +++ b/rust/library_test.go @@ -85,6 +85,22 @@ func TestDylibPreferDynamic(t *testing.T) { } } +// Check that we are passing the android_dylib config flag +func TestAndroidDylib(t *testing.T) { + ctx := testRust(t, ` + rust_library_host_dylib { + name: "libfoo", + srcs: ["foo.rs"], + crate_name: "foo", + }`) + + libfooDylib := ctx.ModuleForTests("libfoo", "linux_glibc_x86_64_dylib").Output("libfoo.dylib.so") + + if !strings.Contains(libfooDylib.Args["rustcFlags"], "--cfg 'android_dylib'") { + t.Errorf("missing android_dylib cfg flag for libfoo dylib, rustcFlags: %#v", libfooDylib.Args["rustcFlags"]) + } +} + func TestValidateLibraryStem(t *testing.T) { testRustError(t, "crate_name must be defined.", ` rust_library_host { diff --git a/rust/rust.go b/rust/rust.go index 38f1742d4..52b409435 100644 --- a/rust/rust.go +++ b/rust/rust.go @@ -119,9 +119,7 @@ type BaseProperties struct { } type Module struct { - android.ModuleBase - android.DefaultableModuleBase - android.ApexModuleBase + cc.FuzzModule VendorProperties cc.VendorProperties diff --git a/rust/test.go b/rust/test.go index 6caa7b168..e95b47cff 100644 --- a/rust/test.go +++ b/rust/test.go @@ -169,3 +169,11 @@ func RustTestHostFactory() android.Module { func (test *testDecorator) stdLinkage(ctx *depsContext) RustLinkage { return RlibLinkage } + +func (test *testDecorator) compilerDeps(ctx DepsContext, deps Deps) Deps { + deps = test.binaryDecorator.compilerDeps(ctx, deps) + + deps.Rustlibs = append(deps.Rustlibs, "libtest") + + return deps +} diff --git a/rust/testing.go b/rust/testing.go index 72f87e136..94cdd9dcd 100644 --- a/rust/testing.go +++ b/rust/testing.go @@ -170,12 +170,10 @@ func GatherRequiredDepsForTest() string { name: "libtest", crate_name: "test", srcs: ["foo.rs"], - no_stdlibs: true, host_supported: true, vendor_available: true, vendor_ramdisk_available: true, native_coverage: false, - sysroot: true, apex_available: ["//apex_available:platform", "//apex_available:anyapex"], min_sdk_version: "29", } diff --git a/rust/vendor_snapshot_test.go b/rust/vendor_snapshot_test.go index 815f80ec7..60ddb653f 100644 --- a/rust/vendor_snapshot_test.go +++ b/rust/vendor_snapshot_test.go @@ -569,7 +569,6 @@ func TestVendorSnapshotUse(t *testing.T) { ], rlibs: [ "libstd", - "libtest", "librust_vendor_available", ], binaries: [ @@ -597,7 +596,6 @@ func TestVendorSnapshotUse(t *testing.T) { ], rlibs: [ "libstd", - "libtest", "librust_vendor_available", ], binaries: [ @@ -665,22 +663,6 @@ func TestVendorSnapshotUse(t *testing.T) { } vendor_snapshot_rlib { - name: "libtest", - version: "30", - target_arch: "arm64", - vendor: true, - sysroot: true, - arch: { - arm64: { - src: "libtest.rlib", - }, - arm: { - src: "libtest.rlib", - }, - }, - } - - vendor_snapshot_rlib { name: "librust_vendor_available", version: "30", target_arch: "arm64", @@ -917,7 +899,6 @@ func TestVendorSnapshotUse(t *testing.T) { "vendor/lib64.so": nil, "vendor/liblog.so": nil, "vendor/libstd.rlib": nil, - "vendor/libtest.rlib": nil, "vendor/librust_vendor_available.rlib": nil, "vendor/crtbegin_so.o": nil, "vendor/crtend_so.o": nil, @@ -962,7 +943,7 @@ func TestVendorSnapshotUse(t *testing.T) { } libclientAndroidMkRlibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkRlibs - if g, w := libclientAndroidMkRlibs, []string{"librust_vendor_available.vendor_rlib.30.arm64.rlib-std", "libstd.vendor_rlib.30.arm64", "libtest.vendor_rlib.30.arm64"}; !reflect.DeepEqual(g, w) { + if g, w := libclientAndroidMkRlibs, []string{"librust_vendor_available.vendor_rlib.30.arm64.rlib-std", "libstd.vendor_rlib.30.arm64"}; !reflect.DeepEqual(g, w) { t.Errorf("wanted libclient libclientAndroidMkRlibs %q, got %q", w, g) } @@ -977,7 +958,7 @@ func TestVendorSnapshotUse(t *testing.T) { } libclientRustAndroidMkRlibs := ctx.ModuleForTests("libclient_rust", rlibVariant).Module().(*Module).Properties.AndroidMkRlibs - if g, w := libclientRustAndroidMkRlibs, []string{"librust_vendor_available.vendor_rlib.30.arm64.rlib-std", "libstd.vendor_rlib.30.arm64", "libtest.vendor_rlib.30.arm64"}; !reflect.DeepEqual(g, w) { + if g, w := libclientRustAndroidMkRlibs, []string{"librust_vendor_available.vendor_rlib.30.arm64.rlib-std", "libstd.vendor_rlib.30.arm64"}; !reflect.DeepEqual(g, w) { t.Errorf("wanted libclient libclientAndroidMkRlibs %q, got %q", w, g) } diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go index a458cba7d..efd2b5bd9 100644 --- a/sdk/bootclasspath_fragment_sdk_test.go +++ b/sdk/bootclasspath_fragment_sdk_test.go @@ -133,6 +133,13 @@ prebuilt_bootclasspath_fragment { apex_available: ["com.android.art"], image_name: "art", contents: ["mybootlib"], + hidden_api: { + stub_flags: "hiddenapi/stub-flags.csv", + annotation_flags: "hiddenapi/annotation-flags.csv", + metadata: "hiddenapi/metadata.csv", + index: "hiddenapi/index.csv", + all_flags: "hiddenapi/all-flags.csv", + }, } java_import { @@ -140,7 +147,7 @@ java_import { prefer: false, visibility: ["//visibility:public"], apex_available: ["com.android.art"], - jars: ["java/mybootlib.jar"], + jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"], } `), checkVersionedAndroidBpContents(` @@ -153,6 +160,13 @@ prebuilt_bootclasspath_fragment { apex_available: ["com.android.art"], image_name: "art", contents: ["mysdk_mybootlib@current"], + hidden_api: { + stub_flags: "hiddenapi/stub-flags.csv", + annotation_flags: "hiddenapi/annotation-flags.csv", + metadata: "hiddenapi/metadata.csv", + index: "hiddenapi/index.csv", + all_flags: "hiddenapi/all-flags.csv", + }, } java_import { @@ -160,7 +174,7 @@ java_import { sdk_member_name: "mybootlib", visibility: ["//visibility:public"], apex_available: ["com.android.art"], - jars: ["java/mybootlib.jar"], + jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"], } sdk_snapshot { @@ -171,8 +185,13 @@ sdk_snapshot { } `), checkAllCopyRules(` -.intermediates/mybootlib/android_common/javac/mybootlib.jar -> java/mybootlib.jar -`), +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/stub-flags.csv -> hiddenapi/stub-flags.csv +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/annotation-flags.csv -> hiddenapi/annotation-flags.csv +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/index.csv -> hiddenapi/index.csv +.intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/all-flags.csv -> hiddenapi/all-flags.csv +.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar + `), snapshotTestPreparer(checkSnapshotWithoutSource, preparerForSnapshot), // Check the behavior of the snapshot without the source. @@ -326,7 +345,8 @@ java_import { prefer: false, visibility: ["//visibility:public"], apex_available: ["myapex"], - jars: ["java/mybootlib.jar"], + jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"], + permitted_packages: ["mybootlib"], } java_sdk_library_import { @@ -336,6 +356,7 @@ java_sdk_library_import { apex_available: ["myapex"], shared_library: true, compile_dex: true, + permitted_packages: ["myothersdklibrary"], public: { jars: ["sdk_library/public/myothersdklibrary-stubs.jar"], stub_srcs: ["sdk_library/public/myothersdklibrary_stub_sources"], @@ -408,7 +429,8 @@ java_import { sdk_member_name: "mybootlib", visibility: ["//visibility:public"], apex_available: ["myapex"], - jars: ["java/mybootlib.jar"], + jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"], + permitted_packages: ["mybootlib"], } java_sdk_library_import { @@ -418,6 +440,7 @@ java_sdk_library_import { apex_available: ["myapex"], shared_library: true, compile_dex: true, + permitted_packages: ["myothersdklibrary"], public: { jars: ["sdk_library/public/myothersdklibrary-stubs.jar"], stub_srcs: ["sdk_library/public/myothersdklibrary_stub_sources"], @@ -476,7 +499,7 @@ sdk_snapshot { .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/index.csv -> hiddenapi/index.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/all-flags.csv -> hiddenapi/all-flags.csv -.intermediates/mybootlib/android_common/javac/mybootlib.jar -> java/mybootlib.jar +.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar .intermediates/myothersdklibrary.stubs/android_common/javac/myothersdklibrary.stubs.jar -> sdk_library/public/myothersdklibrary-stubs.jar .intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_api.txt -> sdk_library/public/myothersdklibrary.txt .intermediates/myothersdklibrary.stubs.source/android_common/metalava/myothersdklibrary.stubs.source_removed.txt -> sdk_library/public/myothersdklibrary-removed.txt @@ -509,6 +532,12 @@ sdk_snapshot { out/soong/.intermediates/frameworks/base/boot/platform-bootclasspath/android_common/hiddenapi-monolithic/index-from-classes.csv snapshot/hiddenapi/index.csv `, rule) + + // Make sure that the permitted packages from the prebuilts end up in the + // updatable-bcp-packages.txt file. + rule = module.Output("updatable-bcp-packages.txt") + expectedContents := `'mybootlib\nmyothersdklibrary\n'` + android.AssertStringEquals(t, "updatable-bcp-packages.txt", expectedContents, rule.Args["content"]) }), snapshotTestPreparer(checkSnapshotWithSourcePreferred, preparerForSnapshot), snapshotTestPreparer(checkSnapshotPreferredWithSource, preparerForSnapshot), @@ -779,6 +808,7 @@ func TestSnapshotWithBootclasspathFragment_HiddenAPI(t *testing.T) { srcs: ["Test.java"], compile_dex: true, public: {enabled: true}, + permitted_packages: ["mysdklibrary"], } `), ).RunTest(t) @@ -821,7 +851,8 @@ java_import { prefer: false, visibility: ["//visibility:public"], apex_available: ["myapex"], - jars: ["java/mybootlib.jar"], + jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"], + permitted_packages: ["mybootlib"], } java_sdk_library_import { @@ -831,6 +862,7 @@ java_sdk_library_import { apex_available: ["//apex_available:platform"], shared_library: true, compile_dex: true, + permitted_packages: ["mysdklibrary"], public: { jars: ["sdk_library/public/mysdklibrary-stubs.jar"], stub_srcs: ["sdk_library/public/mysdklibrary_stub_sources"], @@ -854,7 +886,7 @@ my-unsupported-packages.txt -> hiddenapi/my-unsupported-packages.txt .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/metadata.csv -> hiddenapi/metadata.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/index.csv -> hiddenapi/index.csv .intermediates/mybootclasspathfragment/android_common/modular-hiddenapi/all-flags.csv -> hiddenapi/all-flags.csv -.intermediates/mybootlib/android_common/javac/mybootlib.jar -> java/mybootlib.jar +.intermediates/mysdk/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar .intermediates/mysdklibrary.stubs/android_common/javac/mysdklibrary.stubs.jar -> sdk_library/public/mysdklibrary-stubs.jar .intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_api.txt -> sdk_library/public/mysdklibrary.txt .intermediates/mysdklibrary.stubs.source/android_common/metalava/mysdklibrary.stubs.source_removed.txt -> sdk_library/public/mysdklibrary-removed.txt diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go index a2cfe6d16..9efb3a49a 100644 --- a/sdk/java_sdk_test.go +++ b/sdk/java_sdk_test.go @@ -175,6 +175,7 @@ func TestSnapshotWithJavaHeaderLibrary(t *testing.T) { sdk_version: "none", compile_dex: true, host_supported: true, + permitted_packages: ["pkg.myjavalib"], } `) @@ -188,6 +189,7 @@ java_import { visibility: ["//visibility:public"], apex_available: ["//apex_available:platform"], jars: ["java/myjavalib.jar"], + permitted_packages: ["pkg.myjavalib"], } `), checkVersionedAndroidBpContents(` @@ -199,6 +201,7 @@ java_import { visibility: ["//visibility:public"], apex_available: ["//apex_available:platform"], jars: ["java/myjavalib.jar"], + permitted_packages: ["pkg.myjavalib"], } sdk_snapshot { @@ -437,6 +440,7 @@ func TestSnapshotWithJavaBootLibrary(t *testing.T) { system_modules: "none", sdk_version: "none", compile_dex: true, + permitted_packages: ["pkg.myjavalib"], } `) @@ -449,7 +453,8 @@ java_import { prefer: false, visibility: ["//visibility:public"], apex_available: ["//apex_available:platform"], - jars: ["java/myjavalib.jar"], + jars: ["java_boot_libs/snapshot/jars/are/invalid/myjavalib.jar"], + permitted_packages: ["pkg.myjavalib"], } `), checkVersionedAndroidBpContents(` @@ -460,7 +465,8 @@ java_import { sdk_member_name: "myjavalib", visibility: ["//visibility:public"], apex_available: ["//apex_available:platform"], - jars: ["java/myjavalib.jar"], + jars: ["java_boot_libs/snapshot/jars/are/invalid/myjavalib.jar"], + permitted_packages: ["pkg.myjavalib"], } module_exports_snapshot { @@ -468,9 +474,10 @@ module_exports_snapshot { visibility: ["//visibility:public"], java_boot_libs: ["myexports_myjavalib@current"], } + `), checkAllCopyRules(` -.intermediates/myjavalib/android_common/withres/myjavalib.jar -> java/myjavalib.jar +.intermediates/myexports/common_os/empty -> java_boot_libs/snapshot/jars/are/invalid/myjavalib.jar `), ) } @@ -1045,6 +1052,7 @@ func TestSnapshotWithJavaSdkLibrary(t *testing.T) { shared_library: false, stubs_library_visibility: ["//other"], stubs_source_visibility: ["//another"], + permitted_packages: ["pkg.myjavalib"], } `) @@ -1058,6 +1066,7 @@ java_sdk_library_import { visibility: ["//visibility:public"], apex_available: ["//apex_available:anyapex"], shared_library: false, + permitted_packages: ["pkg.myjavalib"], public: { jars: ["sdk_library/public/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], @@ -1090,6 +1099,7 @@ java_sdk_library_import { visibility: ["//visibility:public"], apex_available: ["//apex_available:anyapex"], shared_library: false, + permitted_packages: ["pkg.myjavalib"], public: { jars: ["sdk_library/public/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go index a13b0d7d0..97fb2485f 100644 --- a/sdk/sdk_test.go +++ b/sdk/sdk_test.go @@ -565,6 +565,49 @@ sdk_snapshot { ) }) + t.Run("SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR=module:build_from_source", func(t *testing.T) { + result := android.GroupFixturePreparers( + preparer, + android.FixtureMergeEnv(map[string]string{ + "SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR": "module:build_from_source", + }), + ).RunTest(t) + + checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk-current.zip") + + CheckSnapshot(t, result, "mysdk", "", + checkAndroidBpContents(` +// This is auto-generated. DO NOT EDIT. + +java_import { + name: "mysdk_myjavalib@current", + sdk_member_name: "myjavalib", + visibility: ["//visibility:public"], + apex_available: ["//apex_available:platform"], + jars: ["java/myjavalib.jar"], +} + +java_import { + name: "myjavalib", + prefer: false, + use_source_config_var: { + config_namespace: "module", + var_name: "build_from_source", + }, + visibility: ["//visibility:public"], + apex_available: ["//apex_available:platform"], + jars: ["java/myjavalib.jar"], +} + +sdk_snapshot { + name: "mysdk@current", + visibility: ["//visibility:public"], + java_header_libs: ["mysdk_myjavalib@current"], +} + `), + ) + }) + t.Run("SOONG_SDK_SNAPSHOT_VERSION=unversioned", func(t *testing.T) { result := android.GroupFixturePreparers( preparer, diff --git a/sdk/update.go b/sdk/update.go index b146b62c8..3ec1bfaf4 100644 --- a/sdk/update.go +++ b/sdk/update.go @@ -35,6 +35,37 @@ import ( // By default every unversioned module in the generated snapshot has prefer: false. Building it // with SOONG_SDK_SNAPSHOT_PREFER=true will force them to use prefer: true. // +// SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR +// If set this specifies the Soong config var that can be used to control whether the prebuilt +// modules from the generated snapshot or the original source modules. Values must be a colon +// separated pair of strings, the first of which is the Soong config namespace, and the second +// is the name of the variable within that namespace. +// +// The config namespace and var name are used to set the `use_source_config_var` property. That +// in turn will cause the generated prebuilts to use the soong config variable to select whether +// source or the prebuilt is used. +// e.g. If an sdk snapshot is built using: +// m SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR=acme:build_from_source sdkextensions-sdk +// Then the resulting snapshot will include: +// use_source_config_var: { +// config_namespace: "acme", +// var_name: "build_from_source", +// } +// +// Assuming that the config variable is defined in .mk using something like: +// $(call add_soong_config_namespace,acme) +// $(call add_soong_config_var_value,acme,build_from_source,true) +// +// Then when the snapshot is unpacked in the repository it will have the following behavior: +// m droid - will use the sdkextensions-sdk prebuilts if present. Otherwise, it will use the +// sources. +// m SOONG_CONFIG_acme_build_from_source=true droid - will use the sdkextensions-sdk +// sources, if present. Otherwise, it will use the prebuilts. +// +// This is a temporary mechanism to control the prefer flags and will be removed once a more +// maintainable solution has been implemented. +// TODO(b/174997203): Remove when no longer necessary. +// // SOONG_SDK_SNAPSHOT_VERSION // This provides control over the version of the generated snapshot. // @@ -760,6 +791,8 @@ func (t unversionedToVersionedTransformation) transformModule(module *bpModule) module.insertAfter("name", "sdk_member_name", name) // Remove the prefer property if present as versioned modules never need marking with prefer. module.removeProperty("prefer") + // Ditto for use_source_config_var + module.removeProperty("use_source_config_var") return module } @@ -996,6 +1029,9 @@ type snapshotBuilder struct { filesToZip android.Paths zipsToMerge android.Paths + // The path to an empty file. + emptyFile android.WritablePath + prebuiltModules map[string]*bpModule prebuiltOrder []*bpModule @@ -1046,6 +1082,19 @@ func (s *snapshotBuilder) UnzipToSnapshot(zipPath android.Path, destDir string) s.zipsToMerge = append(s.zipsToMerge, tmpZipPath) } +func (s *snapshotBuilder) EmptyFile() android.Path { + if s.emptyFile == nil { + ctx := s.ctx + s.emptyFile = android.PathForModuleOut(ctx, "empty") + s.ctx.Build(pctx, android.BuildParams{ + Rule: android.Touch, + Output: s.emptyFile, + }) + } + + return s.emptyFile +} + func (s *snapshotBuilder) AddPrebuiltModule(member android.SdkMember, moduleType string) android.BpModule { name := member.Name() if s.prebuiltModules[name] != nil { @@ -1627,13 +1676,24 @@ func (s *sdk) createMemberSnapshot(ctx *memberContext, member *sdkMember, bpModu // snapshot to be created that sets prefer: true. // TODO(b/174997203): Remove once the ability to select the modules to prefer can be done // dynamically at build time not at snapshot generation time. - prefer := ctx.sdkMemberContext.Config().IsEnvTrue("SOONG_SDK_SNAPSHOT_PREFER") + config := ctx.sdkMemberContext.Config() + prefer := config.IsEnvTrue("SOONG_SDK_SNAPSHOT_PREFER") // Set prefer. Setting this to false is not strictly required as that is the default but it does // provide a convenient hook to post-process the generated Android.bp file, e.g. in tests to // check the behavior when a prebuilt is preferred. It also makes it explicit what the default // behavior is for the module. bpModule.insertAfter("name", "prefer", prefer) + + configVar := config.Getenv("SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR") + if configVar != "" { + parts := strings.Split(configVar, ":") + cfp := android.ConfigVarProperties{ + Config_namespace: proptools.StringPtr(parts[0]), + Var_name: proptools.StringPtr(parts[1]), + } + bpModule.insertAfter("prefer", "use_source_config_var", cfp) + } } // Group the variants by os type. diff --git a/ui/build/config.go b/ui/build/config.go index 737062732..cd6d549ea 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -345,12 +345,7 @@ func storeConfigMetrics(ctx Context, config Config) { return } - b := &smpb.BuildConfig{ - ForceUseGoma: proto.Bool(config.ForceUseGoma()), - UseGoma: proto.Bool(config.UseGoma()), - UseRbe: proto.Bool(config.UseRBE()), - } - ctx.Metrics.BuildConfig(b) + ctx.Metrics.BuildConfig(buildConfig(config)) s := &smpb.SystemResourceInfo{ TotalPhysicalMemory: proto.Uint64(config.TotalRAM()), @@ -359,6 +354,16 @@ func storeConfigMetrics(ctx Context, config Config) { ctx.Metrics.SystemResourceInfo(s) } +func buildConfig(config Config) *smpb.BuildConfig { + return &smpb.BuildConfig{ + ForceUseGoma: proto.Bool(config.ForceUseGoma()), + UseGoma: proto.Bool(config.UseGoma()), + UseRbe: proto.Bool(config.UseRBE()), + BazelAsNinja: proto.Bool(config.UseBazel()), + BazelMixedBuild: proto.Bool(config.bazelBuildMode() == mixedBuild), + } +} + // getConfigArgs processes the command arguments based on the build action and creates a set of new // arguments to be accepted by Config. func getConfigArgs(action BuildAction, dir string, ctx Context, args []string) []string { diff --git a/ui/build/config_test.go b/ui/build/config_test.go index 7b14c4703..7d4c76b83 100644 --- a/ui/build/config_test.go +++ b/ui/build/config_test.go @@ -26,7 +26,10 @@ import ( "testing" "android/soong/ui/logger" + smpb "android/soong/ui/metrics/metrics_proto" "android/soong/ui/status" + + "github.com/golang/protobuf/proto" ) func testContext() Context { @@ -995,3 +998,111 @@ func TestGetConfigArgsBuildModulesInDirectories(t *testing.T) { }) } } + +func TestBuildConfig(t *testing.T) { + tests := []struct { + name string + environ Environment + useBazel bool + expectedBuildConfig *smpb.BuildConfig + }{ + { + name: "none set", + environ: Environment{}, + expectedBuildConfig: &smpb.BuildConfig{ + ForceUseGoma: proto.Bool(false), + UseGoma: proto.Bool(false), + UseRbe: proto.Bool(false), + BazelAsNinja: proto.Bool(false), + BazelMixedBuild: proto.Bool(false), + }, + }, + { + name: "force use goma", + environ: Environment{"FORCE_USE_GOMA=1"}, + expectedBuildConfig: &smpb.BuildConfig{ + ForceUseGoma: proto.Bool(true), + UseGoma: proto.Bool(false), + UseRbe: proto.Bool(false), + BazelAsNinja: proto.Bool(false), + BazelMixedBuild: proto.Bool(false), + }, + }, + { + name: "use goma", + environ: Environment{"USE_GOMA=1"}, + expectedBuildConfig: &smpb.BuildConfig{ + ForceUseGoma: proto.Bool(false), + UseGoma: proto.Bool(true), + UseRbe: proto.Bool(false), + BazelAsNinja: proto.Bool(false), + BazelMixedBuild: proto.Bool(false), + }, + }, + { + name: "use rbe", + environ: Environment{"USE_RBE=1"}, + expectedBuildConfig: &smpb.BuildConfig{ + ForceUseGoma: proto.Bool(false), + UseGoma: proto.Bool(false), + UseRbe: proto.Bool(true), + BazelAsNinja: proto.Bool(false), + BazelMixedBuild: proto.Bool(false), + }, + }, + { + name: "use bazel as ninja", + environ: Environment{}, + useBazel: true, + expectedBuildConfig: &smpb.BuildConfig{ + ForceUseGoma: proto.Bool(false), + UseGoma: proto.Bool(false), + UseRbe: proto.Bool(false), + BazelAsNinja: proto.Bool(true), + BazelMixedBuild: proto.Bool(false), + }, + }, + { + name: "bazel mixed build", + environ: Environment{"USE_BAZEL_ANALYSIS=1"}, + expectedBuildConfig: &smpb.BuildConfig{ + ForceUseGoma: proto.Bool(false), + UseGoma: proto.Bool(false), + UseRbe: proto.Bool(false), + BazelAsNinja: proto.Bool(false), + BazelMixedBuild: proto.Bool(true), + }, + }, + { + name: "all set", + environ: Environment{ + "FORCE_USE_GOMA=1", + "USE_GOMA=1", + "USE_RBE=1", + "USE_BAZEL_ANALYSIS=1", + }, + useBazel: true, + expectedBuildConfig: &smpb.BuildConfig{ + ForceUseGoma: proto.Bool(true), + UseGoma: proto.Bool(true), + UseRbe: proto.Bool(true), + BazelAsNinja: proto.Bool(true), + BazelMixedBuild: proto.Bool(true), + }, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + c := &configImpl{ + environ: &tc.environ, + useBazel: tc.useBazel, + } + config := Config{c} + actualBuildConfig := buildConfig(config) + if expected := tc.expectedBuildConfig; !proto.Equal(expected, actualBuildConfig) { + t.Errorf("Expected build config != actual build config: %#v != %#v", *expected, *actualBuildConfig) + } + }) + } +} diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go index 83c8865de..f3c442ec8 100644 --- a/ui/build/dumpvars.go +++ b/ui/build/dumpvars.go @@ -163,6 +163,7 @@ var BannerVars = []string{ "AUX_OS_VARIANT_LIST", "PRODUCT_SOONG_NAMESPACES", "SOONG_SDK_SNAPSHOT_PREFER", + "SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR", "SOONG_SDK_SNAPSHOT_VERSION", } diff --git a/ui/metrics/metrics_proto/metrics.pb.go b/ui/metrics/metrics_proto/metrics.pb.go index fc2cfa492..106333707 100644 --- a/ui/metrics/metrics_proto/metrics.pb.go +++ b/ui/metrics/metrics_proto/metrics.pb.go @@ -433,9 +433,14 @@ func (m *MetricsBase) GetBazelRuns() []*PerfInfo { } type BuildConfig struct { - UseGoma *bool `protobuf:"varint,1,opt,name=use_goma,json=useGoma" json:"use_goma,omitempty"` - UseRbe *bool `protobuf:"varint,2,opt,name=use_rbe,json=useRbe" json:"use_rbe,omitempty"` - ForceUseGoma *bool `protobuf:"varint,3,opt,name=force_use_goma,json=forceUseGoma" json:"force_use_goma,omitempty"` + UseGoma *bool `protobuf:"varint,1,opt,name=use_goma,json=useGoma" json:"use_goma,omitempty"` + UseRbe *bool `protobuf:"varint,2,opt,name=use_rbe,json=useRbe" json:"use_rbe,omitempty"` + ForceUseGoma *bool `protobuf:"varint,3,opt,name=force_use_goma,json=forceUseGoma" json:"force_use_goma,omitempty"` + // Whether the Bazel is acting as the Ninja executor for this build. + BazelAsNinja *bool `protobuf:"varint,4,opt,name=bazel_as_ninja,json=bazelAsNinja" json:"bazel_as_ninja,omitempty"` + // Whether build is occurring in a mixed build mode, where Bazel maintains the + // definition and build of some modules in cooperation with Soong. + BazelMixedBuild *bool `protobuf:"varint,5,opt,name=bazel_mixed_build,json=bazelMixedBuild" json:"bazel_mixed_build,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -487,6 +492,20 @@ func (m *BuildConfig) GetForceUseGoma() bool { return false } +func (m *BuildConfig) GetBazelAsNinja() bool { + if m != nil && m.BazelAsNinja != nil { + return *m.BazelAsNinja + } + return false +} + +func (m *BuildConfig) GetBazelMixedBuild() bool { + if m != nil && m.BazelMixedBuild != nil { + return *m.BazelMixedBuild + } + return false +} + type SystemResourceInfo struct { // The total physical memory in bytes. TotalPhysicalMemory *uint64 `protobuf:"varint,1,opt,name=total_physical_memory,json=totalPhysicalMemory" json:"total_physical_memory,omitempty"` @@ -990,92 +1009,94 @@ func init() { } var fileDescriptor_6039342a2ba47b72 = []byte{ - // 1380 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xef, 0x52, 0x1b, 0x37, - 0x10, 0x8f, 0xc1, 0x60, 0x7b, 0xfd, 0x07, 0x23, 0xa0, 0x5c, 0x48, 0xd2, 0x52, 0xb7, 0x49, 0x99, - 0x4e, 0x43, 0x32, 0x34, 0xc3, 0x64, 0x98, 0x4c, 0xa7, 0xe0, 0xd0, 0x34, 0x65, 0xc0, 0x8c, 0x08, - 0x69, 0xda, 0x7e, 0x50, 0xe5, 0xb3, 0x0c, 0x97, 0xdc, 0x9d, 0x6e, 0x24, 0x1d, 0xc5, 0x79, 0xb3, - 0x7e, 0xee, 0x4b, 0xf4, 0x05, 0xfa, 0x04, 0x7d, 0x81, 0x8e, 0x56, 0x77, 0xe6, 0x20, 0x6e, 0xc2, - 0xe4, 0xdb, 0xe9, 0xb7, 0xbf, 0xdf, 0x6a, 0xb5, 0xd2, 0xee, 0xda, 0xd0, 0x8c, 0x84, 0x51, 0x81, - 0xaf, 0xd7, 0x13, 0x25, 0x8d, 0x24, 0x0b, 0x5a, 0xca, 0xf8, 0x84, 0xf5, 0xd3, 0x20, 0x1c, 0xb0, - 0xcc, 0xd4, 0xf9, 0xbb, 0x01, 0xf5, 0x7d, 0xf7, 0xbd, 0xc3, 0xb5, 0x20, 0x0f, 0x61, 0xd1, 0x11, - 0x06, 0xdc, 0x08, 0x66, 0x82, 0x48, 0x68, 0xc3, 0xa3, 0xc4, 0x2b, 0xad, 0x96, 0xd6, 0xa6, 0x29, - 0x41, 0xdb, 0x53, 0x6e, 0xc4, 0x8b, 0xdc, 0x42, 0x6e, 0x42, 0xd5, 0x29, 0x82, 0x81, 0x37, 0xb5, - 0x5a, 0x5a, 0xab, 0xd1, 0x0a, 0xae, 0x9f, 0x0f, 0xc8, 0x16, 0xdc, 0x4c, 0x42, 0x6e, 0x86, 0x52, - 0x45, 0xec, 0x4c, 0x28, 0x1d, 0xc8, 0x98, 0xf9, 0x72, 0x20, 0x62, 0x1e, 0x09, 0x6f, 0x1a, 0xb9, - 0xcb, 0x39, 0xe1, 0xa5, 0xb3, 0x77, 0x33, 0x33, 0xb9, 0x0b, 0x2d, 0xc3, 0xd5, 0x89, 0x30, 0x2c, - 0x51, 0x72, 0x90, 0xfa, 0xc6, 0x2b, 0xa3, 0xa0, 0xe9, 0xd0, 0x43, 0x07, 0x92, 0x01, 0x2c, 0x66, - 0x34, 0x17, 0xc4, 0x19, 0x57, 0x01, 0x8f, 0x8d, 0x37, 0xb3, 0x5a, 0x5a, 0x6b, 0x6d, 0xdc, 0x5f, - 0x9f, 0x70, 0xe6, 0xf5, 0xc2, 0x79, 0xd7, 0x77, 0xac, 0xe5, 0xa5, 0x13, 0x6d, 0x4d, 0xef, 0x1e, - 0x3c, 0xa3, 0xc4, 0xf9, 0x2b, 0x1a, 0x48, 0x0f, 0xea, 0xd9, 0x2e, 0x5c, 0xf9, 0xa7, 0xde, 0x2c, - 0x3a, 0xbf, 0xfb, 0x41, 0xe7, 0xdb, 0xca, 0x3f, 0xdd, 0xaa, 0x1c, 0x1f, 0xec, 0x1d, 0xf4, 0x7e, - 0x3e, 0xa0, 0xe0, 0x5c, 0x58, 0x90, 0xac, 0xc3, 0x42, 0xc1, 0xe1, 0x38, 0xea, 0x0a, 0x1e, 0x71, - 0xfe, 0x82, 0x98, 0x07, 0xf0, 0x0d, 0x64, 0x61, 0x31, 0x3f, 0x49, 0xc7, 0xf4, 0x2a, 0xd2, 0xdb, - 0xce, 0xd2, 0x4d, 0xd2, 0x9c, 0xbd, 0x07, 0xb5, 0x53, 0xa9, 0xb3, 0x60, 0x6b, 0x1f, 0x15, 0x6c, - 0xd5, 0x3a, 0xc0, 0x50, 0x29, 0x34, 0xd1, 0xd9, 0x46, 0x3c, 0x70, 0x0e, 0xe1, 0xa3, 0x1c, 0xd6, - 0xad, 0x93, 0x8d, 0x78, 0x80, 0x3e, 0x97, 0xa1, 0x82, 0x3e, 0xa5, 0xf6, 0xea, 0x78, 0x86, 0x59, - 0xbb, 0xec, 0x69, 0xd2, 0xc9, 0x36, 0x93, 0x9a, 0x89, 0x73, 0xa3, 0xb8, 0xd7, 0x40, 0x73, 0xdd, - 0x99, 0x77, 0x2d, 0x34, 0xe6, 0xf8, 0x4a, 0x6a, 0x6d, 0x5d, 0x34, 0x2f, 0x38, 0x5d, 0x8b, 0xf5, - 0x34, 0xb9, 0x07, 0x73, 0x05, 0x0e, 0x86, 0xdd, 0x72, 0xcf, 0x67, 0xcc, 0xc2, 0x40, 0xee, 0xc3, - 0x42, 0x81, 0x37, 0x3e, 0xe2, 0x9c, 0x4b, 0xec, 0x98, 0x5b, 0x88, 0x5b, 0xa6, 0x86, 0x0d, 0x02, - 0xe5, 0xb5, 0x5d, 0xdc, 0x32, 0x35, 0x4f, 0x03, 0x45, 0xbe, 0x83, 0xba, 0x16, 0x26, 0x4d, 0x98, - 0x91, 0x32, 0xd4, 0xde, 0xfc, 0xea, 0xf4, 0x5a, 0x7d, 0xe3, 0xce, 0xc4, 0x14, 0x1d, 0x0a, 0x35, - 0x7c, 0x1e, 0x0f, 0x25, 0x05, 0x54, 0xbc, 0xb0, 0x02, 0xb2, 0x05, 0xb5, 0x37, 0xdc, 0x04, 0x4c, - 0xa5, 0xb1, 0xf6, 0xc8, 0x75, 0xd4, 0x55, 0xcb, 0xa7, 0x69, 0xac, 0xc9, 0x13, 0x00, 0xc7, 0x44, - 0xf1, 0xc2, 0x75, 0xc4, 0x35, 0xb4, 0xe6, 0xea, 0x38, 0x88, 0x5f, 0x73, 0xa7, 0x5e, 0xbc, 0x96, - 0x1a, 0x05, 0xa8, 0xfe, 0x16, 0x66, 0x8c, 0x34, 0x3c, 0xf4, 0x96, 0x56, 0x4b, 0x1f, 0x16, 0x3a, - 0x2e, 0x79, 0x09, 0x93, 0x5a, 0x91, 0xf7, 0x09, 0xba, 0xb8, 0x37, 0xd1, 0xc5, 0x91, 0xc5, 0xb0, - 0x24, 0xb3, 0x17, 0x46, 0xe7, 0xf5, 0x55, 0x88, 0x74, 0xa1, 0xe1, 0x54, 0xbe, 0x8c, 0x87, 0xc1, - 0x89, 0xb7, 0x8c, 0x0e, 0x57, 0x27, 0x3a, 0x44, 0x61, 0x17, 0x79, 0xb4, 0xde, 0xbf, 0x58, 0x90, - 0x15, 0xc0, 0xa7, 0x8f, 0x2d, 0xca, 0xc3, 0x3b, 0x1e, 0xaf, 0xc9, 0x2f, 0xb0, 0xa8, 0x47, 0xda, - 0x88, 0x88, 0x29, 0xa1, 0x65, 0xaa, 0x7c, 0xc1, 0x82, 0x78, 0x28, 0xbd, 0x9b, 0xb8, 0xd1, 0x57, - 0x93, 0x23, 0x47, 0x01, 0xcd, 0xf8, 0x98, 0x06, 0xa2, 0xdf, 0xc1, 0xc8, 0x17, 0xd0, 0xcc, 0x63, - 0x8f, 0x22, 0x1e, 0x0f, 0xbc, 0x15, 0xdc, 0xbb, 0x91, 0x85, 0x86, 0x98, 0xbd, 0xab, 0x3e, 0x7f, - 0x2b, 0x42, 0x77, 0x57, 0xb7, 0xae, 0x75, 0x57, 0x28, 0xb0, 0x77, 0xd5, 0x79, 0x08, 0x8d, 0x4b, - 0x4d, 0xad, 0x0a, 0xe5, 0xe3, 0xa3, 0x5d, 0xda, 0xbe, 0x41, 0x9a, 0x50, 0xb3, 0x5f, 0x4f, 0x77, - 0x77, 0x8e, 0x9f, 0xb5, 0x4b, 0xa4, 0x02, 0xb6, 0x11, 0xb6, 0xa7, 0x3a, 0x4f, 0xa0, 0x8c, 0xcf, - 0xbe, 0x0e, 0x79, 0x19, 0xb7, 0x6f, 0x58, 0xeb, 0x36, 0xdd, 0x6f, 0x97, 0x48, 0x0d, 0x66, 0xb6, - 0xe9, 0xfe, 0xe6, 0xa3, 0xf6, 0x94, 0xc5, 0x5e, 0x3d, 0xde, 0x6c, 0x4f, 0x13, 0x80, 0xd9, 0x57, - 0x8f, 0x37, 0xd9, 0xe6, 0xa3, 0x76, 0xb9, 0x73, 0x02, 0xf5, 0x42, 0x96, 0xed, 0x9c, 0x48, 0xb5, - 0x60, 0x27, 0x32, 0xe2, 0x38, 0x4d, 0xaa, 0xb4, 0x92, 0x6a, 0xf1, 0x4c, 0x46, 0xdc, 0x96, 0x95, - 0x35, 0xa9, 0xbe, 0xc0, 0x09, 0x52, 0xa5, 0xb3, 0xa9, 0x16, 0xb4, 0x2f, 0xc8, 0x97, 0xd0, 0x1a, - 0x4a, 0x9b, 0xe6, 0xb1, 0x72, 0x1a, 0xed, 0x0d, 0x44, 0x8f, 0x9d, 0xbc, 0x23, 0x81, 0xbc, 0x9b, - 0x65, 0xb2, 0x01, 0x4b, 0xf8, 0xdc, 0x58, 0x72, 0x3a, 0xd2, 0x81, 0xcf, 0x43, 0x16, 0x89, 0x48, - 0xaa, 0x11, 0x6e, 0x5e, 0xa6, 0x0b, 0x68, 0x3c, 0xcc, 0x6c, 0xfb, 0x68, 0xb2, 0x43, 0x87, 0x9f, - 0xf1, 0x20, 0xe4, 0xfd, 0x50, 0xd8, 0x4e, 0xab, 0x31, 0x9e, 0x19, 0xda, 0x1c, 0xa3, 0xdd, 0x24, - 0xd5, 0x9d, 0x7f, 0x4b, 0x50, 0xcd, 0x33, 0x4c, 0x08, 0x94, 0x07, 0x42, 0xfb, 0xe8, 0xb6, 0x46, - 0xf1, 0xdb, 0x62, 0xf8, 0x80, 0xdc, 0x3c, 0xc4, 0x6f, 0x72, 0x07, 0x40, 0x1b, 0xae, 0x0c, 0x0e, - 0x55, 0x3c, 0x47, 0x99, 0xd6, 0x10, 0xb1, 0xb3, 0x94, 0xdc, 0x82, 0x9a, 0x12, 0x3c, 0x74, 0xd6, - 0x32, 0x5a, 0xab, 0x16, 0x40, 0xe3, 0xe7, 0x00, 0x2e, 0x78, 0x9b, 0x08, 0x9c, 0x6d, 0xe5, 0x9d, - 0x29, 0xaf, 0x44, 0x6b, 0x0e, 0x3d, 0xd6, 0x82, 0xfc, 0x0e, 0xcb, 0x89, 0x92, 0xbe, 0xd0, 0x5a, - 0xe8, 0x2b, 0xcf, 0x73, 0x16, 0x1f, 0xca, 0xda, 0xe4, 0x87, 0xe2, 0x34, 0x97, 0xde, 0xe7, 0xd2, - 0xd8, 0x51, 0x11, 0xee, 0xfc, 0x39, 0x0d, 0x0b, 0x13, 0xe8, 0xe3, 0xc3, 0x96, 0x0a, 0x87, 0x5d, - 0x83, 0x76, 0xaa, 0x85, 0xc2, 0xd3, 0xb0, 0x28, 0xb0, 0xed, 0x15, 0x93, 0x51, 0xa6, 0x2d, 0x8b, - 0xdb, 0x43, 0xed, 0x23, 0x6a, 0x27, 0x5b, 0x56, 0x53, 0x45, 0xae, 0x4b, 0x4f, 0xdb, 0x59, 0x0a, - 0xec, 0xdb, 0x00, 0x11, 0x3f, 0x67, 0x4a, 0x6b, 0xf6, 0xa6, 0x9f, 0xa7, 0x29, 0xe2, 0xe7, 0x54, - 0xeb, 0xbd, 0x3e, 0xf9, 0x1a, 0xe6, 0xa3, 0x20, 0x96, 0x8a, 0x25, 0xfc, 0x44, 0xb0, 0x21, 0x4f, - 0x43, 0xa3, 0x5d, 0xb6, 0xe8, 0x1c, 0x1a, 0x0e, 0xf9, 0x89, 0xf8, 0x01, 0x61, 0xe4, 0xf2, 0xd7, - 0x57, 0xb8, 0xb3, 0x19, 0xd7, 0x1a, 0x0a, 0xdc, 0x4f, 0xa1, 0x1e, 0x48, 0x16, 0xc4, 0x49, 0x6a, - 0xec, 0xb6, 0x15, 0x77, 0x77, 0x81, 0x7c, 0x6e, 0x91, 0xbd, 0x3e, 0x59, 0x85, 0x46, 0x20, 0x99, - 0x4c, 0x4d, 0x46, 0xa8, 0x22, 0x01, 0x02, 0xd9, 0x43, 0x68, 0xaf, 0x4f, 0x9e, 0xc0, 0xca, 0x99, - 0x0c, 0xd3, 0xd8, 0x70, 0x35, 0xb2, 0xed, 0xc9, 0x88, 0x73, 0xc3, 0xf4, 0x1f, 0x81, 0xf1, 0x4f, - 0x85, 0xc6, 0x11, 0x5d, 0xa6, 0xde, 0x98, 0xd1, 0x75, 0x84, 0xa3, 0xcc, 0x4e, 0xbe, 0x87, 0xdb, - 0x41, 0xfc, 0x1e, 0x3d, 0xa0, 0x7e, 0xa5, 0xc0, 0xb9, 0xe2, 0xa1, 0xf3, 0x4f, 0x09, 0x5a, 0xfb, - 0x72, 0x90, 0x86, 0xe2, 0xc5, 0x28, 0x71, 0xd7, 0xf6, 0x5b, 0xde, 0x2d, 0x5d, 0x92, 0xf1, 0xfa, - 0x5a, 0x1b, 0x0f, 0x26, 0x8f, 0xf5, 0x4b, 0x52, 0xd7, 0x3c, 0x5d, 0xc9, 0x15, 0x06, 0x7c, 0xff, - 0x02, 0x25, 0x9f, 0x41, 0x3d, 0x42, 0x0d, 0x33, 0xa3, 0x24, 0xaf, 0x03, 0x88, 0xc6, 0x6e, 0x6c, - 0x65, 0xc7, 0x69, 0xc4, 0xe4, 0x90, 0x39, 0xd0, 0x5d, 0x79, 0x93, 0x36, 0xe2, 0x34, 0xea, 0x0d, - 0xdd, 0x7e, 0xba, 0xf3, 0x20, 0x6b, 0x21, 0x99, 0xd7, 0x4b, 0x7d, 0xa8, 0x06, 0x33, 0x47, 0xbd, - 0xde, 0x81, 0x6d, 0x58, 0x55, 0x28, 0xef, 0x6f, 0xef, 0xed, 0xb6, 0xa7, 0x3a, 0x21, 0xac, 0x74, - 0x55, 0x60, 0x6c, 0x49, 0x1f, 0x6b, 0xa1, 0x7e, 0x92, 0xa9, 0x8a, 0xc5, 0x28, 0x1f, 0x10, 0x93, - 0x5e, 0xea, 0x16, 0x54, 0xf2, 0x01, 0x34, 0xf5, 0x9e, 0x79, 0x51, 0xf8, 0x61, 0x43, 0x73, 0x41, - 0xa7, 0x0f, 0xb7, 0x26, 0xec, 0xa6, 0x2f, 0xe6, 0x51, 0xd9, 0x4f, 0x5f, 0x6b, 0xaf, 0x84, 0xf5, - 0x37, 0x39, 0xb3, 0xff, 0x1f, 0x2d, 0x45, 0x71, 0xe7, 0xaf, 0x12, 0xcc, 0xbf, 0x33, 0xfd, 0x88, - 0x07, 0x95, 0x3c, 0x6f, 0x25, 0xcc, 0x5b, 0xbe, 0xb4, 0xf3, 0x2b, 0xfb, 0x79, 0xe8, 0x0e, 0xd4, - 0xa4, 0xe3, 0xb5, 0x7d, 0xf3, 0xae, 0x25, 0xf2, 0x30, 0x94, 0x3e, 0xf3, 0x65, 0x1a, 0x9b, 0xac, - 0xd4, 0xe6, 0xd0, 0xb0, 0x6d, 0xf1, 0xae, 0x85, 0x6d, 0x05, 0x17, 0xb9, 0x3a, 0x78, 0x9b, 0xb7, - 0xa5, 0xd6, 0x05, 0xf5, 0x28, 0x78, 0x2b, 0xec, 0xef, 0x31, 0x5b, 0x93, 0xa7, 0x82, 0x27, 0x8e, - 0xe6, 0x2a, 0xae, 0x1e, 0xf1, 0xf3, 0x1f, 0x05, 0x4f, 0x2c, 0x67, 0x67, 0xe9, 0xd7, 0x6c, 0xe4, - 0x67, 0xe7, 0x66, 0xf8, 0x97, 0xe4, 0xbf, 0x00, 0x00, 0x00, 0xff, 0xff, 0xcb, 0xfb, 0x8e, 0xf5, - 0xa2, 0x0c, 0x00, 0x00, + // 1423 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x57, 0xdd, 0x52, 0x1b, 0xc7, + 0x12, 0xb6, 0x40, 0x20, 0xa9, 0xf5, 0x83, 0x18, 0xe0, 0xb0, 0xc6, 0xf6, 0x39, 0x1c, 0xc5, 0x76, + 0xa8, 0x54, 0x8c, 0x5d, 0xc4, 0x45, 0xb9, 0x28, 0x57, 0x2a, 0x20, 0x13, 0xc7, 0xa1, 0x84, 0xa8, + 0xc1, 0x38, 0x4e, 0x72, 0x31, 0x19, 0xad, 0x46, 0xb0, 0xf6, 0xee, 0xce, 0xd6, 0xcc, 0x2c, 0x01, + 0xbf, 0x99, 0xaf, 0xf3, 0x12, 0x79, 0x81, 0x3c, 0x41, 0x5e, 0x20, 0x35, 0x3d, 0xbb, 0x62, 0xc1, + 0x8a, 0x4d, 0xf9, 0x4e, 0xfb, 0xf5, 0xf7, 0xf5, 0x76, 0xf7, 0xf4, 0x74, 0xaf, 0xa0, 0x19, 0x09, + 0xa3, 0x02, 0x5f, 0xaf, 0x27, 0x4a, 0x1a, 0x49, 0x16, 0xb4, 0x94, 0xf1, 0x31, 0x1b, 0xa4, 0x41, + 0x38, 0x64, 0x99, 0xa9, 0xf3, 0x67, 0x03, 0xea, 0x3d, 0xf7, 0x7b, 0x87, 0x6b, 0x41, 0x1e, 0xc1, + 0xa2, 0x23, 0x0c, 0xb9, 0x11, 0xcc, 0x04, 0x91, 0xd0, 0x86, 0x47, 0x89, 0x57, 0x5a, 0x2d, 0xad, + 0x4d, 0x53, 0x82, 0xb6, 0x67, 0xdc, 0x88, 0x97, 0xb9, 0x85, 0xdc, 0x84, 0xaa, 0x53, 0x04, 0x43, + 0x6f, 0x6a, 0xb5, 0xb4, 0x56, 0xa3, 0x15, 0x7c, 0x7e, 0x31, 0x24, 0x5b, 0x70, 0x33, 0x09, 0xb9, + 0x19, 0x49, 0x15, 0xb1, 0x53, 0xa1, 0x74, 0x20, 0x63, 0xe6, 0xcb, 0xa1, 0x88, 0x79, 0x24, 0xbc, + 0x69, 0xe4, 0x2e, 0xe7, 0x84, 0x57, 0xce, 0xde, 0xcd, 0xcc, 0xe4, 0x1e, 0xb4, 0x0c, 0x57, 0xc7, + 0xc2, 0xb0, 0x44, 0xc9, 0x61, 0xea, 0x1b, 0xaf, 0x8c, 0x82, 0xa6, 0x43, 0x0f, 0x1c, 0x48, 0x86, + 0xb0, 0x98, 0xd1, 0x5c, 0x10, 0xa7, 0x5c, 0x05, 0x3c, 0x36, 0xde, 0xcc, 0x6a, 0x69, 0xad, 0xb5, + 0xf1, 0x60, 0x7d, 0x42, 0xce, 0xeb, 0x85, 0x7c, 0xd7, 0x77, 0xac, 0xe5, 0x95, 0x13, 0x6d, 0x4d, + 0xef, 0xee, 0x3f, 0xa7, 0xc4, 0xf9, 0x2b, 0x1a, 0x48, 0x1f, 0xea, 0xd9, 0x5b, 0xb8, 0xf2, 0x4f, + 0xbc, 0x59, 0x74, 0x7e, 0xef, 0x93, 0xce, 0xb7, 0x95, 0x7f, 0xb2, 0x55, 0x39, 0xda, 0xdf, 0xdb, + 0xef, 0xff, 0xb4, 0x4f, 0xc1, 0xb9, 0xb0, 0x20, 0x59, 0x87, 0x85, 0x82, 0xc3, 0x71, 0xd4, 0x15, + 0x4c, 0x71, 0xfe, 0x82, 0x98, 0x07, 0xf0, 0x35, 0x64, 0x61, 0x31, 0x3f, 0x49, 0xc7, 0xf4, 0x2a, + 0xd2, 0xdb, 0xce, 0xd2, 0x4d, 0xd2, 0x9c, 0xbd, 0x07, 0xb5, 0x13, 0xa9, 0xb3, 0x60, 0x6b, 0x9f, + 0x15, 0x6c, 0xd5, 0x3a, 0xc0, 0x50, 0x29, 0x34, 0xd1, 0xd9, 0x46, 0x3c, 0x74, 0x0e, 0xe1, 0xb3, + 0x1c, 0xd6, 0xad, 0x93, 0x8d, 0x78, 0x88, 0x3e, 0x97, 0xa1, 0x82, 0x3e, 0xa5, 0xf6, 0xea, 0x98, + 0xc3, 0xac, 0x7d, 0xec, 0x6b, 0xd2, 0xc9, 0x5e, 0x26, 0x35, 0x13, 0x67, 0x46, 0x71, 0xaf, 0x81, + 0xe6, 0xba, 0x33, 0xef, 0x5a, 0x68, 0xcc, 0xf1, 0x95, 0xd4, 0xda, 0xba, 0x68, 0x5e, 0x70, 0xba, + 0x16, 0xeb, 0x6b, 0x72, 0x1f, 0xe6, 0x0a, 0x1c, 0x0c, 0xbb, 0xe5, 0xda, 0x67, 0xcc, 0xc2, 0x40, + 0x1e, 0xc0, 0x42, 0x81, 0x37, 0x4e, 0x71, 0xce, 0x15, 0x76, 0xcc, 0x2d, 0xc4, 0x2d, 0x53, 0xc3, + 0x86, 0x81, 0xf2, 0xda, 0x2e, 0x6e, 0x99, 0x9a, 0x67, 0x81, 0x22, 0xdf, 0x42, 0x5d, 0x0b, 0x93, + 0x26, 0xcc, 0x48, 0x19, 0x6a, 0x6f, 0x7e, 0x75, 0x7a, 0xad, 0xbe, 0x71, 0x67, 0x62, 0x89, 0x0e, + 0x84, 0x1a, 0xbd, 0x88, 0x47, 0x92, 0x02, 0x2a, 0x5e, 0x5a, 0x01, 0xd9, 0x82, 0xda, 0x5b, 0x6e, + 0x02, 0xa6, 0xd2, 0x58, 0x7b, 0xe4, 0x3a, 0xea, 0xaa, 0xe5, 0xd3, 0x34, 0xd6, 0xe4, 0x29, 0x80, + 0x63, 0xa2, 0x78, 0xe1, 0x3a, 0xe2, 0x1a, 0x5a, 0x73, 0x75, 0x1c, 0xc4, 0x6f, 0xb8, 0x53, 0x2f, + 0x5e, 0x4b, 0x8d, 0x02, 0x54, 0x7f, 0x03, 0x33, 0x46, 0x1a, 0x1e, 0x7a, 0x4b, 0xab, 0xa5, 0x4f, + 0x0b, 0x1d, 0x97, 0xbc, 0x82, 0x49, 0xa3, 0xc8, 0xfb, 0x0f, 0xba, 0xb8, 0x3f, 0xd1, 0xc5, 0xa1, + 0xc5, 0xf0, 0x4a, 0x66, 0x1d, 0x46, 0xe7, 0xf5, 0x55, 0x88, 0x74, 0xa1, 0xe1, 0x54, 0xbe, 0x8c, + 0x47, 0xc1, 0xb1, 0xb7, 0x8c, 0x0e, 0x57, 0x27, 0x3a, 0x44, 0x61, 0x17, 0x79, 0xb4, 0x3e, 0xb8, + 0x78, 0x20, 0x2b, 0x80, 0xad, 0x8f, 0x23, 0xca, 0xc3, 0x33, 0x1e, 0x3f, 0x93, 0x9f, 0x61, 0x51, + 0x9f, 0x6b, 0x23, 0x22, 0xa6, 0x84, 0x96, 0xa9, 0xf2, 0x05, 0x0b, 0xe2, 0x91, 0xf4, 0x6e, 0xe2, + 0x8b, 0xbe, 0x9c, 0x1c, 0x39, 0x0a, 0x68, 0xc6, 0xc7, 0x32, 0x10, 0xfd, 0x01, 0x46, 0xbe, 0x80, + 0x66, 0x1e, 0x7b, 0x14, 0xf1, 0x78, 0xe8, 0xad, 0xe0, 0xbb, 0x1b, 0x59, 0x68, 0x88, 0xd9, 0xb3, + 0x1a, 0xf0, 0x77, 0x22, 0x74, 0x67, 0x75, 0xeb, 0x5a, 0x67, 0x85, 0x02, 0x7b, 0x56, 0x9d, 0x47, + 0xd0, 0xb8, 0x34, 0xd4, 0xaa, 0x50, 0x3e, 0x3a, 0xdc, 0xa5, 0xed, 0x1b, 0xa4, 0x09, 0x35, 0xfb, + 0xeb, 0xd9, 0xee, 0xce, 0xd1, 0xf3, 0x76, 0x89, 0x54, 0xc0, 0x0e, 0xc2, 0xf6, 0x54, 0xe7, 0x29, + 0x94, 0xb1, 0xed, 0xeb, 0x90, 0x5f, 0xe3, 0xf6, 0x0d, 0x6b, 0xdd, 0xa6, 0xbd, 0x76, 0x89, 0xd4, + 0x60, 0x66, 0x9b, 0xf6, 0x36, 0x1f, 0xb7, 0xa7, 0x2c, 0xf6, 0xfa, 0xc9, 0x66, 0x7b, 0x9a, 0x00, + 0xcc, 0xbe, 0x7e, 0xb2, 0xc9, 0x36, 0x1f, 0xb7, 0xcb, 0x9d, 0xf7, 0x25, 0xa8, 0x17, 0xca, 0x6c, + 0x17, 0x45, 0xaa, 0x05, 0x3b, 0x96, 0x11, 0xc7, 0x75, 0x52, 0xa5, 0x95, 0x54, 0x8b, 0xe7, 0x32, + 0xe2, 0xf6, 0x5e, 0x59, 0x93, 0x1a, 0x08, 0x5c, 0x21, 0x55, 0x3a, 0x9b, 0x6a, 0x41, 0x07, 0x82, + 0xdc, 0x85, 0xd6, 0x48, 0xda, 0x3a, 0x8f, 0x95, 0xd3, 0x68, 0x6f, 0x20, 0x7a, 0x94, 0xc9, 0xef, + 0x42, 0xcb, 0xd5, 0x85, 0x6b, 0x86, 0xbd, 0x89, 0xbb, 0xa2, 0x4a, 0x1b, 0x88, 0x6e, 0xeb, 0x7d, + 0x8b, 0x91, 0xaf, 0x60, 0xde, 0xb1, 0xa2, 0xe0, 0x4c, 0x0c, 0x5d, 0xc1, 0x70, 0x4f, 0x54, 0xe9, + 0x1c, 0x1a, 0x7a, 0x16, 0xc7, 0x88, 0x3b, 0x12, 0xc8, 0x87, 0x07, 0x47, 0x36, 0x60, 0x09, 0x3b, + 0x98, 0x25, 0x27, 0xe7, 0x3a, 0xf0, 0x79, 0xc8, 0x22, 0x11, 0x49, 0x75, 0x8e, 0xe9, 0x94, 0xe9, + 0x02, 0x1a, 0x0f, 0x32, 0x5b, 0x0f, 0x4d, 0x76, 0x8f, 0xf1, 0x53, 0x1e, 0x84, 0x7c, 0x10, 0x0a, + 0x3b, 0xbc, 0x35, 0x66, 0x38, 0x43, 0x9b, 0x63, 0xb4, 0x9b, 0xa4, 0xba, 0xf3, 0x77, 0x09, 0xaa, + 0xf9, 0xa1, 0x11, 0x02, 0xe5, 0xa1, 0xd0, 0x3e, 0xba, 0xad, 0x51, 0xfc, 0x6d, 0x31, 0xec, 0x49, + 0xb7, 0x62, 0xf1, 0x37, 0xb9, 0x03, 0xa0, 0x0d, 0x57, 0x06, 0xf7, 0x34, 0x56, 0xa6, 0x4c, 0x6b, + 0x88, 0xd8, 0xf5, 0x4c, 0x6e, 0x41, 0x4d, 0x09, 0x1e, 0x3a, 0x6b, 0x19, 0xad, 0x55, 0x0b, 0xa0, + 0xf1, 0xff, 0x00, 0x2e, 0x78, 0x5b, 0x5a, 0x2c, 0x43, 0x79, 0x67, 0xca, 0x2b, 0xd1, 0x9a, 0x43, + 0x8f, 0xb4, 0x20, 0xbf, 0xc1, 0x72, 0xa2, 0xa4, 0x2f, 0xb4, 0x16, 0xfa, 0x4a, 0xc7, 0xcf, 0x62, + 0xef, 0xad, 0x4d, 0xee, 0x3d, 0xa7, 0xb9, 0xd4, 0xf2, 0x4b, 0x63, 0x47, 0x45, 0xb8, 0xf3, 0x7e, + 0x1a, 0x16, 0x26, 0xd0, 0xc7, 0xc9, 0x96, 0x0a, 0xc9, 0xae, 0x41, 0x3b, 0xd5, 0x42, 0x61, 0x36, + 0x2c, 0x0a, 0xec, 0xc4, 0xc6, 0x62, 0x94, 0x69, 0xcb, 0xe2, 0x36, 0xa9, 0x1e, 0xa2, 0x76, 0x59, + 0x66, 0xd7, 0xb4, 0xc8, 0x75, 0xe5, 0x69, 0x3b, 0x4b, 0x81, 0x7d, 0x1b, 0x20, 0xe2, 0x67, 0x4c, + 0x69, 0xcd, 0xde, 0x0e, 0xf2, 0x32, 0x45, 0xfc, 0x8c, 0x6a, 0xbd, 0x37, 0xb0, 0x4d, 0x13, 0x05, + 0xb1, 0x54, 0x2c, 0xe1, 0xc7, 0x82, 0x8d, 0x78, 0x1a, 0x1a, 0xed, 0xaa, 0x45, 0xe7, 0xd0, 0x70, + 0xc0, 0x8f, 0xc5, 0xf7, 0x08, 0x23, 0x97, 0xbf, 0xb9, 0xc2, 0x9d, 0xcd, 0xb8, 0xd6, 0x50, 0xe0, + 0xfe, 0x17, 0xea, 0x81, 0x64, 0x41, 0x9c, 0xa4, 0xc6, 0xbe, 0xb6, 0xe2, 0xce, 0x2e, 0x90, 0x2f, + 0x2c, 0xb2, 0x37, 0x20, 0xab, 0xd0, 0x08, 0x24, 0x93, 0xa9, 0xc9, 0x08, 0x55, 0x24, 0x40, 0x20, + 0xfb, 0x08, 0xed, 0x0d, 0xc8, 0x53, 0x58, 0x39, 0x95, 0x61, 0x1a, 0x1b, 0xae, 0xce, 0xed, 0xc4, + 0x33, 0xe2, 0xcc, 0x30, 0xfd, 0x7b, 0x60, 0xfc, 0x13, 0xa1, 0x71, 0xeb, 0x97, 0xa9, 0x37, 0x66, + 0x74, 0x1d, 0xe1, 0x30, 0xb3, 0x93, 0xef, 0xe0, 0x76, 0x10, 0x7f, 0x44, 0x0f, 0xa8, 0x5f, 0x29, + 0x70, 0xae, 0x78, 0xe8, 0xfc, 0x55, 0x82, 0x56, 0x4f, 0x0e, 0xd3, 0x50, 0xbc, 0x3c, 0x4f, 0xdc, + 0xb1, 0xfd, 0x9a, 0x0f, 0x60, 0x57, 0x64, 0x3c, 0xbe, 0xd6, 0xc6, 0xc3, 0xc9, 0x5f, 0x0a, 0x97, + 0xa4, 0x6e, 0x1e, 0xbb, 0x2b, 0x57, 0xf8, 0x66, 0x18, 0x5c, 0xa0, 0xe4, 0x7f, 0x50, 0x8f, 0x50, + 0xc3, 0xcc, 0x79, 0x92, 0xdf, 0x03, 0x88, 0xc6, 0x6e, 0xec, 0x14, 0x88, 0xd3, 0x88, 0xc9, 0x11, + 0x73, 0xa0, 0x3b, 0xf2, 0x26, 0x6d, 0xc4, 0x69, 0xd4, 0x1f, 0xb9, 0xf7, 0xe9, 0xce, 0xc3, 0x6c, + 0x28, 0x65, 0x5e, 0x2f, 0x8d, 0xb6, 0x1a, 0xcc, 0x1c, 0xf6, 0xfb, 0xfb, 0x76, 0x06, 0x56, 0xa1, + 0xdc, 0xdb, 0xde, 0xdb, 0x6d, 0x4f, 0x75, 0x42, 0x58, 0xe9, 0xaa, 0xc0, 0xd8, 0x2b, 0x7d, 0xa4, + 0x85, 0xfa, 0x51, 0xa6, 0x2a, 0x16, 0xe7, 0xf9, 0xce, 0x99, 0xd4, 0xa9, 0x5b, 0x50, 0xc9, 0x77, + 0xda, 0xd4, 0x47, 0x56, 0x50, 0xe1, 0x5b, 0x89, 0xe6, 0x82, 0xce, 0x00, 0x6e, 0x4d, 0x78, 0x9b, + 0xbe, 0x58, 0x71, 0x65, 0x3f, 0x7d, 0xa3, 0xbd, 0x12, 0xde, 0xbf, 0xc9, 0x95, 0xfd, 0xf7, 0x68, + 0x29, 0x8a, 0x3b, 0x7f, 0x94, 0x60, 0xfe, 0x83, 0x85, 0x4a, 0x3c, 0xa8, 0xe4, 0x75, 0x2b, 0x61, + 0xdd, 0xf2, 0x47, 0xbb, 0x12, 0xb3, 0x2f, 0x4e, 0x97, 0x50, 0x93, 0x8e, 0x9f, 0x6d, 0xcf, 0xbb, + 0x91, 0xc8, 0xc3, 0x50, 0xfa, 0xcc, 0x97, 0x69, 0x6c, 0xb2, 0xab, 0x36, 0x87, 0x86, 0x6d, 0x8b, + 0x77, 0x2d, 0x6c, 0x6f, 0x70, 0x91, 0xab, 0x83, 0x77, 0xf9, 0x58, 0x6a, 0x5d, 0x50, 0x0f, 0x83, + 0x77, 0xc2, 0x7e, 0xe2, 0xd9, 0x3b, 0x79, 0x22, 0x78, 0xe2, 0x68, 0xee, 0xc6, 0xd5, 0x23, 0x7e, + 0xf6, 0x83, 0xe0, 0x89, 0xe5, 0xec, 0x2c, 0xfd, 0x92, 0x7d, 0x45, 0x64, 0x79, 0x33, 0xfc, 0x97, + 0xf3, 0x4f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xe9, 0x63, 0x09, 0x14, 0xf5, 0x0c, 0x00, 0x00, } diff --git a/ui/metrics/metrics_proto/metrics.proto b/ui/metrics/metrics_proto/metrics.proto index 91d8dd9b7..b284bf982 100644 --- a/ui/metrics/metrics_proto/metrics.proto +++ b/ui/metrics/metrics_proto/metrics.proto @@ -116,6 +116,13 @@ message BuildConfig { optional bool use_rbe = 2; optional bool force_use_goma = 3; + + // Whether the Bazel is acting as the Ninja executor for this build. + optional bool bazel_as_ninja = 4; + + // Whether build is occurring in a mixed build mode, where Bazel maintains the + // definition and build of some modules in cooperation with Soong. + optional bool bazel_mixed_build = 5; } message SystemResourceInfo { |