diff options
60 files changed, 1632 insertions, 599 deletions
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index 6405e9fe9..a5fcee414 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -477,6 +477,7 @@ var ( "code_coverage.policy", "code_coverage.policy.other", "codec2_soft_exports", + "compatibility_matrix_schema", "flatbuffer_headers", "framework-connectivity-protos", "gemmlowp_headers", @@ -766,6 +767,27 @@ var ( "libauto_value_plugin", "auto_value_plugin_resources", "auto_value_extension", + + // Used by xsd_config + "xsdc", + + // cc_test that can be run by b test + "binderRpcWireProtocolTest", + "binderUnitTest", + "cpu_features-bit_utils_test", + "liblp_test", + "android.hardware.audio.common.test.utility_tests", + "HalAudioStreamWorkerTest", + "libjavacore-unit-tests", + "NeuralNetworksTest_utils", + "NeuralNetworksTest_logtag", + "NeuralNetworksTest_operations", + "nanoapp_chqts_shared_tests", + "fakeservicemanager_test", + "tristate_test", + "binderUtilsHostTest", + "run_dex2oat_test", + "bluetooth-address-unit-tests", } Bp2buildModuleTypeAlwaysConvertList = []string{ @@ -778,6 +800,7 @@ var ( "java_import_host", "java_sdk_library", "sysprop_library", + "xsd_config", } // Add the names of modules that bp2build should never convert, if it is @@ -847,9 +870,6 @@ var ( "host_bionic_linker_asm", // depends on extract_linker, a go binary. "host_bionic_linker_script", // depends on extract_linker, a go binary. - // in cmd attribute of genrule rule //system/timezone/output_data:robolectric_tzdata: label '//system/timezone/output_data:iana/tzdata' in $(location) expression is not a declared prerequisite of this rule - "robolectric_tzdata", - // rust support "libtombstoned_client_rust_bridge_code", "libtombstoned_client_wrapper", // rust conversions are not supported @@ -897,8 +917,6 @@ var ( "static_crasher", // depends on unconverted modules: libdebuggerd_handler "test_fips", // depends on unconverted modules: adb "timezone-host", // depends on unconverted modules: art.module.api.annotations - "truth-host-prebuilt", // depends on unconverted modules: truth-prebuilt - "truth-prebuilt", // depends on unconverted modules: asm-7.0, guava // '//bionic/libc:libc_bp2build_cc_library_static' is duplicated in the 'deps' attribute of rule "toybox-static", @@ -945,12 +963,10 @@ var ( "svcenc", "svcdec", // Failing host cc_tests - "memunreachable_unit_test", "libprocinfo_test", "ziparchive-tests", "gtest_isolated_tests", "libunwindstack_unit_test", - "task_profiles_test", "power_tests", // failing test on server, but not on host // reflect: call of reflect.Value.NumField on interface Value @@ -1030,7 +1046,6 @@ var ( "libBionicLoaderTests", // depends on unconverted modules: libmeminfo "libapexutil_tests", // depends on unconverted modules: apex-info-list-tinyxml, libapexutil "libcutils_sockets_test", - "libexpectedutils_test", "libhwbinder_latency", "liblog-host-test", // failing tests "libminijail_test", @@ -1067,7 +1082,6 @@ var ( "scudo_unit_tests", "stats-log-api-gen-test", // depends on unconverted modules: libstats_proto_host "syscall_filter_unittest_gtest", - "sysprop_test", // depends on unconverted modules: libcom.android.sysprop.tests "thread_exit_cb_helper", "tls_properties_helper", "ulp", @@ -1467,6 +1481,13 @@ var ( // python_test_host with test data "sbom_writers_test", + + // TODO(B/283193845): tradefed and its java_test_host dependents + "tradefed", + "permissive_mte_test", + "ICU4CTestRunner", + + "HelloWorldHostTest", // TODO(b/280452825): Convert HelloWorldHostTest to b test } MixedBuildsDisabledList = []string{ @@ -1585,12 +1606,13 @@ var ( } // These should be the libs that are included by the apexes in the StagingMixedBuildsEnabledList - StagingDclaMixedBuildsEnabledList = []string{} + StagingDclaMixedBuildsEnabledList = []string{ + "libstagefright_flacdec", + "libutils", + } // TODO(b/269342245): Enable the rest of the DCLA libs // "libssl", - // "libstagefright_flacdec", - // "libutils", // The list of module types which are expected to spend lots of build time. // With `--ninja_weight_source=soong`, ninja builds these module types and deps first. diff --git a/android/bazel_handler.go b/android/bazel_handler.go index 47dd16180..d71eca2fa 100644 --- a/android/bazel_handler.go +++ b/android/bazel_handler.go @@ -674,6 +674,18 @@ func (context *mixedBuildBazelContext) createBazelCommand(config Config, runName // We don't need to set --host_platforms because it's set in bazelrc files // that the bazel shell script wrapper passes + // Optimize Ninja rebuilds by ensuring Bazel write into product-agnostic + // output paths for the configured targets that shouldn't be affected by + // TARGET_PRODUCT. Otherwise product agnostic modules will be rebuilt by + // Ninja when the product changes, unconditionally. + // + // For example, Mainline APEXes should be identical regardless of the + // product (modulo arch/cpu). + // + // This flag forcibly disables the platform prefix in the intermediate + // outputs during a mixed build. + "--noexperimental_platform_in_output_dir", + // Suppress noise "--ui_event_filters=-INFO", "--noshow_progress", @@ -719,9 +731,9 @@ func (context *mixedBuildBazelContext) mainBzlFileContents() []byte { ##################################################### def _config_node_transition_impl(settings, attr): if attr.os == "android" and attr.arch == "target": - target = "{PRODUCT}-{VARIANT}" + target = "current_product-{VARIANT}" else: - target = "{PRODUCT}-{VARIANT}_%s_%s" % (attr.os, attr.arch) + target = "current_product-{VARIANT}_%s_%s" % (attr.os, attr.arch) apex_name = "" if attr.within_apex: # //build/bazel/rules/apex:apex_name has to be set to a non_empty value, @@ -732,7 +744,7 @@ def _config_node_transition_impl(settings, attr): # value here. apex_name = "dcla_apex" outputs = { - "//command_line_option:platforms": "@soong_injection//product_config_platforms/products/{PRODUCT}-{VARIANT}:%s" % target, + "//command_line_option:platforms": "@soong_injection//product_config_platforms:%s" % target, "@//build/bazel/rules/apex:within_apex": attr.within_apex, "@//build/bazel/rules/apex:min_sdk_version": attr.apex_sdk_version, "@//build/bazel/rules/apex:apex_name": apex_name, @@ -958,9 +970,9 @@ def get_arch(target): platform_name = platforms[0].name if platform_name == "host": return "HOST" - if not platform_name.startswith("{TARGET_PRODUCT}-{TARGET_BUILD_VARIANT}"): - fail("expected platform name of the form '{TARGET_PRODUCT}-{TARGET_BUILD_VARIANT}_android_<arch>' or '{TARGET_PRODUCT}-{TARGET_BUILD_VARIANT}_linux_<arch>', but was " + str(platforms)) - platform_name = platform_name.removeprefix("{TARGET_PRODUCT}-{TARGET_BUILD_VARIANT}").removeprefix("_") + if not platform_name.startswith("current_product-{TARGET_BUILD_VARIANT}"): + fail("expected platform name of the form 'current_product-{TARGET_BUILD_VARIANT}_android_<arch>' or 'current_product-{TARGET_BUILD_VARIANT}_linux_<arch>', but was " + str(platforms)) + platform_name = platform_name.removeprefix("current_product-{TARGET_BUILD_VARIANT}").removeprefix("_") config_key = "" if not platform_name: config_key = "target|android" @@ -969,7 +981,7 @@ def get_arch(target): elif platform_name.startswith("linux_"): config_key = platform_name.removeprefix("linux_") + "|linux" else: - fail("expected platform name of the form '{TARGET_PRODUCT}-{TARGET_BUILD_VARIANT}_android_<arch>' or '{TARGET_PRODUCT}-{TARGET_BUILD_VARIANT}_linux_<arch>', but was " + str(platforms)) + fail("expected platform name of the form 'current_product-{TARGET_BUILD_VARIANT}_android_<arch>' or 'current_product-{TARGET_BUILD_VARIANT}_linux_<arch>', but was " + str(platforms)) within_apex = buildoptions.get("//build/bazel/rules/apex:within_apex") apex_sdk_version = buildoptions.get("//build/bazel/rules/apex:min_sdk_version") diff --git a/android/bazel_paths.go b/android/bazel_paths.go index ddbdbd49b..872e908e8 100644 --- a/android/bazel_paths.go +++ b/android/bazel_paths.go @@ -242,6 +242,11 @@ func transformSubpackagePath(ctx BazelConversionPathContext, path bazel.Label) b // Don't transform OriginalModuleName newPath.OriginalModuleName = path.OriginalModuleName + // if it wasn't a module, store the original path. We may need the original path to replace + // references if it is actually in another package + if path.OriginalModuleName == "" { + newPath.OriginalModuleName = path.Label + } if strings.HasPrefix(path.Label, "//") { // Assume absolute labels are already correct (e.g. //path/to/some/package:foo.h) diff --git a/android/config.go b/android/config.go index bed57e3b5..d4703ff03 100644 --- a/android/config.go +++ b/android/config.go @@ -517,6 +517,8 @@ func NewConfig(cmdArgs CmdArgs, availableEnv map[string]string) (Config, error) config: config, } + config.productVariables.Build_from_text_stub = boolPtr(config.buildFromTextStub) + // Soundness check of the build and source directories. This won't catch strange // configurations with symlinks, but at least checks the obvious case. absBuildDir, err := filepath.Abs(cmdArgs.SoongOutDir) @@ -1710,10 +1712,6 @@ func (c *config) ProductPrivateSepolicyDirs() []string { return c.productVariables.ProductPrivateSepolicyDirs } -func (c *config) MissingUsesLibraries() []string { - return c.productVariables.MissingUsesLibraries -} - func (c *config) TargetMultitreeUpdateMeta() bool { return c.productVariables.MultitreeUpdateMeta } @@ -1929,6 +1927,10 @@ func (c *deviceConfig) BuildBrokenInputDir(name string) bool { return InList(name, c.config.productVariables.BuildBrokenInputDirModules) } +func (c *config) BuildWarningBadOptionalUsesLibsAllowlist() []string { + return c.productVariables.BuildWarningBadOptionalUsesLibsAllowlist +} + func (c *deviceConfig) GenruleSandboxing() bool { return Bool(c.config.productVariables.GenruleSandboxing) } @@ -1941,10 +1943,6 @@ func (c *config) SelinuxIgnoreNeverallows() bool { return c.productVariables.SelinuxIgnoreNeverallows } -func (c *deviceConfig) SepolicySplit() bool { - return c.config.productVariables.SepolicySplit -} - func (c *deviceConfig) SepolicyFreezeTestExtraDirs() []string { return c.config.productVariables.SepolicyFreezeTestExtraDirs } @@ -2021,6 +2019,7 @@ func (c *config) BuildFromTextStub() bool { func (c *config) SetBuildFromTextStub(b bool) { c.buildFromTextStub = b + c.productVariables.Build_from_text_stub = boolPtr(b) } func (c *config) AddForceEnabledModules(forceEnabled []string) { diff --git a/android/module.go b/android/module.go index 98084f359..ba327108f 100644 --- a/android/module.go +++ b/android/module.go @@ -4014,3 +4014,53 @@ func (s *soongConfigTraceSingleton) GenerateBuildActions(ctx SingletonContext) { WriteFileRule(ctx, outFile, string(j)) ctx.Phony("soong_config_trace", outFile) } + +// Interface implemented by xsd_config which has 1:many mappings in bp2build workspace +// This interface exists because we want to +// 1. Determine the name of the additional targets generated by the primary soong module +// 2. Enable distinguishing an xsd_config module from other Soong modules using type assertion +type XsdConfigBp2buildTargets interface { + CppBp2buildTargetName() string + JavaBp2buildTargetName() string +} + +// PartitionXsdSrcs partitions srcs into xsd_config modules and others +// Since xsd_config are soong modules, we cannot use file extension for partitioning +func PartitionXsdSrcs(ctx BazelConversionPathContext, srcs []string) ([]string, []string) { + //isXsd returns true if src is a soong module of type xsd_config + isXsd := func(src string) bool { + mod, exists := ctx.ModuleFromName(src) + if !exists { + return false + } + _, _isXsd := mod.(XsdConfigBp2buildTargets) + return _isXsd + } + nonXsd := []string{} + xsd := []string{} + + for _, src := range srcs { + if isXsd(src) { + xsd = append(xsd, src) + } else { + nonXsd = append(nonXsd, src) + } + } + + return nonXsd, xsd +} + +// Replaces //a/b/my_xsd_config with //a/b/my_xsd_config-{cpp|java} +// The new target name is provided by the `targetName` callback function +func XsdConfigBp2buildTarget(ctx BazelConversionPathContext, mod blueprint.Module, targetName func(xsd XsdConfigBp2buildTargets) string) string { + xsd, isXsd := mod.(XsdConfigBp2buildTargets) + if !isXsd { + ctx.ModuleErrorf("xsdConfigJavaTarget called on %v, which is not an xsd_config", mod) + } + ret := BazelModuleLabel(ctx, mod) + // Remove the base module name + ret = strings.TrimSuffix(ret, mod.Name()) + // Append the language specific target name + ret += targetName(xsd) + return ret +} diff --git a/android/neverallow.go b/android/neverallow.go index 5b5e61328..f2e8c8534 100644 --- a/android/neverallow.go +++ b/android/neverallow.go @@ -59,6 +59,7 @@ func init() { AddNeverAllowRules(createProhibitFrameworkAccessRules()...) AddNeverAllowRules(createBp2BuildRule()) AddNeverAllowRules(createCcStubsRule()) + AddNeverAllowRules(createJavaExcludeStaticLibsRule()) } // Add a NeverAllow rule to the set of rules to apply. @@ -253,6 +254,14 @@ func createProhibitFrameworkAccessRules() []Rule { } } +func createJavaExcludeStaticLibsRule() Rule { + return NeverAllow(). + NotIn("build/soong"). + ModuleType("java_library"). + WithMatcher("exclude_static_libs", isSetMatcherInstance). + Because("exclude_static_libs property is only allowed for java modules defined in build/soong") +} + func neverallowMutator(ctx BottomUpMutatorContext) { m, ok := ctx.Module().(Module) if !ok { diff --git a/android/neverallow_test.go b/android/neverallow_test.go index ddd982d15..1639bbf40 100644 --- a/android/neverallow_test.go +++ b/android/neverallow_test.go @@ -344,6 +344,23 @@ var neverallowTests = []struct { `module "outside_allowed_list": violates neverallow`, }, }, + // Test for the rule restricting use of exclude_static_libs + { + name: `"exclude_static_libs" outside allowed directory`, + fs: map[string][]byte{ + "a/b/Android.bp": []byte(` + java_library { + name: "baz", + exclude_static_libs: [ + "bar", + ], + } + `), + }, + expectedErrors: []string{ + `exclude_static_libs property is only allowed for java modules defined in build/soong`, + }, + }, } var prepareForNeverAllowTest = GroupFixturePreparers( @@ -430,9 +447,10 @@ func (p *mockCcLibraryModule) GenerateAndroidBuildActions(ModuleContext) { } type mockJavaLibraryProperties struct { - Libs []string - Sdk_version *string - Uncompress_dex *bool + Libs []string + Sdk_version *string + Uncompress_dex *bool + Exclude_static_libs []string } type mockJavaLibraryModule struct { diff --git a/android/sdk_version.go b/android/sdk_version.go index 08762eff2..80aeb2e69 100644 --- a/android/sdk_version.go +++ b/android/sdk_version.go @@ -84,12 +84,6 @@ func (k SdkKind) String() string { } } -// JavaLibraryName returns the soong module containing the Java APIs of that API surface. -func (k SdkKind) JavaLibraryName(c Config) string { - name := k.DefaultJavaLibraryName() - return JavaApiLibraryName(c, name) -} - // JavaApiLibraryName returns the name of .txt equivalent of a java_library, but does // not check if either module exists. // TODO: Return .txt (single-tree or multi-tree equivalents) based on config @@ -335,11 +329,10 @@ func init() { // Export the name of the soong modules representing the various Java API surfaces. func javaSdkMakeVars(ctx MakeVarsContext) { - ctx.Strict("ANDROID_PUBLIC_STUBS", SdkPublic.JavaLibraryName(ctx.Config())) - ctx.Strict("ANDROID_SYSTEM_STUBS", SdkSystem.JavaLibraryName(ctx.Config())) - ctx.Strict("ANDROID_TEST_STUBS", SdkTest.JavaLibraryName(ctx.Config())) - ctx.Strict("ANDROID_MODULE_LIB_STUBS", SdkModule.JavaLibraryName(ctx.Config())) - ctx.Strict("ANDROID_SYSTEM_SERVER_STUBS", SdkSystemServer.JavaLibraryName(ctx.Config())) - // TODO (jihoonkang): Create a .txt equivalent for core.current.stubs - ctx.Strict("ANDROID_CORE_STUBS", SdkCore.JavaLibraryName(ctx.Config())) + ctx.Strict("ANDROID_PUBLIC_STUBS", SdkPublic.DefaultJavaLibraryName()) + ctx.Strict("ANDROID_SYSTEM_STUBS", SdkSystem.DefaultJavaLibraryName()) + ctx.Strict("ANDROID_TEST_STUBS", SdkTest.DefaultJavaLibraryName()) + ctx.Strict("ANDROID_MODULE_LIB_STUBS", SdkModule.DefaultJavaLibraryName()) + ctx.Strict("ANDROID_SYSTEM_SERVER_STUBS", SdkSystemServer.DefaultJavaLibraryName()) + ctx.Strict("ANDROID_CORE_STUBS", SdkCore.DefaultJavaLibraryName()) } diff --git a/android/variable.go b/android/variable.go index 77888e586..636295359 100644 --- a/android/variable.go +++ b/android/variable.go @@ -109,6 +109,11 @@ type variableProperties struct { Cflags []string } + Build_from_text_stub struct { + Static_libs []string + Exclude_static_libs []string + } + // debuggable is true for eng and userdebug builds, and can be used to turn on additional // debugging features that don't significantly impact runtime behavior. userdebug builds // are used for dogfooding and performance testing, and should be as similar to user builds @@ -286,6 +291,7 @@ type productVariables struct { Uml *bool `json:",omitempty"` Arc *bool `json:",omitempty"` MinimizeJavaDebugInfo *bool `json:",omitempty"` + Build_from_text_stub *bool `json:",omitempty"` Check_elf_files *bool `json:",omitempty"` @@ -420,8 +426,6 @@ type productVariables struct { TargetFSConfigGen []string `json:",omitempty"` - MissingUsesLibraries []string `json:",omitempty"` - EnforceProductPartitionInterface *bool `json:",omitempty"` EnforceInterPartitionJavaSdkLibrary *bool `json:",omitempty"` @@ -451,14 +455,14 @@ type productVariables struct { BuildBrokenVendorPropertyNamespace bool `json:",omitempty"` BuildBrokenInputDirModules []string `json:",omitempty"` + BuildWarningBadOptionalUsesLibsAllowlist []string `json:",omitempty"` + BuildDebugfsRestrictionsEnabled bool `json:",omitempty"` RequiresInsecureExecmemForSwiftshader bool `json:",omitempty"` SelinuxIgnoreNeverallows bool `json:",omitempty"` - SepolicySplit bool `json:",omitempty"` - SepolicyFreezeTestExtraDirs []string `json:",omitempty"` SepolicyFreezeTestExtraPrebuiltDirs []string `json:",omitempty"` @@ -528,6 +532,7 @@ func (v *productVariables) SetDefaultConfig() { Malloc_pattern_fill_contents: boolPtr(false), Safestack: boolPtr(false), TrimmedApex: boolPtr(false), + Build_from_text_stub: boolPtr(false), BootJars: ConfiguredJarList{apexes: []string{}, jars: []string{}}, ApexBootJars: ConfiguredJarList{apexes: []string{}, jars: []string{}}, diff --git a/apex/apex.go b/apex/apex.go index f49492e84..32d7250ff 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -220,6 +220,13 @@ type apexBundleProperties struct { // imageApex or flattenedApex depending on Config.FlattenApex(). When payload_type is zip, // this becomes zipApex. ApexType apexPackaging `blueprint:"mutated"` + + // Name that dependencies can specify in their apex_available properties to refer to this module. + // If not specified, this defaults to Soong module name. This must be the name of a Soong module. + Apex_available_name *string + + // Variant version of the mainline module. Must be an integer between 0-9 + Variant_version *string } type ApexNativeDependencies struct { @@ -3134,6 +3141,13 @@ func (a *apexBundle) checkApexAvailability(ctx android.ModuleContext) { } apexName := ctx.ModuleName() + for _, props := range ctx.Module().GetProperties() { + if apexProps, ok := props.(*apexBundleProperties); ok { + if apexProps.Apex_available_name != nil { + apexName = *apexProps.Apex_available_name + } + } + } fromName := ctx.OtherModuleName(from) toName := ctx.OtherModuleName(to) @@ -3516,6 +3530,8 @@ type bazelApexBundleAttributes struct { Logging_parent *string Tests bazel.LabelListAttribute Base_apex_name *string + Apex_available_name *string + Variant_version *string } type convertedNativeSharedLibs struct { @@ -3666,6 +3682,8 @@ func convertWithBp2build(a *apexBundle, ctx android.TopDownMutatorContext) (baze Package_name: packageName, Logging_parent: loggingParent, Tests: testsAttrs, + Apex_available_name: a.properties.Apex_available_name, + Variant_version: a.properties.Variant_version, } props := bazel.BazelTargetModuleProperties{ diff --git a/apex/apex_test.go b/apex/apex_test.go index 38e24e844..c781be4ef 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -6717,6 +6717,266 @@ func TestApexAvailable_InvalidApexName(t *testing.T) { }`) } +func TestApexAvailable_ApexAvailableNameWithVersionCodeError(t *testing.T) { + t.Run("negative variant_version produces error", func(t *testing.T) { + testApexError(t, "expected an integer between 0-9; got -1", ` + apex { + name: "myapex", + key: "myapex.key", + apex_available_name: "com.android.foo", + variant_version: "-1", + updatable: false, + } + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + `) + }) + + t.Run("variant_version greater than 9 produces error", func(t *testing.T) { + testApexError(t, "expected an integer between 0-9; got 10", ` + apex { + name: "myapex", + key: "myapex.key", + apex_available_name: "com.android.foo", + variant_version: "10", + updatable: false, + } + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + `) + }) +} + +func TestApexAvailable_ApexAvailableNameWithVersionCode(t *testing.T) { + context := android.GroupFixturePreparers( + android.PrepareForIntegrationTestWithAndroid, + PrepareForTestWithApexBuildComponents, + android.FixtureMergeMockFs(android.MockFS{ + "system/sepolicy/apex/foo-file_contexts": nil, + "system/sepolicy/apex/bar-file_contexts": nil, + }), + ) + result := context.RunTestWithBp(t, ` + apex { + name: "foo", + key: "myapex.key", + apex_available_name: "com.android.foo", + variant_version: "0", + updatable: false, + } + apex { + name: "bar", + key: "myapex.key", + apex_available_name: "com.android.foo", + variant_version: "3", + updatable: false, + } + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + `) + + fooManifestRule := result.ModuleForTests("foo", "android_common_foo_image").Rule("apexManifestRule") + fooExpectedDefaultVersion := android.DefaultUpdatableModuleVersion + fooActualDefaultVersion := fooManifestRule.Args["default_version"] + if fooActualDefaultVersion != fooExpectedDefaultVersion { + t.Errorf("expected to find defaultVersion %q; got %q", fooExpectedDefaultVersion, fooActualDefaultVersion) + } + + barManifestRule := result.ModuleForTests("bar", "android_common_bar_image").Rule("apexManifestRule") + defaultVersionInt, _ := strconv.Atoi(android.DefaultUpdatableModuleVersion) + barExpectedDefaultVersion := fmt.Sprint(defaultVersionInt + 3) + barActualDefaultVersion := barManifestRule.Args["default_version"] + if barActualDefaultVersion != barExpectedDefaultVersion { + t.Errorf("expected to find defaultVersion %q; got %q", barExpectedDefaultVersion, barActualDefaultVersion) + } +} + +func TestApexAvailable_ApexAvailableName(t *testing.T) { + t.Run("using name of apex that sets apex_available_name is not allowed", func(t *testing.T) { + testApexError(t, "Consider adding \"myapex\" to 'apex_available' property of \"AppFoo\"", ` + apex { + name: "myapex_sminus", + key: "myapex.key", + apps: ["AppFoo"], + apex_available_name: "myapex", + updatable: false, + } + apex { + name: "myapex", + key: "myapex.key", + apps: ["AppFoo"], + updatable: false, + } + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + android_app { + name: "AppFoo", + srcs: ["foo/bar/MyClass.java"], + sdk_version: "none", + system_modules: "none", + apex_available: [ "myapex_sminus" ], + }`, + android.FixtureMergeMockFs(android.MockFS{ + "system/sepolicy/apex/myapex_sminus-file_contexts": nil, + }), + ) + }) + + t.Run("apex_available_name allows module to be used in two different apexes", func(t *testing.T) { + testApex(t, ` + apex { + name: "myapex_sminus", + key: "myapex.key", + apps: ["AppFoo"], + apex_available_name: "myapex", + updatable: false, + } + apex { + name: "myapex", + key: "myapex.key", + apps: ["AppFoo"], + updatable: false, + } + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + android_app { + name: "AppFoo", + srcs: ["foo/bar/MyClass.java"], + sdk_version: "none", + system_modules: "none", + apex_available: [ "myapex" ], + }`, + android.FixtureMergeMockFs(android.MockFS{ + "system/sepolicy/apex/myapex_sminus-file_contexts": nil, + }), + ) + }) + + t.Run("override_apexes work with apex_available_name", func(t *testing.T) { + testApex(t, ` + override_apex { + name: "myoverrideapex_sminus", + base: "myapex_sminus", + key: "myapex.key", + apps: ["AppFooOverride"], + } + override_apex { + name: "myoverrideapex", + base: "myapex", + key: "myapex.key", + apps: ["AppFooOverride"], + } + apex { + name: "myapex_sminus", + key: "myapex.key", + apps: ["AppFoo"], + apex_available_name: "myapex", + updatable: false, + } + apex { + name: "myapex", + key: "myapex.key", + apps: ["AppFoo"], + updatable: false, + } + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + android_app { + name: "AppFooOverride", + srcs: ["foo/bar/MyClass.java"], + sdk_version: "none", + system_modules: "none", + apex_available: [ "myapex" ], + } + android_app { + name: "AppFoo", + srcs: ["foo/bar/MyClass.java"], + sdk_version: "none", + system_modules: "none", + apex_available: [ "myapex" ], + }`, + android.FixtureMergeMockFs(android.MockFS{ + "system/sepolicy/apex/myapex_sminus-file_contexts": nil, + }), + ) + }) +} + +func TestApexAvailable_ApexAvailableNameWithOverrides(t *testing.T) { + context := android.GroupFixturePreparers( + android.PrepareForIntegrationTestWithAndroid, + PrepareForTestWithApexBuildComponents, + java.PrepareForTestWithDexpreopt, + android.FixtureMergeMockFs(android.MockFS{ + "system/sepolicy/apex/myapex-file_contexts": nil, + "system/sepolicy/apex/myapex_sminus-file_contexts": nil, + }), + android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { + variables.BuildId = proptools.StringPtr("buildid") + }), + ) + context.RunTestWithBp(t, ` + override_apex { + name: "myoverrideapex_sminus", + base: "myapex_sminus", + } + override_apex { + name: "myoverrideapex", + base: "myapex", + } + apex { + name: "myapex", + key: "myapex.key", + apps: ["AppFoo"], + updatable: false, + } + apex { + name: "myapex_sminus", + apex_available_name: "myapex", + key: "myapex.key", + apps: ["AppFoo_sminus"], + updatable: false, + } + apex_key { + name: "myapex.key", + public_key: "testkey.avbpubkey", + private_key: "testkey.pem", + } + android_app { + name: "AppFoo", + srcs: ["foo/bar/MyClass.java"], + sdk_version: "none", + system_modules: "none", + apex_available: [ "myapex" ], + } + android_app { + name: "AppFoo_sminus", + srcs: ["foo/bar/MyClass.java"], + sdk_version: "none", + min_sdk_version: "29", + system_modules: "none", + apex_available: [ "myapex" ], + }`) +} + func TestApexAvailable_CheckForPlatform(t *testing.T) { ctx := testApex(t, ` apex { diff --git a/apex/builder.go b/apex/builder.go index 7c6522d1d..c691a3341 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -275,6 +275,22 @@ func (a *apexBundle) buildManifest(ctx android.ModuleContext, provideNativeLibs, manifestJsonFullOut := android.PathForModuleOut(ctx, "apex_manifest_full.json") defaultVersion := android.DefaultUpdatableModuleVersion + if a.properties.Variant_version != nil { + defaultVersionInt, err := strconv.Atoi(defaultVersion) + if err != nil { + ctx.ModuleErrorf("expected DefaultUpdatableModuleVersion to be an int, but got %s", defaultVersion) + } + if defaultVersionInt%10 != 0 { + ctx.ModuleErrorf("expected DefaultUpdatableModuleVersion to end in a zero, but got %s", defaultVersion) + } + variantVersion := []rune(*a.properties.Variant_version) + if len(variantVersion) != 1 || variantVersion[0] < '0' || variantVersion[0] > '9' { + ctx.PropertyErrorf("variant_version", "expected an integer between 0-9; got %s", *a.properties.Variant_version) + } + defaultVersionRunes := []rune(defaultVersion) + defaultVersionRunes[len(defaultVersion)-1] = []rune(variantVersion)[0] + defaultVersion = string(defaultVersionRunes) + } if override := ctx.Config().Getenv("OVERRIDE_APEX_MANIFEST_DEFAULT_VERSION"); override != "" { defaultVersion = override } diff --git a/bazel/bazel_proxy.go b/bazel/bazel_proxy.go index 2940b9995..229818da0 100644 --- a/bazel/bazel_proxy.go +++ b/bazel/bazel_proxy.go @@ -26,10 +26,11 @@ import ( "time" ) -// Logs fatal events of ProxyServer. +// Logs events of ProxyServer. type ServerLogger interface { Fatal(v ...interface{}) Fatalf(format string, v ...interface{}) + Println(v ...interface{}) } // CmdRequest is a request to the Bazel Proxy server. @@ -71,9 +72,10 @@ type ProxyClient struct { // The ProxyServer will only live as long as soong_ui does; the // underlying Bazel server will live past the duration of the build. type ProxyServer struct { - logger ServerLogger - outDir string - workspaceDir string + logger ServerLogger + outDir string + workspaceDir string + bazeliskVersion string // The server goroutine will listen on this channel and stop handling requests // once it is written to. done chan struct{} @@ -119,12 +121,17 @@ func (b *ProxyClient) IssueCommand(req CmdRequest) (CmdResponse, error) { } // NewProxyServer is a constructor for a ProxyServer. -func NewProxyServer(logger ServerLogger, outDir string, workspaceDir string) *ProxyServer { +func NewProxyServer(logger ServerLogger, outDir string, workspaceDir string, bazeliskVersion string) *ProxyServer { + if len(bazeliskVersion) > 0 { + logger.Println("** Using Bazelisk for this build, due to env var USE_BAZEL_VERSION=" + bazeliskVersion + " **") + } + return &ProxyServer{ - logger: logger, - outDir: outDir, - workspaceDir: workspaceDir, - done: make(chan struct{}), + logger: logger, + outDir: outDir, + workspaceDir: workspaceDir, + done: make(chan struct{}), + bazeliskVersion: bazeliskVersion, } } @@ -155,6 +162,9 @@ func (b *ProxyServer) handleRequest(conn net.Conn) error { return fmt.Errorf("Error decoding request: %s", err) } + if len(b.bazeliskVersion) > 0 { + req.Env = append(req.Env, "USE_BAZEL_VERSION="+b.bazeliskVersion) + } stdout, stderr, cmdErr := ExecBazel("./build/bazel/bin/bazel", b.workspaceDir, req) errorString := "" if cmdErr != nil { diff --git a/bp2build/Android.bp b/bp2build/Android.bp index 9ec3a40b9..4ecd05de7 100644 --- a/bp2build/Android.bp +++ b/bp2build/Android.bp @@ -72,7 +72,6 @@ bootstrap_go_package { "license_conversion_test.go", "license_kind_conversion_test.go", "linker_config_conversion_test.go", - "ndk_headers_conversion_test.go", "package_conversion_test.go", "performance_test.go", "prebuilt_etc_conversion_test.go", diff --git a/bp2build/bp2build_product_config.go b/bp2build/bp2build_product_config.go index 3abef9db1..66d0cc554 100644 --- a/bp2build/bp2build_product_config.go +++ b/bp2build/bp2build_product_config.go @@ -68,6 +68,14 @@ package(default_visibility = [ "@//build/bazel/product_config:__subpackages__", "@soong_injection//product_config_platforms:__subpackages__", ]) + +load("//{PRODUCT_FOLDER}:soong.variables.bzl", _soong_variables = "variables") +load("@//build/bazel/product_config:android_product.bzl", "android_product") + +android_product( + name = "current_product-{VARIANT}", + soong_variables = _soong_variables, +) `)), newFile( "product_config_platforms", @@ -78,6 +86,7 @@ package(default_visibility = [ # TODO: When we start generating the platforms for more than just the # currently lunched product, they should all be listed here product_labels = [ + "@soong_injection//product_config_platforms:current_product-{VARIANT}", "@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}" ] `)), @@ -85,25 +94,30 @@ product_labels = [ "product_config_platforms", "common.bazelrc", productReplacer.Replace(` -build --platforms @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64 +# current_product refers to the current TARGET_PRODUCT set, usually through +# 'lunch' or 'banchan'. Every build will have a primary TARGET_PRODUCT, but +# bazel supports using other products in tests or configuration transitions. The +# other products can be found in +# @soong_injection//product_config_platforms/products/... +build --platforms @soong_injection//product_config_platforms:current_product-{VARIANT}_linux_x86_64 -build:android --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT} -build:linux_x86_64 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64 -build:linux_bionic_x86_64 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_bionic_x86_64 -build:linux_musl_x86 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_musl_x86 -build:linux_musl_x86_64 --platforms=@soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_musl_x86_64 +build:android --platforms=@soong_injection//product_config_platforms:current_product-{VARIANT} +build:linux_x86_64 --platforms=@soong_injection//product_config_platforms:current_product-{VARIANT}_linux_x86_64 +build:linux_bionic_x86_64 --platforms=@soong_injection//product_config_platforms:current_product-{VARIANT}_linux_bionic_x86_64 +build:linux_musl_x86 --platforms=@soong_injection//product_config_platforms:current_product-{VARIANT}_linux_musl_x86 +build:linux_musl_x86_64 --platforms=@soong_injection//product_config_platforms:current_product-{VARIANT}_linux_musl_x86_64 `)), newFile( "product_config_platforms", "linux.bazelrc", productReplacer.Replace(` -build --host_platform @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x86_64 +build --host_platform @soong_injection//product_config_platforms:current_product-{VARIANT}_linux_x86_64 `)), newFile( "product_config_platforms", "darwin.bazelrc", productReplacer.Replace(` -build --host_platform @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_darwin_x86_64 +build --host_platform product_config_platforms:current_product-{VARIANT}_darwin_x86_64 `)), newFile( "product_config_platforms", @@ -111,7 +125,7 @@ build --host_platform @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_dar productReplacer.Replace(` flags: --cpu=k8 - @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT} + @soong_injection//product_config_platforms:current_product-{VARIANT} `)), } diff --git a/bp2build/cc_binary_conversion_test.go b/bp2build/cc_binary_conversion_test.go index 8a83cc0d5..610a9ca58 100644 --- a/bp2build/cc_binary_conversion_test.go +++ b/bp2build/cc_binary_conversion_test.go @@ -1036,3 +1036,73 @@ func TestCcBinaryHiddenVisibilityConvertedToFeatureOsSpecific(t *testing.T) { }, }) } + +func TestCcBinaryWithCfi(t *testing.T) { + runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{ + description: "cc_binary has correct features when cfi is enabled", + blueprint: ` +{rule_name} { + name: "foo", + sanitize: { + cfi: true, + }, +}`, + targets: []testBazelTarget{ + {"cc_binary", "foo", AttrNameToString{ + "features": `["android_cfi"]`, + "local_includes": `["."]`, + }}, + }, + }) +} + +func TestCcBinaryWithCfiOsSpecific(t *testing.T) { + runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{ + description: "cc_binary has correct features when cfi is enabled for specific variants", + blueprint: ` +{rule_name} { + name: "foo", + target: { + android: { + sanitize: { + cfi: true, + }, + }, + }, +}`, + targets: []testBazelTarget{ + {"cc_binary", "foo", AttrNameToString{ + "features": `select({ + "//build/bazel/platforms/os:android": ["android_cfi"], + "//conditions:default": [], + })`, + "local_includes": `["."]`, + }}, + }, + }) +} + +func TestCcBinaryWithCfiAndCfiAssemblySupport(t *testing.T) { + runCcBinaryTestCase(t, ccBinaryBp2buildTestCase{ + description: "cc_binary has correct features when cfi is enabled with cfi assembly support", + blueprint: ` +{rule_name} { + name: "foo", + sanitize: { + cfi: true, + config: { + cfi_assembly_support: true, + }, + }, +}`, + targets: []testBazelTarget{ + {"cc_binary", "foo", AttrNameToString{ + "features": `[ + "android_cfi", + "android_cfi_assembly_support", + ]`, + "local_includes": `["."]`, + }}, + }, + }) +} diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go index 3dd937319..c2dba67a5 100644 --- a/bp2build/cc_library_conversion_test.go +++ b/bp2build/cc_library_conversion_test.go @@ -4718,3 +4718,97 @@ func TestCcLibraryHostLdLibs(t *testing.T) { }, }) } + +func TestCcLibraryWithCfi(t *testing.T) { + runCcLibraryTestCase(t, Bp2buildTestCase{ + Description: "cc_library has correct features when cfi is enabled", + ModuleTypeUnderTest: "cc_library", + ModuleTypeUnderTestFactory: cc.LibraryFactory, + Blueprint: ` +cc_library { + name: "foo", + sanitize: { + cfi: true, + }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{ + "features": `["android_cfi"]`, + "local_includes": `["."]`, + }), + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "features": `["android_cfi"]`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibraryWithCfiOsSpecific(t *testing.T) { + runCcLibraryTestCase(t, Bp2buildTestCase{ + Description: "cc_library has correct features when cfi is enabled for specific variants", + ModuleTypeUnderTest: "cc_library", + ModuleTypeUnderTestFactory: cc.LibraryFactory, + Blueprint: ` +cc_library { + name: "foo", + target: { + android: { + sanitize: { + cfi: true, + }, + }, + }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{ + "features": `select({ + "//build/bazel/platforms/os:android": ["android_cfi"], + "//conditions:default": [], + })`, + "local_includes": `["."]`, + }), + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "features": `select({ + "//build/bazel/platforms/os:android": ["android_cfi"], + "//conditions:default": [], + })`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibraryWithCfiAndCfiAssemblySupport(t *testing.T) { + runCcLibraryTestCase(t, Bp2buildTestCase{ + Description: "cc_library has correct features when cfi is enabled with cfi_assembly_support", + ModuleTypeUnderTest: "cc_library", + ModuleTypeUnderTestFactory: cc.LibraryFactory, + Blueprint: ` +cc_library { + name: "foo", + sanitize: { + cfi: true, + config: { + cfi_assembly_support: true, + }, + }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{ + "features": `[ + "android_cfi", + "android_cfi_assembly_support", + ]`, + "local_includes": `["."]`, + }), + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "features": `[ + "android_cfi", + "android_cfi_assembly_support", + ]`, + "local_includes": `["."]`, + }), + }, + }) +} diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go index 6c9f9a18f..7f0ba4477 100644 --- a/bp2build/cc_library_shared_conversion_test.go +++ b/bp2build/cc_library_shared_conversion_test.go @@ -1445,3 +1445,73 @@ cc_library_shared { }, }) } + +func TestCcLibrarySharedWithCfi(t *testing.T) { + runCcLibrarySharedTestCase(t, Bp2buildTestCase{ + Description: "cc_library_shared has correct features when cfi is enabled for specific variants", + Blueprint: ` +cc_library_shared { + name: "foo", + sanitize: { + cfi: true, + }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "features": `["android_cfi"]`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibrarySharedWithCfiOsSpecific(t *testing.T) { + runCcLibrarySharedTestCase(t, Bp2buildTestCase{ + Description: "cc_library_shared has correct features when cfi is enabled", + Blueprint: ` +cc_library_shared { + name: "foo", + target: { + android: { + sanitize: { + cfi: true, + }, + }, + }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{ + "features": `select({ + "//build/bazel/platforms/os:android": ["android_cfi"], + "//conditions:default": [], + })`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibrarySharedWithCfiAndCfiAssemblySupport(t *testing.T) { + runCcLibrarySharedTestCase(t, Bp2buildTestCase{ + Description: "cc_library_shared has correct features when cfi is enabled with cfi assembly support", + Blueprint: ` +cc_library_static { + name: "foo", + sanitize: { + cfi: true, + config: { + cfi_assembly_support: true, + }, + }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo", AttrNameToString{ + "features": `[ + "android_cfi", + "android_cfi_assembly_support", + ]`, + "local_includes": `["."]`, + }), + }, + }) +} diff --git a/bp2build/cc_library_static_conversion_test.go b/bp2build/cc_library_static_conversion_test.go index 2705aafe5..f5378718f 100644 --- a/bp2build/cc_library_static_conversion_test.go +++ b/bp2build/cc_library_static_conversion_test.go @@ -2075,3 +2075,73 @@ cc_library_static { }, }) } + +func TestCcLibraryStaticWithCfi(t *testing.T) { + runCcLibraryStaticTestCase(t, Bp2buildTestCase{ + Description: "cc_library_static has correct features when cfi is enabled", + Blueprint: ` +cc_library_static { + name: "foo", + sanitize: { + cfi: true, + }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo", AttrNameToString{ + "features": `["android_cfi"]`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibraryStaticWithCfiOsSpecific(t *testing.T) { + runCcLibraryStaticTestCase(t, Bp2buildTestCase{ + Description: "cc_library_static has correct features when cfi is enabled for specific variants", + Blueprint: ` +cc_library_static { + name: "foo", + target: { + android: { + sanitize: { + cfi: true, + }, + }, + }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo", AttrNameToString{ + "features": `select({ + "//build/bazel/platforms/os:android": ["android_cfi"], + "//conditions:default": [], + })`, + "local_includes": `["."]`, + }), + }, + }) +} + +func TestCcLibraryStaticWithCfiAndCfiAssemblySupport(t *testing.T) { + runCcLibraryStaticTestCase(t, Bp2buildTestCase{ + Description: "cc_library_static has correct features when cfi is enabled with cfi_assembly_support", + Blueprint: ` +cc_library_static { + name: "foo", + sanitize: { + cfi: true, + config: { + cfi_assembly_support: true, + }, + }, +}`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("cc_library_static", "foo", AttrNameToString{ + "features": `[ + "android_cfi", + "android_cfi_assembly_support", + ]`, + "local_includes": `["."]`, + }), + }, + }) +} diff --git a/bp2build/genrule_conversion_test.go b/bp2build/genrule_conversion_test.go index 349088136..5cf4fb216 100644 --- a/bp2build/genrule_conversion_test.go +++ b/bp2build/genrule_conversion_test.go @@ -49,6 +49,7 @@ func otherGenruleBp(genruleTarget string) map[string]string { srcs: ["other_tool.in"], cmd: "cp $(in) $(out)", }`, genruleTarget, genruleTarget), + "other/file.txt": "", } } @@ -293,17 +294,20 @@ func TestGenruleSrcsLocationsAbsoluteLabel(t *testing.T) { bp := `%s { name: "foo", out: ["foo.out"], - srcs: [":other.tool"], + srcs: [":other.tool", "other/file.txt",], tool_files: [":foo.tool"], - cmd: "$(locations :foo.tool) -s $(out) $(location :other.tool)", + cmd: "$(locations :foo.tool) $(location other/file.txt) -s $(out) $(location :other.tool)", bazel_module: { bp2build_available: true }, }` for _, tc := range testCases { moduleAttrs := AttrNameToString{ - "cmd": `"$(locations //other:foo.tool) -s $(OUTS) $(location //other:other.tool)"`, - "outs": `["foo.out"]`, - "srcs": `["//other:other.tool"]`, + "cmd": `"$(locations //other:foo.tool) $(location //other:file.txt) -s $(OUTS) $(location //other:other.tool)"`, + "outs": `["foo.out"]`, + "srcs": `[ + "//other:other.tool", + "//other:file.txt", + ]`, "tools": `["//other:foo.tool"]`, } diff --git a/bp2build/java_test_host_conversion_test.go b/bp2build/java_test_host_conversion_test.go new file mode 100644 index 000000000..f411ffb07 --- /dev/null +++ b/bp2build/java_test_host_conversion_test.go @@ -0,0 +1,149 @@ +// Copyright 2023 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 bp2build + +import ( + "testing" + + "android/soong/android" + "android/soong/java" +) + +func runJavaTestHostTestCase(t *testing.T, tc Bp2buildTestCase) { + t.Helper() + (&tc).ModuleTypeUnderTest = "java_test_host" + (&tc).ModuleTypeUnderTestFactory = java.TestHostFactory + RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) { + ctx.RegisterModuleType("java_library", java.LibraryFactory) + }, tc) +} + +func TestJavaTestHostGeneral(t *testing.T) { + runJavaTestHostTestCase(t, Bp2buildTestCase{ + Description: "java_test_host general", + Filesystem: map[string]string{}, + Blueprint: ` +java_test_host { + name: "java_test_host-1", + srcs: ["a.java", "b.java"], + libs: ["lib_a"], + static_libs: ["static_libs_a"], + exclude_srcs: ["b.java"], + javacflags: ["-Xdoclint:all/protected"], + java_version: "8", +} + +java_library { + name: "lib_a", + bazel_module: { bp2build_available: false }, +} + +java_library { + name: "static_libs_a", + bazel_module: { bp2build_available: false }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("java_library", "java_test_host-1_lib", AttrNameToString{ + "deps": `[ + ":lib_a-neverlink", + ":static_libs_a", + ]`, + "java_version": `"8"`, + "javacopts": `["-Xdoclint:all/protected"]`, + "srcs": `["a.java"]`, + "target_compatible_with": `select({ + "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], + "//conditions:default": [], + })`, + }), + MakeBazelTarget("java_test", "java_test_host-1", AttrNameToString{ + "runtime_deps": `[":java_test_host-1_lib"]`, + "target_compatible_with": `select({ + "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], + "//conditions:default": [], + })`, + }), + }, + }) +} + +func TestJavaTestHostNoSrcs(t *testing.T) { + runJavaTestHostTestCase(t, Bp2buildTestCase{ + Description: "java_test_host without srcs", + Filesystem: map[string]string{}, + Blueprint: ` +java_test_host { + name: "java_test_host-1", + libs: ["lib_a"], + static_libs: ["static_libs_a"], +} + +java_library { + name: "lib_a", + bazel_module: { bp2build_available: false }, +} + +java_library { + name: "static_libs_a", + bazel_module: { bp2build_available: false }, +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("java_test", "java_test_host-1", AttrNameToString{ + "runtime_deps": `[ + ":lib_a-neverlink", + ":static_libs_a", + ]`, + "target_compatible_with": `select({ + "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], + "//conditions:default": [], + })`, + }), + }, + }) +} + +func TestJavaTestHostKotlinSrcs(t *testing.T) { + runJavaTestHostTestCase(t, Bp2buildTestCase{ + Description: "java_test_host with .kt in srcs", + Filesystem: map[string]string{}, + Blueprint: ` +java_test_host { + name: "java_test_host-1", + srcs: ["a.java", "b.kt"], +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget("java_test", "java_test_host-1", AttrNameToString{ + "runtime_deps": `[":java_test_host-1_lib"]`, + "target_compatible_with": `select({ + "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], + "//conditions:default": [], + })`, + }), + MakeBazelTarget("kt_jvm_library", "java_test_host-1_lib", AttrNameToString{ + "srcs": `[ + "a.java", + "b.kt", + ]`, + "target_compatible_with": `select({ + "//build/bazel/platforms/os:android": ["@platforms//:incompatible"], + "//conditions:default": [], + })`, + }), + }, + }) +} diff --git a/bp2build/ndk_headers_conversion_test.go b/bp2build/ndk_headers_conversion_test.go deleted file mode 100644 index 9d0f1f233..000000000 --- a/bp2build/ndk_headers_conversion_test.go +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright 2022 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 bp2build - -import ( - "fmt" - "testing" - - "android/soong/cc" -) - -func TestNdkHeaderFilepaths(t *testing.T) { - bpTemplate := ` - ndk_headers { - name: "foo", - srcs: %v, - exclude_srcs: %v, - } - ` - testCases := []struct { - desc string - srcs string - excludeSrcs string - expectedHdrs string - }{ - { - desc: "Single header file", - srcs: `["foo.h"]`, - excludeSrcs: `[]`, - expectedHdrs: `["foo.h"]`, - }, - { - desc: "Multiple header files", - srcs: `["foo.h", "foo_other.h"]`, - excludeSrcs: `[]`, - expectedHdrs: `[ - "foo.h", - "foo_other.h", - ]`, - }, - { - desc: "Multiple header files with excludes", - srcs: `["foo.h", "foo_other.h"]`, - excludeSrcs: `["foo_other.h"]`, - expectedHdrs: `["foo.h"]`, - }, - { - desc: "Multiple header files via Soong-supported globs", - srcs: `["*.h"]`, - excludeSrcs: `[]`, - expectedHdrs: `[ - "foo.h", - "foo_other.h", - ]`, - }, - } - for _, testCase := range testCases { - fs := map[string]string{ - "foo.h": "", - "foo_other.h": "", - } - expectedApiContributionTargetName := "foo.contribution" - expectedBazelTarget := MakeBazelTargetNoRestrictions( - "cc_api_headers", - expectedApiContributionTargetName, - AttrNameToString{ - "hdrs": testCase.expectedHdrs, - }, - ) - RunApiBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{ - Description: testCase.desc, - Blueprint: fmt.Sprintf(bpTemplate, testCase.srcs, testCase.excludeSrcs), - ExpectedBazelTargets: []string{expectedBazelTarget}, - Filesystem: fs, - }) - } -} - -func TestNdkHeaderIncludeDir(t *testing.T) { - bpTemplate := ` - ndk_headers { - name: "foo", - from: %v, - to: "this/value/is/ignored", - } - ` - testCases := []struct { - desc string - from string - expectedIncludeDir string - }{ - { - desc: "Empty `from` value", - from: `""`, - expectedIncludeDir: `""`, - }, - { - desc: "Non-Empty `from` value", - from: `"include"`, - expectedIncludeDir: `"include"`, - }, - } - for _, testCase := range testCases { - expectedApiContributionTargetName := "foo.contribution" - expectedBazelTarget := MakeBazelTargetNoRestrictions( - "cc_api_headers", - expectedApiContributionTargetName, - AttrNameToString{ - "include_dir": testCase.expectedIncludeDir, - }, - ) - RunApiBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{ - Description: testCase.desc, - Blueprint: fmt.Sprintf(bpTemplate, testCase.from), - ExpectedBazelTargets: []string{expectedBazelTarget}, - }) - } -} - -func TestVersionedNdkHeaderFilepaths(t *testing.T) { - bp := ` - versioned_ndk_headers { - name: "common_libc", - from: "include" - } - ` - fs := map[string]string{ - "include/math.h": "", - "include/stdio.h": "", - "include/arm/arm.h": "", - "include/x86/x86.h": "", - } - expectedApiContributionTargetName := "common_libc.contribution" - expectedBazelTarget := MakeBazelTargetNoRestrictions( - "cc_api_headers", - expectedApiContributionTargetName, - AttrNameToString{ - "include_dir": `"include"`, - "hdrs": `[ - "include/math.h", - "include/stdio.h", - "include/arm/arm.h", - "include/x86/x86.h", - ]`, - }, - ) - RunApiBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{ - Blueprint: bp, - Filesystem: fs, - ExpectedBazelTargets: []string{expectedBazelTarget}, - }) -} diff --git a/bp2build/ndk_library_conversion_test.go b/bp2build/ndk_library_conversion_test.go deleted file mode 100644 index 819ab25f8..000000000 --- a/bp2build/ndk_library_conversion_test.go +++ /dev/null @@ -1,77 +0,0 @@ -// Copyright 2022 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 bp2build - -import ( - "testing" - - "android/soong/cc" -) - -func TestNdkLibraryContributionSymbolFile(t *testing.T) { - bp := ` - ndk_library { - name: "libfoo", - symbol_file: "libfoo.map.txt", - } - ` - expectedBazelTarget := MakeBazelTargetNoRestrictions( - "cc_api_contribution", - "libfoo.ndk.contribution", - AttrNameToString{ - "api": `"libfoo.map.txt"`, - "api_surfaces": `["publicapi"]`, - "library_name": `"libfoo"`, - "target_compatible_with": `["//build/bazel/platforms/os:android"]`, - }, - ) - RunApiBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{ - Blueprint: bp, - ExpectedBazelTargets: []string{expectedBazelTarget}, - }) -} - -func TestNdkLibraryContributionHeaders(t *testing.T) { - bp := ` - ndk_library { - name: "libfoo", - symbol_file: "libfoo.map.txt", - export_header_libs: ["libfoo_headers"], - } - ` - fs := map[string]string{ - "header_directory/Android.bp": ` - ndk_headers { - name: "libfoo_headers", - } - `, - } - expectedBazelTarget := MakeBazelTargetNoRestrictions( - "cc_api_contribution", - "libfoo.ndk.contribution", - AttrNameToString{ - "api": `"libfoo.map.txt"`, - "api_surfaces": `["publicapi"]`, - "library_name": `"libfoo"`, - "hdrs": `["//header_directory:libfoo_headers.contribution"]`, - "target_compatible_with": `["//build/bazel/platforms/os:android"]`, - }, - ) - RunApiBp2BuildTestCase(t, cc.RegisterNdkModuleTypes, Bp2buildTestCase{ - Blueprint: bp, - Filesystem: fs, - ExpectedBazelTargets: []string{expectedBazelTarget}, - }) -} diff --git a/cc/afdo.go b/cc/afdo.go index 49f69873c..137ea97fe 100644 --- a/cc/afdo.go +++ b/cc/afdo.go @@ -34,7 +34,7 @@ var ( var afdoProfileProjectsConfigKey = android.NewOnceKey("AfdoProfileProjects") -const afdoCFlagsFormat = "-fprofile-sample-accurate -fprofile-sample-use=%s" +const afdoCFlagsFormat = "-fprofile-sample-use=%s" func recordMissingAfdoProfileFile(ctx android.BaseModuleContext, missing string) { getNamedMapForConfig(ctx.Config(), modulesMissingProfileFileKey).Store(missing, true) diff --git a/cc/bp2build.go b/cc/bp2build.go index 259ba397a..34cc5744c 100644 --- a/cc/bp2build.go +++ b/cc/bp2build.go @@ -591,7 +591,8 @@ func parseSrcs(ctx android.BazelConversionPathContext, props *BaseCompilerProper anySrcs := false // Add srcs-like dependencies such as generated files. // First create a LabelList containing these dependencies, then merge the values with srcs. - generatedSrcsLabelList := android.BazelLabelForModuleDepsExcludes(ctx, props.Generated_sources, props.Exclude_generated_sources) + genSrcs, _ := android.PartitionXsdSrcs(ctx, props.Generated_sources) + generatedSrcsLabelList := android.BazelLabelForModuleDepsExcludes(ctx, genSrcs, props.Exclude_generated_sources) if len(props.Generated_sources) > 0 || len(props.Exclude_generated_sources) > 0 { anySrcs = true } @@ -716,6 +717,14 @@ func bp2BuildYasm(ctx android.Bp2buildMutatorContext, m *Module, ca compilerAttr return ret } +// Replaces //a/b/my_xsd_config with //a/b/my_xsd_config-cpp +func xsdConfigCppTarget(ctx android.BazelConversionPathContext, mod blueprint.Module) string { + callback := func(xsd android.XsdConfigBp2buildTargets) string { + return xsd.CppBp2buildTargetName() + } + return android.XsdConfigBp2buildTarget(ctx, mod, callback) +} + // bp2BuildParseBaseProps returns all compiler, linker, library attributes of a cc module.. func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) baseAttributes { archVariantCompilerProps := module.GetArchVariantProperties(ctx, &BaseCompilerProperties{}) @@ -754,7 +763,14 @@ func bp2BuildParseBaseProps(ctx android.Bp2buildMutatorContext, module *Module) for cfg := range configs { var allHdrs []string if baseCompilerProps, ok := archVariantCompilerProps[axis][cfg].(*BaseCompilerProperties); ok { - allHdrs = baseCompilerProps.Generated_headers + ah, allHdrsXsd := android.PartitionXsdSrcs(ctx, baseCompilerProps.Generated_headers) + allHdrs = ah + // in the synthetic bp2build workspace, xsd sources are compiled to a static library + xsdCppConfigLibraryLabels := android.BazelLabelForModuleDepsWithFn(ctx, allHdrsXsd, xsdConfigCppTarget) + iwad := linkerAttrs.implementationWholeArchiveDeps.SelectValue(axis, cfg) + (&iwad).Append(xsdCppConfigLibraryLabels) + linkerAttrs.implementationWholeArchiveDeps.SetSelectValue(axis, cfg, bazel.FirstUniqueBazelLabelList(iwad)) + if baseCompilerProps.Lex != nil { compilerAttrs.lexopts.SetSelectValue(axis, cfg, baseCompilerProps.Lex.Flags) } @@ -1757,6 +1773,12 @@ func bp2buildSanitizerFeatures(ctx android.BazelConversionPathContext, m *Module for _, sanitizer := range sanitizerProps.Sanitize.Misc_undefined { features = append(features, "ubsan_"+sanitizer) } + if proptools.Bool(sanitizerProps.Sanitize.Cfi) { + features = append(features, "android_cfi") + if proptools.Bool(sanitizerProps.Sanitize.Config.Cfi_assembly_support) { + features = append(features, "android_cfi_assembly_support") + } + } sanitizerFeatures.SetSelectValue(axis, config, features) } }) @@ -524,6 +524,7 @@ type ModuleContextIntf interface { isAfdoCompile() bool isPgoCompile() bool isCfi() bool + isFuzzer() bool isNDKStubLibrary() bool useClangLld(actx ModuleContext) bool isForPlatform() bool @@ -1365,6 +1366,13 @@ func (c *Module) isCfi() bool { return false } +func (c *Module) isFuzzer() bool { + if sanitize := c.sanitize; sanitize != nil { + return Bool(sanitize.Properties.SanitizeMutated.Fuzzer) + } + return false +} + func (c *Module) isNDKStubLibrary() bool { if _, ok := c.compiler.(*stubDecorator); ok { return true @@ -1660,6 +1668,10 @@ func (ctx *moduleContextImpl) isCfi() bool { return ctx.mod.isCfi() } +func (ctx *moduleContextImpl) isFuzzer() bool { + return ctx.mod.isFuzzer() +} + func (ctx *moduleContextImpl) isNDKStubLibrary() bool { return ctx.mod.isNDKStubLibrary() } @@ -1916,7 +1928,6 @@ func allEnabledSanitizersSupportedByBazel(c *Module) bool { unsupportedSanitizers := []*bool{ sanitizeProps.Safestack, - sanitizeProps.Cfi, sanitizeProps.Scudo, BoolPtr(len(c.sanitize.Properties.Sanitize.Recover) > 0), BoolPtr(c.sanitize.Properties.Sanitize.Blocklist != nil), @@ -1935,6 +1946,8 @@ func allEnabledSanitizersSupportedByBazel(c *Module) bool { if ubsanEnabled && !c.MinimalRuntimeNeeded() { return false } + } else if san == cfi { + continue } else if c.sanitize.isSanitizerEnabled(san) { return false } @@ -4100,8 +4113,6 @@ func (c *Module) ConvertWithApiBp2build(ctx android.TopDownMutatorContext) { // Aggressively generate api targets for all header modules // This is necessary since the header module does not know if it is a dep of API surface stub library apiLibraryHeadersBp2Build(ctx, c) - case ndkLibrary: - ndkLibraryBp2build(ctx, c) } } diff --git a/cc/cc_test.go b/cc/cc_test.go index 173911bc4..701c3bb74 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -5538,7 +5538,7 @@ func TestDisableSanitizerVariantsInMixedBuilds(t *testing.T) { name: "foo_cfi", variant: "android_arm64_armv8-a_static_cfi_apex28", expectedOutputPaths: []string{ - "out/soong/.intermediates/foo_cfi/android_arm64_armv8-a_static_cfi_apex28/foo_cfi.a", + "outputbase/execroot/__main__/foo_cfi.a", }, }, { diff --git a/cc/config/tidy.go b/cc/config/tidy.go index d55a13dcf..efa45495b 100644 --- a/cc/config/tidy.go +++ b/cc/config/tidy.go @@ -42,6 +42,8 @@ var ( "-bugprone-unchecked-optional-access", // http://b/265438407 "-misc-use-anonymous-namespace", + // http://b/285005947 + "-performance-avoid-endl", } // Some clang-tidy checks are included in some tidy_checks_as_errors lists, @@ -56,6 +58,14 @@ var ( "-bugprone-signed-char-misuse", // http://b/241819232 "-misc-const-correctness", + // http://b/285356805 + "-bugprone-unsafe-functions", + "-cert-msc24-c", + "-cert-msc33-c", + // http://b/285356799 + "-modernize-type-traits", + // http://b/285361108 + "-readability-avoid-unconditional-preprocessor-if", } extraArgFlags = []string{ @@ -43,22 +43,16 @@ type LTOProperties struct { // referred to in blueprint files as "lto" Lto struct { Never *bool `android:"arch_variant"` - Full *bool `android:"arch_variant"` Thin *bool `android:"arch_variant"` } `android:"arch_variant"` // Dep properties indicate that this module needs to be built with LTO // since it is an object dependency of an LTO module. - FullEnabled bool `blueprint:"mutated"` ThinEnabled bool `blueprint:"mutated"` NoLtoEnabled bool `blueprint:"mutated"` - FullDep bool `blueprint:"mutated"` ThinDep bool `blueprint:"mutated"` NoLtoDep bool `blueprint:"mutated"` - // Use clang lld instead of gnu ld. - Use_clang_lld *bool - // Use -fwhole-program-vtables cflag. Whole_program_vtables *bool } @@ -77,17 +71,10 @@ func (lto *lto) begin(ctx BaseModuleContext) { } } -func (lto *lto) useClangLld(ctx BaseModuleContext) bool { - if lto.Properties.Use_clang_lld != nil { - return Bool(lto.Properties.Use_clang_lld) - } - return true -} - func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags { // TODO(b/131771163): Disable LTO when using explicit fuzzing configurations. // LTO breaks fuzzer builds. - if inList("-fsanitize=fuzzer-no-link", flags.Local.CFlags) { + if ctx.isFuzzer() { return flags } @@ -96,8 +83,6 @@ func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags { var ltoLdFlag string if lto.ThinLTO() { ltoCFlag = "-flto=thin -fsplit-lto-unit" - } else if lto.FullLTO() { - ltoCFlag = "-flto" } else { ltoCFlag = "-flto=thin -fsplit-lto-unit" ltoLdFlag = "-Wl,--lto-O0" @@ -112,7 +97,7 @@ func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags { flags.Local.CFlags = append(flags.Local.CFlags, "-fwhole-program-vtables") } - if (lto.DefaultThinLTO(ctx) || lto.ThinLTO()) && ctx.Config().IsEnvTrue("USE_THINLTO_CACHE") && lto.useClangLld(ctx) { + if (lto.DefaultThinLTO(ctx) || lto.ThinLTO()) && ctx.Config().IsEnvTrue("USE_THINLTO_CACHE") { // Set appropriate ThinLTO cache policy cacheDirFormat := "-Wl,--thinlto-cache-dir=" cacheDir := android.PathForOutput(ctx, "thinlto-cache").String() @@ -136,13 +121,13 @@ func (lto *lto) flags(ctx BaseModuleContext, flags Flags) Flags { } func (lto *lto) LTO(ctx BaseModuleContext) bool { - return lto.ThinLTO() || lto.FullLTO() || lto.DefaultThinLTO(ctx) + return lto.ThinLTO() || lto.DefaultThinLTO(ctx) } func (lto *lto) DefaultThinLTO(ctx BaseModuleContext) bool { // LP32 has many subtle issues and less test coverage. lib32 := ctx.Arch().ArchType.Multilib == "lib32" - // CFI enables full LTO. + // CFI adds LTO flags by itself. cfi := ctx.isCfi() // Performance and binary size are less important for host binaries and tests. host := ctx.Host() @@ -153,10 +138,6 @@ func (lto *lto) DefaultThinLTO(ctx BaseModuleContext) bool { return GlobalThinLTO(ctx) && !lto.Never() && !lib32 && !cfi && !host && !test && !vndk } -func (lto *lto) FullLTO() bool { - return lto != nil && (proptools.Bool(lto.Properties.Lto.Full) || lto.Properties.FullEnabled) -} - func (lto *lto) ThinLTO() bool { return lto != nil && (proptools.Bool(lto.Properties.Lto.Thin) || lto.Properties.ThinEnabled) } @@ -174,12 +155,8 @@ func ltoDepsMutator(mctx android.TopDownMutatorContext) { globalThinLTO := GlobalThinLTO(mctx) if m, ok := mctx.Module().(*Module); ok { - full := m.lto.FullLTO() thin := m.lto.ThinLTO() never := m.lto.Never() - if full && thin { - mctx.PropertyErrorf("LTO", "FullLTO and ThinLTO are mutually exclusive") - } mctx.WalkDeps(func(dep android.Module, parent android.Module) bool { tag := mctx.OtherModuleDependencyTag(dep) @@ -197,9 +174,6 @@ func ltoDepsMutator(mctx android.TopDownMutatorContext) { } if dep, ok := dep.(*Module); ok { - if full && !dep.lto.FullLTO() { - dep.lto.Properties.FullDep = true - } if !globalThinLTO && thin && !dep.lto.ThinLTO() { dep.lto.Properties.ThinDep = true } @@ -222,9 +196,6 @@ func ltoMutator(mctx android.BottomUpMutatorContext) { // Create variations for LTO types required as static // dependencies variationNames := []string{""} - if m.lto.Properties.FullDep && !m.lto.FullLTO() { - variationNames = append(variationNames, "lto-full") - } if !globalThinLTO && m.lto.Properties.ThinDep && !m.lto.ThinLTO() { variationNames = append(variationNames, "lto-thin") } @@ -234,13 +205,10 @@ func ltoMutator(mctx android.BottomUpMutatorContext) { // Use correct dependencies if LTO property is explicitly set // (mutually exclusive) - if m.lto.FullLTO() { - mctx.SetDependencyVariation("lto-full") - } if !globalThinLTO && m.lto.ThinLTO() { mctx.SetDependencyVariation("lto-thin") } - // Never must be the last, it overrides Thin or Full. + // Never must be the last, it overrides Thin. if globalThinLTO && m.lto.Never() { mctx.SetDependencyVariation("lto-none") } @@ -257,9 +225,6 @@ func ltoMutator(mctx android.BottomUpMutatorContext) { } // LTO properties for dependencies - if name == "lto-full" { - variation.lto.Properties.FullEnabled = true - } if name == "lto-thin" { variation.lto.Properties.ThinEnabled = true } @@ -268,7 +233,6 @@ func ltoMutator(mctx android.BottomUpMutatorContext) { } variation.Properties.PreventInstall = true variation.Properties.HideFromMake = true - variation.lto.Properties.FullDep = false variation.lto.Properties.ThinDep = false variation.lto.Properties.NoLtoDep = false } diff --git a/cc/ndk_headers.go b/cc/ndk_headers.go index 7354be9f7..d0ae4a56d 100644 --- a/cc/ndk_headers.go +++ b/cc/ndk_headers.go @@ -19,10 +19,8 @@ import ( "path/filepath" "github.com/google/blueprint" - "github.com/google/blueprint/proptools" "android/soong/android" - "android/soong/bazel" ) var ( @@ -81,7 +79,6 @@ type headerProperties struct { type headerModule struct { android.ModuleBase - android.BazelModuleBase properties headerProperties @@ -147,39 +144,6 @@ func (m *headerModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { } } -// TODO(b/243196151): Populate `system` and `arch` metadata -type bazelCcApiHeadersAttributes struct { - Hdrs bazel.LabelListAttribute - Include_dir *string -} - -func createCcApiHeadersTarget(ctx android.TopDownMutatorContext, includes []string, excludes []string, include_dir *string) { - props := bazel.BazelTargetModuleProperties{ - Rule_class: "cc_api_headers", - Bzl_load_location: "//build/bazel/rules/apis:cc_api_contribution.bzl", - } - attrs := &bazelCcApiHeadersAttributes{ - Hdrs: bazel.MakeLabelListAttribute( - android.BazelLabelForModuleSrcExcludes( - ctx, - includes, - excludes, - ), - ), - Include_dir: include_dir, - } - ctx.CreateBazelTargetModule(props, android.CommonAttributes{ - Name: android.ApiContributionTargetName(ctx.ModuleName()), - }, attrs) -} - -var _ android.ApiProvider = (*headerModule)(nil) - -func (h *headerModule) ConvertWithApiBp2build(ctx android.TopDownMutatorContext) { - // Generate `cc_api_headers` target for Multi-tree API export - createCcApiHeadersTarget(ctx, h.properties.Srcs, h.properties.Exclude_srcs, h.properties.From) -} - // ndk_headers installs the sets of ndk headers defined in the srcs property // to the sysroot base + "usr/include" + to directory + directory component. // ndk_headers requires the license file to be specified. Example: @@ -226,7 +190,6 @@ type versionedHeaderProperties struct { // Note that this is really only built to handle bionic/libc/include. type versionedHeaderModule struct { android.ModuleBase - android.BazelModuleBase properties versionedHeaderProperties @@ -264,15 +227,6 @@ func (m *versionedHeaderModule) GenerateAndroidBuildActions(ctx android.ModuleCo processHeadersWithVersioner(ctx, fromSrcPath, toOutputPath, srcFiles, installPaths) } -var _ android.ApiProvider = (*versionedHeaderModule)(nil) - -func (h *versionedHeaderModule) ConvertWithApiBp2build(ctx android.TopDownMutatorContext) { - // Glob all .h files under `From` - includePattern := headerGlobPattern(proptools.String(h.properties.From)) - // Generate `cc_api_headers` target for Multi-tree API export - createCcApiHeadersTarget(ctx, []string{includePattern}, []string{}, h.properties.From) -} - func processHeadersWithVersioner(ctx android.ModuleContext, srcDir, outDir android.Path, srcFiles android.Paths, installPaths []android.WritablePath) android.Path { // The versioner depends on a dependencies directory to simplify determining include paths diff --git a/cc/ndk_library.go b/cc/ndk_library.go index f8a355950..f0b7cc52b 100644 --- a/cc/ndk_library.go +++ b/cc/ndk_library.go @@ -599,24 +599,3 @@ func apiHeaderLabels(ctx android.TopDownMutatorContext, hdrLibs []string) bazel. } return android.BazelLabelForModuleDepsWithFn(ctx, hdrLibs, addSuffix) } - -func ndkLibraryBp2build(ctx android.TopDownMutatorContext, m *Module) { - props := bazel.BazelTargetModuleProperties{ - Rule_class: "cc_api_contribution", - Bzl_load_location: "//build/bazel/rules/apis:cc_api_contribution.bzl", - } - stubLibrary := m.compiler.(*stubDecorator) - attrs := &bazelCcApiContributionAttributes{ - Library_name: stubLibrary.implementationModuleName(m.Name()), - Api_surfaces: bazel.MakeStringListAttribute( - []string{android.PublicApi.String()}), - } - if symbolFile := stubLibrary.properties.Symbol_file; symbolFile != nil { - apiLabel := android.BazelLabelForModuleSrcSingle(ctx, proptools.String(symbolFile)).Label - attrs.Api = *bazel.MakeLabelAttribute(apiLabel) - } - apiHeaders := apiHeaderLabels(ctx, stubLibrary.properties.Export_header_libs) - attrs.Hdrs = bazel.MakeLabelListAttribute(apiHeaders) - apiContributionTargetName := android.ApiContributionTargetName(ctx.ModuleName()) - ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: apiContributionTargetName}, attrs) -} diff --git a/cc/sanitize.go b/cc/sanitize.go index 6e732b617..a5691ee24 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -64,13 +64,14 @@ var ( cfiBlocklistPath = "external/compiler-rt/lib/cfi" cfiBlocklistFilename = "cfi_blocklist.txt" + cfiEnableFlag = "-fsanitize=cfi" cfiCrossDsoFlag = "-fsanitize-cfi-cross-dso" cfiCflags = []string{"-flto", cfiCrossDsoFlag, "-fsanitize-ignorelist=" + cfiBlocklistPath + "/" + cfiBlocklistFilename} // -flto and -fvisibility are required by clang when -fsanitize=cfi is // used, but have no effect on assembly files cfiAsflags = []string{"-flto", "-fvisibility=default"} - cfiLdflags = []string{"-flto", cfiCrossDsoFlag, "-fsanitize=cfi", + cfiLdflags = []string{"-flto", cfiCrossDsoFlag, cfiEnableFlag, "-Wl,-plugin-opt,O1"} cfiExportsMapPath = "build/soong/cc/config" cfiExportsMapFilename = "cfi_exports.map" @@ -395,8 +396,8 @@ func init() { // Leave out "-flto" from the slices exported to bazel, as we will use the // dedicated LTO feature for this. For C Flags and Linker Flags, also leave - // out the cross DSO flag which will be added separately by transitions. - exportedVars.ExportStringList("CfiCFlags", cfiCflags[2:]) + // out the cross DSO flag which will be added separately under the correct conditions. + exportedVars.ExportStringList("CfiCFlags", append(cfiCflags[2:], cfiEnableFlag)) exportedVars.ExportStringList("CfiLdFlags", cfiLdflags[2:]) exportedVars.ExportStringList("CfiAsFlags", cfiAsflags[1:]) diff --git a/cc/test.go b/cc/test.go index 27de06b07..3f5f71007 100644 --- a/cc/test.go +++ b/cc/test.go @@ -70,6 +70,10 @@ type TestOptions struct { // Add MinApiLevelModuleController with ro.vndk.version property. If ro.vndk.version has an // integer value and the value is less than the min_vndk_version, skip this module. Min_vndk_version *int64 + + // Extra <option> tags to add to the auto generated test xml file under the test runner, e.g., GTest. + // The "key" is optional in each of these. + Test_runner_options []tradefed.Option } type TestBinaryProperties struct { @@ -398,6 +402,7 @@ func (test *testBinary) install(ctx ModuleContext, file android.Path) { TestConfigTemplateProp: test.Properties.Test_config_template, TestSuites: test.testDecorator.InstallerProperties.Test_suites, Config: configs, + TestRunnerOptions: test.Properties.Test_options.Test_runner_options, AutoGenConfig: test.Properties.Auto_gen_config, TestInstallBase: testInstallBase, DeviceTemplate: "${NativeTestConfigTemplate}", diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go index e006c9d7e..2e6b6d44a 100644 --- a/cmd/soong_build/main.go +++ b/cmd/soong_build/main.go @@ -16,6 +16,7 @@ package main import ( "bytes" + "errors" "flag" "fmt" "os" @@ -135,12 +136,24 @@ func runMixedModeBuild(ctx *android.Context, extraNinjaDeps []string) string { writeDepFile(cmdlineArgs.OutFile, ctx.EventHandler, ninjaDeps) - if ctx.Config().IsEnvTrue("SOONG_GENERATES_NINJA_HINT") { + if needToWriteNinjaHint(ctx) { writeNinjaHint(ctx) } return cmdlineArgs.OutFile } +func needToWriteNinjaHint(ctx *android.Context) bool { + switch ctx.Config().GetenvWithDefault("SOONG_GENERATES_NINJA_HINT", "") { + case "always": + return true + case "depend": + if _, err := os.Stat(filepath.Join(ctx.Config().OutDir(), ".ninja_log")); errors.Is(err, os.ErrNotExist) { + return true + } + } + return false +} + // Run the code-generation phase to convert BazelTargetModules to BUILD files. func runQueryView(queryviewDir, queryviewMarker string, ctx *android.Context) { ctx.EventHandler.Begin("queryview") @@ -460,7 +473,7 @@ func runSoongOnlyBuild(ctx *android.Context, extraNinjaDeps []string) string { // The actual output (build.ninja) was written in the RunBlueprint() call // above writeDepFile(cmdlineArgs.OutFile, ctx.EventHandler, ninjaDeps) - if ctx.Config().IsEnvTrue("SOONG_GENERATES_NINJA_HINT") { + if needToWriteNinjaHint(ctx) { writeNinjaHint(ctx) } return cmdlineArgs.OutFile @@ -552,6 +565,12 @@ func main() { } writeMetrics(configuration, ctx.EventHandler, metricsDir) } + + // Register this environment variablesas being an implicit dependencies of + // soong_build. Changes to this environment variable will result in + // retriggering soong_build. + configuration.Getenv("USE_BAZEL_VERSION") + writeUsedEnvironmentFile(configuration) // Touch the output file so that it's the newest file created by soong_build. diff --git a/fuzz/fuzz_common.go b/fuzz/fuzz_common.go index 2a1b40452..b470304b5 100644 --- a/fuzz/fuzz_common.go +++ b/fuzz/fuzz_common.go @@ -170,6 +170,27 @@ func (service_privilege ServicePrivilege) isValidServicePrivilege() bool { return false } +type UsePlatformLibs string + +const ( + unknown_use_platform_libs UsePlatformLibs = "unknown_use_platform_libs" + // Use the native libraries on the device, typically in /system directory + use_platform_libs = "use_platform_libs" + // Do not use any native libraries (ART will not be initialized) + use_none = "use_none" +) + +func (use_platform_libs UsePlatformLibs) isValidUsePlatformLibs() bool { + switch use_platform_libs { + case "", + unknown_use_platform_libs, + use_platform_libs, + use_none: + return true + } + return false +} + type UserData string const ( @@ -284,6 +305,10 @@ func IsValidConfig(fuzzModule FuzzPackagedModule, moduleName string) bool { if !config.Automatically_route_to.isValidAutomaticallyRouteTo() { panic(fmt.Errorf("Invalid automatically_route_to in fuzz config in %s", moduleName)) } + + if !config.Use_platform_libs.isValidUsePlatformLibs() { + panic(fmt.Errorf("Invalid use_platform_libs in fuzz config in %s", moduleName)) + } } return true } @@ -341,6 +366,8 @@ type FuzzConfig struct { Target_modules []string `json:"target_modules,omitempty"` // Specifies a bug assignee to replace default ISE assignment Triage_assignee string `json:"triage_assignee,omitempty"` + // Specifies libs used to initialize ART (java only, 'use_none' for no initialization) + Use_platform_libs UsePlatformLibs `json:"use_platform_libs,omitempty"` } type FuzzFrameworks struct { diff --git a/genrule/allowlists.go b/genrule/allowlists.go index 875dbabed..2954f8bc1 100644 --- a/genrule/allowlists.go +++ b/genrule/allowlists.go @@ -14,10 +14,6 @@ package genrule -import ( - "android/soong/android" -) - var ( DepfileAllowList = []string{ "depfile_allowed_for_test", @@ -136,12 +132,3 @@ var ( "external/perfetto", } ) -var DepfileAllowSet = map[string]bool{} -var SandboxingDenyModuleSet = map[string]bool{} -var SandboxingDenyPathSet = map[string]bool{} - -func init() { - android.AddToStringSet(DepfileAllowSet, DepfileAllowList) - android.AddToStringSet(SandboxingDenyModuleSet, append(DepfileAllowList, SandboxingDenyModuleList...)) - android.AddToStringSet(SandboxingDenyPathSet, SandboxingDenyPathList) -} diff --git a/genrule/genrule.go b/genrule/genrule.go index c830fcc43..4992625e5 100644 --- a/genrule/genrule.go +++ b/genrule/genrule.go @@ -24,6 +24,7 @@ import ( "path/filepath" "strconv" "strings" + "sync" "android/soong/bazel/cquery" @@ -60,6 +61,12 @@ var PrepareForIntegrationTestWithGenrule = android.GroupFixturePreparers( PrepareForTestWithGenRuleBuildComponents, ) +var DepfileAllowSet map[string]bool +var SandboxingDenyModuleSet map[string]bool +var SandboxingDenyPathSet map[string]bool +var SandboxingDenyModuleSetLock sync.Mutex +var DepfileAllowSetLock sync.Mutex + func RegisterGenruleBuildComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("genrule_defaults", defaultsFactory) @@ -595,6 +602,12 @@ func (g *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Allowlist genrule to use depfile until we have a solution to remove it. // TODO(b/235582219): Remove allowlist for genrule if Bool(g.properties.Depfile) { + if DepfileAllowSet == nil { + DepfileAllowSetLock.Lock() + defer DepfileAllowSetLock.Unlock() + DepfileAllowSet = map[string]bool{} + android.AddToStringSet(DepfileAllowSet, DepfileAllowList) + } // TODO(b/283852474): Checking the GenruleSandboxing flag is temporary in // order to pass the presubmit before internal master is updated. if ctx.DeviceConfig().GenruleSandboxing() && !DepfileAllowSet[g.Name()] { @@ -1024,8 +1037,19 @@ func DefaultsFactory(props ...interface{}) android.Module { } func getSandboxedRuleBuilder(ctx android.ModuleContext, r *android.RuleBuilder) *android.RuleBuilder { - if !ctx.DeviceConfig().GenruleSandboxing() || SandboxingDenyPathSet[ctx.ModuleDir()] || - SandboxingDenyModuleSet[ctx.ModuleName()] { + if !ctx.DeviceConfig().GenruleSandboxing() { + return r.SandboxTools() + } + if SandboxingDenyModuleSet == nil { + SandboxingDenyModuleSetLock.Lock() + defer SandboxingDenyModuleSetLock.Unlock() + SandboxingDenyModuleSet = map[string]bool{} + SandboxingDenyPathSet = map[string]bool{} + android.AddToStringSet(SandboxingDenyModuleSet, append(DepfileAllowList, SandboxingDenyModuleList...)) + android.AddToStringSet(SandboxingDenyPathSet, SandboxingDenyPathList) + } + + if SandboxingDenyPathSet[ctx.ModuleDir()] || SandboxingDenyModuleSet[ctx.ModuleName()] { return r.SandboxTools() } return r.SandboxInputs() diff --git a/java/app.go b/java/app.go index 561ce1d17..d9272e4fc 100755 --- a/java/app.go +++ b/java/app.go @@ -18,6 +18,7 @@ package java // related module types, including their override variants. import ( + "fmt" "path/filepath" "strings" @@ -288,7 +289,13 @@ func (a *AndroidApp) OverridablePropertiesDepsMutator(ctx android.BottomUpMutato } if a.appProperties.Privapp_allowlist != nil && !Bool(a.appProperties.Privileged) { - ctx.PropertyErrorf("privapp_allowlist", "privileged must be set in order to use privapp_allowlist") + // There are a few uids that are explicitly considered privileged regardless of their + // app's location. Bluetooth is one such app. It should arguably be moved to priv-app, + // but for now, allow it not to be in priv-app. + privilegedBecauseOfUid := ctx.ModuleName() == "Bluetooth" + if !privilegedBecauseOfUid { + ctx.PropertyErrorf("privapp_allowlist", "privileged must be set in order to use privapp_allowlist (with a few exceptions)") + } } for _, cert := range a.appProperties.Additional_certificates { @@ -795,8 +802,9 @@ func (a *AndroidApp) generateAndroidBuildActions(ctx android.ModuleContext) { shouldInstallAppPackage := (Bool(a.Module.properties.Installable) || ctx.Host()) && apexInfo.IsForPlatform() && !a.appProperties.PreventInstall if shouldInstallAppPackage { if a.privAppAllowlist.Valid() { - installPath := android.PathForModuleInstall(ctx, "etc", "permissions") - ctx.InstallFile(installPath, a.privAppAllowlist.Path().Base(), a.privAppAllowlist.Path()) + allowlistInstallPath := android.PathForModuleInstall(ctx, "etc", "permissions") + allowlistInstallFilename := a.installApkName + ".xml" + ctx.InstallFile(allowlistInstallPath, allowlistInstallFilename, a.privAppAllowlist.Path()) } var extraInstalledPaths android.Paths @@ -1390,10 +1398,15 @@ func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps boo } } -// presentOptionalUsesLibs returns optional_uses_libs after filtering out MissingUsesLibraries, which don't exist in the -// build. +// presentOptionalUsesLibs returns optional_uses_libs after filtering out libraries that don't exist in the source tree. func (u *usesLibrary) presentOptionalUsesLibs(ctx android.BaseModuleContext) []string { - optionalUsesLibs, _ := android.FilterList(u.usesLibraryProperties.Optional_uses_libs, ctx.Config().MissingUsesLibraries()) + optionalUsesLibs := android.FilterListPred(u.usesLibraryProperties.Optional_uses_libs, func(s string) bool { + exists := ctx.OtherModuleExists(s) + if !exists && !android.InList(ctx.ModuleName(), ctx.Config().BuildWarningBadOptionalUsesLibsAllowlist()) { + fmt.Printf("Warning: Module '%s' depends on non-existing optional_uses_libs '%s'\n", ctx.ModuleName(), s) + } + return exists + }) return optionalUsesLibs } diff --git a/java/app_test.go b/java/app_test.go index 7f9f0ed9f..cf7d17490 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -2645,7 +2645,7 @@ func TestUsesLibraries(t *testing.T) { PrepareForTestWithJavaSdkLibraryFiles, FixtureWithLastReleaseApis("runtime-library", "foo", "quuz", "qux", "bar", "fred"), android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { - variables.MissingUsesLibraries = []string{"baz"} + variables.BuildWarningBadOptionalUsesLibsAllowlist = []string{"app", "prebuilt"} }), ).RunTestWithBp(t, bp) @@ -3545,8 +3545,8 @@ func TestPrivappAllowlist(t *testing.T) { } // verify that permissions are copied to device - app.Output("out/soong/target/product/test_device/system/etc/permissions/privapp_allowlist_com.android.foo.xml") - overrideApp.Output("out/soong/target/product/test_device/system/etc/permissions/privapp_allowlist_com.google.android.foo.xml") + app.Output("out/soong/target/product/test_device/system/etc/permissions/foo.xml") + overrideApp.Output("out/soong/target/product/test_device/system/etc/permissions/bar.xml") } func TestPrivappAllowlistAndroidMk(t *testing.T) { @@ -3597,7 +3597,7 @@ func TestPrivappAllowlistAndroidMk(t *testing.T) { t, "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include privapp_allowlist", baseEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0], - "privapp_allowlist_com.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/privapp_allowlist_com.android.foo.xml", + "privapp_allowlist_com.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/foo.xml", ) overrideAndroidApp := overrideApp.Module().(*AndroidApp) @@ -3624,6 +3624,6 @@ func TestPrivappAllowlistAndroidMk(t *testing.T) { t, "androidmk has incorrect LOCAL_SOONG_INSTALL_PAIRS; expected to it to include privapp_allowlist", overrideEntries.EntryMap["LOCAL_SOONG_INSTALL_PAIRS"][0], - "\\S+soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/privapp_allowlist_com.google.android.foo.xml", + "\\S+soong/.intermediates/foo/android_common_bar/privapp_allowlist_com.google.android.foo.xml:\\S+/target/product/test_device/system/etc/permissions/bar.xml", ) } diff --git a/java/base.go b/java/base.go index 374138c78..ed61e12ed 100644 --- a/java/base.go +++ b/java/base.go @@ -79,6 +79,9 @@ type CommonProperties struct { // list of java libraries that will be compiled into the resulting jar Static_libs []string `android:"arch_variant"` + // list of java libraries that should not be used to build this module + Exclude_static_libs []string `android:"arch_variant"` + // manifest file to be included in resulting jar Manifest *string `android:"path"` @@ -724,6 +727,8 @@ func (j *Module) deps(ctx android.BottomUpMutatorContext) { } libDeps := ctx.AddVariationDependencies(nil, libTag, j.properties.Libs...) + + j.properties.Static_libs = android.RemoveListFromList(j.properties.Static_libs, j.properties.Exclude_static_libs) ctx.AddVariationDependencies(nil, staticLibTag, j.properties.Static_libs...) // Add dependency on libraries that provide additional hidden api annotations. @@ -1923,22 +1928,22 @@ type moduleWithSdkDep interface { func (m *Module) getSdkLinkType(ctx android.BaseModuleContext, name string) (ret sdkLinkType, stubs bool) { switch name { - case android.SdkCore.JavaLibraryName(ctx.Config()), - android.JavaApiLibraryName(ctx.Config(), "legacy.core.platform.api.stubs"), - android.JavaApiLibraryName(ctx.Config(), "stable.core.platform.api.stubs"), + case android.SdkCore.DefaultJavaLibraryName(), + "legacy.core.platform.api.stubs", + "stable.core.platform.api.stubs", "stub-annotations", "private-stub-annotations-jar", - android.JavaApiLibraryName(ctx.Config(), "core-lambda-stubs"), + "core-lambda-stubs", "core-generated-annotation-stubs": return javaCore, true - case android.SdkPublic.JavaLibraryName(ctx.Config()): + case android.SdkPublic.DefaultJavaLibraryName(): return javaSdk, true - case android.SdkSystem.JavaLibraryName(ctx.Config()): + case android.SdkSystem.DefaultJavaLibraryName(): return javaSystem, true - case android.SdkModule.JavaLibraryName(ctx.Config()): + case android.SdkModule.DefaultJavaLibraryName(): return javaModule, true - case android.SdkSystemServer.JavaLibraryName(ctx.Config()): + case android.SdkSystemServer.DefaultJavaLibraryName(): return javaSystemServer, true - case android.SdkTest.JavaLibraryName(ctx.Config()): + case android.SdkTest.DefaultJavaLibraryName(): return javaSystem, true } @@ -2188,5 +2193,9 @@ func (j *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) { if binary, ok := ctx.Module().(*Binary); ok { javaBinaryHostBp2Build(ctx, binary) } + case "java_test_host": + if testHost, ok := ctx.Module().(*TestHost); ok { + javaTestHostBp2Build(ctx, testHost) + } } } diff --git a/java/core-libraries/Android.bp b/java/core-libraries/Android.bp index 958f4cead..eadd9c697 100644 --- a/java/core-libraries/Android.bp +++ b/java/core-libraries/Android.bp @@ -33,19 +33,45 @@ dist_targets = [ "win_sdk", ] -java_library { - name: "core.current.stubs", +java_defaults { + name: "core.current.stubs.defaults", visibility: ["//visibility:public"], + sdk_version: "none", + system_modules: "none", + dist: { + targets: dist_targets, + }, +} + +java_library { + name: "core.current.stubs.from-source", + defaults: [ + "core.current.stubs.defaults", + ], static_libs: [ "art.module.public.api.stubs", "conscrypt.module.public.api.stubs", "i18n.module.public.api.stubs", ], - sdk_version: "none", - system_modules: "none", +} - dist: { - targets: dist_targets, +java_library { + name: "core.current.stubs", + defaults: [ + "core.current.stubs.defaults", + ], + static_libs: [ + "core.current.stubs.from-source", + ], + product_variables: { + build_from_text_stub: { + static_libs: [ + "core.current.stubs.from-text", + ], + exclude_static_libs: [ + "core.current.stubs.from-source", + ], + }, }, } @@ -199,18 +225,46 @@ core_platform_visibility = ["//visibility:public"] // API annotations are available to the dex tools that enable enforcement of runtime // accessibility. b/119068555 java_library { + name: "legacy.core.platform.api.stubs.from-source", + visibility: core_platform_visibility, + defaults: [ + "core.platform.api.stubs.defaults", + ], + static_libs: [ + "art.module.public.api.stubs.module_lib", + "conscrypt.module.platform.api.stubs", + "legacy.i18n.module.platform.api.stubs", + ], +} + +java_library { name: "legacy.core.platform.api.stubs", visibility: core_platform_visibility, + defaults: [ + "core.platform.api.stubs.defaults", + ], + static_libs: [ + "legacy.core.platform.api.stubs.from-source", + ], + product_variables: { + build_from_text_stub: { + static_libs: [ + "stable.core.platform.api.stubs.from-text", + ], + exclude_static_libs: [ + "stable.core.platform.api.stubs.from-source", + ], + }, + }, +} + +java_defaults { + name: "core.platform.api.stubs.defaults", hostdex: true, compile_dex: true, sdk_version: "none", system_modules: "none", - static_libs: [ - "art.module.public.api.stubs.module_lib", - "conscrypt.module.platform.api.stubs", - "legacy.i18n.module.platform.api.stubs", - ], patch_module: "java.base", } @@ -233,20 +287,38 @@ java_library { } java_library { - name: "stable.core.platform.api.stubs", + name: "stable.core.platform.api.stubs.from-source", visibility: core_platform_visibility, - hostdex: true, - compile_dex: true, - - sdk_version: "none", - system_modules: "none", + defaults: [ + "core.platform.api.stubs.defaults", + ], static_libs: [ "art.module.public.api.stubs.module_lib", // conscrypt only has a stable version, so it is okay to depend on it here: "conscrypt.module.platform.api.stubs", "stable.i18n.module.platform.api.stubs", ], - patch_module: "java.base", +} + +java_library { + name: "stable.core.platform.api.stubs", + visibility: core_platform_visibility, + defaults: [ + "core.platform.api.stubs.defaults", + ], + static_libs: [ + "stable.core.platform.api.stubs.from-source", + ], + product_variables: { + build_from_text_stub: { + static_libs: [ + "stable.core.platform.api.stubs.from-text", + ], + exclude_static_libs: [ + "stable.core.platform.api.stubs.from-source", + ], + }, + }, } // Same as stable.core.platform.api.stubs, but android annotations are diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index 116c833e0..35f60979f 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -816,7 +816,7 @@ func buildBootImageVariant(ctx android.ModuleContext, image *bootImageVariant, p cmd.FlagWithArg("--instruction-set-features=", global.InstructionSetFeatures[arch]) } - if global.EnableUffdGc { + if global.EnableUffdGc && image.target.Os == android.Android { cmd.Flag("--runtime-arg").Flag("-Xgc:CMC") } diff --git a/java/droidstubs.go b/java/droidstubs.go index 8a521aabb..151c94a43 100644 --- a/java/droidstubs.go +++ b/java/droidstubs.go @@ -535,6 +535,14 @@ func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersi // b/223382732 FlagWithArg("--hide ", "ChangedDefault") + // Force metalava to ignore classes on the classpath when an API file contains missing classes. + // See b/285140653 for more information. + cmd.FlagWithArg("--api-class-resolution ", "api") + + // Force metalava to sort overloaded methods by their order in the source code. + // See b/285312164 for more information. + cmd.FlagWithArg("--api-overloaded-method-order ", "source") + return cmd } diff --git a/java/fuzz.go b/java/fuzz.go index 5dfaacfb3..b3c2fd47c 100644 --- a/java/fuzz.go +++ b/java/fuzz.go @@ -30,8 +30,12 @@ import ( const ( hostString = "host" targetString = "target" + deviceString = "device" ) +// Any shared libs for these deps will also be packaged +var artDeps = []string{"libdl_android"} + func init() { RegisterJavaFuzzBuildComponents(android.InitRegistrationContext) } @@ -78,7 +82,18 @@ func JavaFuzzFactory() android.Module { } func (j *JavaFuzzTest) DepsMutator(ctx android.BottomUpMutatorContext) { + if j.Os().Class.String() == deviceString { + j.testProperties.Jni_libs = append(j.testProperties.Jni_libs, artDeps...) + } + if len(j.testProperties.Jni_libs) > 0 { + if j.fuzzPackagedModule.FuzzProperties.Fuzz_config == nil { + config := &fuzz.FuzzConfig{} + j.fuzzPackagedModule.FuzzProperties.Fuzz_config = config + } + // this will be used by the ingestion pipeline to determine the version + // of jazzer to add to the fuzzer package + j.fuzzPackagedModule.FuzzProperties.Fuzz_config.IsJni = proptools.BoolPtr(true) for _, target := range ctx.MultiTargets() { sharedLibVariations := append(target.Variations(), blueprint.Variation{Mutator: "link", Variation: "shared"}) ctx.AddFarVariationDependencies(sharedLibVariations, jniLibTag, j.testProperties.Jni_libs...) diff --git a/java/hiddenapi_modular.go b/java/hiddenapi_modular.go index e54275b88..da9c9970a 100644 --- a/java/hiddenapi_modular.go +++ b/java/hiddenapi_modular.go @@ -236,12 +236,12 @@ func hiddenAPIComputeMonolithicStubLibModules(config android.Config) map[*Hidden testStubModules = append(testStubModules, "sdk_test_current_android") } else { // Use stub modules built from source - publicStubModules = append(publicStubModules, android.SdkPublic.JavaLibraryName(config)) - systemStubModules = append(systemStubModules, android.SdkSystem.JavaLibraryName(config)) - testStubModules = append(testStubModules, android.SdkTest.JavaLibraryName(config)) + publicStubModules = append(publicStubModules, android.SdkPublic.DefaultJavaLibraryName()) + systemStubModules = append(systemStubModules, android.SdkSystem.DefaultJavaLibraryName()) + testStubModules = append(testStubModules, android.SdkTest.DefaultJavaLibraryName()) } // We do not have prebuilts of the core platform api yet - corePlatformStubModules = append(corePlatformStubModules, android.JavaApiLibraryName(config, "legacy.core.platform.api.stubs")) + corePlatformStubModules = append(corePlatformStubModules, "legacy.core.platform.api.stubs") // Allow products to define their own stubs for custom product jars that apps can use. publicStubModules = append(publicStubModules, config.ProductHiddenAPIStubs()...) diff --git a/java/java.go b/java/java.go index aa9f936d0..a8793fe87 100644 --- a/java/java.go +++ b/java/java.go @@ -936,6 +936,10 @@ type TestOptions struct { // Extra <option> tags to add to the auto generated test xml file. The "key" // is optional in each of these. Tradefed_options []tradefed.Option + + // Extra <option> tags to add to the auto generated test xml file under the test runner, e.g., AndroidJunitTest. + // The "key" is optional in each of these. + Test_runner_options []tradefed.Option } type testProperties struct { @@ -1218,6 +1222,7 @@ func (j *Test) generateAndroidBuildActionsWithConfig(ctx android.ModuleContext, TestSuites: j.testProperties.Test_suites, Config: configs, OptionsForAutogenerated: j.testProperties.Test_options.Tradefed_options, + TestRunnerOptions: j.testProperties.Test_options.Test_runner_options, AutoGenConfig: j.testProperties.Auto_gen_config, UnitTest: j.testProperties.Test_options.Unit_test, DeviceTemplate: "${JavaTestConfigTemplate}", @@ -1416,6 +1421,8 @@ func TestHostFactory() android.Module { nil, nil) + android.InitBazelModule(module) + InitJavaModuleMultiTargets(module, android.HostSupported) return module @@ -1728,6 +1735,14 @@ func metalavaStubCmd(ctx android.ModuleContext, rule *android.RuleBuilder, FlagWithArg("--hide ", "InvalidNullabilityOverride"). FlagWithArg("--hide ", "ChangedDefault") + // Force metalava to ignore classes on the classpath when an API file contains missing classes. + // See b/285140653 for more information. + cmd.FlagWithArg("--api-class-resolution ", "api") + + // Force metalava to sort overloaded methods by their order in the source code. + // See b/285312164 for more information. + cmd.FlagWithArg("--api-overloaded-method-order ", "source") + return cmd } @@ -2798,6 +2813,14 @@ type bp2BuildJavaInfo struct { hasKotlin bool } +// Replaces //a/b/my_xsd_config with //a/b/my_xsd_config-java +func xsdConfigJavaTarget(ctx android.BazelConversionPathContext, mod blueprint.Module) string { + callback := func(xsd android.XsdConfigBp2buildTargets) string { + return xsd.JavaBp2buildTargetName() + } + return android.XsdConfigBp2buildTarget(ctx, mod, callback) +} + // convertLibraryAttrsBp2Build returns a javaCommonAttributes struct with // converted attributes shared across java_* modules and a bp2BuildJavaInfo struct // which has other non-attribute information needed for bp2build conversion @@ -2812,8 +2835,15 @@ func (m *Library) convertLibraryAttrsBp2Build(ctx android.TopDownMutatorContext) for axis, configToProps := range archVariantProps { for config, _props := range configToProps { if archProps, ok := _props.(*CommonProperties); ok { - archSrcs := android.BazelLabelForModuleSrcExcludes(ctx, archProps.Srcs, archProps.Exclude_srcs) + srcsNonXsd, srcsXsd := android.PartitionXsdSrcs(ctx, archProps.Srcs) + excludeSrcsNonXsd, _ := android.PartitionXsdSrcs(ctx, archProps.Exclude_srcs) + archSrcs := android.BazelLabelForModuleSrcExcludes(ctx, srcsNonXsd, excludeSrcsNonXsd) srcs.SetSelectValue(axis, config, archSrcs) + + // Add to static deps + xsdJavaConfigLibraryLabels := android.BazelLabelForModuleDepsWithFn(ctx, srcsXsd, xsdConfigJavaTarget) + staticDeps.Append(xsdJavaConfigLibraryLabels) + } } } @@ -3114,23 +3144,89 @@ func javaBinaryHostBp2Build(ctx android.TopDownMutatorContext, m *Binary) { return } - libName := m.Name() + "_lib" + libInfo := libraryCreationInfo{ + deps: deps, + attrs: commonAttrs, + baseName: m.Name(), + hasKotlin: bp2BuildInfo.hasKotlin, + } + libName := createLibraryTarget(ctx, libInfo) + binAttrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}}) + + // Create the BazelTargetModule. + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, binAttrs) +} + +type javaTestHostAttributes struct { + *javaCommonAttributes + Deps bazel.LabelListAttribute + Runtime_deps bazel.LabelListAttribute +} + +// javaTestHostBp2Build is for java_test_host bp2build. +func javaTestHostBp2Build(ctx android.TopDownMutatorContext, m *TestHost) { + commonAttrs, bp2BuildInfo := m.convertLibraryAttrsBp2Build(ctx) + depLabels := bp2BuildInfo.DepLabels + + deps := depLabels.Deps + deps.Append(depLabels.StaticDeps) + + var runtimeDeps bazel.LabelListAttribute + attrs := &javaTestHostAttributes{ + Runtime_deps: runtimeDeps, + } + props := bazel.BazelTargetModuleProperties{ + Rule_class: "java_test", + Bzl_load_location: "//build/bazel/rules/java:test.bzl", + } + + if commonAttrs.Srcs.IsEmpty() { + // if there are no sources, then the dependencies can only be used at runtime + attrs.Runtime_deps = deps + attrs.javaCommonAttributes = commonAttrs + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs) + return + } + + libInfo := libraryCreationInfo{ + deps: deps, + attrs: commonAttrs, + baseName: m.Name(), + hasKotlin: bp2BuildInfo.hasKotlin, + } + libName := createLibraryTarget(ctx, libInfo) + attrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}}) + + // Create the BazelTargetModule. + ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, attrs) +} + +// libraryCreationInfo encapsulates the info needed to create java_library target from +// java_binary_host or java_test_host. +type libraryCreationInfo struct { + deps bazel.LabelListAttribute + attrs *javaCommonAttributes + baseName string + hasKotlin bool +} + +// helper function that creates java_library target from java_binary_host or java_test_host, +// and returns the library target name, +func createLibraryTarget(ctx android.TopDownMutatorContext, libInfo libraryCreationInfo) string { + libName := libInfo.baseName + "_lib" var libProps bazel.BazelTargetModuleProperties - if bp2BuildInfo.hasKotlin { + if libInfo.hasKotlin { libProps = ktJvmLibraryBazelTargetModuleProperties() } else { libProps = javaLibraryBazelTargetModuleProperties() } libAttrs := &javaLibraryAttributes{ - Deps: deps, - javaCommonAttributes: commonAttrs, + Deps: libInfo.deps, + javaCommonAttributes: libInfo.attrs, } ctx.CreateBazelTargetModule(libProps, android.CommonAttributes{Name: libName}, libAttrs) - binAttrs.Runtime_deps.Add(&bazel.LabelAttribute{Value: &bazel.Label{Label: ":" + libName}}) - - // Create the BazelTargetModule. - ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: m.Name()}, binAttrs) + return libName } type bazelJavaImportAttributes struct { diff --git a/java/java_test.go b/java/java_test.go index ea89e6eb8..561b187d0 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -2298,3 +2298,58 @@ java_test_host { t.Errorf("Expected args[\"extraConfigs\"] to equal %q, was %q", expected, args["extraConfigs"]) } } + +func TestTestRunnerOptions(t *testing.T) { + result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, ` +java_test_host { + name: "foo", + test_options: { + test_runner_options: [ + { + name: "test-timeout", + value: "10m" + } + ] + } +} +`) + + buildOS := result.Config.BuildOS.String() + args := result.ModuleForTests("foo", buildOS+"_common"). + Output("out/soong/.intermediates/foo/" + buildOS + "_common/foo.config").Args + expected := proptools.NinjaAndShellEscape("<option name=\"test-timeout\" value=\"10m\" />\\n ") + if args["extraTestRunnerConfigs"] != expected { + t.Errorf("Expected args[\"extraTestRunnerConfigs\"] to equal %q, was %q", expected, args["extraTestRunnerConfigs"]) + } +} + +func TestJavaExcludeStaticLib(t *testing.T) { + ctx, _ := testJava(t, ` + java_library { + name: "bar", + } + java_library { + name: "foo", + } + java_library { + name: "baz", + static_libs: [ + "foo", + "bar", + ], + exclude_static_libs: [ + "bar", + ], + } + `) + + // "bar" not included as dependency of "baz" + CheckModuleDependencies(t, ctx, "baz", "android_common", []string{ + `core-lambda-stubs`, + `ext`, + `foo`, + `framework`, + `stable-core-platform-api-stubs-system-modules`, + `stable.core.platform.api.stubs`, + }) +} diff --git a/java/sdk.go b/java/sdk.go index 7fa604fdb..7699aabe0 100644 --- a/java/sdk.go +++ b/java/sdk.go @@ -151,7 +151,7 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext android.SdkContext) systemModules := android.JavaApiLibraryName(ctx.Config(), fmt.Sprintf("core-%s-stubs-system-modules", systemModulesKind)) return sdkDep{ useModule: true, - bootclasspath: []string{module, android.JavaApiLibraryName(ctx.Config(), config.DefaultLambdaStubsLibrary)}, + bootclasspath: []string{module, config.DefaultLambdaStubsLibrary}, systemModules: systemModules, java9Classpath: []string{module}, frameworkResModule: "framework-res", @@ -193,20 +193,20 @@ func decodeSdkDep(ctx android.EarlyModuleContext, sdkContext android.SdkContext) noFrameworksLibs: true, } case android.SdkPublic, android.SdkSystem, android.SdkTest: - return toModule(sdkVersion.Kind.JavaLibraryName(ctx.Config()), sdkFrameworkAidlPath(ctx)) + return toModule(sdkVersion.Kind.DefaultJavaLibraryName(), sdkFrameworkAidlPath(ctx)) case android.SdkCore: return sdkDep{ useModule: true, - bootclasspath: []string{android.SdkCore.JavaLibraryName(ctx.Config()), android.JavaApiLibraryName(ctx.Config(), config.DefaultLambdaStubsLibrary)}, + bootclasspath: []string{android.SdkCore.DefaultJavaLibraryName(), config.DefaultLambdaStubsLibrary}, systemModules: android.JavaApiLibraryName(ctx.Config(), "core-public-stubs-system-modules"), noFrameworksLibs: true, } case android.SdkModule: // TODO(146757305): provide .apk and .aidl that have more APIs for modules - return toModule(sdkVersion.Kind.JavaLibraryName(ctx.Config()), nonUpdatableFrameworkAidlPath(ctx)) + return toModule(sdkVersion.Kind.DefaultJavaLibraryName(), nonUpdatableFrameworkAidlPath(ctx)) case android.SdkSystemServer: // TODO(146757305): provide .apk and .aidl that have more APIs for modules - return toModule(sdkVersion.Kind.JavaLibraryName(ctx.Config()), sdkFrameworkAidlPath(ctx)) + return toModule(sdkVersion.Kind.DefaultJavaLibraryName(), sdkFrameworkAidlPath(ctx)) default: panic(fmt.Errorf("invalid sdk %q", sdkVersion.Raw)) } @@ -269,9 +269,9 @@ func (sdkSingleton) GenerateBuildActions(ctx android.SingletonContext) { // Create framework.aidl by extracting anything that implements android.os.Parcelable from the SDK stubs modules. func createSdkFrameworkAidl(ctx android.SingletonContext) { stubsModules := []string{ - android.SdkPublic.JavaLibraryName(ctx.Config()), - android.SdkTest.JavaLibraryName(ctx.Config()), - android.SdkSystem.JavaLibraryName(ctx.Config()), + android.SdkPublic.DefaultJavaLibraryName(), + android.SdkTest.DefaultJavaLibraryName(), + android.SdkSystem.DefaultJavaLibraryName(), } combinedAidl := sdkFrameworkAidlPath(ctx) @@ -286,7 +286,7 @@ func createSdkFrameworkAidl(ctx android.SingletonContext) { // Creates a version of framework.aidl for the non-updatable part of the platform. func createNonUpdatableFrameworkAidl(ctx android.SingletonContext) { - stubsModules := []string{android.SdkModule.JavaLibraryName(ctx.Config())} + stubsModules := []string{android.SdkModule.DefaultJavaLibraryName()} combinedAidl := nonUpdatableFrameworkAidlPath(ctx) tempPath := tempPathForRestat(ctx, combinedAidl) diff --git a/rust/builder.go b/rust/builder.go index 0aa2225f7..0dfaef49f 100644 --- a/rust/builder.go +++ b/rust/builder.go @@ -261,7 +261,7 @@ func transformSrctoCrate(ctx ModuleContext, main android.Path, deps PathDeps, fl // Disallow experimental features modulePath := android.PathForModuleSrc(ctx).String() if !(android.IsThirdPartyPath(modulePath) || strings.HasPrefix(modulePath, "prebuilts")) { - rustcFlags = append(rustcFlags, "-Zallow-features=\"custom_inner_attributes,mixed_integer_ops\"") + rustcFlags = append(rustcFlags, "-Zallow-features=\"\"") } // Collect linker flags diff --git a/rust/config/global.go b/rust/config/global.go index 748bb3d2f..60acc6e28 100644 --- a/rust/config/global.go +++ b/rust/config/global.go @@ -51,9 +51,6 @@ var ( // Use v0 mangling to distinguish from C++ symbols "-C symbol-mangling-version=v0", "--color always", - // TODO (b/267698452): Temporary workaround until the "no unstable - // features" policy is enforced. - "-A stable-features", "-Zdylib-lto", } diff --git a/tests/apex_comparison_tests.sh b/tests/apex_comparison_tests.sh index e350323f3..889306008 100755 --- a/tests/apex_comparison_tests.sh +++ b/tests/apex_comparison_tests.sh @@ -29,7 +29,7 @@ fi # Test Setup ############ -OUTPUT_DIR="$(mktemp -d tmp.XXXXXX)" +OUTPUT_DIR="$(mktemp -d $(pwd)/tmp.XXXXXX)" SOONG_OUTPUT_DIR="$OUTPUT_DIR/soong" BAZEL_OUTPUT_DIR="$OUTPUT_DIR/bazel" @@ -45,6 +45,12 @@ function cleanup { call_bazel clean rm -rf "${OUTPUT_DIR}" } + +function deapexer() { + DEBUGFS_PATH="$(realpath $(call_bazel cquery --config=bp2build --config=linux_x86_64 --config=ci --output=files //external/e2fsprogs/debugfs))" + call_bazel run --config=bp2build //system/apex/tools:deapexer -- --debugfs_path=$DEBUGFS_PATH $@ +} + trap cleanup EXIT ########### @@ -72,10 +78,7 @@ BAZEL_TZDATA="$(realpath $(call_bazel cquery --config=bp2build --config=android BAZEL_MINIMAL="$(realpath $(call_bazel cquery --config=bp2build --config=android --config=ci --output=files //build/bazel/examples/apex/minimal:build.bazel.examples.apex.minimal))" # # Build debugfs separately, as it's not a dep of apexer, but needs to be an explicit arg. -call_bazel build --config=bp2build --config=linux_x86_64 //external/e2fsprogs/debugfs //system/apex/tools:deapexer -DEBUGFS_PATH="$(realpath $(call_bazel cquery --config=bp2build --config=linux_x86_64 --config=ci --output=files //external/e2fsprogs/debugfs))" -DEAPEXER="bazel-bin/system/apex/tools/deapexer" -DEAPEXER="$DEAPEXER --debugfs_path=$DEBUGFS_PATH" +call_bazel build --config=bp2build --config=linux_x86_64 //external/e2fsprogs/debugfs ####### # Tests @@ -91,8 +94,8 @@ function compare_deapexer_list() { local SOONG_LIST="$OUTPUT_DIR/soong.list" local BAZEL_LIST="$OUTPUT_DIR/bazel.list" - $DEAPEXER list "$SOONG_APEX" > "$SOONG_LIST" - $DEAPEXER list "$BAZEL_APEX" > "$BAZEL_LIST" + deapexer list "$SOONG_APEX" > "$SOONG_LIST" + deapexer list "$BAZEL_APEX" > "$BAZEL_LIST" if cmp -s "$SOONG_LIST" "$BAZEL_LIST" then diff --git a/tests/dcla_apex_comparison_test.sh b/tests/dcla_apex_comparison_test.sh index 667dde0b7..e3c189f1c 100755 --- a/tests/dcla_apex_comparison_test.sh +++ b/tests/dcla_apex_comparison_test.sh @@ -55,6 +55,8 @@ DCLA_LIBS=( libc++.so libcrypto.so libcutils.so + libstagefright_flacdec.so + libutils.so ) if [[ -z ${OUT_DIR+x} ]]; then diff --git a/tests/genrule_sandbox_test.sh b/tests/genrule_sandbox_test.sh new file mode 100755 index 000000000..21b476bad --- /dev/null +++ b/tests/genrule_sandbox_test.sh @@ -0,0 +1,111 @@ +#!/bin/bash + +# Copyright (C) 2023 The Android Open Source Project +# +# 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. + +set -e + +# Build the given genrule modules with GENRULE_SANDBOXING enabled and disabled, +# then compare the output of the modules and report result. + +function die() { format=$1; shift; printf >&2 "$format\n" $@; exit 1; } + +function usage() { + die "usage: ${0##*/} <-t lunch_target> [module]..." +} + +if [ ! -e "build/make/core/Makefile" ]; then + die "$0 must be run from the top of the Android source tree." +fi + +declare TARGET= +while getopts "t:" opt; do + case $opt in + t) + TARGET=$OPTARG ;; + *) usage ;; + esac +done + +shift $((OPTIND-1)) +MODULES="$@" + +source build/envsetup.sh + +if [[ -n $TARGET ]]; then + lunch $TARGET +fi + +if [[ -z ${OUT_DIR+x} ]]; then + OUT_DIR="out" +fi + +OUTPUT_DIR="$(mktemp -d tmp.XXXXXX)" +PASS=true + +function cleanup { + if [ $PASS = true ]; then + rm -rf "${OUTPUT_DIR}" + fi +} +trap cleanup EXIT + +declare -A GEN_PATH_MAP + +function find_gen_paths() { + for module in $MODULES; do + module_path=$(pathmod "$module") + package_path=${module_path#$ANDROID_BUILD_TOP} + gen_path=$OUT_DIR/soong/.intermediates$package_path/$module + GEN_PATH_MAP[$module]=$gen_path + done +} + +function store_outputs() { + local dir=$1; shift + + for module in $MODULES; do + dest_dir=$dir/${module} + mkdir -p $dest_dir + gen_path=${GEN_PATH_MAP[$module]} + cp -r $gen_path $dest_dir + done +} + +function cmp_outputs() { + local dir1=$1; shift + local dir2=$1; shift + + for module in $MODULES; do + if ! diff -rq --exclude=genrule.sbox.textproto $dir1/$module $dir2/$module; then + PASS=false + echo "$module differ" + fi + done + if [ $PASS = true ]; then + echo "Test passed" + fi +} + +if [ ! -f "$ANDROID_PRODUCT_OUT/module-info.json" ]; then + refreshmod +fi + +find_gen_paths +m --skip-soong-tests GENRULE_SANDBOXING=true "${MODULES[@]}" +store_outputs "$OUTPUT_DIR/sandbox" +m --skip-soong-tests GENRULE_SANDBOXING=false "${MODULES[@]}" +store_outputs "$OUTPUT_DIR/non_sandbox" + +cmp_outputs "$OUTPUT_DIR/non_sandbox" "$OUTPUT_DIR/sandbox" diff --git a/tradefed/autogen.go b/tradefed/autogen.go index 49b09afea..3c55c51e1 100644 --- a/tradefed/autogen.go +++ b/tradefed/autogen.go @@ -40,9 +40,9 @@ func getTestConfig(ctx android.ModuleContext, prop *string) android.Path { } var autogenTestConfig = pctx.StaticRule("autogenTestConfig", blueprint.RuleParams{ - Command: "sed 's&{MODULE}&${name}&g;s&{EXTRA_CONFIGS}&'${extraConfigs}'&g;s&{OUTPUT_FILENAME}&'${outputFileName}'&g;s&{TEST_INSTALL_BASE}&'${testInstallBase}'&g' $template > $out", + Command: "sed 's&{MODULE}&${name}&g;s&{EXTRA_CONFIGS}&'${extraConfigs}'&g;s&{EXTRA_TEST_RUNNER_CONFIGS}&'${extraTestRunnerConfigs}'&g;s&{OUTPUT_FILENAME}&'${outputFileName}'&g;s&{TEST_INSTALL_BASE}&'${testInstallBase}'&g' $template > $out", CommandDeps: []string{"$template"}, -}, "name", "template", "extraConfigs", "outputFileName", "testInstallBase") +}, "name", "template", "extraConfigs", "outputFileName", "testInstallBase", "extraTestRunnerConfigs") func testConfigPath(ctx android.ModuleContext, prop *string, testSuites []string, autoGenConfig *bool, testConfigTemplateProp *string) (path android.Path, autogenPath android.WritablePath) { p := getTestConfig(ctx, prop) @@ -107,7 +107,7 @@ func (ob Object) Config() string { } -func autogenTemplate(ctx android.ModuleContext, name string, output android.WritablePath, template string, configs []Config, outputFileName string, testInstallBase string) { +func autogenTemplate(ctx android.ModuleContext, name string, output android.WritablePath, template string, configs []Config, testRunnerConfigs []Option, outputFileName string, testInstallBase string) { if template == "" { ctx.ModuleErrorf("Empty template") } @@ -118,16 +118,27 @@ func autogenTemplate(ctx android.ModuleContext, name string, output android.Writ extraConfigs := strings.Join(configStrings, fmt.Sprintf("\\n%s", test_xml_indent)) extraConfigs = proptools.NinjaAndShellEscape(extraConfigs) + var testRunnerConfigStrings []string + for _, config := range testRunnerConfigs { + testRunnerConfigStrings = append(testRunnerConfigStrings, config.Config()) + } + extraTestRunnerConfigs := strings.Join(testRunnerConfigStrings, fmt.Sprintf("\\n%s%s", test_xml_indent, test_xml_indent)) + if len(extraTestRunnerConfigs) > 0 { + extraTestRunnerConfigs += fmt.Sprintf("\\n%s%s", test_xml_indent, test_xml_indent) + } + extraTestRunnerConfigs = proptools.NinjaAndShellEscape(extraTestRunnerConfigs) + ctx.Build(pctx, android.BuildParams{ Rule: autogenTestConfig, Description: "test config", Output: output, Args: map[string]string{ - "name": name, - "template": template, - "extraConfigs": extraConfigs, - "outputFileName": outputFileName, - "testInstallBase": testInstallBase, + "name": name, + "template": template, + "extraConfigs": extraConfigs, + "outputFileName": outputFileName, + "testInstallBase": testInstallBase, + "extraTestRunnerConfigs": extraTestRunnerConfigs, }, }) } @@ -142,6 +153,7 @@ type AutoGenTestConfigOptions struct { TestSuites []string Config []Config OptionsForAutogenerated []Option + TestRunnerOptions []Option AutoGenConfig *bool UnitTest *bool TestInstallBase string @@ -155,6 +167,7 @@ func AutoGenTestConfig(ctx android.ModuleContext, options AutoGenTestConfigOptio for _, c := range options.OptionsForAutogenerated { configs = append(configs, c) } + testRunnerConfigs := append([]Option{}, options.TestRunnerOptions...) name := options.Name if name == "" { name = ctx.ModuleName() @@ -163,15 +176,15 @@ func AutoGenTestConfig(ctx android.ModuleContext, options AutoGenTestConfigOptio if autogenPath != nil { templatePath := getTestConfigTemplate(ctx, options.TestConfigTemplateProp) if templatePath.Valid() { - autogenTemplate(ctx, name, autogenPath, templatePath.String(), configs, options.OutputFileName, options.TestInstallBase) + autogenTemplate(ctx, name, autogenPath, templatePath.String(), configs, testRunnerConfigs, options.OutputFileName, options.TestInstallBase) } else { if ctx.Device() { - autogenTemplate(ctx, name, autogenPath, options.DeviceTemplate, configs, options.OutputFileName, options.TestInstallBase) + autogenTemplate(ctx, name, autogenPath, options.DeviceTemplate, configs, testRunnerConfigs, options.OutputFileName, options.TestInstallBase) } else { if Bool(options.UnitTest) { - autogenTemplate(ctx, name, autogenPath, options.HostUnitTestTemplate, configs, options.OutputFileName, options.TestInstallBase) + autogenTemplate(ctx, name, autogenPath, options.HostUnitTestTemplate, configs, testRunnerConfigs, options.OutputFileName, options.TestInstallBase) } else { - autogenTemplate(ctx, name, autogenPath, options.HostTemplate, configs, options.OutputFileName, options.TestInstallBase) + autogenTemplate(ctx, name, autogenPath, options.HostTemplate, configs, testRunnerConfigs, options.OutputFileName, options.TestInstallBase) } } } diff --git a/ui/build/cleanbuild.go b/ui/build/cleanbuild.go index ee5332735..41cb5ab6d 100644 --- a/ui/build/cleanbuild.go +++ b/ui/build/cleanbuild.go @@ -135,6 +135,7 @@ func installClean(ctx Context, config Config) { productOut("obj/NOTICE_FILES"), productOut("obj/PACKAGING"), productOut("ramdisk"), + productOut("ramdisk_16k"), productOut("debug_ramdisk"), productOut("vendor_ramdisk"), productOut("vendor_debug_ramdisk"), diff --git a/ui/build/config.go b/ui/build/config.go index 1698e63b4..bc0ab33d9 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -17,6 +17,7 @@ package build import ( "context" "encoding/json" + "errors" "fmt" "io/ioutil" "math/rand" @@ -140,6 +141,9 @@ const ( EXTERNAL_FILE // ninja uses a prioritized module list from Soong HINT_FROM_SOONG + // If ninja log exists, use NINJA_LOG, if not, use HINT_FROM_SOONG instead. + // We can assume it is an incremental build if ninja log exists. + DEFAULT ) const srcDirFileCheck = "build/soong/root.bp" @@ -316,8 +320,9 @@ func UploadOnlyConfig(ctx Context, args ...string) Config { func NewConfig(ctx Context, args ...string) Config { ret := &configImpl{ - environ: OsEnvironment(), - sandboxConfig: &SandboxConfig{}, + environ: OsEnvironment(), + sandboxConfig: &SandboxConfig{}, + ninjaWeightListSource: DEFAULT, } // Default matching ninja @@ -328,8 +333,21 @@ func NewConfig(ctx Context, args ...string) Config { ret.parseArgs(ctx, args) if ret.ninjaWeightListSource == HINT_FROM_SOONG { - ret.environ.Set("SOONG_GENERATES_NINJA_HINT", "true") + ret.environ.Set("SOONG_GENERATES_NINJA_HINT", "always") + } else if ret.ninjaWeightListSource == DEFAULT { + defaultNinjaWeightListSource := NINJA_LOG + if _, err := os.Stat(filepath.Join(ret.OutDir(), ninjaLogFileName)); errors.Is(err, os.ErrNotExist) { + ctx.Verboseln("$OUT/.ninja_log doesn't exist, use HINT_FROM_SOONG instead") + defaultNinjaWeightListSource = HINT_FROM_SOONG + } else { + ctx.Verboseln("$OUT/.ninja_log exist, use NINJA_LOG") + } + ret.ninjaWeightListSource = defaultNinjaWeightListSource + // soong_build generates ninja hint depending on ninja log existence. + // Set it "depend" to avoid soong re-run due to env variable change. + ret.environ.Set("SOONG_GENERATES_NINJA_HINT", "depend") } + // Make sure OUT_DIR is set appropriately if outDir, ok := ret.environ.Get("OUT_DIR"); ok { ret.environ.Set("OUT_DIR", filepath.Clean(outDir)) @@ -1729,6 +1747,16 @@ func (c *configImpl) IsPersistentBazelEnabled() bool { return c.Environment().IsEnvTrue("USE_PERSISTENT_BAZEL") } +// GetBazeliskBazelVersion returns the Bazel version to use for this build, +// or the empty string if the current canonical prod Bazel should be used. +// This environment variable should only be set to debug the build system. +// The Bazel version, if set, will be passed to Bazelisk, and Bazelisk will +// handle downloading and invoking the correct Bazel binary. +func (c *configImpl) GetBazeliskBazelVersion() string { + value, _ := c.Environment().Get("USE_BAZEL_VERSION") + return value +} + func (c *configImpl) BazelModulesForceEnabledByFlag() string { return c.bazelForceEnabledModules } diff --git a/ui/build/ninja.go b/ui/build/ninja.go index 5d56531b2..61aaad86b 100644 --- a/ui/build/ninja.go +++ b/ui/build/ninja.go @@ -35,48 +35,6 @@ const ( ninjaWeightListFileName = ".ninja_weight_list" ) -func useNinjaBuildLog(ctx Context, config Config, cmd *Cmd) { - ninjaLogFile := filepath.Join(config.OutDir(), ninjaLogFileName) - data, err := os.ReadFile(ninjaLogFile) - var outputBuilder strings.Builder - if err == nil { - lines := strings.Split(strings.TrimSpace(string(data)), "\n") - // ninja log: <start> <end> <restat> <name> <cmdhash> - // ninja weight list: <name>,<end-start+1> - for _, line := range lines { - if strings.HasPrefix(line, "#") { - continue - } - fields := strings.Split(line, "\t") - path := fields[3] - start, err := strconv.Atoi(fields[0]) - if err != nil { - continue - } - end, err := strconv.Atoi(fields[1]) - if err != nil { - continue - } - outputBuilder.WriteString(path) - outputBuilder.WriteString(",") - outputBuilder.WriteString(strconv.Itoa(end-start+1) + "\n") - } - } else { - // If there is no ninja log file, just pass empty ninja weight list. - // Because it is still efficient with critical path calculation logic even without weight. - ctx.Verbosef("There is an error during reading ninja log, so ninja will use empty weight list: %s", err) - } - - weightListFile := filepath.Join(config.OutDir(), ninjaWeightListFileName) - - err = os.WriteFile(weightListFile, []byte(outputBuilder.String()), 0644) - if err == nil { - cmd.Args = append(cmd.Args, "-o", "usesweightlist="+weightListFile) - } else { - ctx.Panicf("Could not write ninja weight list file %s", err) - } -} - // Constructs and runs the Ninja command line with a restricted set of // environment variables. It's important to restrict the environment Ninja runs // for hermeticity reasons, and to avoid spurious rebuilds. @@ -131,7 +89,7 @@ func runNinjaForBuild(ctx Context, config Config) { switch config.NinjaWeightListSource() { case NINJA_LOG: - useNinjaBuildLog(ctx, config, cmd) + cmd.Args = append(cmd.Args, "-o", "usesninjalogasweightlist=yes") case EVENLY_DISTRIBUTED: // pass empty weight list means ninja considers every tasks's weight as 1(default value). cmd.Args = append(cmd.Args, "-o", "usesweightlist=/dev/null") diff --git a/ui/build/paths/config.go b/ui/build/paths/config.go index b3092eaf1..b3e871fc7 100644 --- a/ui/build/paths/config.go +++ b/ui/build/paths/config.go @@ -86,27 +86,29 @@ func GetConfig(name string) PathConfig { // This list specifies whether a particular binary from $PATH is allowed to be // run during the build. For more documentation, see path_interposer.go . var Configuration = map[string]PathConfig{ - "bash": Allowed, - "dd": Allowed, - "diff": Allowed, - "dlv": Allowed, - "expr": Allowed, - "fuser": Allowed, - "getopt": Allowed, - "git": Allowed, - "hexdump": Allowed, - "jar": Allowed, - "java": Allowed, - "javap": Allowed, - "lsof": Allowed, - "openssl": Allowed, - "pstree": Allowed, - "rsync": Allowed, - "sh": Allowed, - "stubby": Allowed, - "tr": Allowed, - "unzip": Allowed, - "zip": Allowed, + "bash": Allowed, + "dd": Allowed, + "diff": Allowed, + "dlv": Allowed, + "expr": Allowed, + "fuser": Allowed, + "gcert": Allowed, + "getopt": Allowed, + "git": Allowed, + "hexdump": Allowed, + "jar": Allowed, + "java": Allowed, + "javap": Allowed, + "lsof": Allowed, + "openssl": Allowed, + "prodcertstatus": Allowed, + "pstree": Allowed, + "rsync": Allowed, + "sh": Allowed, + "stubby": Allowed, + "tr": Allowed, + "unzip": Allowed, + "zip": Allowed, // Host toolchain is removed. In-tree toolchain should be used instead. // GCC also can't find cc1 with this implementation. diff --git a/ui/build/soong.go b/ui/build/soong.go index e24abddd1..b14208eb4 100644 --- a/ui/build/soong.go +++ b/ui/build/soong.go @@ -537,7 +537,7 @@ func runSoong(ctx Context, config Config) { defer ctx.EndTrace() if config.IsPersistentBazelEnabled() { - bazelProxy := bazel.NewProxyServer(ctx.Logger, config.OutDir(), filepath.Join(config.SoongOutDir(), "workspace")) + bazelProxy := bazel.NewProxyServer(ctx.Logger, config.OutDir(), filepath.Join(config.SoongOutDir(), "workspace"), config.GetBazeliskBazelVersion()) bazelProxy.Start() defer bazelProxy.Close() } diff --git a/ui/metrics/BUILD.bazel b/ui/metrics/BUILD.bazel index 2dc1ab633..ca39c59b1 100644 --- a/ui/metrics/BUILD.bazel +++ b/ui/metrics/BUILD.bazel @@ -23,6 +23,7 @@ py_proto_library( proto_library( name = "metrics-proto", srcs = [ + "bazel_metrics_proto/bazel_metrics.proto", "bp2build_metrics_proto/bp2build_metrics.proto", "metrics_proto/metrics.proto", ], |