Merge "Turn on metalava sandbox warning in all droiddoc metalava invocations."
diff --git a/Android.bp b/Android.bp
index 73fad25..0b44198 100644
--- a/Android.bp
+++ b/Android.bp
@@ -11,14 +11,6 @@
]
bootstrap_go_package {
- name: "soong-env",
- pkgPath: "android/soong/env",
- srcs: [
- "env/env.go",
- ],
-}
-
-bootstrap_go_package {
name: "soong",
pkgPath: "android/soong",
deps: [
@@ -29,546 +21,6 @@
],
}
-bootstrap_go_package {
- name: "soong-android",
- pkgPath: "android/soong/android",
- deps: [
- "blueprint",
- "blueprint-bootstrap",
- "soong",
- "soong-android-soongconfig",
- "soong-env",
- "soong-shared",
- "soong-ui-metrics_proto",
- ],
- 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/metrics.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/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-remoteexec",
- "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",
- "soong-remoteexec",
- ],
- 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/coverage.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/coverage_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/OWNERS b/OWNERS
index e1db459..adf2b4c 100644
--- a/OWNERS
+++ b/OWNERS
@@ -1,4 +1,10 @@
-per-file * = asmundak@google.com,ccross@android.com,dwillemsen@google.com,jungjw@google.com,paulduffin@google.com
+per-file * = asmundak@google.com
+per-file * = ccross@android.com
+per-file * = dwillemsen@google.com
+per-file * = eakammer@google.com
+per-file * = jungjw@google.com
+per-file * = patricearruda@google.com
+per-file * = paulduffin@google.com
per-file ndk_*.go, *gen_stub_libs.py = danalbert@google.com
per-file clang.go,global.go = srhines@google.com, chh@google.com, pirama@google.com, yikong@google.com
diff --git a/android/Android.bp b/android/Android.bp
new file mode 100644
index 0000000..47dbc5d
--- /dev/null
+++ b/android/Android.bp
@@ -0,0 +1,80 @@
+bootstrap_go_package {
+ name: "soong-android",
+ pkgPath: "android/soong/android",
+ deps: [
+ "blueprint",
+ "blueprint-bootstrap",
+ "soong",
+ "soong-android-soongconfig",
+ "soong-env",
+ "soong-shared",
+ "soong-ui-metrics_proto",
+ ],
+ 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",
+ "metrics.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/neverallow.go b/android/neverallow.go
index 9e075b7..be3f712 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -187,6 +187,10 @@
// derive_sdk_prefer32 suppress the platform installation rules, but fails when
// the APEX modules contain the SDK variant and the platform variant still exists.
"frameworks/base/apex/sdkextensions/derive_sdk",
+ // These are for apps and shouldn't be used by non-SDK variant modules.
+ "prebuilts/ndk",
+ "tools/test/graphicsbenchmark/apps/sample_app",
+ "tools/test/graphicsbenchmark/functional_tests/java",
}
platformVariantPropertiesWhitelist := []string{
diff --git a/android/sh_binary.go b/android/sh_binary.go
deleted file mode 100644
index 7d9dc67..0000000
--- a/android/sh_binary.go
+++ /dev/null
@@ -1,259 +0,0 @@
-// Copyright 2019 Google Inc. All rights reserved.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package android
-
-import (
- "fmt"
- "path/filepath"
- "strings"
-)
-
-// sh_binary is for shell scripts (and batch files) that are installed as
-// executable files into .../bin/
-//
-// Do not use them for prebuilt C/C++/etc files. Use cc_prebuilt_binary
-// instead.
-
-func init() {
- RegisterModuleType("sh_binary", ShBinaryFactory)
- RegisterModuleType("sh_binary_host", ShBinaryHostFactory)
- RegisterModuleType("sh_test", ShTestFactory)
- RegisterModuleType("sh_test_host", ShTestHostFactory)
-}
-
-type shBinaryProperties struct {
- // Source file of this prebuilt.
- Src *string `android:"path,arch_variant"`
-
- // optional subdirectory under which this file is installed into
- Sub_dir *string `android:"arch_variant"`
-
- // optional name for the installed file. If unspecified, name of the module is used as the file name
- Filename *string `android:"arch_variant"`
-
- // when set to true, and filename property is not set, the name for the installed file
- // is the same as the file name of the source file.
- Filename_from_src *bool `android:"arch_variant"`
-
- // Whether this module is directly installable to one of the partitions. Default: true.
- Installable *bool
-
- // install symlinks to the binary
- Symlinks []string `android:"arch_variant"`
-}
-
-type TestProperties struct {
- // list of compatibility suites (for example "cts", "vts") that the module should be
- // installed into.
- Test_suites []string `android:"arch_variant"`
-
- // the name of the test configuration (for example "AndroidTest.xml") that should be
- // installed with the module.
- Test_config *string `android:"arch_variant"`
-
- // list of files or filegroup modules that provide data that should be installed alongside
- // the test.
- Data []string `android:"path,arch_variant"`
-}
-
-type ShBinary struct {
- ModuleBase
-
- properties shBinaryProperties
-
- sourceFilePath Path
- outputFilePath OutputPath
- installedFile InstallPath
-}
-
-var _ HostToolProvider = (*ShBinary)(nil)
-
-type ShTest struct {
- ShBinary
-
- testProperties TestProperties
-
- data Paths
-}
-
-func (s *ShBinary) HostToolPath() OptionalPath {
- return OptionalPathForPath(s.installedFile)
-}
-
-func (s *ShBinary) DepsMutator(ctx BottomUpMutatorContext) {
- if s.properties.Src == nil {
- ctx.PropertyErrorf("src", "missing prebuilt source file")
- }
-}
-
-func (s *ShBinary) OutputFile() OutputPath {
- return s.outputFilePath
-}
-
-func (s *ShBinary) SubDir() string {
- return String(s.properties.Sub_dir)
-}
-
-func (s *ShBinary) Installable() bool {
- return s.properties.Installable == nil || 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)
- if filename == "" {
- if filename_from_src {
- filename = s.sourceFilePath.Base()
- } else {
- filename = ctx.ModuleName()
- }
- } else if filename_from_src {
- ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
- return
- }
- s.outputFilePath = 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,
- Output: s.outputFilePath,
- Input: s.sourceFilePath,
- })
-}
-
-func (s *ShBinary) GenerateAndroidBuildActions(ctx ModuleContext) {
- s.generateAndroidBuildActions(ctx)
- installDir := PathForModuleInstall(ctx, "bin", String(s.properties.Sub_dir))
- s.installedFile = ctx.InstallExecutable(installDir, s.outputFilePath.Base(), s.outputFilePath)
-}
-
-func (s *ShBinary) AndroidMkEntries() []AndroidMkEntries {
- return []AndroidMkEntries{AndroidMkEntries{
- Class: "EXECUTABLES",
- OutputFile: OptionalPathForPath(s.outputFilePath),
- Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
- ExtraEntries: []AndroidMkExtraEntriesFunc{
- func(entries *AndroidMkEntries) {
- s.customAndroidMkEntries(entries)
- },
- },
- }}
-}
-
-func (s *ShBinary) customAndroidMkEntries(entries *AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_RELATIVE_PATH", String(s.properties.Sub_dir))
- entries.SetString("LOCAL_MODULE_SUFFIX", "")
- entries.SetString("LOCAL_MODULE_STEM", s.outputFilePath.Rel())
- if len(s.properties.Symlinks) > 0 {
- entries.SetString("LOCAL_MODULE_SYMLINKS", strings.Join(s.properties.Symlinks, " "))
- }
-}
-
-func (s *ShTest) GenerateAndroidBuildActions(ctx ModuleContext) {
- s.ShBinary.generateAndroidBuildActions(ctx)
- testDir := "nativetest"
- if ctx.Target().Arch.ArchType.Multilib == "lib64" {
- testDir = "nativetest64"
- }
- if ctx.Target().NativeBridge == 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))
- s.installedFile = ctx.InstallExecutable(installDir, s.outputFilePath.Base(), s.outputFilePath)
-
- s.data = PathsForModuleSrc(ctx, s.testProperties.Data)
-}
-
-func (s *ShTest) InstallInData() bool {
- return true
-}
-
-func (s *ShTest) AndroidMkEntries() []AndroidMkEntries {
- return []AndroidMkEntries{AndroidMkEntries{
- Class: "NATIVE_TESTS",
- OutputFile: OptionalPathForPath(s.outputFilePath),
- Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
- ExtraEntries: []AndroidMkExtraEntriesFunc{
- func(entries *AndroidMkEntries) {
- s.customAndroidMkEntries(entries)
-
- entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", s.testProperties.Test_suites...)
- entries.SetString("LOCAL_TEST_CONFIG", String(s.testProperties.Test_config))
- for _, d := range s.data {
- rel := d.Rel()
- path := d.String()
- if !strings.HasSuffix(path, rel) {
- panic(fmt.Errorf("path %q does not end with %q", path, rel))
- }
- path = strings.TrimSuffix(path, rel)
- entries.AddStrings("LOCAL_TEST_DATA", path+":"+rel)
- }
- },
- },
- }}
-}
-
-func InitShBinaryModule(s *ShBinary) {
- s.AddProperties(&s.properties)
-}
-
-// sh_binary is for a shell script or batch file to be installed as an
-// executable binary to <partition>/bin.
-func ShBinaryFactory() Module {
- module := &ShBinary{}
- module.Prefer32(func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool {
- return class == Device && ctx.Config().DevicePrefer32BitExecutables()
- })
- InitShBinaryModule(module)
- InitAndroidArchModule(module, HostAndDeviceSupported, 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 {
- module := &ShBinary{}
- InitShBinaryModule(module)
- InitAndroidArchModule(module, HostSupported, MultilibFirst)
- return module
-}
-
-// sh_test defines a shell script based test module.
-func ShTestFactory() Module {
- module := &ShTest{}
- InitShBinaryModule(&module.ShBinary)
- module.AddProperties(&module.testProperties)
-
- InitAndroidArchModule(module, HostAndDeviceSupported, MultilibFirst)
- return module
-}
-
-// sh_test_host defines a shell script based test module that runs on a host.
-func ShTestHostFactory() Module {
- module := &ShTest{}
- InitShBinaryModule(&module.ShBinary)
- module.AddProperties(&module.testProperties)
-
- InitAndroidArchModule(module, HostSupported, MultilibFirst)
- return module
-}
diff --git a/android/soongconfig/Android.bp b/android/soongconfig/Android.bp
new file mode 100644
index 0000000..df912e6
--- /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 0000000..144f441
--- /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/androidmk.go b/apex/androidmk.go
index 9321ad2..1b3a4ba 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -81,7 +81,7 @@
seenDataOutPaths := make(map[string]bool)
for _, fi := range a.filesInfo {
- if cc, ok := fi.module.(*cc.Module); ok && cc.Properties.HideFromMake {
+ if ccMod, ok := fi.module.(*cc.Module); ok && ccMod.Properties.HideFromMake {
continue
}
@@ -178,7 +178,8 @@
if fi.jacocoReportClassesFile != nil {
fmt.Fprintln(w, "LOCAL_SOONG_JACOCO_REPORT_CLASSES_JAR :=", fi.jacocoReportClassesFile.String())
}
- if fi.class == javaSharedLib {
+ switch fi.class {
+ case javaSharedLib:
javaModule := fi.module.(java.Dependency)
// soong_java_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .jar Therefore
// we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
@@ -189,7 +190,7 @@
fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", fi.builtFile.String())
fmt.Fprintln(w, "LOCAL_DEX_PREOPT := false")
fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_java_prebuilt.mk")
- } else if fi.class == app {
+ case app:
fmt.Fprintln(w, "LOCAL_CERTIFICATE :=", fi.certificate.AndroidMkString())
// soong_app_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .apk Therefore
// we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
@@ -199,19 +200,26 @@
fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", strings.Join(app.JniCoverageOutputs().Strings(), " "))
}
fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_app_prebuilt.mk")
- } else if fi.class == nativeSharedLib || fi.class == nativeExecutable || fi.class == nativeTest {
+ case appSet:
+ as, ok := fi.module.(*java.AndroidAppSet)
+ if !ok {
+ panic(fmt.Sprintf("Expected %s to be AndroidAppSet", fi.module))
+ }
+ fmt.Fprintln(w, "LOCAL_APK_SET_MASTER_FILE :=", as.MasterFile())
+ fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_android_app_set.mk")
+ case nativeSharedLib, nativeExecutable, nativeTest:
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.Stem())
- if cc, ok := fi.module.(*cc.Module); ok {
- if cc.UnstrippedOutputFile() != nil {
- fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", cc.UnstrippedOutputFile().String())
+ if ccMod, ok := fi.module.(*cc.Module); ok {
+ if ccMod.UnstrippedOutputFile() != nil {
+ fmt.Fprintln(w, "LOCAL_SOONG_UNSTRIPPED_BINARY :=", ccMod.UnstrippedOutputFile().String())
}
- cc.AndroidMkWriteAdditionalDependenciesForSourceAbiDiff(w)
- if cc.CoverageOutputFile().Valid() {
- fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", cc.CoverageOutputFile().String())
+ ccMod.AndroidMkWriteAdditionalDependenciesForSourceAbiDiff(w)
+ if ccMod.CoverageOutputFile().Valid() {
+ fmt.Fprintln(w, "LOCAL_PREBUILT_COVERAGE_ARCHIVE :=", ccMod.CoverageOutputFile().String())
}
}
fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_cc_prebuilt.mk")
- } else {
+ default:
fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.Stem())
if fi.builtFile == a.manifestPbOut && apexType == flattenedApex {
if a.primaryApexType {
diff --git a/apex/apex.go b/apex/apex.go
index 10c16f5..2f7b2e5 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -22,14 +22,16 @@
"strings"
"sync"
- "android/soong/android"
- "android/soong/cc"
- "android/soong/java"
- "android/soong/python"
-
"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"
+ "android/soong/sh"
)
const (
@@ -1113,6 +1115,7 @@
javaSharedLib
nativeTest
app
+ appSet
)
func (class apexFileClass) NameInMake() string {
@@ -1127,7 +1130,7 @@
return "JAVA_LIBRARIES"
case nativeTest:
return "NATIVE_TESTS"
- case app:
+ case app, appSet:
// b/142537672 Why isn't this APP? We want to have full control over
// the paths and file names of the apk file under the flattend APEX.
// If this is set to APP, then the paths and file names are modified
@@ -1639,7 +1642,7 @@
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)
@@ -1648,20 +1651,21 @@
}
type javaDependency interface {
- java.Dependency
+ DexJarBuildPath() android.Path
+ JacocoReportClassesFile() android.Path
Stem() string
}
func apexFileForJavaLibrary(ctx android.BaseModuleContext, lib javaDependency, module android.Module) apexFile {
dirInApex := "javalib"
- fileToCopy := lib.DexJar()
+ fileToCopy := lib.DexJarBuildPath()
af := newApexFile(ctx, fileToCopy, module.Name(), dirInApex, javaSharedLib, module)
af.jacocoReportClassesFile = lib.JacocoReportClassesFile()
af.stem = lib.Stem() + ".jar"
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)
@@ -1965,7 +1969,7 @@
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))
@@ -1975,23 +1979,16 @@
ctx.PropertyErrorf("binaries", "%q is neither cc_binary, (embedded) py_binary, (host) blueprint_go_binary, (host) bootstrap_go_binary, nor sh_binary", depName)
}
case javaLibTag:
- if javaLib, ok := child.(*java.Library); ok {
- af := apexFileForJavaLibrary(ctx, javaLib, javaLib)
- if !af.Ok() {
- ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
- } else {
- filesInfo = append(filesInfo, af)
- return true // track transitive dependencies
- }
- } else if sdkLib, ok := child.(*java.SdkLibrary); ok {
- af := apexFileForJavaLibrary(ctx, sdkLib, sdkLib)
+ switch child.(type) {
+ case *java.Library, *java.SdkLibrary, *java.DexImport:
+ af := apexFileForJavaLibrary(ctx, child.(javaDependency), child.(android.Module))
if !af.Ok() {
ctx.PropertyErrorf("java_libs", "%q is not configured to be compiled into dex", depName)
return false
}
filesInfo = append(filesInfo, af)
return true // track transitive dependencies
- } else {
+ default:
ctx.PropertyErrorf("java_libs", "%q of type %q is not supported", depName, ctx.OtherModuleType(child))
}
case androidAppTag:
@@ -2002,6 +1999,15 @@
filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap))
} else if ap, ok := child.(*java.AndroidTestHelperApp); ok {
filesInfo = append(filesInfo, apexFileForAndroidApp(ctx, ap))
+ } else if ap, ok := child.(*java.AndroidAppSet); ok {
+ appDir := "app"
+ if ap.Privileged() {
+ appDir = "priv-app"
+ }
+ af := newApexFile(ctx, ap.OutputFile(), ap.Name(),
+ filepath.Join(appDir, ap.BaseModuleName()), appSet, ap)
+ af.certificate = java.PresignedCertificate
+ filesInfo = append(filesInfo, af)
} else {
ctx.PropertyErrorf("apps", "%q is not an android_app module", depName)
}
@@ -2012,7 +2018,7 @@
ctx.PropertyErrorf("rros", "%q is not an runtime_resource_overlay 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))
@@ -2109,7 +2115,7 @@
// 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 29bd087..d6a5d09 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -29,7 +29,9 @@
"android/soong/android"
"android/soong/cc"
"android/soong/dexpreopt"
+ prebuilt_etc "android/soong/etc"
"android/soong/java"
+ "android/soong/sh"
)
var buildDir string
@@ -94,7 +96,7 @@
// - X86 (secondary)
// - Arm64 on X86_64 (native bridge)
// - Arm on X86 (native bridge)
-func withNativeBridgeEnabled(fs map[string][]byte, config android.Config) {
+func withNativeBridgeEnabled(_ map[string][]byte, config android.Config) {
config.Targets[android.Android] = []android.Target{
{Os: android.Android, Arch: android.Arch{ArchType: android.X86_64, ArchVariant: "silvermont", Abi: []string{"arm64-v8a"}},
NativeBridge: android.NativeBridgeDisabled, NativeBridgeHostArchName: "", NativeBridgeRelativePath: ""},
@@ -113,15 +115,15 @@
}
}
-func withBinder32bit(fs map[string][]byte, config android.Config) {
+func withBinder32bit(_ map[string][]byte, config android.Config) {
config.TestProductVariables.Binder32bit = proptools.BoolPtr(true)
}
-func withUnbundledBuild(fs map[string][]byte, config android.Config) {
+func withUnbundledBuild(_ map[string][]byte, config android.Config) {
config.TestProductVariables.Unbundled_build = proptools.BoolPtr(true)
}
-func testApexContext(t *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
+func testApexContext(_ *testing.T, bp string, handlers ...testCustomizer) (*android.TestContext, android.Config) {
android.ClearApexDependency()
bp = bp + `
@@ -185,6 +187,7 @@
"baz": nil,
"bar/baz": nil,
"testdata/baz": nil,
+ "AppSet.apks": nil,
}
cc.GatherRequiredFilesForTest(fs)
@@ -230,9 +233,9 @@
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)
@@ -256,7 +259,7 @@
}
func tearDown() {
- os.RemoveAll(buildDir)
+ _ = os.RemoveAll(buildDir)
}
// ensure that 'result' equals 'expected'
@@ -292,6 +295,17 @@
}
}
+func ensureMatches(t *testing.T, result string, expectedRex string) {
+ ok, err := regexp.MatchString(expectedRex, result)
+ if err != nil {
+ t.Fatalf("regexp failure trying to match %s against `%s` expression: %s", result, expectedRex, err)
+ return
+ }
+ if !ok {
+ t.Errorf("%s does not match regular expession %s", result, expectedRex)
+ }
+}
+
func ensureListContains(t *testing.T, result []string, expected string) {
t.Helper()
if !android.InList(expected, result) {
@@ -327,7 +341,10 @@
binaries: ["foo",],
}
},
- java_libs: ["myjar"],
+ java_libs: [
+ "myjar",
+ "myjar_dex",
+ ],
}
apex {
@@ -436,6 +453,15 @@
],
}
+ dex_import {
+ name: "myjar_dex",
+ jars: ["prebuilt.jar"],
+ apex_available: [
+ "//apex_available:platform",
+ "myapex",
+ ],
+ }
+
java_library {
name: "myotherjar",
srcs: ["foo/bar/MyClass.java"],
@@ -471,6 +497,7 @@
// Ensure that apex variant is created for the direct dep
ensureListContains(t, ctx.ModuleVariantsForTests("mylib"), "android_arm64_armv8-a_shared_myapex")
ensureListContains(t, ctx.ModuleVariantsForTests("myjar"), "android_common_myapex")
+ ensureListContains(t, ctx.ModuleVariantsForTests("myjar_dex"), "android_common_myapex")
// Ensure that apex variant is created for the indirect dep
ensureListContains(t, ctx.ModuleVariantsForTests("mylib2"), "android_arm64_armv8-a_shared_myapex")
@@ -480,6 +507,7 @@
ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
ensureContains(t, copyCmds, "image.apex/lib64/mylib2.so")
ensureContains(t, copyCmds, "image.apex/javalib/myjar_stem.jar")
+ ensureContains(t, copyCmds, "image.apex/javalib/myjar_dex.jar")
// .. but not for java libs
ensureNotContains(t, copyCmds, "image.apex/javalib/myotherjar.jar")
ensureNotContains(t, copyCmds, "image.apex/javalib/msharedjar.jar")
@@ -4756,6 +4784,38 @@
ensureContains(t, content, `"apex_config":{"apex_embedded_apk_config":[{"package_name":"com.android.foo","path":"app/AppFoo/AppFoo.apk"}]}`)
}
+func TestAppSetBundle(t *testing.T) {
+ ctx, _ := testApex(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ apps: ["AppSet"],
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ android_app_set {
+ name: "AppSet",
+ set: "AppSet.apks",
+ }`)
+ mod := ctx.ModuleForTests("myapex", "android_common_myapex_image")
+ bundleConfigRule := mod.Description("Bundle Config")
+ content := bundleConfigRule.Args["content"]
+ ensureContains(t, content, `"compression":{"uncompressed_glob":["apex_payload.img","apex_manifest.*"]}`)
+ s := mod.Rule("apexRule").Args["copy_commands"]
+ copyCmds := regexp.MustCompile(" *&& *").Split(s, -1)
+ if len(copyCmds) != 3 {
+ t.Fatalf("Expected 3 commands, got %d in:\n%s", len(copyCmds), s)
+ }
+ ensureMatches(t, copyCmds[0], "^rm -rf .*/app/AppSet$")
+ ensureMatches(t, copyCmds[1], "^mkdir -p .*/app/AppSet$")
+ ensureMatches(t, copyCmds[2], "^unzip .*-d .*/app/AppSet .*/AppSet.zip$")
+}
+
func testNoUpdatableJarsInBootImage(t *testing.T, errmsg string, transformDexpreoptConfig func(*dexpreopt.GlobalConfig)) {
t.Helper()
@@ -4915,7 +4975,7 @@
func TestNoUpdatableJarsInBootImage(t *testing.T) {
- var error string
+ var err string
var transform func(*dexpreopt.GlobalConfig)
t.Run("updatable jar from ART apex in the ART boot image => ok", func(t *testing.T) {
@@ -4926,35 +4986,35 @@
})
t.Run("updatable jar from ART apex in the framework boot image => error", func(t *testing.T) {
- error = "module 'some-art-lib' from updatable apex 'com.android.art.something' is not allowed in the framework boot image"
+ err = "module 'some-art-lib' from updatable apex 'com.android.art.something' is not allowed in the framework boot image"
transform = func(config *dexpreopt.GlobalConfig) {
config.BootJars = []string{"com.android.art.something:some-art-lib"}
}
- testNoUpdatableJarsInBootImage(t, error, transform)
+ testNoUpdatableJarsInBootImage(t, err, transform)
})
t.Run("updatable jar from some other apex in the ART boot image => error", func(t *testing.T) {
- error = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the ART boot image"
+ err = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the ART boot image"
transform = func(config *dexpreopt.GlobalConfig) {
config.ArtApexJars = []string{"some-updatable-apex:some-updatable-apex-lib"}
}
- testNoUpdatableJarsInBootImage(t, error, transform)
+ testNoUpdatableJarsInBootImage(t, err, transform)
})
t.Run("non-updatable jar from some other apex in the ART boot image => error", func(t *testing.T) {
- error = "module 'some-non-updatable-apex-lib' is not allowed in the ART boot image"
+ err = "module 'some-non-updatable-apex-lib' is not allowed in the ART boot image"
transform = func(config *dexpreopt.GlobalConfig) {
config.ArtApexJars = []string{"some-non-updatable-apex:some-non-updatable-apex-lib"}
}
- testNoUpdatableJarsInBootImage(t, error, transform)
+ testNoUpdatableJarsInBootImage(t, err, transform)
})
t.Run("updatable jar from some other apex in the framework boot image => error", func(t *testing.T) {
- error = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the framework boot image"
+ err = "module 'some-updatable-apex-lib' from updatable apex 'some-updatable-apex' is not allowed in the framework boot image"
transform = func(config *dexpreopt.GlobalConfig) {
config.BootJars = []string{"some-updatable-apex:some-updatable-apex-lib"}
}
- testNoUpdatableJarsInBootImage(t, error, transform)
+ testNoUpdatableJarsInBootImage(t, err, transform)
})
t.Run("non-updatable jar from some other apex in the framework boot image => ok", func(t *testing.T) {
@@ -4965,27 +5025,27 @@
})
t.Run("nonexistent jar in the ART boot image => error", func(t *testing.T) {
- error = "failed to find a dex jar path for module 'nonexistent'"
+ err = "failed to find a dex jar path for module 'nonexistent'"
transform = func(config *dexpreopt.GlobalConfig) {
config.ArtApexJars = []string{"platform:nonexistent"}
}
- testNoUpdatableJarsInBootImage(t, error, transform)
+ testNoUpdatableJarsInBootImage(t, err, transform)
})
t.Run("nonexistent jar in the framework boot image => error", func(t *testing.T) {
- error = "failed to find a dex jar path for module 'nonexistent'"
+ err = "failed to find a dex jar path for module 'nonexistent'"
transform = func(config *dexpreopt.GlobalConfig) {
config.BootJars = []string{"platform:nonexistent"}
}
- testNoUpdatableJarsInBootImage(t, error, transform)
+ testNoUpdatableJarsInBootImage(t, err, transform)
})
t.Run("platform jar in the ART boot image => error", func(t *testing.T) {
- error = "module 'some-platform-lib' is not allowed in the ART boot image"
+ err = "module 'some-platform-lib' is not allowed in the ART boot image"
transform = func(config *dexpreopt.GlobalConfig) {
config.ArtApexJars = []string{"platform:some-platform-lib"}
}
- testNoUpdatableJarsInBootImage(t, error, transform)
+ testNoUpdatableJarsInBootImage(t, err, transform)
})
t.Run("platform jar in the framework boot image => ok", func(t *testing.T) {
diff --git a/apex/builder.go b/apex/builder.go
index 0108d06..17eac1a 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -69,11 +69,14 @@
// by default set to (uid/gid/mode) = (1000/1000/0644)
// TODO(b/113082813) make this configurable using config.fs syntax
generateFsConfig = pctx.StaticRule("generateFsConfig", blueprint.RuleParams{
- Command: `echo '/ 1000 1000 0755' > ${out} && ` +
- `echo ${ro_paths} | tr ' ' '\n' | awk '{print "/"$$1 " 1000 1000 0644"}' >> ${out} && ` +
- `echo ${exec_paths} | tr ' ' '\n' | awk '{print "/"$$1 " 0 2000 0755"}' >> ${out}`,
- Description: "fs_config ${out}",
- }, "ro_paths", "exec_paths")
+ Command: `( echo '/ 1000 1000 0755' ` +
+ `&& for i in ${ro_paths}; do echo "/$$i 1000 1000 0644"; done ` +
+ `&& for i in ${exec_paths}; do echo "/$$i 0 2000 0755"; done ` +
+ `&& ( tr ' ' '\n' <${out}.apklist | for i in ${apk_paths}; do read apk; echo "/$$i 0 2000 0755"; zipinfo -1 $$apk | sed "s:\(.*\):/$$i/\1 1000 1000 0644:"; done ) ) > ${out}`,
+ Description: "fs_config ${out}",
+ Rspfile: "$out.apklist",
+ RspfileContent: "$in",
+ }, "ro_paths", "exec_paths", "apk_paths")
apexManifestRule = pctx.StaticRule("apexManifestRule", blueprint.RuleParams{
Command: `rm -f $out && ${jsonmodify} $in ` +
@@ -287,7 +290,7 @@
// collect the manifest names and paths of android apps
// if their manifest names are overridden
for _, fi := range a.filesInfo {
- if fi.class != app {
+ if fi.class != app && fi.class != appSet {
continue
}
packageName := fi.overriddenPackageName
@@ -337,13 +340,22 @@
var copyCommands []string
for _, fi := range a.filesInfo {
destPath := android.PathForModuleOut(ctx, "image"+suffix, fi.Path()).String()
- copyCommands = append(copyCommands, "mkdir -p "+filepath.Dir(destPath))
+ destPathDir := filepath.Dir(destPath)
+ if fi.class == appSet {
+ copyCommands = append(copyCommands, "rm -rf "+destPathDir)
+ }
+ copyCommands = append(copyCommands, "mkdir -p "+destPathDir)
if a.linkToSystemLib && fi.transitiveDep && fi.AvailableToPlatform() {
// TODO(jiyong): pathOnDevice should come from fi.module, not being calculated here
pathOnDevice := filepath.Join("/system", fi.Path())
copyCommands = append(copyCommands, "ln -sfn "+pathOnDevice+" "+destPath)
} else {
- copyCommands = append(copyCommands, "cp -f "+fi.builtFile.String()+" "+destPath)
+ if fi.class == appSet {
+ copyCommands = append(copyCommands,
+ fmt.Sprintf("unzip -q -d %s %s", destPathDir, fi.builtFile.String()))
+ } else {
+ copyCommands = append(copyCommands, "cp -f "+fi.builtFile.String()+" "+destPath)
+ }
implicitInputs = append(implicitInputs, fi.builtFile)
}
// create additional symlinks pointing the file inside the APEX
@@ -416,6 +428,8 @@
// files and dirs that will be created in APEX
var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"}
var executablePaths []string // this also includes dirs
+ var extractedAppSetPaths android.Paths
+ var extractedAppSetDirs []string
for _, f := range a.filesInfo {
pathInApex := f.Path()
if f.installDir == "bin" || strings.HasPrefix(f.installDir, "bin/") {
@@ -426,6 +440,9 @@
for _, s := range f.symlinks {
executablePaths = append(executablePaths, filepath.Join(f.installDir, s))
}
+ } else if f.class == appSet {
+ extractedAppSetPaths = append(extractedAppSetPaths, f.builtFile)
+ extractedAppSetDirs = append(extractedAppSetDirs, f.installDir)
} else {
readOnlyPaths = append(readOnlyPaths, pathInApex)
}
@@ -446,9 +463,11 @@
Rule: generateFsConfig,
Output: cannedFsConfig,
Description: "generate fs config",
+ Inputs: extractedAppSetPaths,
Args: map[string]string{
"ro_paths": strings.Join(readOnlyPaths, " "),
"exec_paths": strings.Join(executablePaths, " "),
+ "apk_paths": strings.Join(extractedAppSetDirs, " "),
},
})
diff --git a/cc/Android.bp b/cc/Android.bp
new file mode 100644
index 0000000..9ece05f
--- /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 3ce1a89..52480ea 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -548,6 +548,25 @@
})
}
+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 661264e..251b7f0 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -231,6 +231,10 @@
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)
diff --git a/cc/cc.go b/cc/cc.go
index 94512d5..8eabff5 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -316,6 +316,8 @@
static() bool
staticBinary() bool
header() bool
+ binary() bool
+ object() bool
toolchain() config.Toolchain
canUseSdk() bool
useSdk() bool
@@ -1017,14 +1019,8 @@
}
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
}
@@ -1129,6 +1125,14 @@
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()
}
@@ -1925,7 +1929,7 @@
if deps.StaticUnwinderIfLegacy {
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "link", Variation: "static"},
- }, staticUnwinderDepTag, staticUnwinder(actx))
+ }, staticUnwinderDepTag, rewriteSnapshotLibs(staticUnwinder(actx), vendorSnapshotStaticLibs))
}
for _, lib := range deps.LateStaticLibs {
@@ -2006,11 +2010,13 @@
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)
@@ -2752,6 +2758,24 @@
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 {
@@ -3064,20 +3088,32 @@
// 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.
- // vendor_available modules are also available to /product.
- if !m.IsVndk() {
+
+ // 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() {
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 67eb248..76b4e38 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -258,9 +258,7 @@
}
}
-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 @@
}
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 @@
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 @@
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 @@
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 @@
// 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)
+ 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 libraries, all vendor:true and vendor_available modules are captured.
+ // 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/compiler.go b/cc/compiler.go
index 681b1ab..e7495da 100644
--- a/cc/compiler.go
+++ b/cc/compiler.go
@@ -300,8 +300,7 @@
if !(ctx.useSdk() || ctx.useVndk()) || ctx.Host() {
flags.SystemIncludeFlags = append(flags.SystemIncludeFlags,
"${config.CommonGlobalIncludes}",
- tc.IncludeFlags(),
- "${config.CommonNativehelperInclude}")
+ tc.IncludeFlags())
}
if ctx.useSdk() {
diff --git a/cc/config/Android.bp b/cc/config/Android.bp
new file mode 100644
index 0000000..6275064
--- /dev/null
+++ b/cc/config/Android.bp
@@ -0,0 +1,30 @@
+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",
+ "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/genrule.go b/cc/genrule.go
index 9331448..66d1784 100644
--- a/cc/genrule.go
+++ b/cc/genrule.go
@@ -79,8 +79,14 @@
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/object.go b/cc/object.go
index 19decec..15a529e 100644
--- a/cc/object.go
+++ b/cc/object.go
@@ -158,3 +158,7 @@
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 ac990f3..0751f1c 100644
--- a/cc/prebuilt.go
+++ b/cc/prebuilt.go
@@ -291,6 +291,10 @@
return nil
}
+func (p *prebuiltObjectLinker) object() bool {
+ return true
+}
+
func newPrebuiltObject() *Module {
module := newObject()
prebuilt := &prebuiltObjectLinker{
@@ -349,6 +353,10 @@
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 be020c5..edbb24d 100644
--- a/cc/testing.go
+++ b/cc/testing.go
@@ -496,6 +496,7 @@
"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 5801fc7..ea94544 100644
--- a/cc/vendor_snapshot.go
+++ b/cc/vendor_snapshot.go
@@ -30,6 +30,7 @@
vendorSnapshotSharedSuffix = ".vendor_shared."
vendorSnapshotStaticSuffix = ".vendor_static."
vendorSnapshotBinarySuffix = ".vendor_binary."
+ vendorSnapshotObjectSuffix = ".vendor_object."
)
var (
@@ -39,6 +40,7 @@
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 @@
}).(*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 @@
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 @@
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 @@
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 @@
// 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 @@
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 @@
(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 @@
(header only libraries)
binary/
(executable binaries)
+ object/
+ (.o object files)
NOTICE_FILES/
(notice files, e.g. libbase.txt)
configs/
@@ -620,7 +726,7 @@
}
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 @@
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 @@
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 @@
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 @@
}
} 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 @@
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 @@
// header
snapshotMap = vendorSnapshotHeaderLibs(ctx.Config())
}
- } else if _, ok := module.linker.(*binaryDecorator); ok {
+ } else if module.binary() {
snapshotMap = vendorSnapshotBinaries(ctx.Config())
- } else if _, ok := module.linker.(*prebuiltBinaryLinker); ok {
- 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 e5e4533..04b865f 100644
--- a/cc/vndk.go
+++ b/cc/vndk.go
@@ -25,6 +25,7 @@
"android/soong/android"
"android/soong/cc/config"
+ "android/soong/etc"
)
const (
@@ -416,7 +417,7 @@
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 53b5181..5a44c46 100644
--- a/cc/vndk_prebuilt.go
+++ b/cc/vndk_prebuilt.go
@@ -186,6 +186,10 @@
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/dexpreopt/config.go b/dexpreopt/config.go
index 98850e5..3440f8e 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -50,6 +50,8 @@
UpdatableSystemServerJars []string // jars within apex that are loaded into system server
SpeedApps []string // apps that should be speed optimized
+ BrokenSuboptimalOrderOfSystemServerJars bool // if true, sub-optimal order does not cause a build error
+
PreoptFlags []string // global dex2oat flags that should be used if no module-specific dex2oat flags are specified
DefaultCompilerFilter string // default compiler filter to pass to dex2oat, overridden by --compiler-filter= in module-specific dex2oat flags
@@ -98,6 +100,15 @@
ConstructContext android.Path
}
+// LibraryPath contains paths to the library DEX jar on host and on device.
+type LibraryPath struct {
+ Host android.Path
+ Device string
+}
+
+// LibraryPaths is a map from library name to on-host and on-device paths to its DEX jar.
+type LibraryPaths map[string]*LibraryPath
+
type ModuleConfig struct {
Name string
DexLocation string // dex location on device
@@ -115,7 +126,7 @@
EnforceUsesLibraries bool
PresentOptionalUsesLibraries []string
UsesLibraries []string
- LibraryPaths map[string]android.Path
+ LibraryPaths LibraryPaths
Archs []android.ArchType
DexPreoptImages []android.Path
@@ -163,14 +174,6 @@
return ret
}
-func constructPathMap(ctx android.PathContext, paths map[string]string) map[string]android.Path {
- ret := map[string]android.Path{}
- for key, path := range paths {
- ret[key] = constructPath(ctx, path)
- }
- return ret
-}
-
func constructWritablePath(ctx android.PathContext, path string) android.WritablePath {
if path == "" {
return nil
@@ -262,6 +265,13 @@
// from Make to read the module dexpreopt.config written in the Make config
// stage.
func ParseModuleConfig(ctx android.PathContext, data []byte) (*ModuleConfig, error) {
+ type jsonLibraryPath struct {
+ Host string
+ Device string
+ }
+
+ type jsonLibraryPaths map[string]jsonLibraryPath
+
type ModuleJSONConfig struct {
*ModuleConfig
@@ -271,12 +281,24 @@
DexPath string
ManifestPath string
ProfileClassListing string
- LibraryPaths map[string]string
+ LibraryPaths jsonLibraryPaths
DexPreoptImages []string
DexPreoptImageLocations []string
PreoptBootClassPathDexFiles []string
}
+ // convert JSON map of library paths to LibraryPaths
+ constructLibraryPaths := func(ctx android.PathContext, paths jsonLibraryPaths) LibraryPaths {
+ m := LibraryPaths{}
+ for lib, path := range paths {
+ m[lib] = &LibraryPath{
+ constructPath(ctx, path.Host),
+ path.Device,
+ }
+ }
+ return m
+ }
+
config := ModuleJSONConfig{}
err := json.Unmarshal(data, &config)
@@ -289,7 +311,7 @@
config.ModuleConfig.DexPath = constructPath(ctx, config.DexPath)
config.ModuleConfig.ManifestPath = constructPath(ctx, config.ManifestPath)
config.ModuleConfig.ProfileClassListing = android.OptionalPathForPath(constructPath(ctx, config.ProfileClassListing))
- config.ModuleConfig.LibraryPaths = constructPathMap(ctx, config.LibraryPaths)
+ config.ModuleConfig.LibraryPaths = constructLibraryPaths(ctx, config.LibraryPaths)
config.ModuleConfig.DexPreoptImages = constructPaths(ctx, config.DexPreoptImages)
config.ModuleConfig.DexPreoptImageLocations = config.DexPreoptImageLocations
config.ModuleConfig.PreoptBootClassPathDexFiles = constructPaths(ctx, config.PreoptBootClassPathDexFiles)
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index de696da..57a9250 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -37,6 +37,7 @@
"fmt"
"path/filepath"
"runtime"
+ "sort"
"strings"
"android/soong/android"
@@ -192,6 +193,56 @@
return profilePath
}
+type classLoaderContext struct {
+ // The class loader context using paths in the build.
+ Host android.Paths
+
+ // The class loader context using paths as they will be on the device.
+ Target []string
+}
+
+// A map of class loader contexts for each SDK version.
+// A map entry for "any" version contains libraries that are unconditionally added to class loader
+// context. Map entries for existing versions contains libraries that were in the default classpath
+// until that API version, and should be added to class loader context if and only if the
+// targetSdkVersion in the manifest or APK is less than that API version.
+type classLoaderContextMap map[int]*classLoaderContext
+
+const anySdkVersion int = -1
+
+func (m classLoaderContextMap) getSortedKeys() []int {
+ keys := make([]int, 0, len(m))
+ for k := range m {
+ keys = append(keys, k)
+ }
+ sort.Ints(keys)
+ return keys
+}
+
+func (m classLoaderContextMap) getValue(sdkVer int) *classLoaderContext {
+ if _, ok := m[sdkVer]; !ok {
+ m[sdkVer] = &classLoaderContext{}
+ }
+ return m[sdkVer]
+}
+
+func (m classLoaderContextMap) addLibs(sdkVer int, module *ModuleConfig, libs ...string) {
+ clc := m.getValue(sdkVer)
+ for _, lib := range libs {
+ p := pathForLibrary(module, lib)
+ clc.Host = append(clc.Host, p.Host)
+ clc.Target = append(clc.Target, p.Device)
+ }
+}
+
+func (m classLoaderContextMap) addSystemServerLibs(sdkVer int, ctx android.PathContext, module *ModuleConfig, libs ...string) {
+ clc := m.getValue(sdkVer)
+ for _, lib := range libs {
+ clc.Host = append(clc.Host, SystemServerDexJarHostPath(ctx, lib))
+ clc.Target = append(clc.Target, filepath.Join("/system/framework", lib+".jar"))
+ }
+}
+
func dexpreoptCommand(ctx android.PathContext, globalSoong *GlobalSoongConfig, global *GlobalConfig,
module *ModuleConfig, rule *android.RuleBuilder, archIdx int, profile android.WritablePath,
appImage bool, generateDM bool) {
@@ -227,86 +278,45 @@
systemServerJars := NonUpdatableSystemServerJars(ctx, global)
- // The class loader context using paths in the build
- var classLoaderContextHost android.Paths
-
- // The class loader context using paths as they will be on the device
- var classLoaderContextTarget []string
-
- // Extra paths that will be appended to the class loader if the APK manifest has targetSdkVersion < 28
- var conditionalClassLoaderContextHost28 android.Paths
- var conditionalClassLoaderContextTarget28 []string
-
- // Extra paths that will be appended to the class loader if the APK manifest has targetSdkVersion < 29
- var conditionalClassLoaderContextHost29 android.Paths
- var conditionalClassLoaderContextTarget29 []string
-
- // Extra paths that will be appended to the class loader if the APK manifest has targetSdkVersion < 30
- var conditionalClassLoaderContextHost30 android.Paths
- var conditionalClassLoaderContextTarget30 []string
+ classLoaderContexts := make(classLoaderContextMap)
// A flag indicating if the '&' class loader context is used.
unknownClassLoaderContext := false
if module.EnforceUsesLibraries {
+ // Unconditional class loader context.
usesLibs := append(copyOf(module.UsesLibraries), module.PresentOptionalUsesLibraries...)
+ classLoaderContexts.addLibs(anySdkVersion, module, usesLibs...)
- // Create class loader context for dex2oat from uses libraries and filtered optional libraries
- for _, l := range usesLibs {
-
- classLoaderContextHost = append(classLoaderContextHost,
- pathForLibrary(module, l))
- classLoaderContextTarget = append(classLoaderContextTarget,
- filepath.Join("/system/framework", l+".jar"))
- }
-
- // org.apache.http.legacy contains classes that were in the default classpath until API 28.
- // If the targetSdkVersion in the manifest or APK is < 28, and the module does not explicitly
- // depend on org.apache.http.legacy, then implicitly add it to the classpath for dexpreopt.
+ // Conditional class loader context for API version < 28.
const httpLegacy = "org.apache.http.legacy"
if !contains(usesLibs, httpLegacy) {
- conditionalClassLoaderContextHost28 = append(conditionalClassLoaderContextHost28,
- pathForLibrary(module, httpLegacy))
- conditionalClassLoaderContextTarget28 = append(conditionalClassLoaderContextTarget28,
- filepath.Join("/system/framework", httpLegacy+".jar"))
+ classLoaderContexts.addLibs(28, module, httpLegacy)
}
- // android.hidl.base-V1.0-java and android.hidl.manager-V1.0 contain classes that were in the default
- // classpath until API 29. If the targetSdkVersion in the manifest or APK is < 29 then implicitly add
- // the classes to the classpath for dexpreopt.
- const hidlBase = "android.hidl.base-V1.0-java"
- const hidlManager = "android.hidl.manager-V1.0-java"
- conditionalClassLoaderContextHost29 = append(conditionalClassLoaderContextHost29,
- pathForLibrary(module, hidlManager))
- conditionalClassLoaderContextTarget29 = append(conditionalClassLoaderContextTarget29,
- filepath.Join("/system/framework", hidlManager+".jar"))
- conditionalClassLoaderContextHost29 = append(conditionalClassLoaderContextHost29,
- pathForLibrary(module, hidlBase))
- conditionalClassLoaderContextTarget29 = append(conditionalClassLoaderContextTarget29,
- filepath.Join("/system/framework", hidlBase+".jar"))
+ // Conditional class loader context for API version < 29.
+ usesLibs29 := []string{
+ "android.hidl.base-V1.0-java",
+ "android.hidl.manager-V1.0-java",
+ }
+ classLoaderContexts.addLibs(29, module, usesLibs29...)
- // android.test.base contains classes that were in the default classpath until API 30.
- // If the targetSdkVersion in the manifest or APK is < 30 then implicitly add it to the
- // classpath for dexpreopt.
+ // Conditional class loader context for API version < 30.
const testBase = "android.test.base"
if !contains(usesLibs, testBase) {
- conditionalClassLoaderContextHost30 = append(conditionalClassLoaderContextHost30,
- pathForLibrary(module, testBase))
- conditionalClassLoaderContextTarget30 = append(conditionalClassLoaderContextTarget30,
- filepath.Join("/system/framework", testBase+".jar"))
+ classLoaderContexts.addLibs(30, module, testBase)
}
} else if jarIndex := android.IndexList(module.Name, systemServerJars); jarIndex >= 0 {
// System server jars should be dexpreopted together: class loader context of each jar
// should include all preceding jars on the system server classpath.
- for _, otherJar := range systemServerJars[:jarIndex] {
- classLoaderContextHost = append(classLoaderContextHost, SystemServerDexJarHostPath(ctx, otherJar))
- classLoaderContextTarget = append(classLoaderContextTarget, "/system/framework/"+otherJar+".jar")
- }
+ classLoaderContexts.addSystemServerLibs(anySdkVersion, ctx, module, systemServerJars[:jarIndex]...)
// Copy the system server jar to a predefined location where dex2oat will find it.
dexPathHost := SystemServerDexJarHostPath(ctx, module.Name)
rule.Command().Text("mkdir -p").Flag(filepath.Dir(dexPathHost.String()))
rule.Command().Text("cp -f").Input(module.DexPath).Output(dexPathHost)
+
+ checkSystemServerOrder(ctx, jarIndex)
} else {
// Pass special class loader context to skip the classpath and collision check.
// This will get removed once LOCAL_USES_LIBRARIES is enforced.
@@ -323,10 +333,11 @@
Text(`class_loader_context_arg=--class-loader-context=\&`).
Text(`stored_class_loader_context_arg=""`)
} else {
+ clc := classLoaderContexts[anySdkVersion]
rule.Command().
- Text("class_loader_context_arg=--class-loader-context=PCL[" + strings.Join(classLoaderContextHost.Strings(), ":") + "]").
- Implicits(classLoaderContextHost).
- Text("stored_class_loader_context_arg=--stored-class-loader-context=PCL[" + strings.Join(classLoaderContextTarget, ":") + "]")
+ Text("class_loader_context_arg=--class-loader-context=PCL[" + strings.Join(clc.Host.Strings(), ":") + "]").
+ Implicits(clc.Host).
+ Text("stored_class_loader_context_arg=--stored-class-loader-context=PCL[" + strings.Join(clc.Target, ":") + "]")
}
if module.EnforceUsesLibraries {
@@ -345,26 +356,19 @@
Text(`| grep "targetSdkVersion" | sed -n "s/targetSdkVersion:'\(.*\)'/\1/p"`).
Text(`)"`)
}
- rule.Command().Textf(`dex_preopt_host_libraries="%s"`,
- strings.Join(classLoaderContextHost.Strings(), " ")).
- Implicits(classLoaderContextHost)
- rule.Command().Textf(`dex_preopt_target_libraries="%s"`,
- strings.Join(classLoaderContextTarget, " "))
- rule.Command().Textf(`conditional_host_libs_28="%s"`,
- strings.Join(conditionalClassLoaderContextHost28.Strings(), " ")).
- Implicits(conditionalClassLoaderContextHost28)
- rule.Command().Textf(`conditional_target_libs_28="%s"`,
- strings.Join(conditionalClassLoaderContextTarget28, " "))
- rule.Command().Textf(`conditional_host_libs_29="%s"`,
- strings.Join(conditionalClassLoaderContextHost29.Strings(), " ")).
- Implicits(conditionalClassLoaderContextHost29)
- rule.Command().Textf(`conditional_target_libs_29="%s"`,
- strings.Join(conditionalClassLoaderContextTarget29, " "))
- rule.Command().Textf(`conditional_host_libs_30="%s"`,
- strings.Join(conditionalClassLoaderContextHost30.Strings(), " ")).
- Implicits(conditionalClassLoaderContextHost30)
- rule.Command().Textf(`conditional_target_libs_30="%s"`,
- strings.Join(conditionalClassLoaderContextTarget30, " "))
+ for _, ver := range classLoaderContexts.getSortedKeys() {
+ clc := classLoaderContexts.getValue(ver)
+ var varHost, varTarget string
+ if ver == anySdkVersion {
+ varHost = "dex_preopt_host_libraries"
+ varTarget = "dex_preopt_target_libraries"
+ } else {
+ varHost = fmt.Sprintf("conditional_host_libs_%d", ver)
+ varTarget = fmt.Sprintf("conditional_target_libs_%d", ver)
+ }
+ rule.Command().Textf(varHost+`="%s"`, strings.Join(clc.Host.Strings(), " ")).Implicits(clc.Host)
+ rule.Command().Textf(varTarget+`="%s"`, strings.Join(clc.Target, " "))
+ }
rule.Command().Text("source").Tool(globalSoong.ConstructContext).Input(module.DexPath)
}
@@ -554,7 +558,7 @@
return filepath.Join(filepath.Dir(filepath.Dir(path.String())), filepath.Base(path.String()))
}
-func pathForLibrary(module *ModuleConfig, lib string) android.Path {
+func pathForLibrary(module *ModuleConfig, lib string) *LibraryPath {
path, ok := module.LibraryPaths[lib]
if !ok {
panic(fmt.Errorf("unknown library path for %q", lib))
@@ -606,6 +610,29 @@
}
}
+// Check the order of jars on the system server classpath and give a warning/error if a jar precedes
+// one of its dependencies. This is not an error, but a missed optimization, as dexpreopt won't
+// have the dependency jar in the class loader context, and it won't be able to resolve any
+// references to its classes and methods.
+func checkSystemServerOrder(ctx android.PathContext, jarIndex int) {
+ mctx, isModule := ctx.(android.ModuleContext)
+ if isModule {
+ config := GetGlobalConfig(ctx)
+ jars := NonUpdatableSystemServerJars(ctx, config)
+ mctx.WalkDeps(func(dep android.Module, parent android.Module) bool {
+ depIndex := android.IndexList(dep.Name(), jars)
+ if jarIndex < depIndex && !config.BrokenSuboptimalOrderOfSystemServerJars {
+ jar := jars[jarIndex]
+ dep := jars[depIndex]
+ mctx.ModuleErrorf("non-optimal order of jars on the system server classpath:"+
+ " '%s' precedes its dependency '%s', so dexpreopt is unable to resolve any"+
+ " references from '%s' to '%s'.\n", jar, dep, jar, dep)
+ }
+ return true
+ })
+ }
+}
+
func contains(l []string, s string) bool {
for _, e := range l {
if e == s {
diff --git a/env/Android.bp b/env/Android.bp
new file mode 100644
index 0000000..90c6047
--- /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 0000000..cfd303e
--- /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
similarity index 62%
rename from android/prebuilt_etc.go
rename to etc/prebuilt_etc.go
index f0c0767..d6eb008 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 {
@@ -55,24 +65,24 @@
}
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 {
@@ -99,65 +109,65 @@
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()
@@ -168,7 +178,7 @@
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.
@@ -176,18 +186,18 @@
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"
@@ -195,12 +205,12 @@
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())
@@ -225,61 +235,61 @@
// 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
similarity index 89%
rename from android/prebuilt_etc_test.go
rename to etc/prebuilt_etc_test.go
index 6e751e7..e13cb3c 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 @@
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 @@
}
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 @@
}
`)
- 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 @@
}
`)
- 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 0000000..ff543a6
--- /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 0000000..2de1b8e
--- /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/aar.go b/java/aar.go
index c8daf83..7413c80 100644
--- a/java/aar.go
+++ b/java/aar.go
@@ -730,7 +730,7 @@
return android.Paths{a.classpathFile}
}
-func (a *AARImport) DexJar() android.Path {
+func (a *AARImport) DexJarBuildPath() android.Path {
return nil
}
diff --git a/java/app.go b/java/app.go
index a45ab6f..24dde79 100755
--- a/java/app.go
+++ b/java/app.go
@@ -28,6 +28,7 @@
"android/soong/android"
"android/soong/cc"
+ "android/soong/dexpreopt"
"android/soong/tradefed"
)
@@ -96,6 +97,14 @@
return Bool(as.properties.Privileged)
}
+func (as *AndroidAppSet) OutputFile() android.Path {
+ return as.packedOutput
+}
+
+func (as *AndroidAppSet) MasterFile() string {
+ return as.masterFile
+}
+
var TargetCpuAbi = map[string]string{
"arm": "ARMEABI_V7A",
"arm64": "ARM64_V8A",
@@ -120,7 +129,7 @@
}
func (as *AndroidAppSet) GenerateAndroidBuildActions(ctx android.ModuleContext) {
- as.packedOutput = android.PathForModuleOut(ctx, "extracted.zip")
+ as.packedOutput = android.PathForModuleOut(ctx, ctx.ModuleName()+".zip")
// We are assuming here that the master file in the APK
// set has `.apk` suffix. If it doesn't the build will fail.
// APK sets containing APEX files are handled elsewhere.
@@ -145,26 +154,17 @@
"stem": ctx.ModuleName(),
},
})
- // TODO(asmundak): add this (it's wrong now, will cause copying extracted.zip)
- /*
- var installDir android.InstallPath
- if Bool(as.properties.Privileged) {
- installDir = android.PathForModuleInstall(ctx, "priv-app", as.BaseModuleName())
- } else if ctx.InstallInTestcases() {
- installDir = android.PathForModuleInstall(ctx, as.BaseModuleName(), ctx.DeviceConfig().DeviceArch())
- } else {
- installDir = android.PathForModuleInstall(ctx, "app", as.BaseModuleName())
- }
- ctx.InstallFile(installDir, as.masterFile", as.packedOutput)
- */
}
// android_app_set extracts a set of APKs based on the target device
// configuration and installs this set as "split APKs".
-// The set will always contain `base-master.apk` and every APK built
-// to the target device. All density-specific APK will be included, too,
-// unless PRODUCT_APPT_PREBUILT_DPI is defined (should contain comma-sepearated
-// list of density names (LDPI, MDPI, HDPI, etc.)
+// The extracted set always contains 'master' APK whose name is
+// _module_name_.apk and every split APK matching target device.
+// The extraction of the density-specific splits depends on
+// PRODUCT_AAPT_PREBUILT_DPI variable. If present (its value should
+// be a list density names: LDPI, MDPI, HDPI, etc.), only listed
+// splits will be extracted. Otherwise all density-specific splits
+// will be extracted.
func AndroidApkSetFactory() android.Module {
module := &AndroidAppSet{}
module.AddProperties(&module.properties)
@@ -335,7 +335,7 @@
presigned bool
}
-var presignedCertificate = Certificate{presigned: true}
+var PresignedCertificate = Certificate{presigned: true}
func (c Certificate) AndroidMkString() string {
if c.presigned {
@@ -445,8 +445,11 @@
return
}
dep, _ := m.(*cc.Module)
- jniSdkVersion, err := android.ApiStrToNum(ctx, dep.SdkVersion())
- if err != nil || int(minSdkVersion) < jniSdkVersion {
+ // 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
@@ -1186,7 +1189,7 @@
android.OverrideModuleBase
}
-func (i *OverrideAndroidApp) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+func (i *OverrideAndroidApp) GenerateAndroidBuildActions(_ android.ModuleContext) {
// All the overrides happen in the base module.
// TODO(jungjw): Check the base module type.
}
@@ -1207,7 +1210,7 @@
android.OverrideModuleBase
}
-func (i *OverrideAndroidTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+func (i *OverrideAndroidTest) GenerateAndroidBuildActions(_ android.ModuleContext) {
// All the overrides happen in the base module.
// TODO(jungjw): Check the base module type.
}
@@ -1229,7 +1232,7 @@
android.OverrideModuleBase
}
-func (i *OverrideRuntimeResourceOverlay) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+func (i *OverrideRuntimeResourceOverlay) GenerateAndroidBuildActions(_ android.ModuleContext) {
// All the overrides happen in the base module.
// TODO(jungjw): Check the base module type.
}
@@ -1474,7 +1477,7 @@
// Sign or align the package if package has not been preprocessed
if a.preprocessed {
a.outputFile = srcApk
- a.certificate = presignedCertificate
+ a.certificate = PresignedCertificate
} else if !Bool(a.properties.Presigned) {
// If the certificate property is empty at this point, default_dev_cert must be set to true.
// Which makes processMainCert's behavior for the empty cert string WAI.
@@ -1494,7 +1497,7 @@
alignedApk := android.PathForModuleOut(ctx, "zip-aligned", apkFilename)
TransformZipAlign(ctx, alignedApk, dexOutput)
a.outputFile = alignedApk
- a.certificate = presignedCertificate
+ a.certificate = PresignedCertificate
}
// TODO: Optionally compress the output apk.
@@ -1552,7 +1555,7 @@
return Bool(a.properties.Privileged)
}
-func (a *AndroidAppImport) DepIsInSameApex(ctx android.BaseModuleContext, dep android.Module) bool {
+func (a *AndroidAppImport) DepIsInSameApex(_ android.BaseModuleContext, _ android.Module) bool {
// android_app_import might have extra dependencies via uses_libs property.
// Don't track the dependency as we don't automatically add those libraries
// to the classpath. It should be explicitly added to java_libs property of APEX
@@ -1875,24 +1878,30 @@
return optionalUsesLibs
}
-// usesLibraryPaths returns a map of module names of shared library dependencies to the paths to their dex jars.
-func (u *usesLibrary) usesLibraryPaths(ctx android.ModuleContext) map[string]android.Path {
- usesLibPaths := make(map[string]android.Path)
+// usesLibraryPaths returns a map of module names of shared library dependencies to the paths
+// to their dex jars on host and on device.
+func (u *usesLibrary) usesLibraryPaths(ctx android.ModuleContext) dexpreopt.LibraryPaths {
+ usesLibPaths := make(dexpreopt.LibraryPaths)
if !ctx.Config().UnbundledBuild() {
ctx.VisitDirectDepsWithTag(usesLibTag, func(m android.Module) {
+ dep := ctx.OtherModuleName(m)
if lib, ok := m.(Dependency); ok {
- if dexJar := lib.DexJar(); dexJar != nil {
- usesLibPaths[ctx.OtherModuleName(m)] = dexJar
+ if dexJar := lib.DexJarBuildPath(); dexJar != nil {
+ usesLibPaths[dep] = &dexpreopt.LibraryPath{
+ dexJar,
+ // TODO(b/132357300): propagate actual install paths here.
+ filepath.Join("/system/framework", dep+".jar"),
+ }
} else {
- ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must produce a dex jar, does it have installable: true?",
- ctx.OtherModuleName(m))
+ ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must"+
+ " produce a dex jar, does it have installable: true?", dep)
}
} else if ctx.Config().AllowMissingDependencies() {
- ctx.AddMissingDependencies([]string{ctx.OtherModuleName(m)})
+ ctx.AddMissingDependencies([]string{dep})
} else {
- ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be a java library",
- ctx.OtherModuleName(m))
+ ctx.ModuleErrorf("module %q in uses_libs or optional_uses_libs must be "+
+ "a java library", dep)
}
})
}
diff --git a/java/app_test.go b/java/app_test.go
index eb583be..eeba161 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -149,7 +149,7 @@
prerelease: true,
}`)
module := ctx.ModuleForTests("foo", "android_common")
- const packedSplitApks = "extracted.zip"
+ const packedSplitApks = "foo.zip"
params := module.Output(packedSplitApks)
if params.Rule == nil {
t.Errorf("expected output %s is missing", packedSplitApks)
@@ -218,7 +218,7 @@
ctx := testContext()
run(t, ctx, config)
module := ctx.ModuleForTests("foo", "android_common")
- const packedSplitApks = "extracted.zip"
+ const packedSplitApks = "foo.zip"
params := module.Output(packedSplitApks)
for k, v := range test.expected {
if actual := params.Args[k]; actual != v {
diff --git a/java/config/Android.bp b/java/config/Android.bp
new file mode 100644
index 0000000..1983521
--- /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/device_host_converter.go b/java/device_host_converter.go
index b40ab93..1ffb13f 100644
--- a/java/device_host_converter.go
+++ b/java/device_host_converter.go
@@ -150,7 +150,7 @@
return d.implementationAndResourceJars
}
-func (d *DeviceHostConverter) DexJar() android.Path {
+func (d *DeviceHostConverter) DexJarBuildPath() android.Path {
return nil
}
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 4725b07..2911fd9 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -37,7 +37,7 @@
usesLibs []string
optionalUsesLibs []string
enforceUsesLibs bool
- libraryPaths map[string]android.Path
+ libraryPaths dexpreopt.LibraryPaths
builtInstalled string
}
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index ed61d4b..9d93838 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -255,7 +255,7 @@
return -1, nil
}
- jar, hasJar := module.(interface{ DexJar() android.Path })
+ jar, hasJar := module.(interface{ DexJarBuildPath() android.Path })
if !hasJar {
return -1, nil
}
@@ -296,7 +296,7 @@
panic("unknown boot image: " + image.name)
}
- return index, jar.DexJar()
+ return index, jar.DexJarBuildPath()
}
// buildBootImage takes a bootImageConfig, creates rules to build it, and returns the image.
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 1b279cc..4c3e112 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -1334,13 +1334,10 @@
d.annotationsZip = android.PathForModuleOut(ctx, ctx.ModuleName()+"_annotations.zip")
cmd.FlagWithOutput("--extract-annotations ", d.annotationsZip)
- if len(d.properties.Merge_annotations_dirs) == 0 {
- ctx.PropertyErrorf("merge_annotations_dirs",
- "has to be non-empty if annotations was enabled!")
+ if len(d.properties.Merge_annotations_dirs) != 0 {
+ d.mergeAnnoDirFlags(ctx, cmd)
}
- d.mergeAnnoDirFlags(ctx, cmd)
-
// TODO(tnorbye): find owners to fix these warnings when annotation was enabled.
cmd.FlagWithArg("--hide ", "HiddenTypedefConstant").
FlagWithArg("--hide ", "SuperfluousPrefix").
diff --git a/java/hiddenapi_singleton.go b/java/hiddenapi_singleton.go
index c7f7cbd..2f35798 100644
--- a/java/hiddenapi_singleton.go
+++ b/java/hiddenapi_singleton.go
@@ -147,7 +147,7 @@
name := ctx.ModuleName(module)
for moduleList, pathList := range moduleListToPathList {
if i := android.IndexList(name, *moduleList); i != -1 {
- pathList[i] = j.DexJar()
+ pathList[i] = j.DexJarBuildPath()
}
}
}
diff --git a/java/java.go b/java/java.go
index 76bfa86..0ba1f5a 100644
--- a/java/java.go
+++ b/java/java.go
@@ -501,7 +501,7 @@
ImplementationJars() android.Paths
ResourceJars() android.Paths
ImplementationAndResourcesJars() android.Paths
- DexJar() android.Path
+ DexJarBuildPath() android.Path
AidlIncludeDirs() android.Paths
ExportedSdkLibs() []string
ExportedPlugins() (android.Paths, []string)
@@ -836,41 +836,46 @@
}
func (m *Module) getLinkType(name string) (ret linkType, stubs bool) {
- ver := m.sdkVersion()
- switch {
- case name == "core.current.stubs" || name == "core.platform.api.stubs" ||
- name == "stub-annotations" || name == "private-stub-annotations-jar" ||
- name == "core-lambda-stubs" || name == "core-generated-annotation-stubs":
+ switch name {
+ case "core.current.stubs", "core.platform.api.stubs", "stub-annotations",
+ "private-stub-annotations-jar", "core-lambda-stubs", "core-generated-annotation-stubs":
return javaCore, true
- case ver.kind == sdkCore:
- return javaCore, false
- case name == "android_system_stubs_current":
- return javaSystem, true
- case ver.kind == sdkSystem:
- return javaSystem, false
- case name == "android_test_stubs_current":
- return javaSystem, true
- case ver.kind == sdkTest:
- return javaPlatform, false
- case name == "android_stubs_current":
+ case "android_stubs_current":
return javaSdk, true
- case ver.kind == sdkPublic:
- return javaSdk, false
- case name == "android_module_lib_stubs_current":
+ case "android_system_stubs_current":
+ return javaSystem, true
+ case "android_module_lib_stubs_current":
return javaModule, true
- case ver.kind == sdkModule:
- return javaModule, false
- case name == "android_system_server_stubs_current":
+ case "android_system_server_stubs_current":
return javaSystemServer, true
- case ver.kind == sdkSystemServer:
- return javaSystemServer, false
- case ver.kind == sdkPrivate || ver.kind == sdkNone || ver.kind == sdkCorePlatform:
- return javaPlatform, false
- case !ver.valid():
- panic(fmt.Errorf("sdk_version is invalid. got %q", ver.raw))
- default:
- return javaSdk, false
+ case "android_test_stubs_current":
+ return javaSystem, true
}
+
+ if stub, linkType := moduleStubLinkType(name); stub {
+ return linkType, true
+ }
+
+ ver := m.sdkVersion()
+ switch ver.kind {
+ case sdkCore:
+ return javaCore, false
+ case sdkSystem:
+ return javaSystem, false
+ case sdkPublic:
+ return javaSdk, false
+ case sdkModule:
+ return javaModule, false
+ case sdkSystemServer:
+ return javaSystemServer, false
+ case sdkPrivate, sdkNone, sdkCorePlatform, sdkTest:
+ return javaPlatform, false
+ }
+
+ if !ver.valid() {
+ panic(fmt.Errorf("sdk_version is invalid. got %q", ver.raw))
+ }
+ return javaSdk, false
}
func checkLinkType(ctx android.ModuleContext, from *Module, to linkTypeContext, tag dependencyTag) {
@@ -1739,7 +1744,7 @@
return android.Paths{j.implementationJarFile}
}
-func (j *Module) DexJar() android.Path {
+func (j *Module) DexJarBuildPath() android.Path {
return j.dexJarFile
}
@@ -2565,7 +2570,7 @@
return android.Paths{j.combinedClasspathFile}
}
-func (j *Import) DexJar() android.Path {
+func (j *Import) DexJarBuildPath() android.Path {
return nil
}
@@ -2691,6 +2696,10 @@
return proptools.StringDefault(j.properties.Stem, j.ModuleBase.Name())
}
+func (a *DexImport) JacocoReportClassesFile() android.Path {
+ return nil
+}
+
func (j *DexImport) IsInstallable() bool {
return true
}
@@ -2748,7 +2757,7 @@
j.Stem()+".jar", dexOutputFile)
}
-func (j *DexImport) DexJar() android.Path {
+func (j *DexImport) DexJarBuildPath() android.Path {
return j.dexJarFile
}
diff --git a/java/sdk.go b/java/sdk.go
index 9310f78..2a08f32 100644
--- a/java/sdk.go
+++ b/java/sdk.go
@@ -35,6 +35,7 @@
var sdkVersionsKey = android.NewOnceKey("sdkVersionsKey")
var sdkFrameworkAidlPathKey = android.NewOnceKey("sdkFrameworkAidlPathKey")
+var nonUpdatableFrameworkAidlPathKey = android.NewOnceKey("nonUpdatableFrameworkAidlPathKey")
var apiFingerprintPathKey = android.NewOnceKey("apiFingerprintPathKey")
type sdkContext interface {
@@ -447,7 +448,7 @@
return toModule([]string{"core.current.stubs"}, "", nil)
case sdkModule:
// TODO(146757305): provide .apk and .aidl that have more APIs for modules
- return toModule([]string{"android_module_lib_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
+ return toModule([]string{"android_module_lib_stubs_current"}, "framework-res", nonUpdatableFrameworkAidlPath(ctx))
case sdkSystemServer:
// TODO(146757305): provide .apk and .aidl that have more APIs for modules
return toModule([]string{"android_system_server_stubs_current"}, "framework-res", sdkFrameworkAidlPath(ctx))
@@ -506,6 +507,7 @@
}
createSdkFrameworkAidl(ctx)
+ createNonUpdatableFrameworkAidl(ctx)
createAPIFingerprint(ctx)
}
@@ -517,6 +519,31 @@
"android_system_stubs_current",
}
+ combinedAidl := sdkFrameworkAidlPath(ctx)
+ tempPath := combinedAidl.ReplaceExtension(ctx, "aidl.tmp")
+
+ rule := createFrameworkAidl(stubsModules, tempPath, ctx)
+
+ commitChangeForRestat(rule, tempPath, combinedAidl)
+
+ rule.Build(pctx, ctx, "framework_aidl", "generate framework.aidl")
+}
+
+// Creates a version of framework.aidl for the non-updatable part of the platform.
+func createNonUpdatableFrameworkAidl(ctx android.SingletonContext) {
+ stubsModules := []string{"android_module_lib_stubs_current"}
+
+ combinedAidl := nonUpdatableFrameworkAidlPath(ctx)
+ tempPath := combinedAidl.ReplaceExtension(ctx, "aidl.tmp")
+
+ rule := createFrameworkAidl(stubsModules, tempPath, ctx)
+
+ commitChangeForRestat(rule, tempPath, combinedAidl)
+
+ rule.Build(pctx, ctx, "framework_non_updatable_aidl", "generate framework_non_updatable.aidl")
+}
+
+func createFrameworkAidl(stubsModules []string, path android.OutputPath, ctx android.SingletonContext) *android.RuleBuilder {
stubsJars := make([]android.Paths, len(stubsModules))
ctx.VisitAllModules(func(module android.Module) {
@@ -536,8 +563,7 @@
if ctx.Config().AllowMissingDependencies() {
missingDeps = append(missingDeps, stubsModules[i])
} else {
- ctx.Errorf("failed to find dex jar path for module %q",
- stubsModules[i])
+ ctx.Errorf("failed to find dex jar path for module %q", stubsModules[i])
}
}
}
@@ -561,20 +587,15 @@
}
}
- combinedAidl := sdkFrameworkAidlPath(ctx)
- tempPath := combinedAidl.ReplaceExtension(ctx, "aidl.tmp")
-
rule.Command().
- Text("rm -f").Output(tempPath)
+ Text("rm -f").Output(path)
rule.Command().
Text("cat").
Inputs(aidls).
Text("| sort -u >").
- Output(tempPath)
+ Output(path)
- commitChangeForRestat(rule, tempPath, combinedAidl)
-
- rule.Build(pctx, ctx, "framework_aidl", "generate framework.aidl")
+ return rule
}
func sdkFrameworkAidlPath(ctx android.PathContext) android.OutputPath {
@@ -583,6 +604,12 @@
}).(android.OutputPath)
}
+func nonUpdatableFrameworkAidlPath(ctx android.PathContext) android.OutputPath {
+ return ctx.Config().Once(nonUpdatableFrameworkAidlPathKey, func() interface{} {
+ return android.PathForOutput(ctx, "framework_non_updatable.aidl")
+ }).(android.OutputPath)
+}
+
// Create api_fingerprint.txt
func createAPIFingerprint(ctx android.SingletonContext) {
out := ApiFingerprintPath(ctx)
diff --git a/java/sdk_library.go b/java/sdk_library.go
index c4d257f..de5ee03 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1113,7 +1113,9 @@
props.Product_variables.Pdk.Enabled = proptools.BoolPtr(false)
props.Openjdk9.Srcs = module.properties.Openjdk9.Srcs
props.Openjdk9.Javacflags = module.properties.Openjdk9.Javacflags
- props.Java_version = module.properties.Java_version
+ // We compile the stubs for 1.8 in line with the main android.jar stubs, and potential
+ // interop with older developer tools that don't support 1.9.
+ props.Java_version = proptools.StringPtr("1.8")
if module.deviceProperties.Compile_dex != nil {
props.Compile_dex = module.deviceProperties.Compile_dex
}
@@ -1575,6 +1577,24 @@
var _ sdkLibraryComponentNamingScheme = (*frameworkModulesNamingScheme)(nil)
+func moduleStubLinkType(name string) (stub bool, ret linkType) {
+ // This suffix-based approach is fragile and could potentially mis-trigger.
+ // TODO(b/155164730): Clean this up when modules no longer reference sdk_lib stubs directly.
+ if strings.HasSuffix(name, ".stubs.public") || strings.HasSuffix(name, "-stubs-publicapi") {
+ return true, javaSdk
+ }
+ if strings.HasSuffix(name, ".stubs.system") || strings.HasSuffix(name, "-stubs-systemapi") {
+ return true, javaSystem
+ }
+ if strings.HasSuffix(name, ".stubs.module_lib") || strings.HasSuffix(name, "-stubs-module_libs_api") {
+ return true, javaModule
+ }
+ if strings.HasSuffix(name, ".stubs.test") {
+ return true, javaSystem
+ }
+ return false, javaPlatform
+}
+
// java_sdk_library is a special Java library that provides optional platform APIs to apps.
// In practice, it can be viewed as a combination of several modules: 1) stubs library that clients
// are linked against to, 2) droiddoc module that internally generates API stubs source files,
@@ -2083,7 +2103,7 @@
if properties.RemovedApiFile != nil {
removedApiSnapshotPath := filepath.Join(scopeDir, ctx.Name()+"-removed.txt")
- ctx.SnapshotBuilder().CopyToSnapshot(properties.CurrentApiFile, removedApiSnapshotPath)
+ ctx.SnapshotBuilder().CopyToSnapshot(properties.RemovedApiFile, removedApiSnapshotPath)
scopeSet.AddProperty("removed_api", removedApiSnapshotPath)
}
diff --git a/java/sdk_test.go b/java/sdk_test.go
index fb86463..52d2df5 100644
--- a/java/sdk_test.go
+++ b/java/sdk_test.go
@@ -252,7 +252,7 @@
bootclasspath: []string{"android_module_lib_stubs_current", "core-lambda-stubs"},
system: "core-current-stubs-system-modules",
java9classpath: []string{"android_module_lib_stubs_current"},
- aidl: "-p" + buildDir + "/framework.aidl",
+ aidl: "-p" + buildDir + "/framework_non_updatable.aidl",
},
{
name: "system_server_current",
diff --git a/phony/Android.bp b/phony/Android.bp
new file mode 100644
index 0000000..2c423ef
--- /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 0000000..ffd03fe
--- /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 0000000..fc2c0e3
--- /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/rust/Android.bp b/rust/Android.bp
new file mode 100644
index 0000000..684db0b
--- /dev/null
+++ b/rust/Android.bp
@@ -0,0 +1,32 @@
+bootstrap_go_package {
+ name: "soong-rust",
+ pkgPath: "android/soong/rust",
+ deps: [
+ "soong",
+ "soong-android",
+ "soong-cc",
+ "soong-rust-config",
+ ],
+ srcs: [
+ "androidmk.go",
+ "compiler.go",
+ "coverage.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",
+ "coverage_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 0000000..1a10312
--- /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/sdk/Android.bp b/sdk/Android.bp
new file mode 100644
index 0000000..cb93351
--- /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 f8e9fc1..af792f2 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -1063,13 +1063,13 @@
checkAllCopyRules(`
.intermediates/myjavalib.stubs/android_common/javac/myjavalib.stubs.jar -> sdk_library/public/myjavalib-stubs.jar
.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib.txt
-.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib-removed.txt
+.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_removed.txt -> sdk_library/public/myjavalib-removed.txt
.intermediates/myjavalib.stubs.system/android_common/javac/myjavalib.stubs.system.jar -> sdk_library/system/myjavalib-stubs.jar
.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_api.txt -> sdk_library/system/myjavalib.txt
-.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_api.txt -> sdk_library/system/myjavalib-removed.txt
+.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_removed.txt -> sdk_library/system/myjavalib-removed.txt
.intermediates/myjavalib.stubs.test/android_common/javac/myjavalib.stubs.test.jar -> sdk_library/test/myjavalib-stubs.jar
.intermediates/myjavalib.stubs.source.test/android_common/myjavalib.stubs.source.test_api.txt -> sdk_library/test/myjavalib.txt
-.intermediates/myjavalib.stubs.source.test/android_common/myjavalib.stubs.source.test_api.txt -> sdk_library/test/myjavalib-removed.txt
+.intermediates/myjavalib.stubs.source.test/android_common/myjavalib.stubs.source.test_removed.txt -> sdk_library/test/myjavalib-removed.txt
`),
checkMergeZips(
".intermediates/mysdk/common_os/tmp/sdk_library/public/myjavalib_stub_sources.zip",
@@ -1131,7 +1131,7 @@
checkAllCopyRules(`
.intermediates/myjavalib.stubs/android_common/javac/myjavalib.stubs.jar -> sdk_library/public/myjavalib-stubs.jar
.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib.txt
-.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib-removed.txt
+.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_removed.txt -> sdk_library/public/myjavalib-removed.txt
`),
checkMergeZips(
".intermediates/mysdk/common_os/tmp/sdk_library/public/myjavalib_stub_sources.zip",
@@ -1195,7 +1195,7 @@
checkAllCopyRules(`
.intermediates/myjavalib.stubs/android_common/javac/myjavalib.stubs.jar -> sdk_library/public/myjavalib-stubs.jar
.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib.txt
-.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib-removed.txt
+.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_removed.txt -> sdk_library/public/myjavalib-removed.txt
`),
checkMergeZips(
".intermediates/mysdk/common_os/tmp/sdk_library/public/myjavalib_stub_sources.zip",
@@ -1278,10 +1278,10 @@
checkAllCopyRules(`
.intermediates/myjavalib.stubs/android_common/javac/myjavalib.stubs.jar -> sdk_library/public/myjavalib-stubs.jar
.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib.txt
-.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib-removed.txt
+.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_removed.txt -> sdk_library/public/myjavalib-removed.txt
.intermediates/myjavalib.stubs.system/android_common/javac/myjavalib.stubs.system.jar -> sdk_library/system/myjavalib-stubs.jar
.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_api.txt -> sdk_library/system/myjavalib.txt
-.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_api.txt -> sdk_library/system/myjavalib-removed.txt
+.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_removed.txt -> sdk_library/system/myjavalib-removed.txt
`),
checkMergeZips(
".intermediates/mysdk/common_os/tmp/sdk_library/public/myjavalib_stub_sources.zip",
@@ -1382,13 +1382,13 @@
checkAllCopyRules(`
.intermediates/myjavalib.stubs/android_common/javac/myjavalib.stubs.jar -> sdk_library/public/myjavalib-stubs.jar
.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib.txt
-.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_api.txt -> sdk_library/public/myjavalib-removed.txt
+.intermediates/myjavalib.stubs.source/android_common/myjavalib.stubs.source_removed.txt -> sdk_library/public/myjavalib-removed.txt
.intermediates/myjavalib.stubs.system/android_common/javac/myjavalib.stubs.system.jar -> sdk_library/system/myjavalib-stubs.jar
.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_api.txt -> sdk_library/system/myjavalib.txt
-.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_api.txt -> sdk_library/system/myjavalib-removed.txt
+.intermediates/myjavalib.stubs.source.system/android_common/myjavalib.stubs.source.system_removed.txt -> sdk_library/system/myjavalib-removed.txt
.intermediates/myjavalib.stubs.module_lib/android_common/javac/myjavalib.stubs.module_lib.jar -> sdk_library/module-lib/myjavalib-stubs.jar
.intermediates/myjavalib.api.module_lib/android_common/myjavalib.api.module_lib_api.txt -> sdk_library/module-lib/myjavalib.txt
-.intermediates/myjavalib.api.module_lib/android_common/myjavalib.api.module_lib_api.txt -> sdk_library/module-lib/myjavalib-removed.txt
+.intermediates/myjavalib.api.module_lib/android_common/myjavalib.api.module_lib_removed.txt -> sdk_library/module-lib/myjavalib-removed.txt
`),
checkMergeZips(
".intermediates/mysdk/common_os/tmp/sdk_library/public/myjavalib_stub_sources.zip",
@@ -1459,7 +1459,7 @@
checkAllCopyRules(`
.intermediates/myjavalib-stubs-publicapi/android_common/javac/myjavalib-stubs-publicapi.jar -> sdk_library/public/myjavalib-stubs.jar
.intermediates/myjavalib-stubs-srcs-publicapi/android_common/myjavalib-stubs-srcs-publicapi_api.txt -> sdk_library/public/myjavalib.txt
-.intermediates/myjavalib-stubs-srcs-publicapi/android_common/myjavalib-stubs-srcs-publicapi_api.txt -> sdk_library/public/myjavalib-removed.txt
+.intermediates/myjavalib-stubs-srcs-publicapi/android_common/myjavalib-stubs-srcs-publicapi_removed.txt -> sdk_library/public/myjavalib-removed.txt
`),
checkMergeZips(
".intermediates/mysdk/common_os/tmp/sdk_library/public/myjavalib_stub_sources.zip",
diff --git a/sh/Android.bp b/sh/Android.bp
new file mode 100644
index 0000000..0f40c5f
--- /dev/null
+++ b/sh/Android.bp
@@ -0,0 +1,17 @@
+bootstrap_go_package {
+ name: "soong-sh",
+ pkgPath: "android/soong/sh",
+ deps: [
+ "blueprint",
+ "soong",
+ "soong-android",
+ "soong-tradefed",
+ ],
+ srcs: [
+ "sh_binary.go",
+ ],
+ testSrcs: [
+ "sh_binary_test.go",
+ ],
+ pluginFor: ["soong_build"],
+}
diff --git a/sh/sh_binary.go b/sh/sh_binary.go
new file mode 100644
index 0000000..9276a62
--- /dev/null
+++ b/sh/sh_binary.go
@@ -0,0 +1,300 @@
+// Copyright 2019 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package sh
+
+import (
+ "fmt"
+ "path/filepath"
+ "strings"
+
+ "github.com/google/blueprint/proptools"
+
+ "android/soong/android"
+ "android/soong/tradefed"
+)
+
+// sh_binary is for shell scripts (and batch files) that are installed as
+// executable files into .../bin/
+//
+// Do not use them for prebuilt C/C++/etc files. Use cc_prebuilt_binary
+// instead.
+
+var pctx = android.NewPackageContext("android/soong/sh")
+
+func init() {
+ 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 {
+ // Source file of this prebuilt.
+ Src *string `android:"path,arch_variant"`
+
+ // optional subdirectory under which this file is installed into
+ Sub_dir *string `android:"arch_variant"`
+
+ // optional name for the installed file. If unspecified, name of the module is used as the file name
+ Filename *string `android:"arch_variant"`
+
+ // when set to true, and filename property is not set, the name for the installed file
+ // is the same as the file name of the source file.
+ Filename_from_src *bool `android:"arch_variant"`
+
+ // Whether this module is directly installable to one of the partitions. Default: true.
+ Installable *bool
+
+ // install symlinks to the binary
+ Symlinks []string `android:"arch_variant"`
+}
+
+type TestProperties struct {
+ // list of compatibility suites (for example "cts", "vts") that the module should be
+ // installed into.
+ Test_suites []string `android:"arch_variant"`
+
+ // the name of the test configuration (for example "AndroidTest.xml") that should be
+ // installed with the module.
+ Test_config *string `android:"arch_variant"`
+
+ // list of files or filegroup modules that provide data that should be installed alongside
+ // the test.
+ Data []string `android:"path,arch_variant"`
+
+ // Add RootTargetPreparer to auto generated test config. This guarantees the test to run
+ // with root permission.
+ Require_root *bool
+
+ // the name of the test configuration template (for example "AndroidTestTemplate.xml") that
+ // should be installed with the module.
+ Test_config_template *string `android:"path,arch_variant"`
+
+ // Flag to indicate whether or not to create test config automatically. If AndroidTest.xml
+ // doesn't exist next to the Android.bp, this attribute doesn't need to be set to true
+ // explicitly.
+ Auto_gen_config *bool
+}
+
+type ShBinary struct {
+ android.ModuleBase
+
+ properties shBinaryProperties
+
+ sourceFilePath android.Path
+ outputFilePath android.OutputPath
+ installedFile android.InstallPath
+}
+
+var _ android.HostToolProvider = (*ShBinary)(nil)
+
+type ShTest struct {
+ ShBinary
+
+ testProperties TestProperties
+
+ data android.Paths
+ testConfig android.Path
+}
+
+func (s *ShBinary) HostToolPath() android.OptionalPath {
+ return android.OptionalPathForPath(s.installedFile)
+}
+
+func (s *ShBinary) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if s.properties.Src == nil {
+ ctx.PropertyErrorf("src", "missing prebuilt source file")
+ }
+}
+
+func (s *ShBinary) OutputFile() android.OutputPath {
+ return s.outputFilePath
+}
+
+func (s *ShBinary) SubDir() string {
+ return proptools.String(s.properties.Sub_dir)
+}
+
+func (s *ShBinary) Installable() bool {
+ return s.properties.Installable == nil || proptools.Bool(s.properties.Installable)
+}
+
+func (s *ShBinary) Symlinks() []string {
+ return s.properties.Symlinks
+}
+
+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()
+ } else {
+ filename = ctx.ModuleName()
+ }
+ } else if filename_from_src {
+ ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
+ return
+ }
+ 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, android.BuildParams{
+ Rule: android.CpExecutable,
+ Output: s.outputFilePath,
+ Input: s.sourceFilePath,
+ })
+}
+
+func (s *ShBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
+ s.generateAndroidBuildActions(ctx)
+ 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() []android.AndroidMkEntries {
+ return []android.AndroidMkEntries{android.AndroidMkEntries{
+ Class: "EXECUTABLES",
+ OutputFile: android.OptionalPathForPath(s.outputFilePath),
+ Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
+ ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+ func(entries *android.AndroidMkEntries) {
+ s.customAndroidMkEntries(entries)
+ },
+ },
+ }}
+}
+
+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 {
+ entries.SetString("LOCAL_MODULE_SYMLINKS", strings.Join(s.properties.Symlinks, " "))
+ }
+}
+
+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 == 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 := android.PathForModuleInstall(ctx, testDir, proptools.String(s.properties.Sub_dir))
+ s.installedFile = ctx.InstallExecutable(installDir, s.outputFilePath.Base(), s.outputFilePath)
+
+ s.data = android.PathsForModuleSrc(ctx, s.testProperties.Data)
+
+ var configs []tradefed.Config
+ if Bool(s.testProperties.Require_root) {
+ configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", nil})
+ } else {
+ options := []tradefed.Option{{Name: "force-root", Value: "false"}}
+ configs = append(configs, tradefed.Object{"target_preparer", "com.android.tradefed.targetprep.RootTargetPreparer", options})
+ }
+ s.testConfig = tradefed.AutoGenShellTestConfig(ctx, s.testProperties.Test_config,
+ s.testProperties.Test_config_template, s.testProperties.Test_suites, configs, s.testProperties.Auto_gen_config, s.outputFilePath.Base())
+}
+
+func (s *ShTest) InstallInData() bool {
+ return true
+}
+
+func (s *ShTest) AndroidMkEntries() []android.AndroidMkEntries {
+ return []android.AndroidMkEntries{android.AndroidMkEntries{
+ Class: "NATIVE_TESTS",
+ OutputFile: android.OptionalPathForPath(s.outputFilePath),
+ Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
+ ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+ func(entries *android.AndroidMkEntries) {
+ s.customAndroidMkEntries(entries)
+
+ entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", s.testProperties.Test_suites...)
+ if s.testProperties.Test_config != nil {
+ entries.SetString("LOCAL_TEST_CONFIG", proptools.String(s.testProperties.Test_config))
+ } else {
+ if s.testConfig != nil {
+ entries.SetString("LOCAL_FULL_TEST_CONFIG", s.testConfig.String())
+ }
+ }
+ for _, d := range s.data {
+ rel := d.Rel()
+ path := d.String()
+ if !strings.HasSuffix(path, rel) {
+ panic(fmt.Errorf("path %q does not end with %q", path, rel))
+ }
+ path = strings.TrimSuffix(path, rel)
+ entries.AddStrings("LOCAL_TEST_DATA", path+":"+rel)
+ }
+ },
+ },
+ }}
+}
+
+func InitShBinaryModule(s *ShBinary) {
+ s.AddProperties(&s.properties)
+}
+
+// sh_binary is for a shell script or batch file to be installed as an
+// executable binary to <partition>/bin.
+func ShBinaryFactory() android.Module {
+ module := &ShBinary{}
+ module.Prefer32(func(ctx android.BaseModuleContext, base *android.ModuleBase, class android.OsClass) bool {
+ return class == android.Device && ctx.Config().DevicePrefer32BitExecutables()
+ })
+ InitShBinaryModule(module)
+ 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() android.Module {
+ module := &ShBinary{}
+ InitShBinaryModule(module)
+ android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst)
+ return module
+}
+
+// sh_test defines a shell script based test module.
+func ShTestFactory() android.Module {
+ module := &ShTest{}
+ InitShBinaryModule(&module.ShBinary)
+ module.AddProperties(&module.testProperties)
+
+ 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() android.Module {
+ module := &ShTest{}
+ InitShBinaryModule(&module.ShBinary)
+ module.AddProperties(&module.testProperties)
+
+ android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst)
+ return module
+}
+
+var Bool = proptools.Bool
diff --git a/android/sh_binary_test.go b/sh/sh_binary_test.go
similarity index 64%
rename from android/sh_binary_test.go
rename to sh/sh_binary_test.go
index 137e773..6c0d96a 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 @@
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 @@
}
`)
- 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 0000000..07dfe11
--- /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 0000000..48094f1
--- /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 0000000..6e5e533
--- /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/tradefed/autogen.go b/tradefed/autogen.go
index be44cac..2829146 100644
--- a/tradefed/autogen.go
+++ b/tradefed/autogen.go
@@ -40,9 +40,9 @@
}
var autogenTestConfig = pctx.StaticRule("autogenTestConfig", blueprint.RuleParams{
- Command: "sed 's&{MODULE}&${name}&g;s&{EXTRA_CONFIGS}&'${extraConfigs}'&g' $template > $out",
+ Command: "sed 's&{MODULE}&${name}&g;s&{EXTRA_CONFIGS}&'${extraConfigs}'&g;s&{OUTPUT_FILENAME}&'${outputFileName}'&g' $template > $out",
CommandDeps: []string{"$template"},
-}, "name", "template", "extraConfigs")
+}, "name", "template", "extraConfigs", "outputFileName")
func testConfigPath(ctx android.ModuleContext, prop *string, testSuites []string, autoGenConfig *bool, testConfigTemplateProp *string) (path android.Path, autogenPath android.WritablePath) {
p := getTestConfig(ctx, prop)
@@ -108,10 +108,14 @@
}
func autogenTemplate(ctx android.ModuleContext, output android.WritablePath, template string, configs []Config) {
- autogenTemplateWithName(ctx, ctx.ModuleName(), output, template, configs)
+ autogenTemplateWithNameAndOutputFile(ctx, ctx.ModuleName(), output, template, configs, "")
}
func autogenTemplateWithName(ctx android.ModuleContext, name string, output android.WritablePath, template string, configs []Config) {
+ autogenTemplateWithNameAndOutputFile(ctx, ctx.ModuleName(), output, template, configs, "")
+}
+
+func autogenTemplateWithNameAndOutputFile(ctx android.ModuleContext, name string, output android.WritablePath, template string, configs []Config, outputFileName string) {
var configStrings []string
for _, config := range configs {
configStrings = append(configStrings, config.Config())
@@ -124,9 +128,10 @@
Description: "test config",
Output: output,
Args: map[string]string{
- "name": name,
- "template": template,
- "extraConfigs": extraConfigs,
+ "name": name,
+ "template": template,
+ "extraConfigs": extraConfigs,
+ "outputFileName": outputFileName,
},
})
}
@@ -150,6 +155,21 @@
return path
}
+func AutoGenShellTestConfig(ctx android.ModuleContext, testConfigProp *string,
+ testConfigTemplateProp *string, testSuites []string, config []Config, autoGenConfig *bool, outputFileName string) android.Path {
+ path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
+ if autogenPath != nil {
+ templatePath := getTestConfigTemplate(ctx, testConfigTemplateProp)
+ if templatePath.Valid() {
+ autogenTemplateWithNameAndOutputFile(ctx, ctx.ModuleName(), autogenPath, templatePath.String(), config, outputFileName)
+ } else {
+ autogenTemplateWithNameAndOutputFile(ctx, ctx.ModuleName(), autogenPath, "${ShellTestConfigTemplate}", config, outputFileName)
+ }
+ return autogenPath
+ }
+ return path
+}
+
func AutoGenNativeBenchmarkTestConfig(ctx android.ModuleContext, testConfigProp *string,
testConfigTemplateProp *string, testSuites []string, configs []Config, autoGenConfig *bool) android.Path {
path, autogenPath := testConfigPath(ctx, testConfigProp, testSuites, autoGenConfig, testConfigTemplateProp)
diff --git a/tradefed/config.go b/tradefed/config.go
index a289073..34195c3 100644
--- a/tradefed/config.go
+++ b/tradefed/config.go
@@ -33,6 +33,7 @@
pctx.SourcePathVariable("PythonBinaryHostTestConfigTemplate", "build/make/core/python_binary_host_test_config_template.xml")
pctx.SourcePathVariable("RustDeviceTestConfigTemplate", "build/make/core/rust_device_test_config_template.xml")
pctx.SourcePathVariable("RustHostTestConfigTemplate", "build/make/core/rust_host_test_config_template.xml")
+ pctx.SourcePathVariable("ShellTestConfigTemplate", "build/make/core/shell_test_config_template.xml")
pctx.SourcePathVariable("EmptyTestConfig", "build/make/core/empty_test_config.xml")
}
diff --git a/tradefed/makevars.go b/tradefed/makevars.go
index d4cf7a8..f9682e4 100644
--- a/tradefed/makevars.go
+++ b/tradefed/makevars.go
@@ -33,6 +33,7 @@
ctx.Strict("PYTHON_BINARY_HOST_TEST_CONFIG_TEMPLATE", "${PythonBinaryHostTestConfigTemplate}")
ctx.Strict("RUST_DEVICE_TEST_CONFIG_TEMPLATE", "${RustDeviceTestConfigTemplate}")
ctx.Strict("RUST_HOST_TEST_CONFIG_TEMPLATE", "${RustHostTestConfigTemplate}")
+ ctx.Strict("SHELL_TEST_CONFIG_TEMPLATE", "${ShellTestConfigTemplate}")
ctx.Strict("EMPTY_TEST_CONFIG", "${EmptyTestConfig}")
}
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index a559330..7dc4915 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -54,18 +54,16 @@
var ret map[string]string
if len(makeVars) > 0 {
+ // It's not safe to use the same TMPDIR as the build, as that can be removed.
tmpDir, err := ioutil.TempDir("", "dumpvars")
if err != nil {
return nil, err
}
defer os.RemoveAll(tmpDir)
- // It's not safe to use the same TMPDIR as the build, as that can be removed.
- config.Environment().Set("TMPDIR", tmpDir)
+ SetupLitePath(ctx, config, tmpDir)
- SetupLitePath(ctx, config)
-
- ret, err = dumpMakeVars(ctx, config, goals, makeVars, false)
+ ret, err = dumpMakeVars(ctx, config, goals, makeVars, false, tmpDir)
if err != nil {
return ret, err
}
@@ -82,7 +80,7 @@
return ret, nil
}
-func dumpMakeVars(ctx Context, config Config, goals, vars []string, write_soong_vars bool) (map[string]string, error) {
+func dumpMakeVars(ctx Context, config Config, goals, vars []string, write_soong_vars bool, tmpDir string) (map[string]string, error) {
ctx.BeginTrace(metrics.RunKati, "dumpvars")
defer ctx.EndTrace()
@@ -98,6 +96,9 @@
cmd.Environment.Set("WRITE_SOONG_VARIABLES", "true")
}
cmd.Environment.Set("DUMP_MANY_VARS", strings.Join(vars, " "))
+ if tmpDir != "" {
+ cmd.Environment.Set("TMPDIR", tmpDir)
+ }
cmd.Sandbox = dumpvarsSandbox
output := bytes.Buffer{}
cmd.Stdout = &output
@@ -253,7 +254,7 @@
"BUILD_BROKEN_USES_BUILD_STATIC_LIBRARY",
}, exportEnvVars...), BannerVars...)
- make_vars, err := dumpMakeVars(ctx, config, config.Arguments(), allVars, true)
+ make_vars, err := dumpMakeVars(ctx, config, config.Arguments(), allVars, true, "")
if err != nil {
ctx.Fatalln("Error dumping make vars:", err)
}
diff --git a/ui/build/path.go b/ui/build/path.go
index 7122927..6f5cf78 100644
--- a/ui/build/path.go
+++ b/ui/build/path.go
@@ -55,8 +55,9 @@
}
// A "lite" version of SetupPath used for dumpvars, or other places that need
-// minimal overhead (but at the expense of logging).
-func SetupLitePath(ctx Context, config Config) {
+// minimal overhead (but at the expense of logging). If tmpDir is empty, the
+// default TMPDIR is used from config.
+func SetupLitePath(ctx Context, config Config, tmpDir string) {
if config.pathReplaced {
return
}
@@ -65,8 +66,11 @@
defer ctx.EndTrace()
origPath, _ := config.Environment().Get("PATH")
- myPath, _ := config.Environment().Get("TMPDIR")
- myPath = filepath.Join(myPath, "path")
+
+ if tmpDir == "" {
+ tmpDir, _ = config.Environment().Get("TMPDIR")
+ }
+ myPath := filepath.Join(tmpDir, "path")
ensureEmptyDirectoriesExist(ctx, myPath)
os.Setenv("PATH", origPath)
diff --git a/xml/Android.bp b/xml/Android.bp
new file mode 100644
index 0000000..cd25cff
--- /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 3a680ec..8810ae4 100644
--- a/xml/xml.go
+++ b/xml/xml.go
@@ -16,6 +16,7 @@
import (
"android/soong/android"
+ "android/soong/etc"
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
@@ -62,7 +63,7 @@
}
type prebuiltEtcXml struct {
- android.PrebuiltEtc
+ etc.PrebuiltEtc
properties prebuiltEtcXmlProperties
}
@@ -121,7 +122,7 @@
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 f8ec823..abcb108 100644
--- a/xml/xml_test.go
+++ b/xml/xml_test.go
@@ -20,6 +20,7 @@
"testing"
"android/soong/android"
+ "android/soong/etc"
)
var buildDir string
@@ -57,7 +58,7 @@
}
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"})