diff options
45 files changed, 1215 insertions, 805 deletions
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go index fb56ee135..0c1be6e7b 100644 --- a/android/allowlists/allowlists.go +++ b/android/allowlists/allowlists.go @@ -673,6 +673,9 @@ var ( // kotlin srcs in java binary "AnalyzerKt", "trebuchet-core", + + // kotlin srcs in android_library + "renderscript_toolkit", } Bp2buildModuleTypeAlwaysConvertList = []string{ @@ -1381,5 +1384,9 @@ var ( StagingMixedBuildsEnabledList = []string{ "com.android.adbd", "adbd_test", + "adb_crypto_test", + "adb_pairing_auth_test", + "adb_pairing_connection_test", + "adb_tls_connection_test", } ) diff --git a/android/bazel_handler.go b/android/bazel_handler.go index 8d4504175..4a495f02e 100644 --- a/android/bazel_handler.go +++ b/android/bazel_handler.go @@ -233,27 +233,42 @@ func (m MockBazelContext) QueueBazelRequest(_ string, _ cqueryRequest, _ configK } func (m MockBazelContext) GetOutputFiles(label string, _ configKey) ([]string, error) { - result, _ := m.LabelToOutputFiles[label] + result, ok := m.LabelToOutputFiles[label] + if !ok { + return []string{}, fmt.Errorf("no target with label %q in LabelToOutputFiles", label) + } return result, nil } func (m MockBazelContext) GetCcInfo(label string, _ configKey) (cquery.CcInfo, error) { - result, _ := m.LabelToCcInfo[label] + result, ok := m.LabelToCcInfo[label] + if !ok { + return cquery.CcInfo{}, fmt.Errorf("no target with label %q in LabelToCcInfo", label) + } return result, nil } func (m MockBazelContext) GetPythonBinary(label string, _ configKey) (string, error) { - result, _ := m.LabelToPythonBinary[label] + result, ok := m.LabelToPythonBinary[label] + if !ok { + return "", fmt.Errorf("no target with label %q in LabelToPythonBinary", label) + } return result, nil } func (m MockBazelContext) GetApexInfo(label string, _ configKey) (cquery.ApexInfo, error) { - result, _ := m.LabelToApexInfo[label] + result, ok := m.LabelToApexInfo[label] + if !ok { + return cquery.ApexInfo{}, fmt.Errorf("no target with label %q in LabelToApexInfo", label) + } return result, nil } func (m MockBazelContext) GetCcUnstrippedInfo(label string, _ configKey) (cquery.CcUnstrippedInfo, error) { - result, _ := m.LabelToCcBinary[label] + result, ok := m.LabelToCcBinary[label] + if !ok { + return cquery.CcUnstrippedInfo{}, fmt.Errorf("no target with label %q in LabelToCcBinary", label) + } return result, nil } diff --git a/apex/androidmk.go b/apex/androidmk.go index b76f6bdd3..aadccb724 100644 --- a/apex/androidmk.go +++ b/apex/androidmk.go @@ -317,14 +317,14 @@ func (a *apexBundle) writeRequiredModules(w io.Writer, moduleNames []string) { func (a *apexBundle) androidMkForType() android.AndroidMkData { return android.AndroidMkData{ Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) { - moduleNames := []string{} apexType := a.properties.ApexType - if a.installable() { - apexName := proptools.StringDefault(a.properties.Apex_name, name) - moduleNames = a.androidMkForFiles(w, name, apexName, moduleDir, data) - } if apexType == flattenedApex { + var moduleNames []string = nil + if a.installable() { + apexName := proptools.StringDefault(a.properties.Apex_name, name) + moduleNames = a.androidMkForFiles(w, name, apexName, moduleDir, data) + } // Only image APEXes can be flattened. fmt.Fprintln(w, "\ninclude $(CLEAR_VARS) # apex.apexBundle.flat") fmt.Fprintln(w, "LOCAL_PATH :=", moduleDir) @@ -366,7 +366,7 @@ func (a *apexBundle) androidMkForType() android.AndroidMkData { } android.AndroidMkEmitAssignList(w, "LOCAL_OVERRIDES_MODULES", a.overridableProperties.Overrides) - a.writeRequiredModules(w, moduleNames) + a.writeRequiredModules(w, nil) fmt.Fprintln(w, "include $(BUILD_PREBUILT)") diff --git a/apex/apex.go b/apex/apex.go index 9485a4b0b..ad7da2716 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -1657,7 +1657,7 @@ func apexFileForRustLibrary(ctx android.BaseModuleContext, rustm *rust.Module) a return newApexFile(ctx, fileToCopy, androidMkModuleName, dirInApex, nativeSharedLib, rustm) } -func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.Module) apexFile { +func apexFileForPyBinary(ctx android.BaseModuleContext, py *python.PythonBinaryModule) apexFile { dirInApex := "bin" fileToCopy := py.HostToolPath().Path() return newApexFile(ctx, fileToCopy, py.BaseModuleName(), dirInApex, pyBinary, py) @@ -2147,7 +2147,7 @@ func (a *apexBundle) depVisitor(vctx *visitorContext, ctx android.ModuleContext, case *cc.Module: vctx.filesInfo = append(vctx.filesInfo, apexFileForExecutable(ctx, ch)) return true // track transitive dependencies - case *python.Module: + case *python.PythonBinaryModule: if ch.HostToolPath().Valid() { vctx.filesInfo = append(vctx.filesInfo, apexFileForPyBinary(ctx, ch)) } diff --git a/apex/apex_test.go b/apex/apex_test.go index 33fce7c8b..395da952f 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -526,7 +526,6 @@ func TestBasicApex(t *testing.T) { data.Custom(&builder, ab.BaseModuleName(), "TARGET_", "", data) androidMk := builder.String() - ensureContains(t, androidMk, "LOCAL_MODULE := mylib.myapex\n") ensureNotContains(t, androidMk, "LOCAL_MODULE := mylib.com.android.myapex\n") optFlags := apexRule.Args["opt_flags"] @@ -2996,7 +2995,7 @@ func TestAndroidMk_VendorApexRequired(t *testing.T) { var builder strings.Builder data.Custom(&builder, name, prefix, "", data) androidMk := builder.String() - ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := libc++.vendor.myapex:64 mylib.vendor.myapex:64 apex_manifest.pb.myapex apex_pubkey.myapex libc.vendor libm.vendor libdl.vendor\n") + ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := libc.vendor libm.vendor libdl.vendor\n") } func TestAndroidMkWritesCommonProperties(t *testing.T) { @@ -3329,17 +3328,14 @@ func TestMacro(t *testing.T) { // non-APEX variant does not have __ANDROID_APEX__ defined mylibCFlags := ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"] ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__") - ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__") - // APEX variant has __ANDROID_APEX__ and __ANDROID_APEX_SDK__ defined + // APEX variant has __ANDROID_APEX__ and __ANDROID_APEX__ defined mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex10000").Rule("cc").Args["cFlags"] ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__") - ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__=10000") - // APEX variant has __ANDROID_APEX__ and __ANDROID_APEX_SDK__ defined + // APEX variant has __ANDROID_APEX__ and __ANDROID_APEX__ defined mylibCFlags = ctx.ModuleForTests("mylib", "android_arm64_armv8-a_static_apex29").Rule("cc").Args["cFlags"] ensureContains(t, mylibCFlags, "-D__ANDROID_APEX__") - ensureContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__=29") // When a cc_library sets use_apex_name_macro: true each apex gets a unique variant and // each variant defines additional macros to distinguish which apex variant it is built for @@ -3348,19 +3344,17 @@ func TestMacro(t *testing.T) { mylibCFlags = ctx.ModuleForTests("mylib3", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"] ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__") - // recovery variant does not set __ANDROID_APEX_MIN_SDK_VERSION__ + // recovery variant does not set __ANDROID_APEX__ mylibCFlags = ctx.ModuleForTests("mylib3", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"] ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__") - ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__") // non-APEX variant does not have __ANDROID_APEX__ defined mylibCFlags = ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"] ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__") - // recovery variant does not set __ANDROID_APEX_MIN_SDK_VERSION__ + // recovery variant does not set __ANDROID_APEX__ mylibCFlags = ctx.ModuleForTests("mylib2", "android_recovery_arm64_armv8-a_static").Rule("cc").Args["cFlags"] ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX__") - ensureNotContains(t, mylibCFlags, "-D__ANDROID_APEX_MIN_SDK_VERSION__") } func TestHeaderLibsDependency(t *testing.T) { @@ -4153,7 +4147,6 @@ func TestApexName(t *testing.T) { var builder strings.Builder data.Custom(&builder, name, prefix, "", data) androidMk := builder.String() - ensureContains(t, androidMk, "LOCAL_MODULE := mylib.myapex\n") ensureNotContains(t, androidMk, "LOCAL_MODULE := mylib.com.android.myapex\n") } @@ -5687,12 +5680,6 @@ func TestApexWithTests(t *testing.T) { var builder strings.Builder data.Custom(&builder, name, prefix, "", data) androidMk := builder.String() - ensureContains(t, androidMk, "LOCAL_MODULE := mytest.myapex\n") - ensureContains(t, androidMk, "LOCAL_MODULE := mytest1.myapex\n") - ensureContains(t, androidMk, "LOCAL_MODULE := mytest2.myapex\n") - ensureContains(t, androidMk, "LOCAL_MODULE := mytest3.myapex\n") - ensureContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.myapex\n") - ensureContains(t, androidMk, "LOCAL_MODULE := apex_pubkey.myapex\n") ensureContains(t, androidMk, "LOCAL_MODULE := myapex\n") flatBundle := ctx.ModuleForTests("myapex", "android_common_myapex_flattened").Module().(*apexBundle) @@ -5726,7 +5713,7 @@ func TestInstallExtraFlattenedApexes(t *testing.T) { var builder strings.Builder mk.Custom(&builder, ab.Name(), "TARGET_", "", mk) androidMk := builder.String() - ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := apex_manifest.pb.myapex apex_pubkey.myapex myapex.flattened\n") + ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := myapex.flattened\n") } func TestErrorsIfDepsAreNotEnabled(t *testing.T) { @@ -6519,12 +6506,6 @@ func TestOverrideApex(t *testing.T) { var builder strings.Builder data.Custom(&builder, name, "TARGET_", "", data) androidMk := builder.String() - ensureContains(t, androidMk, "LOCAL_MODULE := override_app.override_myapex") - ensureContains(t, androidMk, "LOCAL_MODULE := overrideBpf.o.override_myapex") - ensureContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.override_myapex") - ensureContains(t, androidMk, "LOCAL_MODULE := override_bcplib.override_myapex") - ensureContains(t, androidMk, "LOCAL_MODULE := override_systemserverlib.override_myapex") - ensureContains(t, androidMk, "LOCAL_MODULE := override_java_library.override_myapex") ensureContains(t, androidMk, "LOCAL_MODULE_STEM := override_myapex.apex") ensureContains(t, androidMk, "LOCAL_OVERRIDES_MODULES := unknownapex myapex") ensureNotContains(t, androidMk, "LOCAL_MODULE := app.myapex") @@ -7116,7 +7097,7 @@ func TestCarryRequiredModuleNames(t *testing.T) { var builder strings.Builder data.Custom(&builder, name, prefix, "", data) androidMk := builder.String() - ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := mylib.myapex:64 apex_manifest.pb.myapex apex_pubkey.myapex a b\n") + ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := a b\n") ensureContains(t, androidMk, "LOCAL_HOST_REQUIRED_MODULES := c d\n") ensureContains(t, androidMk, "LOCAL_TARGET_REQUIRED_MODULES := e f\n") } @@ -7287,6 +7268,9 @@ func TestSymlinksFromApexToSystemRequiredModuleNames(t *testing.T) { "myapex", "//apex_available:platform", ], + stubs: { + versions: ["current"], + }, } `) @@ -7296,11 +7280,10 @@ func TestSymlinksFromApexToSystemRequiredModuleNames(t *testing.T) { data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data) androidMk := builder.String() // `myotherlib` is added to `myapex` as symlink - ensureContains(t, androidMk, "LOCAL_MODULE := mylib.myapex\n") ensureNotContains(t, androidMk, "LOCAL_MODULE := prebuilt_myotherlib.myapex\n") ensureNotContains(t, androidMk, "LOCAL_MODULE := myotherlib.myapex\n") // `myapex` should have `myotherlib` in its required line, not `prebuilt_myotherlib` - ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := mylib.myapex:64 myotherlib:64 apex_manifest.pb.myapex apex_pubkey.myapex\n") + ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := myotherlib\n") } func TestApexWithJniLibs(t *testing.T) { @@ -8813,7 +8796,7 @@ func TestPreferredPrebuiltSharedLibDep(t *testing.T) { // The make level dependency needs to be on otherlib - prebuilt_otherlib isn't // a thing there. - ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := libc++:64 mylib.myapex:64 apex_manifest.pb.myapex apex_pubkey.myapex otherlib\n") + ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := otherlib\n") } func TestExcludeDependency(t *testing.T) { @@ -9207,7 +9190,7 @@ func TestAndroidMk_DexpreoptBuiltInstalledForApex(t *testing.T) { var builder strings.Builder data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data) androidMk := builder.String() - ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := foo.myapex apex_manifest.pb.myapex apex_pubkey.myapex foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.odex foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.vdex\n") + ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.odex foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.vdex\n") } func TestAndroidMk_DexpreoptBuiltInstalledForApex_Prebuilt(t *testing.T) { @@ -9283,7 +9266,7 @@ func TestAndroidMk_RequiredModules(t *testing.T) { var builder strings.Builder data.Custom(&builder, apexBundle.BaseModuleName(), "TARGET_", "", data) androidMk := builder.String() - ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := foo.myapex apex_manifest.pb.myapex apex_pubkey.myapex otherapex") + ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := otherapex") } func TestAndroidMk_RequiredDeps(t *testing.T) { @@ -9307,7 +9290,7 @@ func TestAndroidMk_RequiredDeps(t *testing.T) { var builder strings.Builder data.Custom(&builder, bundle.BaseModuleName(), "TARGET_", "", data) androidMk := builder.String() - ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := apex_manifest.pb.myapex apex_pubkey.myapex foo\n") + ensureContains(t, androidMk, "LOCAL_REQUIRED_MODULES := foo\n") flattenedBundle := ctx.ModuleForTests("myapex", "android_common_myapex_flattened").Module().(*apexBundle) flattenedBundle.requiredDeps = append(flattenedBundle.requiredDeps, "foo") diff --git a/bp2build/aar_conversion_test.go b/bp2build/aar_conversion_test.go index 5f93eb70c..0cda5dd26 100644 --- a/bp2build/aar_conversion_test.go +++ b/bp2build/aar_conversion_test.go @@ -138,3 +138,36 @@ android_library_import { }, ) } + +func TestConvertAndroidLibraryKotlin(t *testing.T) { + t.Helper() + RunBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, Bp2buildTestCase{ + Description: "Android Library with .kt srcs and common_srcs attribute", + ModuleTypeUnderTest: "android_library", + ModuleTypeUnderTestFactory: java.AndroidLibraryFactory, + Filesystem: map[string]string{ + "AndroidManifest.xml": "", + }, + Blueprint: ` +android_library { + name: "TestLib", + srcs: ["a.java", "b.kt"], + common_srcs: ["c.kt"], +} +`, + ExpectedBazelTargets: []string{ + MakeBazelTarget( + "android_library", + "TestLib", + AttrNameToString{ + "srcs": `[ + "a.java", + "b.kt", + ]`, + "common_srcs": `["c.kt"]`, + "manifest": `"AndroidManifest.xml"`, + "resource_files": `[]`, + }), + MakeNeverlinkDuplicateTarget("android_library", "TestLib"), + }}) +} diff --git a/bp2build/bp2build_product_config.go b/bp2build/bp2build_product_config.go index e343a05d9..3eec43905 100644 --- a/bp2build/bp2build_product_config.go +++ b/bp2build/bp2build_product_config.go @@ -97,6 +97,8 @@ build --platforms @soong_injection//{PRODUCT_FOLDER}:{PRODUCT}-{VARIANT}_linux_x 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 `)), newFile( "product_config_platforms", diff --git a/bp2build/conversion.go b/bp2build/conversion.go index e53f29e39..c43fbd86e 100644 --- a/bp2build/conversion.go +++ b/bp2build/conversion.go @@ -6,6 +6,7 @@ import ( "strings" "android/soong/android" + "android/soong/cc" cc_config "android/soong/cc/config" java_config "android/soong/java/config" @@ -28,7 +29,8 @@ func soongInjectionFiles(cfg android.Config, metrics CodegenMetrics) []BazelFile files = append(files, newFile("android", "constants.bzl", android.BazelCcToolchainVars(cfg))) files = append(files, newFile("cc_toolchain", GeneratedBuildFileName, "")) // Creates a //cc_toolchain package. - files = append(files, newFile("cc_toolchain", "constants.bzl", cc_config.BazelCcToolchainVars(cfg))) + files = append(files, newFile("cc_toolchain", "config_constants.bzl", cc_config.BazelCcToolchainVars(cfg))) + files = append(files, newFile("cc_toolchain", "sanitizer_constants.bzl", cc.BazelCcSanitizerToolchainVars(cfg))) files = append(files, newFile("java_toolchain", GeneratedBuildFileName, "")) // Creates a //java_toolchain package. files = append(files, newFile("java_toolchain", "constants.bzl", java_config.BazelJavaToolchainVars(cfg))) diff --git a/bp2build/conversion_test.go b/bp2build/conversion_test.go index 43daddc1a..b9c06bc04 100644 --- a/bp2build/conversion_test.go +++ b/bp2build/conversion_test.go @@ -101,7 +101,11 @@ func TestCreateBazelFiles_Bp2Build_CreatesDefaultFiles(t *testing.T) { }, { dir: "cc_toolchain", - basename: "constants.bzl", + basename: "config_constants.bzl", + }, + { + dir: "cc_toolchain", + basename: "sanitizer_constants.bzl", }, { dir: "java_toolchain", diff --git a/cc/builder.go b/cc/builder.go index 0629406c2..fef00d4d5 100644 --- a/cc/builder.go +++ b/cc/builder.go @@ -519,6 +519,13 @@ func transformSourceToObj(ctx ModuleContext, subdir string, srcFiles, noTidySrcs cppflags += " ${config.NoOverrideGlobalCflags}" toolingCppflags += " ${config.NoOverrideGlobalCflags}" + if flags.toolchain.Is64Bit() { + cflags += " ${config.NoOverride64GlobalCflags}" + toolingCflags += " ${config.NoOverride64GlobalCflags}" + cppflags += " ${config.NoOverride64GlobalCflags}" + toolingCppflags += " ${config.NoOverride64GlobalCflags}" + } + modulePath := android.PathForModuleSrc(ctx).String() if android.IsThirdPartyPath(modulePath) { cflags += " ${config.NoOverrideExternalGlobalCflags}" @@ -1859,6 +1859,10 @@ func (c *Module) QueueBazelCall(ctx android.BaseModuleContext) { var ( mixedBuildSupportedCcTest = []string{ "adbd_test", + "adb_crypto_test", + "adb_pairing_auth_test", + "adb_pairing_connection_test", + "adb_tls_connection_test", } ) diff --git a/cc/cc_test.go b/cc/cc_test.go index 6dfd395cb..8293f2db7 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -4483,6 +4483,39 @@ func TestIncludeDirectoryOrdering(t *testing.T) { } +func TestAddnoOverride64GlobalCflags(t *testing.T) { + t.Parallel() + ctx := testCc(t, ` + cc_library_shared { + name: "libclient", + srcs: ["foo.c"], + shared_libs: ["libfoo#1"], + } + + cc_library_shared { + name: "libfoo", + srcs: ["foo.c"], + shared_libs: ["libbar"], + export_shared_lib_headers: ["libbar"], + stubs: { + symbol_file: "foo.map.txt", + versions: ["1", "2", "3"], + }, + } + + cc_library_shared { + name: "libbar", + export_include_dirs: ["include/libbar"], + srcs: ["foo.c"], + }`) + + cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"] + + if !strings.Contains(cFlags, "${config.NoOverride64GlobalCflags}") { + t.Errorf("expected %q in cflags, got %q", "${config.NoOverride64GlobalCflags}", cFlags) + } +} + func TestCcBuildBrokenClangProperty(t *testing.T) { t.Parallel() tests := []struct { diff --git a/cc/compiler.go b/cc/compiler.go index a75175482..88985b6f9 100644 --- a/cc/compiler.go +++ b/cc/compiler.go @@ -416,11 +416,6 @@ func (compiler *baseCompiler) compilerFlags(ctx ModuleContext, flags Flags, deps if ctx.apexVariationName() != "" { flags.Global.CommonFlags = append(flags.Global.CommonFlags, "-D__ANDROID_APEX__") - if ctx.Device() { - flags.Global.CommonFlags = append(flags.Global.CommonFlags, - fmt.Sprintf("-D__ANDROID_APEX_MIN_SDK_VERSION__=%d", - ctx.apexSdkVersion().FinalOrFutureInt())) - } } if ctx.Target().NativeBridge == android.NativeBridgeEnabled { diff --git a/cc/config/global.go b/cc/config/global.go index 811e86ec5..2205c9e48 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -247,6 +247,8 @@ var ( "-Wno-error=enum-constexpr-conversion", // http://b/243964282 } + noOverride64GlobalCflags = []string{} + noOverrideExternalGlobalCflags = []string{ // http://b/148815709 "-Wno-sizeof-array-div", @@ -384,12 +386,26 @@ func init() { return strings.Join(deviceGlobalCflags, " ") }) - // Export the static default NoOverrideGlobalCflags to Bazel. + // Export the static default NoOverrideGlobalCflags and NoOverride64GlobalCflags to Bazel. exportedVars.ExportStringList("NoOverrideGlobalCflags", noOverrideGlobalCflags) + exportedVars.ExportStringList("NoOverride64GlobalCflags", noOverride64GlobalCflags) pctx.VariableFunc("NoOverrideGlobalCflags", func(ctx android.PackageVarContext) string { flags := noOverrideGlobalCflags if ctx.Config().IsEnvTrue("LLVM_NEXT") { flags = append(noOverrideGlobalCflags, llvmNextExtraCommonGlobalCflags...) + if ctx.Config().Android64() { + flags = append(noOverride64GlobalCflags) + } + } + return strings.Join(flags, " ") + }) + + // Export the static default NoOverride64GlobalCflags to Bazel. + exportedVars.ExportStringList("NoOverride64GlobalCflags", noOverride64GlobalCflags) + pctx.VariableFunc("NoOverride64GlobalCflags", func(ctx android.PackageVarContext) string { + flags := noOverride64GlobalCflags + if ctx.Config().IsEnvTrue("LLVM_NEXT") && ctx.Config().Android64() { + flags = append(noOverride64GlobalCflags, llvmNextExtraCommonGlobalCflags...) } return strings.Join(flags, " ") }) diff --git a/cc/library.go b/cc/library.go index 8fd001988..1291f5cd3 100644 --- a/cc/library.go +++ b/cc/library.go @@ -1239,6 +1239,10 @@ func (library *libraryDecorator) compile(ctx ModuleContext, flags Flags, deps Pa // b/239274367 --apex and --systemapi filters symbols tagged with # apex and # // systemapi, respectively. The former is for symbols defined in platform libraries // and the latter is for symbols defined in APEXes. + // A single library can contain either # apex or # systemapi, but not both. + // The stub generator (ndkstubgen) is additive, so passing _both_ of these to it should be a no-op. + // However, having this distinction helps guard accidental + // promotion or demotion of API and also helps the API review process b/191371676 var flag string if ctx.Module().(android.ApexModule).NotInPlatform() { flag = "--apex" diff --git a/cc/library_stub.go b/cc/library_stub.go index d21df5105..08a5eb6ae 100644 --- a/cc/library_stub.go +++ b/cc/library_stub.go @@ -205,6 +205,14 @@ func (d *apiLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps d.libraryDecorator.flagExporter.Properties.Export_include_dirs = append( d.libraryDecorator.flagExporter.Properties.Export_include_dirs, variantMod.exportProperties.Export_include_dirs...) + + // Export headers as system include dirs if specified. Mostly for libc + if Bool(variantMod.exportProperties.Export_headers_as_system) { + d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs = append( + d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs, + d.libraryDecorator.flagExporter.Properties.Export_include_dirs...) + d.libraryDecorator.flagExporter.Properties.Export_include_dirs = nil + } } } } diff --git a/cc/makevars.go b/cc/makevars.go index c70d4a6ff..6c3f551d7 100644 --- a/cc/makevars.go +++ b/cc/makevars.go @@ -93,6 +93,7 @@ func makeVarsProvider(ctx android.MakeVarsContext) { ctx.Strict("CLANG_EXTERNAL_CFLAGS", "${config.ExternalCflags}") ctx.Strict("GLOBAL_CLANG_CFLAGS_NO_OVERRIDE", "${config.NoOverrideGlobalCflags}") + ctx.Strict("GLOBAL_CLANG_CFLAGS_64_NO_OVERRIDE", "${config.NoOverride64GlobalCflags}") ctx.Strict("GLOBAL_CLANG_CPPFLAGS_NO_OVERRIDE", "") ctx.Strict("GLOBAL_CLANG_EXTERNAL_CFLAGS_NO_OVERRIDE", "${config.NoOverrideExternalGlobalCflags}") diff --git a/cc/sanitize.go b/cc/sanitize.go index 8e2d16183..c61e5e495 100644 --- a/cc/sanitize.go +++ b/cc/sanitize.go @@ -78,6 +78,9 @@ var ( hwasanGlobalOptions = []string{"heap_history_size=1023", "stack_history_size=512", "export_memory_stats=0", "max_malloc_fill_size=4096", "malloc_fill_byte=0"} memtagStackCommonFlags = []string{"-march=armv8-a+memtag"} + + hostOnlySanitizeFlags = []string{"-fno-sanitize-recover=all"} + deviceOnlySanitizeFlags = []string{"-fsanitize-trap=all", "-ftrap-function=abort"} ) type SanitizerType int @@ -379,7 +382,12 @@ func (t libraryDependencyTag) SkipApexAllowedDependenciesCheck() bool { var _ android.SkipApexAllowedDependenciesCheck = (*libraryDependencyTag)(nil) +var exportedVars = android.NewExportedVariables(pctx) + func init() { + exportedVars.ExportStringListStaticVariable("HostOnlySanitizeFlags", hostOnlySanitizeFlags) + exportedVars.ExportStringList("DeviceOnlySanitizeFlags", deviceOnlySanitizeFlags) + android.RegisterMakeVarsProvider(pctx, cfiMakeVarsProvider) android.RegisterMakeVarsProvider(pctx, hwasanMakeVarsProvider) } @@ -869,9 +877,9 @@ func (s *sanitize) flags(ctx ModuleContext, flags Flags) Flags { // When fuzzing, we wish to crash with diagnostics on any bug. flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-trap=all", "-fno-sanitize-recover=all") } else if ctx.Host() { - flags.Local.CFlags = append(flags.Local.CFlags, "-fno-sanitize-recover=all") + flags.Local.CFlags = append(flags.Local.CFlags, hostOnlySanitizeFlags...) } else { - flags.Local.CFlags = append(flags.Local.CFlags, "-fsanitize-trap=all", "-ftrap-function=abort") + flags.Local.CFlags = append(flags.Local.CFlags, deviceOnlySanitizeFlags...) } if enableMinimalRuntime(s) { @@ -1787,3 +1795,7 @@ func cfiMakeVarsProvider(ctx android.MakeVarsContext) { func hwasanMakeVarsProvider(ctx android.MakeVarsContext) { hwasanStaticLibs(ctx.Config()).exportToMake(ctx) } + +func BazelCcSanitizerToolchainVars(config android.Config) string { + return android.BazelToolchainVars(config, exportedVars) +} diff --git a/java/aar.go b/java/aar.go index 58b72abce..a483e13b9 100644 --- a/java/aar.go +++ b/java/aar.go @@ -651,6 +651,8 @@ type AARImport struct { // Functionality common to Module and Import. embeddableInModuleAndImport + providesTransitiveHeaderJars + properties AARImportProperties classpathFile android.WritablePath @@ -897,8 +899,11 @@ func (a *AARImport) GenerateAndroidBuildActions(ctx android.ModuleContext) { a.assetsPackage = mergedAssets } + a.collectTransitiveHeaderJars(ctx) ctx.SetProvider(JavaInfoProvider, JavaInfo{ HeaderJars: android.PathsIfNonNil(a.classpathFile), + TransitiveLibsHeaderJars: a.transitiveLibsHeaderJars, + TransitiveStaticLibsHeaderJars: a.transitiveStaticLibsHeaderJars, ImplementationAndResourcesJars: android.PathsIfNonNil(a.classpathFile), ImplementationJars: android.PathsIfNonNil(a.classpathFile), }) @@ -1069,6 +1074,10 @@ func (a *AndroidLibrary) ConvertWithBp2build(ctx android.TopDownMutatorContext) ctx.ModuleErrorf("Module has direct dependencies but no sources. Bazel will not allow this.") } + if len(a.properties.Common_srcs) != 0 { + commonAttrs.Common_srcs = bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, a.properties.Common_srcs)) + } + name := a.Name() props := bazel.BazelTargetModuleProperties{ Rule_class: "android_library", diff --git a/java/app.go b/java/app.go index 98c31bc49..4d9c407c5 100755 --- a/java/app.go +++ b/java/app.go @@ -1312,6 +1312,9 @@ func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, addCompatDeps boo ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...) ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...) } + } else { + ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.usesLibraryProperties.Uses_libs...) + ctx.AddVariationDependencies(nil, r8LibraryJarTag, u.presentOptionalUsesLibs(ctx)...) } } diff --git a/java/base.go b/java/base.go index 84fda37cb..cce06a4e9 100644 --- a/java/base.go +++ b/java/base.go @@ -1583,6 +1583,8 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { ctx.SetProvider(JavaInfoProvider, JavaInfo{ HeaderJars: android.PathsIfNonNil(j.headerJarFile), + TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars, + TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars, ImplementationAndResourcesJars: android.PathsIfNonNil(j.implementationAndResourcesJar), ImplementationJars: android.PathsIfNonNil(j.implementationJarFile), ResourceJars: android.PathsIfNonNil(j.resourceJar), @@ -1719,6 +1721,52 @@ func (j *Module) instrument(ctx android.ModuleContext, flags javaBuilderFlags, return instrumentedJar } +type providesTransitiveHeaderJars struct { + // set of header jars for all transitive libs deps + transitiveLibsHeaderJars *android.DepSet + // set of header jars for all transitive static libs deps + transitiveStaticLibsHeaderJars *android.DepSet +} + +func (j *providesTransitiveHeaderJars) TransitiveLibsHeaderJars() *android.DepSet { + return j.transitiveLibsHeaderJars +} + +func (j *providesTransitiveHeaderJars) TransitiveStaticLibsHeaderJars() *android.DepSet { + return j.transitiveStaticLibsHeaderJars +} + +func (j *providesTransitiveHeaderJars) collectTransitiveHeaderJars(ctx android.ModuleContext) { + directLibs := android.Paths{} + directStaticLibs := android.Paths{} + transitiveLibs := []*android.DepSet{} + transitiveStaticLibs := []*android.DepSet{} + ctx.VisitDirectDeps(func(module android.Module) { + // don't add deps of the prebuilt version of the same library + if ctx.ModuleName() == android.RemoveOptionalPrebuiltPrefix(module.Name()) { + return + } + + dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo) + if dep.TransitiveLibsHeaderJars != nil { + transitiveLibs = append(transitiveLibs, dep.TransitiveLibsHeaderJars) + } + if dep.TransitiveStaticLibsHeaderJars != nil { + transitiveStaticLibs = append(transitiveStaticLibs, dep.TransitiveStaticLibsHeaderJars) + } + + tag := ctx.OtherModuleDependencyTag(module) + _, isUsesLibDep := tag.(usesLibraryDependencyTag) + if tag == libTag || tag == r8LibraryJarTag || isUsesLibDep { + directLibs = append(directLibs, dep.HeaderJars...) + } else if tag == staticLibTag { + directStaticLibs = append(directStaticLibs, dep.HeaderJars...) + } + }) + j.transitiveLibsHeaderJars = android.NewDepSet(android.POSTORDER, directLibs, transitiveLibs) + j.transitiveStaticLibsHeaderJars = android.NewDepSet(android.POSTORDER, directStaticLibs, transitiveStaticLibs) +} + func (j *Module) HeaderJars() android.Paths { if j.headerJarFile == nil { return nil @@ -1947,6 +1995,7 @@ func (j *Module) collectDeps(ctx android.ModuleContext) deps { sdkLinkType, _ := j.getSdkLinkType(ctx, ctx.ModuleName()) + j.collectTransitiveHeaderJars(ctx) ctx.VisitDirectDeps(func(module android.Module) { otherName := ctx.OtherModuleName(module) tag := ctx.OtherModuleDependencyTag(module) diff --git a/java/core-libraries/Android.bp b/java/core-libraries/Android.bp index 4fb1d76fd..b9332dda5 100644 --- a/java/core-libraries/Android.bp +++ b/java/core-libraries/Android.bp @@ -63,11 +63,6 @@ java_library { // This one is not on device but it's needed when javac compiles code // containing lambdas. "core-lambda-stubs-for-system-modules", - // This one is not on device but it's needed when javac compiles code - // containing @Generated annotations produced by some code generation - // tools. - // See http://b/123891440. - "core-generated-annotation-stubs", ], sdk_version: "none", system_modules: "none", @@ -148,11 +143,6 @@ java_library { // This one is not on device but it's needed when javac compiles code // containing lambdas. "core-lambda-stubs-for-system-modules", - // This one is not on device but it's needed when javac compiles code - // containing @Generated annotations produced by some code generation - // tools. - // See http://b/123891440. - "core-generated-annotation-stubs", ], sdk_version: "none", system_modules: "none", @@ -278,11 +268,6 @@ java_system_modules { // This one is not on device but it's needed when javac compiles code // containing lambdas. "core-lambda-stubs-for-system-modules", - // This one is not on device but it's needed when javac compiles code - // containing @Generated annotations produced by some code generation - // tools. - // See http://b/123891440. - "core-generated-annotation-stubs", ], } @@ -294,11 +279,6 @@ java_system_modules { // This one is not on device but it's needed when javac compiles code // containing lambdas. "core-lambda-stubs-for-system-modules", - // This one is not on device but it's needed when javac compiles code - // containing @Generated annotations produced by some code generation - // tools. - // See http://b/123891440. - "core-generated-annotation-stubs", ], } @@ -322,11 +302,6 @@ java_system_modules { // This one is not on device but it's needed when javac compiles code // containing lambdas. "core-lambda-stubs-for-system-modules", - // This one is not on device but it's needed when javac compiles code - // containing @Generated annotations produced by some code generation - // tools. - // See http://b/123891440. - "core-generated-annotation-stubs", // Ensure that core libraries that depend on the public API can access // the UnsupportedAppUsage, CorePlatformApi and IntraCoreApi diff --git a/java/dex.go b/java/dex.go index 40ee99d3b..b6fe10982 100644 --- a/java/dex.go +++ b/java/dex.go @@ -22,6 +22,7 @@ import ( "github.com/google/blueprint/proptools" "android/soong/android" + "android/soong/java/config" "android/soong/remoteexec" ) @@ -89,7 +90,10 @@ type dexer struct { // list of extra proguard flag files extraProguardFlagFiles android.Paths proguardDictionary android.OptionalPath + proguardConfiguration android.OptionalPath proguardUsageZip android.OptionalPath + + providesTransitiveHeaderJars } func (d *dexer) effectiveOptimizeEnabled() bool { @@ -130,17 +134,18 @@ var d8, d8RE = pctx.MultiCommandRemoteStaticRules("d8", var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8", blueprint.RuleParams{ Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` + - `rm -f "$outDict" && rm -rf "${outUsageDir}" && ` + + `rm -f "$outDict" && rm -f "$outConfig" && rm -rf "${outUsageDir}" && ` + `mkdir -p $$(dirname ${outUsage}) && ` + `mkdir -p $$(dirname $tmpJar) && ` + `${config.Zip2ZipCmd} -i $in -o $tmpJar -x '**/*.dex' && ` + `$r8Template${config.R8Cmd} ${config.R8Flags} -injars $tmpJar --output $outDir ` + `--no-data-resources ` + `-printmapping ${outDict} ` + + `--pg-conf-output ${outConfig} ` + `-printusage ${outUsage} ` + `--deps-file ${out}.d ` + `$r8Flags && ` + - `touch "${outDict}" "${outUsage}" && ` + + `touch "${outDict}" "${outConfig}" "${outUsage}" && ` + `${config.SoongZipCmd} -o ${outUsageZip} -C ${outUsageDir} -f ${outUsage} && ` + `rm -rf ${outUsageDir} && ` + `$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` + @@ -176,7 +181,7 @@ var r8, r8RE = pctx.MultiCommandRemoteStaticRules("r8", ExecStrategy: "${config.RER8ExecStrategy}", Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, }, - }, []string{"outDir", "outDict", "outUsage", "outUsageZip", "outUsageDir", + }, []string{"outDir", "outDict", "outConfig", "outUsage", "outUsageZip", "outUsageDir", "r8Flags", "zipFlags", "tmpJar", "mergeZipsFlags"}, []string{"implicits"}) func (d *dexer) dexCommonFlags(ctx android.ModuleContext, @@ -249,12 +254,37 @@ func (d *dexer) r8Flags(ctx android.ModuleContext, flags javaBuilderFlags) (r8Fl }) r8Flags = append(r8Flags, proguardRaiseDeps.FormJavaClassPath("-libraryjars")) - r8Flags = append(r8Flags, flags.bootClasspath.FormJavaClassPath("-libraryjars")) - r8Flags = append(r8Flags, flags.dexClasspath.FormJavaClassPath("-libraryjars")) - r8Deps = append(r8Deps, proguardRaiseDeps...) + r8Flags = append(r8Flags, flags.bootClasspath.FormJavaClassPath("-libraryjars")) r8Deps = append(r8Deps, flags.bootClasspath...) + r8Flags = append(r8Flags, flags.dexClasspath.FormJavaClassPath("-libraryjars")) r8Deps = append(r8Deps, flags.dexClasspath...) + r8Flags = append(r8Flags, flags.processorPath.FormJavaClassPath("-libraryjars")) + r8Deps = append(r8Deps, flags.processorPath...) + + errorProneClasspath := classpath(android.PathsForSource(ctx, config.ErrorProneClasspath)) + r8Flags = append(r8Flags, errorProneClasspath.FormJavaClassPath("-libraryjars")) + r8Deps = append(r8Deps, errorProneClasspath...) + + transitiveStaticLibsLookupMap := map[android.Path]bool{} + if d.transitiveStaticLibsHeaderJars != nil { + for _, jar := range d.transitiveStaticLibsHeaderJars.ToList() { + transitiveStaticLibsLookupMap[jar] = true + } + } + transitiveHeaderJars := android.Paths{} + if d.transitiveLibsHeaderJars != nil { + for _, jar := range d.transitiveLibsHeaderJars.ToList() { + if _, ok := transitiveStaticLibsLookupMap[jar]; ok { + // don't include a lib if it is already packaged in the current JAR as a static lib + continue + } + transitiveHeaderJars = append(transitiveHeaderJars, jar) + } + } + transitiveClasspath := classpath(transitiveHeaderJars) + r8Flags = append(r8Flags, transitiveClasspath.FormJavaClassPath("-libraryjars")) + r8Deps = append(r8Deps, transitiveClasspath...) flagFiles := android.Paths{ android.PathForSource(ctx, "build/make/core/proguard.flags"), @@ -342,6 +372,8 @@ func (d *dexer) compileDex(ctx android.ModuleContext, flags javaBuilderFlags, mi if useR8 { proguardDictionary := android.PathForModuleOut(ctx, "proguard_dictionary") d.proguardDictionary = android.OptionalPathForPath(proguardDictionary) + proguardConfiguration := android.PathForModuleOut(ctx, "proguard_configuration") + d.proguardConfiguration = android.OptionalPathForPath(proguardConfiguration) proguardUsageDir := android.PathForModuleOut(ctx, "proguard_usage") proguardUsage := proguardUsageDir.Join(ctx, ctx.Namespace().Path, android.ModuleNameWithPossibleOverride(ctx), "unused.txt") @@ -354,6 +386,7 @@ func (d *dexer) compileDex(ctx android.ModuleContext, flags javaBuilderFlags, mi "r8Flags": strings.Join(append(commonFlags, r8Flags...), " "), "zipFlags": zipFlags, "outDict": proguardDictionary.String(), + "outConfig": proguardConfiguration.String(), "outUsageDir": proguardUsageDir.String(), "outUsage": proguardUsage.String(), "outUsageZip": proguardUsageZip.String(), diff --git a/java/dex_test.go b/java/dex_test.go index fc6cd0f3f..dc85f9e34 100644 --- a/java/dex_test.go +++ b/java/dex_test.go @@ -18,6 +18,8 @@ import ( "testing" "android/soong/android" + + "github.com/google/blueprint/proptools" ) func TestR8(t *testing.T) { @@ -74,7 +76,7 @@ func TestR8(t *testing.T) { android.AssertStringDoesContain(t, "expected lib header jar in app r8 classpath", appR8.Args["r8Flags"], libHeader.String()) - android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app javac classpath", + android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app r8 classpath", appR8.Args["r8Flags"], staticLibHeader.String()) android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags", appR8.Args["r8Flags"], "-ignorewarnings") @@ -86,6 +88,174 @@ func TestR8(t *testing.T) { corePlatformAppR8.Args["r8Flags"], "--android-platform-build") } +func TestR8TransitiveDeps(t *testing.T) { + bp := ` + override_android_app { + name: "override_app", + base: "app", + } + + android_app { + name: "app", + srcs: ["foo.java"], + libs: [ + "lib", + "uses_libs_dep_import", + ], + static_libs: [ + "static_lib", + "repeated_dep", + ], + platform_apis: true, + } + + java_library { + name: "static_lib", + srcs: ["foo.java"], + } + + java_library { + name: "lib", + libs: [ + "transitive_lib", + "repeated_dep", + "prebuilt_lib", + ], + static_libs: ["transitive_static_lib"], + srcs: ["foo.java"], + } + + java_library { + name: "repeated_dep", + srcs: ["foo.java"], + } + + java_library { + name: "transitive_static_lib", + srcs: ["foo.java"], + } + + java_library { + name: "transitive_lib", + srcs: ["foo.java"], + libs: ["transitive_lib_2"], + } + + java_library { + name: "transitive_lib_2", + srcs: ["foo.java"], + } + + java_import { + name: "lib", + jars: ["lib.jar"], + } + + java_library { + name: "uses_lib", + srcs: ["foo.java"], + } + + java_library { + name: "optional_uses_lib", + srcs: ["foo.java"], + } + + android_library { + name: "uses_libs_dep", + uses_libs: ["uses_lib"], + optional_uses_libs: ["optional_uses_lib"], + } + + android_library_import { + name: "uses_libs_dep_import", + aars: ["aar.aar"], + static_libs: ["uses_libs_dep"], + } + ` + + testcases := []struct { + name string + unbundled bool + }{ + { + name: "non-unbundled build", + unbundled: false, + }, + { + name: "unbundled build", + unbundled: true, + }, + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + fixturePreparer := PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd + if tc.unbundled { + fixturePreparer = android.GroupFixturePreparers( + fixturePreparer, + android.FixtureModifyProductVariables( + func(variables android.FixtureProductVariables) { + variables.Unbundled_build = proptools.BoolPtr(true) + }, + ), + ) + } + result := fixturePreparer.RunTestWithBp(t, bp) + + getHeaderJar := func(name string) android.Path { + mod := result.ModuleForTests(name, "android_common") + return mod.Output("turbine-combined/" + name + ".jar").Output + } + + appR8 := result.ModuleForTests("app", "android_common").Rule("r8") + overrideAppR8 := result.ModuleForTests("app", "android_common_override_app").Rule("r8") + appHeader := getHeaderJar("app") + overrideAppHeader := result.ModuleForTests("app", "android_common_override_app").Output("turbine-combined/app.jar").Output + libHeader := getHeaderJar("lib") + transitiveLibHeader := getHeaderJar("transitive_lib") + transitiveLib2Header := getHeaderJar("transitive_lib_2") + staticLibHeader := getHeaderJar("static_lib") + transitiveStaticLibHeader := getHeaderJar("transitive_static_lib") + repeatedDepHeader := getHeaderJar("repeated_dep") + usesLibHeader := getHeaderJar("uses_lib") + optionalUsesLibHeader := getHeaderJar("optional_uses_lib") + prebuiltLibHeader := result.ModuleForTests("prebuilt_lib", "android_common").Output("combined/lib.jar").Output + + for _, rule := range []android.TestingBuildParams{appR8, overrideAppR8} { + android.AssertStringDoesNotContain(t, "expected no app header jar in app r8 classpath", + rule.Args["r8Flags"], appHeader.String()) + android.AssertStringDoesNotContain(t, "expected no override_app header jar in app r8 classpath", + rule.Args["r8Flags"], overrideAppHeader.String()) + android.AssertStringDoesContain(t, "expected transitive lib header jar in app r8 classpath", + rule.Args["r8Flags"], transitiveLibHeader.String()) + android.AssertStringDoesContain(t, "expected transitive lib ^2 header jar in app r8 classpath", + rule.Args["r8Flags"], transitiveLib2Header.String()) + android.AssertStringDoesContain(t, "expected lib header jar in app r8 classpath", + rule.Args["r8Flags"], libHeader.String()) + android.AssertStringDoesContain(t, "expected uses_lib header jar in app r8 classpath", + rule.Args["r8Flags"], usesLibHeader.String()) + android.AssertStringDoesContain(t, "expected optional_uses_lib header jar in app r8 classpath", + rule.Args["r8Flags"], optionalUsesLibHeader.String()) + android.AssertStringDoesNotContain(t, "expected no static_lib header jar in app r8 classpath", + rule.Args["r8Flags"], staticLibHeader.String()) + android.AssertStringDoesNotContain(t, "expected no transitive static_lib header jar in app r8 classpath", + rule.Args["r8Flags"], transitiveStaticLibHeader.String()) + // we shouldn't list this dep because it is already included as static_libs in the app + android.AssertStringDoesNotContain(t, "expected no repeated_dep header jar in app r8 classpath", + rule.Args["r8Flags"], repeatedDepHeader.String()) + // skip a prebuilt transitive dep if the source is also a transitive dep + android.AssertStringDoesNotContain(t, "expected no prebuilt header jar in app r8 classpath", + rule.Args["r8Flags"], prebuiltLibHeader.String()) + android.AssertStringDoesContain(t, "expected -ignorewarnings in app r8 flags", + rule.Args["r8Flags"], "-ignorewarnings") + android.AssertStringDoesContain(t, "expected --android-platform-build in app r8 flags", + rule.Args["r8Flags"], "--android-platform-build") + } + }) + } +} + func TestR8Flags(t *testing.T) { result := PrepareForTestWithJavaDefaultModulesWithoutFakeDex2oatd.RunTestWithBp(t, ` android_app { diff --git a/java/java.go b/java/java.go index 146931b2b..19077319c 100644 --- a/java/java.go +++ b/java/java.go @@ -230,6 +230,12 @@ type JavaInfo struct { // against this module. If empty, ImplementationJars should be used instead. HeaderJars android.Paths + // set of header jars for all transitive libs deps + TransitiveLibsHeaderJars *android.DepSet + + // set of header jars for all transitive static libs deps + TransitiveStaticLibsHeaderJars *android.DepSet + // ImplementationAndResourceJars is a list of jars that contain the implementations of classes // in the module as well as any resources included in the module. ImplementationAndResourcesJars android.Paths @@ -380,6 +386,7 @@ var ( instrumentationForTag = dependencyTag{name: "instrumentation_for"} extraLintCheckTag = dependencyTag{name: "extra-lint-check", toolchain: true} jniLibTag = dependencyTag{name: "jnilib", runtimeLinked: true} + r8LibraryJarTag = dependencyTag{name: "r8-libraryjar", runtimeLinked: true} syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"} jniInstallTag = installDependencyTag{name: "jni install"} binaryInstallTag = installDependencyTag{name: "binary install"} @@ -1618,6 +1625,10 @@ type JavaApiLibraryProperties struct { // List of flags to be passed to the javac compiler to generate jar file Javacflags []string + + // List of shared java libs that this module has dependencies to and + // should be passed as classpath in javac invocation + Libs []string } func ApiLibraryFactory() android.Module { @@ -1689,6 +1700,7 @@ func (al *ApiLibrary) DepsMutator(ctx android.BottomUpMutatorContext) { for _, apiContributionName := range apiContributions { ctx.AddDependency(ctx.Module(), javaApiContributionTag, apiContributionName) } + ctx.AddVariationDependencies(nil, libTag, al.properties.Libs...) } func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { @@ -1706,10 +1718,18 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { homeDir := android.PathForModuleOut(ctx, "metalava", "home") - var srcFiles []android.Path - ctx.VisitDirectDepsWithTag(javaApiContributionTag, func(dep android.Module) { - provider := ctx.OtherModuleProvider(dep, JavaApiImportProvider).(JavaApiImportInfo) - srcFiles = append(srcFiles, android.PathForSource(ctx, provider.ApiFile.String())) + var srcFiles android.Paths + var classPaths android.Paths + ctx.VisitDirectDeps(func(dep android.Module) { + tag := ctx.OtherModuleDependencyTag(dep) + switch tag { + case javaApiContributionTag: + provider := ctx.OtherModuleProvider(dep, JavaApiImportProvider).(JavaApiImportInfo) + srcFiles = append(srcFiles, android.PathForSource(ctx, provider.ApiFile.String())) + case libTag: + provider := ctx.OtherModuleProvider(dep, JavaInfoProvider).(JavaInfo) + classPaths = append(classPaths, provider.HeaderJars...) + } }) // Add the api_files inputs @@ -1739,11 +1759,16 @@ func (al *ApiLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { var flags javaBuilderFlags flags.javaVersion = getStubsJavaVersion() flags.javacFlags = strings.Join(al.properties.Javacflags, " ") + flags.classpath = classpath(classPaths) TransformJavaToClasses(ctx, al.stubsJar, 0, android.Paths{}, android.Paths{al.stubsSrcJar}, flags, android.Paths{}) ctx.Phony(ctx.ModuleName(), al.stubsJar) + + ctx.SetProvider(JavaInfoProvider, JavaInfo{ + HeaderJars: android.PathsIfNonNil(al.stubsJar), + }) } // @@ -1926,9 +1951,9 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { var flags javaBuilderFlags + j.collectTransitiveHeaderJars(ctx) ctx.VisitDirectDeps(func(module android.Module) { tag := ctx.OtherModuleDependencyTag(module) - if ctx.OtherModuleHasProvider(module, JavaInfoProvider) { dep := ctx.OtherModuleProvider(module, JavaInfoProvider).(JavaInfo) switch tag { @@ -2018,6 +2043,8 @@ func (j *Import) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.SetProvider(JavaInfoProvider, JavaInfo{ HeaderJars: android.PathsIfNonNil(j.combinedClasspathFile), + TransitiveLibsHeaderJars: j.transitiveLibsHeaderJars, + TransitiveStaticLibsHeaderJars: j.transitiveStaticLibsHeaderJars, ImplementationAndResourcesJars: android.PathsIfNonNil(j.combinedClasspathFile), ImplementationJars: android.PathsIfNonNil(j.combinedClasspathFile), AidlIncludeDirs: j.exportAidlIncludeDirs, diff --git a/java/java_test.go b/java/java_test.go index 49adefbde..ae77842a5 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -1895,22 +1895,26 @@ func TestJavaApiLibraryAndProviderLink(t *testing.T) { } func TestJavaApiLibraryAndDefaultsLink(t *testing.T) { - provider_bp_a := `java_api_contribution { + provider_bp_a := ` + java_api_contribution { name: "foo1", api_file: "foo1.txt", } ` - provider_bp_b := `java_api_contribution { + provider_bp_b := ` + java_api_contribution { name: "foo2", api_file: "foo2.txt", } ` - provider_bp_c := `java_api_contribution { + provider_bp_c := ` + java_api_contribution { name: "foo3", api_file: "foo3.txt", } ` - provider_bp_d := `java_api_contribution { + provider_bp_d := ` + java_api_contribution { name: "foo4", api_file: "foo4.txt", } @@ -1989,7 +1993,8 @@ func TestJavaApiLibraryJarGeneration(t *testing.T) { api_file: "foo1.txt", } ` - provider_bp_b := `java_api_contribution { + provider_bp_b := ` + java_api_contribution { name: "foo2", api_file: "foo2.txt", } @@ -2034,6 +2039,81 @@ func TestJavaApiLibraryJarGeneration(t *testing.T) { } } +func TestJavaApiLibraryLibsLink(t *testing.T) { + provider_bp_a := ` + java_api_contribution { + name: "foo1", + api_file: "foo1.txt", + } + ` + provider_bp_b := ` + java_api_contribution { + name: "foo2", + api_file: "foo2.txt", + } + ` + lib_bp_a := ` + java_library { + name: "lib1", + srcs: ["Lib.java"], + } + ` + lib_bp_b := ` + java_library { + name: "lib2", + srcs: ["Lib.java"], + } + ` + + ctx, _ := testJavaWithFS(t, ` + java_api_library { + name: "bar1", + api_surface: "public", + api_contributions: ["foo1"], + libs: ["lib1"], + } + + java_api_library { + name: "bar2", + api_surface: "system", + api_contributions: ["foo1", "foo2"], + libs: ["lib1", "lib2", "bar1"], + } + `, + map[string][]byte{ + "a/Android.bp": []byte(provider_bp_a), + "b/Android.bp": []byte(provider_bp_b), + "c/Android.bp": []byte(lib_bp_a), + "c/Lib.java": {}, + "d/Android.bp": []byte(lib_bp_b), + "d/Lib.java": {}, + }) + + testcases := []struct { + moduleName string + classPathJarNames []string + }{ + { + moduleName: "bar1", + classPathJarNames: []string{"lib1.jar"}, + }, + { + moduleName: "bar2", + classPathJarNames: []string{"lib1.jar", "lib2.jar", "bar1/android.jar"}, + }, + } + for _, c := range testcases { + m := ctx.ModuleForTests(c.moduleName, "android_common") + javacRules := m.Rule("javac") + classPathArgs := javacRules.Args["classpath"] + for _, jarName := range c.classPathJarNames { + if !strings.Contains(classPathArgs, jarName) { + t.Errorf("Module output does not contain expected jar %s", jarName) + } + } + } +} + func TestTradefedOptions(t *testing.T) { result := PrepareForTestWithJavaBuildComponents.RunTestWithBp(t, ` java_test_host { diff --git a/java/kotlin_test.go b/java/kotlin_test.go index 491ce2939..933fc5187 100644 --- a/java/kotlin_test.go +++ b/java/kotlin_test.go @@ -44,6 +44,10 @@ func TestKotlin(t *testing.T) { kotlinStdlib := ctx.ModuleForTests("kotlin-stdlib", "android_common"). Output("turbine-combined/kotlin-stdlib.jar").Output + kotlinStdlibJdk7 := ctx.ModuleForTests("kotlin-stdlib-jdk7", "android_common"). + Output("turbine-combined/kotlin-stdlib-jdk7.jar").Output + kotlinStdlibJdk8 := ctx.ModuleForTests("kotlin-stdlib-jdk8", "android_common"). + Output("turbine-combined/kotlin-stdlib-jdk8.jar").Output kotlinAnnotations := ctx.ModuleForTests("kotlin-annotations", "android_common"). Output("turbine-combined/kotlin-annotations.jar").Output @@ -79,6 +83,16 @@ func TestKotlin(t *testing.T) { fooJar.Inputs.Strings(), kotlinStdlib.String()) } + if !inList(kotlinStdlibJdk7.String(), fooJar.Inputs.Strings()) { + t.Errorf("foo jar inputs %v does not contain %v", + fooJar.Inputs.Strings(), kotlinStdlibJdk7.String()) + } + + if !inList(kotlinStdlibJdk8.String(), fooJar.Inputs.Strings()) { + t.Errorf("foo jar inputs %v does not contain %v", + fooJar.Inputs.Strings(), kotlinStdlibJdk8.String()) + } + if !inList(kotlinAnnotations.String(), fooJar.Inputs.Strings()) { t.Errorf("foo jar inputs %v does not contain %v", fooJar.Inputs.Strings(), kotlinAnnotations.String()) diff --git a/mk2rbc/android_products_test.go b/mk2rbc/android_products_test.go index f8c930aeb..5f55f6a90 100644 --- a/mk2rbc/android_products_test.go +++ b/mk2rbc/android_products_test.go @@ -29,7 +29,6 @@ func TestProductsMakefile(t *testing.T) { } expectedProducts := map[string]string{ "aosp_cf_x86_tv": abspath("vsoc_x86/tv/device.mk"), - "aosp_tv_arm": abspath("aosp_tv_arm.mk"), "aosp_tv_arm64": abspath("aosp_tv_arm64.mk"), } if !reflect.DeepEqual(actualProducts, expectedProducts) { diff --git a/mk2rbc/test/android_products.mk.test b/mk2rbc/test/android_products.mk.test index a2220edac..400ec3598 100644 --- a/mk2rbc/test/android_products.mk.test +++ b/mk2rbc/test/android_products.mk.test @@ -1,4 +1,3 @@ PRODUCT_MAKEFILES := \ - $(LOCAL_DIR)/aosp_tv_arm.mk \ $(LOCAL_DIR)/aosp_tv_arm64.mk \ aosp_cf_x86_tv:$(LOCAL_DIR)/vsoc_x86/tv/device.mk
\ No newline at end of file diff --git a/python/Android.bp b/python/Android.bp index e49fa6a3c..4584f1e83 100644 --- a/python/Android.bp +++ b/python/Android.bp @@ -11,11 +11,10 @@ bootstrap_go_package { "soong-tradefed", ], srcs: [ - "androidmk.go", "binary.go", + "bp2build.go", "builder.go", "defaults.go", - "installer.go", "library.go", "proto.go", "python.go", diff --git a/python/androidmk.go b/python/androidmk.go deleted file mode 100644 index 7dc471397..000000000 --- a/python/androidmk.go +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2017 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 python - -import ( - "path/filepath" - "strings" - - "android/soong/android" -) - -type subAndroidMkProvider interface { - AndroidMk(*Module, *android.AndroidMkEntries) -} - -func (p *Module) subAndroidMk(entries *android.AndroidMkEntries, obj interface{}) { - if p.subAndroidMkOnce == nil { - p.subAndroidMkOnce = make(map[subAndroidMkProvider]bool) - } - if androidmk, ok := obj.(subAndroidMkProvider); ok { - if !p.subAndroidMkOnce[androidmk] { - p.subAndroidMkOnce[androidmk] = true - androidmk.AndroidMk(p, entries) - } - } -} - -func (p *Module) AndroidMkEntries() []android.AndroidMkEntries { - entries := android.AndroidMkEntries{OutputFile: p.installSource} - - p.subAndroidMk(&entries, p.installer) - - return []android.AndroidMkEntries{entries} -} - -func (p *binaryDecorator) AndroidMk(base *Module, entries *android.AndroidMkEntries) { - entries.Class = "EXECUTABLES" - - entries.ExtraEntries = append(entries.ExtraEntries, - func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { - entries.AddCompatibilityTestSuites(p.binaryProperties.Test_suites...) - }) - base.subAndroidMk(entries, p.pythonInstaller) -} - -func (p *testDecorator) AndroidMk(base *Module, entries *android.AndroidMkEntries) { - entries.Class = "NATIVE_TESTS" - - entries.ExtraEntries = append(entries.ExtraEntries, - func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { - entries.AddCompatibilityTestSuites(p.binaryDecorator.binaryProperties.Test_suites...) - if p.testConfig != nil { - entries.SetString("LOCAL_FULL_TEST_CONFIG", p.testConfig.String()) - } - - entries.SetBoolIfTrue("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", !BoolDefault(p.binaryProperties.Auto_gen_config, true)) - - entries.AddStrings("LOCAL_TEST_DATA", android.AndroidMkDataPaths(p.data)...) - - p.testProperties.Test_options.SetAndroidMkEntries(entries) - }) - base.subAndroidMk(entries, p.binaryDecorator.pythonInstaller) -} - -func (installer *pythonInstaller) AndroidMk(base *Module, entries *android.AndroidMkEntries) { - entries.Required = append(entries.Required, "libc++") - entries.ExtraEntries = append(entries.ExtraEntries, - func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { - path, file := filepath.Split(installer.path.String()) - stem := strings.TrimSuffix(file, filepath.Ext(file)) - - entries.SetString("LOCAL_MODULE_SUFFIX", filepath.Ext(file)) - entries.SetString("LOCAL_MODULE_PATH", path) - entries.SetString("LOCAL_MODULE_STEM", stem) - entries.AddStrings("LOCAL_SHARED_LIBRARIES", installer.androidMkSharedLibs...) - entries.SetBool("LOCAL_CHECK_ELF_FILES", false) - }) -} diff --git a/python/binary.go b/python/binary.go index 670e0d313..95eb2c66c 100644 --- a/python/binary.go +++ b/python/binary.go @@ -18,11 +18,12 @@ package python import ( "fmt" + "path/filepath" + "strings" - "android/soong/android" - "android/soong/bazel" + "github.com/google/blueprint" - "github.com/google/blueprint/proptools" + "android/soong/android" ) func init() { @@ -33,63 +34,6 @@ func registerPythonBinaryComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("python_binary_host", PythonBinaryHostFactory) } -type bazelPythonBinaryAttributes struct { - Main *bazel.Label - Srcs bazel.LabelListAttribute - Deps bazel.LabelListAttribute - Python_version *string - Imports bazel.StringListAttribute -} - -func pythonBinaryBp2Build(ctx android.TopDownMutatorContext, m *Module) { - // TODO(b/182306917): this doesn't fully handle all nested props versioned - // by the python version, which would have been handled by the version split - // mutator. This is sufficient for very simple python_binary_host modules - // under Bionic. - py3Enabled := proptools.BoolDefault(m.properties.Version.Py3.Enabled, false) - py2Enabled := proptools.BoolDefault(m.properties.Version.Py2.Enabled, false) - var python_version *string - if py3Enabled && py2Enabled { - panic(fmt.Errorf( - "error for '%s' module: bp2build's python_binary_host converter does not support "+ - "converting a module that is enabled for both Python 2 and 3 at the same time.", m.Name())) - } else if py2Enabled { - python_version = &pyVersion2 - } else { - // do nothing, since python_version defaults to PY3. - } - - baseAttrs := m.makeArchVariantBaseAttributes(ctx) - attrs := &bazelPythonBinaryAttributes{ - Main: nil, - Srcs: baseAttrs.Srcs, - Deps: baseAttrs.Deps, - Python_version: python_version, - Imports: baseAttrs.Imports, - } - - for _, propIntf := range m.GetProperties() { - if props, ok := propIntf.(*BinaryProperties); ok { - // main is optional. - if props.Main != nil { - main := android.BazelLabelForModuleSrcSingle(ctx, *props.Main) - attrs.Main = &main - break - } - } - } - - props := bazel.BazelTargetModuleProperties{ - // Use the native py_binary rule. - Rule_class: "py_binary", - } - - ctx.CreateBazelTargetModule(props, android.CommonAttributes{ - Name: m.Name(), - Data: baseAttrs.Data, - }, attrs) -} - type BinaryProperties struct { // the name of the source file that is the main entry point of the program. // this file must also be listed in srcs. @@ -118,52 +62,61 @@ type BinaryProperties struct { Auto_gen_config *bool } -type binaryDecorator struct { +type PythonBinaryModule struct { + PythonLibraryModule binaryProperties BinaryProperties - *pythonInstaller + // (.intermediate) module output path as installation source. + installSource android.Path + + // Final installation path. + installedDest android.Path + + androidMkSharedLibs []string } +var _ android.AndroidMkEntriesProvider = (*PythonBinaryModule)(nil) +var _ android.Module = (*PythonBinaryModule)(nil) + type IntermPathProvider interface { IntermPathForModuleOut() android.OptionalPath } -func NewBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) { - module := newModule(hod, android.MultilibFirst) - decorator := &binaryDecorator{pythonInstaller: NewPythonInstaller("bin", "")} - - module.bootstrapper = decorator - module.installer = decorator - - return module, decorator +func NewBinary(hod android.HostOrDeviceSupported) *PythonBinaryModule { + return &PythonBinaryModule{ + PythonLibraryModule: *newModule(hod, android.MultilibFirst), + } } func PythonBinaryHostFactory() android.Module { - module, _ := NewBinary(android.HostSupported) - - android.InitBazelModule(module) - - return module.init() + return NewBinary(android.HostSupported).init() } -func (binary *binaryDecorator) autorun() bool { - return BoolDefault(binary.binaryProperties.Autorun, true) +func (p *PythonBinaryModule) init() android.Module { + p.AddProperties(&p.properties, &p.protoProperties) + p.AddProperties(&p.binaryProperties) + android.InitAndroidArchModule(p, p.hod, p.multilib) + android.InitDefaultableModule(p) + android.InitBazelModule(p) + return p } -func (binary *binaryDecorator) bootstrapperProps() []interface{} { - return []interface{}{&binary.binaryProperties} +func (p *PythonBinaryModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { + p.PythonLibraryModule.GenerateAndroidBuildActions(ctx) + p.buildBinary(ctx) + p.installedDest = ctx.InstallFile(installDir(ctx, "bin", "", ""), + p.installSource.Base(), p.installSource) } -func (binary *binaryDecorator) bootstrap(ctx android.ModuleContext, actualVersion string, - embeddedLauncher bool, srcsPathMappings []pathMapping, srcsZip android.Path, - depsSrcsZips android.Paths) android.OptionalPath { - +func (p *PythonBinaryModule) buildBinary(ctx android.ModuleContext) { + depsSrcsZips := p.collectPathsFromTransitiveDeps(ctx) main := "" - if binary.autorun() { - main = binary.getPyMainFile(ctx, srcsPathMappings) + if p.autorun() { + main = p.getPyMainFile(ctx, p.srcsPathMappings) } var launcherPath android.OptionalPath + embeddedLauncher := p.isEmbeddedLauncherEnabled() if embeddedLauncher { ctx.VisitDirectDepsWithTag(launcherTag, func(m android.Module) { if provider, ok := m.(IntermPathProvider); ok { @@ -175,15 +128,137 @@ func (binary *binaryDecorator) bootstrap(ctx android.ModuleContext, actualVersio } }) } - binFile := registerBuildActionForParFile(ctx, embeddedLauncher, launcherPath, - binary.getHostInterpreterName(ctx, actualVersion), - main, binary.getStem(ctx), append(android.Paths{srcsZip}, depsSrcsZips...)) + p.installSource = registerBuildActionForParFile(ctx, embeddedLauncher, launcherPath, + p.getHostInterpreterName(ctx, p.properties.Actual_version), + main, p.getStem(ctx), append(android.Paths{p.srcsZip}, depsSrcsZips...)) + + var sharedLibs []string + // if embedded launcher is enabled, we need to collect the shared library dependencies of the + // launcher + for _, dep := range ctx.GetDirectDepsWithTag(launcherSharedLibTag) { + sharedLibs = append(sharedLibs, ctx.OtherModuleName(dep)) + } + p.androidMkSharedLibs = sharedLibs +} + +func (p *PythonBinaryModule) AndroidMkEntries() []android.AndroidMkEntries { + entries := android.AndroidMkEntries{OutputFile: android.OptionalPathForPath(p.installSource)} + + entries.Class = "EXECUTABLES" + + entries.ExtraEntries = append(entries.ExtraEntries, + func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { + entries.AddCompatibilityTestSuites(p.binaryProperties.Test_suites...) + }) + + entries.Required = append(entries.Required, "libc++") + entries.ExtraEntries = append(entries.ExtraEntries, + func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { + path, file := filepath.Split(p.installedDest.String()) + stem := strings.TrimSuffix(file, filepath.Ext(file)) + + entries.SetString("LOCAL_MODULE_SUFFIX", filepath.Ext(file)) + entries.SetString("LOCAL_MODULE_PATH", path) + entries.SetString("LOCAL_MODULE_STEM", stem) + entries.AddStrings("LOCAL_SHARED_LIBRARIES", p.androidMkSharedLibs...) + entries.SetBool("LOCAL_CHECK_ELF_FILES", false) + }) + + return []android.AndroidMkEntries{entries} +} + +func (p *PythonBinaryModule) DepsMutator(ctx android.BottomUpMutatorContext) { + p.PythonLibraryModule.DepsMutator(ctx) + + versionVariation := []blueprint.Variation{ + {"python_version", p.properties.Actual_version}, + } + + // If this module will be installed and has an embedded launcher, we need to add dependencies for: + // * standard library + // * launcher + // * shared dependencies of the launcher + if p.isEmbeddedLauncherEnabled() { + var stdLib string + var launcherModule string + // Add launcher shared lib dependencies. Ideally, these should be + // derived from the `shared_libs` property of the launcher. However, we + // cannot read the property at this stage and it will be too late to add + // dependencies later. + launcherSharedLibDeps := []string{ + "libsqlite", + } + // Add launcher-specific dependencies for bionic + if ctx.Target().Os.Bionic() { + launcherSharedLibDeps = append(launcherSharedLibDeps, "libc", "libdl", "libm") + } + if ctx.Target().Os == android.LinuxMusl && !ctx.Config().HostStaticBinaries() { + launcherSharedLibDeps = append(launcherSharedLibDeps, "libc_musl") + } + + switch p.properties.Actual_version { + case pyVersion2: + stdLib = "py2-stdlib" - return android.OptionalPathForPath(binFile) + launcherModule = "py2-launcher" + if p.autorun() { + launcherModule = "py2-launcher-autorun" + } + + launcherSharedLibDeps = append(launcherSharedLibDeps, "libc++") + + case pyVersion3: + stdLib = "py3-stdlib" + + launcherModule = "py3-launcher" + if p.autorun() { + launcherModule = "py3-launcher-autorun" + } + if ctx.Config().HostStaticBinaries() && ctx.Target().Os == android.LinuxMusl { + launcherModule += "-static" + } + + if ctx.Device() { + launcherSharedLibDeps = append(launcherSharedLibDeps, "liblog") + } + default: + panic(fmt.Errorf("unknown Python Actual_version: %q for module: %q.", + p.properties.Actual_version, ctx.ModuleName())) + } + ctx.AddVariationDependencies(versionVariation, pythonLibTag, stdLib) + ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherTag, launcherModule) + ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherSharedLibTag, launcherSharedLibDeps...) + } +} + +// HostToolPath returns a path if appropriate such that this module can be used as a host tool, +// fulfilling the android.HostToolProvider interface. +func (p *PythonBinaryModule) HostToolPath() android.OptionalPath { + // TODO: This should only be set when building host binaries -- tests built for device would be + // setting this incorrectly. + return android.OptionalPathForPath(p.installedDest) +} + +// OutputFiles returns output files based on given tag, returns an error if tag is unsupported. +func (p *PythonBinaryModule) OutputFiles(tag string) (android.Paths, error) { + switch tag { + case "": + return android.Paths{p.installSource}, nil + default: + return nil, fmt.Errorf("unsupported module reference tag %q", tag) + } +} + +func (p *PythonBinaryModule) isEmbeddedLauncherEnabled() bool { + return Bool(p.properties.Embedded_launcher) +} + +func (b *PythonBinaryModule) autorun() bool { + return BoolDefault(b.binaryProperties.Autorun, true) } // get host interpreter name. -func (binary *binaryDecorator) getHostInterpreterName(ctx android.ModuleContext, +func (p *PythonBinaryModule) getHostInterpreterName(ctx android.ModuleContext, actualVersion string) string { var interp string switch actualVersion { @@ -200,13 +275,13 @@ func (binary *binaryDecorator) getHostInterpreterName(ctx android.ModuleContext, } // find main program path within runfiles tree. -func (binary *binaryDecorator) getPyMainFile(ctx android.ModuleContext, +func (p *PythonBinaryModule) getPyMainFile(ctx android.ModuleContext, srcsPathMappings []pathMapping) string { var main string - if String(binary.binaryProperties.Main) == "" { + if String(p.binaryProperties.Main) == "" { main = ctx.ModuleName() + pyExt } else { - main = String(binary.binaryProperties.Main) + main = String(p.binaryProperties.Main) } for _, path := range srcsPathMappings { @@ -219,11 +294,21 @@ func (binary *binaryDecorator) getPyMainFile(ctx android.ModuleContext, return "" } -func (binary *binaryDecorator) getStem(ctx android.ModuleContext) string { +func (p *PythonBinaryModule) getStem(ctx android.ModuleContext) string { stem := ctx.ModuleName() - if String(binary.binaryProperties.Stem) != "" { - stem = String(binary.binaryProperties.Stem) + if String(p.binaryProperties.Stem) != "" { + stem = String(p.binaryProperties.Stem) } - return stem + String(binary.binaryProperties.Suffix) + return stem + String(p.binaryProperties.Suffix) +} + +func installDir(ctx android.ModuleContext, dir, dir64, relative string) android.InstallPath { + if ctx.Arch().ArchType.Multilib == "lib64" && dir64 != "" { + dir = dir64 + } + if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) { + dir = filepath.Join(dir, ctx.Arch().ArchType.String()) + } + return android.PathForModuleInstall(ctx, dir, relative) } diff --git a/python/bp2build.go b/python/bp2build.go new file mode 100644 index 000000000..bdac2dc38 --- /dev/null +++ b/python/bp2build.go @@ -0,0 +1,226 @@ +// 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 python + +import ( + "fmt" + "path/filepath" + "strings" + + "github.com/google/blueprint/proptools" + + "android/soong/android" + "android/soong/bazel" +) + +type bazelPythonLibraryAttributes struct { + Srcs bazel.LabelListAttribute + Deps bazel.LabelListAttribute + Imports bazel.StringListAttribute + Srcs_version *string +} + +type bazelPythonProtoLibraryAttributes struct { + Deps bazel.LabelListAttribute +} + +type baseAttributes struct { + // TODO(b/200311466): Probably not translate b/c Bazel has no good equiv + //Pkg_path bazel.StringAttribute + // TODO: Related to Pkg_bath and similarLy gated + //Is_internal bazel.BoolAttribute + // Combines Srcs and Exclude_srcs + Srcs bazel.LabelListAttribute + Deps bazel.LabelListAttribute + // Combines Data and Java_data (invariant) + Data bazel.LabelListAttribute + Imports bazel.StringListAttribute +} + +func (m *PythonLibraryModule) makeArchVariantBaseAttributes(ctx android.TopDownMutatorContext) baseAttributes { + var attrs baseAttributes + archVariantBaseProps := m.GetArchVariantProperties(ctx, &BaseProperties{}) + for axis, configToProps := range archVariantBaseProps { + for config, props := range configToProps { + if baseProps, ok := props.(*BaseProperties); ok { + attrs.Srcs.SetSelectValue(axis, config, + android.BazelLabelForModuleSrcExcludes(ctx, baseProps.Srcs, baseProps.Exclude_srcs)) + attrs.Deps.SetSelectValue(axis, config, + android.BazelLabelForModuleDeps(ctx, baseProps.Libs)) + data := android.BazelLabelForModuleSrc(ctx, baseProps.Data) + data.Append(android.BazelLabelForModuleSrc(ctx, baseProps.Java_data)) + attrs.Data.SetSelectValue(axis, config, data) + } + } + } + + partitionedSrcs := bazel.PartitionLabelListAttribute(ctx, &attrs.Srcs, bazel.LabelPartitions{ + "proto": android.ProtoSrcLabelPartition, + "py": bazel.LabelPartition{Keep_remainder: true}, + }) + attrs.Srcs = partitionedSrcs["py"] + + if !partitionedSrcs["proto"].IsEmpty() { + protoInfo, _ := android.Bp2buildProtoProperties(ctx, &m.ModuleBase, partitionedSrcs["proto"]) + protoLabel := bazel.Label{Label: ":" + protoInfo.Name} + + pyProtoLibraryName := m.Name() + "_py_proto" + ctx.CreateBazelTargetModule(bazel.BazelTargetModuleProperties{ + Rule_class: "py_proto_library", + Bzl_load_location: "//build/bazel/rules/python:py_proto.bzl", + }, android.CommonAttributes{ + Name: pyProtoLibraryName, + }, &bazelPythonProtoLibraryAttributes{ + Deps: bazel.MakeSingleLabelListAttribute(protoLabel), + }) + + attrs.Deps.Add(bazel.MakeLabelAttribute(":" + pyProtoLibraryName)) + } + + // Bazel normally requires `import path.from.top.of.tree` statements in + // python code, but with soong you can directly import modules from libraries. + // Add "imports" attributes to the bazel library so it matches soong's behavior. + imports := "." + if m.properties.Pkg_path != nil { + // TODO(b/215119317) This is a hack to handle the fact that we don't convert + // pkg_path properly right now. If the folder structure that contains this + // Android.bp file matches pkg_path, we can set imports to an appropriate + // number of ../..s to emulate moving the files under a pkg_path folder. + pkg_path := filepath.Clean(*m.properties.Pkg_path) + if strings.HasPrefix(pkg_path, "/") { + ctx.ModuleErrorf("pkg_path cannot start with a /: %s", pkg_path) + } + + if !strings.HasSuffix(ctx.ModuleDir(), "/"+pkg_path) && ctx.ModuleDir() != pkg_path { + ctx.ModuleErrorf("Currently, bp2build only supports pkg_paths that are the same as the folders the Android.bp file is in. pkg_path: %s, module directory: %s", pkg_path, ctx.ModuleDir()) + } + numFolders := strings.Count(pkg_path, "/") + 1 + dots := make([]string, numFolders) + for i := 0; i < numFolders; i++ { + dots[i] = ".." + } + imports = strings.Join(dots, "/") + } + attrs.Imports = bazel.MakeStringListAttribute([]string{imports}) + + return attrs +} + +func pythonLibBp2Build(ctx android.TopDownMutatorContext, m *PythonLibraryModule) { + // TODO(b/182306917): this doesn't fully handle all nested props versioned + // by the python version, which would have been handled by the version split + // mutator. This is sufficient for very simple python_library modules under + // Bionic. + py3Enabled := proptools.BoolDefault(m.properties.Version.Py3.Enabled, true) + py2Enabled := proptools.BoolDefault(m.properties.Version.Py2.Enabled, false) + var python_version *string + if py2Enabled && !py3Enabled { + python_version = &pyVersion2 + } else if !py2Enabled && py3Enabled { + python_version = &pyVersion3 + } else if !py2Enabled && !py3Enabled { + ctx.ModuleErrorf("bp2build converter doesn't understand having neither py2 nor py3 enabled") + } else { + // do nothing, since python_version defaults to PY2ANDPY3 + } + + baseAttrs := m.makeArchVariantBaseAttributes(ctx) + + attrs := &bazelPythonLibraryAttributes{ + Srcs: baseAttrs.Srcs, + Deps: baseAttrs.Deps, + Srcs_version: python_version, + Imports: baseAttrs.Imports, + } + + props := bazel.BazelTargetModuleProperties{ + // Use the native py_library rule. + Rule_class: "py_library", + } + + ctx.CreateBazelTargetModule(props, android.CommonAttributes{ + Name: m.Name(), + Data: baseAttrs.Data, + }, attrs) +} + +type bazelPythonBinaryAttributes struct { + Main *bazel.Label + Srcs bazel.LabelListAttribute + Deps bazel.LabelListAttribute + Python_version *string + Imports bazel.StringListAttribute +} + +func pythonBinaryBp2Build(ctx android.TopDownMutatorContext, m *PythonBinaryModule) { + // TODO(b/182306917): this doesn't fully handle all nested props versioned + // by the python version, which would have been handled by the version split + // mutator. This is sufficient for very simple python_binary_host modules + // under Bionic. + py3Enabled := proptools.BoolDefault(m.properties.Version.Py3.Enabled, false) + py2Enabled := proptools.BoolDefault(m.properties.Version.Py2.Enabled, false) + var python_version *string + if py3Enabled && py2Enabled { + panic(fmt.Errorf( + "error for '%s' module: bp2build's python_binary_host converter does not support "+ + "converting a module that is enabled for both Python 2 and 3 at the same time.", m.Name())) + } else if py2Enabled { + python_version = &pyVersion2 + } else { + // do nothing, since python_version defaults to PY3. + } + + baseAttrs := m.makeArchVariantBaseAttributes(ctx) + attrs := &bazelPythonBinaryAttributes{ + Main: nil, + Srcs: baseAttrs.Srcs, + Deps: baseAttrs.Deps, + Python_version: python_version, + Imports: baseAttrs.Imports, + } + + for _, propIntf := range m.GetProperties() { + if props, ok := propIntf.(*BinaryProperties); ok { + // main is optional. + if props.Main != nil { + main := android.BazelLabelForModuleSrcSingle(ctx, *props.Main) + attrs.Main = &main + break + } + } + } + + props := bazel.BazelTargetModuleProperties{ + // Use the native py_binary rule. + Rule_class: "py_binary", + } + + ctx.CreateBazelTargetModule(props, android.CommonAttributes{ + Name: m.Name(), + Data: baseAttrs.Data, + }, attrs) +} + +func (p *PythonLibraryModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + pythonLibBp2Build(ctx, p) +} + +func (p *PythonBinaryModule) ConvertWithBp2build(ctx android.TopDownMutatorContext) { + pythonBinaryBp2Build(ctx, p) +} + +func (p *PythonTestModule) ConvertWithBp2build(_ android.TopDownMutatorContext) { + // Tests are currently unsupported +} diff --git a/python/installer.go b/python/installer.go deleted file mode 100644 index 396f03667..000000000 --- a/python/installer.go +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright 2017 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 python - -import ( - "path/filepath" - - "android/soong/android" -) - -// This file handles installing python executables into their final location - -type installLocation int - -const ( - InstallInData installLocation = iota -) - -type pythonInstaller struct { - dir string - dir64 string - relative string - - path android.InstallPath - - androidMkSharedLibs []string -} - -func NewPythonInstaller(dir, dir64 string) *pythonInstaller { - return &pythonInstaller{ - dir: dir, - dir64: dir64, - } -} - -var _ installer = (*pythonInstaller)(nil) - -func (installer *pythonInstaller) installDir(ctx android.ModuleContext) android.InstallPath { - dir := installer.dir - if ctx.Arch().ArchType.Multilib == "lib64" && installer.dir64 != "" { - dir = installer.dir64 - } - if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) { - dir = filepath.Join(dir, ctx.Arch().ArchType.String()) - } - return android.PathForModuleInstall(ctx, dir, installer.relative) -} - -func (installer *pythonInstaller) install(ctx android.ModuleContext, file android.Path) { - installer.path = ctx.InstallFile(installer.installDir(ctx), file.Base(), file) -} - -func (installer *pythonInstaller) setAndroidMkSharedLibs(sharedLibs []string) { - installer.androidMkSharedLibs = sharedLibs -} diff --git a/python/library.go b/python/library.go index df92df42b..7cdb80b87 100644 --- a/python/library.go +++ b/python/library.go @@ -18,9 +18,6 @@ package python import ( "android/soong/android" - "android/soong/bazel" - - "github.com/google/blueprint/proptools" ) func init() { @@ -33,66 +30,9 @@ func registerPythonLibraryComponents(ctx android.RegistrationContext) { } func PythonLibraryHostFactory() android.Module { - module := newModule(android.HostSupported, android.MultilibFirst) - - android.InitBazelModule(module) - - return module.init() -} - -type bazelPythonLibraryAttributes struct { - Srcs bazel.LabelListAttribute - Deps bazel.LabelListAttribute - Imports bazel.StringListAttribute - Srcs_version *string -} - -type bazelPythonProtoLibraryAttributes struct { - Deps bazel.LabelListAttribute -} - -func pythonLibBp2Build(ctx android.TopDownMutatorContext, m *Module) { - // TODO(b/182306917): this doesn't fully handle all nested props versioned - // by the python version, which would have been handled by the version split - // mutator. This is sufficient for very simple python_library modules under - // Bionic. - py3Enabled := proptools.BoolDefault(m.properties.Version.Py3.Enabled, true) - py2Enabled := proptools.BoolDefault(m.properties.Version.Py2.Enabled, false) - var python_version *string - if py2Enabled && !py3Enabled { - python_version = &pyVersion2 - } else if !py2Enabled && py3Enabled { - python_version = &pyVersion3 - } else if !py2Enabled && !py3Enabled { - ctx.ModuleErrorf("bp2build converter doesn't understand having neither py2 nor py3 enabled") - } else { - // do nothing, since python_version defaults to PY2ANDPY3 - } - - baseAttrs := m.makeArchVariantBaseAttributes(ctx) - - attrs := &bazelPythonLibraryAttributes{ - Srcs: baseAttrs.Srcs, - Deps: baseAttrs.Deps, - Srcs_version: python_version, - Imports: baseAttrs.Imports, - } - - props := bazel.BazelTargetModuleProperties{ - // Use the native py_library rule. - Rule_class: "py_library", - } - - ctx.CreateBazelTargetModule(props, android.CommonAttributes{ - Name: m.Name(), - Data: baseAttrs.Data, - }, attrs) + return newModule(android.HostSupported, android.MultilibFirst).init() } func PythonLibraryFactory() android.Module { - module := newModule(android.HostAndDeviceSupported, android.MultilibBoth) - - android.InitBazelModule(module) - - return module.init() + return newModule(android.HostAndDeviceSupported, android.MultilibBoth).init() } diff --git a/python/python.go b/python/python.go index 24e1bb2ec..2b71e83fe 100644 --- a/python/python.go +++ b/python/python.go @@ -22,8 +22,6 @@ import ( "regexp" "strings" - "android/soong/bazel" - "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -122,26 +120,13 @@ type BaseProperties struct { Embedded_launcher *bool `blueprint:"mutated"` } -type baseAttributes struct { - // TODO(b/200311466): Probably not translate b/c Bazel has no good equiv - //Pkg_path bazel.StringAttribute - // TODO: Related to Pkg_bath and similarLy gated - //Is_internal bazel.BoolAttribute - // Combines Srcs and Exclude_srcs - Srcs bazel.LabelListAttribute - Deps bazel.LabelListAttribute - // Combines Data and Java_data (invariant) - Data bazel.LabelListAttribute - Imports bazel.StringListAttribute -} - // Used to store files of current module after expanding dependencies type pathMapping struct { dest string src android.Path } -type Module struct { +type PythonLibraryModule struct { android.ModuleBase android.DefaultableModuleBase android.BazelModuleBase @@ -153,16 +138,6 @@ type Module struct { hod android.HostOrDeviceSupported multilib android.Multilib - // interface used to bootstrap .par executable when embedded_launcher is true - // this should be set by Python modules which are runnable, e.g. binaries and tests - // bootstrapper might be nil (e.g. Python library module). - bootstrapper bootstrapper - - // interface that implements functions required for installation - // this should be set by Python modules which are runnable, e.g. binaries and tests - // installer might be nil (e.g. Python library module). - installer installer - // the Python files of current module after expanding source dependencies. // pathMapping: <dest: runfile_path, src: source_path> srcsPathMappings []pathMapping @@ -173,110 +148,16 @@ type Module struct { // the zip filepath for zipping current module source/data files. srcsZip android.Path - - // dependency modules' zip filepath for zipping current module source/data files. - depsSrcsZips android.Paths - - // (.intermediate) module output path as installation source. - installSource android.OptionalPath - - // Map to ensure sub-part of the AndroidMk for this module is only added once - subAndroidMkOnce map[subAndroidMkProvider]bool } // newModule generates new Python base module -func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *Module { - return &Module{ +func newModule(hod android.HostOrDeviceSupported, multilib android.Multilib) *PythonLibraryModule { + return &PythonLibraryModule{ hod: hod, multilib: multilib, } } -func (m *Module) makeArchVariantBaseAttributes(ctx android.TopDownMutatorContext) baseAttributes { - var attrs baseAttributes - archVariantBaseProps := m.GetArchVariantProperties(ctx, &BaseProperties{}) - for axis, configToProps := range archVariantBaseProps { - for config, props := range configToProps { - if baseProps, ok := props.(*BaseProperties); ok { - attrs.Srcs.SetSelectValue(axis, config, - android.BazelLabelForModuleSrcExcludes(ctx, baseProps.Srcs, baseProps.Exclude_srcs)) - attrs.Deps.SetSelectValue(axis, config, - android.BazelLabelForModuleDeps(ctx, baseProps.Libs)) - data := android.BazelLabelForModuleSrc(ctx, baseProps.Data) - data.Append(android.BazelLabelForModuleSrc(ctx, baseProps.Java_data)) - attrs.Data.SetSelectValue(axis, config, data) - } - } - } - - partitionedSrcs := bazel.PartitionLabelListAttribute(ctx, &attrs.Srcs, bazel.LabelPartitions{ - "proto": android.ProtoSrcLabelPartition, - "py": bazel.LabelPartition{Keep_remainder: true}, - }) - attrs.Srcs = partitionedSrcs["py"] - - if !partitionedSrcs["proto"].IsEmpty() { - protoInfo, _ := android.Bp2buildProtoProperties(ctx, &m.ModuleBase, partitionedSrcs["proto"]) - protoLabel := bazel.Label{Label: ":" + protoInfo.Name} - - pyProtoLibraryName := m.Name() + "_py_proto" - ctx.CreateBazelTargetModule(bazel.BazelTargetModuleProperties{ - Rule_class: "py_proto_library", - Bzl_load_location: "//build/bazel/rules/python:py_proto.bzl", - }, android.CommonAttributes{ - Name: pyProtoLibraryName, - }, &bazelPythonProtoLibraryAttributes{ - Deps: bazel.MakeSingleLabelListAttribute(protoLabel), - }) - - attrs.Deps.Add(bazel.MakeLabelAttribute(":" + pyProtoLibraryName)) - } - - // Bazel normally requires `import path.from.top.of.tree` statements in - // python code, but with soong you can directly import modules from libraries. - // Add "imports" attributes to the bazel library so it matches soong's behavior. - imports := "." - if m.properties.Pkg_path != nil { - // TODO(b/215119317) This is a hack to handle the fact that we don't convert - // pkg_path properly right now. If the folder structure that contains this - // Android.bp file matches pkg_path, we can set imports to an appropriate - // number of ../..s to emulate moving the files under a pkg_path folder. - pkg_path := filepath.Clean(*m.properties.Pkg_path) - if strings.HasPrefix(pkg_path, "/") { - ctx.ModuleErrorf("pkg_path cannot start with a /: %s", pkg_path) - } - - if !strings.HasSuffix(ctx.ModuleDir(), "/"+pkg_path) && ctx.ModuleDir() != pkg_path { - ctx.ModuleErrorf("Currently, bp2build only supports pkg_paths that are the same as the folders the Android.bp file is in. pkg_path: %s, module directory: %s", pkg_path, ctx.ModuleDir()) - } - numFolders := strings.Count(pkg_path, "/") + 1 - dots := make([]string, numFolders) - for i := 0; i < numFolders; i++ { - dots[i] = ".." - } - imports = strings.Join(dots, "/") - } - attrs.Imports = bazel.MakeStringListAttribute([]string{imports}) - - return attrs -} - -// bootstrapper interface should be implemented for runnable modules, e.g. binary and test -type bootstrapper interface { - bootstrapperProps() []interface{} - bootstrap(ctx android.ModuleContext, ActualVersion string, embeddedLauncher bool, - srcsPathMappings []pathMapping, srcsZip android.Path, - depsSrcsZips android.Paths) android.OptionalPath - - autorun() bool -} - -// installer interface should be implemented for installable modules, e.g. binary and test -type installer interface { - install(ctx android.ModuleContext, path android.Path) - setAndroidMkSharedLibs(sharedLibs []string) -} - // interface implemented by Python modules to provide source and data mappings and zip to python // modules that depend on it type pythonDependency interface { @@ -286,37 +167,31 @@ type pythonDependency interface { } // getSrcsPathMappings gets this module's path mapping of src source path : runfiles destination -func (p *Module) getSrcsPathMappings() []pathMapping { +func (p *PythonLibraryModule) getSrcsPathMappings() []pathMapping { return p.srcsPathMappings } // getSrcsPathMappings gets this module's path mapping of data source path : runfiles destination -func (p *Module) getDataPathMappings() []pathMapping { +func (p *PythonLibraryModule) getDataPathMappings() []pathMapping { return p.dataPathMappings } // getSrcsZip returns the filepath where the current module's source/data files are zipped. -func (p *Module) getSrcsZip() android.Path { +func (p *PythonLibraryModule) getSrcsZip() android.Path { return p.srcsZip } -var _ pythonDependency = (*Module)(nil) +func (p *PythonLibraryModule) getBaseProperties() *BaseProperties { + return &p.properties +} -var _ android.AndroidMkEntriesProvider = (*Module)(nil) +var _ pythonDependency = (*PythonLibraryModule)(nil) -func (p *Module) init(additionalProps ...interface{}) android.Module { +func (p *PythonLibraryModule) init() android.Module { p.AddProperties(&p.properties, &p.protoProperties) - - // Add additional properties for bootstrapping/installation - // This is currently tied to the bootstrapper interface; - // however, these are a combination of properties for the installation and bootstrapping of a module - if p.bootstrapper != nil { - p.AddProperties(p.bootstrapper.bootstrapperProps()...) - } - android.InitAndroidArchModule(p, p.hod, p.multilib) android.InitDefaultableModule(p) - + android.InitBazelModule(p) return p } @@ -350,24 +225,29 @@ var ( internalPath = "internal" ) +type basePropertiesProvider interface { + getBaseProperties() *BaseProperties +} + // versionSplitMutator creates version variants for modules and appends the version-specific // properties for a given variant to the properties in the variant module func versionSplitMutator() func(android.BottomUpMutatorContext) { return func(mctx android.BottomUpMutatorContext) { - if base, ok := mctx.Module().(*Module); ok { - versionNames := []string{} + if base, ok := mctx.Module().(basePropertiesProvider); ok { + props := base.getBaseProperties() + var versionNames []string // collect version specific properties, so that we can merge version-specific properties // into the module's overall properties - versionProps := []VersionProperties{} + var versionProps []VersionProperties // PY3 is first so that we alias the PY3 variant rather than PY2 if both // are available - if proptools.BoolDefault(base.properties.Version.Py3.Enabled, true) { + if proptools.BoolDefault(props.Version.Py3.Enabled, true) { versionNames = append(versionNames, pyVersion3) - versionProps = append(versionProps, base.properties.Version.Py3) + versionProps = append(versionProps, props.Version.Py3) } - if proptools.BoolDefault(base.properties.Version.Py2.Enabled, false) { + if proptools.BoolDefault(props.Version.Py2.Enabled, false) { versionNames = append(versionNames, pyVersion2) - versionProps = append(versionProps, base.properties.Version.Py2) + versionProps = append(versionProps, props.Version.Py2) } modules := mctx.CreateLocalVariations(versionNames...) // Alias module to the first variant @@ -376,9 +256,10 @@ func versionSplitMutator() func(android.BottomUpMutatorContext) { } for i, v := range versionNames { // set the actual version for Python module. - modules[i].(*Module).properties.Actual_version = v + newProps := modules[i].(basePropertiesProvider).getBaseProperties() + newProps.Actual_version = v // append versioned properties for the Python module to the overall properties - err := proptools.AppendMatchingProperties([]interface{}{&modules[i].(*Module).properties}, &versionProps[i], nil) + err := proptools.AppendMatchingProperties([]interface{}{newProps}, &versionProps[i], nil) if err != nil { panic(err) } @@ -387,38 +268,6 @@ func versionSplitMutator() func(android.BottomUpMutatorContext) { } } -// HostToolPath returns a path if appropriate such that this module can be used as a host tool, -// fulfilling HostToolProvider interface. -func (p *Module) HostToolPath() android.OptionalPath { - if p.installer != nil { - if bin, ok := p.installer.(*binaryDecorator); ok { - // TODO: This should only be set when building host binaries -- tests built for device would be - // setting this incorrectly. - return android.OptionalPathForPath(bin.path) - } - } - - return android.OptionalPath{} - -} - -// OutputFiles returns output files based on given tag, returns an error if tag is unsupported. -func (p *Module) OutputFiles(tag string) (android.Paths, error) { - switch tag { - case "": - if outputFile := p.installSource; outputFile.Valid() { - return android.Paths{outputFile.Path()}, nil - } - return android.Paths{}, nil - default: - return nil, fmt.Errorf("unsupported module reference tag %q", tag) - } -} - -func (p *Module) isEmbeddedLauncherEnabled() bool { - return p.installer != nil && Bool(p.properties.Embedded_launcher) -} - func anyHasExt(paths []string, ext string) bool { for _, p := range paths { if filepath.Ext(p) == ext { @@ -429,7 +278,7 @@ func anyHasExt(paths []string, ext string) bool { return false } -func (p *Module) anySrcHasExt(ctx android.BottomUpMutatorContext, ext string) bool { +func (p *PythonLibraryModule) anySrcHasExt(ctx android.BottomUpMutatorContext, ext string) bool { return anyHasExt(p.properties.Srcs, ext) } @@ -437,7 +286,7 @@ func (p *Module) anySrcHasExt(ctx android.BottomUpMutatorContext, ext string) bo // - handles proto dependencies, // - if required, specifies launcher and adds launcher dependencies, // - applies python version mutations to Python dependencies -func (p *Module) DepsMutator(ctx android.BottomUpMutatorContext) { +func (p *PythonLibraryModule) DepsMutator(ctx android.BottomUpMutatorContext) { android.ProtoDeps(ctx, &p.protoProperties) versionVariation := []blueprint.Variation{ @@ -452,111 +301,15 @@ func (p *Module) DepsMutator(ctx android.BottomUpMutatorContext) { // Add python library dependencies for this python version variation ctx.AddVariationDependencies(versionVariation, pythonLibTag, android.LastUniqueStrings(p.properties.Libs)...) - // If this module will be installed and has an embedded launcher, we need to add dependencies for: - // * standard library - // * launcher - // * shared dependencies of the launcher - if p.installer != nil && p.isEmbeddedLauncherEnabled() { - var stdLib string - var launcherModule string - // Add launcher shared lib dependencies. Ideally, these should be - // derived from the `shared_libs` property of the launcher. However, we - // cannot read the property at this stage and it will be too late to add - // dependencies later. - launcherSharedLibDeps := []string{ - "libsqlite", - } - // Add launcher-specific dependencies for bionic - if ctx.Target().Os.Bionic() { - launcherSharedLibDeps = append(launcherSharedLibDeps, "libc", "libdl", "libm") - } - if ctx.Target().Os == android.LinuxMusl && !ctx.Config().HostStaticBinaries() { - launcherSharedLibDeps = append(launcherSharedLibDeps, "libc_musl") - } - - switch p.properties.Actual_version { - case pyVersion2: - stdLib = "py2-stdlib" - - launcherModule = "py2-launcher" - if p.bootstrapper.autorun() { - launcherModule = "py2-launcher-autorun" - } - - launcherSharedLibDeps = append(launcherSharedLibDeps, "libc++") - - case pyVersion3: - stdLib = "py3-stdlib" - - launcherModule = "py3-launcher" - if p.bootstrapper.autorun() { - launcherModule = "py3-launcher-autorun" - } - if ctx.Config().HostStaticBinaries() && ctx.Target().Os == android.LinuxMusl { - launcherModule += "-static" - } - - if ctx.Device() { - launcherSharedLibDeps = append(launcherSharedLibDeps, "liblog") - } - default: - panic(fmt.Errorf("unknown Python Actual_version: %q for module: %q.", - p.properties.Actual_version, ctx.ModuleName())) - } - ctx.AddVariationDependencies(versionVariation, pythonLibTag, stdLib) - ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherTag, launcherModule) - ctx.AddFarVariationDependencies(ctx.Target().Variations(), launcherSharedLibTag, launcherSharedLibDeps...) - } - // Emulate the data property for java_data but with the arch variation overridden to "common" // so that it can point to java modules. javaDataVariation := []blueprint.Variation{{"arch", android.Common.String()}} ctx.AddVariationDependencies(javaDataVariation, javaDataTag, p.properties.Java_data...) } -func (p *Module) GenerateAndroidBuildActions(ctx android.ModuleContext) { - p.generatePythonBuildActions(ctx) - - // Only Python binary and test modules have non-empty bootstrapper. - if p.bootstrapper != nil { - // if the module is being installed, we need to collect all transitive dependencies to embed in - // the final par - p.collectPathsFromTransitiveDeps(ctx) - // bootstrap the module, including resolving main file, getting launcher path, and - // registering actions to build the par file - // bootstrap returns the binary output path - p.installSource = p.bootstrapper.bootstrap(ctx, p.properties.Actual_version, - p.isEmbeddedLauncherEnabled(), p.srcsPathMappings, p.srcsZip, p.depsSrcsZips) - } - - // Only Python binary and test modules have non-empty installer. - if p.installer != nil { - var sharedLibs []string - // if embedded launcher is enabled, we need to collect the shared library depenendencies of the - // launcher - for _, dep := range ctx.GetDirectDepsWithTag(launcherSharedLibTag) { - sharedLibs = append(sharedLibs, ctx.OtherModuleName(dep)) - } - - p.installer.setAndroidMkSharedLibs(sharedLibs) - - // Install the par file from installSource - if p.installSource.Valid() { - p.installer.install(ctx, p.installSource.Path()) - } - } -} - -// generatePythonBuildActions performs build actions common to all Python modules -func (p *Module) generatePythonBuildActions(ctx android.ModuleContext) { +// GenerateAndroidBuildActions performs build actions common to all Python modules +func (p *PythonLibraryModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { expandedSrcs := android.PathsForModuleSrcExcludes(ctx, p.properties.Srcs, p.properties.Exclude_srcs) - requiresSrcs := true - if p.bootstrapper != nil && !p.bootstrapper.autorun() { - requiresSrcs = false - } - if len(expandedSrcs) == 0 && requiresSrcs { - ctx.ModuleErrorf("doesn't have any source files!") - } // expand data files from "data" property. expandedData := android.PathsForModuleSrc(ctx, p.properties.Data) @@ -607,7 +360,7 @@ func isValidPythonPath(path string) error { // For this module, generate unique pathMappings: <dest: runfiles_path, src: source_path> // for python/data files expanded from properties. -func (p *Module) genModulePathMappings(ctx android.ModuleContext, pkgPath string, +func (p *PythonLibraryModule) genModulePathMappings(ctx android.ModuleContext, pkgPath string, expandedSrcs, expandedData android.Paths) { // fetch <runfiles_path, source_path> pairs from "src" and "data" properties to // check current module duplicates. @@ -642,7 +395,7 @@ func (p *Module) genModulePathMappings(ctx android.ModuleContext, pkgPath string } // createSrcsZip registers build actions to zip current module's sources and data. -func (p *Module) createSrcsZip(ctx android.ModuleContext, pkgPath string) android.Path { +func (p *PythonLibraryModule) createSrcsZip(ctx android.ModuleContext, pkgPath string) android.Path { relativeRootMap := make(map[string]android.Paths) pathMappings := append(p.srcsPathMappings, p.dataPathMappings...) @@ -654,13 +407,8 @@ func (p *Module) createSrcsZip(ctx android.ModuleContext, pkgPath string) androi if path.src.Ext() == protoExt { protoSrcs = append(protoSrcs, path.src) } else { - var relativeRoot string - relativeRoot = strings.TrimSuffix(path.src.String(), path.src.Rel()) - if v, found := relativeRootMap[relativeRoot]; found { - relativeRootMap[relativeRoot] = append(v, path.src) - } else { - relativeRootMap[relativeRoot] = android.Paths{path.src} - } + relativeRoot := strings.TrimSuffix(path.src.String(), path.src.Rel()) + relativeRootMap[relativeRoot] = append(relativeRootMap[relativeRoot], path.src) } } var zips android.Paths @@ -736,30 +484,20 @@ func (p *Module) createSrcsZip(ctx android.ModuleContext, pkgPath string) androi } } -// isPythonLibModule returns whether the given module is a Python library Module or not +// isPythonLibModule returns whether the given module is a Python library PythonLibraryModule or not func isPythonLibModule(module blueprint.Module) bool { - if m, ok := module.(*Module); ok { - return m.isLibrary() + if _, ok := module.(*PythonLibraryModule); ok { + if _, ok := module.(*PythonBinaryModule); !ok { + return true + } } return false } -// This is distinguished by the fact that Python libraries are not installable, while other Python -// modules are. -func (p *Module) isLibrary() bool { - // Python library has no bootstrapper or installer - return p.bootstrapper == nil && p.installer == nil -} - -func (p *Module) isBinary() bool { - _, ok := p.bootstrapper.(*binaryDecorator) - return ok -} - // collectPathsFromTransitiveDeps checks for source/data files for duplicate paths // for module and its transitive dependencies and collects list of data/source file // zips for transitive dependencies. -func (p *Module) collectPathsFromTransitiveDeps(ctx android.ModuleContext) { +func (p *PythonLibraryModule) collectPathsFromTransitiveDeps(ctx android.ModuleContext) android.Paths { // fetch <runfiles_path, source_path> pairs from "src" and "data" properties to // check duplicates. destToPySrcs := make(map[string]string) @@ -773,6 +511,8 @@ func (p *Module) collectPathsFromTransitiveDeps(ctx android.ModuleContext) { seen := make(map[android.Module]bool) + var result android.Paths + // visit all its dependencies in depth first. ctx.WalkDeps(func(child, parent android.Module) bool { // we only collect dependencies tagged as python library deps @@ -801,10 +541,11 @@ func (p *Module) collectPathsFromTransitiveDeps(ctx android.ModuleContext) { checkForDuplicateOutputPath(ctx, destToPyData, path.dest, path.src.String(), ctx.ModuleName(), ctx.OtherModuleName(child)) } - p.depsSrcsZips = append(p.depsSrcsZips, dep.getSrcsZip()) + result = append(result, dep.getSrcsZip()) } return true }) + return result } // chckForDuplicateOutputPath checks whether outputPath has already been included in map m, which @@ -825,18 +566,10 @@ func checkForDuplicateOutputPath(ctx android.ModuleContext, m map[string]string, } // InstallInData returns true as Python is not supported in the system partition -func (p *Module) InstallInData() bool { +func (p *PythonLibraryModule) InstallInData() bool { return true } -func (p *Module) ConvertWithBp2build(ctx android.TopDownMutatorContext) { - if p.isLibrary() { - pythonLibBp2Build(ctx, p) - } else if p.isBinary() { - pythonBinaryBp2Build(ctx, p) - } -} - var Bool = proptools.Bool var BoolDefault = proptools.BoolDefault var String = proptools.String diff --git a/python/python_test.go b/python/python_test.go index 42a1ffb2c..6f4223a7c 100644 --- a/python/python_test.go +++ b/python/python_test.go @@ -312,10 +312,6 @@ var ( "e/file4.py", }, srcsZip: "out/soong/.intermediates/dir/bin/PY3/bin.py.srcszip", - depsSrcsZips: []string{ - "out/soong/.intermediates/dir/lib5/PY3/lib5.py.srcszip", - "out/soong/.intermediates/dir/lib6/PY3/lib6.py.srcszip", - }, }, }, }, @@ -346,17 +342,17 @@ func TestPythonModule(t *testing.T) { for _, e := range d.expectedBinaries { t.Run(e.name, func(t *testing.T) { - expectModule(t, result.TestContext, e.name, e.actualVersion, e.srcsZip, e.pyRunfiles, e.depsSrcsZips) + expectModule(t, result.TestContext, e.name, e.actualVersion, e.srcsZip, e.pyRunfiles) }) } }) } } -func expectModule(t *testing.T, ctx *android.TestContext, name, variant, expectedSrcsZip string, expectedPyRunfiles, expectedDepsSrcsZips []string) { +func expectModule(t *testing.T, ctx *android.TestContext, name, variant, expectedSrcsZip string, expectedPyRunfiles []string) { module := ctx.ModuleForTests(name, variant) - base, baseOk := module.Module().(*Module) + base, baseOk := module.Module().(*PythonLibraryModule) if !baseOk { t.Fatalf("%s is not Python module!", name) } @@ -369,8 +365,6 @@ func expectModule(t *testing.T, ctx *android.TestContext, name, variant, expecte android.AssertDeepEquals(t, "pyRunfiles", expectedPyRunfiles, actualPyRunfiles) android.AssertPathRelativeToTopEquals(t, "srcsZip", expectedSrcsZip, base.srcsZip) - - android.AssertPathsRelativeToTopEquals(t, "depsSrcsZips", expectedDepsSrcsZips, base.depsSrcsZips) } func TestMain(m *testing.M) { diff --git a/python/test.go b/python/test.go index fc5c2112f..fb8e91806 100644 --- a/python/test.go +++ b/python/test.go @@ -32,6 +32,20 @@ func registerPythonTestComponents(ctx android.RegistrationContext) { ctx.RegisterModuleType("python_test", PythonTestFactory) } +func NewTest(hod android.HostOrDeviceSupported) *PythonTestModule { + return &PythonTestModule{PythonBinaryModule: *NewBinary(hod)} +} + +func PythonTestHostFactory() android.Module { + return NewTest(android.HostSupportedNoCross).init() +} + +func PythonTestFactory() android.Module { + module := NewTest(android.HostAndDeviceSupported) + module.multilib = android.MultilibBoth + return module.init() +} + type TestProperties struct { // the name of the test configuration (for example "AndroidTest.xml") that should be // installed with the module. @@ -52,76 +66,79 @@ type TestProperties struct { Test_options android.CommonTestOptions } -type testDecorator struct { - *binaryDecorator +type PythonTestModule struct { + PythonBinaryModule testProperties TestProperties - - testConfig android.Path - - data []android.DataPath + testConfig android.Path + data []android.DataPath } -func (test *testDecorator) bootstrapperProps() []interface{} { - return append(test.binaryDecorator.bootstrapperProps(), &test.testProperties) +func (p *PythonTestModule) init() android.Module { + p.AddProperties(&p.properties, &p.protoProperties) + p.AddProperties(&p.binaryProperties) + p.AddProperties(&p.testProperties) + android.InitAndroidArchModule(p, p.hod, p.multilib) + android.InitDefaultableModule(p) + android.InitBazelModule(p) + if p.hod == android.HostSupportedNoCross && p.testProperties.Test_options.Unit_test == nil { + p.testProperties.Test_options.Unit_test = proptools.BoolPtr(true) + } + return p } -func (test *testDecorator) install(ctx android.ModuleContext, file android.Path) { - test.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{ - TestConfigProp: test.testProperties.Test_config, - TestConfigTemplateProp: test.testProperties.Test_config_template, - TestSuites: test.binaryDecorator.binaryProperties.Test_suites, - AutoGenConfig: test.binaryDecorator.binaryProperties.Auto_gen_config, +func (p *PythonTestModule) GenerateAndroidBuildActions(ctx android.ModuleContext) { + // We inherit from only the library's GenerateAndroidBuildActions, and then + // just use buildBinary() so that the binary is not installed into the location + // it would be for regular binaries. + p.PythonLibraryModule.GenerateAndroidBuildActions(ctx) + p.buildBinary(ctx) + + p.testConfig = tradefed.AutoGenTestConfig(ctx, tradefed.AutoGenTestConfigOptions{ + TestConfigProp: p.testProperties.Test_config, + TestConfigTemplateProp: p.testProperties.Test_config_template, + TestSuites: p.binaryProperties.Test_suites, + AutoGenConfig: p.binaryProperties.Auto_gen_config, DeviceTemplate: "${PythonBinaryHostTestConfigTemplate}", HostTemplate: "${PythonBinaryHostTestConfigTemplate}", }) - test.binaryDecorator.pythonInstaller.dir = "nativetest" - test.binaryDecorator.pythonInstaller.dir64 = "nativetest64" + p.installedDest = ctx.InstallFile(installDir(ctx, "nativetest", "nativetest64", ctx.ModuleName()), p.installSource.Base(), p.installSource) - test.binaryDecorator.pythonInstaller.relative = ctx.ModuleName() - - test.binaryDecorator.pythonInstaller.install(ctx, file) - - dataSrcPaths := android.PathsForModuleSrc(ctx, test.testProperties.Data) - - for _, dataSrcPath := range dataSrcPaths { - test.data = append(test.data, android.DataPath{SrcPath: dataSrcPath}) + for _, dataSrcPath := range android.PathsForModuleSrc(ctx, p.testProperties.Data) { + p.data = append(p.data, android.DataPath{SrcPath: dataSrcPath}) } // Emulate the data property for java_data dependencies. for _, javaData := range ctx.GetDirectDepsWithTag(javaDataTag) { for _, javaDataSrcPath := range android.OutputFilesForModule(ctx, javaData, "") { - test.data = append(test.data, android.DataPath{SrcPath: javaDataSrcPath}) + p.data = append(p.data, android.DataPath{SrcPath: javaDataSrcPath}) } } } -func NewTest(hod android.HostOrDeviceSupported) *Module { - module, binary := NewBinary(hod) - - binary.pythonInstaller = NewPythonInstaller("nativetest", "nativetest64") - - test := &testDecorator{binaryDecorator: binary} - if hod == android.HostSupportedNoCross && test.testProperties.Test_options.Unit_test == nil { - test.testProperties.Test_options.Unit_test = proptools.BoolPtr(true) +func (p *PythonTestModule) AndroidMkEntries() []android.AndroidMkEntries { + entriesList := p.PythonBinaryModule.AndroidMkEntries() + if len(entriesList) != 1 { + panic("Expected 1 entry") } + entries := &entriesList[0] - module.bootstrapper = test - module.installer = test + entries.Class = "NATIVE_TESTS" - return module -} + entries.ExtraEntries = append(entries.ExtraEntries, + func(ctx android.AndroidMkExtraEntriesContext, entries *android.AndroidMkEntries) { + //entries.AddCompatibilityTestSuites(p.binaryProperties.Test_suites...) + if p.testConfig != nil { + entries.SetString("LOCAL_FULL_TEST_CONFIG", p.testConfig.String()) + } -func PythonTestHostFactory() android.Module { - module := NewTest(android.HostSupportedNoCross) + entries.SetBoolIfTrue("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", !BoolDefault(p.binaryProperties.Auto_gen_config, true)) - return module.init() -} + entries.AddStrings("LOCAL_TEST_DATA", android.AndroidMkDataPaths(p.data)...) -func PythonTestFactory() android.Module { - module := NewTest(android.HostAndDeviceSupported) - module.multilib = android.MultilibBoth + p.testProperties.Test_options.SetAndroidMkEntries(entries) + }) - return module.init() + return entriesList } diff --git a/rust/bindgen.go b/rust/bindgen.go index 17d80ddee..1ad33a129 100644 --- a/rust/bindgen.go +++ b/rust/bindgen.go @@ -15,7 +15,6 @@ package rust import ( - "fmt" "strings" "github.com/google/blueprint" @@ -178,10 +177,6 @@ func (b *bindgenDecorator) GenerateSource(ctx ModuleContext, deps PathDeps) andr if mctx, ok := ctx.(*moduleContext); ok && mctx.apexVariationName() != "" { cflags = append(cflags, "-D__ANDROID_APEX__") - if ctx.Device() { - cflags = append(cflags, fmt.Sprintf("-D__ANDROID_APEX_MIN_SDK_VERSION__=%d", - ctx.RustModule().apexSdkVersion.FinalOrFutureInt())) - } } if ctx.Target().NativeBridge == android.NativeBridgeEnabled { diff --git a/rust/config/global.go b/rust/config/global.go index 81aec7e73..26e2d06ff 100644 --- a/rust/config/global.go +++ b/rust/config/global.go @@ -24,7 +24,7 @@ import ( var pctx = android.NewPackageContext("android/soong/rust/config") var ( - RustDefaultVersion = "1.64.0" + RustDefaultVersion = "1.65.0" RustDefaultBase = "prebuilts/rust/" DefaultEdition = "2021" Stdlibs = []string{ diff --git a/rust/image.go b/rust/image.go index dfc7f7431..50bf02a4a 100644 --- a/rust/image.go +++ b/rust/image.go @@ -129,6 +129,10 @@ func (ctx *moduleContext) DeviceSpecific() bool { return ctx.ModuleContext.DeviceSpecific() || (ctx.RustModule().InVendor() && ctx.RustModule().VendorVariantToOdm()) } +func (ctx *moduleContext) SystemExtSpecific() bool { + return ctx.ModuleContext.SystemExtSpecific() +} + // Returns true when this module creates a vendor variant and wants to install the vendor variant // to the odm partition. func (c *Module) VendorVariantToOdm() bool { @@ -158,22 +162,15 @@ func (mod *Module) InVendorRamdisk() bool { } func (mod *Module) OnlyInRamdisk() bool { - // TODO(b/165791368) - return false + return mod.ModuleBase.InstallInRamdisk() } func (mod *Module) OnlyInRecovery() bool { - // TODO(b/165791368) - return false + return mod.ModuleBase.InstallInRecovery() } func (mod *Module) OnlyInVendorRamdisk() bool { - return false -} - -func (mod *Module) OnlyInProduct() bool { - //TODO(b/165791368) - return false + return mod.ModuleBase.InstallInVendorRamdisk() } // Returns true when this module is configured to have core and vendor variants. @@ -226,10 +223,7 @@ func (mod *Module) ImageMutatorBegin(mctx android.BaseModuleContext) { // Rust does not support installing to the product image yet. vendorSpecific := mctx.SocSpecific() || mctx.DeviceSpecific() - if mctx.ProductSpecific() { - mctx.PropertyErrorf("product_specific", - "Rust modules do not yet support installing to the product image.") - } else if Bool(mod.VendorProperties.Double_loadable) { + if Bool(mod.VendorProperties.Double_loadable) { mctx.PropertyErrorf("double_loadable", "Rust modules do not yet support double loading") } @@ -243,6 +237,11 @@ func (mod *Module) ImageMutatorBegin(mctx android.BaseModuleContext) { mctx.PropertyErrorf("vendor", "Vendor-only dylibs are not yet supported, use rust_library_rlib.") } } + if mctx.ProductSpecific() { + if lib, ok := mod.compiler.(libraryInterface); ok && lib.buildDylib() { + mctx.PropertyErrorf("product", "Product-only dylibs are not yet supported, use rust_library_rlib.") + } + } cc.MutateImage(mctx, mod) diff --git a/rust/image_test.go b/rust/image_test.go index 95e788f88..818587218 100644 --- a/rust/image_test.go +++ b/rust/image_test.go @@ -103,3 +103,93 @@ func TestForbiddenVendorLinkage(t *testing.T) { } `) } + +func checkInstallPartition(t *testing.T, ctx *android.TestContext, name, variant, expected string) { + mod := ctx.ModuleForTests(name, variant).Module().(*Module) + partitionDefined := false + checkPartition := func(specific bool, partition string) { + if specific { + if expected != partition && !partitionDefined { + // The variant is installed to the 'partition' + t.Errorf("%s variant of %q must not be installed to %s partition", variant, name, partition) + } + partitionDefined = true + } else { + // The variant is not installed to the 'partition' + if expected == partition { + t.Errorf("%s variant of %q must be installed to %s partition", variant, name, partition) + } + } + } + socSpecific := func(m *Module) bool { + return m.SocSpecific() + } + deviceSpecific := func(m *Module) bool { + return m.DeviceSpecific() + } + productSpecific := func(m *Module) bool { + return m.ProductSpecific() || m.productSpecificModuleContext() + } + systemExtSpecific := func(m *Module) bool { + return m.SystemExtSpecific() + } + checkPartition(socSpecific(mod), "vendor") + checkPartition(deviceSpecific(mod), "odm") + checkPartition(productSpecific(mod), "product") + checkPartition(systemExtSpecific(mod), "system_ext") + if !partitionDefined && expected != "system" { + t.Errorf("%s variant of %q is expected to be installed to %s partition,"+ + " but installed to system partition", variant, name, expected) + } +} + +func TestInstallPartition(t *testing.T) { + t.Parallel() + t.Helper() + ctx := testRust(t, ` + rust_binary { + name: "sample_system", + crate_name: "sample", + srcs: ["foo.rs"], + } + rust_binary { + name: "sample_system_ext", + crate_name: "sample", + srcs: ["foo.rs"], + system_ext_specific: true, + } + rust_binary { + name: "sample_product", + crate_name: "sample", + srcs: ["foo.rs"], + product_specific: true, + } + rust_binary { + name: "sample_vendor", + crate_name: "sample", + srcs: ["foo.rs"], + vendor: true, + } + rust_binary { + name: "sample_odm", + crate_name: "sample", + srcs: ["foo.rs"], + device_specific: true, + } + rust_binary { + name: "sample_all_available", + crate_name: "sample", + srcs: ["foo.rs"], + vendor_available: true, + product_available: true, + } + `) + + checkInstallPartition(t, ctx, "sample_system", binaryCoreVariant, "system") + checkInstallPartition(t, ctx, "sample_system_ext", binaryCoreVariant, "system_ext") + checkInstallPartition(t, ctx, "sample_product", binaryProductVariant, "product") + checkInstallPartition(t, ctx, "sample_vendor", binaryVendorVariant, "vendor") + checkInstallPartition(t, ctx, "sample_odm", binaryVendorVariant, "odm") + + checkInstallPartition(t, ctx, "sample_all_available", binaryCoreVariant, "system") +} diff --git a/rust/rust_test.go b/rust/rust_test.go index 97bd541ae..3bcd58cb8 100644 --- a/rust/rust_test.go +++ b/rust/rust_test.go @@ -83,6 +83,10 @@ const ( rlibVendorVariant = "android_vendor.29_arm64_armv8-a_rlib_rlib-std" sharedRecoveryVariant = "android_recovery_arm64_armv8-a_shared" rlibRecoveryVariant = "android_recovery_arm64_armv8-a_rlib_rlib-std" + binaryCoreVariant = "android_arm64_armv8-a" + binaryVendorVariant = "android_vendor.29_arm64_armv8-a" + binaryProductVariant = "android_product.29_arm64_armv8-a" + binaryRecoveryVariant = "android_recovery_arm64_armv8-a" ) func testRustVndkFs(t *testing.T, bp string, fs android.MockFS) *android.TestContext { diff --git a/rust/testing.go b/rust/testing.go index 4796f691a..24ca3d627 100644 --- a/rust/testing.go +++ b/rust/testing.go @@ -104,6 +104,7 @@ func GatherRequiredDepsForTest() string { crate_name: "std", srcs: ["foo.rs"], no_stdlibs: true, + product_available: true, host_supported: true, vendor_available: true, vendor_ramdisk_available: true, diff --git a/ui/metrics/bp2build_progress_metrics_proto/BUILD.bazel b/ui/metrics/bp2build_progress_metrics_proto/BUILD.bazel index 356b18854..f6c6df809 100644 --- a/ui/metrics/bp2build_progress_metrics_proto/BUILD.bazel +++ b/ui/metrics/bp2build_progress_metrics_proto/BUILD.bazel @@ -22,6 +22,6 @@ proto_library( py_proto_library( name = "bp2build_py_proto", + visibility = ["//build/bazel/scripts/bp2build_progress:__pkg__"], deps = [":bp2build_proto"], - visibility = ["//build/bazel/scripts/bp2build-progress:__pkg__"], ) |