diff options
63 files changed, 1689 insertions, 933 deletions
diff --git a/Android.bp b/Android.bp index d7c7dae52..2df1afb66 100644 --- a/Android.bp +++ b/Android.bp @@ -11,14 +11,6 @@ subdirs = [ ] bootstrap_go_package { - name: "soong-env", - pkgPath: "android/soong/env", - srcs: [ - "env/env.go", - ], -} - -bootstrap_go_package { name: "soong", pkgPath: "android/soong", deps: [ @@ -29,542 +21,6 @@ bootstrap_go_package { ], } -bootstrap_go_package { - name: "soong-android", - pkgPath: "android/soong/android", - deps: [ - "blueprint", - "blueprint-bootstrap", - "soong", - "soong-android-soongconfig", - "soong-env", - "soong-shared", - ], - srcs: [ - "android/androidmk.go", - "android/apex.go", - "android/api_levels.go", - "android/arch.go", - "android/config.go", - "android/csuite_config.go", - "android/defaults.go", - "android/defs.go", - "android/expand.go", - "android/filegroup.go", - "android/hooks.go", - "android/image.go", - "android/makevars.go", - "android/module.go", - "android/mutator.go", - "android/namespace.go", - "android/neverallow.go", - "android/notices.go", - "android/onceper.go", - "android/override_module.go", - "android/package.go", - "android/package_ctx.go", - "android/path_properties.go", - "android/paths.go", - "android/prebuilt.go", - "android/prebuilt_etc.go", - "android/proto.go", - "android/register.go", - "android/rule_builder.go", - "android/sandbox.go", - "android/sdk.go", - "android/sh_binary.go", - "android/singleton.go", - "android/soong_config_modules.go", - "android/testing.go", - "android/util.go", - "android/variable.go", - "android/visibility.go", - "android/vts_config.go", - "android/writedocs.go", - - // Lock down environment access last - "android/env.go", - ], - testSrcs: [ - "android/android_test.go", - "android/androidmk_test.go", - "android/arch_test.go", - "android/config_test.go", - "android/csuite_config_test.go", - "android/expand_test.go", - "android/module_test.go", - "android/mutator_test.go", - "android/namespace_test.go", - "android/neverallow_test.go", - "android/onceper_test.go", - "android/package_test.go", - "android/path_properties_test.go", - "android/paths_test.go", - "android/prebuilt_test.go", - "android/prebuilt_etc_test.go", - "android/rule_builder_test.go", - "android/soong_config_modules_test.go", - "android/util_test.go", - "android/variable_test.go", - "android/visibility_test.go", - "android/vts_config_test.go", - ], -} - -bootstrap_go_package { - name: "soong-android-soongconfig", - pkgPath: "android/soong/android/soongconfig", - deps: [ - "blueprint", - "blueprint-parser", - "blueprint-proptools", - ], - srcs: [ - "android/soongconfig/config.go", - "android/soongconfig/modules.go", - ], -} - -bootstrap_go_package { - name: "soong-cc-config", - pkgPath: "android/soong/cc/config", - deps: [ - "soong-android", - "soong-remoteexec", - ], - srcs: [ - "cc/config/clang.go", - "cc/config/global.go", - "cc/config/tidy.go", - "cc/config/toolchain.go", - "cc/config/vndk.go", - - "cc/config/arm_device.go", - "cc/config/arm64_device.go", - "cc/config/arm64_fuchsia_device.go", - "cc/config/mips_device.go", - "cc/config/mips64_device.go", - "cc/config/x86_device.go", - "cc/config/x86_64_device.go", - "cc/config/x86_64_fuchsia_device.go", - - "cc/config/x86_darwin_host.go", - "cc/config/x86_linux_host.go", - "cc/config/x86_linux_bionic_host.go", - "cc/config/x86_windows_host.go", - ], - testSrcs: [ - "cc/config/tidy_test.go", - ], -} - -bootstrap_go_package { - name: "soong-cc", - pkgPath: "android/soong/cc", - deps: [ - "blueprint", - "blueprint-pathtools", - "soong", - "soong-android", - "soong-cc-config", - "soong-genrule", - "soong-tradefed", - ], - srcs: [ - "cc/androidmk.go", - "cc/builder.go", - "cc/cc.go", - "cc/ccdeps.go", - "cc/check.go", - "cc/coverage.go", - "cc/gen.go", - "cc/linkable.go", - "cc/lto.go", - "cc/makevars.go", - "cc/pgo.go", - "cc/prebuilt.go", - "cc/proto.go", - "cc/rs.go", - "cc/sanitize.go", - "cc/sabi.go", - "cc/sdk.go", - "cc/snapshot_utils.go", - "cc/stl.go", - "cc/strip.go", - "cc/sysprop.go", - "cc/tidy.go", - "cc/util.go", - "cc/vendor_snapshot.go", - "cc/vndk.go", - "cc/vndk_prebuilt.go", - - "cc/cflag_artifacts.go", - "cc/cmakelists.go", - "cc/compdb.go", - "cc/compiler.go", - "cc/installer.go", - "cc/linker.go", - - "cc/binary.go", - "cc/binary_sdk_member.go", - "cc/fuzz.go", - "cc/library.go", - "cc/library_headers.go", - "cc/library_sdk_member.go", - "cc/object.go", - "cc/test.go", - "cc/toolchain_library.go", - - "cc/ndk_prebuilt.go", - "cc/ndk_headers.go", - "cc/ndk_library.go", - "cc/ndk_sysroot.go", - - "cc/llndk_library.go", - - "cc/kernel_headers.go", - - "cc/genrule.go", - - "cc/vendor_public_library.go", - - "cc/testing.go", - ], - testSrcs: [ - "cc/cc_test.go", - "cc/compiler_test.go", - "cc/gen_test.go", - "cc/genrule_test.go", - "cc/library_headers_test.go", - "cc/library_test.go", - "cc/object_test.go", - "cc/prebuilt_test.go", - "cc/proto_test.go", - "cc/test_data_test.go", - ], - pluginFor: ["soong_build"], -} - -bootstrap_go_package { - name: "soong-genrule", - pkgPath: "android/soong/genrule", - deps: [ - "blueprint", - "blueprint-pathtools", - "soong", - "soong-android", - "soong-shared", - ], - srcs: [ - "genrule/genrule.go", - ], - testSrcs: [ - "genrule/genrule_test.go", - ], - pluginFor: ["soong_build"], -} - -bootstrap_go_package { - name: "soong-phony", - pkgPath: "android/soong/phony", - deps: [ - "blueprint", - "soong-android", - ], - srcs: [ - "phony/phony.go", - ], - pluginFor: ["soong_build"], -} - -bootstrap_go_package { - name: "soong-java", - pkgPath: "android/soong/java", - deps: [ - "blueprint", - "blueprint-pathtools", - "soong", - "soong-android", - "soong-cc", - "soong-dexpreopt", - "soong-genrule", - "soong-java-config", - "soong-tradefed", - ], - srcs: [ - "java/aapt2.go", - "java/aar.go", - "java/android_manifest.go", - "java/android_resources.go", - "java/androidmk.go", - "java/app_builder.go", - "java/app.go", - "java/builder.go", - "java/device_host_converter.go", - "java/dex.go", - "java/dexpreopt.go", - "java/dexpreopt_bootjars.go", - "java/dexpreopt_config.go", - "java/droiddoc.go", - "java/gen.go", - "java/genrule.go", - "java/hiddenapi.go", - "java/hiddenapi_singleton.go", - "java/jacoco.go", - "java/java.go", - "java/jdeps.go", - "java/java_resources.go", - "java/kotlin.go", - "java/platform_compat_config.go", - "java/plugin.go", - "java/prebuilt_apis.go", - "java/proto.go", - "java/robolectric.go", - "java/sdk.go", - "java/sdk_library.go", - "java/support_libraries.go", - "java/sysprop.go", - "java/system_modules.go", - "java/testing.go", - "java/tradefed.go", - ], - testSrcs: [ - "java/androidmk_test.go", - "java/app_test.go", - "java/device_host_converter_test.go", - "java/dexpreopt_test.go", - "java/dexpreopt_bootjars_test.go", - "java/java_test.go", - "java/jdeps_test.go", - "java/kotlin_test.go", - "java/plugin_test.go", - "java/sdk_test.go", - ], - pluginFor: ["soong_build"], -} - -bootstrap_go_package { - name: "soong-java-config", - pkgPath: "android/soong/java/config", - deps: [ - "blueprint-proptools", - "soong-android", - ], - srcs: [ - "java/config/config.go", - "java/config/error_prone.go", - "java/config/kotlin.go", - "java/config/makevars.go", - ], -} - -bootstrap_go_package { - name: "soong-rust-config", - pkgPath: "android/soong/rust/config", - deps: [ - "soong-android", - "soong-cc-config", - ], - srcs: [ - "rust/config/arm_device.go", - "rust/config/arm64_device.go", - "rust/config/global.go", - "rust/config/toolchain.go", - "rust/config/whitelist.go", - "rust/config/x86_darwin_host.go", - "rust/config/x86_linux_host.go", - "rust/config/x86_device.go", - "rust/config/x86_64_device.go", - ], -} - -bootstrap_go_package { - name: "soong-rust", - pkgPath: "android/soong/rust", - deps: [ - "soong", - "soong-android", - "soong-cc", - "soong-rust-config", - ], - srcs: [ - "rust/androidmk.go", - "rust/compiler.go", - "rust/binary.go", - "rust/builder.go", - "rust/library.go", - "rust/prebuilt.go", - "rust/proc_macro.go", - "rust/rust.go", - "rust/test.go", - "rust/testing.go", - ], - testSrcs: [ - "rust/binary_test.go", - "rust/compiler_test.go", - "rust/library_test.go", - "rust/rust_test.go", - "rust/test_test.go", - ], - pluginFor: ["soong_build"], -} - -bootstrap_go_package { - name: "soong-python", - pkgPath: "android/soong/python", - deps: [ - "blueprint", - "soong-android", - "soong-tradefed", - ], - srcs: [ - "python/androidmk.go", - "python/binary.go", - "python/builder.go", - "python/defaults.go", - "python/installer.go", - "python/library.go", - "python/proto.go", - "python/python.go", - "python/test.go", - ], - testSrcs: [ - "python/python_test.go", - ], - pluginFor: ["soong_build"], -} - -bootstrap_go_package { - name: "soong-shared", - pkgPath: "android/soong/shared", - srcs: [ - "shared/paths.go", - ], -} - -bootstrap_go_package { - name: "soong-tradefed", - pkgPath: "android/soong/tradefed", - deps: [ - "blueprint", - "soong-android", - ], - srcs: [ - "tradefed/autogen.go", - "tradefed/config.go", - "tradefed/makevars.go", - ], - pluginFor: ["soong_build"], -} - -bootstrap_go_package { - name: "soong-xml", - pkgPath: "android/soong/xml", - deps: [ - "blueprint", - "blueprint-pathtools", - "soong", - "soong-android", - ], - srcs: [ - "xml/xml.go", - ], - testSrcs: [ - "xml/xml_test.go", - ], - pluginFor: ["soong_build"], -} - -bootstrap_go_package { - name: "soong-apex", - pkgPath: "android/soong/apex", - deps: [ - "blueprint", - "soong", - "soong-android", - "soong-cc", - "soong-java", - "soong-python", - ], - srcs: [ - "apex/androidmk.go", - "apex/apex.go", - "apex/apex_singleton.go", - "apex/builder.go", - "apex/key.go", - "apex/prebuilt.go", - "apex/vndk.go", - ], - testSrcs: [ - "apex/apex_test.go", - "apex/vndk_test.go", - ], - pluginFor: ["soong_build"], -} - -bootstrap_go_package { - name: "soong-sysprop", - pkgPath: "android/soong/sysprop", - deps: [ - "blueprint", - "soong", - "soong-android", - "soong-cc", - "soong-java", - ], - srcs: [ - "sysprop/sysprop_library.go", - ], - testSrcs: [ - "sysprop/sysprop_test.go", - ], - pluginFor: ["soong_build"], -} - -bootstrap_go_package { - name: "soong-sdk", - pkgPath: "android/soong/sdk", - deps: [ - "blueprint", - "soong", - "soong-android", - "soong-apex", - "soong-cc", - "soong-java", - ], - srcs: [ - "sdk/bp.go", - "sdk/exports.go", - "sdk/sdk.go", - "sdk/update.go", - ], - testSrcs: [ - "sdk/bp_test.go", - "sdk/cc_sdk_test.go", - "sdk/exports_test.go", - "sdk/java_sdk_test.go", - "sdk/sdk_test.go", - "sdk/testing.go", - ], - pluginFor: ["soong_build"], -} - -bootstrap_go_package { - name: "soong-remoteexec", - pkgPath: "android/soong/remoteexec", - deps: [ - "blueprint", - "soong-android", - ], - srcs: [ - "remoteexec/remoteexec.go", - ], - testSrcs: [ - "remoteexec/remoteexec_test.go", - ], - pluginFor: ["soong_build"], -} - // // Defaults to enable various configurations of host bionic // diff --git a/android/Android.bp b/android/Android.bp new file mode 100644 index 000000000..654110647 --- /dev/null +++ b/android/Android.bp @@ -0,0 +1,78 @@ +bootstrap_go_package { + name: "soong-android", + pkgPath: "android/soong/android", + deps: [ + "blueprint", + "blueprint-bootstrap", + "soong", + "soong-android-soongconfig", + "soong-env", + "soong-shared", + ], + srcs: [ + "androidmk.go", + "apex.go", + "api_levels.go", + "arch.go", + "config.go", + "csuite_config.go", + "defaults.go", + "defs.go", + "expand.go", + "filegroup.go", + "hooks.go", + "image.go", + "makevars.go", + "module.go", + "mutator.go", + "namespace.go", + "neverallow.go", + "notices.go", + "onceper.go", + "override_module.go", + "package.go", + "package_ctx.go", + "path_properties.go", + "paths.go", + "prebuilt.go", + "proto.go", + "register.go", + "rule_builder.go", + "sandbox.go", + "sdk.go", + "singleton.go", + "soong_config_modules.go", + "testing.go", + "util.go", + "variable.go", + "visibility.go", + "vts_config.go", + "writedocs.go", + + // Lock down environment access last + "env.go", + ], + testSrcs: [ + "android_test.go", + "androidmk_test.go", + "arch_test.go", + "config_test.go", + "csuite_config_test.go", + "expand_test.go", + "module_test.go", + "mutator_test.go", + "namespace_test.go", + "neverallow_test.go", + "onceper_test.go", + "package_test.go", + "path_properties_test.go", + "paths_test.go", + "prebuilt_test.go", + "rule_builder_test.go", + "soong_config_modules_test.go", + "util_test.go", + "variable_test.go", + "visibility_test.go", + "vts_config_test.go", + ], +} diff --git a/android/package_ctx.go b/android/package_ctx.go index 5a43ea9c7..0de356e1c 100644 --- a/android/package_ctx.go +++ b/android/package_ctx.go @@ -232,30 +232,10 @@ func (p PackageContext) StaticRule(name string, params blueprint.RuleParams, }, argNames...) } -// RBEExperimentalFlag indicates which flag should be set for the AndroidRemoteStaticRule -// to use RBE. -type RBEExperimentalFlag int - -const ( - // RBE_NOT_EXPERIMENTAL indicates the rule should use RBE in every build that has - // UseRBE set. - RBE_NOT_EXPERIMENTAL RBEExperimentalFlag = iota - // RBE_JAVAC indicates the rule should use RBE only if the RBE_JAVAC variable is - // set in an RBE enabled build. - RBE_JAVAC - // RBE_R8 indicates the rule should use RBE only if the RBE_R8 variable is set in - // an RBE enabled build. - RBE_R8 - // RBE_D8 indicates the rule should use RBE only if the RBE_D8 variable is set in - // an RBE enabled build. - RBE_D8 -) - // RemoteRuleSupports configures rules with whether they have Goma and/or RBE support. type RemoteRuleSupports struct { - Goma bool - RBE bool - RBEFlag RBEExperimentalFlag + Goma bool + RBE bool } // AndroidRemoteStaticRule wraps blueprint.StaticRule but uses goma or RBE's parallelism if goma or RBE are enabled @@ -277,18 +257,6 @@ func (p PackageContext) AndroidRemoteStaticRule(name string, supports RemoteRule params.Pool = localPool } - if ctx.Config().UseRBE() && supports.RBE { - if supports.RBEFlag == RBE_JAVAC && !ctx.Config().UseRBEJAVAC() { - params.Pool = localPool - } - if supports.RBEFlag == RBE_R8 && !ctx.Config().UseRBER8() { - params.Pool = localPool - } - if supports.RBEFlag == RBE_D8 && !ctx.Config().UseRBED8() { - params.Pool = localPool - } - } - return params, nil }, argNames...) } diff --git a/android/paths.go b/android/paths.go index 0edda38bf..1d8d92a34 100644 --- a/android/paths.go +++ b/android/paths.go @@ -483,6 +483,15 @@ outer: return list[:k] } +// SortedUniquePaths returns what its name says +func SortedUniquePaths(list Paths) Paths { + unique := FirstUniquePaths(list) + sort.Slice(unique, func(i, j int) bool { + return unique[i].String() < unique[j].String() + }) + return unique +} + // LastUniquePaths returns all unique elements of a Paths, keeping the last copy of each. It // modifies the Paths slice contents in place, and returns a subslice of the original slice. func LastUniquePaths(list Paths) Paths { diff --git a/android/soongconfig/Android.bp b/android/soongconfig/Android.bp new file mode 100644 index 000000000..df912e62e --- /dev/null +++ b/android/soongconfig/Android.bp @@ -0,0 +1,13 @@ +bootstrap_go_package { + name: "soong-android-soongconfig", + pkgPath: "android/soong/android/soongconfig", + deps: [ + "blueprint", + "blueprint-parser", + "blueprint-proptools", + ], + srcs: [ + "config.go", + "modules.go", + ], +} diff --git a/apex/Android.bp b/apex/Android.bp new file mode 100644 index 000000000..144f44197 --- /dev/null +++ b/apex/Android.bp @@ -0,0 +1,27 @@ +bootstrap_go_package { + name: "soong-apex", + pkgPath: "android/soong/apex", + deps: [ + "blueprint", + "soong", + "soong-android", + "soong-cc", + "soong-java", + "soong-python", + "soong-sh", + ], + srcs: [ + "androidmk.go", + "apex.go", + "apex_singleton.go", + "builder.go", + "key.go", + "prebuilt.go", + "vndk.go", + ], + testSrcs: [ + "apex_test.go", + "vndk_test.go", + ], + pluginFor: ["soong_build"], +} diff --git a/apex/apex.go b/apex/apex.go index 34b5595b4..2d1b06dca 100644 --- a/apex/apex.go +++ b/apex/apex.go @@ -23,14 +23,16 @@ import ( "strings" "sync" + "github.com/google/blueprint" + "github.com/google/blueprint/bootstrap" + "github.com/google/blueprint/proptools" + "android/soong/android" "android/soong/cc" + prebuilt_etc "android/soong/etc" "android/soong/java" "android/soong/python" - - "github.com/google/blueprint" - "github.com/google/blueprint/bootstrap" - "github.com/google/blueprint/proptools" + "android/soong/sh" ) const ( @@ -1664,7 +1666,7 @@ func apexFileForGoBinary(ctx android.BaseModuleContext, depName string, gb boots return newApexFile(ctx, fileToCopy, depName, dirInApex, goBinary, nil) } -func apexFileForShBinary(ctx android.BaseModuleContext, sh *android.ShBinary) apexFile { +func apexFileForShBinary(ctx android.BaseModuleContext, sh *sh.ShBinary) apexFile { dirInApex := filepath.Join("bin", sh.SubDir()) fileToCopy := sh.OutputFile() af := newApexFile(ctx, fileToCopy, sh.Name(), dirInApex, shBinary, sh) @@ -1686,7 +1688,7 @@ func apexFileForJavaLibrary(ctx android.BaseModuleContext, lib javaDependency, m return af } -func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt android.PrebuiltEtcModule, depName string) apexFile { +func apexFileForPrebuiltEtc(ctx android.BaseModuleContext, prebuilt prebuilt_etc.PrebuiltEtcModule, depName string) apexFile { dirInApex := filepath.Join("etc", prebuilt.SubDir()) fileToCopy := prebuilt.OutputFile() return newApexFile(ctx, fileToCopy, depName, dirInApex, etc, prebuilt) @@ -1948,7 +1950,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { if cc, ok := child.(*cc.Module); ok { filesInfo = append(filesInfo, apexFileForExecutable(ctx, cc)) return true // track transitive dependencies - } else if sh, ok := child.(*android.ShBinary); ok { + } else if sh, ok := child.(*sh.ShBinary); ok { filesInfo = append(filesInfo, apexFileForShBinary(ctx, sh)) } else if py, ok := child.(*python.Module); ok && py.HostToolPath().Valid() { filesInfo = append(filesInfo, apexFileForPyBinary(ctx, py)) @@ -1989,7 +1991,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { ctx.PropertyErrorf("apps", "%q is not an android_app module", depName) } case prebuiltTag: - if prebuilt, ok := child.(android.PrebuiltEtcModule); ok { + if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok { filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName)) } else if prebuilt, ok := child.(java.PlatformCompatConfigIntf); ok { filesInfo = append(filesInfo, apexFileForCompatConfig(ctx, prebuilt, depName)) @@ -2086,7 +2088,7 @@ func (a *apexBundle) GenerateAndroidBuildActions(ctx android.ModuleContext) { // Because APK-in-APEX embeds jni_libs transitively, we don't need to track transitive deps return false } else if java.IsXmlPermissionsFileDepTag(depTag) { - if prebuilt, ok := child.(android.PrebuiltEtcModule); ok { + if prebuilt, ok := child.(prebuilt_etc.PrebuiltEtcModule); ok { filesInfo = append(filesInfo, apexFileForPrebuiltEtc(ctx, prebuilt, depName)) } } else if am.CanHaveApexVariants() && am.IsInstallableToApex() { diff --git a/apex/apex_test.go b/apex/apex_test.go index 89f8c8993..3ff47ce85 100644 --- a/apex/apex_test.go +++ b/apex/apex_test.go @@ -29,7 +29,9 @@ import ( "android/soong/android" "android/soong/cc" "android/soong/dexpreopt" + prebuilt_etc "android/soong/etc" "android/soong/java" + "android/soong/sh" ) var buildDir string @@ -209,9 +211,9 @@ func testApexContext(t *testing.T, bp string, handlers ...testCustomizer) (*andr ctx.RegisterModuleType("cc_test", cc.TestFactory) ctx.RegisterModuleType("vndk_prebuilt_shared", cc.VndkPrebuiltSharedFactory) ctx.RegisterModuleType("vndk_libraries_txt", cc.VndkLibrariesTxtFactory) - ctx.RegisterModuleType("prebuilt_etc", android.PrebuiltEtcFactory) + ctx.RegisterModuleType("prebuilt_etc", prebuilt_etc.PrebuiltEtcFactory) ctx.RegisterModuleType("platform_compat_config", java.PlatformCompatConfigFactory) - ctx.RegisterModuleType("sh_binary", android.ShBinaryFactory) + ctx.RegisterModuleType("sh_binary", sh.ShBinaryFactory) ctx.RegisterModuleType("filegroup", android.FileGroupFactory) java.RegisterJavaBuildComponents(ctx) java.RegisterSystemModulesBuildComponents(ctx) diff --git a/apex/builder.go b/apex/builder.go index ee097e49f..fce250365 100644 --- a/apex/builder.go +++ b/apex/builder.go @@ -238,7 +238,7 @@ func (a *apexBundle) buildNoticeFiles(ctx android.ModuleContext, apexFileName st return android.NoticeOutputs{} } - return android.BuildNoticeOutput(ctx, a.installDir, apexFileName, android.FirstUniquePaths(noticeFiles)) + return android.BuildNoticeOutput(ctx, a.installDir, apexFileName, android.SortedUniquePaths(noticeFiles)) } func (a *apexBundle) buildInstalledFilesFile(ctx android.ModuleContext, builtApex android.Path, imageDir android.Path) android.OutputPath { @@ -557,19 +557,27 @@ func (a *apexBundle) buildUnflattenedApex(ctx android.ModuleContext) { } a.outputFile = android.PathForModuleOut(ctx, a.Name()+suffix) + rule := java.Signapk + args := map[string]string{ + "certificates": a.container_certificate_file.String() + " " + a.container_private_key_file.String(), + "flags": "-a 4096", //alignment + } + implicits := android.Paths{ + a.container_certificate_file, + a.container_private_key_file, + } + if ctx.Config().IsEnvTrue("RBE_SIGNAPK") { + rule = java.SignapkRE + args["implicits"] = strings.Join(implicits.Strings(), ",") + args["outCommaList"] = a.outputFile.String() + } ctx.Build(pctx, android.BuildParams{ - Rule: java.Signapk, + Rule: rule, Description: "signapk", Output: a.outputFile, Input: unsignedOutputFile, - Implicits: []android.Path{ - a.container_certificate_file, - a.container_private_key_file, - }, - Args: map[string]string{ - "certificates": a.container_certificate_file.String() + " " + a.container_private_key_file.String(), - "flags": "-a 4096", //alignment - }, + Implicits: implicits, + Args: args, }) // Install to $OUT/soong/{target,host}/.../apex diff --git a/cc/Android.bp b/cc/Android.bp new file mode 100644 index 000000000..9ece05f6c --- /dev/null +++ b/cc/Android.bp @@ -0,0 +1,87 @@ +bootstrap_go_package { + name: "soong-cc", + pkgPath: "android/soong/cc", + deps: [ + "blueprint", + "blueprint-pathtools", + "soong", + "soong-android", + "soong-cc-config", + "soong-etc", + "soong-genrule", + "soong-tradefed", + ], + srcs: [ + "androidmk.go", + "builder.go", + "cc.go", + "ccdeps.go", + "check.go", + "coverage.go", + "gen.go", + "linkable.go", + "lto.go", + "makevars.go", + "pgo.go", + "prebuilt.go", + "proto.go", + "rs.go", + "sanitize.go", + "sabi.go", + "sdk.go", + "snapshot_utils.go", + "stl.go", + "strip.go", + "sysprop.go", + "tidy.go", + "util.go", + "vendor_snapshot.go", + "vndk.go", + "vndk_prebuilt.go", + + "cflag_artifacts.go", + "cmakelists.go", + "compdb.go", + "compiler.go", + "installer.go", + "linker.go", + + "binary.go", + "binary_sdk_member.go", + "fuzz.go", + "library.go", + "library_headers.go", + "library_sdk_member.go", + "object.go", + "test.go", + "toolchain_library.go", + + "ndk_prebuilt.go", + "ndk_headers.go", + "ndk_library.go", + "ndk_sysroot.go", + + "llndk_library.go", + + "kernel_headers.go", + + "genrule.go", + + "vendor_public_library.go", + + "testing.go", + ], + testSrcs: [ + "cc_test.go", + "compiler_test.go", + "gen_test.go", + "genrule_test.go", + "library_headers_test.go", + "library_test.go", + "object_test.go", + "prebuilt_test.go", + "proto_test.go", + "test_data_test.go", + ], + pluginFor: ["soong_build"], +} diff --git a/cc/androidmk.go b/cc/androidmk.go index 5438b149d..fede601b4 100644 --- a/cc/androidmk.go +++ b/cc/androidmk.go @@ -540,6 +540,25 @@ func (c *vendorSnapshotBinaryDecorator) AndroidMkEntries(ctx AndroidMkContext, e }) } +func (c *vendorSnapshotObjectLinker) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) { + entries.Class = "STATIC_LIBRARIES" + + if c.androidMkVendorSuffix { + entries.SubName = vendorSuffix + } else { + entries.SubName = "" + } + + entries.ExtraFooters = append(entries.ExtraFooters, + func(w io.Writer, name, prefix, moduleDir string, entries *android.AndroidMkEntries) { + out := entries.OutputFile.Path() + varname := fmt.Sprintf("SOONG_%sOBJECT_%s%s", prefix, name, entries.SubName) + + fmt.Fprintf(w, "\n%s := %s\n", varname, out.String()) + fmt.Fprintln(w, ".KATI_READONLY: "+varname) + }) +} + func (c *ndkPrebuiltStlLinker) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) { entries.Class = "SHARED_LIBRARIES" } diff --git a/cc/binary.go b/cc/binary.go index 661264eef..251b7f0c4 100644 --- a/cc/binary.go +++ b/cc/binary.go @@ -231,6 +231,10 @@ func (binary *binaryDecorator) staticBinary() bool { return binary.static() } +func (binary *binaryDecorator) binary() bool { + return true +} + func (binary *binaryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags { flags = binary.baseLinker.linkerFlags(ctx, flags) @@ -309,6 +309,8 @@ type ModuleContextIntf interface { static() bool staticBinary() bool header() bool + binary() bool + object() bool toolchain() config.Toolchain canUseSdk() bool useSdk() bool @@ -1002,14 +1004,8 @@ func (c *Module) nativeCoverage() bool { } func (c *Module) isSnapshotPrebuilt() bool { - if _, ok := c.linker.(*vndkPrebuiltLibraryDecorator); ok { - return true - } - if _, ok := c.linker.(*vendorSnapshotLibraryDecorator); ok { - return true - } - if _, ok := c.linker.(*vendorSnapshotBinaryDecorator); ok { - return true + if p, ok := c.linker.(interface{ isSnapshotPrebuilt() bool }); ok { + return p.isSnapshotPrebuilt() } return false } @@ -1114,6 +1110,14 @@ func (ctx *moduleContextImpl) header() bool { return ctx.mod.header() } +func (ctx *moduleContextImpl) binary() bool { + return ctx.mod.binary() +} + +func (ctx *moduleContextImpl) object() bool { + return ctx.mod.object() +} + func (ctx *moduleContextImpl) canUseSdk() bool { return ctx.mod.canUseSdk() } @@ -1896,7 +1900,7 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { if deps.StaticUnwinderIfLegacy { actx.AddVariationDependencies([]blueprint.Variation{ {Mutator: "link", Variation: "static"}, - }, staticUnwinderDepTag, staticUnwinder(actx)) + }, staticUnwinderDepTag, rewriteSnapshotLibs(staticUnwinder(actx), vendorSnapshotStaticLibs)) } for _, lib := range deps.LateStaticLibs { @@ -1977,11 +1981,13 @@ func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) { actx.AddVariationDependencies(nil, objDepTag, deps.ObjFiles...) + vendorSnapshotObjects := vendorSnapshotObjects(actx.Config()) + if deps.CrtBegin != "" { - actx.AddVariationDependencies(nil, CrtBeginDepTag, deps.CrtBegin) + actx.AddVariationDependencies(nil, CrtBeginDepTag, rewriteSnapshotLibs(deps.CrtBegin, vendorSnapshotObjects)) } if deps.CrtEnd != "" { - actx.AddVariationDependencies(nil, CrtEndDepTag, deps.CrtEnd) + actx.AddVariationDependencies(nil, CrtEndDepTag, rewriteSnapshotLibs(deps.CrtEnd, vendorSnapshotObjects)) } if deps.LinkerFlagsFile != "" { actx.AddDependency(c, linkerFlagsDepTag, deps.LinkerFlagsFile) @@ -2713,6 +2719,24 @@ func (c *Module) header() bool { return false } +func (c *Module) binary() bool { + if b, ok := c.linker.(interface { + binary() bool + }); ok { + return b.binary() + } + return false +} + +func (c *Module) object() bool { + if o, ok := c.linker.(interface { + object() bool + }); ok { + return o.object() + } + return false +} + func (c *Module) getMakeLinkType(actx android.ModuleContext) string { if c.UseVndk() { if lib, ok := c.linker.(*llndkStubDecorator); ok { @@ -3022,20 +3046,32 @@ func (m *Module) ImageMutatorBegin(mctx android.BaseModuleContext) { // This will be available in /system, /vendor and /product // or a /system directory that is available to vendor and product. coreVariantNeeded = true - vendorVariants = append(vendorVariants, platformVndkVersion) - productVariants = append(productVariants, platformVndkVersion) - // VNDK modules must not create BOARD_VNDK_VERSION variant because its - // code is PLATFORM_VNDK_VERSION. - // On the other hand, vendor_available modules which are not VNDK should - // also build BOARD_VNDK_VERSION because it's installed in /vendor. + + // We assume that modules under proprietary paths are compatible for + // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or + // PLATFORM_VNDK_VERSION. + if isVendorProprietaryPath(mctx.ModuleDir()) { + vendorVariants = append(vendorVariants, boardVndkVersion) + } else { + vendorVariants = append(vendorVariants, platformVndkVersion) + } + // vendor_available modules are also available to /product. + productVariants = append(productVariants, platformVndkVersion) + // VNDK is always PLATFORM_VNDK_VERSION if !m.IsVndk() { - vendorVariants = append(vendorVariants, boardVndkVersion) productVariants = append(productVariants, productVndkVersion) } } else if vendorSpecific && String(m.Properties.Sdk_version) == "" { // This will be available in /vendor (or /odm) only - vendorVariants = append(vendorVariants, boardVndkVersion) + // We assume that modules under proprietary paths are compatible for + // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, or + // PLATFORM_VNDK_VERSION. + if isVendorProprietaryPath(mctx.ModuleDir()) { + vendorVariants = append(vendorVariants, boardVndkVersion) + } else { + vendorVariants = append(vendorVariants, platformVndkVersion) + } } else { // This is either in /system (or similar: /data), or is a // modules built with the NDK. Modules built with the NDK diff --git a/cc/cc_test.go b/cc/cc_test.go index 67eb248d2..76b4e38e2 100644 --- a/cc/cc_test.go +++ b/cc/cc_test.go @@ -258,9 +258,7 @@ func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string } } -func checkSnapshot(t *testing.T, ctx *android.TestContext, singletonName, moduleName, snapshotFilename, subDir, variant string) { - snapshotSingleton := ctx.SingletonForTests(singletonName) - +func checkSnapshot(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string) { mod, ok := ctx.ModuleForTests(moduleName, variant).Module().(android.OutputFileProducer) if !ok { t.Errorf("%q must have output\n", moduleName) @@ -273,7 +271,7 @@ func checkSnapshot(t *testing.T, ctx *android.TestContext, singletonName, module } snapshotPath := filepath.Join(subDir, snapshotFilename) - out := snapshotSingleton.Output(snapshotPath) + out := singleton.Output(snapshotPath) if out.Input.String() != outputFiles[0].String() { t.Errorf("The input of snapshot %q must be %q, but %q", moduleName, out.Input.String(), outputFiles[0]) } @@ -398,16 +396,18 @@ func TestVndk(t *testing.T) { variant := "android_vendor.VER_arm64_armv8-a_shared" variant2nd := "android_vendor.VER_arm_armv7-a-neon_shared" - checkSnapshot(t, ctx, "vndk-snapshot", "libvndk", "libvndk.so", vndkCoreLibPath, variant) - checkSnapshot(t, ctx, "vndk-snapshot", "libvndk", "libvndk.so", vndkCoreLib2ndPath, variant2nd) - checkSnapshot(t, ctx, "vndk-snapshot", "libvndk_sp", "libvndk_sp-x.so", vndkSpLibPath, variant) - checkSnapshot(t, ctx, "vndk-snapshot", "libvndk_sp", "libvndk_sp-x.so", vndkSpLib2ndPath, variant2nd) + snapshotSingleton := ctx.SingletonForTests("vndk-snapshot") + + checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", vndkCoreLibPath, variant) + checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", vndkCoreLib2ndPath, variant2nd) + checkSnapshot(t, ctx, snapshotSingleton, "libvndk_sp", "libvndk_sp-x.so", vndkSpLibPath, variant) + checkSnapshot(t, ctx, snapshotSingleton, "libvndk_sp", "libvndk_sp-x.so", vndkSpLib2ndPath, variant2nd) snapshotConfigsPath := filepath.Join(snapshotVariantPath, "configs") - checkSnapshot(t, ctx, "vndk-snapshot", "llndk.libraries.txt", "llndk.libraries.txt", snapshotConfigsPath, "") - checkSnapshot(t, ctx, "vndk-snapshot", "vndkcore.libraries.txt", "vndkcore.libraries.txt", snapshotConfigsPath, "") - checkSnapshot(t, ctx, "vndk-snapshot", "vndksp.libraries.txt", "vndksp.libraries.txt", snapshotConfigsPath, "") - checkSnapshot(t, ctx, "vndk-snapshot", "vndkprivate.libraries.txt", "vndkprivate.libraries.txt", snapshotConfigsPath, "") + checkSnapshot(t, ctx, snapshotSingleton, "llndk.libraries.txt", "llndk.libraries.txt", snapshotConfigsPath, "") + checkSnapshot(t, ctx, snapshotSingleton, "vndkcore.libraries.txt", "vndkcore.libraries.txt", snapshotConfigsPath, "") + checkSnapshot(t, ctx, snapshotSingleton, "vndksp.libraries.txt", "vndksp.libraries.txt", snapshotConfigsPath, "") + checkSnapshot(t, ctx, snapshotSingleton, "vndkprivate.libraries.txt", "vndkprivate.libraries.txt", snapshotConfigsPath, "") checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{ "LLNDK: libc.so", @@ -839,6 +839,17 @@ func TestVendorSnapshot(t *testing.T) { vendor_available: true, nocrt: true, } + + toolchain_library { + name: "libb", + vendor_available: true, + src: "libb.a", + } + + cc_object { + name: "obj", + vendor_available: true, + } ` config := TestConfig(buildDir, android.Android, nil, bp, nil) config.TestProductVariables.DeviceVndkVersion = StringPtr("current") @@ -849,6 +860,9 @@ func TestVendorSnapshot(t *testing.T) { snapshotDir := "vendor-snapshot" snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64") + snapshotSingleton := ctx.SingletonForTests("vendor-snapshot") + + var jsonFiles []string for _, arch := range [][]string{ []string{"arm64", "armv8-a"}, @@ -861,22 +875,51 @@ func TestVendorSnapshot(t *testing.T) { // For shared libraries, only non-VNDK vendor_available modules are captured sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant) sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared") - checkSnapshot(t, ctx, "vendor-snapshot", "libvendor", "libvendor.so", sharedDir, sharedVariant) - checkSnapshot(t, ctx, "vendor-snapshot", "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant) + checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant) + checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant) + jsonFiles = append(jsonFiles, + filepath.Join(sharedDir, "libvendor.so.json"), + filepath.Join(sharedDir, "libvendor_available.so.json")) // For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured. staticVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static", archType, archVariant) staticDir := filepath.Join(snapshotVariantPath, archDir, "static") - checkSnapshot(t, ctx, "vendor-snapshot", "libvndk", "libvndk.a", staticDir, staticVariant) - checkSnapshot(t, ctx, "vendor-snapshot", "libvendor", "libvendor.a", staticDir, staticVariant) - checkSnapshot(t, ctx, "vendor-snapshot", "libvendor_available", "libvendor_available.a", staticDir, staticVariant) - - // For binary libraries, all vendor:true and vendor_available modules are captured. + checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant) + checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.a", staticDir, staticVariant) + checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.a", staticDir, staticVariant) + checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.a", staticDir, staticVariant) + jsonFiles = append(jsonFiles, + filepath.Join(staticDir, "libb.a.json"), + filepath.Join(staticDir, "libvndk.a.json"), + filepath.Join(staticDir, "libvendor.a.json"), + filepath.Join(staticDir, "libvendor_available.a.json")) + + // For binary executables, all vendor:true and vendor_available modules are captured. if archType == "arm64" { binaryVariant := fmt.Sprintf("android_vendor.VER_%s_%s", archType, archVariant) binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary") - checkSnapshot(t, ctx, "vendor-snapshot", "vendor_bin", "vendor_bin", binaryDir, binaryVariant) - checkSnapshot(t, ctx, "vendor-snapshot", "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant) + checkSnapshot(t, ctx, snapshotSingleton, "vendor_bin", "vendor_bin", binaryDir, binaryVariant) + checkSnapshot(t, ctx, snapshotSingleton, "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant) + jsonFiles = append(jsonFiles, + filepath.Join(binaryDir, "vendor_bin.json"), + filepath.Join(binaryDir, "vendor_available_bin.json")) + } + + // For header libraries, all vendor:true and vendor_available modules are captured. + headerDir := filepath.Join(snapshotVariantPath, archDir, "header") + jsonFiles = append(jsonFiles, filepath.Join(headerDir, "libvendor_headers.json")) + + // For object modules, all vendor:true and vendor_available modules are captured. + objectVariant := fmt.Sprintf("android_vendor.VER_%s_%s", archType, archVariant) + objectDir := filepath.Join(snapshotVariantPath, archDir, "object") + checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant) + jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json")) + } + + for _, jsonFile := range jsonFiles { + // verify all json files exist + if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil { + t.Errorf("%q expected but not found", jsonFile) } } } diff --git a/cc/config/Android.bp b/cc/config/Android.bp new file mode 100644 index 000000000..7edb0c988 --- /dev/null +++ b/cc/config/Android.bp @@ -0,0 +1,32 @@ +bootstrap_go_package { + name: "soong-cc-config", + pkgPath: "android/soong/cc/config", + deps: [ + "soong-android", + "soong-remoteexec", + ], + srcs: [ + "clang.go", + "global.go", + "tidy.go", + "toolchain.go", + "vndk.go", + + "arm_device.go", + "arm64_device.go", + "arm64_fuchsia_device.go", + "mips_device.go", + "mips64_device.go", + "x86_device.go", + "x86_64_device.go", + "x86_64_fuchsia_device.go", + + "x86_darwin_host.go", + "x86_linux_host.go", + "x86_linux_bionic_host.go", + "x86_windows_host.go", + ], + testSrcs: [ + "tidy_test.go", + ], +} diff --git a/cc/config/global.go b/cc/config/global.go index f4d188e83..aaffcbc17 100644 --- a/cc/config/global.go +++ b/cc/config/global.go @@ -257,10 +257,10 @@ func init() { return "" }) - pctx.VariableFunc("RECXXPool", envOverrideFunc("RBE_CXX_POOL", remoteexec.DefaultPool)) - pctx.VariableFunc("RECXXLinksPool", envOverrideFunc("RBE_CXX_LINKS_POOL", remoteexec.DefaultPool)) - pctx.VariableFunc("RECXXLinksExecStrategy", envOverrideFunc("RBE_CXX_LINKS_EXEC_STRATEGY", remoteexec.LocalExecStrategy)) - pctx.VariableFunc("REAbiDumperExecStrategy", envOverrideFunc("RBE_ABI_DUMPER_EXEC_STRATEGY", remoteexec.LocalExecStrategy)) + pctx.VariableFunc("RECXXPool", remoteexec.EnvOverrideFunc("RBE_CXX_POOL", remoteexec.DefaultPool)) + pctx.VariableFunc("RECXXLinksPool", remoteexec.EnvOverrideFunc("RBE_CXX_LINKS_POOL", remoteexec.DefaultPool)) + pctx.VariableFunc("RECXXLinksExecStrategy", remoteexec.EnvOverrideFunc("RBE_CXX_LINKS_EXEC_STRATEGY", remoteexec.LocalExecStrategy)) + pctx.VariableFunc("REAbiDumperExecStrategy", remoteexec.EnvOverrideFunc("RBE_ABI_DUMPER_EXEC_STRATEGY", remoteexec.LocalExecStrategy)) } var HostPrebuiltTag = pctx.VariableConfigMethod("HostPrebuiltTag", android.Config.PrebuiltOS) diff --git a/cc/genrule.go b/cc/genrule.go index 9331448b8..66d178456 100644 --- a/cc/genrule.go +++ b/cc/genrule.go @@ -79,8 +79,14 @@ func (g *GenruleExtraProperties) ExtraImageVariations(ctx android.BaseModuleCont var variants []string if Bool(g.Vendor_available) || ctx.SocSpecific() || ctx.DeviceSpecific() { - variants = append(variants, VendorVariationPrefix+ctx.DeviceConfig().PlatformVndkVersion()) - if vndkVersion := ctx.DeviceConfig().VndkVersion(); vndkVersion != "current" { + vndkVersion := ctx.DeviceConfig().VndkVersion() + // If vndkVersion is current, we can always use PlatformVndkVersion. + // If not, we assume modules under proprietary paths are compatible for + // BOARD_VNDK_VERSION. The other modules are regarded as AOSP, that is + // PLATFORM_VNDK_VERSION. + if vndkVersion == "current" || !isVendorProprietaryPath(ctx.ModuleDir()) { + variants = append(variants, VendorVariationPrefix+ctx.DeviceConfig().PlatformVndkVersion()) + } else { variants = append(variants, VendorVariationPrefix+vndkVersion) } } diff --git a/cc/library.go b/cc/library.go index 8d4992cb3..3deb17300 100644 --- a/cc/library.go +++ b/cc/library.go @@ -403,6 +403,31 @@ func (l *libraryDecorator) collectHeadersForSnapshot(ctx android.ModuleContext) if strings.HasPrefix(dir, android.PathForOutput(ctx).String()) { continue } + // libeigen wrongly exports the root directory "external/eigen". But only two + // subdirectories "Eigen" and "unsupported" contain exported header files. Even worse + // some of them have no extension. So we need special treatment for libeigen in order + // to glob correctly. + if dir == "external/eigen" { + // Only these two directories contains exported headers. + for _, subdir := range []string{"Eigen", "unsupported/Eigen"} { + glob, err := ctx.GlobWithDeps("external/eigen/"+subdir+"/**/*", nil) + if err != nil { + ctx.ModuleErrorf("glob failed: %#v", err) + return + } + for _, header := range glob { + if strings.HasSuffix(header, "/") { + continue + } + ext := filepath.Ext(header) + if ext != "" && ext != ".h" { + continue + } + ret = append(ret, android.PathForSource(ctx, header)) + } + } + continue + } exts := headerExts // Glob all files under this special directory, because of C++ headers. if strings.HasPrefix(dir, "external/libcxx/include") { diff --git a/cc/object.go b/cc/object.go index 19decec37..15a529e85 100644 --- a/cc/object.go +++ b/cc/object.go @@ -158,3 +158,7 @@ func (object *objectLinker) nativeCoverage() bool { func (object *objectLinker) coverageOutputFilePath() android.OptionalPath { return android.OptionalPath{} } + +func (object *objectLinker) object() bool { + return true +} diff --git a/cc/prebuilt.go b/cc/prebuilt.go index 2ef31950e..b7c0bf2fd 100644 --- a/cc/prebuilt.go +++ b/cc/prebuilt.go @@ -248,6 +248,10 @@ func (p *prebuiltObjectLinker) link(ctx ModuleContext, return nil } +func (p *prebuiltObjectLinker) object() bool { + return true +} + func newPrebuiltObject() *Module { module := newObject() prebuilt := &prebuiltObjectLinker{ @@ -306,6 +310,10 @@ func (p *prebuiltBinaryLinker) link(ctx ModuleContext, return nil } +func (p *prebuiltBinaryLinker) binary() bool { + return true +} + // cc_prebuilt_binary installs a precompiled executable in srcs property in the // device's directory. func prebuiltBinaryFactory() android.Module { diff --git a/cc/testing.go b/cc/testing.go index 611992070..d92309f3d 100644 --- a/cc/testing.go +++ b/cc/testing.go @@ -457,6 +457,7 @@ func TestConfig(buildDir string, os android.OsType, env map[string]string, "my_include": nil, "foo.map.txt": nil, "liba.so": nil, + "libb.a": nil, } GatherRequiredFilesForTest(mockFS) diff --git a/cc/vendor_snapshot.go b/cc/vendor_snapshot.go index c79a653cd..2e2a779f6 100644 --- a/cc/vendor_snapshot.go +++ b/cc/vendor_snapshot.go @@ -30,6 +30,7 @@ const ( vendorSnapshotSharedSuffix = ".vendor_shared." vendorSnapshotStaticSuffix = ".vendor_static." vendorSnapshotBinarySuffix = ".vendor_binary." + vendorSnapshotObjectSuffix = ".vendor_object." ) var ( @@ -39,6 +40,7 @@ var ( vendorSnapshotStaticLibsKey = android.NewOnceKey("vendorSnapshotStaticLibs") vendorSnapshotSharedLibsKey = android.NewOnceKey("vendorSnapshotSharedLibs") vendorSnapshotBinariesKey = android.NewOnceKey("vendorSnapshotBinaries") + vendorSnapshotObjectsKey = android.NewOnceKey("vendorSnapshotObjects") ) // vendor snapshot maps hold names of vendor snapshot modules per arch @@ -72,6 +74,12 @@ func vendorSnapshotBinaries(config android.Config) *snapshotMap { }).(*snapshotMap) } +func vendorSnapshotObjects(config android.Config) *snapshotMap { + return config.Once(vendorSnapshotObjectsKey, func() interface{} { + return newSnapshotMap() + }).(*snapshotMap) +} + type vendorSnapshotLibraryProperties struct { // snapshot version. Version string @@ -185,6 +193,10 @@ func (p *vendorSnapshotLibraryDecorator) nativeCoverage() bool { return false } +func (p *vendorSnapshotLibraryDecorator) isSnapshotPrebuilt() bool { + return true +} + func (p *vendorSnapshotLibraryDecorator) install(ctx ModuleContext, file android.Path) { if p.matchesWithDevice(ctx.DeviceConfig()) && (p.shared() || p.static()) { p.baseInstaller.install(ctx, file) @@ -337,6 +349,10 @@ func (p *vendorSnapshotBinaryDecorator) link(ctx ModuleContext, return outputFile } +func (p *vendorSnapshotBinaryDecorator) isSnapshotPrebuilt() bool { + return true +} + func VendorSnapshotBinaryFactory() android.Module { module, binary := NewBinary(android.DeviceSupported) binary.baseLinker.Properties.No_libcrt = BoolPtr(true) @@ -364,12 +380,98 @@ func VendorSnapshotBinaryFactory() android.Module { return module.Init() } +type vendorSnapshotObjectProperties struct { + // snapshot version. + Version string + + // Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64_ab') + Target_arch string + + // Prebuilt file for each arch. + Src *string `android:"arch_variant"` +} + +type vendorSnapshotObjectLinker struct { + objectLinker + properties vendorSnapshotObjectProperties + androidMkVendorSuffix bool +} + +func (p *vendorSnapshotObjectLinker) Name(name string) string { + return name + p.NameSuffix() +} + +func (p *vendorSnapshotObjectLinker) NameSuffix() string { + versionSuffix := p.version() + if p.arch() != "" { + versionSuffix += "." + p.arch() + } + return vendorSnapshotObjectSuffix + versionSuffix +} + +func (p *vendorSnapshotObjectLinker) version() string { + return p.properties.Version +} + +func (p *vendorSnapshotObjectLinker) arch() string { + return p.properties.Target_arch +} + +func (p *vendorSnapshotObjectLinker) matchesWithDevice(config android.DeviceConfig) bool { + if config.DeviceArch() != p.arch() { + return false + } + if p.properties.Src == nil { + return false + } + return true +} + +func (p *vendorSnapshotObjectLinker) link(ctx ModuleContext, + flags Flags, deps PathDeps, objs Objects) android.Path { + if !p.matchesWithDevice(ctx.DeviceConfig()) { + return nil + } + + m := ctx.Module().(*Module) + p.androidMkVendorSuffix = vendorSuffixModules(ctx.Config())[m.BaseModuleName()] + + return android.PathForModuleSrc(ctx, *p.properties.Src) +} + +func (p *vendorSnapshotObjectLinker) nativeCoverage() bool { + return false +} + +func (p *vendorSnapshotObjectLinker) isSnapshotPrebuilt() bool { + return true +} + +func VendorSnapshotObjectFactory() android.Module { + module := newObject() + + prebuilt := &vendorSnapshotObjectLinker{ + objectLinker: objectLinker{ + baseLinker: NewBaseLinker(nil), + }, + } + module.linker = prebuilt + + android.AddLoadHook(module, func(ctx android.LoadHookContext) { + vendorSnapshotLoadHook(ctx, prebuilt) + }) + + module.AddProperties(&prebuilt.properties) + return module.Init() +} + func init() { android.RegisterSingletonType("vendor-snapshot", VendorSnapshotSingleton) android.RegisterModuleType("vendor_snapshot_shared", VendorSnapshotSharedFactory) android.RegisterModuleType("vendor_snapshot_static", VendorSnapshotStaticFactory) android.RegisterModuleType("vendor_snapshot_header", VendorSnapshotHeaderFactory) android.RegisterModuleType("vendor_snapshot_binary", VendorSnapshotBinaryFactory) + android.RegisterModuleType("vendor_snapshot_object", VendorSnapshotObjectFactory) } func VendorSnapshotSingleton() android.Singleton { @@ -429,7 +531,7 @@ func isVendorProprietaryPath(dir string) bool { // depend on newer VNDK) So they are captured as vendor snapshot To build older vendor // image and newer system image altogether. func isVendorSnapshotModule(m *Module, moduleDir string) bool { - if !m.Enabled() { + if !m.Enabled() || m.Properties.HideFromMake { return false } // skip proprietary modules, but include all VNDK (static) @@ -443,37 +545,37 @@ func isVendorSnapshotModule(m *Module, moduleDir string) bool { return false } // the module must be installed in /vendor - if !m.installable() || m.isSnapshotPrebuilt() || !m.inVendor() { - return false - } - // exclude test modules - if _, ok := m.linker.(interface{ gtest() bool }); ok { - return false - } - // TODO(b/65377115): add full support for sanitizer - if m.sanitize != nil && !m.sanitize.isUnsanitizedVariant() { + if !m.IsForPlatform() || m.isSnapshotPrebuilt() || !m.inVendor() { return false } // Libraries if l, ok := m.linker.(snapshotLibraryInterface); ok { + // TODO(b/65377115): add full support for sanitizer + if m.sanitize != nil { + // cfi, scs and hwasan export both sanitized and unsanitized variants for static and header + // Always use unsanitized variants of them. + for _, t := range []sanitizerType{cfi, scs, hwasan} { + if !l.shared() && m.sanitize.isSanitizerEnabled(t) { + return false + } + } + } if l.static() { - return proptools.BoolDefault(m.VendorProperties.Vendor_available, true) + return m.outputFile.Valid() && proptools.BoolDefault(m.VendorProperties.Vendor_available, true) } if l.shared() { - return !m.IsVndk() + return m.outputFile.Valid() && !m.IsVndk() } return true } - // Binaries - _, ok := m.linker.(*binaryDecorator) - if !ok { - if _, ok := m.linker.(*prebuiltBinaryLinker); !ok { - return false - } + // Binaries and Objects + if m.binary() || m.object() { + return m.outputFile.Valid() && proptools.BoolDefault(m.VendorProperties.Vendor_available, true) } - return proptools.BoolDefault(m.VendorProperties.Vendor_available, true) + + return false } func (c *vendorSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) { @@ -496,6 +598,8 @@ func (c *vendorSnapshotSingleton) GenerateBuildActions(ctx android.SingletonCont (header only libraries) binary/ (executable binaries) + object/ + (.o object files) arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/ shared/ (.so shared libraries) @@ -505,6 +609,8 @@ func (c *vendorSnapshotSingleton) GenerateBuildActions(ctx android.SingletonCont (header only libraries) binary/ (executable binaries) + object/ + (.o object files) NOTICE_FILES/ (notice files, e.g. libbase.txt) configs/ @@ -620,7 +726,7 @@ func (c *vendorSnapshotSingleton) GenerateBuildActions(ctx android.SingletonCont } propOut = filepath.Join(snapshotArchDir, targetArch, libType, stem+".json") - } else { + } else if m.binary() { // binary flags prop.Symlinks = m.Symlinks() prop.SharedLibs = m.Properties.SnapshotSharedLibs @@ -630,6 +736,17 @@ func (c *vendorSnapshotSingleton) GenerateBuildActions(ctx android.SingletonCont snapshotBinOut := filepath.Join(snapshotArchDir, targetArch, "binary", binPath.Base()) ret = append(ret, copyFile(ctx, binPath, snapshotBinOut)) propOut = snapshotBinOut + ".json" + } else if m.object() { + // object files aren't installed to the device, so their names can conflict. + // Use module name as stem. + objPath := m.outputFile.Path() + snapshotObjOut := filepath.Join(snapshotArchDir, targetArch, "object", + ctx.ModuleName(m)+filepath.Ext(objPath.Base())) + ret = append(ret, copyFile(ctx, objPath, snapshotObjOut)) + propOut = snapshotObjOut + ".json" + } else { + ctx.Errorf("unknown module %q in vendor snapshot", m.String()) + return nil } j, err := json.Marshal(prop) @@ -716,6 +833,7 @@ type snapshotInterface interface { var _ snapshotInterface = (*vndkPrebuiltLibraryDecorator)(nil) var _ snapshotInterface = (*vendorSnapshotLibraryDecorator)(nil) var _ snapshotInterface = (*vendorSnapshotBinaryDecorator)(nil) +var _ snapshotInterface = (*vendorSnapshotObjectLinker)(nil) // gathers all snapshot modules for vendor, and disable unnecessary snapshots // TODO(b/145966707): remove mutator and utilize android.Prebuilt to override source modules @@ -731,12 +849,12 @@ func VendorSnapshotMutator(ctx android.BottomUpMutatorContext) { return } - snapshot, ok := module.linker.(snapshotInterface) - if !ok { + if !module.isSnapshotPrebuilt() { return } - if !snapshot.matchesWithDevice(ctx.DeviceConfig()) { + // isSnapshotPrebuilt ensures snapshotInterface + if !module.linker.(snapshotInterface).matchesWithDevice(ctx.DeviceConfig()) { // Disable unnecessary snapshot module, but do not disable // vndk_prebuilt_shared because they might be packed into vndk APEX if !module.IsVndk() { @@ -758,6 +876,8 @@ func VendorSnapshotMutator(ctx android.BottomUpMutatorContext) { } } else if _, ok := module.linker.(*vendorSnapshotBinaryDecorator); ok { snapshotMap = vendorSnapshotBinaries(ctx.Config()) + } else if _, ok := module.linker.(*vendorSnapshotObjectLinker); ok { + snapshotMap = vendorSnapshotObjects(ctx.Config()) } else { return } @@ -804,6 +924,11 @@ func VendorSnapshotSourceMutator(ctx android.BottomUpMutatorContext) { return } + // .. and also filter out llndk library + if module.isLlndk(ctx.Config()) { + return + } + var snapshotMap *snapshotMap if lib, ok := module.linker.(libraryInterface); ok { @@ -815,10 +940,10 @@ func VendorSnapshotSourceMutator(ctx android.BottomUpMutatorContext) { // header snapshotMap = vendorSnapshotHeaderLibs(ctx.Config()) } - } else if _, ok := module.linker.(*binaryDecorator); ok { - snapshotMap = vendorSnapshotBinaries(ctx.Config()) - } else if _, ok := module.linker.(*prebuiltBinaryLinker); ok { + } else if module.binary() { snapshotMap = vendorSnapshotBinaries(ctx.Config()) + } else if module.object() { + snapshotMap = vendorSnapshotObjects(ctx.Config()) } else { return } diff --git a/cc/vndk.go b/cc/vndk.go index 8eab8ba79..ef33c1a50 100644 --- a/cc/vndk.go +++ b/cc/vndk.go @@ -25,6 +25,7 @@ import ( "android/soong/android" "android/soong/cc/config" + "android/soong/etc" ) const ( @@ -410,7 +411,7 @@ type vndkLibrariesTxt struct { outputFile android.OutputPath } -var _ android.PrebuiltEtcModule = &vndkLibrariesTxt{} +var _ etc.PrebuiltEtcModule = &vndkLibrariesTxt{} var _ android.OutputFileProducer = &vndkLibrariesTxt{} // vndk_libraries_txt is a special kind of module type in that it name is one of diff --git a/cc/vndk_prebuilt.go b/cc/vndk_prebuilt.go index 53b518186..5a44c4663 100644 --- a/cc/vndk_prebuilt.go +++ b/cc/vndk_prebuilt.go @@ -186,6 +186,10 @@ func (p *vndkPrebuiltLibraryDecorator) nativeCoverage() bool { return false } +func (p *vndkPrebuiltLibraryDecorator) isSnapshotPrebuilt() bool { + return true +} + func (p *vndkPrebuiltLibraryDecorator) install(ctx ModuleContext, file android.Path) { arches := ctx.DeviceConfig().Arches() if len(arches) == 0 || arches[0].ArchType.String() != p.arch() { diff --git a/cmd/pom2bp/pom2bp.go b/cmd/pom2bp/pom2bp.go index 191b919e9..d341b8c10 100644 --- a/cmd/pom2bp/pom2bp.go +++ b/cmd/pom2bp/pom2bp.go @@ -213,10 +213,14 @@ func (p Pom) IsHostAndDeviceModule() bool { return hostAndDeviceModuleNames.IsHostAndDeviceModule(p.GroupId, p.ArtifactId) } +func (p Pom) IsHostOnly() bool { + return p.IsHostModule() && !p.IsHostAndDeviceModule() +} + func (p Pom) ModuleType() string { if p.IsAar() { return "android_library" - } else if p.IsHostModule() && !p.IsHostAndDeviceModule() { + } else if p.IsHostOnly() { return "java_library_host" } else { return "java_library_static" @@ -226,7 +230,7 @@ func (p Pom) ModuleType() string { func (p Pom) ImportModuleType() string { if p.IsAar() { return "android_library_import" - } else if p.IsHostModule() && !p.IsHostAndDeviceModule() { + } else if p.IsHostOnly() { return "java_import_host" } else { return "java_import" @@ -366,6 +370,12 @@ var bpTemplate = template.Must(template.New("bp").Parse(` {{- if .IsHostAndDeviceModule}} host_supported: true, {{- end}} + {{- if not .IsHostOnly}} + apex_available: [ + "//apex_available:platform", + "//apex_available:anyapex", + ], + {{- end}} {{- if .IsAar}} min_sdk_version: "{{.MinSdkVersion}}", static_libs: [ @@ -401,6 +411,12 @@ var bpDepsTemplate = template.Must(template.New("bp").Parse(` {{- if .IsHostAndDeviceModule}} host_supported: true, {{- end}} + {{- if not .IsHostOnly}} + apex_available: [ + "//apex_available:platform", + "//apex_available:anyapex", + ], + {{- end}} {{- if .IsAar}} min_sdk_version: "{{.MinSdkVersion}}", static_libs: [ @@ -431,9 +447,17 @@ var bpDepsTemplate = template.Must(template.New("bp").Parse(` {{- if .IsHostAndDeviceModule}} host_supported: true, {{- end}} + {{- if not .IsHostOnly}} + apex_available: [ + "//apex_available:platform", + "//apex_available:anyapex", + ], + {{- end}} {{- if .IsAar}} min_sdk_version: "{{.MinSdkVersion}}", manifest: "manifests/{{.BpName}}/AndroidManifest.xml", + {{- else if not .IsHostOnly}} + min_sdk_version: "24", {{- end}} {{- end}} static_libs: [ diff --git a/env/Android.bp b/env/Android.bp new file mode 100644 index 000000000..90c604729 --- /dev/null +++ b/env/Android.bp @@ -0,0 +1,7 @@ +bootstrap_go_package { + name: "soong-env", + pkgPath: "android/soong/env", + srcs: [ + "env.go", + ], +} diff --git a/etc/Android.bp b/etc/Android.bp new file mode 100644 index 000000000..cfd303ec8 --- /dev/null +++ b/etc/Android.bp @@ -0,0 +1,16 @@ +bootstrap_go_package { + name: "soong-etc", + pkgPath: "android/soong/etc", + deps: [ + "blueprint", + "soong", + "soong-android", + ], + srcs: [ + "prebuilt_etc.go", + ], + testSrcs: [ + "prebuilt_etc_test.go", + ], + pluginFor: ["soong_build"], +} diff --git a/android/prebuilt_etc.go b/etc/prebuilt_etc.go index 3dea6d8f6..842d9eec1 100644 --- a/android/prebuilt_etc.go +++ b/etc/prebuilt_etc.go @@ -12,19 +12,29 @@ // See the License for the specific language governing permissions and // limitations under the License. -package android +package etc -import "strconv" +import ( + "strconv" + + "github.com/google/blueprint/proptools" + + "android/soong/android" +) + +var pctx = android.NewPackageContext("android/soong/etc") // TODO(jungw): Now that it handles more than the ones in etc/, consider renaming this file. func init() { - RegisterModuleType("prebuilt_etc", PrebuiltEtcFactory) - RegisterModuleType("prebuilt_etc_host", PrebuiltEtcHostFactory) - RegisterModuleType("prebuilt_usr_share", PrebuiltUserShareFactory) - RegisterModuleType("prebuilt_usr_share_host", PrebuiltUserShareHostFactory) - RegisterModuleType("prebuilt_font", PrebuiltFontFactory) - RegisterModuleType("prebuilt_firmware", PrebuiltFirmwareFactory) + pctx.Import("android/soong/android") + + android.RegisterModuleType("prebuilt_etc", PrebuiltEtcFactory) + android.RegisterModuleType("prebuilt_etc_host", PrebuiltEtcHostFactory) + android.RegisterModuleType("prebuilt_usr_share", PrebuiltUserShareFactory) + android.RegisterModuleType("prebuilt_usr_share_host", PrebuiltUserShareHostFactory) + android.RegisterModuleType("prebuilt_font", PrebuiltFontFactory) + android.RegisterModuleType("prebuilt_firmware", PrebuiltFirmwareFactory) } type prebuiltEtcProperties struct { @@ -52,24 +62,24 @@ type prebuiltEtcProperties struct { } type PrebuiltEtcModule interface { - Module + android.Module SubDir() string - OutputFile() OutputPath + OutputFile() android.OutputPath } type PrebuiltEtc struct { - ModuleBase + android.ModuleBase properties prebuiltEtcProperties - sourceFilePath Path - outputFilePath OutputPath + sourceFilePath android.Path + outputFilePath android.OutputPath // The base install location, e.g. "etc" for prebuilt_etc, "usr/share" for prebuilt_usr_share. installDirBase string // The base install location when soc_specific property is set to true, e.g. "firmware" for prebuilt_firmware. socInstallDirBase string - installDirPath InstallPath - additionalDependencies *Paths + installDirPath android.InstallPath + additionalDependencies *android.Paths } func (p *PrebuiltEtc) inRamdisk() bool { @@ -96,65 +106,65 @@ func (p *PrebuiltEtc) InstallInRecovery() bool { return p.inRecovery() } -var _ ImageInterface = (*PrebuiltEtc)(nil) +var _ android.ImageInterface = (*PrebuiltEtc)(nil) -func (p *PrebuiltEtc) ImageMutatorBegin(ctx BaseModuleContext) {} +func (p *PrebuiltEtc) ImageMutatorBegin(ctx android.BaseModuleContext) {} -func (p *PrebuiltEtc) CoreVariantNeeded(ctx BaseModuleContext) bool { +func (p *PrebuiltEtc) CoreVariantNeeded(ctx android.BaseModuleContext) bool { return !p.ModuleBase.InstallInRecovery() && !p.ModuleBase.InstallInRamdisk() } -func (p *PrebuiltEtc) RamdiskVariantNeeded(ctx BaseModuleContext) bool { - return Bool(p.properties.Ramdisk_available) || p.ModuleBase.InstallInRamdisk() +func (p *PrebuiltEtc) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool { + return proptools.Bool(p.properties.Ramdisk_available) || p.ModuleBase.InstallInRamdisk() } -func (p *PrebuiltEtc) RecoveryVariantNeeded(ctx BaseModuleContext) bool { - return Bool(p.properties.Recovery_available) || p.ModuleBase.InstallInRecovery() +func (p *PrebuiltEtc) RecoveryVariantNeeded(ctx android.BaseModuleContext) bool { + return proptools.Bool(p.properties.Recovery_available) || p.ModuleBase.InstallInRecovery() } -func (p *PrebuiltEtc) ExtraImageVariations(ctx BaseModuleContext) []string { +func (p *PrebuiltEtc) ExtraImageVariations(ctx android.BaseModuleContext) []string { return nil } -func (p *PrebuiltEtc) SetImageVariation(ctx BaseModuleContext, variation string, module Module) { +func (p *PrebuiltEtc) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) { } -func (p *PrebuiltEtc) DepsMutator(ctx BottomUpMutatorContext) { +func (p *PrebuiltEtc) DepsMutator(ctx android.BottomUpMutatorContext) { if p.properties.Src == nil { ctx.PropertyErrorf("src", "missing prebuilt source file") } } -func (p *PrebuiltEtc) SourceFilePath(ctx ModuleContext) Path { - return PathForModuleSrc(ctx, String(p.properties.Src)) +func (p *PrebuiltEtc) SourceFilePath(ctx android.ModuleContext) android.Path { + return android.PathForModuleSrc(ctx, android.String(p.properties.Src)) } -func (p *PrebuiltEtc) InstallDirPath() InstallPath { +func (p *PrebuiltEtc) InstallDirPath() android.InstallPath { return p.installDirPath } // This allows other derivative modules (e.g. prebuilt_etc_xml) to perform // additional steps (like validating the src) before the file is installed. -func (p *PrebuiltEtc) SetAdditionalDependencies(paths Paths) { +func (p *PrebuiltEtc) SetAdditionalDependencies(paths android.Paths) { p.additionalDependencies = &paths } -func (p *PrebuiltEtc) OutputFile() OutputPath { +func (p *PrebuiltEtc) OutputFile() android.OutputPath { return p.outputFilePath } func (p *PrebuiltEtc) SubDir() string { - return String(p.properties.Sub_dir) + return android.String(p.properties.Sub_dir) } func (p *PrebuiltEtc) Installable() bool { - return p.properties.Installable == nil || Bool(p.properties.Installable) + return p.properties.Installable == nil || android.Bool(p.properties.Installable) } -func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx ModuleContext) { - p.sourceFilePath = PathForModuleSrc(ctx, String(p.properties.Src)) - filename := String(p.properties.Filename) - filename_from_src := Bool(p.properties.Filename_from_src) +func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx android.ModuleContext) { + p.sourceFilePath = android.PathForModuleSrc(ctx, android.String(p.properties.Src)) + filename := android.String(p.properties.Filename) + filename_from_src := android.Bool(p.properties.Filename_from_src) if filename == "" { if filename_from_src { filename = p.sourceFilePath.Base() @@ -165,7 +175,7 @@ func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx ModuleContext) { ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true") return } - p.outputFilePath = PathForModuleOut(ctx, filename).OutputPath + p.outputFilePath = android.PathForModuleOut(ctx, filename).OutputPath // If soc install dir was specified and SOC specific is set, set the installDirPath to the specified // socInstallDirBase. @@ -173,18 +183,18 @@ func (p *PrebuiltEtc) GenerateAndroidBuildActions(ctx ModuleContext) { if ctx.SocSpecific() && p.socInstallDirBase != "" { installBaseDir = p.socInstallDirBase } - p.installDirPath = PathForModuleInstall(ctx, installBaseDir, String(p.properties.Sub_dir)) + p.installDirPath = android.PathForModuleInstall(ctx, installBaseDir, proptools.String(p.properties.Sub_dir)) // This ensures that outputFilePath has the correct name for others to // use, as the source file may have a different name. - ctx.Build(pctx, BuildParams{ - Rule: Cp, + ctx.Build(pctx, android.BuildParams{ + Rule: android.Cp, Output: p.outputFilePath, Input: p.sourceFilePath, }) } -func (p *PrebuiltEtc) AndroidMkEntries() []AndroidMkEntries { +func (p *PrebuiltEtc) AndroidMkEntries() []android.AndroidMkEntries { nameSuffix := "" if p.inRamdisk() && !p.onlyInRamdisk() { nameSuffix = ".ramdisk" @@ -192,12 +202,12 @@ func (p *PrebuiltEtc) AndroidMkEntries() []AndroidMkEntries { if p.inRecovery() && !p.onlyInRecovery() { nameSuffix = ".recovery" } - return []AndroidMkEntries{AndroidMkEntries{ + return []android.AndroidMkEntries{android.AndroidMkEntries{ Class: "ETC", SubName: nameSuffix, - OutputFile: OptionalPathForPath(p.outputFilePath), - ExtraEntries: []AndroidMkExtraEntriesFunc{ - func(entries *AndroidMkEntries) { + OutputFile: android.OptionalPathForPath(p.outputFilePath), + ExtraEntries: []android.AndroidMkExtraEntriesFunc{ + func(entries *android.AndroidMkEntries) { entries.SetString("LOCAL_MODULE_TAGS", "optional") entries.SetString("LOCAL_MODULE_PATH", p.installDirPath.ToMakePath().String()) entries.SetString("LOCAL_INSTALLED_MODULE_STEM", p.outputFilePath.Base()) @@ -219,61 +229,61 @@ func InitPrebuiltEtcModule(p *PrebuiltEtc, dirBase string) { // prebuilt_etc is for a prebuilt artifact that is installed in // <partition>/etc/<sub_dir> directory. -func PrebuiltEtcFactory() Module { +func PrebuiltEtcFactory() android.Module { module := &PrebuiltEtc{} InitPrebuiltEtcModule(module, "etc") // This module is device-only - InitAndroidArchModule(module, DeviceSupported, MultilibFirst) + android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) return module } // prebuilt_etc_host is for a host prebuilt artifact that is installed in // $(HOST_OUT)/etc/<sub_dir> directory. -func PrebuiltEtcHostFactory() Module { +func PrebuiltEtcHostFactory() android.Module { module := &PrebuiltEtc{} InitPrebuiltEtcModule(module, "etc") // This module is host-only - InitAndroidArchModule(module, HostSupported, MultilibCommon) + android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon) return module } // prebuilt_usr_share is for a prebuilt artifact that is installed in // <partition>/usr/share/<sub_dir> directory. -func PrebuiltUserShareFactory() Module { +func PrebuiltUserShareFactory() android.Module { module := &PrebuiltEtc{} InitPrebuiltEtcModule(module, "usr/share") // This module is device-only - InitAndroidArchModule(module, DeviceSupported, MultilibFirst) + android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) return module } // prebuild_usr_share_host is for a host prebuilt artifact that is installed in // $(HOST_OUT)/usr/share/<sub_dir> directory. -func PrebuiltUserShareHostFactory() Module { +func PrebuiltUserShareHostFactory() android.Module { module := &PrebuiltEtc{} InitPrebuiltEtcModule(module, "usr/share") // This module is host-only - InitAndroidArchModule(module, HostSupported, MultilibCommon) + android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon) return module } // prebuilt_font installs a font in <partition>/fonts directory. -func PrebuiltFontFactory() Module { +func PrebuiltFontFactory() android.Module { module := &PrebuiltEtc{} InitPrebuiltEtcModule(module, "fonts") // This module is device-only - InitAndroidArchModule(module, DeviceSupported, MultilibFirst) + android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) return module } // prebuilt_firmware installs a firmware file to <partition>/etc/firmware directory for system image. // If soc_specific property is set to true, the firmware file is installed to the vendor <partition>/firmware // directory for vendor image. -func PrebuiltFirmwareFactory() Module { +func PrebuiltFirmwareFactory() android.Module { module := &PrebuiltEtc{} module.socInstallDirBase = "firmware" InitPrebuiltEtcModule(module, "etc/firmware") // This module is device-only - InitAndroidArchModule(module, DeviceSupported, MultilibFirst) + android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) return module } diff --git a/android/prebuilt_etc_test.go b/etc/prebuilt_etc_test.go index 6e751e757..e13cb3cb7 100644 --- a/android/prebuilt_etc_test.go +++ b/etc/prebuilt_etc_test.go @@ -12,24 +12,53 @@ // See the License for the specific language governing permissions and // limitations under the License. -package android +package etc import ( + "io/ioutil" + "os" "path/filepath" "reflect" "testing" + + "android/soong/android" ) -func testPrebuiltEtc(t *testing.T, bp string) (*TestContext, Config) { +var buildDir string + +func setUp() { + var err error + buildDir, err = ioutil.TempDir("", "soong_etc_test") + if err != nil { + panic(err) + } +} + +func tearDown() { + os.RemoveAll(buildDir) +} + +func TestMain(m *testing.M) { + run := func() int { + setUp() + defer tearDown() + + return m.Run() + } + + os.Exit(run()) +} + +func testPrebuiltEtc(t *testing.T, bp string) (*android.TestContext, android.Config) { fs := map[string][]byte{ "foo.conf": nil, "bar.conf": nil, "baz.conf": nil, } - config := TestArchConfig(buildDir, nil, bp, fs) + config := android.TestArchConfig(buildDir, nil, bp, fs) - ctx := NewTestArchContext() + ctx := android.NewTestArchContext() ctx.RegisterModuleType("prebuilt_etc", PrebuiltEtcFactory) ctx.RegisterModuleType("prebuilt_etc_host", PrebuiltEtcHostFactory) ctx.RegisterModuleType("prebuilt_usr_share", PrebuiltUserShareFactory) @@ -38,9 +67,9 @@ func testPrebuiltEtc(t *testing.T, bp string) (*TestContext, Config) { ctx.RegisterModuleType("prebuilt_firmware", PrebuiltFirmwareFactory) ctx.Register(config) _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - FailIfErrored(t, errs) + android.FailIfErrored(t, errs) _, errs = ctx.PrepareBuildActions(config) - FailIfErrored(t, errs) + android.FailIfErrored(t, errs) return ctx, config } @@ -142,7 +171,7 @@ func TestPrebuiltEtcAndroidMk(t *testing.T) { } mod := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*PrebuiltEtc) - entries := AndroidMkEntriesForTest(t, config, "", mod)[0] + entries := android.AndroidMkEntriesForTest(t, config, "", mod)[0] for k, expectedValue := range expected { if value, ok := entries.EntryMap[k]; ok { if !reflect.DeepEqual(value, expectedValue) { @@ -162,7 +191,7 @@ func TestPrebuiltEtcHost(t *testing.T) { } `) - buildOS := BuildOs.String() + buildOS := android.BuildOs.String() p := ctx.ModuleForTests("foo.conf", buildOS+"_common").Module().(*PrebuiltEtc) if !p.Host() { t.Errorf("host bit is not set for a prebuilt_etc_host module.") @@ -194,7 +223,7 @@ func TestPrebuiltUserShareHostInstallDirPath(t *testing.T) { } `) - buildOS := BuildOs.String() + buildOS := android.BuildOs.String() p := ctx.ModuleForTests("foo.conf", buildOS+"_common").Module().(*PrebuiltEtc) expected := filepath.Join(buildDir, "host", config.PrebuiltOS(), "usr", "share", "bar") if p.installDirPath.String() != expected { diff --git a/genrule/Android.bp b/genrule/Android.bp new file mode 100644 index 000000000..ff543a61f --- /dev/null +++ b/genrule/Android.bp @@ -0,0 +1,18 @@ +bootstrap_go_package { + name: "soong-genrule", + pkgPath: "android/soong/genrule", + deps: [ + "blueprint", + "blueprint-pathtools", + "soong", + "soong-android", + "soong-shared", + ], + srcs: [ + "genrule.go", + ], + testSrcs: [ + "genrule_test.go", + ], + pluginFor: ["soong_build"], +} diff --git a/java/Android.bp b/java/Android.bp new file mode 100644 index 000000000..2de1b8ea1 --- /dev/null +++ b/java/Android.bp @@ -0,0 +1,66 @@ +bootstrap_go_package { + name: "soong-java", + pkgPath: "android/soong/java", + deps: [ + "blueprint", + "blueprint-pathtools", + "soong", + "soong-android", + "soong-cc", + "soong-dexpreopt", + "soong-genrule", + "soong-java-config", + "soong-remoteexec", + "soong-tradefed", + ], + srcs: [ + "aapt2.go", + "aar.go", + "android_manifest.go", + "android_resources.go", + "androidmk.go", + "app_builder.go", + "app.go", + "builder.go", + "device_host_converter.go", + "dex.go", + "dexpreopt.go", + "dexpreopt_bootjars.go", + "dexpreopt_config.go", + "droiddoc.go", + "gen.go", + "genrule.go", + "hiddenapi.go", + "hiddenapi_singleton.go", + "jacoco.go", + "java.go", + "jdeps.go", + "java_resources.go", + "kotlin.go", + "platform_compat_config.go", + "plugin.go", + "prebuilt_apis.go", + "proto.go", + "robolectric.go", + "sdk.go", + "sdk_library.go", + "support_libraries.go", + "sysprop.go", + "system_modules.go", + "testing.go", + "tradefed.go", + ], + testSrcs: [ + "androidmk_test.go", + "app_test.go", + "device_host_converter_test.go", + "dexpreopt_test.go", + "dexpreopt_bootjars_test.go", + "java_test.go", + "jdeps_test.go", + "kotlin_test.go", + "plugin_test.go", + "sdk_test.go", + ], + pluginFor: ["soong_build"], +} diff --git a/java/androidmk.go b/java/androidmk.go index 861bb5e99..75fb5fb02 100644 --- a/java/androidmk.go +++ b/java/androidmk.go @@ -69,7 +69,26 @@ func (library *Library) AndroidMkEntries() []android.AndroidMkEntries { if !library.ApexModuleBase.AvailableFor(android.AvailableToPlatform) { hideFromMake = true } - if !hideFromMake { + if hideFromMake { + // May still need to add some additional dependencies. This will be called + // once for the platform variant (even if it is not being used) and once each + // for the APEX specific variants. In order to avoid adding the dependency + // multiple times only add it for the platform variant. + checkedModulePaths := library.additionalCheckedModules + if library.IsForPlatform() && len(checkedModulePaths) != 0 { + mainEntries = android.AndroidMkEntries{ + Class: "FAKE", + // Need at least one output file in order for this to take effect. + OutputFile: android.OptionalPathForPath(checkedModulePaths[0]), + Include: "$(BUILD_PHONY_PACKAGE)", + ExtraEntries: []android.AndroidMkExtraEntriesFunc{ + func(entries *android.AndroidMkEntries) { + entries.AddStrings("LOCAL_ADDITIONAL_CHECKED_MODULE", checkedModulePaths.Strings()...) + }, + }, + } + } + } else { mainEntries = android.AndroidMkEntries{ Class: "JAVA_LIBRARIES", DistFile: android.OptionalPathForPath(library.distFile), diff --git a/java/app.go b/java/app.go index e44b87d92..5bc09ff4d 100755 --- a/java/app.go +++ b/java/app.go @@ -421,12 +421,43 @@ func (a *AndroidApp) checkAppSdkVersions(ctx android.ModuleContext) { if String(a.deviceProperties.Min_sdk_version) == "" { ctx.PropertyErrorf("updatable", "updatable apps must set min_sdk_version.") } + if minSdkVersion, err := a.minSdkVersion().effectiveVersion(ctx); err == nil { + a.checkJniLibsSdkVersion(ctx, minSdkVersion) + } else { + ctx.PropertyErrorf("min_sdk_version", "%s", err.Error()) + } } a.checkPlatformAPI(ctx) a.checkSdkVersions(ctx) } +// If an updatable APK sets min_sdk_version, min_sdk_vesion of JNI libs should match with it. +// This check is enforced for "updatable" APKs (including APK-in-APEX). +// b/155209650: until min_sdk_version is properly supported, use sdk_version instead. +// because, sdk_version is overridden by min_sdk_version (if set as smaller) +// and linkType is checked with dependencies so we can be sure that the whole dependency tree +// will meet the requirements. +func (a *AndroidApp) checkJniLibsSdkVersion(ctx android.ModuleContext, minSdkVersion sdkVersion) { + // It's enough to check direct JNI deps' sdk_version because all transitive deps from JNI deps are checked in cc.checkLinkType() + ctx.VisitDirectDeps(func(m android.Module) { + if !IsJniDepTag(ctx.OtherModuleDependencyTag(m)) { + return + } + dep, _ := m.(*cc.Module) + // The domain of cc.sdk_version is "current" and <number> + // We can rely on sdkSpec to convert it to <number> so that "current" is handled + // properly regardless of sdk finalization. + jniSdkVersion, err := sdkSpecFrom(dep.SdkVersion()).effectiveVersion(ctx) + if err != nil || minSdkVersion < jniSdkVersion { + ctx.OtherModuleErrorf(dep, "sdk_version(%v) is higher than min_sdk_version(%v) of the containing android_app(%v)", + dep.SdkVersion(), minSdkVersion, ctx.ModuleName()) + return + } + + }) +} + // Returns true if the native libraries should be stored in the APK uncompressed and the // extractNativeLibs application flag should be set to false in the manifest. func (a *AndroidApp) useEmbeddedNativeLibs(ctx android.ModuleContext) bool { diff --git a/java/app_builder.go b/java/app_builder.go index 967c55fcc..97ec269ee 100644 --- a/java/app_builder.go +++ b/java/app_builder.go @@ -26,16 +26,23 @@ import ( "github.com/google/blueprint/proptools" "android/soong/android" + "android/soong/remoteexec" ) var ( - Signapk = pctx.AndroidStaticRule("signapk", + Signapk, SignapkRE = remoteexec.StaticRules(pctx, "signapk", blueprint.RuleParams{ - Command: `${config.JavaCmd} ${config.JavaVmFlags} -Djava.library.path=$$(dirname ${config.SignapkJniLibrary}) ` + + Command: `$reTemplate${config.JavaCmd} ${config.JavaVmFlags} -Djava.library.path=$$(dirname ${config.SignapkJniLibrary}) ` + `-jar ${config.SignapkCmd} $flags $certificates $in $out`, CommandDeps: []string{"${config.SignapkCmd}", "${config.SignapkJniLibrary}"}, }, - "flags", "certificates") + &remoteexec.REParams{Labels: map[string]string{"type": "tool", "name": "signapk"}, + ExecStrategy: "${config.RESignApkExecStrategy}", + Inputs: []string{"${config.SignapkCmd}", "$in", "$$(dirname ${config.SignapkJniLibrary})", "$implicits"}, + OutputFiles: []string{"$outCommaList"}, + ToolchainInputs: []string{"${config.JavaCmd}"}, + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, []string{"flags", "certificates"}, []string{"implicits", "outCommaList"}) ) var combineApk = pctx.AndroidStaticRule("combineApk", @@ -90,16 +97,23 @@ func SignAppPackage(ctx android.ModuleContext, signedApk android.WritablePath, u deps = append(deps, lineageFile) } + rule := Signapk + args := map[string]string{ + "certificates": strings.Join(certificateArgs, " "), + "flags": strings.Join(flags, " "), + } + if ctx.Config().IsEnvTrue("RBE_SIGNAPK") { + rule = SignapkRE + args["implicits"] = strings.Join(deps.Strings(), ",") + args["outCommaList"] = strings.Join(outputFiles.Strings(), ",") + } ctx.Build(pctx, android.BuildParams{ - Rule: Signapk, + Rule: rule, Description: "signapk", Outputs: outputFiles, Input: unsignedApk, Implicits: deps, - Args: map[string]string{ - "certificates": strings.Join(certificateArgs, " "), - "flags": strings.Join(flags, " "), - }, + Args: args, }) } @@ -223,14 +237,20 @@ func TransformJniLibsToJar(ctx android.ModuleContext, outputFile android.Writabl "-f", j.path.String()) } + rule := zip + args := map[string]string{ + "jarArgs": strings.Join(proptools.NinjaAndShellEscapeList(jarArgs), " "), + } + if ctx.Config().IsEnvTrue("RBE_ZIP") { + rule = zipRE + args["implicits"] = strings.Join(deps.Strings(), ",") + } ctx.Build(pctx, android.BuildParams{ - Rule: zip, + Rule: rule, Description: "zip jni libs", Output: outputFile, Implicits: deps, - Args: map[string]string{ - "jarArgs": strings.Join(proptools.NinjaAndShellEscapeList(jarArgs), " "), - }, + Args: args, }) } diff --git a/java/app_test.go b/java/app_test.go index 8afd97d9e..e686f2780 100644 --- a/java/app_test.go +++ b/java/app_test.go @@ -473,6 +473,127 @@ func TestUpdatableApps(t *testing.T) { } } +func TestUpdatableApps_JniLibsShouldShouldSupportMinSdkVersion(t *testing.T) { + testJava(t, cc.GatherRequiredDepsForTest(android.Android)+` + android_app { + name: "foo", + srcs: ["a.java"], + updatable: true, + sdk_version: "current", + min_sdk_version: "current", + jni_libs: ["libjni"], + } + + cc_library { + name: "libjni", + stl: "none", + system_shared_libs: [], + sdk_version: "current", + } + `) +} + +func TestUpdatableApps_JniLibShouldBeBuiltAgainstMinSdkVersion(t *testing.T) { + bp := cc.GatherRequiredDepsForTest(android.Android) + ` + android_app { + name: "foo", + srcs: ["a.java"], + updatable: true, + sdk_version: "current", + min_sdk_version: "29", + jni_libs: ["libjni"], + } + + cc_library { + name: "libjni", + stl: "none", + system_shared_libs: [], + sdk_version: "29", + } + + ndk_prebuilt_object { + name: "ndk_crtbegin_so.29", + sdk_version: "29", + } + + ndk_prebuilt_object { + name: "ndk_crtend_so.29", + sdk_version: "29", + } + ` + fs := map[string][]byte{ + "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtbegin_so.o": nil, + "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtend_so.o": nil, + "prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtbegin_so.o": nil, + "prebuilts/ndk/current/platforms/android-29/arch-arm/usr/lib/crtend_so.o": nil, + } + + ctx, _ := testJavaWithConfig(t, testConfig(nil, bp, fs)) + + inputs := ctx.ModuleForTests("libjni", "android_arm64_armv8-a_sdk_shared").Description("link").Implicits + var crtbeginFound, crtendFound bool + for _, input := range inputs { + switch input.String() { + case "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtbegin_so.o": + crtbeginFound = true + case "prebuilts/ndk/current/platforms/android-29/arch-arm64/usr/lib/crtend_so.o": + crtendFound = true + } + } + if !crtbeginFound || !crtendFound { + t.Error("should link with ndk_crtbegin_so.29 and ndk_crtend_so.29") + } +} + +func TestUpdatableApps_ErrorIfJniLibDoesntSupportMinSdkVersion(t *testing.T) { + bp := cc.GatherRequiredDepsForTest(android.Android) + ` + android_app { + name: "foo", + srcs: ["a.java"], + updatable: true, + sdk_version: "current", + min_sdk_version: "29", // this APK should support 29 + jni_libs: ["libjni"], + } + + cc_library { + name: "libjni", + stl: "none", + sdk_version: "current", + } + ` + testJavaError(t, `"libjni" .*: sdk_version\(current\) is higher than min_sdk_version\(29\)`, bp) +} + +func TestUpdatableApps_ErrorIfDepSdkVersionIsHigher(t *testing.T) { + bp := cc.GatherRequiredDepsForTest(android.Android) + ` + android_app { + name: "foo", + srcs: ["a.java"], + updatable: true, + sdk_version: "current", + min_sdk_version: "29", // this APK should support 29 + jni_libs: ["libjni"], + } + + cc_library { + name: "libjni", + stl: "none", + shared_libs: ["libbar"], + system_shared_libs: [], + sdk_version: "27", + } + + cc_library { + name: "libbar", + stl: "none", + system_shared_libs: [], + sdk_version: "current", + } + ` + testJavaError(t, `"libjni" .*: links "libbar" built against newer API version "current"`, bp) +} + func TestResourceDirs(t *testing.T) { testCases := []struct { name string diff --git a/java/builder.go b/java/builder.go index 714d76aa5..a27e5c390 100644 --- a/java/builder.go +++ b/java/builder.go @@ -27,6 +27,7 @@ import ( "github.com/google/blueprint/proptools" "android/soong/android" + "android/soong/remoteexec" ) var ( @@ -38,17 +39,18 @@ var ( // this, all java rules write into separate directories and then are combined into a .jar file // (if the rule produces .class files) or a .srcjar file (if the rule produces .java files). // .srcjar files are unzipped into a temporary directory when compiled with javac. - javac = pctx.AndroidRemoteStaticRule("javac", android.RemoteRuleSupports{Goma: true, RBE: true, RBEFlag: android.RBE_JAVAC}, + // TODO(b/143658984): goma can't handle the --system argument to javac. + javac, javacRE = remoteexec.MultiCommandStaticRules(pctx, "javac", blueprint.RuleParams{ Command: `rm -rf "$outDir" "$annoDir" "$srcJarDir" && mkdir -p "$outDir" "$annoDir" "$srcJarDir" && ` + `${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` + `(if [ -s $srcJarDir/list ] || [ -s $out.rsp ] ; then ` + - `${config.SoongJavacWrapper} ${config.JavacWrapper}${config.JavacCmd} ` + + `${config.SoongJavacWrapper} $javaTemplate${config.JavacCmd} ` + `${config.JavacHeapFlags} ${config.JavacVmFlags} ${config.CommonJdkFlags} ` + `$processorpath $processor $javacFlags $bootClasspath $classpath ` + `-source $javaVersion -target $javaVersion ` + `-d $outDir -s $annoDir @$out.rsp @$srcJarDir/list ; fi ) && ` + - `${config.SoongZipCmd} -jar -o $out -C $outDir -D $outDir && ` + + `$zipTemplate${config.SoongZipCmd} -jar -o $out -C $outDir -D $outDir && ` + `rm -rf "$srcJarDir"`, CommandDeps: []string{ "${config.JavacCmd}", @@ -58,9 +60,21 @@ var ( CommandOrderOnly: []string{"${config.SoongJavacWrapper}"}, Rspfile: "$out.rsp", RspfileContent: "$in", - }, - "javacFlags", "bootClasspath", "classpath", "processorpath", "processor", "srcJars", "srcJarDir", - "outDir", "annoDir", "javaVersion") + }, map[string]*remoteexec.REParams{ + "$javaTemplate": &remoteexec.REParams{ + Labels: map[string]string{"type": "compile", "lang": "java", "compiler": "javac"}, + ExecStrategy: "${config.REJavacExecStrategy}", + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, + "$zipTemplate": &remoteexec.REParams{ + Labels: map[string]string{"type": "tool", "name": "soong_zip"}, + Inputs: []string{"${config.SoongZipCmd}", "$outDir"}, + OutputFiles: []string{"$out"}, + ExecStrategy: "${config.REJavacExecStrategy}", + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, + }, []string{"javacFlags", "bootClasspath", "classpath", "processorpath", "processor", "srcJars", "srcJarDir", + "outDir", "annoDir", "javaVersion"}, nil) _ = pctx.VariableFunc("kytheCorpus", func(ctx android.PackageVarContext) string { return ctx.Config().XrefCorpusName() }) @@ -111,10 +125,10 @@ var ( }, "abis", "allow-prereleased", "screen-densities", "sdk-version", "stem") - turbine = pctx.AndroidStaticRule("turbine", + turbine, turbineRE = remoteexec.StaticRules(pctx, "turbine", blueprint.RuleParams{ Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` + - `${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.TurbineJar} --output $out.tmp ` + + `$reTemplate${config.JavaCmd} ${config.JavaVmFlags} -jar ${config.TurbineJar} --output $out.tmp ` + `--temp_dir "$outDir" --sources @$out.rsp --source_jars $srcJars ` + `--javacopts ${config.CommonJdkFlags} ` + `$javacFlags -source $javaVersion -target $javaVersion -- $bootClasspath $classpath && ` + @@ -129,25 +143,45 @@ var ( RspfileContent: "$in", Restat: true, }, - "javacFlags", "bootClasspath", "classpath", "srcJars", "outDir", "javaVersion") - - jar = pctx.AndroidStaticRule("jar", + &remoteexec.REParams{Labels: map[string]string{"type": "tool", "name": "turbine"}, + ExecStrategy: "${config.RETurbineExecStrategy}", + Inputs: []string{"${config.TurbineJar}", "${out}.rsp", "$implicits"}, + RSPFile: "${out}.rsp", + OutputFiles: []string{"$out.tmp"}, + OutputDirectories: []string{"$outDir"}, + ToolchainInputs: []string{"${config.JavaCmd}"}, + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, []string{"javacFlags", "bootClasspath", "classpath", "srcJars", "outDir", "javaVersion"}, []string{"implicits"}) + + jar, jarRE = remoteexec.StaticRules(pctx, "jar", blueprint.RuleParams{ - Command: `${config.SoongZipCmd} -jar -o $out @$out.rsp`, + Command: `$reTemplate${config.SoongZipCmd} -jar -o $out @$out.rsp`, CommandDeps: []string{"${config.SoongZipCmd}"}, Rspfile: "$out.rsp", RspfileContent: "$jarArgs", }, - "jarArgs") - - zip = pctx.AndroidStaticRule("zip", + &remoteexec.REParams{ + ExecStrategy: "${config.REJarExecStrategy}", + Inputs: []string{"${config.SoongZipCmd}", "${out}.rsp"}, + RSPFile: "${out}.rsp", + OutputFiles: []string{"$out"}, + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, []string{"jarArgs"}, nil) + + zip, zipRE = remoteexec.StaticRules(pctx, "zip", blueprint.RuleParams{ Command: `${config.SoongZipCmd} -o $out @$out.rsp`, CommandDeps: []string{"${config.SoongZipCmd}"}, Rspfile: "$out.rsp", RspfileContent: "$jarArgs", }, - "jarArgs") + &remoteexec.REParams{ + ExecStrategy: "${config.REZipExecStrategy}", + Inputs: []string{"${config.SoongZipCmd}", "${out}.rsp", "$implicits"}, + RSPFile: "${out}.rsp", + OutputFiles: []string{"$out"}, + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, []string{"jarArgs"}, []string{"implicits"}) combineJar = pctx.AndroidStaticRule("combineJar", blueprint.RuleParams{ @@ -199,6 +233,7 @@ var ( func init() { pctx.Import("android/soong/android") pctx.Import("android/soong/java/config") + pctx.Import("android/soong/remoteexec") } type javaBuilderFlags struct { @@ -340,20 +375,26 @@ func TransformJavaToHeaderClasses(ctx android.ModuleContext, outputFile android. deps = append(deps, classpath...) deps = append(deps, flags.processorPath...) + rule := turbine + args := map[string]string{ + "javacFlags": flags.javacFlags, + "bootClasspath": bootClasspath, + "srcJars": strings.Join(srcJars.Strings(), " "), + "classpath": classpath.FormTurbineClassPath("--classpath "), + "outDir": android.PathForModuleOut(ctx, "turbine", "classes").String(), + "javaVersion": flags.javaVersion.String(), + } + if ctx.Config().IsEnvTrue("RBE_TURBINE") { + rule = turbineRE + args["implicits"] = strings.Join(deps.Strings(), ",") + } ctx.Build(pctx, android.BuildParams{ - Rule: turbine, + Rule: rule, Description: "turbine", Output: outputFile, Inputs: srcFiles, Implicits: deps, - Args: map[string]string{ - "javacFlags": flags.javacFlags, - "bootClasspath": bootClasspath, - "srcJars": strings.Join(srcJars.Strings(), " "), - "classpath": classpath.FormTurbineClassPath("--classpath "), - "outDir": android.PathForModuleOut(ctx, "turbine", "classes").String(), - "javaVersion": flags.javaVersion.String(), - }, + Args: args, }) } @@ -409,8 +450,12 @@ func transformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab outDir = filepath.Join(shardDir, outDir) annoDir = filepath.Join(shardDir, annoDir) } + rule := javac + if ctx.Config().IsEnvTrue("RBE_JAVAC") { + rule = javacRE + } ctx.Build(pctx, android.BuildParams{ - Rule: javac, + Rule: rule, Description: desc, Output: outputFile, Inputs: srcFiles, @@ -433,8 +478,12 @@ func transformJavaToClasses(ctx android.ModuleContext, outputFile android.Writab func TransformResourcesToJar(ctx android.ModuleContext, outputFile android.WritablePath, jarArgs []string, deps android.Paths) { + rule := jar + if ctx.Config().IsEnvTrue("RBE_JAR") { + rule = jarRE + } ctx.Build(pctx, android.BuildParams{ - Rule: jar, + Rule: rule, Description: "jar", Output: outputFile, Implicits: deps, diff --git a/java/config/Android.bp b/java/config/Android.bp new file mode 100644 index 000000000..198352187 --- /dev/null +++ b/java/config/Android.bp @@ -0,0 +1,15 @@ +bootstrap_go_package { + name: "soong-java-config", + pkgPath: "android/soong/java/config", + deps: [ + "blueprint-proptools", + "soong-android", + "soong-remoteexec", + ], + srcs: [ + "config.go", + "error_prone.go", + "kotlin.go", + "makevars.go", + ], +} diff --git a/java/config/config.go b/java/config/config.go index 9ac5a50cb..337355d80 100644 --- a/java/config/config.go +++ b/java/config/config.go @@ -22,6 +22,7 @@ import ( _ "github.com/google/blueprint/bootstrap" "android/soong/android" + "android/soong/remoteexec" ) var ( @@ -139,30 +140,20 @@ func init() { pctx.HostJavaToolVariable("MetalavaJar", "metalava.jar") pctx.HostJavaToolVariable("DokkaJar", "dokka.jar") pctx.HostJavaToolVariable("JetifierJar", "jetifier.jar") + pctx.HostJavaToolVariable("R8Jar", "r8-compat-proguard.jar") + pctx.HostJavaToolVariable("D8Jar", "d8.jar") pctx.HostBinToolVariable("SoongJavacWrapper", "soong_javac_wrapper") pctx.HostBinToolVariable("DexpreoptGen", "dexpreopt_gen") - pctx.VariableFunc("JavacWrapper", func(ctx android.PackageVarContext) string { - if override := ctx.Config().Getenv("JAVAC_WRAPPER"); override != "" { - return override + " " - } - return "" - }) - - pctx.VariableFunc("R8Wrapper", func(ctx android.PackageVarContext) string { - if override := ctx.Config().Getenv("R8_WRAPPER"); override != "" { - return override + " " - } - return "" - }) - - pctx.VariableFunc("D8Wrapper", func(ctx android.PackageVarContext) string { - if override := ctx.Config().Getenv("D8_WRAPPER"); override != "" { - return override + " " - } - return "" - }) + pctx.VariableFunc("REJavaPool", remoteexec.EnvOverrideFunc("RBE_JAVA_POOL", "java16")) + pctx.VariableFunc("REJavacExecStrategy", remoteexec.EnvOverrideFunc("RBE_JAVAC_EXEC_STRATEGY", remoteexec.LocalExecStrategy)) + pctx.VariableFunc("RED8ExecStrategy", remoteexec.EnvOverrideFunc("RBE_D8_EXEC_STRATEGY", remoteexec.LocalExecStrategy)) + pctx.VariableFunc("RER8ExecStrategy", remoteexec.EnvOverrideFunc("RBE_R8_EXEC_STRATEGY", remoteexec.LocalExecStrategy)) + pctx.VariableFunc("RETurbineExecStrategy", remoteexec.EnvOverrideFunc("RBE_TURBINE_EXEC_STRATEGY", remoteexec.LocalExecStrategy)) + pctx.VariableFunc("RESignApkExecStrategy", remoteexec.EnvOverrideFunc("RBE_SIGNAPK_EXEC_STRATEGY", remoteexec.LocalExecStrategy)) + pctx.VariableFunc("REJarExecStrategy", remoteexec.EnvOverrideFunc("RBE_JAR_EXEC_STRATEGY", remoteexec.LocalExecStrategy)) + pctx.VariableFunc("REZipExecStrategy", remoteexec.EnvOverrideFunc("RBE_ZIP_EXEC_STRATEGY", remoteexec.LocalExecStrategy)) pctx.HostJavaToolVariable("JacocoCLIJar", "jacoco-cli.jar") diff --git a/java/dex.go b/java/dex.go index 62f17c6d8..9e61e95ad 100644 --- a/java/dex.go +++ b/java/dex.go @@ -21,41 +21,70 @@ import ( "github.com/google/blueprint/proptools" "android/soong/android" + "android/soong/remoteexec" ) -var d8 = pctx.AndroidRemoteStaticRule("d8", android.RemoteRuleSupports{RBE: true, RBEFlag: android.RBE_D8}, +var d8, d8RE = remoteexec.MultiCommandStaticRules(pctx, "d8", blueprint.RuleParams{ Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` + - `${config.D8Wrapper}${config.D8Cmd} ${config.DexFlags} --output $outDir $d8Flags $in && ` + - `${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` + + `$d8Template${config.D8Cmd} ${config.DexFlags} --output $outDir $d8Flags $in && ` + + `$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` + `${config.MergeZipsCmd} -D -stripFile "**/*.class" $out $outDir/classes.dex.jar $in`, CommandDeps: []string{ "${config.D8Cmd}", "${config.SoongZipCmd}", "${config.MergeZipsCmd}", }, - }, - "outDir", "d8Flags", "zipFlags") + }, map[string]*remoteexec.REParams{ + "$d8Template": &remoteexec.REParams{ + Labels: map[string]string{"type": "compile", "compiler": "d8"}, + Inputs: []string{"${config.D8Jar}"}, + ExecStrategy: "${config.RED8ExecStrategy}", + ToolchainInputs: []string{"${config.JavaCmd}"}, + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, + "$zipTemplate": &remoteexec.REParams{ + Labels: map[string]string{"type": "tool", "name": "soong_zip"}, + Inputs: []string{"${config.SoongZipCmd}", "$outDir"}, + OutputFiles: []string{"$outDir/classes.dex.jar"}, + ExecStrategy: "${config.RED8ExecStrategy}", + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, + }, []string{"outDir", "d8Flags", "zipFlags"}, nil) -var r8 = pctx.AndroidRemoteStaticRule("r8", android.RemoteRuleSupports{RBE: true, RBEFlag: android.RBE_R8}, +var r8, r8RE = remoteexec.MultiCommandStaticRules(pctx, "r8", blueprint.RuleParams{ Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` + `rm -f "$outDict" && ` + - `${config.R8Wrapper}${config.R8Cmd} ${config.DexFlags} -injars $in --output $outDir ` + + `$r8Template${config.R8Cmd} ${config.DexFlags} -injars $in --output $outDir ` + `--force-proguard-compatibility ` + `--no-data-resources ` + `-printmapping $outDict ` + `$r8Flags && ` + `touch "$outDict" && ` + - `${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` + + `$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` + `${config.MergeZipsCmd} -D -stripFile "**/*.class" $out $outDir/classes.dex.jar $in`, CommandDeps: []string{ "${config.R8Cmd}", "${config.SoongZipCmd}", "${config.MergeZipsCmd}", }, - }, - "outDir", "outDict", "r8Flags", "zipFlags") + }, map[string]*remoteexec.REParams{ + "$r8Template": &remoteexec.REParams{ + Labels: map[string]string{"type": "compile", "compiler": "r8"}, + Inputs: []string{"$implicits", "${config.R8Jar}"}, + ExecStrategy: "${config.RER8ExecStrategy}", + ToolchainInputs: []string{"${config.JavaCmd}"}, + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, + "$zipTemplate": &remoteexec.REParams{ + Labels: map[string]string{"type": "tool", "name": "soong_zip"}, + Inputs: []string{"${config.SoongZipCmd}", "$outDir"}, + OutputFiles: []string{"$outDir/classes.dex.jar"}, + ExecStrategy: "${config.RER8ExecStrategy}", + Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"}, + }, + }, []string{"outDir", "outDict", "r8Flags", "zipFlags"}, []string{"implicits"}) func (j *Module) dexCommonFlags(ctx android.ModuleContext) []string { flags := j.deviceProperties.Dxflags @@ -186,24 +215,34 @@ func (j *Module) compileDex(ctx android.ModuleContext, flags javaBuilderFlags, proguardDictionary := android.PathForModuleOut(ctx, "proguard_dictionary") j.proguardDictionary = proguardDictionary r8Flags, r8Deps := j.r8Flags(ctx, flags) + rule := r8 + args := map[string]string{ + "r8Flags": strings.Join(r8Flags, " "), + "zipFlags": zipFlags, + "outDict": j.proguardDictionary.String(), + "outDir": outDir.String(), + } + if ctx.Config().IsEnvTrue("RBE_R8") { + rule = r8RE + args["implicits"] = strings.Join(r8Deps.Strings(), ",") + } ctx.Build(pctx, android.BuildParams{ - Rule: r8, + Rule: rule, Description: "r8", Output: javalibJar, ImplicitOutput: proguardDictionary, Input: classesJar, Implicits: r8Deps, - Args: map[string]string{ - "r8Flags": strings.Join(r8Flags, " "), - "zipFlags": zipFlags, - "outDict": j.proguardDictionary.String(), - "outDir": outDir.String(), - }, + Args: args, }) } else { d8Flags, d8Deps := j.d8Flags(ctx, flags) + rule := d8 + if ctx.Config().IsEnvTrue("RBE_D8") { + rule = d8RE + } ctx.Build(pctx, android.BuildParams{ - Rule: d8, + Rule: rule, Description: "d8", Output: javalibJar, Input: classesJar, diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go index b518e9c0d..2f0cbdb8c 100644 --- a/java/dexpreopt_bootjars.go +++ b/java/dexpreopt_bootjars.go @@ -611,10 +611,10 @@ func updatableBcpPackagesRule(ctx android.SingletonContext, image *bootImageConf // Collect `permitted_packages` for updatable boot jars. var updatablePackages []string ctx.VisitAllModules(func(module android.Module) { - if j, ok := module.(*Library); ok { + if j, ok := module.(PermittedPackagesForUpdatableBootJars); ok { name := ctx.ModuleName(module) if i := android.IndexList(name, updatableModules); i != -1 { - pp := j.properties.Permitted_packages + pp := j.PermittedPackagesForUpdatableBootJars() if len(pp) > 0 { updatablePackages = append(updatablePackages, pp...) } else { diff --git a/java/java.go b/java/java.go index c30dc4e50..2623d2c10 100644 --- a/java/java.go +++ b/java/java.go @@ -1462,13 +1462,19 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) { serviceFile := file.String() zipargs = append(zipargs, "-C", filepath.Dir(serviceFile), "-f", serviceFile) } + rule := zip + args := map[string]string{ + "jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscapeList(zipargs), " "), + } + if ctx.Config().IsEnvTrue("RBE_ZIP") { + rule = zipRE + args["implicits"] = strings.Join(services.Strings(), ",") + } ctx.Build(pctx, android.BuildParams{ - Rule: zip, + Rule: rule, Output: servicesJar, Implicits: services, - Args: map[string]string{ - "jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscapeList(zipargs), " "), - }, + Args: args, }) jars = append(jars, servicesJar) } @@ -1839,6 +1845,17 @@ type Library struct { InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths) } +// Provides access to the list of permitted packages from updatable boot jars. +type PermittedPackagesForUpdatableBootJars interface { + PermittedPackagesForUpdatableBootJars() []string +} + +var _ PermittedPackagesForUpdatableBootJars = (*Library)(nil) + +func (j *Library) PermittedPackagesForUpdatableBootJars() []string { + return j.properties.Permitted_packages +} + func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool { // Store uncompressed (and aligned) any dex files from jars in APEXes. if am, ok := ctx.Module().(android.ApexModule); ok && !am.IsForPlatform() { diff --git a/java/java_test.go b/java/java_test.go index 385fe6afd..04717238d 100644 --- a/java/java_test.go +++ b/java/java_test.go @@ -1465,6 +1465,33 @@ func TestJavaSdkLibrary_FallbackScope(t *testing.T) { `) } +func TestJavaSdkLibrary_DefaultToStubs(t *testing.T) { + ctx, _ := testJava(t, ` + java_sdk_library { + name: "foo", + srcs: ["a.java"], + system: { + enabled: true, + }, + default_to_stubs: true, + } + + java_library { + name: "baz", + srcs: ["a.java"], + libs: ["foo"], + // does not have sdk_version set, should fallback to module, + // which will then fallback to system because the module scope + // is not enabled. + } + `) + // The baz library should depend on the system stubs jar. + bazLibrary := ctx.ModuleForTests("baz", "android_common").Rule("javac") + if expected, actual := `^-classpath .*:/[^:]*/turbine-combined/foo\.stubs.system\.jar$`, bazLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) { + t.Errorf("expected %q, found %#q", expected, actual) + } +} + var compilerFlagsTestCases = []struct { in string out bool diff --git a/java/sdk_library.go b/java/sdk_library.go index 17217ed41..03b63b9f8 100644 --- a/java/sdk_library.go +++ b/java/sdk_library.go @@ -438,6 +438,14 @@ type sdkLibraryProperties struct { // disabled by default. Module_lib ApiScopeProperties + // Determines if the stubs are preferred over the implementation library + // for linking, even when the client doesn't specify sdk_version. When this + // is set to true, such clients are provided with the widest API surface that + // this lib provides. Note however that this option doesn't affect the clients + // that are in the same APEX as this library. In that case, the clients are + // always linked with the implementation library. Default is false. + Default_to_stubs *bool + // Properties related to api linting. Api_lint struct { // Enable api linting. @@ -1354,6 +1362,13 @@ func (module *SdkLibrary) withinSameApexAs(other android.Module) bool { } func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec, headerJars bool) android.Paths { + // If the client doesn't set sdk_version, but if this library prefers stubs over + // the impl library, let's provide the widest API surface possible. To do so, + // force override sdk_version to module_current so that the closest possible API + // surface could be found in selectHeaderJarsForSdkVersion + if module.defaultsToStubs() && !sdkVersion.specified() { + sdkVersion = sdkSpecFrom("module_current") + } // Only provide access to the implementation library if it is actually built. if module.requiresRuntimeImplementationLibrary() { @@ -1517,6 +1532,10 @@ func (module *SdkLibrary) requiresRuntimeImplementationLibrary() bool { return !proptools.Bool(module.sdkLibraryProperties.Api_only) } +func (module *SdkLibrary) defaultsToStubs() bool { + return proptools.Bool(module.sdkLibraryProperties.Default_to_stubs) +} + // Defines how to name the individual component modules the sdk library creates. type sdkLibraryComponentNamingScheme interface { stubsLibraryModuleName(scope *apiScope, baseName string) string @@ -2017,6 +2036,10 @@ type sdkLibrarySdkMemberProperties struct { // The naming scheme. Naming_scheme *string + + // True if the java_sdk_library_import is for a shared library, false + // otherwise. + Shared_library *bool } type scopeProperties struct { @@ -2051,12 +2074,16 @@ func (s *sdkLibrarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMembe s.Libs = sdk.properties.Libs s.Naming_scheme = sdk.commonSdkLibraryProperties.Naming_scheme + s.Shared_library = proptools.BoolPtr(sdk.sharedLibrary()) } func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) { if s.Naming_scheme != nil { propertySet.AddProperty("naming_scheme", proptools.String(s.Naming_scheme)) } + if s.Shared_library != nil { + propertySet.AddProperty("shared_library", *s.Shared_library) + } for _, apiScope := range allApiScopes { if properties, ok := s.Scopes[apiScope]; ok { diff --git a/phony/Android.bp b/phony/Android.bp new file mode 100644 index 000000000..2c423ef75 --- /dev/null +++ b/phony/Android.bp @@ -0,0 +1,12 @@ +bootstrap_go_package { + name: "soong-phony", + pkgPath: "android/soong/phony", + deps: [ + "blueprint", + "soong-android", + ], + srcs: [ + "phony.go", + ], + pluginFor: ["soong_build"], +} diff --git a/python/Android.bp b/python/Android.bp new file mode 100644 index 000000000..ffd03fe89 --- /dev/null +++ b/python/Android.bp @@ -0,0 +1,24 @@ +bootstrap_go_package { + name: "soong-python", + pkgPath: "android/soong/python", + deps: [ + "blueprint", + "soong-android", + "soong-tradefed", + ], + srcs: [ + "androidmk.go", + "binary.go", + "builder.go", + "defaults.go", + "installer.go", + "library.go", + "proto.go", + "python.go", + "test.go", + ], + testSrcs: [ + "python_test.go", + ], + pluginFor: ["soong_build"], +} diff --git a/remoteexec/Android.bp b/remoteexec/Android.bp new file mode 100644 index 000000000..fc2c0e324 --- /dev/null +++ b/remoteexec/Android.bp @@ -0,0 +1,15 @@ +bootstrap_go_package { + name: "soong-remoteexec", + pkgPath: "android/soong/remoteexec", + deps: [ + "blueprint", + "soong-android", + ], + srcs: [ + "remoteexec.go", + ], + testSrcs: [ + "remoteexec_test.go", + ], + pluginFor: ["soong_build"], +} diff --git a/remoteexec/remoteexec.go b/remoteexec/remoteexec.go index f51192263..c7d518eec 100644 --- a/remoteexec/remoteexec.go +++ b/remoteexec/remoteexec.go @@ -75,6 +75,9 @@ type REParams struct { // OutputFiles is a list of output file paths or ninja variables as placeholders for rule // outputs. OutputFiles []string + // OutputDirectories is a list of output directory paths or ninja variables as placeholders + // for rule outputs. + OutputDirectories []string // ToolchainInputs is a list of paths or ninja variables pointing to the location of // toolchain binaries used by the rule. ToolchainInputs []string @@ -137,6 +140,10 @@ func (r *REParams) Template() string { template += " --output_files=" + strings.Join(r.OutputFiles, ",") } + if len(r.OutputDirectories) > 0 { + template += " --output_directories=" + strings.Join(r.OutputDirectories, ",") + } + if len(r.ToolchainInputs) > 0 { template += " --toolchain_inputs=" + strings.Join(r.ToolchainInputs, ",") } @@ -145,7 +152,9 @@ func (r *REParams) Template() string { } // StaticRules returns a pair of rules based on the given RuleParams, where the first rule is a -// locally executable rule and the second rule is a remotely executable rule. +// locally executable rule and the second rule is a remotely executable rule. commonArgs are args +// used for both the local and remotely executable rules. reArgs are used only for remote +// execution. func StaticRules(ctx android.PackageContext, name string, ruleParams blueprint.RuleParams, reParams *REParams, commonArgs []string, reArgs []string) (blueprint.Rule, blueprint.Rule) { ruleParamsRE := ruleParams ruleParams.Command = strings.ReplaceAll(ruleParams.Command, "$reTemplate", "") @@ -154,3 +163,30 @@ func StaticRules(ctx android.PackageContext, name string, ruleParams blueprint.R return ctx.AndroidStaticRule(name, ruleParams, commonArgs...), ctx.AndroidRemoteStaticRule(name+"RE", android.RemoteRuleSupports{RBE: true}, ruleParamsRE, append(commonArgs, reArgs...)...) } + +// MultiCommandStaticRules returns a pair of rules based on the given RuleParams, where the first +// rule is a locally executable rule and the second rule is a remotely executable rule. This +// function supports multiple remote execution wrappers placed in the template when commands are +// chained together with &&. commonArgs are args used for both the local and remotely executable +// rules. reArgs are args used only for remote execution. +func MultiCommandStaticRules(ctx android.PackageContext, name string, ruleParams blueprint.RuleParams, reParams map[string]*REParams, commonArgs []string, reArgs []string) (blueprint.Rule, blueprint.Rule) { + ruleParamsRE := ruleParams + for k, v := range reParams { + ruleParams.Command = strings.ReplaceAll(ruleParams.Command, k, "") + ruleParamsRE.Command = strings.ReplaceAll(ruleParamsRE.Command, k, v.Template()) + } + + return ctx.AndroidStaticRule(name, ruleParams, commonArgs...), + ctx.AndroidRemoteStaticRule(name+"RE", android.RemoteRuleSupports{RBE: true}, ruleParamsRE, append(commonArgs, reArgs...)...) +} + +// EnvOverrideFunc retrieves a variable func that evaluates to the value of the given environment +// variable if set, otherwise the given default. +func EnvOverrideFunc(envVar, defaultVal string) func(ctx android.PackageVarContext) string { + return func(ctx android.PackageVarContext) string { + if override := ctx.Config().Getenv(envVar); override != "" { + return override + } + return defaultVal + } +} diff --git a/rust/Android.bp b/rust/Android.bp new file mode 100644 index 000000000..24fd83015 --- /dev/null +++ b/rust/Android.bp @@ -0,0 +1,30 @@ +bootstrap_go_package { + name: "soong-rust", + pkgPath: "android/soong/rust", + deps: [ + "soong", + "soong-android", + "soong-cc", + "soong-rust-config", + ], + srcs: [ + "androidmk.go", + "compiler.go", + "binary.go", + "builder.go", + "library.go", + "prebuilt.go", + "proc_macro.go", + "rust.go", + "test.go", + "testing.go", + ], + testSrcs: [ + "binary_test.go", + "compiler_test.go", + "library_test.go", + "rust_test.go", + "test_test.go", + ], + pluginFor: ["soong_build"], +} diff --git a/rust/config/Android.bp b/rust/config/Android.bp new file mode 100644 index 000000000..1a10312e2 --- /dev/null +++ b/rust/config/Android.bp @@ -0,0 +1,19 @@ +bootstrap_go_package { + name: "soong-rust-config", + pkgPath: "android/soong/rust/config", + deps: [ + "soong-android", + "soong-cc-config", + ], + srcs: [ + "arm_device.go", + "arm64_device.go", + "global.go", + "toolchain.go", + "whitelist.go", + "x86_darwin_host.go", + "x86_linux_host.go", + "x86_device.go", + "x86_64_device.go", + ], +} diff --git a/scripts/package-check.sh b/scripts/package-check.sh index f982e8244..d7e602f31 100755 --- a/scripts/package-check.sh +++ b/scripts/package-check.sh @@ -52,6 +52,7 @@ zip_contents=`zipinfo -1 $jar_file` # Check all class file names against the expected prefixes. old_ifs=${IFS} IFS=$'\n' +failed=false for zip_entry in ${zip_contents}; do # Check the suffix. if [[ "${zip_entry}" = *.class ]]; then @@ -65,8 +66,11 @@ for zip_entry in ${zip_contents}; do done if [[ "${found}" == "false" ]]; then echo "Class file ${zip_entry} is outside specified packages." - exit 1 + failed=true fi fi done +if [[ "${failed}" == "true" ]]; then + exit 1 +fi IFS=${old_ifs} diff --git a/sdk/Android.bp b/sdk/Android.bp new file mode 100644 index 000000000..cb93351d9 --- /dev/null +++ b/sdk/Android.bp @@ -0,0 +1,27 @@ +bootstrap_go_package { + name: "soong-sdk", + pkgPath: "android/soong/sdk", + deps: [ + "blueprint", + "soong", + "soong-android", + "soong-apex", + "soong-cc", + "soong-java", + ], + srcs: [ + "bp.go", + "exports.go", + "sdk.go", + "update.go", + ], + testSrcs: [ + "bp_test.go", + "cc_sdk_test.go", + "exports_test.go", + "java_sdk_test.go", + "sdk_test.go", + "testing.go", + ], + pluginFor: ["soong_build"], +} diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go index bbd638494..f8e9fc163 100644 --- a/sdk/java_sdk_test.go +++ b/sdk/java_sdk_test.go @@ -989,6 +989,7 @@ func TestSnapshotWithJavaSdkLibrary(t *testing.T) { apex_available: ["//apex_available:anyapex"], srcs: ["Test.java"], sdk_version: "current", + shared_library: false, stubs_library_visibility: ["//other"], stubs_source_visibility: ["//another"], } @@ -1002,6 +1003,7 @@ java_sdk_library_import { name: "mysdk_myjavalib@current", sdk_member_name: "myjavalib", apex_available: ["//apex_available:anyapex"], + shared_library: false, public: { jars: ["sdk_library/public/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], @@ -1029,6 +1031,7 @@ java_sdk_library_import { name: "myjavalib", prefer: false, apex_available: ["//apex_available:anyapex"], + shared_library: false, public: { jars: ["sdk_library/public/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], @@ -1097,6 +1100,7 @@ func TestSnapshotWithJavaSdkLibrary_SdkVersion_None(t *testing.T) { java_sdk_library_import { name: "mysdk_myjavalib@current", sdk_member_name: "myjavalib", + shared_library: true, public: { jars: ["sdk_library/public/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], @@ -1109,6 +1113,7 @@ java_sdk_library_import { java_sdk_library_import { name: "myjavalib", prefer: false, + shared_library: true, public: { jars: ["sdk_library/public/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], @@ -1159,6 +1164,7 @@ func TestSnapshotWithJavaSdkLibrary_SdkVersion_ForScope(t *testing.T) { java_sdk_library_import { name: "mysdk_myjavalib@current", sdk_member_name: "myjavalib", + shared_library: true, public: { jars: ["sdk_library/public/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], @@ -1171,6 +1177,7 @@ java_sdk_library_import { java_sdk_library_import { name: "myjavalib", prefer: false, + shared_library: true, public: { jars: ["sdk_library/public/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], @@ -1225,6 +1232,7 @@ java_sdk_library_import { name: "mysdk_myjavalib@current", sdk_member_name: "myjavalib", apex_available: ["//apex_available:anyapex"], + shared_library: true, public: { jars: ["sdk_library/public/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], @@ -1245,6 +1253,7 @@ java_sdk_library_import { name: "myjavalib", prefer: false, apex_available: ["//apex_available:anyapex"], + shared_library: true, public: { jars: ["sdk_library/public/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], @@ -1313,6 +1322,7 @@ java_sdk_library_import { name: "mysdk_myjavalib@current", sdk_member_name: "myjavalib", apex_available: ["//apex_available:anyapex"], + shared_library: true, public: { jars: ["sdk_library/public/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], @@ -1340,6 +1350,7 @@ java_sdk_library_import { name: "myjavalib", prefer: false, apex_available: ["//apex_available:anyapex"], + shared_library: true, public: { jars: ["sdk_library/public/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], @@ -1415,6 +1426,7 @@ java_sdk_library_import { sdk_member_name: "myjavalib", apex_available: ["//apex_available:anyapex"], naming_scheme: "framework-modules", + shared_library: true, public: { jars: ["sdk_library/public/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], @@ -1429,6 +1441,7 @@ java_sdk_library_import { prefer: false, apex_available: ["//apex_available:anyapex"], naming_scheme: "framework-modules", + shared_library: true, public: { jars: ["sdk_library/public/myjavalib-stubs.jar"], stub_srcs: ["sdk_library/public/myjavalib_stub_sources"], diff --git a/sh/Android.bp b/sh/Android.bp new file mode 100644 index 000000000..0b04e7dea --- /dev/null +++ b/sh/Android.bp @@ -0,0 +1,16 @@ +bootstrap_go_package { + name: "soong-sh", + pkgPath: "android/soong/sh", + deps: [ + "blueprint", + "soong", + "soong-android", + ], + srcs: [ + "sh_binary.go", + ], + testSrcs: [ + "sh_binary_test.go", + ], + pluginFor: ["soong_build"], +} diff --git a/android/sh_binary.go b/sh/sh_binary.go index 7d9dc67b8..2dcd7162c 100644 --- a/android/sh_binary.go +++ b/sh/sh_binary.go @@ -12,12 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -package android +package sh import ( "fmt" "path/filepath" "strings" + + "github.com/google/blueprint/proptools" + + "android/soong/android" ) // sh_binary is for shell scripts (and batch files) that are installed as @@ -26,11 +30,15 @@ import ( // Do not use them for prebuilt C/C++/etc files. Use cc_prebuilt_binary // instead. +var pctx = android.NewPackageContext("android/soong/sh") + func init() { - RegisterModuleType("sh_binary", ShBinaryFactory) - RegisterModuleType("sh_binary_host", ShBinaryHostFactory) - RegisterModuleType("sh_test", ShTestFactory) - RegisterModuleType("sh_test_host", ShTestHostFactory) + pctx.Import("android/soong/android") + + android.RegisterModuleType("sh_binary", ShBinaryFactory) + android.RegisterModuleType("sh_binary_host", ShBinaryHostFactory) + android.RegisterModuleType("sh_test", ShTestFactory) + android.RegisterModuleType("sh_test_host", ShTestHostFactory) } type shBinaryProperties struct { @@ -69,55 +77,55 @@ type TestProperties struct { } type ShBinary struct { - ModuleBase + android.ModuleBase properties shBinaryProperties - sourceFilePath Path - outputFilePath OutputPath - installedFile InstallPath + sourceFilePath android.Path + outputFilePath android.OutputPath + installedFile android.InstallPath } -var _ HostToolProvider = (*ShBinary)(nil) +var _ android.HostToolProvider = (*ShBinary)(nil) type ShTest struct { ShBinary testProperties TestProperties - data Paths + data android.Paths } -func (s *ShBinary) HostToolPath() OptionalPath { - return OptionalPathForPath(s.installedFile) +func (s *ShBinary) HostToolPath() android.OptionalPath { + return android.OptionalPathForPath(s.installedFile) } -func (s *ShBinary) DepsMutator(ctx BottomUpMutatorContext) { +func (s *ShBinary) DepsMutator(ctx android.BottomUpMutatorContext) { if s.properties.Src == nil { ctx.PropertyErrorf("src", "missing prebuilt source file") } } -func (s *ShBinary) OutputFile() OutputPath { +func (s *ShBinary) OutputFile() android.OutputPath { return s.outputFilePath } func (s *ShBinary) SubDir() string { - return String(s.properties.Sub_dir) + return proptools.String(s.properties.Sub_dir) } func (s *ShBinary) Installable() bool { - return s.properties.Installable == nil || Bool(s.properties.Installable) + return s.properties.Installable == nil || proptools.Bool(s.properties.Installable) } func (s *ShBinary) Symlinks() []string { return s.properties.Symlinks } -func (s *ShBinary) generateAndroidBuildActions(ctx ModuleContext) { - s.sourceFilePath = PathForModuleSrc(ctx, String(s.properties.Src)) - filename := String(s.properties.Filename) - filename_from_src := Bool(s.properties.Filename_from_src) +func (s *ShBinary) generateAndroidBuildActions(ctx android.ModuleContext) { + s.sourceFilePath = android.PathForModuleSrc(ctx, proptools.String(s.properties.Src)) + filename := proptools.String(s.properties.Filename) + filename_from_src := proptools.Bool(s.properties.Filename_from_src) if filename == "" { if filename_from_src { filename = s.sourceFilePath.Base() @@ -128,38 +136,38 @@ func (s *ShBinary) generateAndroidBuildActions(ctx ModuleContext) { ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true") return } - s.outputFilePath = PathForModuleOut(ctx, filename).OutputPath + s.outputFilePath = android.PathForModuleOut(ctx, filename).OutputPath // This ensures that outputFilePath has the correct name for others to // use, as the source file may have a different name. - ctx.Build(pctx, BuildParams{ - Rule: CpExecutable, + ctx.Build(pctx, android.BuildParams{ + Rule: android.CpExecutable, Output: s.outputFilePath, Input: s.sourceFilePath, }) } -func (s *ShBinary) GenerateAndroidBuildActions(ctx ModuleContext) { +func (s *ShBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) { s.generateAndroidBuildActions(ctx) - installDir := PathForModuleInstall(ctx, "bin", String(s.properties.Sub_dir)) + installDir := android.PathForModuleInstall(ctx, "bin", proptools.String(s.properties.Sub_dir)) s.installedFile = ctx.InstallExecutable(installDir, s.outputFilePath.Base(), s.outputFilePath) } -func (s *ShBinary) AndroidMkEntries() []AndroidMkEntries { - return []AndroidMkEntries{AndroidMkEntries{ +func (s *ShBinary) AndroidMkEntries() []android.AndroidMkEntries { + return []android.AndroidMkEntries{android.AndroidMkEntries{ Class: "EXECUTABLES", - OutputFile: OptionalPathForPath(s.outputFilePath), + OutputFile: android.OptionalPathForPath(s.outputFilePath), Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk", - ExtraEntries: []AndroidMkExtraEntriesFunc{ - func(entries *AndroidMkEntries) { + ExtraEntries: []android.AndroidMkExtraEntriesFunc{ + func(entries *android.AndroidMkEntries) { s.customAndroidMkEntries(entries) }, }, }} } -func (s *ShBinary) customAndroidMkEntries(entries *AndroidMkEntries) { - entries.SetString("LOCAL_MODULE_RELATIVE_PATH", String(s.properties.Sub_dir)) +func (s *ShBinary) customAndroidMkEntries(entries *android.AndroidMkEntries) { + entries.SetString("LOCAL_MODULE_RELATIVE_PATH", proptools.String(s.properties.Sub_dir)) entries.SetString("LOCAL_MODULE_SUFFIX", "") entries.SetString("LOCAL_MODULE_STEM", s.outputFilePath.Rel()) if len(s.properties.Symlinks) > 0 { @@ -167,38 +175,38 @@ func (s *ShBinary) customAndroidMkEntries(entries *AndroidMkEntries) { } } -func (s *ShTest) GenerateAndroidBuildActions(ctx ModuleContext) { +func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) { s.ShBinary.generateAndroidBuildActions(ctx) testDir := "nativetest" if ctx.Target().Arch.ArchType.Multilib == "lib64" { testDir = "nativetest64" } - if ctx.Target().NativeBridge == NativeBridgeEnabled { + if ctx.Target().NativeBridge == android.NativeBridgeEnabled { testDir = filepath.Join(testDir, ctx.Target().NativeBridgeRelativePath) } else if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) { testDir = filepath.Join(testDir, ctx.Arch().ArchType.String()) } - installDir := PathForModuleInstall(ctx, testDir, String(s.properties.Sub_dir)) + installDir := android.PathForModuleInstall(ctx, testDir, proptools.String(s.properties.Sub_dir)) s.installedFile = ctx.InstallExecutable(installDir, s.outputFilePath.Base(), s.outputFilePath) - s.data = PathsForModuleSrc(ctx, s.testProperties.Data) + s.data = android.PathsForModuleSrc(ctx, s.testProperties.Data) } func (s *ShTest) InstallInData() bool { return true } -func (s *ShTest) AndroidMkEntries() []AndroidMkEntries { - return []AndroidMkEntries{AndroidMkEntries{ +func (s *ShTest) AndroidMkEntries() []android.AndroidMkEntries { + return []android.AndroidMkEntries{android.AndroidMkEntries{ Class: "NATIVE_TESTS", - OutputFile: OptionalPathForPath(s.outputFilePath), + OutputFile: android.OptionalPathForPath(s.outputFilePath), Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk", - ExtraEntries: []AndroidMkExtraEntriesFunc{ - func(entries *AndroidMkEntries) { + ExtraEntries: []android.AndroidMkExtraEntriesFunc{ + func(entries *android.AndroidMkEntries) { s.customAndroidMkEntries(entries) entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", s.testProperties.Test_suites...) - entries.SetString("LOCAL_TEST_CONFIG", String(s.testProperties.Test_config)) + entries.SetString("LOCAL_TEST_CONFIG", proptools.String(s.testProperties.Test_config)) for _, d := range s.data { rel := d.Rel() path := d.String() @@ -219,41 +227,41 @@ func InitShBinaryModule(s *ShBinary) { // sh_binary is for a shell script or batch file to be installed as an // executable binary to <partition>/bin. -func ShBinaryFactory() Module { +func ShBinaryFactory() android.Module { module := &ShBinary{} - module.Prefer32(func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool { - return class == Device && ctx.Config().DevicePrefer32BitExecutables() + module.Prefer32(func(ctx android.BaseModuleContext, base *android.ModuleBase, class android.OsClass) bool { + return class == android.Device && ctx.Config().DevicePrefer32BitExecutables() }) InitShBinaryModule(module) - InitAndroidArchModule(module, HostAndDeviceSupported, MultilibFirst) + android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibFirst) return module } // sh_binary_host is for a shell script to be installed as an executable binary // to $(HOST_OUT)/bin. -func ShBinaryHostFactory() Module { +func ShBinaryHostFactory() android.Module { module := &ShBinary{} InitShBinaryModule(module) - InitAndroidArchModule(module, HostSupported, MultilibFirst) + android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst) return module } // sh_test defines a shell script based test module. -func ShTestFactory() Module { +func ShTestFactory() android.Module { module := &ShTest{} InitShBinaryModule(&module.ShBinary) module.AddProperties(&module.testProperties) - InitAndroidArchModule(module, HostAndDeviceSupported, MultilibFirst) + android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibFirst) return module } // sh_test_host defines a shell script based test module that runs on a host. -func ShTestHostFactory() Module { +func ShTestHostFactory() android.Module { module := &ShTest{} InitShBinaryModule(&module.ShBinary) module.AddProperties(&module.testProperties) - InitAndroidArchModule(module, HostSupported, MultilibFirst) + android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst) return module } diff --git a/android/sh_binary_test.go b/sh/sh_binary_test.go index 137e77348..6c0d96abe 100644 --- a/android/sh_binary_test.go +++ b/sh/sh_binary_test.go @@ -1,27 +1,56 @@ -package android +package sh import ( + "io/ioutil" + "os" "reflect" "testing" + + "android/soong/android" ) -func testShBinary(t *testing.T, bp string) (*TestContext, Config) { +var buildDir string + +func setUp() { + var err error + buildDir, err = ioutil.TempDir("", "soong_sh_test") + if err != nil { + panic(err) + } +} + +func tearDown() { + os.RemoveAll(buildDir) +} + +func TestMain(m *testing.M) { + run := func() int { + setUp() + defer tearDown() + + return m.Run() + } + + os.Exit(run()) +} + +func testShBinary(t *testing.T, bp string) (*android.TestContext, android.Config) { fs := map[string][]byte{ "test.sh": nil, "testdata/data1": nil, "testdata/sub/data2": nil, } - config := TestArchConfig(buildDir, nil, bp, fs) + config := android.TestArchConfig(buildDir, nil, bp, fs) - ctx := NewTestArchContext() + ctx := android.NewTestArchContext() ctx.RegisterModuleType("sh_test", ShTestFactory) ctx.RegisterModuleType("sh_test_host", ShTestHostFactory) ctx.Register(config) _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) - FailIfErrored(t, errs) + android.FailIfErrored(t, errs) _, errs = ctx.PrepareBuildActions(config) - FailIfErrored(t, errs) + android.FailIfErrored(t, errs) return ctx, config } @@ -41,7 +70,7 @@ func TestShTestTestData(t *testing.T) { mod := ctx.ModuleForTests("foo", "android_arm64_armv8-a").Module().(*ShTest) - entries := AndroidMkEntriesForTest(t, config, "", mod)[0] + entries := android.AndroidMkEntriesForTest(t, config, "", mod)[0] expected := []string{":testdata/data1", ":testdata/sub/data2"} actual := entries.EntryMap["LOCAL_TEST_DATA"] if !reflect.DeepEqual(expected, actual) { @@ -62,7 +91,7 @@ func TestShTestHost(t *testing.T) { } `) - buildOS := BuildOs.String() + buildOS := android.BuildOs.String() mod := ctx.ModuleForTests("foo", buildOS+"_x86_64").Module().(*ShTest) if !mod.Host() { t.Errorf("host bit is not set for a sh_test_host module.") diff --git a/shared/Android.bp b/shared/Android.bp new file mode 100644 index 000000000..07dfe11d3 --- /dev/null +++ b/shared/Android.bp @@ -0,0 +1,7 @@ +bootstrap_go_package { + name: "soong-shared", + pkgPath: "android/soong/shared", + srcs: [ + "paths.go", + ], +} diff --git a/sysprop/Android.bp b/sysprop/Android.bp new file mode 100644 index 000000000..48094f1ef --- /dev/null +++ b/sysprop/Android.bp @@ -0,0 +1,18 @@ +bootstrap_go_package { + name: "soong-sysprop", + pkgPath: "android/soong/sysprop", + deps: [ + "blueprint", + "soong", + "soong-android", + "soong-cc", + "soong-java", + ], + srcs: [ + "sysprop_library.go", + ], + testSrcs: [ + "sysprop_test.go", + ], + pluginFor: ["soong_build"], +} diff --git a/tradefed/Android.bp b/tradefed/Android.bp new file mode 100644 index 000000000..6e5e5330e --- /dev/null +++ b/tradefed/Android.bp @@ -0,0 +1,14 @@ +bootstrap_go_package { + name: "soong-tradefed", + pkgPath: "android/soong/tradefed", + deps: [ + "blueprint", + "soong-android", + ], + srcs: [ + "autogen.go", + "config.go", + "makevars.go", + ], + pluginFor: ["soong_build"], +} diff --git a/ui/build/build.go b/ui/build/build.go index f3feac2be..349a7de5e 100644 --- a/ui/build/build.go +++ b/ui/build/build.go @@ -142,7 +142,26 @@ func help(ctx Context, config Config, what int) { func Build(ctx Context, config Config, what int) { ctx.Verboseln("Starting build with args:", config.Arguments()) ctx.Verboseln("Environment:", config.Environment().Environ()) - ctx.Verbosef("Total RAM: %dGB", config.TotalRAM()/1024/1024/1024) + + if totalRAM := config.TotalRAM(); totalRAM != 0 { + ram := float32(totalRAM) / (1024 * 1024 * 1024) + ctx.Verbosef("Total RAM: %.3vGB", ram) + + if ram <= 16 { + ctx.Println("************************************************************") + ctx.Printf("You are building on a machine with %.3vGB of RAM\n", ram) + ctx.Println("") + ctx.Println("The minimum required amount of free memory is around 16GB,") + ctx.Println("and even with that, some configurations may not work.") + ctx.Println("") + ctx.Println("If you run into segfaults or other errors, try reducing your") + ctx.Println("-j value.") + ctx.Println("************************************************************") + } else if ram <= float32(config.Parallel()) { + ctx.Printf("Warning: high -j%d count compared to %.3vGB of RAM", config.Parallel(), ram) + ctx.Println("If you run into segfaults or other errors, try a lower -j value") + } + } ctx.BeginTrace(metrics.Total, "total") defer ctx.EndTrace() diff --git a/ui/build/config.go b/ui/build/config.go index 5b9d10aa9..3a1188bdf 100644 --- a/ui/build/config.go +++ b/ui/build/config.go @@ -738,6 +738,9 @@ func (c *configImpl) HighmemParallel() int { } else if c.totalRAM == 0 { // Couldn't detect the total RAM, don't restrict highmem processes. return parallel + } else if c.totalRAM <= 16*1024*1024*1024 { + // Less than 16GB of ram, restrict to 1 highmem processes + return 1 } else if c.totalRAM <= 32*1024*1024*1024 { // Less than 32GB of ram, restrict to 2 highmem processes return 2 @@ -787,48 +790,6 @@ func (c *configImpl) UseRBE() bool { return false } -func (c *configImpl) UseRBEJAVAC() bool { - if !c.UseRBE() { - return false - } - - if v, ok := c.environ.Get("RBE_JAVAC"); ok { - v = strings.TrimSpace(v) - if v != "" && v != "false" { - return true - } - } - return false -} - -func (c *configImpl) UseRBER8() bool { - if !c.UseRBE() { - return false - } - - if v, ok := c.environ.Get("RBE_R8"); ok { - v = strings.TrimSpace(v) - if v != "" && v != "false" { - return true - } - } - return false -} - -func (c *configImpl) UseRBED8() bool { - if !c.UseRBE() { - return false - } - - if v, ok := c.environ.Get("RBE_D8"); ok { - v = strings.TrimSpace(v) - if v != "" && v != "false" { - return true - } - } - return false -} - func (c *configImpl) StartRBE() bool { if !c.UseRBE() { return false diff --git a/xml/Android.bp b/xml/Android.bp new file mode 100644 index 000000000..cd25cff7b --- /dev/null +++ b/xml/Android.bp @@ -0,0 +1,18 @@ +bootstrap_go_package { + name: "soong-xml", + pkgPath: "android/soong/xml", + deps: [ + "blueprint", + "blueprint-pathtools", + "soong", + "soong-android", + "soong-etc", + ], + srcs: [ + "xml.go", + ], + testSrcs: [ + "xml_test.go", + ], + pluginFor: ["soong_build"], +} diff --git a/xml/xml.go b/xml/xml.go index 3a680eca3..8810ae4d5 100644 --- a/xml/xml.go +++ b/xml/xml.go @@ -16,6 +16,7 @@ package xml import ( "android/soong/android" + "android/soong/etc" "github.com/google/blueprint" "github.com/google/blueprint/proptools" @@ -62,7 +63,7 @@ type prebuiltEtcXmlProperties struct { } type prebuiltEtcXml struct { - android.PrebuiltEtc + etc.PrebuiltEtc properties prebuiltEtcXmlProperties } @@ -121,7 +122,7 @@ func (p *prebuiltEtcXml) GenerateAndroidBuildActions(ctx android.ModuleContext) func PrebuiltEtcXmlFactory() android.Module { module := &prebuiltEtcXml{} module.AddProperties(&module.properties) - android.InitPrebuiltEtcModule(&module.PrebuiltEtc, "etc") + etc.InitPrebuiltEtcModule(&module.PrebuiltEtc, "etc") // This module is device-only android.InitAndroidArchModule(module, android.DeviceSupported, android.MultilibFirst) return module diff --git a/xml/xml_test.go b/xml/xml_test.go index f8ec82356..abcb1085f 100644 --- a/xml/xml_test.go +++ b/xml/xml_test.go @@ -20,6 +20,7 @@ import ( "testing" "android/soong/android" + "android/soong/etc" ) var buildDir string @@ -57,7 +58,7 @@ func testXml(t *testing.T, bp string) *android.TestContext { } config := android.TestArchConfig(buildDir, nil, bp, fs) ctx := android.NewTestArchContext() - ctx.RegisterModuleType("prebuilt_etc", android.PrebuiltEtcFactory) + ctx.RegisterModuleType("prebuilt_etc", etc.PrebuiltEtcFactory) ctx.RegisterModuleType("prebuilt_etc_xml", PrebuiltEtcXmlFactory) ctx.Register(config) _, errs := ctx.ParseFileList(".", []string{"Android.bp"}) |