Merge "Use new pass manager for HWASan builds."
diff --git a/README.md b/README.md
index 10ddd73..e92349e 100644
--- a/README.md
+++ b/README.md
@@ -451,15 +451,10 @@
The values of the variables can be set from a product's `BoardConfig.mk` file:
```
-SOONG_CONFIG_NAMESPACES += acme
-SOONG_CONFIG_acme += \
- board \
- feature \
- width \
-
-SOONG_CONFIG_acme_board := soc_a
-SOONG_CONFIG_acme_feature := true
-SOONG_CONFIG_acme_width := 200
+$(call add_soong_config_namespace, acme)
+$(call add_soong_config_var_value, acme, board, soc_a)
+$(call add_soong_config_var_value, acme, feature, true)
+$(call add_soong_config_var_value, acme, width, 200)
```
The `acme_cc_defaults` module type can be used anywhere after the definition in
diff --git a/android/config.go b/android/config.go
index 35403b8..23423b7 100644
--- a/android/config.go
+++ b/android/config.go
@@ -1665,8 +1665,9 @@
return ConfiguredJarList{apexes, jars}
}
-// Filter keeps the entries if a jar appears in the given list of jars to keep; returns a new list.
-func (l *ConfiguredJarList) Filter(jarsToKeep []string) ConfiguredJarList {
+// Filter keeps the entries if a jar appears in the given list of jars to keep. Returns a new list
+// and any remaining jars that are not on this list.
+func (l *ConfiguredJarList) Filter(jarsToKeep []string) (ConfiguredJarList, []string) {
var apexes []string
var jars []string
@@ -1677,7 +1678,7 @@
}
}
- return ConfiguredJarList{apexes, jars}
+ return ConfiguredJarList{apexes, jars}, RemoveListFromList(jarsToKeep, jars)
}
// CopyOfJars returns a copy of the list of strings containing jar module name
diff --git a/android/module.go b/android/module.go
index b571f15..cc03418 100644
--- a/android/module.go
+++ b/android/module.go
@@ -986,10 +986,13 @@
// Device is built by default. Host and HostCross are not supported.
DeviceSupported = deviceSupported | deviceDefault
- // Device is built by default. Host and HostCross are supported.
+ // By default, _only_ device variant is built. Device variant can be disabled with `device_supported: false`
+ // Host and HostCross are disabled by default and can be enabled with `host_supported: true`
HostAndDeviceSupported = hostSupported | hostCrossSupported | deviceSupported | deviceDefault
// Host, HostCross, and Device are built by default.
+ // Building Device can be disabled with `device_supported: false`
+ // Building Host and HostCross can be disabled with `host_supported: false`
HostAndDeviceDefault = hostSupported | hostCrossSupported | hostDefault |
deviceSupported | deviceDefault
diff --git a/android/soong_config_modules.go b/android/soong_config_modules.go
index 289e910..17f6d66 100644
--- a/android/soong_config_modules.go
+++ b/android/soong_config_modules.go
@@ -122,15 +122,10 @@
// }
//
// If an acme BoardConfig.mk file contained:
-//
-// SOONG_CONFIG_NAMESPACES += acme
-// SOONG_CONFIG_acme += \
-// board \
-// feature \
-//
-// SOONG_CONFIG_acme_board := soc_a
-// SOONG_CONFIG_acme_feature := true
-// SOONG_CONFIG_acme_width := 200
+// $(call add_sonng_config_namespace, acme)
+// $(call add_soong_config_var_value, acme, board, soc_a)
+// $(call add_soong_config_var_value, acme, feature, true)
+// $(call add_soong_config_var_value, acme, width, 200)
//
// Then libacme_foo would build with cflags "-DGENERIC -DSOC_A -DFEATURE -DWIDTH=200".
//
diff --git a/apex/classpath_element_test.go b/apex/classpath_element_test.go
index e2d8465..60f18bd 100644
--- a/apex/classpath_element_test.go
+++ b/apex/classpath_element_test.go
@@ -159,11 +159,6 @@
],
}
- bootclasspath_fragment {
- name: "non-apex-fragment",
- contents: ["othersdklibrary"],
- }
-
apex {
name: "otherapex",
key: "otherapex.key",
@@ -213,7 +208,6 @@
myFragment := result.Module("mybootclasspath-fragment", "android_common_apex10000")
myBar := result.Module("bar", "android_common_apex10000")
- nonApexFragment := result.Module("non-apex-fragment", "android_common")
other := result.Module("othersdklibrary", "android_common_apex10000")
otherApexLibrary := result.Module("otherapexlibrary", "android_common_apex10000")
@@ -253,15 +247,6 @@
assertElementsEquals(t, "elements", expectedElements, elements)
})
- // Verify that CreateClasspathElements detects when a fragment does not have an associated apex.
- t.Run("non apex fragment", func(t *testing.T) {
- ctx := newCtx()
- elements := java.CreateClasspathElements(ctx, []android.Module{}, []android.Module{nonApexFragment})
- android.FailIfNoMatchingErrors(t, "fragment non-apex-fragment{.*} is not part of an apex", ctx.errs)
- expectedElements := java.ClasspathElements{}
- assertElementsEquals(t, "elements", expectedElements, elements)
- })
-
// Verify that CreateClasspathElements detects when an apex has multiple fragments.
t.Run("multiple fragments for same apex", func(t *testing.T) {
ctx := newCtx()
diff --git a/apex/platform_bootclasspath_test.go b/apex/platform_bootclasspath_test.go
index e0421f6..513ddc0 100644
--- a/apex/platform_bootclasspath_test.go
+++ b/apex/platform_bootclasspath_test.go
@@ -543,3 +543,140 @@
"out/soong/target/product/test_device/system/etc/classpaths",
)
}
+
+func TestBootJarNotInApex(t *testing.T) {
+ android.GroupFixturePreparers(
+ prepareForTestWithPlatformBootclasspath,
+ PrepareForTestWithApexBuildComponents,
+ prepareForTestWithMyapex,
+ java.FixtureConfigureApexBootJars("myapex:foo"),
+ ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
+ `dependency "foo" of "myplatform-bootclasspath" missing variant`)).
+ RunTestWithBp(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_library {
+ name: "foo",
+ srcs: ["b.java"],
+ installable: true,
+ apex_available: [
+ "myapex",
+ ],
+ }
+
+ bootclasspath_fragment {
+ name: "not-in-apex-fragment",
+ contents: [
+ "foo",
+ ],
+ }
+
+ platform_bootclasspath {
+ name: "myplatform-bootclasspath",
+ }
+ `)
+}
+
+func TestBootFragmentNotInApex(t *testing.T) {
+ android.GroupFixturePreparers(
+ prepareForTestWithPlatformBootclasspath,
+ PrepareForTestWithApexBuildComponents,
+ prepareForTestWithMyapex,
+ java.FixtureConfigureApexBootJars("myapex:foo"),
+ ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
+ `library foo.*have no corresponding fragment.*`)).RunTestWithBp(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ java_libs: ["foo"],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_library {
+ name: "foo",
+ srcs: ["b.java"],
+ installable: true,
+ apex_available: ["myapex"],
+ permitted_packages: ["foo"],
+ }
+
+ bootclasspath_fragment {
+ name: "not-in-apex-fragment",
+ contents: ["foo"],
+ }
+
+ platform_bootclasspath {
+ name: "myplatform-bootclasspath",
+ }
+ `)
+}
+
+func TestNonBootJarInFragment(t *testing.T) {
+ android.GroupFixturePreparers(
+ prepareForTestWithPlatformBootclasspath,
+ PrepareForTestWithApexBuildComponents,
+ prepareForTestWithMyapex,
+ java.FixtureConfigureApexBootJars("myapex:foo"),
+ ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
+ `in contents must also be declared in PRODUCT_APEX_BOOT_JARS`)).
+ RunTestWithBp(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ bootclasspath_fragments: ["apex-fragment"],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_library {
+ name: "foo",
+ srcs: ["b.java"],
+ installable: true,
+ apex_available: ["myapex"],
+ permitted_packages: ["foo"],
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["b.java"],
+ installable: true,
+ apex_available: ["myapex"],
+ permitted_packages: ["bar"],
+ }
+
+ bootclasspath_fragment {
+ name: "apex-fragment",
+ contents: ["foo", "bar"],
+ apex_available:[ "myapex" ],
+ }
+
+ platform_bootclasspath {
+ name: "myplatform-bootclasspath",
+ fragments: [{
+ apex: "myapex",
+ module:"apex-fragment",
+ }],
+ }
+ `)
+}
diff --git a/apex/systemserver_classpath_fragment_test.go b/apex/systemserver_classpath_fragment_test.go
index a64c6f4..a8d5931 100644
--- a/apex/systemserver_classpath_fragment_test.go
+++ b/apex/systemserver_classpath_fragment_test.go
@@ -130,3 +130,54 @@
`mysystemserverclasspathfragment`,
})
}
+
+func TestSystemServerClasspathFragmentWithContentNotInMake(t *testing.T) {
+ android.GroupFixturePreparers(
+ prepareForTestWithSystemserverclasspathFragment,
+ prepareForTestWithMyapex,
+ dexpreopt.FixtureSetApexSystemServerJars("myapex:foo"),
+ ).
+ ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
+ `in contents must also be declared in PRODUCT_UPDATABLE_SYSTEM_SERVER_JARS`)).
+ RunTestWithBp(t, `
+ apex {
+ name: "myapex",
+ key: "myapex.key",
+ systemserverclasspath_fragments: [
+ "mysystemserverclasspathfragment",
+ ],
+ updatable: false,
+ }
+
+ apex_key {
+ name: "myapex.key",
+ public_key: "testkey.avbpubkey",
+ private_key: "testkey.pem",
+ }
+
+ java_library {
+ name: "foo",
+ srcs: ["b.java"],
+ installable: true,
+ apex_available: ["myapex"],
+ }
+
+ java_library {
+ name: "bar",
+ srcs: ["b.java"],
+ installable: true,
+ apex_available: ["myapex"],
+ }
+
+ systemserverclasspath_fragment {
+ name: "mysystemserverclasspathfragment",
+ contents: [
+ "foo",
+ "bar",
+ ],
+ apex_available: [
+ "myapex",
+ ],
+ }
+ `)
+}
diff --git a/bp2build/build_conversion.go b/bp2build/build_conversion.go
index a64d474..f652a35 100644
--- a/bp2build/build_conversion.go
+++ b/bp2build/build_conversion.go
@@ -14,14 +14,20 @@
package bp2build
+/*
+For shareable/common functionality for conversion from soong-module to build files
+for queryview/bp2build
+*/
+
import (
- "android/soong/android"
- "android/soong/bazel"
"fmt"
"reflect"
"sort"
"strings"
+ "android/soong/android"
+ "android/soong/bazel"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index bff192f..c840016 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -15,10 +15,10 @@
package bp2build
import (
+ "testing"
+
"android/soong/android"
"android/soong/cc"
- "strings"
- "testing"
)
const (
@@ -54,59 +54,6 @@
ctx.RegisterModuleType("cc_library_headers", cc.LibraryHeaderFactory)
}
-func runBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc bp2buildTestCase) {
- t.Helper()
- dir := "."
- filesystem := make(map[string][]byte)
- toParse := []string{
- "Android.bp",
- }
- for f, content := range tc.filesystem {
- if strings.HasSuffix(f, "Android.bp") {
- toParse = append(toParse, f)
- }
- filesystem[f] = []byte(content)
- }
- config := android.TestConfig(buildDir, nil, tc.blueprint, filesystem)
- ctx := android.NewTestContext(config)
-
- registerModuleTypes(ctx)
- ctx.RegisterModuleType(tc.moduleTypeUnderTest, tc.moduleTypeUnderTestFactory)
- ctx.RegisterBp2BuildConfig(bp2buildConfig)
- ctx.RegisterBp2BuildMutator(tc.moduleTypeUnderTest, tc.moduleTypeUnderTestBp2BuildMutator)
- ctx.RegisterForBazelConversion()
-
- _, errs := ctx.ParseFileList(dir, toParse)
- if errored(t, tc.description, errs) {
- return
- }
- _, errs = ctx.ResolveDependencies(config)
- if errored(t, tc.description, errs) {
- return
- }
-
- checkDir := dir
- if tc.dir != "" {
- checkDir = tc.dir
- }
- codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
- bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir)
- if actualCount, expectedCount := len(bazelTargets), len(tc.expectedBazelTargets); actualCount != expectedCount {
- t.Errorf("%s: Expected %d bazel target, got %d", tc.description, expectedCount, actualCount)
- } else {
- for i, target := range bazelTargets {
- if w, g := tc.expectedBazelTargets[i], target.content; w != g {
- t.Errorf(
- "%s: Expected generated Bazel target to be '%s', got '%s'",
- tc.description,
- w,
- g,
- )
- }
- }
- }
-}
-
func TestCcLibrarySimple(t *testing.T) {
runCcLibraryTestCase(t, bp2buildTestCase{
description: "cc_library - simple example",
diff --git a/bp2build/cc_library_headers_conversion_test.go b/bp2build/cc_library_headers_conversion_test.go
index 712d0bd..ea2c10a 100644
--- a/bp2build/cc_library_headers_conversion_test.go
+++ b/bp2build/cc_library_headers_conversion_test.go
@@ -40,17 +40,6 @@
}`
)
-type bp2buildTestCase struct {
- description string
- moduleTypeUnderTest string
- moduleTypeUnderTestFactory android.ModuleFactory
- moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
- blueprint string
- expectedBazelTargets []string
- filesystem map[string]string
- dir string
-}
-
func TestCcLibraryHeadersLoadStatement(t *testing.T) {
testCases := []struct {
bazelTargets BazelTargets
diff --git a/bp2build/python_binary_conversion_test.go b/bp2build/python_binary_conversion_test.go
index 7bedf71..cf46322 100644
--- a/bp2build/python_binary_conversion_test.go
+++ b/bp2build/python_binary_conversion_test.go
@@ -3,17 +3,11 @@
import (
"testing"
- "android/soong/android"
"android/soong/python"
)
-func runPythonTestCase(t *testing.T, tc bp2buildTestCase) {
- t.Helper()
- runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc)
-}
-
func TestPythonBinaryHostSimple(t *testing.T) {
- runPythonTestCase(t, bp2buildTestCase{
+ runBp2BuildTestCaseSimple(t, bp2buildTestCase{
description: "simple python_binary_host converts to a native py_binary",
moduleTypeUnderTest: "python_binary_host",
moduleTypeUnderTestFactory: python.PythonBinaryHostFactory,
@@ -49,7 +43,7 @@
}
func TestPythonBinaryHostPy2(t *testing.T) {
- runPythonTestCase(t, bp2buildTestCase{
+ runBp2BuildTestCaseSimple(t, bp2buildTestCase{
description: "py2 python_binary_host",
moduleTypeUnderTest: "python_binary_host",
moduleTypeUnderTestFactory: python.PythonBinaryHostFactory,
@@ -79,7 +73,7 @@
}
func TestPythonBinaryHostPy3(t *testing.T) {
- runPythonTestCase(t, bp2buildTestCase{
+ runBp2BuildTestCaseSimple(t, bp2buildTestCase{
description: "py3 python_binary_host",
moduleTypeUnderTest: "python_binary_host",
moduleTypeUnderTestFactory: python.PythonBinaryHostFactory,
diff --git a/bp2build/testing.go b/bp2build/testing.go
index 266b817..3a77d0e 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -1,6 +1,26 @@
+// Copyright 2021 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
package bp2build
+/*
+For shareable/common bp2build testing functionality and dumping ground for
+specific-but-shared functionality among tests in package
+*/
+
import (
+ "strings"
"testing"
"android/soong/android"
@@ -16,6 +36,86 @@
buildDir string
)
+func errored(t *testing.T, desc string, errs []error) bool {
+ t.Helper()
+ if len(errs) > 0 {
+ for _, err := range errs {
+ t.Errorf("%s: %s", desc, err)
+ }
+ return true
+ }
+ return false
+}
+
+func runBp2BuildTestCaseSimple(t *testing.T, tc bp2buildTestCase) {
+ t.Helper()
+ runBp2BuildTestCase(t, func(ctx android.RegistrationContext) {}, tc)
+}
+
+type bp2buildTestCase struct {
+ description string
+ moduleTypeUnderTest string
+ moduleTypeUnderTestFactory android.ModuleFactory
+ moduleTypeUnderTestBp2BuildMutator func(android.TopDownMutatorContext)
+ blueprint string
+ expectedBazelTargets []string
+ filesystem map[string]string
+ dir string
+}
+
+func runBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc bp2buildTestCase) {
+ t.Helper()
+ dir := "."
+ filesystem := make(map[string][]byte)
+ toParse := []string{
+ "Android.bp",
+ }
+ for f, content := range tc.filesystem {
+ if strings.HasSuffix(f, "Android.bp") {
+ toParse = append(toParse, f)
+ }
+ filesystem[f] = []byte(content)
+ }
+ config := android.TestConfig(buildDir, nil, tc.blueprint, filesystem)
+ ctx := android.NewTestContext(config)
+
+ registerModuleTypes(ctx)
+ ctx.RegisterModuleType(tc.moduleTypeUnderTest, tc.moduleTypeUnderTestFactory)
+ ctx.RegisterBp2BuildConfig(bp2buildConfig)
+ ctx.RegisterBp2BuildMutator(tc.moduleTypeUnderTest, tc.moduleTypeUnderTestBp2BuildMutator)
+ ctx.RegisterForBazelConversion()
+
+ _, errs := ctx.ParseFileList(dir, toParse)
+ if errored(t, tc.description, errs) {
+ return
+ }
+ _, errs = ctx.ResolveDependencies(config)
+ if errored(t, tc.description, errs) {
+ return
+ }
+
+ checkDir := dir
+ if tc.dir != "" {
+ checkDir = tc.dir
+ }
+ codegenCtx := NewCodegenContext(config, *ctx.Context, Bp2Build)
+ bazelTargets := generateBazelTargetsForDir(codegenCtx, checkDir)
+ if actualCount, expectedCount := len(bazelTargets), len(tc.expectedBazelTargets); actualCount != expectedCount {
+ t.Errorf("%s: Expected %d bazel target, got %d", tc.description, expectedCount, actualCount)
+ } else {
+ for i, target := range bazelTargets {
+ if w, g := tc.expectedBazelTargets[i], target.content; w != g {
+ t.Errorf(
+ "%s: Expected generated Bazel target to be '%s', got '%s'",
+ tc.description,
+ w,
+ g,
+ )
+ }
+ }
+ }
+}
+
type nestedProps struct {
Nested_prop string
}
@@ -44,17 +144,6 @@
props customProps
}
-func errored(t *testing.T, desc string, errs []error) bool {
- t.Helper()
- if len(errs) > 0 {
- for _, err := range errs {
- t.Errorf("%s: %s", desc, err)
- }
- return true
- }
- return false
-}
-
// OutputFiles is needed because some instances of this module use dist with a
// tag property which requires the module implements OutputFileProducer.
func (m *customModule) OutputFiles(tag string) (android.Paths, error) {
diff --git a/cc/androidmk.go b/cc/androidmk.go
index e95d5a7..cd52363 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -294,6 +294,9 @@
if library.buildStubs() {
entries.SetBool("LOCAL_NO_NOTICE_FILE", true)
}
+ if library.apiListCoverageXmlPath.String() != "" {
+ entries.SetString("SOONG_CC_API_XML", "$(SOONG_CC_API_XML) "+library.apiListCoverageXmlPath.String())
+ }
})
}
// If a library providing a stub is included in an APEX, the private APIs of the library
diff --git a/cc/binary.go b/cc/binary.go
index 763d2b9..b423c50 100644
--- a/cc/binary.go
+++ b/cc/binary.go
@@ -156,6 +156,10 @@
}
}
+ if binary.static() {
+ deps.StaticLibs = append(deps.StaticLibs, deps.SystemSharedLibs...)
+ }
+
if ctx.toolchain().Bionic() {
if binary.static() {
if ctx.selectedStl() == "libc++_static" {
@@ -208,7 +212,7 @@
func (binary *binaryDecorator) linkerInit(ctx BaseModuleContext) {
binary.baseLinker.linkerInit(ctx)
- if !ctx.toolchain().Bionic() {
+ if !ctx.toolchain().Bionic() && !ctx.toolchain().Musl() {
if ctx.Os() == android.Linux {
// Unless explicitly specified otherwise, host static binaries are built with -static
// if HostStaticBinaries is true for the product configuration.
diff --git a/cc/config/x86_linux_host.go b/cc/config/x86_linux_host.go
index e7fcfed..ac5d5f7 100644
--- a/cc/config/x86_linux_host.go
+++ b/cc/config/x86_linux_host.go
@@ -45,6 +45,7 @@
linuxMuslCflags = []string{
"-D_LIBCPP_HAS_MUSL_LIBC",
+ "-DANDROID_HOST_MUSL",
"-nostdlibinc",
}
@@ -106,7 +107,7 @@
"util",
}, "-l")
- muslCrtBeginStaticBinary, muslCrtEndStaticBinary = []string{"libc_musl_crtbegin_static"}, []string{"crtend_android"}
+ muslCrtBeginStaticBinary, muslCrtEndStaticBinary = []string{"libc_musl_crtbegin_static"}, []string{"libc_musl_crtend"}
muslCrtBeginSharedBinary, muslCrtEndSharedBinary = []string{"libc_musl_crtbegin_dynamic", "musl_linker_script"}, []string{"libc_musl_crtend"}
muslCrtBeginSharedLibrary, muslCrtEndSharedLibrary = []string{"libc_musl_crtbegin_so"}, []string{"libc_musl_crtend_so"}
diff --git a/cc/coverage.go b/cc/coverage.go
index baf4226..8dd2db1 100644
--- a/cc/coverage.go
+++ b/cc/coverage.go
@@ -244,3 +244,19 @@
m[1].(Coverage).EnableCoverageIfNeeded()
}
}
+
+func parseSymbolFileForAPICoverage(ctx ModuleContext, symbolFile string) android.ModuleOutPath {
+ apiLevelsJson := android.GetApiLevelsJson(ctx)
+ symbolFilePath := android.PathForModuleSrc(ctx, symbolFile)
+ outputFile := ctx.baseModuleName() + ".xml"
+ parsedApiCoveragePath := android.PathForModuleOut(ctx, outputFile)
+ rule := android.NewRuleBuilder(pctx, ctx)
+ rule.Command().
+ BuiltTool("ndk_api_coverage_parser").
+ Input(symbolFilePath).
+ Output(parsedApiCoveragePath).
+ Implicit(apiLevelsJson).
+ FlagWithArg("--api-map ", apiLevelsJson.String())
+ rule.Build("native_library_api_list", "Generate native API list based on symbol files for coverage measurement")
+ return parsedApiCoveragePath
+}
diff --git a/cc/library.go b/cc/library.go
index 1526f81..196116b 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -536,6 +536,8 @@
*baseInstaller
collectedSnapshotHeaders android.Paths
+
+ apiListCoverageXmlPath android.ModuleOutPath
}
type ccLibraryBazelHandler struct {
@@ -951,6 +953,12 @@
objs := compileStubLibrary(ctx, flags, nativeAbiResult.stubSrc)
library.versionScriptPath = android.OptionalPathForPath(
nativeAbiResult.versionScript)
+
+ // Parse symbol file to get API list for coverage
+ if library.stubsVersion() == "current" && ctx.PrimaryArch() {
+ library.apiListCoverageXmlPath = parseSymbolFileForAPICoverage(ctx, symbolFile)
+ }
+
return objs
}
diff --git a/cc/ndk_api_coverage_parser/__init__.py b/cc/ndk_api_coverage_parser/__init__.py
index 7817c78..8b9cd66 100755
--- a/cc/ndk_api_coverage_parser/__init__.py
+++ b/cc/ndk_api_coverage_parser/__init__.py
@@ -21,7 +21,12 @@
import sys
from xml.etree.ElementTree import Element, SubElement, tostring
-from symbolfile import ALL_ARCHITECTURES, FUTURE_API_LEVEL, MultiplyDefinedSymbolError, SymbolFileParser
+from symbolfile import (
+ ALL_ARCHITECTURES,
+ FUTURE_API_LEVEL,
+ MultiplyDefinedSymbolError,
+ SymbolFileParser,
+)
ROOT_ELEMENT_TAG = 'ndk-library'
@@ -63,6 +68,7 @@
class XmlGenerator(object):
"""Output generator that writes parsed symbol file to a xml file."""
+
def __init__(self, output_file):
self.output_file = output_file
@@ -74,10 +80,14 @@
continue
version_attributes = parse_tags(version.tags)
_, _, postfix = version.name.partition('_')
- is_platform = postfix == 'PRIVATE' or postfix == 'PLATFORM'
+ is_platform = postfix in ('PRIVATE' , 'PLATFORM')
is_deprecated = postfix == 'DEPRECATED'
- version_attributes.update({PLATFORM_ATTRIBUTE_KEY: str(is_platform)})
- version_attributes.update({DEPRECATED_ATTRIBUTE_KEY: str(is_deprecated)})
+ version_attributes.update(
+ {PLATFORM_ATTRIBUTE_KEY: str(is_platform)}
+ )
+ version_attributes.update(
+ {DEPRECATED_ATTRIBUTE_KEY: str(is_deprecated)}
+ )
for symbol in version.symbols:
if VARIABLE_TAG in symbol.tags:
continue
@@ -103,13 +113,20 @@
"""Parses and returns command line arguments."""
parser = argparse.ArgumentParser()
- parser.add_argument('symbol_file', type=os.path.realpath, help='Path to symbol file.')
parser.add_argument(
- 'output_file', type=os.path.realpath,
- help='The output parsed api coverage file.')
+ 'symbol_file', type=os.path.realpath, help='Path to symbol file.'
+ )
parser.add_argument(
- '--api-map', type=os.path.realpath, required=True,
- help='Path to the API level map JSON file.')
+ 'output_file',
+ type=os.path.realpath,
+ help='The output parsed api coverage file.',
+ )
+ parser.add_argument(
+ '--api-map',
+ type=os.path.realpath,
+ required=True,
+ help='Path to the API level map JSON file.',
+ )
return parser.parse_args()
@@ -122,13 +139,15 @@
with open(args.symbol_file) as symbol_file:
try:
- versions = SymbolFileParser(symbol_file, api_map, "", FUTURE_API_LEVEL,
- True, True).parse()
+ versions = SymbolFileParser(
+ symbol_file, api_map, "", FUTURE_API_LEVEL, True, True
+ ).parse()
except MultiplyDefinedSymbolError as ex:
sys.exit('{}: error: {}'.format(args.symbol_file, ex))
generator = XmlGenerator(args.output_file)
generator.write(versions)
+
if __name__ == '__main__':
main()
diff --git a/cc/ndk_api_coverage_parser/test_ndk_api_coverage_parser.py b/cc/ndk_api_coverage_parser/test_ndk_api_coverage_parser.py
index 3ec14c1..141059c 100644
--- a/cc/ndk_api_coverage_parser/test_ndk_api_coverage_parser.py
+++ b/cc/ndk_api_coverage_parser/test_ndk_api_coverage_parser.py
@@ -50,10 +50,12 @@
return False
return all(etree_equal(c1, c2) for c1, c2 in zip(elem1, elem2))
-
+# pylint: disable=line-too-long
class ApiCoverageSymbolFileParserTest(unittest.TestCase):
def test_parse(self):
- input_file = io.StringIO(textwrap.dedent(u"""\
+ input_file = io.StringIO(
+ textwrap.dedent(
+ u"""\
LIBLOG { # introduced-arm64=24 introduced-x86=24 introduced-x86_64=24
global:
android_name_to_log_id; # apex llndk introduced=23
@@ -64,22 +66,28 @@
local:
*;
};
-
+
LIBLOG_PLATFORM {
android_fdtrack; # llndk
android_net; # introduced=23
};
-
+
LIBLOG_FOO { # var
android_var;
};
- """))
- parser = SymbolFileParser(input_file, {}, "", FUTURE_API_LEVEL, True, True)
+ """
+ )
+ )
+ parser = SymbolFileParser(
+ input_file, {}, "", FUTURE_API_LEVEL, True, True
+ )
generator = nparser.XmlGenerator(io.StringIO())
result = generator.convertToXml(parser.parse())
- expected = fromstring('<ndk-library><symbol apex="True" arch="" introduced="23" introduced-arm64="24" introduced-x86="24" introduced-x86_64="24" is_deprecated="False" is_platform="False" llndk="True" name="android_name_to_log_id" /><symbol arch="arm" introduced-arm64="24" introduced-x86="24" introduced-x86_64="24" is_deprecated="False" is_platform="False" llndk="True" name="android_log_id_to_name" /><symbol arch="" introduced-arm64="24" introduced-x86="23" introduced-x86_64="24" is_deprecated="False" is_platform="False" name="__android_log_assert" /><symbol arch="" introduced-arm64="24" introduced-x86="24" introduced-x86_64="24" is_deprecated="False" is_platform="False" name="__android_log_buf_write" /><symbol arch="" is_deprecated="False" is_platform="True" llndk="True" name="android_fdtrack" /><symbol arch="" introduced="23" is_deprecated="False" is_platform="True" name="android_net" /></ndk-library>')
+ expected = fromstring(
+ '<ndk-library><symbol apex="True" arch="" introduced="23" introduced-arm64="24" introduced-x86="24" introduced-x86_64="24" is_deprecated="False" is_platform="False" llndk="True" name="android_name_to_log_id" /><symbol arch="arm" introduced-arm64="24" introduced-x86="24" introduced-x86_64="24" is_deprecated="False" is_platform="False" llndk="True" name="android_log_id_to_name" /><symbol arch="" introduced-arm64="24" introduced-x86="23" introduced-x86_64="24" is_deprecated="False" is_platform="False" name="__android_log_assert" /><symbol arch="" introduced-arm64="24" introduced-x86="24" introduced-x86_64="24" is_deprecated="False" is_platform="False" name="__android_log_buf_write" /><symbol arch="" is_deprecated="False" is_platform="True" llndk="True" name="android_fdtrack" /><symbol arch="" introduced="23" is_deprecated="False" is_platform="True" name="android_net" /></ndk-library>'
+ )
self.assertTrue(etree_equal(expected, result))
-
+# pylint: enable=line-too-long
def main():
suite = unittest.TestLoader().loadTestsFromName(__name__)
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index 63e8261..51cdddf 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -29,7 +29,6 @@
func init() {
pctx.HostBinToolVariable("ndkStubGenerator", "ndkstubgen")
- pctx.HostBinToolVariable("ndk_api_coverage_parser", "ndk_api_coverage_parser")
pctx.HostBinToolVariable("abidiff", "abidiff")
pctx.HostBinToolVariable("abitidy", "abitidy")
pctx.HostBinToolVariable("abidw", "abidw")
@@ -43,12 +42,6 @@
CommandDeps: []string{"$ndkStubGenerator"},
}, "arch", "apiLevel", "apiMap", "flags")
- parseNdkApiRule = pctx.AndroidStaticRule("parseNdkApiRule",
- blueprint.RuleParams{
- Command: "$ndk_api_coverage_parser $in $out --api-map $apiMap",
- CommandDeps: []string{"$ndk_api_coverage_parser"},
- }, "apiMap")
-
abidw = pctx.AndroidStaticRule("abidw",
blueprint.RuleParams{
Command: "$abidw --type-id-style hash --no-corpus-path " +
@@ -276,24 +269,6 @@
android.Paths{src}, nil, nil)
}
-func parseSymbolFileForCoverage(ctx ModuleContext, symbolFile string) android.ModuleOutPath {
- apiLevelsJson := android.GetApiLevelsJson(ctx)
- symbolFilePath := android.PathForModuleSrc(ctx, symbolFile)
- outputFileName := strings.Split(symbolFilePath.Base(), ".")[0]
- parsedApiCoveragePath := android.PathForModuleOut(ctx, outputFileName+".xml")
- ctx.Build(pctx, android.BuildParams{
- Rule: parseNdkApiRule,
- Description: "parse ndk api symbol file for api coverage: " + symbolFilePath.Rel(),
- Outputs: []android.WritablePath{parsedApiCoveragePath},
- Input: symbolFilePath,
- Implicits: []android.Path{apiLevelsJson},
- Args: map[string]string{
- "apiMap": apiLevelsJson.String(),
- },
- })
- return parsedApiCoveragePath
-}
-
func (this *stubDecorator) findImplementationLibrary(ctx ModuleContext) android.Path {
dep := ctx.GetDirectDepWithTag(strings.TrimSuffix(ctx.ModuleName(), ndkLibrarySuffix),
stubImplementation)
@@ -454,7 +429,7 @@
}
}
if c.apiLevel.IsCurrent() && ctx.PrimaryArch() {
- c.parsedCoverageXmlPath = parseSymbolFileForCoverage(ctx, symbolFile)
+ c.parsedCoverageXmlPath = parseSymbolFileForAPICoverage(ctx, symbolFile)
}
return objs
}
diff --git a/dexpreopt/class_loader_context.go b/dexpreopt/class_loader_context.go
index ebb8959..1bdd040 100644
--- a/dexpreopt/class_loader_context.go
+++ b/dexpreopt/class_loader_context.go
@@ -196,6 +196,10 @@
// If the library is optional or required.
Optional bool
+ // If the library is implicitly infered by Soong (as opposed to explicitly added via `uses_libs`
+ // or `optional_uses_libs`.
+ Implicit bool
+
// On-host build path to the library dex file (used in dex2oat argument --class-loader-context).
Host android.Path
@@ -258,8 +262,9 @@
const AnySdkVersion int = android.FutureApiLevelInt
// Add class loader context for the given library to the map entry for the given SDK version.
-func (clcMap ClassLoaderContextMap) addContext(ctx android.ModuleInstallPathContext, sdkVer int, lib string,
- optional bool, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) error {
+func (clcMap ClassLoaderContextMap) addContext(ctx android.ModuleInstallPathContext, sdkVer int,
+ lib string, optional, implicit bool, hostPath, installPath android.Path,
+ nestedClcMap ClassLoaderContextMap) error {
// For prebuilts, library should have the same name as the source module.
lib = android.RemoveOptionalPrebuiltPrefix(lib)
@@ -308,6 +313,7 @@
clcMap[sdkVer] = append(clcMap[sdkVer], &ClassLoaderContext{
Name: lib,
Optional: optional,
+ Implicit: implicit,
Host: hostPath,
Device: devicePath,
Subcontexts: subcontexts,
@@ -320,9 +326,10 @@
// about paths). For the subset of libraries that are used in dexpreopt, their build/install paths
// are validated later before CLC is used (in validateClassLoaderContext).
func (clcMap ClassLoaderContextMap) AddContext(ctx android.ModuleInstallPathContext, sdkVer int,
- lib string, optional bool, hostPath, installPath android.Path, nestedClcMap ClassLoaderContextMap) {
+ lib string, optional, implicit bool, hostPath, installPath android.Path,
+ nestedClcMap ClassLoaderContextMap) {
- err := clcMap.addContext(ctx, sdkVer, lib, optional, hostPath, installPath, nestedClcMap)
+ err := clcMap.addContext(ctx, sdkVer, lib, optional, implicit, hostPath, installPath, nestedClcMap)
if err != nil {
ctx.ModuleErrorf(err.Error())
}
@@ -366,13 +373,15 @@
// included). This is the list of libraries that should be in the <uses-library> tags in the
// manifest. Some of them may be present in the source manifest, others are added by manifest_fixer.
// Required and optional libraries are in separate lists.
-func (clcMap ClassLoaderContextMap) UsesLibs() (required []string, optional []string) {
+func (clcMap ClassLoaderContextMap) usesLibs(implicit bool) (required []string, optional []string) {
if clcMap != nil {
clcs := clcMap[AnySdkVersion]
required = make([]string, 0, len(clcs))
optional = make([]string, 0, len(clcs))
for _, clc := range clcs {
- if clc.Optional {
+ if implicit && !clc.Implicit {
+ // Skip, this is an explicit library and we need only the implicit ones.
+ } else if clc.Optional {
optional = append(optional, clc.Name)
} else {
required = append(required, clc.Name)
@@ -382,6 +391,14 @@
return required, optional
}
+func (clcMap ClassLoaderContextMap) UsesLibs() ([]string, []string) {
+ return clcMap.usesLibs(false)
+}
+
+func (clcMap ClassLoaderContextMap) ImplicitUsesLibs() ([]string, []string) {
+ return clcMap.usesLibs(true)
+}
+
func (clcMap ClassLoaderContextMap) Dump() string {
jsonCLC := toJsonClassLoaderContext(clcMap)
bytes, err := json.MarshalIndent(jsonCLC, "", " ")
@@ -524,6 +541,8 @@
// the same as Soong representation except that SDK versions and paths are represented with strings.
type jsonClassLoaderContext struct {
Name string
+ Optional bool
+ Implicit bool
Host string
Device string
Subcontexts []*jsonClassLoaderContext
@@ -555,6 +574,8 @@
for _, clc := range jClcs {
clcs = append(clcs, &ClassLoaderContext{
Name: clc.Name,
+ Optional: clc.Optional,
+ Implicit: clc.Implicit,
Host: constructPath(ctx, clc.Host),
Device: clc.Device,
Subcontexts: fromJsonClassLoaderContextRec(ctx, clc.Subcontexts),
@@ -579,6 +600,8 @@
for i, clc := range clcs {
jClcs[i] = &jsonClassLoaderContext{
Name: clc.Name,
+ Optional: clc.Optional,
+ Implicit: clc.Implicit,
Host: clc.Host.String(),
Device: clc.Device,
Subcontexts: toJsonClassLoaderContextRec(clc.Subcontexts),
diff --git a/dexpreopt/class_loader_context_test.go b/dexpreopt/class_loader_context_test.go
index 0b7b546..d81ac2c 100644
--- a/dexpreopt/class_loader_context_test.go
+++ b/dexpreopt/class_loader_context_test.go
@@ -50,33 +50,34 @@
ctx := testContext()
optional := false
+ implicit := true
m := make(ClassLoaderContextMap)
- m.AddContext(ctx, AnySdkVersion, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
- m.AddContext(ctx, AnySdkVersion, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil)
- m.AddContext(ctx, AnySdkVersion, "c", optional, buildPath(ctx, "c"), installPath(ctx, "c"), nil)
+ m.AddContext(ctx, AnySdkVersion, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
+ m.AddContext(ctx, AnySdkVersion, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil)
+ m.AddContext(ctx, AnySdkVersion, "c", optional, implicit, buildPath(ctx, "c"), installPath(ctx, "c"), nil)
// Add some libraries with nested subcontexts.
m1 := make(ClassLoaderContextMap)
- m1.AddContext(ctx, AnySdkVersion, "a1", optional, buildPath(ctx, "a1"), installPath(ctx, "a1"), nil)
- m1.AddContext(ctx, AnySdkVersion, "b1", optional, buildPath(ctx, "b1"), installPath(ctx, "b1"), nil)
+ m1.AddContext(ctx, AnySdkVersion, "a1", optional, implicit, buildPath(ctx, "a1"), installPath(ctx, "a1"), nil)
+ m1.AddContext(ctx, AnySdkVersion, "b1", optional, implicit, buildPath(ctx, "b1"), installPath(ctx, "b1"), nil)
m2 := make(ClassLoaderContextMap)
- m2.AddContext(ctx, AnySdkVersion, "a2", optional, buildPath(ctx, "a2"), installPath(ctx, "a2"), nil)
- m2.AddContext(ctx, AnySdkVersion, "b2", optional, buildPath(ctx, "b2"), installPath(ctx, "b2"), nil)
- m2.AddContext(ctx, AnySdkVersion, "c2", optional, buildPath(ctx, "c2"), installPath(ctx, "c2"), m1)
+ m2.AddContext(ctx, AnySdkVersion, "a2", optional, implicit, buildPath(ctx, "a2"), installPath(ctx, "a2"), nil)
+ m2.AddContext(ctx, AnySdkVersion, "b2", optional, implicit, buildPath(ctx, "b2"), installPath(ctx, "b2"), nil)
+ m2.AddContext(ctx, AnySdkVersion, "c2", optional, implicit, buildPath(ctx, "c2"), installPath(ctx, "c2"), m1)
m3 := make(ClassLoaderContextMap)
- m3.AddContext(ctx, AnySdkVersion, "a3", optional, buildPath(ctx, "a3"), installPath(ctx, "a3"), nil)
- m3.AddContext(ctx, AnySdkVersion, "b3", optional, buildPath(ctx, "b3"), installPath(ctx, "b3"), nil)
+ m3.AddContext(ctx, AnySdkVersion, "a3", optional, implicit, buildPath(ctx, "a3"), installPath(ctx, "a3"), nil)
+ m3.AddContext(ctx, AnySdkVersion, "b3", optional, implicit, buildPath(ctx, "b3"), installPath(ctx, "b3"), nil)
- m.AddContext(ctx, AnySdkVersion, "d", optional, buildPath(ctx, "d"), installPath(ctx, "d"), m2)
+ m.AddContext(ctx, AnySdkVersion, "d", optional, implicit, buildPath(ctx, "d"), installPath(ctx, "d"), m2)
// When the same library is both in conditional and unconditional context, it should be removed
// from conditional context.
- m.AddContext(ctx, 42, "f", optional, buildPath(ctx, "f"), installPath(ctx, "f"), nil)
- m.AddContext(ctx, AnySdkVersion, "f", optional, buildPath(ctx, "f"), installPath(ctx, "f"), nil)
+ m.AddContext(ctx, 42, "f", optional, implicit, buildPath(ctx, "f"), installPath(ctx, "f"), nil)
+ m.AddContext(ctx, AnySdkVersion, "f", optional, implicit, buildPath(ctx, "f"), installPath(ctx, "f"), nil)
// Merge map with implicit root library that is among toplevel contexts => does nothing.
m.AddContextMap(m1, "c")
@@ -85,12 +86,12 @@
m.AddContextMap(m3, "m_g")
// Compatibility libraries with unknown install paths get default paths.
- m.AddContext(ctx, 29, AndroidHidlManager, optional, buildPath(ctx, AndroidHidlManager), nil, nil)
- m.AddContext(ctx, 29, AndroidHidlBase, optional, buildPath(ctx, AndroidHidlBase), nil, nil)
+ m.AddContext(ctx, 29, AndroidHidlManager, optional, implicit, buildPath(ctx, AndroidHidlManager), nil, nil)
+ m.AddContext(ctx, 29, AndroidHidlBase, optional, implicit, buildPath(ctx, AndroidHidlBase), nil, nil)
// Add "android.test.mock" to conditional CLC, observe that is gets removed because it is only
// needed as a compatibility library if "android.test.runner" is in CLC as well.
- m.AddContext(ctx, 30, AndroidTestMock, optional, buildPath(ctx, AndroidTestMock), nil, nil)
+ m.AddContext(ctx, 30, AndroidTestMock, optional, implicit, buildPath(ctx, AndroidTestMock), nil, nil)
valid, validationError := validateClassLoaderContext(m)
@@ -164,11 +165,12 @@
func TestCLCJson(t *testing.T) {
ctx := testContext()
optional := false
+ implicit := true
m := make(ClassLoaderContextMap)
- m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
- m.AddContext(ctx, 29, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil)
- m.AddContext(ctx, 30, "c", optional, buildPath(ctx, "c"), installPath(ctx, "c"), nil)
- m.AddContext(ctx, AnySdkVersion, "d", optional, buildPath(ctx, "d"), installPath(ctx, "d"), nil)
+ m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
+ m.AddContext(ctx, 29, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil)
+ m.AddContext(ctx, 30, "c", optional, implicit, buildPath(ctx, "c"), installPath(ctx, "c"), nil)
+ m.AddContext(ctx, AnySdkVersion, "d", optional, implicit, buildPath(ctx, "d"), installPath(ctx, "d"), nil)
jsonCLC := toJsonClassLoaderContext(m)
restored := fromJsonClassLoaderContext(ctx, jsonCLC)
android.AssertIntEquals(t, "The size of the maps should be the same.", len(m), len(restored))
@@ -189,12 +191,13 @@
func testCLCUnknownPath(t *testing.T, whichPath string) {
ctx := testContext()
optional := false
+ implicit := true
m := make(ClassLoaderContextMap)
if whichPath == "build" {
- m.AddContext(ctx, AnySdkVersion, "a", optional, nil, nil, nil)
+ m.AddContext(ctx, AnySdkVersion, "a", optional, implicit, nil, nil, nil)
} else {
- m.AddContext(ctx, AnySdkVersion, "a", optional, buildPath(ctx, "a"), nil, nil)
+ m.AddContext(ctx, AnySdkVersion, "a", optional, implicit, buildPath(ctx, "a"), nil, nil)
}
// The library should be added to <uses-library> tags by the manifest_fixer.
@@ -229,10 +232,11 @@
func TestCLCNestedConditional(t *testing.T) {
ctx := testContext()
optional := false
+ implicit := true
m1 := make(ClassLoaderContextMap)
- m1.AddContext(ctx, 42, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
+ m1.AddContext(ctx, 42, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
m := make(ClassLoaderContextMap)
- err := m.addContext(ctx, AnySdkVersion, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), m1)
+ err := m.addContext(ctx, AnySdkVersion, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), m1)
checkError(t, err, "nested class loader context shouldn't have conditional part")
}
@@ -241,11 +245,12 @@
func TestCLCSdkVersionOrder(t *testing.T) {
ctx := testContext()
optional := false
+ implicit := true
m := make(ClassLoaderContextMap)
- m.AddContext(ctx, 28, "a", optional, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
- m.AddContext(ctx, 29, "b", optional, buildPath(ctx, "b"), installPath(ctx, "b"), nil)
- m.AddContext(ctx, 30, "c", optional, buildPath(ctx, "c"), installPath(ctx, "c"), nil)
- m.AddContext(ctx, AnySdkVersion, "d", optional, buildPath(ctx, "d"), installPath(ctx, "d"), nil)
+ m.AddContext(ctx, 28, "a", optional, implicit, buildPath(ctx, "a"), installPath(ctx, "a"), nil)
+ m.AddContext(ctx, 29, "b", optional, implicit, buildPath(ctx, "b"), installPath(ctx, "b"), nil)
+ m.AddContext(ctx, 30, "c", optional, implicit, buildPath(ctx, "c"), installPath(ctx, "c"), nil)
+ m.AddContext(ctx, AnySdkVersion, "d", optional, implicit, buildPath(ctx, "d"), installPath(ctx, "d"), nil)
valid, validationError := validateClassLoaderContext(m)
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index 4c6ae82..1401c75 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -430,11 +430,6 @@
}
}
- // Never enable on eng.
- if global.IsEng {
- debugInfo = false
- }
-
if debugInfo {
cmd.Flag("--generate-mini-debug-info")
} else {
diff --git a/java/android_manifest.go b/java/android_manifest.go
index 1f7234d..38065f1 100644
--- a/java/android_manifest.go
+++ b/java/android_manifest.go
@@ -71,7 +71,9 @@
args = append(args, "--use-embedded-dex")
}
- requiredUsesLibs, optionalUsesLibs := classLoaderContexts.UsesLibs()
+ // manifest_fixer should add only the implicit SDK libraries inferred by Soong, not those added
+ // explicitly via `uses_libs`/`optional_uses_libs`.
+ requiredUsesLibs, optionalUsesLibs := classLoaderContexts.ImplicitUsesLibs()
for _, usesLib := range requiredUsesLibs {
args = append(args, "--uses-library", usesLib)
}
diff --git a/java/app.go b/java/app.go
index e7661df..5104f07 100755
--- a/java/app.go
+++ b/java/app.go
@@ -1224,17 +1224,28 @@
func (u *usesLibrary) deps(ctx android.BottomUpMutatorContext, hasFrameworkLibs bool) {
if !ctx.Config().UnbundledBuild() || ctx.Config().UnbundledBuildImage() {
- ctx.AddVariationDependencies(nil, usesLibReqTag, u.usesLibraryProperties.Uses_libs...)
- ctx.AddVariationDependencies(nil, usesLibOptTag, u.presentOptionalUsesLibs(ctx)...)
+ reqTag := makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false, false)
+ ctx.AddVariationDependencies(nil, reqTag, u.usesLibraryProperties.Uses_libs...)
+
+ optTag := makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true, false)
+ ctx.AddVariationDependencies(nil, optTag, u.presentOptionalUsesLibs(ctx)...)
+
// Only add these extra dependencies if the module depends on framework libs. This avoids
// creating a cyclic dependency:
// e.g. framework-res -> org.apache.http.legacy -> ... -> framework-res.
if hasFrameworkLibs {
- // Dexpreopt needs paths to the dex jars of these libraries in order to construct
- // class loader context for dex2oat. Add them as a dependency with a special tag.
- ctx.AddVariationDependencies(nil, usesLibCompat29ReqTag, dexpreopt.CompatUsesLibs29...)
- ctx.AddVariationDependencies(nil, usesLibCompat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
- ctx.AddVariationDependencies(nil, usesLibCompat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
+ // Add implicit <uses-library> dependencies on compatibility libraries. Some of them are
+ // optional, and some required --- this depends on the most common usage of the library
+ // and may be wrong for some apps (they need explicit `uses_libs`/`optional_uses_libs`).
+
+ compat28OptTag := makeUsesLibraryDependencyTag(28, true, true)
+ ctx.AddVariationDependencies(nil, compat28OptTag, dexpreopt.OptionalCompatUsesLibs28...)
+
+ compat29ReqTag := makeUsesLibraryDependencyTag(29, false, true)
+ ctx.AddVariationDependencies(nil, compat29ReqTag, dexpreopt.CompatUsesLibs29...)
+
+ compat30OptTag := makeUsesLibraryDependencyTag(30, true, true)
+ ctx.AddVariationDependencies(nil, compat30OptTag, dexpreopt.OptionalCompatUsesLibs30...)
}
}
}
@@ -1293,7 +1304,7 @@
replaceInList(u.usesLibraryProperties.Uses_libs, dep, libName)
replaceInList(u.usesLibraryProperties.Optional_uses_libs, dep, libName)
}
- clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional,
+ clcMap.AddContext(ctx, tag.sdkVersion, libName, tag.optional, tag.implicit,
lib.DexJarBuildPath(), lib.DexJarInstallPath(), lib.ClassLoaderContexts())
} else if ctx.Config().AllowMissingDependencies() {
ctx.AddMissingDependencies([]string{dep})
diff --git a/java/app_test.go b/java/app_test.go
index c14c65d..56ad28d 100644
--- a/java/app_test.go
+++ b/java/app_test.go
@@ -2398,14 +2398,7 @@
expectManifestFixerArgs := `--extract-native-libs=true ` +
`--uses-library qux ` +
`--uses-library quuz ` +
- `--uses-library foo ` + // TODO(b/132357300): "foo" should not be passed to manifest_fixer
- `--uses-library com.non.sdk.lib ` + // TODO(b/132357300): "com.non.sdk.lib" should not be passed to manifest_fixer
- `--uses-library runtime-library ` +
- `--uses-library runtime-required-x ` + // TODO(b/132357300): "runtime-required-x" should not be passed to manifest_fixer
- `--uses-library runtime-required-y ` + // TODO(b/132357300): "runtime-required-y" should not be passed to manifest_fixer
- `--optional-uses-library bar ` + // TODO(b/132357300): "bar" should not be passed to manifest_fixer
- `--optional-uses-library runtime-optional-x ` + // TODO(b/132357300): "runtime-optional-x" should not be passed to manifest_fixer
- `--optional-uses-library runtime-optional-y` // TODO(b/132357300): "runtime-optional-y" should not be passed to manifest_fixer
+ `--uses-library runtime-library`
android.AssertStringEquals(t, "manifest_fixer args", expectManifestFixerArgs, actualManifestFixerArgs)
// Test that all libraries are verified (library order matters).
diff --git a/java/base.go b/java/base.go
index ea5b137..8e6d1cd 100644
--- a/java/base.go
+++ b/java/base.go
@@ -606,10 +606,8 @@
if component, ok := dep.(SdkLibraryComponentDependency); ok {
if lib := component.OptionalSdkLibraryImplementation(); lib != nil {
// Add library as optional if it's one of the optional compatibility libs.
- tag := usesLibReqTag
- if android.InList(*lib, dexpreopt.OptionalCompatUsesLibs) {
- tag = usesLibOptTag
- }
+ optional := android.InList(*lib, dexpreopt.OptionalCompatUsesLibs)
+ tag := makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, optional, true)
ctx.AddVariationDependencies(nil, tag, *lib)
}
}
diff --git a/java/bootclasspath_fragment.go b/java/bootclasspath_fragment.go
index bb542c4..7577316 100644
--- a/java/bootclasspath_fragment.go
+++ b/java/bootclasspath_fragment.go
@@ -538,7 +538,7 @@
global := dexpreopt.GetGlobalConfig(ctx)
possibleUpdatableModules := gatherPossibleApexModuleNamesAndStems(ctx, b.properties.Contents, bootclasspathFragmentContentDepTag)
- jars := global.ApexBootJars.Filter(possibleUpdatableModules)
+ jars, unknown := global.ApexBootJars.Filter(possibleUpdatableModules)
// TODO(satayev): for apex_test we want to include all contents unconditionally to classpaths
// config. However, any test specific jars would not be present in ApexBootJars. Instead,
@@ -546,6 +546,12 @@
// This is an exception to support end-to-end test for SdkExtensions, until such support exists.
if android.InList("test_framework-sdkextensions", possibleUpdatableModules) {
jars = jars.Append("com.android.sdkext", "test_framework-sdkextensions")
+ } else if global.ApexBootJars.Len() != 0 && !android.IsModuleInVersionedSdk(ctx.Module()) {
+ unknown = android.RemoveListFromList(unknown, b.properties.Coverage.Contents)
+ _, unknown = android.RemoveFromList("core-icu4j", unknown)
+ if len(unknown) > 0 {
+ ctx.ModuleErrorf("%s in contents must also be declared in PRODUCT_APEX_BOOT_JARS", unknown)
+ }
}
return jars
}
diff --git a/java/java.go b/java/java.go
index b46324f..4c2ca9b 100644
--- a/java/java.go
+++ b/java/java.go
@@ -248,15 +248,24 @@
type usesLibraryDependencyTag struct {
dependencyTag
- sdkVersion int // SDK version in which the library appared as a standalone library.
- optional bool // If the dependency is optional or required.
+
+ // SDK version in which the library appared as a standalone library.
+ sdkVersion int
+
+ // If the dependency is optional or required.
+ optional bool
+
+ // Whether this is an implicit dependency inferred by Soong, or an explicit one added via
+ // `uses_libs`/`optional_uses_libs` properties.
+ implicit bool
}
-func makeUsesLibraryDependencyTag(sdkVersion int, optional bool) usesLibraryDependencyTag {
+func makeUsesLibraryDependencyTag(sdkVersion int, optional bool, implicit bool) usesLibraryDependencyTag {
return usesLibraryDependencyTag{
dependencyTag: dependencyTag{name: fmt.Sprintf("uses-library-%d", sdkVersion)},
sdkVersion: sdkVersion,
optional: optional,
+ implicit: implicit,
}
}
@@ -285,11 +294,6 @@
syspropPublicStubDepTag = dependencyTag{name: "sysprop public stub"}
jniInstallTag = installDependencyTag{name: "jni install"}
binaryInstallTag = installDependencyTag{name: "binary install"}
- usesLibReqTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, false)
- usesLibOptTag = makeUsesLibraryDependencyTag(dexpreopt.AnySdkVersion, true)
- usesLibCompat28OptTag = makeUsesLibraryDependencyTag(28, true)
- usesLibCompat29ReqTag = makeUsesLibraryDependencyTag(29, false)
- usesLibCompat30OptTag = makeUsesLibraryDependencyTag(30, true)
)
func IsLibDepTag(depTag blueprint.DependencyTag) bool {
@@ -1813,8 +1817,10 @@
depTag := ctx.OtherModuleDependencyTag(depModule)
if depTag == libTag {
// Ok, propagate <uses-library> through non-static library dependencies.
- } else if tag, ok := depTag.(usesLibraryDependencyTag); ok && tag.sdkVersion == dexpreopt.AnySdkVersion {
- // Ok, propagate <uses-library> through non-compatibility <uses-library> dependencies.
+ } else if tag, ok := depTag.(usesLibraryDependencyTag); ok &&
+ tag.sdkVersion == dexpreopt.AnySdkVersion && tag.implicit {
+ // Ok, propagate <uses-library> through non-compatibility implicit <uses-library>
+ // dependencies.
} else if depTag == staticLibTag {
// Propagate <uses-library> through static library dependencies, unless it is a component
// library (such as stubs). Component libraries have a dependency on their SDK library,
@@ -1832,7 +1838,7 @@
// <uses_library> and should not be added to CLC, but the transitive <uses-library> dependencies
// from its CLC should be added to the current CLC.
if sdkLib != nil {
- clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, false,
+ clcMap.AddContext(ctx, dexpreopt.AnySdkVersion, *sdkLib, false, true,
dep.DexJarBuildPath(), dep.DexJarInstallPath(), dep.ClassLoaderContexts())
} else {
clcMap.AddContextMap(dep.ClassLoaderContexts(), depName)
diff --git a/java/systemserver_classpath_fragment.go b/java/systemserver_classpath_fragment.go
index 6c2a5b5..5311f62 100644
--- a/java/systemserver_classpath_fragment.go
+++ b/java/systemserver_classpath_fragment.go
@@ -107,7 +107,16 @@
global := dexpreopt.GetGlobalConfig(ctx)
possibleUpdatableModules := gatherPossibleApexModuleNamesAndStems(ctx, s.properties.Contents, systemServerClasspathFragmentContentDepTag)
- return global.ApexSystemServerJars.Filter(possibleUpdatableModules)
+ jars, unknown := global.ApexSystemServerJars.Filter(possibleUpdatableModules)
+ // TODO(satayev): remove geotz ssc_fragment, since geotz is not part of SSCP anymore.
+ _, unknown = android.RemoveFromList("geotz", unknown)
+
+ // For non test apexes, make sure that all contents are actually declared in make.
+ if global.ApexSystemServerJars.Len() > 0 && len(unknown) > 0 {
+ ctx.ModuleErrorf("%s in contents must also be declared in PRODUCT_UPDATABLE_SYSTEM_SERVER_JARS", unknown)
+ }
+
+ return jars
}
type systemServerClasspathFragmentContentDependencyTag struct {
diff --git a/python/python.go b/python/python.go
index 0f5b788..83844e6 100644
--- a/python/python.go
+++ b/python/python.go
@@ -675,7 +675,7 @@
if !isPythonLibModule(child) {
ctx.PropertyErrorf("libs",
"the dependency %q of module %q is not Python library!",
- ctx.ModuleName(), ctx.OtherModuleName(child))
+ ctx.OtherModuleName(child), ctx.ModuleName())
}
// collect source and data paths, checking that there are no duplicate output file conflicts
if dep, ok := child.(pythonDependency); ok {
diff --git a/rust/compiler.go b/rust/compiler.go
index d9e21ff..7bd9af4 100644
--- a/rust/compiler.go
+++ b/rust/compiler.go
@@ -397,8 +397,15 @@
}
if compiler.location == InstallInData && ctx.RustModule().UseVndk() {
- dir = filepath.Join(dir, "vendor")
+ if ctx.RustModule().InProduct() {
+ dir = filepath.Join(dir, "product")
+ } else if ctx.RustModule().InVendor() {
+ dir = filepath.Join(dir, "vendor")
+ } else {
+ ctx.ModuleErrorf("Unknown data+VNDK installation kind")
+ }
}
+
return android.PathForModuleInstall(ctx, dir, compiler.subDir,
compiler.relativeInstallPath(), compiler.relative)
}
diff --git a/rust/config/allowed_list.go b/rust/config/allowed_list.go
index 926d2ac..ee9be6e 100644
--- a/rust/config/allowed_list.go
+++ b/rust/config/allowed_list.go
@@ -25,6 +25,7 @@
"system/extras/simpleperf",
"system/hardware/interfaces/keystore2",
"system/librustutils",
+ "system/logging/liblog",
"system/logging/rust",
"system/security",
"system/tools/aidl",
diff --git a/rust/doc.go b/rust/doc.go
index e7f1371..fe3581b 100644
--- a/rust/doc.go
+++ b/rust/doc.go
@@ -29,6 +29,14 @@
type rustdocSingleton struct{}
func (n *rustdocSingleton) GenerateBuildActions(ctx android.SingletonContext) {
+ docDir := android.PathForOutput(ctx, "rustdoc")
+ docZip := android.PathForOutput(ctx, "rustdoc.zip")
+ rule := android.NewRuleBuilder(pctx, ctx)
+ zipCmd := rule.Command().BuiltTool("soong_zip").
+ FlagWithOutput("-o ", docZip).
+ FlagWithArg("-C ", docDir.String()).
+ FlagWithArg("-D ", docDir.String())
+
ctx.VisitAllModules(func(module android.Module) {
if !module.Enabled() {
return
@@ -36,8 +44,10 @@
if m, ok := module.(*Module); ok {
if m.docTimestampFile.Valid() {
- ctx.Phony("rustdoc", m.docTimestampFile.Path())
+ zipCmd.Implicit(m.docTimestampFile.Path())
}
}
})
+ rule.Build("rustdoc-zip", "Zipping all built Rust documentation...")
+ ctx.Phony("rustdoc", docZip)
}
diff --git a/rust/image.go b/rust/image.go
index 5d7c027..5d57f15 100644
--- a/rust/image.go
+++ b/rust/image.go
@@ -136,7 +136,13 @@
}
func (ctx *moduleContext) ProductSpecific() bool {
- return false
+ return ctx.ModuleContext.ProductSpecific() || ctx.RustModule().productSpecificModuleContext()
+}
+
+func (c *Module) productSpecificModuleContext() bool {
+ // Additionally check if this module is inProduct() that means it is a "product" variant of a
+ // module. As well as product specific modules, product variants must be installed to /product.
+ return c.InProduct()
}
func (mod *Module) InRecovery() bool {
diff --git a/rust/rust.go b/rust/rust.go
index ba395ec..0cd299d 100644
--- a/rust/rust.go
+++ b/rust/rust.go
@@ -1233,6 +1233,18 @@
return mod.compiler.inData()
}
+func (mod *Module) InstallInRamdisk() bool {
+ return mod.InRamdisk()
+}
+
+func (mod *Module) InstallInVendorRamdisk() bool {
+ return mod.InVendorRamdisk()
+}
+
+func (mod *Module) InstallInRecovery() bool {
+ return mod.InRecovery()
+}
+
func linkPathFromFilePath(filepath android.Path) string {
return strings.Split(filepath.String(), filepath.Base())[0]
}
diff --git a/scripts/build-rustdocs.sh b/scripts/build-rustdocs.sh
index ad8ba16..fda9688 100755
--- a/scripts/build-rustdocs.sh
+++ b/scripts/build-rustdocs.sh
@@ -27,5 +27,5 @@
if [ -n "${DIST_DIR}" ]; then
mkdir -p ${DIST_DIR}
- cp -r ${OUT_DIR}/soong/rustdoc $DIST_DIR/rustdoc
+ cp ${OUT_DIR}/soong/rustdoc.zip $DIST_DIR
fi