Merge "Add some app modules to the allowed whitelist."
diff --git a/Android.bp b/Android.bp
index ec7d13a..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,545 +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-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/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/module.go b/android/module.go
index 6239d27..82321f4 100644
--- a/android/module.go
+++ b/android/module.go
@@ -111,6 +111,8 @@
OtherModuleErrorf(m blueprint.Module, fmt string, args ...interface{})
OtherModuleDependencyTag(m blueprint.Module) blueprint.DependencyTag
OtherModuleExists(name string) bool
+ OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool
+ OtherModuleReverseDependencyVariantExists(name string) bool
OtherModuleType(m blueprint.Module) string
GetDirectDepsWithTag(tag blueprint.DependencyTag) []Module
@@ -1433,6 +1435,12 @@
return b.bp.OtherModuleDependencyTag(m)
}
func (b *baseModuleContext) OtherModuleExists(name string) bool { return b.bp.OtherModuleExists(name) }
+func (b *baseModuleContext) OtherModuleDependencyVariantExists(variations []blueprint.Variation, name string) bool {
+ return b.bp.OtherModuleDependencyVariantExists(variations, name)
+}
+func (b *baseModuleContext) OtherModuleReverseDependencyVariantExists(name string) bool {
+ return b.bp.OtherModuleReverseDependencyVariantExists(name)
+}
func (b *baseModuleContext) OtherModuleType(m blueprint.Module) string {
return b.bp.OtherModuleType(m)
}
diff --git a/android/neverallow.go b/android/neverallow.go
index 63946a7..be3f712 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -55,6 +55,7 @@
AddNeverAllowRules(createMediaRules()...)
AddNeverAllowRules(createJavaDeviceForHostRules()...)
AddNeverAllowRules(createCcSdkVariantRules()...)
+ AddNeverAllowRules(createUncompressDexRules()...)
}
// Add a NeverAllow rule to the set of rules to apply.
@@ -214,6 +215,15 @@
}
}
+func createUncompressDexRules() []Rule {
+ return []Rule{
+ NeverAllow().
+ NotIn("art").
+ WithMatcher("uncompress_dex", isSetMatcherInstance).
+ Because("uncompress_dex is only allowed for certain jars for test in art."),
+ }
+}
+
func neverallowMutator(ctx BottomUpMutatorContext) {
m, ok := ctx.Module().(Module)
if !ok {
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index 2fc42e3..85c8c59 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -303,6 +303,29 @@
`module "outside_whitelist": violates neverallow`,
},
},
+ {
+ name: "uncompress_dex inside art",
+ fs: map[string][]byte{
+ "art/Android.bp": []byte(`
+ java_library {
+ name: "inside_art_libraries",
+ uncompress_dex: true,
+ }`),
+ },
+ },
+ {
+ name: "uncompress_dex outside art",
+ fs: map[string][]byte{
+ "other/Android.bp": []byte(`
+ java_library {
+ name: "outside_art_libraries",
+ uncompress_dex: true,
+ }`),
+ },
+ expectedErrors: []string{
+ "module \"outside_art_libraries\": violates neverallow",
+ },
+ },
}
func TestNeverallow(t *testing.T) {
@@ -396,8 +419,9 @@
}
type mockJavaLibraryProperties struct {
- Libs []string
- Sdk_version *string
+ Libs []string
+ Sdk_version *string
+ Uncompress_dex *bool
}
type mockJavaLibraryModule struct {
diff --git a/android/paths.go b/android/paths.go
index fcea65c..3ad27ac 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -485,6 +485,15 @@
return firstUniquePathsList(list)
}
+// SortedUniquePaths returns what its name says
+func SortedUniquePaths(list Paths) Paths {
+ unique := FirstUniquePaths(list)
+ sort.Slice(unique, func(i, j int) bool {
+ return unique[i].String() < unique[j].String()
+ })
+ return unique
+}
+
func firstUniquePathsList(list Paths) Paths {
k := 0
outer:
diff --git a/android/prebuilt.go b/android/prebuilt.go
index ee4a13a..a29ec91 100644
--- a/android/prebuilt.go
+++ b/android/prebuilt.go
@@ -52,6 +52,9 @@
SourceExists bool `blueprint:"mutated"`
UsePrebuilt bool `blueprint:"mutated"`
+
+ // Set if the module has been renamed to remove the "prebuilt_" prefix.
+ PrebuiltRenamedToSource bool `blueprint:"mutated"`
}
type Prebuilt struct {
@@ -188,25 +191,38 @@
}
func RegisterPrebuiltsPreArchMutators(ctx RegisterMutatorsContext) {
- ctx.BottomUp("prebuilts", PrebuiltMutator).Parallel()
+ ctx.BottomUp("prebuilt_rename", PrebuiltRenameMutator).Parallel()
}
func RegisterPrebuiltsPostDepsMutators(ctx RegisterMutatorsContext) {
+ ctx.BottomUp("prebuilt_source", PrebuiltSourceDepsMutator).Parallel()
ctx.TopDown("prebuilt_select", PrebuiltSelectModuleMutator).Parallel()
ctx.BottomUp("prebuilt_postdeps", PrebuiltPostDepsMutator).Parallel()
}
-// PrebuiltMutator ensures that there is always a module with an undecorated name, and marks
-// prebuilt modules that have both a prebuilt and a source module.
-func PrebuiltMutator(ctx BottomUpMutatorContext) {
+// PrebuiltRenameMutator ensures that there always is a module with an
+// undecorated name.
+func PrebuiltRenameMutator(ctx BottomUpMutatorContext) {
+ if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil {
+ name := m.base().BaseModuleName()
+ if !ctx.OtherModuleExists(name) {
+ ctx.Rename(name)
+ m.Prebuilt().properties.PrebuiltRenamedToSource = true
+ }
+ }
+}
+
+// PrebuiltSourceDepsMutator adds dependencies to the prebuilt module from the
+// corresponding source module, if one exists for the same variant.
+func PrebuiltSourceDepsMutator(ctx BottomUpMutatorContext) {
if m, ok := ctx.Module().(PrebuiltInterface); ok && m.Prebuilt() != nil {
p := m.Prebuilt()
- name := m.base().BaseModuleName()
- if ctx.OtherModuleExists(name) {
- ctx.AddReverseDependency(ctx.Module(), PrebuiltDepTag, name)
- p.properties.SourceExists = true
- } else {
- ctx.Rename(name)
+ if !p.properties.PrebuiltRenamedToSource {
+ name := m.base().BaseModuleName()
+ if ctx.OtherModuleReverseDependencyVariantExists(name) {
+ ctx.AddReverseDependency(ctx.Module(), PrebuiltDepTag, name)
+ p.properties.SourceExists = true
+ }
}
}
}
diff --git a/android/prebuilt_etc.go b/android/prebuilt_etc.go
deleted file mode 100644
index 3dea6d8..0000000
--- a/android/prebuilt_etc.go
+++ /dev/null
@@ -1,279 +0,0 @@
-// Copyright 2016 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 "strconv"
-
-// 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)
-}
-
-type prebuiltEtcProperties 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"`
-
- // Make this module available when building for ramdisk.
- Ramdisk_available *bool
-
- // Make this module available when building for recovery.
- Recovery_available *bool
-
- // Whether this module is directly installable to one of the partitions. Default: true.
- Installable *bool
-}
-
-type PrebuiltEtcModule interface {
- Module
- SubDir() string
- OutputFile() OutputPath
-}
-
-type PrebuiltEtc struct {
- ModuleBase
-
- properties prebuiltEtcProperties
-
- sourceFilePath Path
- outputFilePath 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
-}
-
-func (p *PrebuiltEtc) inRamdisk() bool {
- return p.ModuleBase.InRamdisk() || p.ModuleBase.InstallInRamdisk()
-}
-
-func (p *PrebuiltEtc) onlyInRamdisk() bool {
- return p.ModuleBase.InstallInRamdisk()
-}
-
-func (p *PrebuiltEtc) InstallInRamdisk() bool {
- return p.inRamdisk()
-}
-
-func (p *PrebuiltEtc) inRecovery() bool {
- return p.ModuleBase.InRecovery() || p.ModuleBase.InstallInRecovery()
-}
-
-func (p *PrebuiltEtc) onlyInRecovery() bool {
- return p.ModuleBase.InstallInRecovery()
-}
-
-func (p *PrebuiltEtc) InstallInRecovery() bool {
- return p.inRecovery()
-}
-
-var _ ImageInterface = (*PrebuiltEtc)(nil)
-
-func (p *PrebuiltEtc) ImageMutatorBegin(ctx BaseModuleContext) {}
-
-func (p *PrebuiltEtc) CoreVariantNeeded(ctx 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) RecoveryVariantNeeded(ctx BaseModuleContext) bool {
- return Bool(p.properties.Recovery_available) || p.ModuleBase.InstallInRecovery()
-}
-
-func (p *PrebuiltEtc) ExtraImageVariations(ctx BaseModuleContext) []string {
- return nil
-}
-
-func (p *PrebuiltEtc) SetImageVariation(ctx BaseModuleContext, variation string, module Module) {
-}
-
-func (p *PrebuiltEtc) DepsMutator(ctx 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) InstallDirPath() 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) {
- p.additionalDependencies = &paths
-}
-
-func (p *PrebuiltEtc) OutputFile() OutputPath {
- return p.outputFilePath
-}
-
-func (p *PrebuiltEtc) SubDir() string {
- return String(p.properties.Sub_dir)
-}
-
-func (p *PrebuiltEtc) Installable() bool {
- return p.properties.Installable == nil || 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)
- if filename == "" {
- if filename_from_src {
- filename = p.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
- }
- p.outputFilePath = PathForModuleOut(ctx, filename).OutputPath
-
- // If soc install dir was specified and SOC specific is set, set the installDirPath to the specified
- // socInstallDirBase.
- installBaseDir := p.installDirBase
- if ctx.SocSpecific() && p.socInstallDirBase != "" {
- installBaseDir = p.socInstallDirBase
- }
- p.installDirPath = PathForModuleInstall(ctx, installBaseDir, 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,
- Output: p.outputFilePath,
- Input: p.sourceFilePath,
- })
-}
-
-func (p *PrebuiltEtc) AndroidMkEntries() []AndroidMkEntries {
- nameSuffix := ""
- if p.inRamdisk() && !p.onlyInRamdisk() {
- nameSuffix = ".ramdisk"
- }
- if p.inRecovery() && !p.onlyInRecovery() {
- nameSuffix = ".recovery"
- }
- return []AndroidMkEntries{AndroidMkEntries{
- Class: "ETC",
- SubName: nameSuffix,
- OutputFile: OptionalPathForPath(p.outputFilePath),
- ExtraEntries: []AndroidMkExtraEntriesFunc{
- func(entries *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())
- entries.SetString("LOCAL_UNINSTALLABLE_MODULE", strconv.FormatBool(!p.Installable()))
- if p.additionalDependencies != nil {
- for _, path := range *p.additionalDependencies {
- entries.SetString("LOCAL_ADDITIONAL_DEPENDENCIES", path.String())
- }
- }
- },
- },
- }}
-}
-
-func InitPrebuiltEtcModule(p *PrebuiltEtc, dirBase string) {
- p.installDirBase = dirBase
- p.AddProperties(&p.properties)
-}
-
-// prebuilt_etc is for a prebuilt artifact that is installed in
-// <partition>/etc/<sub_dir> directory.
-func PrebuiltEtcFactory() Module {
- module := &PrebuiltEtc{}
- InitPrebuiltEtcModule(module, "etc")
- // This module is device-only
- InitAndroidArchModule(module, DeviceSupported, 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 {
- module := &PrebuiltEtc{}
- InitPrebuiltEtcModule(module, "etc")
- // This module is host-only
- InitAndroidArchModule(module, HostSupported, MultilibCommon)
- return module
-}
-
-// prebuilt_usr_share is for a prebuilt artifact that is installed in
-// <partition>/usr/share/<sub_dir> directory.
-func PrebuiltUserShareFactory() Module {
- module := &PrebuiltEtc{}
- InitPrebuiltEtcModule(module, "usr/share")
- // This module is device-only
- InitAndroidArchModule(module, DeviceSupported, 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 {
- module := &PrebuiltEtc{}
- InitPrebuiltEtcModule(module, "usr/share")
- // This module is host-only
- InitAndroidArchModule(module, HostSupported, MultilibCommon)
- return module
-}
-
-// prebuilt_font installs a font in <partition>/fonts directory.
-func PrebuiltFontFactory() Module {
- module := &PrebuiltEtc{}
- InitPrebuiltEtcModule(module, "fonts")
- // This module is device-only
- InitAndroidArchModule(module, DeviceSupported, 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 {
- module := &PrebuiltEtc{}
- module.socInstallDirBase = "firmware"
- InitPrebuiltEtcModule(module, "etc/firmware")
- // This module is device-only
- InitAndroidArchModule(module, DeviceSupported, MultilibFirst)
- return module
-}
diff --git a/android/prebuilt_test.go b/android/prebuilt_test.go
index 8ff5c40..b568f78 100644
--- a/android/prebuilt_test.go
+++ b/android/prebuilt_test.go
@@ -24,7 +24,7 @@
var prebuiltsTests = []struct {
name string
modules string
- prebuilt bool
+ prebuilt []OsClass
}{
{
name: "no prebuilt",
@@ -32,7 +32,7 @@
source {
name: "bar",
}`,
- prebuilt: false,
+ prebuilt: nil,
},
{
name: "no source prebuilt not preferred",
@@ -42,7 +42,7 @@
prefer: false,
srcs: ["prebuilt_file"],
}`,
- prebuilt: true,
+ prebuilt: []OsClass{Device, Host},
},
{
name: "no source prebuilt preferred",
@@ -52,7 +52,7 @@
prefer: true,
srcs: ["prebuilt_file"],
}`,
- prebuilt: true,
+ prebuilt: []OsClass{Device, Host},
},
{
name: "prebuilt not preferred",
@@ -60,13 +60,13 @@
source {
name: "bar",
}
-
+
prebuilt {
name: "bar",
prefer: false,
srcs: ["prebuilt_file"],
}`,
- prebuilt: false,
+ prebuilt: nil,
},
{
name: "prebuilt preferred",
@@ -74,13 +74,13 @@
source {
name: "bar",
}
-
+
prebuilt {
name: "bar",
prefer: true,
srcs: ["prebuilt_file"],
}`,
- prebuilt: true,
+ prebuilt: []OsClass{Device, Host},
},
{
name: "prebuilt no file not preferred",
@@ -88,12 +88,12 @@
source {
name: "bar",
}
-
+
prebuilt {
name: "bar",
prefer: false,
}`,
- prebuilt: false,
+ prebuilt: nil,
},
{
name: "prebuilt no file preferred",
@@ -101,12 +101,12 @@
source {
name: "bar",
}
-
+
prebuilt {
name: "bar",
prefer: true,
}`,
- prebuilt: false,
+ prebuilt: nil,
},
{
name: "prebuilt file from filegroup preferred",
@@ -120,7 +120,40 @@
prefer: true,
srcs: [":fg"],
}`,
- prebuilt: true,
+ prebuilt: []OsClass{Device, Host},
+ },
+ {
+ name: "prebuilt module for device only",
+ modules: `
+ source {
+ name: "bar",
+ }
+
+ prebuilt {
+ name: "bar",
+ host_supported: false,
+ prefer: true,
+ srcs: ["prebuilt_file"],
+ }`,
+ prebuilt: []OsClass{Device},
+ },
+ {
+ name: "prebuilt file for host only",
+ modules: `
+ source {
+ name: "bar",
+ }
+
+ prebuilt {
+ name: "bar",
+ prefer: true,
+ target: {
+ host: {
+ srcs: ["prebuilt_file"],
+ },
+ },
+ }`,
+ prebuilt: []OsClass{Host},
},
}
@@ -138,9 +171,9 @@
deps: [":bar"],
}
` + test.modules
- config := TestConfig(buildDir, nil, bp, fs)
+ config := TestArchConfig(buildDir, nil, bp, fs)
- ctx := NewTestContext()
+ ctx := NewTestArchContext()
registerTestPrebuiltBuildComponents(ctx)
ctx.RegisterModuleType("filegroup", FileGroupFactory)
ctx.Register(config)
@@ -150,61 +183,71 @@
_, errs = ctx.PrepareBuildActions(config)
FailIfErrored(t, errs)
- foo := ctx.ModuleForTests("foo", "")
+ for _, variant := range ctx.ModuleVariantsForTests("foo") {
+ foo := ctx.ModuleForTests("foo", variant)
+ t.Run(foo.Module().Target().Os.Class.String(), func(t *testing.T) {
+ var dependsOnSourceModule, dependsOnPrebuiltModule bool
+ ctx.VisitDirectDeps(foo.Module(), func(m blueprint.Module) {
+ if _, ok := m.(*sourceModule); ok {
+ dependsOnSourceModule = true
+ }
+ if p, ok := m.(*prebuiltModule); ok {
+ dependsOnPrebuiltModule = true
+ if !p.Prebuilt().properties.UsePrebuilt {
+ t.Errorf("dependency on prebuilt module not marked used")
+ }
+ }
+ })
- var dependsOnSourceModule, dependsOnPrebuiltModule bool
- ctx.VisitDirectDeps(foo.Module(), func(m blueprint.Module) {
- if _, ok := m.(*sourceModule); ok {
- dependsOnSourceModule = true
- }
- if p, ok := m.(*prebuiltModule); ok {
- dependsOnPrebuiltModule = true
- if !p.Prebuilt().properties.UsePrebuilt {
- t.Errorf("dependency on prebuilt module not marked used")
+ deps := foo.Module().(*sourceModule).deps
+ if deps == nil || len(deps) != 1 {
+ t.Errorf("deps does not have single path, but is %v", deps)
}
- }
- })
+ var usingSourceFile, usingPrebuiltFile bool
+ if deps[0].String() == "source_file" {
+ usingSourceFile = true
+ }
+ if deps[0].String() == "prebuilt_file" {
+ usingPrebuiltFile = true
+ }
- deps := foo.Module().(*sourceModule).deps
- if deps == nil || len(deps) != 1 {
- t.Errorf("deps does not have single path, but is %v", deps)
- }
- var usingSourceFile, usingPrebuiltFile bool
- if deps[0].String() == "source_file" {
- usingSourceFile = true
- }
- if deps[0].String() == "prebuilt_file" {
- usingPrebuiltFile = true
- }
+ prebuilt := false
+ for _, os := range test.prebuilt {
+ if os == foo.Module().Target().Os.Class {
+ prebuilt = true
+ }
+ }
- if test.prebuilt {
- if !dependsOnPrebuiltModule {
- t.Errorf("doesn't depend on prebuilt module")
- }
- if !usingPrebuiltFile {
- t.Errorf("doesn't use prebuilt_file")
- }
+ if prebuilt {
+ if !dependsOnPrebuiltModule {
+ t.Errorf("doesn't depend on prebuilt module")
+ }
+ if !usingPrebuiltFile {
+ t.Errorf("doesn't use prebuilt_file")
+ }
- if dependsOnSourceModule {
- t.Errorf("depends on source module")
- }
- if usingSourceFile {
- t.Errorf("using source_file")
- }
- } else {
- if dependsOnPrebuiltModule {
- t.Errorf("depends on prebuilt module")
- }
- if usingPrebuiltFile {
- t.Errorf("using prebuilt_file")
- }
+ if dependsOnSourceModule {
+ t.Errorf("depends on source module")
+ }
+ if usingSourceFile {
+ t.Errorf("using source_file")
+ }
+ } else {
+ if dependsOnPrebuiltModule {
+ t.Errorf("depends on prebuilt module")
+ }
+ if usingPrebuiltFile {
+ t.Errorf("using prebuilt_file")
+ }
- if !dependsOnSourceModule {
- t.Errorf("doesn't depend on source module")
- }
- if !usingSourceFile {
- t.Errorf("doesn't use source_file")
- }
+ if !dependsOnSourceModule {
+ t.Errorf("doesn't depend on source module")
+ }
+ if !usingSourceFile {
+ t.Errorf("doesn't use source_file")
+ }
+ }
+ })
}
})
}
@@ -221,7 +264,7 @@
ModuleBase
prebuilt Prebuilt
properties struct {
- Srcs []string `android:"path"`
+ Srcs []string `android:"path,arch_variant"`
}
src Path
}
@@ -230,7 +273,7 @@
m := &prebuiltModule{}
m.AddProperties(&m.properties)
InitPrebuiltModule(m, &m.properties.Srcs)
- InitAndroidModule(m)
+ InitAndroidArchModule(m, HostAndDeviceDefault, MultilibCommon)
return m
}
@@ -260,7 +303,7 @@
type sourceModule struct {
ModuleBase
properties struct {
- Deps []string `android:"path"`
+ Deps []string `android:"path,arch_variant"`
}
dependsOnSourceModule, dependsOnPrebuiltModule bool
deps Paths
@@ -270,7 +313,7 @@
func newSourceModule() Module {
m := &sourceModule{}
m.AddProperties(&m.properties)
- InitAndroidModule(m)
+ InitAndroidArchModule(m, HostAndDeviceDefault, MultilibCommon)
return m
}
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/android/testing.go b/android/testing.go
index 90989ef..696efb6 100644
--- a/android/testing.go
+++ b/android/testing.go
@@ -18,6 +18,7 @@
"fmt"
"path/filepath"
"regexp"
+ "sort"
"strings"
"testing"
@@ -122,9 +123,10 @@
ctx.VisitAllModules(func(m blueprint.Module) {
allModuleNames = append(allModuleNames, m.(Module).Name()+"("+ctx.ModuleSubDir(m)+")")
})
+ sort.Strings(allModuleNames)
- panic(fmt.Errorf("failed to find module %q variant %q."+
- "\nall modules: %v", name, variant, allModuleNames))
+ panic(fmt.Errorf("failed to find module %q variant %q. All modules:\n %s",
+ name, variant, strings.Join(allModuleNames, "\n ")))
}
return TestingModule{module}
diff --git a/androidmk/androidmk/android.go b/androidmk/androidmk/android.go
index 5a62324..eaf06c5 100644
--- a/androidmk/androidmk/android.go
+++ b/androidmk/androidmk/android.go
@@ -40,26 +40,31 @@
append bool
}
+var trueValue = &bpparser.Bool{
+ Value: true,
+}
+
var rewriteProperties = map[string](func(variableAssignmentContext) error){
// custom functions
- "LOCAL_32_BIT_ONLY": local32BitOnly,
- "LOCAL_AIDL_INCLUDES": localAidlIncludes,
- "LOCAL_ASSET_DIR": localizePathList("asset_dirs"),
- "LOCAL_C_INCLUDES": localIncludeDirs,
- "LOCAL_EXPORT_C_INCLUDE_DIRS": exportIncludeDirs,
- "LOCAL_JARJAR_RULES": localizePath("jarjar_rules"),
- "LOCAL_LDFLAGS": ldflags,
- "LOCAL_MODULE_CLASS": prebuiltClass,
- "LOCAL_MODULE_STEM": stem,
- "LOCAL_MODULE_HOST_OS": hostOs,
- "LOCAL_RESOURCE_DIR": localizePathList("resource_dirs"),
- "LOCAL_SANITIZE": sanitize(""),
- "LOCAL_SANITIZE_DIAG": sanitize("diag."),
- "LOCAL_STRIP_MODULE": strip(),
- "LOCAL_CFLAGS": cflags,
- "LOCAL_UNINSTALLABLE_MODULE": invert("installable"),
- "LOCAL_PROGUARD_ENABLED": proguardEnabled,
- "LOCAL_MODULE_PATH": prebuiltModulePath,
+ "LOCAL_32_BIT_ONLY": local32BitOnly,
+ "LOCAL_AIDL_INCLUDES": localAidlIncludes,
+ "LOCAL_ASSET_DIR": localizePathList("asset_dirs"),
+ "LOCAL_C_INCLUDES": localIncludeDirs,
+ "LOCAL_EXPORT_C_INCLUDE_DIRS": exportIncludeDirs,
+ "LOCAL_JARJAR_RULES": localizePath("jarjar_rules"),
+ "LOCAL_LDFLAGS": ldflags,
+ "LOCAL_MODULE_CLASS": prebuiltClass,
+ "LOCAL_MODULE_STEM": stem,
+ "LOCAL_MODULE_HOST_OS": hostOs,
+ "LOCAL_RESOURCE_DIR": localizePathList("resource_dirs"),
+ "LOCAL_SANITIZE": sanitize(""),
+ "LOCAL_SANITIZE_DIAG": sanitize("diag."),
+ "LOCAL_STRIP_MODULE": strip(),
+ "LOCAL_CFLAGS": cflags,
+ "LOCAL_UNINSTALLABLE_MODULE": invert("installable"),
+ "LOCAL_PROGUARD_ENABLED": proguardEnabled,
+ "LOCAL_MODULE_PATH": prebuiltModulePath,
+ "LOCAL_REPLACE_PREBUILT_APK_INSTALLED": prebuiltPreprocessed,
// composite functions
"LOCAL_MODULE_TAGS": includeVariableIf(bpVariable{"tags", bpparser.ListType}, not(valueDumpEquals("optional"))),
@@ -495,10 +500,6 @@
Value: false,
}
- trueValue := &bpparser.Bool{
- Value: true,
- }
-
if inList("windows") {
err = setVariable(ctx.file, ctx.append, "target.windows", "enabled", trueValue, true)
}
@@ -704,6 +705,11 @@
return nil
}
+func prebuiltPreprocessed(ctx variableAssignmentContext) error {
+ ctx.mkvalue = ctx.mkvalue.Clone()
+ return setVariable(ctx.file, false, ctx.prefix, "preprocessed", trueValue, true)
+}
+
func cflags(ctx variableAssignmentContext) error {
// The Soong replacement for CFLAGS doesn't need the same extra escaped quotes that were present in Make
ctx.mkvalue = ctx.mkvalue.Clone()
diff --git a/androidmk/androidmk/androidmk_test.go b/androidmk/androidmk/androidmk_test.go
index d9bde94..54bd586 100644
--- a/androidmk/androidmk/androidmk_test.go
+++ b/androidmk/androidmk/androidmk_test.go
@@ -1342,6 +1342,31 @@
`,
},
{
+ desc: "android_test_import prebuilt",
+ in: `
+ include $(CLEAR_VARS)
+ LOCAL_MODULE := foo
+ LOCAL_SRC_FILES := foo.apk
+ LOCAL_MODULE_CLASS := APPS
+ LOCAL_MODULE_TAGS := tests
+ LOCAL_MODULE_SUFFIX := .apk
+ LOCAL_CERTIFICATE := PRESIGNED
+ LOCAL_REPLACE_PREBUILT_APK_INSTALLED := $(LOCAL_PATH)/foo.apk
+ LOCAL_COMPATIBILITY_SUITE := cts
+ include $(BUILD_PREBUILT)
+ `,
+ expected: `
+android_test_import {
+ name: "foo",
+ srcs: ["foo.apk"],
+
+ certificate: "PRESIGNED",
+ preprocessed: true,
+ test_suites: ["cts"],
+}
+`,
+ },
+ {
desc: "undefined_boolean_var",
in: `
include $(CLEAR_VARS)
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 6b168fe..9321ad2 100644
--- a/apex/androidmk.go
+++ b/apex/androidmk.go
@@ -78,6 +78,8 @@
}
}
+ seenDataOutPaths := make(map[string]bool)
+
for _, fi := range a.filesInfo {
if cc, ok := fi.module.(*cc.Module); ok && cc.Properties.HideFromMake {
continue
@@ -112,16 +114,24 @@
pathWhenActivated := filepath.Join("$(PRODUCT_OUT)", "apex", apexName, fi.installDir)
if apexType == flattenedApex {
// /system/apex/<name>/{lib|framework|...}
- fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", filepath.Join(a.installDir.ToMakePath().String(),
- apexBundleName, fi.installDir))
+ modulePath := filepath.Join(a.installDir.ToMakePath().String(), apexBundleName, fi.installDir)
+ fmt.Fprintln(w, "LOCAL_MODULE_PATH :=", modulePath)
if a.primaryApexType && !symbolFilesNotNeeded {
fmt.Fprintln(w, "LOCAL_SOONG_SYMBOL_PATH :=", pathWhenActivated)
}
if len(fi.symlinks) > 0 {
fmt.Fprintln(w, "LOCAL_MODULE_SYMLINKS :=", strings.Join(fi.symlinks, " "))
}
- if len(fi.dataPaths) > 0 {
- fmt.Fprintln(w, "LOCAL_TEST_DATA :=", strings.Join(cc.AndroidMkDataPaths(fi.dataPaths), " "))
+ newDataPaths := []android.Path{}
+ for _, path := range fi.dataPaths {
+ dataOutPath := modulePath + ":" + path.Rel()
+ if ok := seenDataOutPaths[dataOutPath]; !ok {
+ newDataPaths = append(newDataPaths, path)
+ seenDataOutPaths[dataOutPath] = true
+ }
+ }
+ if len(newDataPaths) > 0 {
+ fmt.Fprintln(w, "LOCAL_TEST_DATA :=", strings.Join(cc.AndroidMkDataPaths(newDataPaths), " "))
}
if fi.module != nil && len(fi.module.NoticeFiles()) > 0 {
@@ -173,7 +183,7 @@
// soong_java_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .jar Therefore
// we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
// we will have foo.jar.jar
- fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", strings.TrimSuffix(fi.builtFile.Base(), ".jar"))
+ fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", strings.TrimSuffix(fi.Stem(), ".jar"))
fmt.Fprintln(w, "LOCAL_SOONG_CLASSES_JAR :=", javaModule.ImplementationAndResourcesJars()[0].String())
fmt.Fprintln(w, "LOCAL_SOONG_HEADER_JAR :=", javaModule.HeaderJars()[0].String())
fmt.Fprintln(w, "LOCAL_SOONG_DEX_JAR :=", fi.builtFile.String())
@@ -184,13 +194,13 @@
// soong_app_prebuilt.mk sets LOCAL_MODULE_SUFFIX := .apk Therefore
// we need to remove the suffix from LOCAL_MODULE_STEM, otherwise
// we will have foo.apk.apk
- fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", strings.TrimSuffix(fi.builtFile.Base(), ".apk"))
+ fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", strings.TrimSuffix(fi.Stem(), ".apk"))
if app, ok := fi.module.(*java.AndroidApp); ok && len(app.JniCoverageOutputs()) > 0 {
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 {
- fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.builtFile.Base())
+ 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())
@@ -202,7 +212,7 @@
}
fmt.Fprintln(w, "include $(BUILD_SYSTEM)/soong_cc_prebuilt.mk")
} else {
- fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.builtFile.Base())
+ fmt.Fprintln(w, "LOCAL_MODULE_STEM :=", fi.Stem())
if fi.builtFile == a.manifestPbOut && apexType == flattenedApex {
if a.primaryApexType {
// Make apex_manifest.pb module for this APEX to override all other
diff --git a/apex/apex.go b/apex/apex.go
index 4fee6e2..d3c5df0 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 (
@@ -93,69 +95,6 @@
//
// Module separator
//
- artApexContents := []string{
- "art_cmdlineparser_headers",
- "art_disassembler_headers",
- "art_libartbase_headers",
- "bionic_libc_platform_headers",
- "core-repackaged-icu4j",
- "cpp-define-generator-asm-support",
- "cpp-define-generator-definitions",
- "crtbegin_dynamic",
- "crtbegin_dynamic1",
- "crtbegin_so1",
- "crtbrand",
- "dex2oat_headers",
- "dt_fd_forward_export",
- "icu4c_extra_headers",
- "javavm_headers",
- "jni_platform_headers",
- "libPlatformProperties",
- "libadbconnection_client",
- "libadbconnection_server",
- "libandroidicuinit",
- "libart_runtime_headers_ndk",
- "libartd-disassembler",
- "libdexfile_all_headers",
- "libdexfile_external_headers",
- "libdexfile_support",
- "libdmabufinfo",
- "libexpat",
- "libfdlibm",
- "libicui18n_headers",
- "libicuuc",
- "libicuuc_headers",
- "libicuuc_stubdata",
- "libjdwp_headers",
- "liblz4",
- "liblzma",
- "libmeminfo",
- "libnativebridge-headers",
- "libnativehelper_header_only",
- "libnativeloader-headers",
- "libnpt_headers",
- "libopenjdkjvmti_headers",
- "libperfetto_client_experimental",
- "libprocinfo",
- "libunwind_llvm",
- "libunwindstack",
- "libv8",
- "libv8base",
- "libv8gen",
- "libv8platform",
- "libv8sampler",
- "libv8src",
- "libvixl",
- "libvixld",
- "libz",
- "libziparchive",
- "perfetto_trace_protos",
- }
- m["com.android.art.debug"] = artApexContents
- m["com.android.art.release"] = artApexContents
- //
- // Module separator
- //
m["com.android.bluetooth.updatable"] = []string{
"android.hardware.audio.common@5.0",
"android.hardware.bluetooth.a2dp@1.0",
@@ -1207,6 +1146,7 @@
// apexFile represents a file in an APEX bundle
type apexFile struct {
builtFile android.Path
+ stem string
moduleName string
installDir string
class apexFileClass
@@ -1255,7 +1195,14 @@
// Path() returns path of this apex file relative to the APEX root
func (af *apexFile) Path() string {
- return af.apexRelativePath(af.builtFile.Base())
+ return af.apexRelativePath(af.Stem())
+}
+
+func (af *apexFile) Stem() string {
+ if af.stem != "" {
+ return af.stem
+ }
+ return af.builtFile.Base()
}
// SymlinkPaths() returns paths of the symlinks (if any) relative to the APEX root
@@ -1694,7 +1641,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)
@@ -1702,15 +1649,21 @@
return af
}
-func apexFileForJavaLibrary(ctx android.BaseModuleContext, lib java.Dependency, module android.Module) apexFile {
+type javaDependency interface {
+ java.Dependency
+ Stem() string
+}
+
+func apexFileForJavaLibrary(ctx android.BaseModuleContext, lib javaDependency, module android.Module) apexFile {
dirInApex := "javalib"
fileToCopy := lib.DexJar()
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)
@@ -1995,13 +1948,13 @@
case sharedLibTag, jniLibTag:
isJniLib := depTag == jniLibTag
if c, ok := child.(*cc.Module); ok {
- // bootstrap bionic libs are treated as provided by system
- if c.HasStubsVariants() && !cc.InstallToBootstrap(c.BaseModuleName(), ctx.Config()) {
- provideNativeLibs = append(provideNativeLibs, c.OutputFile().Path().Base())
- }
fi := apexFileForNativeLibrary(ctx, c, handleSpecialLibs)
fi.isJniLib = isJniLib
filesInfo = append(filesInfo, fi)
+ // bootstrap bionic libs are treated as provided by system
+ if c.HasStubsVariants() && !cc.InstallToBootstrap(c.BaseModuleName(), ctx.Config()) {
+ provideNativeLibs = append(provideNativeLibs, fi.Stem())
+ }
return true // track transitive dependencies
} else {
propertyName := "native_shared_libs"
@@ -2014,7 +1967,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))
@@ -2061,7 +2014,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))
@@ -2121,6 +2074,8 @@
// don't include it in this APEX
return false
}
+ af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs)
+ af.transitiveDep = true
if !a.Host() && !android.DirectlyInApex(ctx.ModuleName(), ctx.OtherModuleName(cc)) && (cc.IsStubs() || cc.HasStubsVariants()) {
// If the dependency is a stubs lib, don't include it in this APEX,
// but make sure that the lib is installed on the device.
@@ -2132,12 +2087,10 @@
if !android.DirectlyInAnyApex(ctx, cc.Name()) && !android.InList(cc.BaseModuleName(), a.requiredDeps) {
a.requiredDeps = append(a.requiredDeps, cc.BaseModuleName())
}
- requireNativeLibs = append(requireNativeLibs, cc.OutputFile().Path().Base())
+ requireNativeLibs = append(requireNativeLibs, af.Stem())
// Don't track further
return false
}
- af := apexFileForNativeLibrary(ctx, cc, handleSpecialLibs)
- af.transitiveDep = true
filesInfo = append(filesInfo, af)
return true // track transitive dependencies
}
@@ -2158,7 +2111,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 5d08f37a..779119c 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
@@ -184,6 +186,7 @@
"dummy.txt": nil,
"baz": nil,
"bar/baz": nil,
+ "testdata/baz": nil,
}
cc.GatherRequiredFilesForTest(fs)
@@ -229,9 +232,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)
@@ -274,6 +277,15 @@
}
}
+// ensure that 'result' contains 'expected' exactly one time
+func ensureContainsOnce(t *testing.T, result string, expected string) {
+ t.Helper()
+ count := strings.Count(result, expected)
+ if count != 1 {
+ t.Errorf("%q is found %d times (expected 1 time) in %q", expected, count, result)
+ }
+}
+
// ensures that 'result' does not contain 'notExpected'
func ensureNotContains(t *testing.T, result string, notExpected string) {
t.Helper()
@@ -414,6 +426,7 @@
java_library {
name: "myjar",
srcs: ["foo/bar/MyClass.java"],
+ stem: "myjar_stem",
sdk_version: "none",
system_modules: "none",
static_libs: ["myotherjar"],
@@ -468,7 +481,7 @@
// Ensure that both direct and indirect deps are copied into apex
ensureContains(t, copyCmds, "image.apex/lib64/mylib.so")
ensureContains(t, copyCmds, "image.apex/lib64/mylib2.so")
- ensureContains(t, copyCmds, "image.apex/javalib/myjar.jar")
+ ensureContains(t, copyCmds, "image.apex/javalib/myjar_stem.jar")
// .. but not for java libs
ensureNotContains(t, copyCmds, "image.apex/javalib/myotherjar.jar")
ensureNotContains(t, copyCmds, "image.apex/javalib/msharedjar.jar")
@@ -3423,6 +3436,13 @@
stl: "none",
}
+ filegroup {
+ name: "fg2",
+ srcs: [
+ "testdata/baz"
+ ],
+ }
+
cc_test {
name: "mytests",
gtest: false,
@@ -3436,6 +3456,10 @@
system_shared_libs: [],
static_executable: true,
stl: "none",
+ data: [
+ ":fg",
+ ":fg2",
+ ],
}
`)
@@ -3456,9 +3480,9 @@
ensureContains(t, copyCmds, "image.apex/bin/test/mytest3")
// Ensure the module is correctly translated.
- apexBundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
- data := android.AndroidMkDataForTest(t, config, "", apexBundle)
- name := apexBundle.BaseModuleName()
+ bundle := ctx.ModuleForTests("myapex", "android_common_myapex_image").Module().(*apexBundle)
+ data := android.AndroidMkDataForTest(t, config, "", bundle)
+ name := bundle.BaseModuleName()
prefix := "TARGET_"
var builder strings.Builder
data.Custom(&builder, name, prefix, "", data)
@@ -3470,6 +3494,13 @@
ensureContains(t, androidMk, "LOCAL_MODULE := apex_manifest.pb.myapex\n")
ensureContains(t, androidMk, "LOCAL_MODULE := apex_pubkey.myapex\n")
ensureContains(t, androidMk, "LOCAL_MODULE := myapex\n")
+
+ flatBundle := ctx.ModuleForTests("myapex", "android_common_myapex_flattened").Module().(*apexBundle)
+ data = android.AndroidMkDataForTest(t, config, "", flatBundle)
+ data.Custom(&builder, name, prefix, "", data)
+ flatAndroidMk := builder.String()
+ ensureContainsOnce(t, flatAndroidMk, "LOCAL_TEST_DATA := :baz :bar/baz\n")
+ ensureContainsOnce(t, flatAndroidMk, "LOCAL_TEST_DATA := :testdata/baz\n")
}
func TestInstallExtraFlattenedApexes(t *testing.T) {
diff --git a/apex/builder.go b/apex/builder.go
index 11652bc..0108d06 100644
--- a/apex/builder.go
+++ b/apex/builder.go
@@ -190,7 +190,7 @@
var jniLibs []string
for _, fi := range a.filesInfo {
if fi.isJniLib {
- jniLibs = append(jniLibs, fi.builtFile.Base())
+ jniLibs = append(jniLibs, fi.Stem())
}
}
if len(jniLibs) > 0 {
@@ -247,7 +247,7 @@
return android.NoticeOutputs{}
}
- return android.BuildNoticeOutput(ctx, a.installDir, apexFileName, android.FirstUniquePaths(noticeFiles))
+ return android.BuildNoticeOutput(ctx, a.installDir, apexFileName, android.SortedUniquePaths(noticeFiles))
}
func (a *apexBundle) buildInstalledFilesFile(ctx android.ModuleContext, builtApex android.Path, imageDir android.Path) android.OutputPath {
@@ -417,7 +417,7 @@
var readOnlyPaths = []string{"apex_manifest.json", "apex_manifest.pb"}
var executablePaths []string // this also includes dirs
for _, f := range a.filesInfo {
- pathInApex := filepath.Join(f.installDir, f.builtFile.Base())
+ pathInApex := f.Path()
if f.installDir == "bin" || strings.HasPrefix(f.installDir, "bin/") {
executablePaths = append(executablePaths, pathInApex)
for _, d := range f.dataPaths {
@@ -582,19 +582,27 @@
}
a.outputFile = android.PathForModuleOut(ctx, a.Name()+suffix)
+ rule := java.Signapk
+ args := map[string]string{
+ "certificates": a.container_certificate_file.String() + " " + a.container_private_key_file.String(),
+ "flags": "-a 4096", //alignment
+ }
+ implicits := android.Paths{
+ a.container_certificate_file,
+ a.container_private_key_file,
+ }
+ if ctx.Config().IsEnvTrue("RBE_SIGNAPK") {
+ rule = java.SignapkRE
+ args["implicits"] = strings.Join(implicits.Strings(), ",")
+ args["outCommaList"] = a.outputFile.String()
+ }
ctx.Build(pctx, android.BuildParams{
- Rule: java.Signapk,
+ Rule: rule,
Description: "signapk",
Output: a.outputFile,
Input: unsignedOutputFile,
- Implicits: []android.Path{
- a.container_certificate_file,
- a.container_private_key_file,
- },
- Args: map[string]string{
- "certificates": a.container_certificate_file.String() + " " + a.container_private_key_file.String(),
- "flags": "-a 4096", //alignment
- },
+ Implicits: implicits,
+ Args: args,
})
// Install to $OUT/soong/{target,host}/.../apex
@@ -659,7 +667,7 @@
apexBundleName := a.Name()
for _, fi := range a.filesInfo {
dir := filepath.Join("apex", apexBundleName, fi.installDir)
- target := ctx.InstallFile(android.PathForModuleInstall(ctx, dir), fi.builtFile.Base(), fi.builtFile)
+ target := ctx.InstallFile(android.PathForModuleInstall(ctx, dir), fi.Stem(), fi.builtFile)
for _, sym := range fi.symlinks {
ctx.InstallSymlink(android.PathForModuleInstall(ctx, dir), sym, target)
}
diff --git a/bpfix/bpfix/bpfix.go b/bpfix/bpfix/bpfix.go
index a1c5de1..e731750 100644
--- a/bpfix/bpfix/bpfix.go
+++ b/bpfix/bpfix/bpfix.go
@@ -408,6 +408,8 @@
switch mod.Type {
case "android_app":
mod.Type = "android_test"
+ case "android_app_import":
+ mod.Type = "android_test_import"
case "java_library", "java_library_installable":
mod.Type = "java_test"
case "java_library_host":
@@ -951,7 +953,8 @@
case strings.Contains(mod.Type, "cc_test"),
strings.Contains(mod.Type, "cc_library_static"),
strings.Contains(mod.Type, "java_test"),
- mod.Type == "android_test":
+ mod.Type == "android_test",
+ mod.Type == "android_test_import":
continue
case strings.Contains(mod.Type, "cc_lib"):
replaceStr += `// WARNING: Module tags are not supported in Soong.
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/binary_sdk_member.go b/cc/binary_sdk_member.go
index 88ac513..372a72e 100644
--- a/cc/binary_sdk_member.go
+++ b/cc/binary_sdk_member.go
@@ -20,6 +20,7 @@
"android/soong/android"
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
)
func init() {
@@ -65,7 +66,15 @@
}
func (mt *binarySdkMemberType) AddPrebuiltModule(ctx android.SdkMemberContext, member android.SdkMember) android.BpModule {
- return ctx.SnapshotBuilder().AddPrebuiltModule(member, "cc_prebuilt_binary")
+ pbm := ctx.SnapshotBuilder().AddPrebuiltModule(member, "cc_prebuilt_binary")
+
+ ccModule := member.Variants()[0].(*Module)
+
+ if stl := ccModule.stl.Properties.Stl; stl != nil {
+ pbm.AddProperty("stl", proptools.String(stl))
+ }
+
+ return pbm
}
func (mt *binarySdkMemberType) CreateVariantPropertiesStruct() android.SdkMemberProperties {
@@ -105,6 +114,10 @@
//
// This field is exported as its contents may not be arch specific.
SystemSharedLibs []string
+
+ // Arch specific flags.
+ StaticExecutable bool
+ Nocrt bool
}
func (p *nativeBinaryInfoProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
@@ -113,6 +126,10 @@
p.archType = ccModule.Target().Arch.ArchType.String()
p.outputFile = getRequiredMemberOutputFile(ctx, ccModule)
+ binaryLinker := ccModule.linker.(*binaryDecorator)
+ p.StaticExecutable = binaryLinker.static()
+ p.Nocrt = Bool(binaryLinker.baseLinker.Properties.Nocrt)
+
if ccModule.linker != nil {
specifiedDeps := specifiedDeps{}
specifiedDeps = ccModule.linker.linkerSpecifiedDeps(specifiedDeps)
@@ -143,4 +160,11 @@
if p.SystemSharedLibs != nil {
propertySet.AddPropertyWithTag("system_shared_libs", p.SystemSharedLibs, builder.SdkMemberReferencePropertyTag(false))
}
+
+ if p.StaticExecutable {
+ propertySet.AddProperty("static_executable", p.StaticExecutable)
+ }
+ if p.Nocrt {
+ propertySet.AddProperty("nocrt", p.Nocrt)
+ }
}
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/library.go b/cc/library.go
index 47485ce..ba8b0f4 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -407,6 +407,31 @@
if strings.HasPrefix(dir, android.PathForOutput(ctx).String()) {
continue
}
+ // libeigen wrongly exports the root directory "external/eigen". But only two
+ // subdirectories "Eigen" and "unsupported" contain exported header files. Even worse
+ // some of them have no extension. So we need special treatment for libeigen in order
+ // to glob correctly.
+ if dir == "external/eigen" {
+ // Only these two directories contains exported headers.
+ for _, subdir := range []string{"Eigen", "unsupported/Eigen"} {
+ glob, err := ctx.GlobWithDeps("external/eigen/"+subdir+"/**/*", nil)
+ if err != nil {
+ ctx.ModuleErrorf("glob failed: %#v", err)
+ return
+ }
+ for _, header := range glob {
+ if strings.HasSuffix(header, "/") {
+ continue
+ }
+ ext := filepath.Ext(header)
+ if ext != "" && ext != ".h" {
+ continue
+ }
+ ret = append(ret, android.PathForSource(ctx, header))
+ }
+ }
+ continue
+ }
exts := headerExts
// Glob all files under this special directory, because of C++ headers.
if strings.HasPrefix(dir, "external/libcxx/include") {
diff --git a/cc/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/cmd/host_bionic_inject/host_bionic_inject.go b/cmd/host_bionic_inject/host_bionic_inject.go
index f7163d7..629f6cc 100644
--- a/cmd/host_bionic_inject/host_bionic_inject.go
+++ b/cmd/host_bionic_inject/host_bionic_inject.go
@@ -105,7 +105,9 @@
err = checkLinker(file, linker, symbols)
if err != nil {
- return 0, err
+ return 0, fmt.Errorf("Linker executable failed verification against app embedded linker: %s\n"+
+ "linker might not be in sync with crtbegin_dynamic.o.",
+ err)
}
start, err := findSymbol(symbols, "_start")
diff --git a/cmd/pom2bp/pom2bp.go b/cmd/pom2bp/pom2bp.go
index 191b919..d341b8c 100644
--- a/cmd/pom2bp/pom2bp.go
+++ b/cmd/pom2bp/pom2bp.go
@@ -213,10 +213,14 @@
return hostAndDeviceModuleNames.IsHostAndDeviceModule(p.GroupId, p.ArtifactId)
}
+func (p Pom) IsHostOnly() bool {
+ return p.IsHostModule() && !p.IsHostAndDeviceModule()
+}
+
func (p Pom) ModuleType() string {
if p.IsAar() {
return "android_library"
- } else if p.IsHostModule() && !p.IsHostAndDeviceModule() {
+ } else if p.IsHostOnly() {
return "java_library_host"
} else {
return "java_library_static"
@@ -226,7 +230,7 @@
func (p Pom) ImportModuleType() string {
if p.IsAar() {
return "android_library_import"
- } else if p.IsHostModule() && !p.IsHostAndDeviceModule() {
+ } else if p.IsHostOnly() {
return "java_import_host"
} else {
return "java_import"
@@ -366,6 +370,12 @@
{{- if .IsHostAndDeviceModule}}
host_supported: true,
{{- end}}
+ {{- if not .IsHostOnly}}
+ apex_available: [
+ "//apex_available:platform",
+ "//apex_available:anyapex",
+ ],
+ {{- end}}
{{- if .IsAar}}
min_sdk_version: "{{.MinSdkVersion}}",
static_libs: [
@@ -401,6 +411,12 @@
{{- if .IsHostAndDeviceModule}}
host_supported: true,
{{- end}}
+ {{- if not .IsHostOnly}}
+ apex_available: [
+ "//apex_available:platform",
+ "//apex_available:anyapex",
+ ],
+ {{- end}}
{{- if .IsAar}}
min_sdk_version: "{{.MinSdkVersion}}",
static_libs: [
@@ -431,9 +447,17 @@
{{- if .IsHostAndDeviceModule}}
host_supported: true,
{{- end}}
+ {{- if not .IsHostOnly}}
+ apex_available: [
+ "//apex_available:platform",
+ "//apex_available:anyapex",
+ ],
+ {{- end}}
{{- if .IsAar}}
min_sdk_version: "{{.MinSdkVersion}}",
manifest: "manifests/{{.BpName}}/AndroidManifest.xml",
+ {{- else if not .IsHostOnly}}
+ min_sdk_version: "24",
{{- end}}
{{- end}}
static_libs: [
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 1d94f02..d0cad78 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -117,6 +117,8 @@
// Command is the type of soong_ui execution. Only one type of
// execution is specified. The args are specific to the command.
func main() {
+ buildStartedMilli := time.Now().UnixNano() / int64(time.Millisecond)
+
c, args := getCommand(os.Args)
if c == nil {
fmt.Fprintf(os.Stderr, "The `soong` native UI is not yet available.\n")
@@ -166,12 +168,17 @@
logsDir = filepath.Join(config.DistDir(), "logs")
}
+ buildErrorFile := filepath.Join(logsDir, c.logsPrefix+"build_error")
+ rbeMetricsFile := filepath.Join(logsDir, c.logsPrefix+"rbe_metrics.pb")
+ soongMetricsFile := filepath.Join(logsDir, c.logsPrefix+"soong_metrics")
+ defer build.UploadMetrics(buildCtx, config, buildStartedMilli, buildErrorFile, rbeMetricsFile, soongMetricsFile)
+
os.MkdirAll(logsDir, 0777)
log.SetOutput(filepath.Join(logsDir, c.logsPrefix+"soong.log"))
trace.SetOutput(filepath.Join(logsDir, c.logsPrefix+"build.trace"))
stat.AddOutput(status.NewVerboseLog(log, filepath.Join(logsDir, c.logsPrefix+"verbose.log")))
stat.AddOutput(status.NewErrorLog(log, filepath.Join(logsDir, c.logsPrefix+"error.log")))
- stat.AddOutput(status.NewProtoErrorLog(log, filepath.Join(logsDir, c.logsPrefix+"build_error")))
+ stat.AddOutput(status.NewProtoErrorLog(log, buildErrorFile))
stat.AddOutput(status.NewCriticalPath(log))
stat.AddOutput(status.NewBuildProgressLog(log, filepath.Join(logsDir, c.logsPrefix+"build_progress.pb")))
@@ -179,7 +186,7 @@
buildCtx.Verbosef("Parallelism (local/remote/highmem): %v/%v/%v",
config.Parallel(), config.RemoteParallel(), config.HighmemParallel())
- defer met.Dump(filepath.Join(logsDir, c.logsPrefix+"soong_metrics"))
+ defer met.Dump(soongMetricsFile)
if start, ok := os.LookupEnv("TRACE_BEGIN_SOONG"); ok {
if !strings.HasSuffix(start, "N") {
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index fc03563..5275e8f 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,55 @@
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 {
+ clc.Host = append(clc.Host, pathForLibrary(module, lib))
+ clc.Target = append(clc.Target, filepath.Join("/system/framework", lib+".jar"))
+ }
+}
+
+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,72 +277,38 @@
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
+ 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"))
- }
-
+ // Conditional class loader context for API version < 28.
const httpLegacy = "org.apache.http.legacy"
- const httpLegacyImpl = "org.apache.http.legacy.impl"
-
- // 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 the classes to the classpath for dexpreopt. One the
- // device the classes will be in a file called org.apache.http.legacy.impl.jar.
- module.LibraryPaths[httpLegacyImpl] = module.LibraryPaths[httpLegacy]
-
- if !contains(module.UsesLibraries, httpLegacy) && !contains(module.PresentOptionalUsesLibraries, httpLegacy) {
- conditionalClassLoaderContextHost28 = append(conditionalClassLoaderContextHost28,
- pathForLibrary(module, httpLegacyImpl))
- conditionalClassLoaderContextTarget28 = append(conditionalClassLoaderContextTarget28,
- filepath.Join("/system/framework", httpLegacyImpl+".jar"))
+ if !contains(usesLibs, httpLegacy) {
+ classLoaderContexts.addLibs(28, module, httpLegacy)
}
- const hidlBase = "android.hidl.base-V1.0-java"
- const hidlManager = "android.hidl.manager-V1.0-java"
+ // 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.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.
- 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 < 30.
+ const testBase = "android.test.base"
+ if !contains(usesLibs, testBase) {
+ 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)
@@ -314,10 +330,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 {
@@ -336,21 +353,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, " "))
+ 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)
}
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/etc/prebuilt_etc.go b/etc/prebuilt_etc.go
new file mode 100644
index 0000000..d6eb008
--- /dev/null
+++ b/etc/prebuilt_etc.go
@@ -0,0 +1,295 @@
+// Copyright 2016 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 etc
+
+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() {
+ 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 {
+ // 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"`
+
+ // Make this module available when building for ramdisk.
+ Ramdisk_available *bool
+
+ // Make this module available when building for recovery.
+ Recovery_available *bool
+
+ // Whether this module is directly installable to one of the partitions. Default: true.
+ Installable *bool
+
+ // Install symlinks to the installed file.
+ Symlinks []string `android:"arch_variant"`
+}
+
+type PrebuiltEtcModule interface {
+ android.Module
+ SubDir() string
+ OutputFile() android.OutputPath
+}
+
+type PrebuiltEtc struct {
+ android.ModuleBase
+
+ properties prebuiltEtcProperties
+
+ 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 android.InstallPath
+ additionalDependencies *android.Paths
+}
+
+func (p *PrebuiltEtc) inRamdisk() bool {
+ return p.ModuleBase.InRamdisk() || p.ModuleBase.InstallInRamdisk()
+}
+
+func (p *PrebuiltEtc) onlyInRamdisk() bool {
+ return p.ModuleBase.InstallInRamdisk()
+}
+
+func (p *PrebuiltEtc) InstallInRamdisk() bool {
+ return p.inRamdisk()
+}
+
+func (p *PrebuiltEtc) inRecovery() bool {
+ return p.ModuleBase.InRecovery() || p.ModuleBase.InstallInRecovery()
+}
+
+func (p *PrebuiltEtc) onlyInRecovery() bool {
+ return p.ModuleBase.InstallInRecovery()
+}
+
+func (p *PrebuiltEtc) InstallInRecovery() bool {
+ return p.inRecovery()
+}
+
+var _ android.ImageInterface = (*PrebuiltEtc)(nil)
+
+func (p *PrebuiltEtc) ImageMutatorBegin(ctx android.BaseModuleContext) {}
+
+func (p *PrebuiltEtc) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+ return !p.ModuleBase.InstallInRecovery() && !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 android.BaseModuleContext) bool {
+ return proptools.Bool(p.properties.Recovery_available) || p.ModuleBase.InstallInRecovery()
+}
+
+func (p *PrebuiltEtc) ExtraImageVariations(ctx android.BaseModuleContext) []string {
+ return nil
+}
+
+func (p *PrebuiltEtc) SetImageVariation(ctx android.BaseModuleContext, variation string, module android.Module) {
+}
+
+func (p *PrebuiltEtc) DepsMutator(ctx android.BottomUpMutatorContext) {
+ if p.properties.Src == nil {
+ ctx.PropertyErrorf("src", "missing prebuilt source file")
+ }
+}
+
+func (p *PrebuiltEtc) SourceFilePath(ctx android.ModuleContext) android.Path {
+ return android.PathForModuleSrc(ctx, android.String(p.properties.Src))
+}
+
+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 android.Paths) {
+ p.additionalDependencies = &paths
+}
+
+func (p *PrebuiltEtc) OutputFile() android.OutputPath {
+ return p.outputFilePath
+}
+
+func (p *PrebuiltEtc) SubDir() string {
+ return android.String(p.properties.Sub_dir)
+}
+
+func (p *PrebuiltEtc) Installable() bool {
+ return p.properties.Installable == nil || android.Bool(p.properties.Installable)
+}
+
+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()
+ } 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
+ }
+ 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.
+ installBaseDir := p.installDirBase
+ if ctx.SocSpecific() && p.socInstallDirBase != "" {
+ installBaseDir = p.socInstallDirBase
+ }
+ 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, android.BuildParams{
+ Rule: android.Cp,
+ Output: p.outputFilePath,
+ Input: p.sourceFilePath,
+ })
+}
+
+func (p *PrebuiltEtc) AndroidMkEntries() []android.AndroidMkEntries {
+ nameSuffix := ""
+ if p.inRamdisk() && !p.onlyInRamdisk() {
+ nameSuffix = ".ramdisk"
+ }
+ if p.inRecovery() && !p.onlyInRecovery() {
+ nameSuffix = ".recovery"
+ }
+ return []android.AndroidMkEntries{android.AndroidMkEntries{
+ Class: "ETC",
+ SubName: nameSuffix,
+ 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())
+ if len(p.properties.Symlinks) > 0 {
+ entries.AddStrings("LOCAL_MODULE_SYMLINKS", p.properties.Symlinks...)
+ }
+ entries.SetString("LOCAL_UNINSTALLABLE_MODULE", strconv.FormatBool(!p.Installable()))
+ if p.additionalDependencies != nil {
+ for _, path := range *p.additionalDependencies {
+ entries.AddStrings("LOCAL_ADDITIONAL_DEPENDENCIES", path.String())
+ }
+ }
+ },
+ },
+ }}
+}
+
+func InitPrebuiltEtcModule(p *PrebuiltEtc, dirBase string) {
+ p.installDirBase = dirBase
+ p.AddProperties(&p.properties)
+}
+
+// prebuilt_etc is for a prebuilt artifact that is installed in
+// <partition>/etc/<sub_dir> directory.
+func PrebuiltEtcFactory() android.Module {
+ module := &PrebuiltEtc{}
+ InitPrebuiltEtcModule(module, "etc")
+ // This module is device-only
+ 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() android.Module {
+ module := &PrebuiltEtc{}
+ InitPrebuiltEtcModule(module, "etc")
+ // This module is host-only
+ 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() android.Module {
+ module := &PrebuiltEtc{}
+ InitPrebuiltEtcModule(module, "usr/share")
+ // This module is device-only
+ 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() android.Module {
+ module := &PrebuiltEtc{}
+ InitPrebuiltEtcModule(module, "usr/share")
+ // This module is host-only
+ android.InitAndroidArchModule(module, android.HostSupported, android.MultilibCommon)
+ return module
+}
+
+// prebuilt_font installs a font in <partition>/fonts directory.
+func PrebuiltFontFactory() android.Module {
+ module := &PrebuiltEtc{}
+ InitPrebuiltEtcModule(module, "fonts")
+ // This module is device-only
+ 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() android.Module {
+ module := &PrebuiltEtc{}
+ module.socInstallDirBase = "firmware"
+ InitPrebuiltEtcModule(module, "etc/firmware")
+ // This module is device-only
+ 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/androidmk.go b/java/androidmk.go
index 5e3b7d2..6eb22fd 100644
--- a/java/androidmk.go
+++ b/java/androidmk.go
@@ -104,10 +104,6 @@
entries.AddStrings("LOCAL_EXPORT_SDK_LIBRARIES", library.exportedSdkLibs...)
- if len(library.additionalCheckedModules) != 0 {
- entries.AddStrings("LOCAL_ADDITIONAL_CHECKED_MODULE", library.additionalCheckedModules.Strings()...)
- }
-
if library.proguardDictionary != nil {
entries.SetPath("LOCAL_SOONG_PROGUARD_DICT", library.proguardDictionary)
}
diff --git a/java/app.go b/java/app.go
index 8241b68..a45ab6f 100755
--- a/java/app.go
+++ b/java/app.go
@@ -568,16 +568,17 @@
installDir = filepath.Join("app", a.installApkName)
}
a.dexpreopter.installPath = android.PathForModuleInstall(ctx, installDir, a.installApkName+".apk")
- a.dexpreopter.uncompressedDex = a.shouldUncompressDex(ctx)
-
+ if a.deviceProperties.Uncompress_dex == nil {
+ // If the value was not force-set by the user, use reasonable default based on the module.
+ a.deviceProperties.Uncompress_dex = proptools.BoolPtr(a.shouldUncompressDex(ctx))
+ }
+ a.dexpreopter.uncompressedDex = *a.deviceProperties.Uncompress_dex
a.dexpreopter.enforceUsesLibs = a.usesLibrary.enforceUsesLibraries()
a.dexpreopter.usesLibs = a.usesLibrary.usesLibraryProperties.Uses_libs
a.dexpreopter.optionalUsesLibs = a.usesLibrary.presentOptionalUsesLibs(ctx)
a.dexpreopter.libraryPaths = a.usesLibrary.usesLibraryPaths(ctx)
a.dexpreopter.manifestFile = a.mergedManifestFile
- a.deviceProperties.UncompressDex = a.dexpreopter.uncompressedDex
-
if ctx.ModuleName() != "framework-res" {
a.Module.compile(ctx, a.aaptSrcJar)
}
@@ -1613,7 +1614,8 @@
})
android.InitApexModule(module)
- InitJavaModule(module, android.DeviceSupported)
+ android.InitAndroidMultiTargetsArchModule(module, android.DeviceSupported, android.MultilibCommon)
+ android.InitDefaultableModule(module)
android.InitSingleSourcePrebuiltModule(module, &module.properties, "Apk")
return module
@@ -1690,6 +1692,9 @@
// module name in the form ":module".
Certificate *string
+ // Name of the signing certificate lineage file.
+ Lineage *string
+
// optional theme name. If specified, the overlay package will be applied
// only when the ro.boot.vendor.overlay.theme system property is set to the same value.
Theme *string
@@ -1764,7 +1769,11 @@
_, certificates := collectAppDeps(ctx, r, false, false)
certificates = processMainCert(r.ModuleBase, String(r.properties.Certificate), certificates, ctx)
signed := android.PathForModuleOut(ctx, "signed", r.Name()+".apk")
- SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, nil)
+ var lineageFile android.Path
+ if lineage := String(r.properties.Lineage); lineage != "" {
+ lineageFile = android.PathForModuleSrc(ctx, lineage)
+ }
+ SignAppPackage(ctx, signed, r.aapt.exportPackage, certificates, lineageFile)
r.certificate = certificates[0]
r.outputFile = signed
@@ -1854,6 +1863,7 @@
"org.apache.http.legacy",
"android.hidl.base-V1.0-java",
"android.hidl.manager-V1.0-java")
+ ctx.AddVariationDependencies(nil, usesLibTag, optionalUsesLibs...)
}
}
}
diff --git a/java/app_builder.go b/java/app_builder.go
index fb9ab42..014bd54 100644
--- a/java/app_builder.go
+++ b/java/app_builder.go
@@ -26,16 +26,23 @@
"github.com/google/blueprint/proptools"
"android/soong/android"
+ "android/soong/remoteexec"
)
var (
- Signapk = pctx.AndroidStaticRule("signapk",
+ Signapk, SignapkRE = remoteexec.StaticRules(pctx, "signapk",
blueprint.RuleParams{
- Command: `${config.JavaCmd} ${config.JavaVmFlags} -Djava.library.path=$$(dirname ${config.SignapkJniLibrary}) ` +
+ Command: `$reTemplate${config.JavaCmd} ${config.JavaVmFlags} -Djava.library.path=$$(dirname ${config.SignapkJniLibrary}) ` +
`-jar ${config.SignapkCmd} $flags $certificates $in $out`,
CommandDeps: []string{"${config.SignapkCmd}", "${config.SignapkJniLibrary}"},
},
- "flags", "certificates")
+ &remoteexec.REParams{Labels: map[string]string{"type": "tool", "name": "signapk"},
+ ExecStrategy: "${config.RESignApkExecStrategy}",
+ Inputs: []string{"${config.SignapkCmd}", "$in", "$$(dirname ${config.SignapkJniLibrary})", "$implicits"},
+ OutputFiles: []string{"$outCommaList"},
+ ToolchainInputs: []string{"${config.JavaCmd}"},
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ }, []string{"flags", "certificates"}, []string{"implicits", "outCommaList"})
)
var combineApk = pctx.AndroidStaticRule("combineApk",
@@ -78,22 +85,30 @@
deps = append(deps, c.Pem, c.Key)
}
+ outputFiles := android.WritablePaths{signedApk}
var flags []string
if lineageFile != nil {
flags = append(flags, "--lineage", lineageFile.String())
deps = append(deps, lineageFile)
}
+ rule := Signapk
+ args := map[string]string{
+ "certificates": strings.Join(certificateArgs, " "),
+ "flags": strings.Join(flags, " "),
+ }
+ if ctx.Config().IsEnvTrue("RBE_SIGNAPK") {
+ rule = SignapkRE
+ args["implicits"] = strings.Join(deps.Strings(), ",")
+ args["outCommaList"] = strings.Join(outputFiles.Strings(), ",")
+ }
ctx.Build(pctx, android.BuildParams{
- Rule: Signapk,
+ Rule: rule,
Description: "signapk",
- Output: signedApk,
+ Outputs: outputFiles,
Input: unsignedApk,
Implicits: deps,
- Args: map[string]string{
- "certificates": strings.Join(certificateArgs, " "),
- "flags": strings.Join(flags, " "),
- },
+ Args: args,
})
}
@@ -217,14 +232,20 @@
"-f", j.path.String())
}
+ rule := zip
+ args := map[string]string{
+ "jarArgs": strings.Join(proptools.NinjaAndShellEscapeList(jarArgs), " "),
+ }
+ if ctx.Config().IsEnvTrue("RBE_ZIP") {
+ rule = zipRE
+ args["implicits"] = strings.Join(deps.Strings(), ",")
+ }
ctx.Build(pctx, android.BuildParams{
- Rule: zip,
+ Rule: rule,
Description: "zip jni libs",
Output: outputFile,
Implicits: deps,
- Args: map[string]string{
- "jarArgs": strings.Join(proptools.NinjaAndShellEscapeList(jarArgs), " "),
- },
+ Args: args,
})
}
diff --git a/java/app_test.go b/java/app_test.go
index 1a718f4..eb583be 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -2806,6 +2806,32 @@
uncompressedPlatform: true,
uncompressedUnbundled: true,
},
+ {
+ name: "normal_uncompress_dex_true",
+ bp: `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ uncompress_dex: true,
+ }
+ `,
+ uncompressedPlatform: true,
+ uncompressedUnbundled: true,
+ },
+ {
+ name: "normal_uncompress_dex_false",
+ bp: `
+ android_app {
+ name: "foo",
+ srcs: ["a.java"],
+ sdk_version: "current",
+ uncompress_dex: false,
+ }
+ `,
+ uncompressedPlatform: false,
+ uncompressedUnbundled: false,
+ },
}
test := func(t *testing.T, bp string, want bool, unbundled bool) {
@@ -2869,6 +2895,7 @@
runtime_resource_overlay {
name: "foo",
certificate: "platform",
+ lineage: "lineage.bin",
product_specific: true,
static_libs: ["bar"],
resource_libs: ["baz"],
@@ -2923,6 +2950,11 @@
// Check cert signing flag.
signedApk := m.Output("signed/foo.apk")
+ lineageFlag := signedApk.Args["flags"]
+ expectedLineageFlag := "--lineage lineage.bin"
+ if expectedLineageFlag != lineageFlag {
+ t.Errorf("Incorrect signing lineage flags, expected: %q, got: %q", expectedLineageFlag, lineageFlag)
+ }
signingFlag := signedApk.Args["certificates"]
expected := "build/make/target/product/security/platform.x509.pem build/make/target/product/security/platform.pk8"
if expected != signingFlag {
diff --git a/java/builder.go b/java/builder.go
index b6cb2ae..640dba9 100644
--- a/java/builder.go
+++ b/java/builder.go
@@ -40,17 +40,17 @@
// (if the rule produces .class files) or a .srcjar file (if the rule produces .java files).
// .srcjar files are unzipped into a temporary directory when compiled with javac.
// TODO(b/143658984): goma can't handle the --system argument to javac.
- javac, javacRE = remoteexec.StaticRules(pctx, "javac",
+ javac, javacRE = remoteexec.MultiCommandStaticRules(pctx, "javac",
blueprint.RuleParams{
Command: `rm -rf "$outDir" "$annoDir" "$srcJarDir" && mkdir -p "$outDir" "$annoDir" "$srcJarDir" && ` +
`${config.ZipSyncCmd} -d $srcJarDir -l $srcJarDir/list -f "*.java" $srcJars && ` +
`(if [ -s $srcJarDir/list ] || [ -s $out.rsp ] ; then ` +
- `${config.SoongJavacWrapper} $reTemplate${config.JavacCmd} ` +
+ `${config.SoongJavacWrapper} $javaTemplate${config.JavacCmd} ` +
`${config.JavacHeapFlags} ${config.JavacVmFlags} ${config.CommonJdkFlags} ` +
`$processorpath $processor $javacFlags $bootClasspath $classpath ` +
`-source $javaVersion -target $javaVersion ` +
`-d $outDir -s $annoDir @$out.rsp @$srcJarDir/list ; fi ) && ` +
- `${config.SoongZipCmd} -jar -o $out -C $outDir -D $outDir && ` +
+ `$zipTemplate${config.SoongZipCmd} -jar -o $out -C $outDir -D $outDir && ` +
`rm -rf "$srcJarDir"`,
CommandDeps: []string{
"${config.JavacCmd}",
@@ -60,10 +60,19 @@
CommandOrderOnly: []string{"${config.SoongJavacWrapper}"},
Rspfile: "$out.rsp",
RspfileContent: "$in",
- }, &remoteexec.REParams{
- Labels: map[string]string{"type": "compile", "lang": "java", "compiler": "javac"},
- ExecStrategy: "${config.REJavacExecStrategy}",
- Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ }, map[string]*remoteexec.REParams{
+ "$javaTemplate": &remoteexec.REParams{
+ Labels: map[string]string{"type": "compile", "lang": "java", "compiler": "javac"},
+ ExecStrategy: "${config.REJavacExecStrategy}",
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ "$zipTemplate": &remoteexec.REParams{
+ Labels: map[string]string{"type": "tool", "name": "soong_zip"},
+ Inputs: []string{"${config.SoongZipCmd}", "$outDir"},
+ OutputFiles: []string{"$out"},
+ ExecStrategy: "${config.REJavacExecStrategy}",
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
}, []string{"javacFlags", "bootClasspath", "classpath", "processorpath", "processor", "srcJars", "srcJarDir",
"outDir", "annoDir", "javaVersion"}, nil)
@@ -144,23 +153,35 @@
Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
}, []string{"javacFlags", "bootClasspath", "classpath", "srcJars", "outDir", "javaVersion"}, []string{"implicits"})
- jar = pctx.AndroidStaticRule("jar",
+ jar, jarRE = remoteexec.StaticRules(pctx, "jar",
blueprint.RuleParams{
- Command: `${config.SoongZipCmd} -jar -o $out @$out.rsp`,
+ Command: `$reTemplate${config.SoongZipCmd} -jar -o $out @$out.rsp`,
CommandDeps: []string{"${config.SoongZipCmd}"},
Rspfile: "$out.rsp",
RspfileContent: "$jarArgs",
},
- "jarArgs")
+ &remoteexec.REParams{
+ ExecStrategy: "${config.REJarExecStrategy}",
+ Inputs: []string{"${config.SoongZipCmd}", "${out}.rsp"},
+ RSPFile: "${out}.rsp",
+ OutputFiles: []string{"$out"},
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ }, []string{"jarArgs"}, nil)
- zip = pctx.AndroidStaticRule("zip",
+ zip, zipRE = remoteexec.StaticRules(pctx, "zip",
blueprint.RuleParams{
Command: `${config.SoongZipCmd} -o $out @$out.rsp`,
CommandDeps: []string{"${config.SoongZipCmd}"},
Rspfile: "$out.rsp",
RspfileContent: "$jarArgs",
},
- "jarArgs")
+ &remoteexec.REParams{
+ ExecStrategy: "${config.REZipExecStrategy}",
+ Inputs: []string{"${config.SoongZipCmd}", "${out}.rsp", "$implicits"},
+ RSPFile: "${out}.rsp",
+ OutputFiles: []string{"$out"},
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ }, []string{"jarArgs"}, []string{"implicits"})
combineJar = pctx.AndroidStaticRule("combineJar",
blueprint.RuleParams{
@@ -185,7 +206,7 @@
blueprint.RuleParams{
Command: "rm -f $out && " +
"${config.PackageCheckCmd} $in $packages && " +
- "touch $out",
+ "cp $in $out",
CommandDeps: []string{"${config.PackageCheckCmd}"},
},
"packages")
@@ -457,8 +478,12 @@
func TransformResourcesToJar(ctx android.ModuleContext, outputFile android.WritablePath,
jarArgs []string, deps android.Paths) {
+ rule := jar
+ if ctx.Config().IsEnvTrue("RBE_JAR") {
+ rule = jarRE
+ }
ctx.Build(pctx, android.BuildParams{
- Rule: jar,
+ Rule: rule,
Description: "jar",
Output: outputFile,
Implicits: deps,
@@ -522,8 +547,9 @@
})
}
-func CheckJarPackages(ctx android.ModuleContext, outputFile android.WritablePath,
- classesJar android.Path, permittedPackages []string) {
+func CheckJarPackages(ctx android.ModuleContext, classesJar android.Path, permittedPackages []string) android.ModuleOutPath {
+ outputFile := android.PathForModuleOut(ctx, "package-check", classesJar.Base())
+
ctx.Build(pctx, android.BuildParams{
Rule: packageCheck,
Description: "packageCheck",
@@ -533,6 +559,8 @@
"packages": strings.Join(permittedPackages, " "),
},
})
+
+ return outputFile
}
func TransformJetifier(ctx android.ModuleContext, outputFile android.WritablePath,
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/config/config.go b/java/config/config.go
index fa19afb..edaed2a 100644
--- a/java/config/config.go
+++ b/java/config/config.go
@@ -149,6 +149,9 @@
pctx.VariableFunc("RED8ExecStrategy", remoteexec.EnvOverrideFunc("RBE_D8_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
pctx.VariableFunc("RER8ExecStrategy", remoteexec.EnvOverrideFunc("RBE_R8_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
pctx.VariableFunc("RETurbineExecStrategy", remoteexec.EnvOverrideFunc("RBE_TURBINE_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
+ pctx.VariableFunc("RESignApkExecStrategy", remoteexec.EnvOverrideFunc("RBE_SIGNAPK_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
+ pctx.VariableFunc("REJarExecStrategy", remoteexec.EnvOverrideFunc("RBE_JAR_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
+ pctx.VariableFunc("REZipExecStrategy", remoteexec.EnvOverrideFunc("RBE_ZIP_EXEC_STRATEGY", remoteexec.LocalExecStrategy))
pctx.HostJavaToolVariable("JacocoCLIJar", "jacoco-cli.jar")
diff --git a/java/dex.go b/java/dex.go
index 27ec6ee..9e61e95 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -18,53 +18,72 @@
"strings"
"github.com/google/blueprint"
+ "github.com/google/blueprint/proptools"
"android/soong/android"
"android/soong/remoteexec"
)
-var d8, d8RE = remoteexec.StaticRules(pctx, "d8",
+var d8, d8RE = remoteexec.MultiCommandStaticRules(pctx, "d8",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
- `$reTemplate${config.D8Cmd} ${config.DexFlags} --output $outDir $d8Flags $in && ` +
- `${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
+ `$d8Template${config.D8Cmd} ${config.DexFlags} --output $outDir $d8Flags $in && ` +
+ `$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
`${config.MergeZipsCmd} -D -stripFile "**/*.class" $out $outDir/classes.dex.jar $in`,
CommandDeps: []string{
"${config.D8Cmd}",
"${config.SoongZipCmd}",
"${config.MergeZipsCmd}",
},
- }, &remoteexec.REParams{
- Labels: map[string]string{"type": "compile", "compiler": "d8"},
- Inputs: []string{"${config.D8Jar}"},
- ExecStrategy: "${config.RED8ExecStrategy}",
- ToolchainInputs: []string{"${config.JavaCmd}"},
- Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ }, map[string]*remoteexec.REParams{
+ "$d8Template": &remoteexec.REParams{
+ Labels: map[string]string{"type": "compile", "compiler": "d8"},
+ Inputs: []string{"${config.D8Jar}"},
+ ExecStrategy: "${config.RED8ExecStrategy}",
+ ToolchainInputs: []string{"${config.JavaCmd}"},
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ "$zipTemplate": &remoteexec.REParams{
+ Labels: map[string]string{"type": "tool", "name": "soong_zip"},
+ Inputs: []string{"${config.SoongZipCmd}", "$outDir"},
+ OutputFiles: []string{"$outDir/classes.dex.jar"},
+ ExecStrategy: "${config.RED8ExecStrategy}",
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
}, []string{"outDir", "d8Flags", "zipFlags"}, nil)
-var r8, r8RE = remoteexec.StaticRules(pctx, "r8",
+var r8, r8RE = remoteexec.MultiCommandStaticRules(pctx, "r8",
blueprint.RuleParams{
Command: `rm -rf "$outDir" && mkdir -p "$outDir" && ` +
`rm -f "$outDict" && ` +
- `$reTemplate${config.R8Cmd} ${config.DexFlags} -injars $in --output $outDir ` +
+ `$r8Template${config.R8Cmd} ${config.DexFlags} -injars $in --output $outDir ` +
`--force-proguard-compatibility ` +
`--no-data-resources ` +
`-printmapping $outDict ` +
`$r8Flags && ` +
`touch "$outDict" && ` +
- `${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
+ `$zipTemplate${config.SoongZipCmd} $zipFlags -o $outDir/classes.dex.jar -C $outDir -f "$outDir/classes*.dex" && ` +
`${config.MergeZipsCmd} -D -stripFile "**/*.class" $out $outDir/classes.dex.jar $in`,
CommandDeps: []string{
"${config.R8Cmd}",
"${config.SoongZipCmd}",
"${config.MergeZipsCmd}",
},
- }, &remoteexec.REParams{
- Labels: map[string]string{"type": "compile", "compiler": "r8"},
- Inputs: []string{"$implicits", "${config.R8Jar}"},
- ExecStrategy: "${config.RER8ExecStrategy}",
- ToolchainInputs: []string{"${config.JavaCmd}"},
- Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ }, map[string]*remoteexec.REParams{
+ "$r8Template": &remoteexec.REParams{
+ Labels: map[string]string{"type": "compile", "compiler": "r8"},
+ Inputs: []string{"$implicits", "${config.R8Jar}"},
+ ExecStrategy: "${config.RER8ExecStrategy}",
+ ToolchainInputs: []string{"${config.JavaCmd}"},
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
+ "$zipTemplate": &remoteexec.REParams{
+ Labels: map[string]string{"type": "tool", "name": "soong_zip"},
+ Inputs: []string{"${config.SoongZipCmd}", "$outDir"},
+ OutputFiles: []string{"$outDir/classes.dex.jar"},
+ ExecStrategy: "${config.RER8ExecStrategy}",
+ Platform: map[string]string{remoteexec.PoolKey: "${config.REJavaPool}"},
+ },
}, []string{"outDir", "outDict", "r8Flags", "zipFlags"}, []string{"implicits"})
func (j *Module) dexCommonFlags(ctx android.ModuleContext) []string {
@@ -188,7 +207,7 @@
outDir := android.PathForModuleOut(ctx, "dex")
zipFlags := "--ignore_missing_files"
- if j.deviceProperties.UncompressDex {
+ if proptools.Bool(j.deviceProperties.Uncompress_dex) {
zipFlags += " -L 0"
}
@@ -235,7 +254,7 @@
},
})
}
- if j.deviceProperties.UncompressDex {
+ if proptools.Bool(j.deviceProperties.Uncompress_dex) {
alignedJavalibJar := android.PathForModuleOut(ctx, "aligned", jarName)
TransformZipAlign(ctx, alignedJavalibJar, javalibJar)
javalibJar = alignedJavalibJar
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index 90457d0..ed61d4b 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -619,10 +619,10 @@
// Collect `permitted_packages` for updatable boot jars.
var updatablePackages []string
ctx.VisitAllModules(func(module android.Module) {
- if j, ok := module.(*Library); ok {
+ if j, ok := module.(PermittedPackagesForUpdatableBootJars); ok {
name := ctx.ModuleName(module)
if i := android.IndexList(name, updatableModules); i != -1 {
- pp := j.properties.Permitted_packages
+ pp := j.PermittedPackagesForUpdatableBootJars()
if len(pp) > 0 {
updatablePackages = append(updatablePackages, pp...)
} else {
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 821bb6d..b16c9cd 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -376,6 +376,7 @@
srcFiles android.Paths
sourcepaths android.Paths
argFiles android.Paths
+ implicits android.Paths
args string
@@ -575,6 +576,7 @@
// do not pass exclude_srcs directly when expanding srcFiles since exclude_srcs
// may contain filegroup or genrule.
srcFiles := android.PathsForModuleSrcExcludes(ctx, j.properties.Srcs, j.properties.Exclude_srcs)
+ j.implicits = append(j.implicits, srcFiles...)
filterByPackage := func(srcs []android.Path, filterPackages []string) []android.Path {
if filterPackages == nil {
@@ -600,6 +602,24 @@
}
srcFiles = filterByPackage(srcFiles, j.properties.Filter_packages)
+ // While metalava needs package html files, it does not need them to be explicit on the command
+ // line. More importantly, the metalava rsp file is also used by the subsequent jdiff action if
+ // jdiff_enabled=true. javadoc complains if it receives html files on the command line. The filter
+ // below excludes html files from the rsp file for both metalava and jdiff. Note that the html
+ // files are still included as implicit inputs for successful remote execution and correct
+ // incremental builds.
+ filterHtml := func(srcs []android.Path) []android.Path {
+ filtered := []android.Path{}
+ for _, src := range srcs {
+ if src.Ext() == ".html" {
+ continue
+ }
+ filtered = append(filtered, src)
+ }
+ return filtered
+ }
+ srcFiles = filterHtml(srcFiles)
+
flags := j.collectAidlFlags(ctx, deps)
srcFiles = j.genSources(ctx, srcFiles, flags)
@@ -1402,10 +1422,26 @@
}
func metalavaCmd(ctx android.ModuleContext, rule *android.RuleBuilder, javaVersion javaVersion, srcs android.Paths,
- srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths) *android.RuleBuilderCommand {
+ srcJarList android.Path, bootclasspath, classpath classpath, sourcepaths android.Paths, implicits android.Paths) *android.RuleBuilderCommand {
// Metalava uses lots of memory, restrict the number of metalava jobs that can run in parallel.
rule.HighMem()
cmd := rule.Command()
+
+ rspFile := ""
+ if len(implicits) > 0 {
+ implicitsRsp := android.PathForModuleOut(ctx, ctx.ModuleName()+"-"+"implicits.rsp")
+ rspFile = implicitsRsp.String()
+ impRule := android.NewRuleBuilder()
+ impCmd := impRule.Command()
+ // A dummy action that copies the ninja generated rsp file to a new location. This allows us to
+ // add a large number of inputs to a file without exceeding bash command length limits (which
+ // would happen if we use the WriteFile rule). The cp is needed because RuleBuilder sets the
+ // rsp file to be ${output}.rsp.
+ impCmd.Text("cp").FlagWithRspFileInputList("", implicits).Output(implicitsRsp)
+ impRule.Build(pctx, ctx, "implicitsGen", "implicits generation")
+ cmd.Implicits(implicits)
+ cmd.Implicit(implicitsRsp)
+ }
if ctx.Config().IsEnvTrue("RBE_METALAVA") {
rule.Remoteable(android.RemoteRuleSupports{RBE: true})
execStrategy := remoteexec.LocalExecStrategy
@@ -1417,7 +1453,6 @@
pool = v
}
inputs := []string{android.PathForOutput(ctx, "host", ctx.Config().PrebuiltOS(), "framework", "metalava.jar").String()}
- inputs = append(inputs, sourcepaths.Strings()...)
if v := ctx.Config().Getenv("RBE_METALAVA_INPUTS"); v != "" {
inputs = append(inputs, strings.Split(v, ",")...)
}
@@ -1425,6 +1460,7 @@
Labels: map[string]string{"type": "compile", "lang": "java", "compiler": "metalava"},
ExecStrategy: execStrategy,
Inputs: inputs,
+ RSPFile: rspFile,
ToolchainInputs: []string{config.JavaCmd(ctx).String()},
Platform: map[string]string{remoteexec.PoolKey: pool},
}).NoVarTemplate(ctx.Config()))
@@ -1482,7 +1518,7 @@
srcJarList := zipSyncCmd(ctx, rule, srcJarDir, d.Javadoc.srcJars)
cmd := metalavaCmd(ctx, rule, javaVersion, d.Javadoc.srcFiles, srcJarList,
- deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths)
+ deps.bootClasspath, deps.classpath, d.Javadoc.sourcepaths, d.Javadoc.implicits)
d.stubsFlags(ctx, cmd, stubsDir)
diff --git a/java/java.go b/java/java.go
index dedbf47..09df2ad 100644
--- a/java/java.go
+++ b/java/java.go
@@ -342,8 +342,13 @@
// set the name of the output
Stem *string
- UncompressDex bool `blueprint:"mutated"`
- IsSDKLibrary bool `blueprint:"mutated"`
+ // Keep the data uncompressed. We always need uncompressed dex for execution,
+ // so this might actually save space by avoiding storing the same data twice.
+ // This defaults to reasonable value based on module and should not be set.
+ // It exists only to support ART tests.
+ Uncompress_dex *bool
+
+ IsSDKLibrary bool `blueprint:"mutated"`
}
func (me *CompilerDeviceProperties) EffectiveOptimizeEnabled() bool {
@@ -458,9 +463,6 @@
// expanded Jarjar_rules
expandJarjarRules android.Path
- // list of additional targets for checkbuild
- additionalCheckedModules android.Paths
-
// Extra files generated by the module type to be added as java resources.
extraResources android.Paths
@@ -1451,13 +1453,19 @@
serviceFile := file.String()
zipargs = append(zipargs, "-C", filepath.Dir(serviceFile), "-f", serviceFile)
}
+ rule := zip
+ args := map[string]string{
+ "jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscapeList(zipargs), " "),
+ }
+ if ctx.Config().IsEnvTrue("RBE_ZIP") {
+ rule = zipRE
+ args["implicits"] = strings.Join(services.Strings(), ",")
+ }
ctx.Build(pctx, android.BuildParams{
- Rule: zip,
+ Rule: rule,
Output: servicesJar,
Implicits: services,
- Args: map[string]string{
- "jarArgs": "-P META-INF/services/ " + strings.Join(proptools.NinjaAndShellEscapeList(zipargs), " "),
- },
+ Args: args,
})
jars = append(jars, servicesJar)
}
@@ -1510,10 +1518,10 @@
// Check package restrictions if necessary.
if len(j.properties.Permitted_packages) > 0 {
- // Check packages and copy to package-checked file.
- pkgckFile := android.PathForModuleOut(ctx, "package-check.stamp")
- CheckJarPackages(ctx, pkgckFile, outputFile, j.properties.Permitted_packages)
- j.additionalCheckedModules = append(j.additionalCheckedModules, pkgckFile)
+ // Check packages and copy input to package-checked file.
+ // Use the file copied after a successful package check as the output file for this
+ // module so that any dependencies on this module will trigger the package check.
+ outputFile = CheckJarPackages(ctx, outputFile, j.properties.Permitted_packages)
if ctx.Failed() {
return
@@ -1570,7 +1578,7 @@
// Hidden API CSV generation and dex encoding
dexOutputFile = j.hiddenAPI.hiddenAPI(ctx, dexOutputFile, j.implementationJarFile,
- j.deviceProperties.UncompressDex)
+ proptools.Bool(j.deviceProperties.Uncompress_dex))
// merge dex jar with resources if necessary
if j.resourceJar != nil {
@@ -1578,7 +1586,7 @@
combinedJar := android.PathForModuleOut(ctx, "dex-withres", jarName)
TransformJarsToJar(ctx, combinedJar, "for dex resources", jars, android.OptionalPath{},
false, nil, nil)
- if j.deviceProperties.UncompressDex {
+ if *j.deviceProperties.Uncompress_dex {
combinedAlignedJar := android.PathForModuleOut(ctx, "dex-withres-aligned", jarName)
TransformZipAlign(ctx, combinedAlignedJar, combinedJar)
dexOutputFile = combinedAlignedJar
@@ -1829,6 +1837,17 @@
InstallMixin func(ctx android.ModuleContext, installPath android.Path) (extraInstallDeps android.Paths)
}
+// Provides access to the list of permitted packages from updatable boot jars.
+type PermittedPackagesForUpdatableBootJars interface {
+ PermittedPackagesForUpdatableBootJars() []string
+}
+
+var _ PermittedPackagesForUpdatableBootJars = (*Library)(nil)
+
+func (j *Library) PermittedPackagesForUpdatableBootJars() []string {
+ return j.properties.Permitted_packages
+}
+
func shouldUncompressDex(ctx android.ModuleContext, dexpreopter *dexpreopter) bool {
// Store uncompressed (and aligned) any dex files from jars in APEXes.
if am, ok := ctx.Module().(android.ApexModule); ok && !am.IsForPlatform() {
@@ -1856,8 +1875,11 @@
j.checkSdkVersions(ctx)
j.dexpreopter.installPath = android.PathForModuleInstall(ctx, "framework", j.Stem()+".jar")
j.dexpreopter.isSDKLibrary = j.deviceProperties.IsSDKLibrary
- j.dexpreopter.uncompressedDex = shouldUncompressDex(ctx, &j.dexpreopter)
- j.deviceProperties.UncompressDex = j.dexpreopter.uncompressedDex
+ if j.deviceProperties.Uncompress_dex == nil {
+ // If the value was not force-set by the user, use reasonable default based on the module.
+ j.deviceProperties.Uncompress_dex = proptools.BoolPtr(shouldUncompressDex(ctx, &j.dexpreopter))
+ }
+ j.dexpreopter.uncompressedDex = *j.deviceProperties.Uncompress_dex
j.compile(ctx, nil)
// Collect the module directory for IDE info in java/jdeps.go.
@@ -1870,7 +1892,7 @@
extraInstallDeps = j.InstallMixin(ctx, j.outputFile)
}
j.installFile = ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
- ctx.ModuleName()+".jar", j.outputFile, extraInstallDeps...)
+ j.Stem()+".jar", j.outputFile, extraInstallDeps...)
}
// Verify Dist.Tag is set to a supported output
@@ -2720,7 +2742,7 @@
j.maybeStrippedDexJarFile = dexOutputFile
ctx.InstallFile(android.PathForModuleInstall(ctx, "framework"),
- ctx.ModuleName()+".jar", dexOutputFile)
+ j.Stem()+".jar", dexOutputFile)
}
func (j *DexImport) DexJar() android.Path {
diff --git a/java/java_test.go b/java/java_test.go
index e03e57b..8ea34d9 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1038,7 +1038,7 @@
for _, i := range metalavaRule.Implicits {
systemJars = append(systemJars, i.Base())
}
- if len(systemJars) != 1 || systemJars[0] != systemJar {
+ if len(systemJars) < 1 || systemJars[0] != systemJar {
t.Errorf("inputs of %q must be []string{%q}, but was %#v.", moduleName, systemJar, systemJars)
}
}
@@ -1465,6 +1465,33 @@
`)
}
+func TestJavaSdkLibrary_DefaultToStubs(t *testing.T) {
+ ctx, _ := testJava(t, `
+ java_sdk_library {
+ name: "foo",
+ srcs: ["a.java"],
+ system: {
+ enabled: true,
+ },
+ default_to_stubs: true,
+ }
+
+ java_library {
+ name: "baz",
+ srcs: ["a.java"],
+ libs: ["foo"],
+ // does not have sdk_version set, should fallback to module,
+ // which will then fallback to system because the module scope
+ // is not enabled.
+ }
+ `)
+ // The baz library should depend on the system stubs jar.
+ bazLibrary := ctx.ModuleForTests("baz", "android_common").Rule("javac")
+ if expected, actual := `^-classpath .*:/[^:]*/turbine-combined/foo\.stubs.system\.jar$`, bazLibrary.Args["classpath"]; !regexp.MustCompile(expected).MatchString(actual) {
+ t.Errorf("expected %q, found %#q", expected, actual)
+ }
+}
+
var compilerFlagsTestCases = []struct {
in string
out bool
diff --git a/java/sdk_library.go b/java/sdk_library.go
index b487efd..67b0bd6 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -348,6 +348,10 @@
}
type sdkLibraryProperties struct {
+ // Visibility for impl library module. If not specified then defaults to the
+ // visibility property.
+ Impl_library_visibility []string
+
// Visibility for stubs library modules. If not specified then defaults to the
// visibility property.
Stubs_library_visibility []string
@@ -431,6 +435,14 @@
// disabled by default.
Module_lib ApiScopeProperties
+ // Determines if the stubs are preferred over the implementation library
+ // for linking, even when the client doesn't specify sdk_version. When this
+ // is set to true, such clients are provided with the widest API surface that
+ // this lib provides. Note however that this option doesn't affect the clients
+ // that are in the same APEX as this library. In that case, the clients are
+ // always linked with the implementation library. Default is false.
+ Default_to_stubs *bool
+
// Properties related to api linting.
Api_lint struct {
// Enable api linting.
@@ -910,6 +922,8 @@
return false
}
+var implLibraryTag = dependencyTag{name: "impl-library"}
+
func (module *SdkLibrary) DepsMutator(ctx android.BottomUpMutatorContext) {
for _, apiScope := range module.getGeneratedApiScopes(ctx) {
// Add dependencies to the stubs library
@@ -928,6 +942,9 @@
}
if module.requiresRuntimeImplementationLibrary() {
+ // Add dependency to the rule for generating the implementation library.
+ ctx.AddDependency(module, implLibraryTag, module.implLibraryModuleName())
+
if module.sharedLibrary() {
// Add dependency to the rule for generating the xml permissions file
ctx.AddDependency(module, xmlPermissionsFileTag, module.xmlFileName())
@@ -982,8 +999,8 @@
}
// Module name of the runtime implementation library
-func (module *SdkLibrary) implName() string {
- return module.BaseModuleName()
+func (module *SdkLibrary) implLibraryModuleName() string {
+ return module.BaseModuleName() + ".impl"
}
// Module name of the XML file for the lib
@@ -1027,6 +1044,27 @@
return ":" + module.BaseModuleName() + "-removed.api." + apiScope.name + ".latest"
}
+// Creates the implementation java library
+func (module *SdkLibrary) createImplLibrary(mctx android.DefaultableHookContext) {
+ props := struct {
+ Name *string
+ Visibility []string
+ }{
+ Name: proptools.StringPtr(module.implLibraryModuleName()),
+ Visibility: module.sdkLibraryProperties.Impl_library_visibility,
+ }
+
+ properties := []interface{}{
+ &module.properties,
+ &module.protoProperties,
+ &module.deviceProperties,
+ &module.dexpreoptProperties,
+ &props,
+ module.sdkComponentPropertiesForChildLibrary(),
+ }
+ mctx.CreateModule(LibraryFactory, properties...)
+}
+
// Creates a static java library that has API stubs
func (module *SdkLibrary) createStubsLibrary(mctx android.DefaultableHookContext, apiScope *apiScope) {
props := struct {
@@ -1312,6 +1350,13 @@
}
func (module *SdkLibrary) sdkJars(ctx android.BaseModuleContext, sdkVersion sdkSpec, headerJars bool) android.Paths {
+ // If the client doesn't set sdk_version, but if this library prefers stubs over
+ // the impl library, let's provide the widest API surface possible. To do so,
+ // force override sdk_version to module_current so that the closest possible API
+ // surface could be found in selectHeaderJarsForSdkVersion
+ if module.defaultsToStubs() && !sdkVersion.specified() {
+ sdkVersion = sdkSpecFrom("module_current")
+ }
// Only provide access to the implementation library if it is actually built.
if module.requiresRuntimeImplementationLibrary() {
@@ -1434,6 +1479,14 @@
}
if module.requiresRuntimeImplementationLibrary() {
+ // Create child module to create an implementation library.
+ //
+ // This temporarily creates a second implementation library that can be explicitly
+ // referenced.
+ //
+ // TODO(b/156618935) - update comment once only one implementation library is created.
+ module.createImplLibrary(mctx)
+
// Only create an XML permissions file that declares the library as being usable
// as a shared library if required.
if module.sharedLibrary() {
@@ -1467,6 +1520,10 @@
return !proptools.Bool(module.sdkLibraryProperties.Api_only)
}
+func (module *SdkLibrary) defaultsToStubs() bool {
+ return proptools.Bool(module.sdkLibraryProperties.Default_to_stubs)
+}
+
// Defines how to name the individual component modules the sdk library creates.
type sdkLibraryComponentNamingScheme interface {
stubsLibraryModuleName(scope *apiScope, baseName string) string
@@ -1541,6 +1598,7 @@
module.scopeToProperties = scopeToProperties
// Add the properties containing visibility rules so that they are checked.
+ android.AddVisibilityProperty(module, "impl_library_visibility", &module.sdkLibraryProperties.Impl_library_visibility)
android.AddVisibilityProperty(module, "stubs_library_visibility", &module.sdkLibraryProperties.Stubs_library_visibility)
android.AddVisibilityProperty(module, "stubs_source_visibility", &module.sdkLibraryProperties.Stubs_source_visibility)
@@ -1948,6 +2006,10 @@
// The naming scheme.
Naming_scheme *string
+
+ // True if the java_sdk_library_import is for a shared library, false
+ // otherwise.
+ Shared_library *bool
}
type scopeProperties struct {
@@ -1982,12 +2044,16 @@
s.Libs = sdk.properties.Libs
s.Naming_scheme = sdk.commonSdkLibraryProperties.Naming_scheme
+ s.Shared_library = proptools.BoolPtr(sdk.sharedLibrary())
}
func (s *sdkLibrarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
if s.Naming_scheme != nil {
propertySet.AddProperty("naming_scheme", proptools.String(s.Naming_scheme))
}
+ if s.Shared_library != nil {
+ propertySet.AddProperty("shared_library", *s.Shared_library)
+ }
for _, apiScope := range allApiScopes {
if properties, ok := s.Scopes[apiScope]; ok {
@@ -2017,7 +2083,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/testing.go b/java/testing.go
index 1967148..faf4d32 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -230,6 +230,22 @@
system_modules: "core-platform-api-stubs-system-modules",
installable: true,
}
+
+ java_library {
+ name: "android.test.base",
+ srcs: ["a.java"],
+ sdk_version: "none",
+ system_modules: "core-platform-api-stubs-system-modules",
+ installable: true,
+ }
+
+ java_library {
+ name: "android.test.mock",
+ srcs: ["a.java"],
+ sdk_version: "none",
+ system_modules: "core-platform-api-stubs-system-modules",
+ installable: true,
+ }
`
systemModules := []string{
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/remoteexec/remoteexec.go b/remoteexec/remoteexec.go
index 2b513b2..d6e2c0a 100644
--- a/remoteexec/remoteexec.go
+++ b/remoteexec/remoteexec.go
@@ -75,8 +75,8 @@
// OutputFiles is a list of output file paths or ninja variables as placeholders for rule
// outputs.
OutputFiles []string
- // OutputDirectories is a list of output directory paths or ninja variables as placeholders
- // for rule outputs.
+ // OutputDirectories is a list of output directories or ninja variables as placeholders for
+ // rule output directories.
OutputDirectories []string
// ToolchainInputs is a list of paths or ninja variables pointing to the location of
// toolchain binaries used by the rule.
@@ -102,7 +102,7 @@
return "${remoteexec.Wrapper}" + r.wrapperArgs()
}
-// NoVarTemplate generate the remote execution wrapper template without variables, to be used in
+// NoVarTemplate generates the remote execution wrapper template without variables, to be used in
// RuleBuilder.
func (r *REParams) NoVarTemplate(cfg android.Config) string {
return wrapper(cfg) + r.wrapperArgs()
@@ -178,6 +178,22 @@
ctx.AndroidRemoteStaticRule(name+"RE", android.RemoteRuleSupports{RBE: true}, ruleParamsRE, append(commonArgs, reArgs...)...)
}
+// MultiCommandStaticRules returns a pair of rules based on the given RuleParams, where the first
+// rule is a locally executable rule and the second rule is a remotely executable rule. This
+// function supports multiple remote execution wrappers placed in the template when commands are
+// chained together with &&. commonArgs are args used for both the local and remotely executable
+// rules. reArgs are args used only for remote execution.
+func MultiCommandStaticRules(ctx android.PackageContext, name string, ruleParams blueprint.RuleParams, reParams map[string]*REParams, commonArgs []string, reArgs []string) (blueprint.Rule, blueprint.Rule) {
+ ruleParamsRE := ruleParams
+ for k, v := range reParams {
+ ruleParams.Command = strings.ReplaceAll(ruleParams.Command, k, "")
+ ruleParamsRE.Command = strings.ReplaceAll(ruleParamsRE.Command, k, v.Template())
+ }
+
+ return ctx.AndroidStaticRule(name, ruleParams, commonArgs...),
+ ctx.AndroidRemoteStaticRule(name+"RE", android.RemoteRuleSupports{RBE: true}, ruleParamsRE, append(commonArgs, reArgs...)...)
+}
+
// EnvOverrideFunc retrieves a variable func that evaluates to the value of the given environment
// variable if set, otherwise the given default.
func EnvOverrideFunc(envVar, defaultVal string) func(ctx android.PackageVarContext) string {
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/rust/config/x86_darwin_host.go b/rust/config/x86_darwin_host.go
index 7cfc59c..4c16693 100644
--- a/rust/config/x86_darwin_host.go
+++ b/rust/config/x86_darwin_host.go
@@ -62,7 +62,11 @@
return "x86_64-apple-darwin"
}
-func (t *toolchainDarwin) ShlibSuffix() string {
+func (t *toolchainDarwin) SharedLibSuffix() string {
+ return ".dylib"
+}
+
+func (t *toolchainDarwin) ProcMacroSuffix() string {
return ".dylib"
}
diff --git a/scripts/package-check.sh b/scripts/package-check.sh
index f982e82..d7e602f 100755
--- a/scripts/package-check.sh
+++ b/scripts/package-check.sh
@@ -52,6 +52,7 @@
# Check all class file names against the expected prefixes.
old_ifs=${IFS}
IFS=$'\n'
+failed=false
for zip_entry in ${zip_contents}; do
# Check the suffix.
if [[ "${zip_entry}" = *.class ]]; then
@@ -65,8 +66,11 @@
done
if [[ "${found}" == "false" ]]; then
echo "Class file ${zip_entry} is outside specified packages."
- exit 1
+ failed=true
fi
fi
done
+if [[ "${failed}" == "true" ]]; then
+ exit 1
+fi
IFS=${old_ifs}
diff --git a/sdk/Android.bp b/sdk/Android.bp
new file mode 100644
index 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/cc_sdk_test.go b/sdk/cc_sdk_test.go
index dded153..4a09081 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -401,7 +401,6 @@
"Test.cpp",
],
compile_multilib: "both",
- stl: "none",
}
`)
@@ -494,6 +493,7 @@
device_supported: false,
host_supported: true,
installable: false,
+ stl: "none",
target: {
linux_glibc: {
compile_multilib: "both",
@@ -518,6 +518,7 @@
prefer: false,
device_supported: false,
host_supported: true,
+ stl: "none",
target: {
linux_glibc: {
compile_multilib: "both",
@@ -557,6 +558,90 @@
)
}
+// Test that we support the necessary flags for the linker binary, which is
+// special in several ways.
+func TestSnapshotWithCcStaticNocrtBinary(t *testing.T) {
+ // b/145598135 - Generating host snapshots for anything other than linux is not supported.
+ SkipIfNotLinux(t)
+
+ result := testSdkWithCc(t, `
+ module_exports {
+ name: "mymodule_exports",
+ host_supported: true,
+ device_supported: false,
+ native_binaries: ["linker"],
+ }
+
+ cc_binary {
+ name: "linker",
+ host_supported: true,
+ static_executable: true,
+ nocrt: true,
+ stl: "none",
+ srcs: [
+ "Test.cpp",
+ ],
+ compile_multilib: "both",
+ }
+ `)
+
+ result.CheckSnapshot("mymodule_exports", "",
+ checkAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_binary {
+ name: "mymodule_exports_linker@current",
+ sdk_member_name: "linker",
+ device_supported: false,
+ host_supported: true,
+ installable: false,
+ stl: "none",
+ static_executable: true,
+ nocrt: true,
+ compile_multilib: "both",
+ arch: {
+ x86_64: {
+ srcs: ["x86_64/bin/linker"],
+ },
+ x86: {
+ srcs: ["x86/bin/linker"],
+ },
+ },
+}
+
+cc_prebuilt_binary {
+ name: "linker",
+ prefer: false,
+ device_supported: false,
+ host_supported: true,
+ stl: "none",
+ static_executable: true,
+ nocrt: true,
+ compile_multilib: "both",
+ arch: {
+ x86_64: {
+ srcs: ["x86_64/bin/linker"],
+ },
+ x86: {
+ srcs: ["x86/bin/linker"],
+ },
+ },
+}
+
+module_exports_snapshot {
+ name: "mymodule_exports@current",
+ device_supported: false,
+ host_supported: true,
+ native_binaries: ["mymodule_exports_linker@current"],
+}
+`),
+ checkAllCopyRules(`
+.intermediates/linker/linux_glibc_x86_64/linker -> x86_64/bin/linker
+.intermediates/linker/linux_glibc_x86/linker -> x86/bin/linker
+`),
+ )
+}
+
func TestSnapshotWithCcSharedLibrary(t *testing.T) {
result := testSdkWithCc(t, `
sdk {
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index bbd6384..af792f2 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -989,6 +989,7 @@
apex_available: ["//apex_available:anyapex"],
srcs: ["Test.java"],
sdk_version: "current",
+ shared_library: false,
stubs_library_visibility: ["//other"],
stubs_source_visibility: ["//another"],
}
@@ -1002,6 +1003,7 @@
name: "mysdk_myjavalib@current",
sdk_member_name: "myjavalib",
apex_available: ["//apex_available:anyapex"],
+ shared_library: false,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
@@ -1029,6 +1031,7 @@
name: "myjavalib",
prefer: false,
apex_available: ["//apex_available:anyapex"],
+ shared_library: false,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
@@ -1060,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",
@@ -1097,6 +1100,7 @@
java_sdk_library_import {
name: "mysdk_myjavalib@current",
sdk_member_name: "myjavalib",
+ shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
@@ -1109,6 +1113,7 @@
java_sdk_library_import {
name: "myjavalib",
prefer: false,
+ shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
@@ -1126,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",
@@ -1159,6 +1164,7 @@
java_sdk_library_import {
name: "mysdk_myjavalib@current",
sdk_member_name: "myjavalib",
+ shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
@@ -1171,6 +1177,7 @@
java_sdk_library_import {
name: "myjavalib",
prefer: false,
+ shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
@@ -1188,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",
@@ -1225,6 +1232,7 @@
name: "mysdk_myjavalib@current",
sdk_member_name: "myjavalib",
apex_available: ["//apex_available:anyapex"],
+ shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
@@ -1245,6 +1253,7 @@
name: "myjavalib",
prefer: false,
apex_available: ["//apex_available:anyapex"],
+ shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
@@ -1269,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",
@@ -1313,6 +1322,7 @@
name: "mysdk_myjavalib@current",
sdk_member_name: "myjavalib",
apex_available: ["//apex_available:anyapex"],
+ shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
@@ -1340,6 +1350,7 @@
name: "myjavalib",
prefer: false,
apex_available: ["//apex_available:anyapex"],
+ shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
@@ -1371,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",
@@ -1415,6 +1426,7 @@
sdk_member_name: "myjavalib",
apex_available: ["//apex_available:anyapex"],
naming_scheme: "framework-modules",
+ shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
@@ -1429,6 +1441,7 @@
prefer: false,
apex_available: ["//apex_available:anyapex"],
naming_scheme: "framework-modules",
+ shared_library: true,
public: {
jars: ["sdk_library/public/myjavalib-stubs.jar"],
stub_srcs: ["sdk_library/public/myjavalib_stub_sources"],
@@ -1446,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..0b04e7d
--- /dev/null
+++ b/sh/Android.bp
@@ -0,0 +1,16 @@
+bootstrap_go_package {
+ name: "soong-sh",
+ pkgPath: "android/soong/sh",
+ deps: [
+ "blueprint",
+ "soong",
+ "soong-android",
+ ],
+ srcs: [
+ "sh_binary.go",
+ ],
+ testSrcs: [
+ "sh_binary_test.go",
+ ],
+ pluginFor: ["soong_build"],
+}
diff --git a/android/sh_binary.go b/sh/sh_binary.go
similarity index 61%
rename from android/sh_binary.go
rename to sh/sh_binary.go
index 7d9dc67..2dcd716 100644
--- a/android/sh_binary.go
+++ b/sh/sh_binary.go
@@ -12,12 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-package android
+package sh
import (
"fmt"
"path/filepath"
"strings"
+
+ "github.com/google/blueprint/proptools"
+
+ "android/soong/android"
)
// sh_binary is for shell scripts (and batch files) that are installed as
@@ -26,11 +30,15 @@
// Do not use them for prebuilt C/C++/etc files. Use cc_prebuilt_binary
// instead.
+var pctx = android.NewPackageContext("android/soong/sh")
+
func init() {
- RegisterModuleType("sh_binary", ShBinaryFactory)
- RegisterModuleType("sh_binary_host", ShBinaryHostFactory)
- RegisterModuleType("sh_test", ShTestFactory)
- RegisterModuleType("sh_test_host", ShTestHostFactory)
+ pctx.Import("android/soong/android")
+
+ android.RegisterModuleType("sh_binary", ShBinaryFactory)
+ android.RegisterModuleType("sh_binary_host", ShBinaryHostFactory)
+ android.RegisterModuleType("sh_test", ShTestFactory)
+ android.RegisterModuleType("sh_test_host", ShTestHostFactory)
}
type shBinaryProperties struct {
@@ -69,55 +77,55 @@
}
type ShBinary struct {
- ModuleBase
+ android.ModuleBase
properties shBinaryProperties
- sourceFilePath Path
- outputFilePath OutputPath
- installedFile InstallPath
+ sourceFilePath android.Path
+ outputFilePath android.OutputPath
+ installedFile android.InstallPath
}
-var _ HostToolProvider = (*ShBinary)(nil)
+var _ android.HostToolProvider = (*ShBinary)(nil)
type ShTest struct {
ShBinary
testProperties TestProperties
- data Paths
+ data android.Paths
}
-func (s *ShBinary) HostToolPath() OptionalPath {
- return OptionalPathForPath(s.installedFile)
+func (s *ShBinary) HostToolPath() android.OptionalPath {
+ return android.OptionalPathForPath(s.installedFile)
}
-func (s *ShBinary) DepsMutator(ctx BottomUpMutatorContext) {
+func (s *ShBinary) DepsMutator(ctx android.BottomUpMutatorContext) {
if s.properties.Src == nil {
ctx.PropertyErrorf("src", "missing prebuilt source file")
}
}
-func (s *ShBinary) OutputFile() OutputPath {
+func (s *ShBinary) OutputFile() android.OutputPath {
return s.outputFilePath
}
func (s *ShBinary) SubDir() string {
- return String(s.properties.Sub_dir)
+ return proptools.String(s.properties.Sub_dir)
}
func (s *ShBinary) Installable() bool {
- return s.properties.Installable == nil || Bool(s.properties.Installable)
+ return s.properties.Installable == nil || proptools.Bool(s.properties.Installable)
}
func (s *ShBinary) Symlinks() []string {
return s.properties.Symlinks
}
-func (s *ShBinary) generateAndroidBuildActions(ctx ModuleContext) {
- s.sourceFilePath = PathForModuleSrc(ctx, String(s.properties.Src))
- filename := String(s.properties.Filename)
- filename_from_src := Bool(s.properties.Filename_from_src)
+func (s *ShBinary) generateAndroidBuildActions(ctx android.ModuleContext) {
+ s.sourceFilePath = android.PathForModuleSrc(ctx, proptools.String(s.properties.Src))
+ filename := proptools.String(s.properties.Filename)
+ filename_from_src := proptools.Bool(s.properties.Filename_from_src)
if filename == "" {
if filename_from_src {
filename = s.sourceFilePath.Base()
@@ -128,38 +136,38 @@
ctx.PropertyErrorf("filename_from_src", "filename is set. filename_from_src can't be true")
return
}
- s.outputFilePath = PathForModuleOut(ctx, filename).OutputPath
+ s.outputFilePath = android.PathForModuleOut(ctx, filename).OutputPath
// This ensures that outputFilePath has the correct name for others to
// use, as the source file may have a different name.
- ctx.Build(pctx, BuildParams{
- Rule: CpExecutable,
+ ctx.Build(pctx, android.BuildParams{
+ Rule: android.CpExecutable,
Output: s.outputFilePath,
Input: s.sourceFilePath,
})
}
-func (s *ShBinary) GenerateAndroidBuildActions(ctx ModuleContext) {
+func (s *ShBinary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
s.generateAndroidBuildActions(ctx)
- installDir := PathForModuleInstall(ctx, "bin", String(s.properties.Sub_dir))
+ installDir := android.PathForModuleInstall(ctx, "bin", proptools.String(s.properties.Sub_dir))
s.installedFile = ctx.InstallExecutable(installDir, s.outputFilePath.Base(), s.outputFilePath)
}
-func (s *ShBinary) AndroidMkEntries() []AndroidMkEntries {
- return []AndroidMkEntries{AndroidMkEntries{
+func (s *ShBinary) AndroidMkEntries() []android.AndroidMkEntries {
+ return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "EXECUTABLES",
- OutputFile: OptionalPathForPath(s.outputFilePath),
+ OutputFile: android.OptionalPathForPath(s.outputFilePath),
Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
- ExtraEntries: []AndroidMkExtraEntriesFunc{
- func(entries *AndroidMkEntries) {
+ ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+ func(entries *android.AndroidMkEntries) {
s.customAndroidMkEntries(entries)
},
},
}}
}
-func (s *ShBinary) customAndroidMkEntries(entries *AndroidMkEntries) {
- entries.SetString("LOCAL_MODULE_RELATIVE_PATH", String(s.properties.Sub_dir))
+func (s *ShBinary) customAndroidMkEntries(entries *android.AndroidMkEntries) {
+ entries.SetString("LOCAL_MODULE_RELATIVE_PATH", proptools.String(s.properties.Sub_dir))
entries.SetString("LOCAL_MODULE_SUFFIX", "")
entries.SetString("LOCAL_MODULE_STEM", s.outputFilePath.Rel())
if len(s.properties.Symlinks) > 0 {
@@ -167,38 +175,38 @@
}
}
-func (s *ShTest) GenerateAndroidBuildActions(ctx ModuleContext) {
+func (s *ShTest) GenerateAndroidBuildActions(ctx android.ModuleContext) {
s.ShBinary.generateAndroidBuildActions(ctx)
testDir := "nativetest"
if ctx.Target().Arch.ArchType.Multilib == "lib64" {
testDir = "nativetest64"
}
- if ctx.Target().NativeBridge == NativeBridgeEnabled {
+ if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
testDir = filepath.Join(testDir, ctx.Target().NativeBridgeRelativePath)
} else if !ctx.Host() && ctx.Config().HasMultilibConflict(ctx.Arch().ArchType) {
testDir = filepath.Join(testDir, ctx.Arch().ArchType.String())
}
- installDir := PathForModuleInstall(ctx, testDir, String(s.properties.Sub_dir))
+ installDir := android.PathForModuleInstall(ctx, testDir, proptools.String(s.properties.Sub_dir))
s.installedFile = ctx.InstallExecutable(installDir, s.outputFilePath.Base(), s.outputFilePath)
- s.data = PathsForModuleSrc(ctx, s.testProperties.Data)
+ s.data = android.PathsForModuleSrc(ctx, s.testProperties.Data)
}
func (s *ShTest) InstallInData() bool {
return true
}
-func (s *ShTest) AndroidMkEntries() []AndroidMkEntries {
- return []AndroidMkEntries{AndroidMkEntries{
+func (s *ShTest) AndroidMkEntries() []android.AndroidMkEntries {
+ return []android.AndroidMkEntries{android.AndroidMkEntries{
Class: "NATIVE_TESTS",
- OutputFile: OptionalPathForPath(s.outputFilePath),
+ OutputFile: android.OptionalPathForPath(s.outputFilePath),
Include: "$(BUILD_SYSTEM)/soong_cc_prebuilt.mk",
- ExtraEntries: []AndroidMkExtraEntriesFunc{
- func(entries *AndroidMkEntries) {
+ ExtraEntries: []android.AndroidMkExtraEntriesFunc{
+ func(entries *android.AndroidMkEntries) {
s.customAndroidMkEntries(entries)
entries.AddStrings("LOCAL_COMPATIBILITY_SUITE", s.testProperties.Test_suites...)
- entries.SetString("LOCAL_TEST_CONFIG", String(s.testProperties.Test_config))
+ entries.SetString("LOCAL_TEST_CONFIG", proptools.String(s.testProperties.Test_config))
for _, d := range s.data {
rel := d.Rel()
path := d.String()
@@ -219,41 +227,41 @@
// sh_binary is for a shell script or batch file to be installed as an
// executable binary to <partition>/bin.
-func ShBinaryFactory() Module {
+func ShBinaryFactory() android.Module {
module := &ShBinary{}
- module.Prefer32(func(ctx BaseModuleContext, base *ModuleBase, class OsClass) bool {
- return class == Device && ctx.Config().DevicePrefer32BitExecutables()
+ module.Prefer32(func(ctx android.BaseModuleContext, base *android.ModuleBase, class android.OsClass) bool {
+ return class == android.Device && ctx.Config().DevicePrefer32BitExecutables()
})
InitShBinaryModule(module)
- InitAndroidArchModule(module, HostAndDeviceSupported, MultilibFirst)
+ android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibFirst)
return module
}
// sh_binary_host is for a shell script to be installed as an executable binary
// to $(HOST_OUT)/bin.
-func ShBinaryHostFactory() Module {
+func ShBinaryHostFactory() android.Module {
module := &ShBinary{}
InitShBinaryModule(module)
- InitAndroidArchModule(module, HostSupported, MultilibFirst)
+ android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst)
return module
}
// sh_test defines a shell script based test module.
-func ShTestFactory() Module {
+func ShTestFactory() android.Module {
module := &ShTest{}
InitShBinaryModule(&module.ShBinary)
module.AddProperties(&module.testProperties)
- InitAndroidArchModule(module, HostAndDeviceSupported, MultilibFirst)
+ android.InitAndroidArchModule(module, android.HostAndDeviceSupported, android.MultilibFirst)
return module
}
// sh_test_host defines a shell script based test module that runs on a host.
-func ShTestHostFactory() Module {
+func ShTestHostFactory() android.Module {
module := &ShTest{}
InitShBinaryModule(&module.ShBinary)
module.AddProperties(&module.testProperties)
- InitAndroidArchModule(module, HostSupported, MultilibFirst)
+ android.InitAndroidArchModule(module, android.HostSupported, android.MultilibFirst)
return module
}
diff --git a/android/sh_binary_test.go b/sh/sh_binary_test.go
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/ui/build/Android.bp b/ui/build/Android.bp
index 2a5a51a..0a0bb16 100644
--- a/ui/build/Android.bp
+++ b/ui/build/Android.bp
@@ -56,12 +56,14 @@
"signal.go",
"soong.go",
"test_build.go",
+ "upload.go",
"util.go",
],
testSrcs: [
"cleanbuild_test.go",
"config_test.go",
"environment_test.go",
+ "upload_test.go",
"util_test.go",
"proc_sync_test.go",
],
diff --git a/ui/build/build.go b/ui/build/build.go
index 1122733..89c3fad 100644
--- a/ui/build/build.go
+++ b/ui/build/build.go
@@ -141,7 +141,26 @@
func Build(ctx Context, config Config, what int) {
ctx.Verboseln("Starting build with args:", config.Arguments())
ctx.Verboseln("Environment:", config.Environment().Environ())
- ctx.Verbosef("Total RAM: %dGB", config.TotalRAM()/1024/1024/1024)
+
+ if totalRAM := config.TotalRAM(); totalRAM != 0 {
+ ram := float32(totalRAM) / (1024 * 1024 * 1024)
+ ctx.Verbosef("Total RAM: %.3vGB", ram)
+
+ if ram <= 16 {
+ ctx.Println("************************************************************")
+ ctx.Printf("You are building on a machine with %.3vGB of RAM\n", ram)
+ ctx.Println("")
+ ctx.Println("The minimum required amount of free memory is around 16GB,")
+ ctx.Println("and even with that, some configurations may not work.")
+ ctx.Println("")
+ ctx.Println("If you run into segfaults or other errors, try reducing your")
+ ctx.Println("-j value.")
+ ctx.Println("************************************************************")
+ } else if ram <= float32(config.Parallel()) {
+ ctx.Printf("Warning: high -j%d count compared to %.3vGB of RAM", config.Parallel(), ram)
+ ctx.Println("If you run into segfaults or other errors, try a lower -j value")
+ }
+ }
ctx.BeginTrace(metrics.Total, "total")
defer ctx.EndTrace()
diff --git a/ui/build/config.go b/ui/build/config.go
index 7fcc471..49f506e 100644
--- a/ui/build/config.go
+++ b/ui/build/config.go
@@ -737,6 +737,9 @@
} else if c.totalRAM == 0 {
// Couldn't detect the total RAM, don't restrict highmem processes.
return parallel
+ } else if c.totalRAM <= 16*1024*1024*1024 {
+ // Less than 16GB of ram, restrict to 1 highmem processes
+ return 1
} else if c.totalRAM <= 32*1024*1024*1024 {
// Less than 32GB of ram, restrict to 2 highmem processes
return 2
@@ -958,3 +961,14 @@
func (c *configImpl) IsPdkBuild() bool {
return c.pdkBuild
}
+
+func (c *configImpl) BuildDateTime() string {
+ return c.buildDateTime
+}
+
+func (c *configImpl) MetricsUploaderApp() string {
+ if p, ok := c.environ.Get("ANDROID_ENABLE_METRICS_UPLOAD"); ok {
+ return p
+ }
+ return ""
+}
diff --git a/ui/build/config_test.go b/ui/build/config_test.go
index df618c4..7b14c47 100644
--- a/ui/build/config_test.go
+++ b/ui/build/config_test.go
@@ -26,6 +26,7 @@
"testing"
"android/soong/ui/logger"
+ "android/soong/ui/status"
)
func testContext() Context {
@@ -33,6 +34,7 @@
Context: context.Background(),
Logger: logger.New(&bytes.Buffer{}),
Writer: &bytes.Buffer{},
+ Status: &status.Status{},
}}
}
diff --git a/ui/build/upload.go b/ui/build/upload.go
new file mode 100644
index 0000000..75a5e2f
--- /dev/null
+++ b/ui/build/upload.go
@@ -0,0 +1,80 @@
+// Copyright 2020 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 build
+
+// This file contains the functionality to upload data from one location to
+// another.
+
+import (
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "time"
+
+ "github.com/golang/protobuf/proto"
+
+ upload_proto "android/soong/ui/metrics/upload_proto"
+)
+
+const (
+ uploadPbFilename = ".uploader.pb"
+)
+
+// UploadMetrics uploads a set of metrics files to a server for analysis. An
+// uploader full path is required to be specified in order to upload the set
+// of metrics files. This is accomplished by defining the ANDROID_ENABLE_METRICS_UPLOAD
+// environment variable.
+func UploadMetrics(ctx Context, config Config, buildStartedMilli int64, files ...string) {
+ uploader := config.MetricsUploaderApp()
+ // No metrics to upload if the path to the uploader was not specified.
+ if uploader == "" {
+ return
+ }
+
+ // Some files may not exist. For example, build errors protobuf file
+ // may not exist since the build was successful.
+ var metricsFiles []string
+ for _, f := range files {
+ if _, err := os.Stat(f); err == nil {
+ metricsFiles = append(metricsFiles, f)
+ }
+ }
+
+ if len(metricsFiles) == 0 {
+ return
+ }
+
+ // For platform builds, the branch and target name is hardcoded to specific
+ // values for later extraction of the metrics in the data metrics pipeline.
+ data, err := proto.Marshal(&upload_proto.Upload{
+ CreationTimestampMs: proto.Uint64(uint64(buildStartedMilli)),
+ CompletionTimestampMs: proto.Uint64(uint64(time.Now().UnixNano() / int64(time.Millisecond))),
+ BranchName: proto.String("developer-metrics"),
+ TargetName: proto.String("platform-build-systems-metrics"),
+ MetricsFiles: metricsFiles,
+ })
+ if err != nil {
+ ctx.Fatalf("failed to marshal metrics upload proto buffer message: %v\n", err)
+ }
+
+ pbFile := filepath.Join(config.OutDir(), uploadPbFilename)
+ if err := ioutil.WriteFile(pbFile, data, 0644); err != nil {
+ ctx.Fatalf("failed to write the marshaled metrics upload protobuf to %q: %v\n", pbFile, err)
+ }
+ // Remove the upload file as it's not longer needed after it has been processed by the uploader.
+ defer os.Remove(pbFile)
+
+ Command(ctx, config, "upload metrics", uploader, "--upload-metrics", pbFile).RunAndStreamOrFatal()
+}
diff --git a/ui/build/upload_test.go b/ui/build/upload_test.go
new file mode 100644
index 0000000..adaa08d
--- /dev/null
+++ b/ui/build/upload_test.go
@@ -0,0 +1,120 @@
+// Copyright 2020 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 build
+
+import (
+ "io/ioutil"
+ "os"
+ "path/filepath"
+ "strconv"
+ "strings"
+ "testing"
+ "time"
+
+ "android/soong/ui/logger"
+)
+
+func TestUploadMetrics(t *testing.T) {
+ ctx := testContext()
+ tests := []struct {
+ description string
+ uploader string
+ createFiles bool
+ files []string
+ }{{
+ description: "ANDROID_ENABLE_METRICS_UPLOAD not set",
+ }, {
+ description: "no metrics files to upload",
+ uploader: "fake",
+ }, {
+ description: "non-existent metrics files no upload",
+ uploader: "fake",
+ files: []string{"metrics_file_1", "metrics_file_2", "metrics_file_3"},
+ }, {
+ description: "trigger upload",
+ uploader: "echo",
+ createFiles: true,
+ files: []string{"metrics_file_1", "metrics_file_2"},
+ }}
+
+ for _, tt := range tests {
+ t.Run(tt.description, func(t *testing.T) {
+ defer logger.Recover(func(err error) {
+ t.Fatalf("got unexpected error: %v", err)
+ })
+
+ outDir, err := ioutil.TempDir("", "")
+ if err != nil {
+ t.Fatalf("failed to create out directory: %v", outDir)
+ }
+ defer os.RemoveAll(outDir)
+
+ var metricsFiles []string
+ if tt.createFiles {
+ for _, f := range tt.files {
+ filename := filepath.Join(outDir, f)
+ metricsFiles = append(metricsFiles, filename)
+ if err := ioutil.WriteFile(filename, []byte("test file"), 0644); err != nil {
+ t.Fatalf("failed to create a fake metrics file %q for uploading: %v", filename, err)
+ }
+ }
+ }
+
+ config := Config{&configImpl{
+ environ: &Environment{
+ "OUT_DIR=" + outDir,
+ "ANDROID_ENABLE_METRICS_UPLOAD=" + tt.uploader,
+ },
+ buildDateTime: strconv.FormatInt(time.Now().UnixNano()/int64(time.Millisecond), 10),
+ }}
+
+ UploadMetrics(ctx, config, 1591031903, metricsFiles...)
+
+ if _, err := os.Stat(filepath.Join(outDir, uploadPbFilename)); err == nil {
+ t.Error("got true, want false for upload protobuf file to exist")
+ }
+ })
+ }
+}
+
+func TestUploadMetricsErrors(t *testing.T) {
+ expectedErr := "failed to write the marshaled"
+ defer logger.Recover(func(err error) {
+ got := err.Error()
+ if !strings.Contains(got, expectedErr) {
+ t.Errorf("got %q, want %q to be contained in error", got, expectedErr)
+ }
+ })
+
+ outDir, err := ioutil.TempDir("", "")
+ if err != nil {
+ t.Fatalf("failed to create out directory: %v", outDir)
+ }
+ defer os.RemoveAll(outDir)
+
+ metricsFile := filepath.Join(outDir, "metrics_file_1")
+ if err := ioutil.WriteFile(metricsFile, []byte("test file"), 0644); err != nil {
+ t.Fatalf("failed to create a fake metrics file %q for uploading: %v", metricsFile, err)
+ }
+
+ config := Config{&configImpl{
+ environ: &Environment{
+ "ANDROID_ENABLE_METRICS_UPLOAD=fake",
+ "OUT_DIR=/bad",
+ }}}
+
+ UploadMetrics(testContext(), config, 1591031903, metricsFile)
+ t.Errorf("got nil, expecting %q as a failure", expectedErr)
+}
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"})