Merge changes Ia165e4be,I63fe74fb
* changes:
Update sanitize to not modify user properties
Extend sanitize_test.go
diff --git a/android/allowlists/allowlists.go b/android/allowlists/allowlists.go
index bf39404..e7bd920 100644
--- a/android/allowlists/allowlists.go
+++ b/android/allowlists/allowlists.go
@@ -166,6 +166,7 @@
"external/minijail": Bp2BuildDefaultTrueRecursively,
"external/objenesis": Bp2BuildDefaultTrueRecursively,
"external/openscreen": Bp2BuildDefaultTrueRecursively,
+ "external/ow2-asm": Bp2BuildDefaultTrueRecursively,
"external/pcre": Bp2BuildDefaultTrueRecursively,
"external/protobuf": Bp2BuildDefaultTrueRecursively,
"external/python/six": Bp2BuildDefaultTrueRecursively,
@@ -373,9 +374,12 @@
"packages/apps/Music":/* recursive = */ true,
"packages/apps/QuickSearchBox":/* recursive = */ true,
+ "prebuilts/abi-dumps/platform":/* recursive = */ true,
+ "prebuilts/abi-dumps/ndk":/* recursive = */ true,
"prebuilts/bazel":/* recursive = */ true,
"prebuilts/bundletool":/* recursive = */ true,
"prebuilts/clang/host/linux-x86":/* recursive = */ false,
+ "prebuilts/clang-tools":/* recursive = */ true,
"prebuilts/gcc":/* recursive = */ true,
"prebuilts/build-tools":/* recursive = */ true,
"prebuilts/jdk/jdk11":/* recursive = */ false,
@@ -383,8 +387,11 @@
"prebuilts/sdk":/* recursive = */ false,
"prebuilts/sdk/tools":/* recursive = */ false,
"prebuilts/r8":/* recursive = */ false,
+ "prebuilts/runtime":/* recursive = */ false,
- "tools/asuite/atest/":/* recursive = */ true,
+ // not recursive due to conflicting workspace paths in tools/atest/bazel/rules
+ "tools/asuite/atest":/* recursive = */ false,
+ "tools/asuite/atest/bazel/reporter":/* recursive = */ true,
}
Bp2buildModuleAlwaysConvertList = []string{
@@ -725,7 +732,6 @@
// aar support
"prebuilt_car-ui-androidx-core-common", // TODO(b/224773339), genrule dependency creates an .aar, not a .jar
- "prebuilt_platform-robolectric-4.4-prebuilt", // aosp/1999250, needs .aar support in Jars
"prebuilt_platform-robolectric-4.5.1-prebuilt", // aosp/1999250, needs .aar support in Jars
// ERROR: The dependencies for the following 1 jar(s) are not complete.
// 1.bazel-out/android_target-fastbuild/bin/prebuilts/tools/common/m2/_aar/robolectric-monitor-1.0.2-alpha1/classes_and_libs_merged.jar
@@ -1344,14 +1350,13 @@
"prebuilt_kotlin-stdlib-jdk8",
"prebuilt_kotlin-test",
// TODO(b/217750501) exclude_files property not supported
- "prebuilt_platform-robolectric-4.4-prebuilt",
"prebuilt_platform-robolectric-4.5.1-prebuilt",
"prebuilt_currysrc_org.eclipse",
}
// Bazel prod-mode allowlist. Modules in this list are built by Bazel
// in either prod mode or staging mode.
- ProdMixedBuildsEnabledList = []string{}
+ ProdMixedBuildsEnabledList = []string{"com.android.tzdata"}
// Staging-mode allowlist. Modules in this list are only built
// by Bazel with --bazel-mode-staging. This list should contain modules
diff --git a/android/bazel.go b/android/bazel.go
index 60989f6..3731dfe 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -383,6 +383,9 @@
// mixedBuildPossible returns true if a module is ready to be replaced by a
// converted or handcrafted Bazel target.
func mixedBuildPossible(ctx BaseModuleContext) bool {
+ if !ctx.Config().IsMixedBuildsEnabled() {
+ return false
+ }
if ctx.Os() == Windows {
// Windows toolchains are not currently supported.
return false
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index e2751d6..acb81a4 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -81,7 +81,7 @@
// all request-relevant information about a target and returns a string containing
// this information.
// The function should have the following properties:
- // - `target` is the only parameter to this function (a configured target).
+ // - The arguments are `target` (a configured target) and `id_string` (the label + configuration).
// - The return value must be a string.
// - The function body should not be indented outside of its own scope.
StarlarkFunctionBody() string
@@ -743,12 +743,12 @@
}
`
functionDefFormatString := `
-def %s(target):
+def %s(target, id_string):
%s
`
mainSwitchSectionFormatString := `
if id_string in %s:
- return id_string + ">>" + %s(target)
+ return id_string + ">>" + %s(target, id_string)
`
for requestType := range requestTypeToCqueryIdEntries {
@@ -1050,18 +1050,26 @@
for _, depset := range ctx.Config().BazelContext.AqueryDepsets() {
var outputs []Path
+ var orderOnlies []Path
for _, depsetDepHash := range depset.TransitiveDepSetHashes {
otherDepsetName := bazelDepsetName(depsetDepHash)
outputs = append(outputs, PathForPhony(ctx, otherDepsetName))
}
for _, artifactPath := range depset.DirectArtifacts {
- outputs = append(outputs, PathForBazelOut(ctx, artifactPath))
+ pathInBazelOut := PathForBazelOut(ctx, artifactPath)
+ if artifactPath == "bazel-out/volatile-status.txt" {
+ // See https://bazel.build/docs/user-manual#workspace-status
+ orderOnlies = append(orderOnlies, pathInBazelOut)
+ } else {
+ outputs = append(outputs, pathInBazelOut)
+ }
}
thisDepsetName := bazelDepsetName(depset.ContentHash)
ctx.Build(pctx, BuildParams{
Rule: blueprint.Phony,
Outputs: []WritablePath{PathForPhony(ctx, thisDepsetName)},
Implicits: outputs,
+ OrderOnly: orderOnlies,
})
}
diff --git a/android/config.go b/android/config.go
index 1deb7d4..f430b72 100644
--- a/android/config.go
+++ b/android/config.go
@@ -536,7 +536,40 @@
// Returns true if "Bazel builds" is enabled. In this mode, part of build
// analysis is handled by Bazel.
func (c *config) IsMixedBuildsEnabled() bool {
- return c.BuildMode == BazelProdMode || c.BuildMode == BazelDevMode || c.BuildMode == BazelStagingMode
+ globalMixedBuildsSupport := c.Once(OnceKey{"globalMixedBuildsSupport"}, func() interface{} {
+ if c.productVariables.DeviceArch != nil && *c.productVariables.DeviceArch == "riscv64" {
+ fmt.Fprintln(os.Stderr, "unsupported device arch 'riscv64' for Bazel: falling back to non-mixed build")
+ return false
+ }
+ if c.IsEnvTrue("GLOBAL_THINLTO") {
+ fmt.Fprintln(os.Stderr, "unsupported env var GLOBAL_THINLTO for Bazel: falling back to non-mixed build")
+ return false
+ }
+ if c.IsEnvTrue("CLANG_COVERAGE") {
+ fmt.Fprintln(os.Stderr, "unsupported env var CLANG_COVERAGE for Bazel: falling back to non-mixed build")
+ return false
+ }
+ if len(c.productVariables.SanitizeHost) > 0 {
+ fmt.Fprintln(os.Stderr, "unsupported product var SanitizeHost for Bazel: falling back to non-mixed build")
+ return false
+ }
+ if len(c.productVariables.SanitizeDevice) > 0 {
+ fmt.Fprintln(os.Stderr, "unsupported product var SanitizeDevice for Bazel: falling back to non-mixed build")
+ return false
+ }
+ if len(c.productVariables.SanitizeDeviceDiag) > 0 {
+ fmt.Fprintln(os.Stderr, "unsupported product var SanitizeDeviceDiag for Bazel: falling back to non-mixed build")
+ return false
+ }
+ if len(c.productVariables.SanitizeDeviceArch) > 0 {
+ fmt.Fprintln(os.Stderr, "unsupported product var SanitizeDeviceArch for Bazel: falling back to non-mixed build")
+ return false
+ }
+ return true
+ }).(bool)
+
+ bazelModeEnabled := c.BuildMode == BazelProdMode || c.BuildMode == BazelDevMode || c.BuildMode == BazelStagingMode
+ return globalMixedBuildsSupport && bazelModeEnabled
}
func (c *config) SetAllowMissingDependencies() {
diff --git a/android/filegroup.go b/android/filegroup.go
index af4d89a..d21d146 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -122,16 +122,18 @@
if fg.ShouldConvertToProtoLibrary(ctx) {
// TODO(b/246997908): we can remove this tag if we could figure out a
// solution for this bug.
- tags := []string{"manual"}
attrs := &ProtoAttrs{
Srcs: srcs,
Strip_import_prefix: fg.properties.Path,
- Tags: tags,
}
+ tags := []string{"manual"}
ctx.CreateBazelTargetModule(
bazel.BazelTargetModuleProperties{Rule_class: "proto_library"},
- CommonAttributes{Name: fg.Name() + convertedProtoLibrarySuffix},
+ CommonAttributes{
+ Name: fg.Name() + convertedProtoLibrarySuffix,
+ Tags: bazel.MakeStringListAttribute(tags),
+ },
attrs)
}
diff --git a/android/license.go b/android/license.go
index cde5e6e..ab8431a 100644
--- a/android/license.go
+++ b/android/license.go
@@ -15,10 +15,12 @@
package android
import (
- "android/soong/bazel"
"fmt"
- "github.com/google/blueprint"
"os"
+
+ "github.com/google/blueprint"
+
+ "android/soong/bazel"
)
type licenseKindDependencyTag struct {
@@ -101,6 +103,14 @@
}
func (m *licenseModule) DepsMutator(ctx BottomUpMutatorContext) {
+ for i, license := range m.properties.License_kinds {
+ for j := i + 1; j < len(m.properties.License_kinds); j++ {
+ if license == m.properties.License_kinds[j] {
+ ctx.ModuleErrorf("Duplicated license kind: %q", license)
+ break
+ }
+ }
+ }
ctx.AddVariationDependencies(nil, licenseKindTag, m.properties.License_kinds...)
}
diff --git a/android/license_test.go b/android/license_test.go
index 7222cd7..89e7f06 100644
--- a/android/license_test.go
+++ b/android/license_test.go
@@ -90,6 +90,36 @@
},
},
{
+ name: "must not duplicate license_kind",
+ fs: map[string][]byte{
+ "top/Android.bp": []byte(`
+ license_kind {
+ name: "top_by_exception_only",
+ conditions: ["by_exception_only"],
+ visibility: ["//visibility:private"],
+ }
+
+ license_kind {
+ name: "top_by_exception_only_2",
+ conditions: ["by_exception_only"],
+ visibility: ["//visibility:private"],
+ }
+
+ license {
+ name: "top_proprietary",
+ license_kinds: [
+ "top_by_exception_only",
+ "top_by_exception_only_2",
+ "top_by_exception_only"
+ ],
+ visibility: ["//visibility:public"],
+ }`),
+ },
+ expectedErrors: []string{
+ `top/Android.bp:14:5: module "top_proprietary": Duplicated license kind: "top_by_exception_only"`,
+ },
+ },
+ {
name: "license_kind module must exist",
fs: map[string][]byte{
"top/Android.bp": []byte(`
diff --git a/android/module.go b/android/module.go
index b41a898..681f724 100644
--- a/android/module.go
+++ b/android/module.go
@@ -2053,7 +2053,7 @@
}
func (m *ModuleBase) InstallInVendor() bool {
- return Bool(m.commonProperties.Vendor)
+ return Bool(m.commonProperties.Vendor) || Bool(m.commonProperties.Soc_specific) || Bool(m.commonProperties.Proprietary)
}
func (m *ModuleBase) InstallInRoot() bool {
diff --git a/android/neverallow.go b/android/neverallow.go
index 293bac8..ad9880a 100644
--- a/android/neverallow.go
+++ b/android/neverallow.go
@@ -59,6 +59,7 @@
AddNeverAllowRules(createInitFirstStageRules()...)
AddNeverAllowRules(createProhibitFrameworkAccessRules()...)
AddNeverAllowRules(createBp2BuildRule())
+ AddNeverAllowRules(createCcStubsRule())
}
// Add a NeverAllow rule to the set of rules to apply.
@@ -214,6 +215,17 @@
}
}
+func createCcStubsRule() Rule {
+ ccStubsImplementationInstallableProjectsAllowedList := []string{
+ "packages/modules/Virtualization/vm_payload",
+ }
+
+ return NeverAllow().
+ NotIn(ccStubsImplementationInstallableProjectsAllowedList...).
+ WithMatcher("stubs.implementation_installable", isSetMatcherInstance).
+ Because("implementation_installable can only be used in allowed projects.")
+}
+
func createUncompressDexRules() []Rule {
return []Rule{
NeverAllow().
diff --git a/android/neverallow_test.go b/android/neverallow_test.go
index 4772799..5f5f9a1 100644
--- a/android/neverallow_test.go
+++ b/android/neverallow_test.go
@@ -367,6 +367,22 @@
"framework can't be used when building against SDK",
},
},
+ // Test for the rule restricting use of implementation_installable
+ {
+ name: `"implementation_installable" outside allowed list`,
+ fs: map[string][]byte{
+ "Android.bp": []byte(`
+ cc_library {
+ name: "outside_allowed_list",
+ stubs: {
+ implementation_installable: true,
+ },
+ }`),
+ },
+ expectedErrors: []string{
+ `module "outside_allowed_list": violates neverallow`,
+ },
+ },
}
var prepareForNeverAllowTest = GroupFixturePreparers(
@@ -419,6 +435,10 @@
Platform struct {
Shared_libs []string
}
+
+ Stubs struct {
+ Implementation_installable *bool
+ }
}
type mockCcLibraryModule struct {
diff --git a/android/proto.go b/android/proto.go
index 3cac9a1..8204f77 100644
--- a/android/proto.go
+++ b/android/proto.go
@@ -164,7 +164,6 @@
Srcs bazel.LabelListAttribute
Strip_import_prefix *string
Deps bazel.LabelListAttribute
- Tags []string
}
// For each package in the include_dirs property a proto_library target should
diff --git a/android/test_config.go b/android/test_config.go
index de546c4..70c319a 100644
--- a/android/test_config.go
+++ b/android/test_config.go
@@ -62,6 +62,7 @@
TestAllowNonExistentPaths: true,
BazelContext: noopBazelContext{},
+ BuildMode: BazelProdMode,
mixedBuildDisabledModules: make(map[string]struct{}),
mixedBuildEnabledModules: make(map[string]struct{}),
}
diff --git a/apex/apex.go b/apex/apex.go
index 04808c1..b1b4e47 100644
--- a/apex/apex.go
+++ b/apex/apex.go
@@ -2301,7 +2301,7 @@
//
// Always include if we are a host-apex however since those won't have any
// system libraries.
- if !am.DirectlyInAnyApex() {
+ if ch.IsStubsImplementationRequired() && !am.DirectlyInAnyApex() {
// we need a module name for Make
name := ch.ImplementationModuleNameForMake(ctx) + ch.Properties.SubName
if !android.InList(name, a.requiredDeps) {
diff --git a/apex/apex_test.go b/apex/apex_test.go
index ea3e734..883c3c8 100644
--- a/apex/apex_test.go
+++ b/apex/apex_test.go
@@ -8413,6 +8413,30 @@
}
}
+func TestApexSet_NativeBridge(t *testing.T) {
+ ctx := testApex(t, `
+ apex_set {
+ name: "myapex",
+ set: "myapex.apks",
+ filename: "foo_v2.apex",
+ overrides: ["foo"],
+ }
+ `,
+ android.FixtureModifyConfig(func(config android.Config) {
+ config.Targets[android.Android] = []android.Target{
+ {Os: android.Android, Arch: android.Arch{ArchType: android.X86_64, ArchVariant: "", Abi: []string{"x86_64"}}},
+ {Os: android.Android, Arch: android.Arch{ArchType: android.Arm64, ArchVariant: "armv8-a", Abi: []string{"arm64-v8a"}}, NativeBridge: android.NativeBridgeEnabled},
+ }
+ }),
+ )
+
+ m := ctx.ModuleForTests("myapex.apex.extractor", "android_common")
+
+ // Check extract_apks tool parameters. No native bridge arch expected
+ extractedApex := m.Output("extracted/myapex.apks")
+ android.AssertStringEquals(t, "abis", "X86_64", extractedApex.Args["abis"])
+}
+
func TestNoStaticLinkingToStubsLib(t *testing.T) {
testApexError(t, `.*required by "mylib" is a native library providing stub.*`, `
apex {
diff --git a/apex/prebuilt.go b/apex/prebuilt.go
index 39446a1..6fdd50a 100644
--- a/apex/prebuilt.go
+++ b/apex/prebuilt.go
@@ -24,6 +24,7 @@
"android/soong/android"
"android/soong/java"
"android/soong/provenance"
+
"github.com/google/blueprint"
"github.com/google/blueprint/proptools"
)
@@ -831,6 +832,8 @@
}
apexSet := android.SingleSourcePathFromSupplier(ctx, srcsSupplier, "set")
p.extractedApex = android.PathForModuleOut(ctx, "extracted", apexSet.Base())
+ // Filter out NativeBridge archs (b/260115309)
+ abis := java.SupportedAbis(ctx, true)
ctx.Build(pctx,
android.BuildParams{
Rule: extractMatchingApex,
@@ -838,7 +841,7 @@
Inputs: android.Paths{apexSet},
Output: p.extractedApex,
Args: map[string]string{
- "abis": strings.Join(java.SupportedAbis(ctx), ","),
+ "abis": strings.Join(abis, ","),
"allow-prereleased": strconv.FormatBool(proptools.Bool(p.properties.Prerelease)),
"sdk-version": ctx.Config().PlatformSdkVersion().String(),
},
diff --git a/bazel/configurability.go b/bazel/configurability.go
index a93aa00..3f4cc73 100644
--- a/bazel/configurability.go
+++ b/bazel/configurability.go
@@ -203,6 +203,11 @@
osAndInApexMap = map[string]string{
AndroidAndInApex: "//build/bazel/rules/apex:android-in_apex",
AndroidAndNonApex: "//build/bazel/rules/apex:android-non_apex",
+ osDarwin: "//build/bazel/platforms/os:darwin",
+ osLinux: "//build/bazel/platforms/os:linux",
+ osLinuxMusl: "//build/bazel/platforms/os:linux_musl",
+ osLinuxBionic: "//build/bazel/platforms/os:linux_bionic",
+ osWindows: "//build/bazel/platforms/os:windows",
ConditionsDefaultConfigKey: ConditionsDefaultSelectKey,
}
diff --git a/bazel/cquery/request_type.go b/bazel/cquery/request_type.go
index b675f17..e4830d3 100644
--- a/bazel/cquery/request_type.go
+++ b/bazel/cquery/request_type.go
@@ -50,7 +50,7 @@
// all request-relevant information about a target and returns a string containing
// this information.
// The function should have the following properties:
-// - `target` is the only parameter to this function (a configured target).
+// - The arguments are `target` (a configured target) and `id_string` (the label + configuration).
// - The return value must be a string.
// - The function body should not be indented outside of its own scope.
func (g getOutputFilesRequestType) StarlarkFunctionBody() string {
@@ -75,7 +75,7 @@
// all request-relevant information about a target and returns a string containing
// this information.
// The function should have the following properties:
-// - `target` is the only parameter to this function (a configured target).
+// - The arguments are `target` (a configured target) and `id_string` (the label + configuration).
// - The return value must be a string.
// - The function body should not be indented outside of its own scope.
func (g getPythonBinaryRequestType) StarlarkFunctionBody() string {
@@ -102,13 +102,16 @@
// all request-relevant information about a target and returns a string containing
// this information.
// The function should have the following properties:
-// - `target` is the only parameter to this function (a configured target).
+// - The arguments are `target` (a configured target) and `id_string` (the label + configuration).
// - The return value must be a string.
// - The function body should not be indented outside of its own scope.
func (g getCcInfoType) StarlarkFunctionBody() string {
return `
outputFiles = [f.path for f in target.files.to_list()]
-cc_info = providers(target)["CcInfo"]
+p = providers(target)
+cc_info = p.get("CcInfo")
+if not cc_info:
+ fail("%s did not provide CcInfo" % id_string)
includes = cc_info.compilation_context.includes.to_list()
system_includes = cc_info.compilation_context.system_includes.to_list()
@@ -120,8 +123,8 @@
linker_inputs = cc_info.linking_context.linker_inputs.to_list()
static_info_tag = "//build/bazel/rules/cc:cc_library_static.bzl%CcStaticLibraryInfo"
-if static_info_tag in providers(target):
- static_info = providers(target)[static_info_tag]
+if static_info_tag in p:
+ static_info = p[static_info_tag]
ccObjectFiles = [f.path for f in static_info.objects]
rootStaticArchives = [static_info.root_static_archive.path]
else:
@@ -141,14 +144,14 @@
unstripped_tag = "//build/bazel/rules/cc:stripped_cc_common.bzl%CcUnstrippedInfo"
unstripped = ""
-if shared_info_tag in providers(target):
- shared_info = providers(target)[shared_info_tag]
+if shared_info_tag in p:
+ shared_info = p[shared_info_tag]
path = shared_info.output_file.path
sharedLibraries.append(path)
rootSharedLibraries += [path]
unstripped = path
- if unstripped_tag in providers(target):
- unstripped = providers(target)[unstripped_tag].unstripped.path
+ if unstripped_tag in p:
+ unstripped = p[unstripped_tag].unstripped.path
else:
for linker_input in linker_inputs:
for library in linker_input.libraries:
@@ -160,14 +163,13 @@
toc_file = ""
toc_file_tag = "//build/bazel/rules/cc:generate_toc.bzl%CcTocInfo"
-if toc_file_tag in providers(target):
- toc_file = providers(target)[toc_file_tag].toc.path
+if toc_file_tag in p:
+ toc_file = p[toc_file_tag].toc.path
else:
# NOTE: It's OK if there's no ToC, as Soong just uses it for optimization
pass
tidy_files = []
-p = providers(target)
clang_tidy_info = p.get("//build/bazel/rules/cc:clang_tidy.bzl%ClangTidyInfo")
if clang_tidy_info:
tidy_files = [v.path for v in clang_tidy_info.tidy_files.to_list()]
@@ -213,11 +215,14 @@
// The returned string is the body of a Starlark function which obtains
// all request-relevant information about a target and returns a string containing
// this information. The function should have the following properties:
-// - `target` is the only parameter to this function (a configured target).
+// - The arguments are `target` (a configured target) and `id_string` (the label + configuration).
// - The return value must be a string.
// - The function body should not be indented outside of its own scope.
func (g getApexInfoType) StarlarkFunctionBody() string {
- return `info = providers(target)["//build/bazel/rules/apex:apex.bzl%ApexInfo"]
+ return `
+info = providers(target).get("//build/bazel/rules/apex:apex.bzl%ApexInfo")
+if not info:
+ fail("%s did not provide ApexInfo" % id_string)
bundle_key_info = info.bundle_key_info
container_key_info = info.container_key_info
return json_encode({
diff --git a/bazel/properties.go b/bazel/properties.go
index 823cda8..ee9609a 100644
--- a/bazel/properties.go
+++ b/bazel/properties.go
@@ -843,6 +843,26 @@
// ResolveExcludes handles excludes across the various axes, ensuring that items are removed from
// the base value and included in default values as appropriate.
func (lla *LabelListAttribute) ResolveExcludes() {
+ // If there are OsAndInApexAxis, we need to use
+ // * includes from the OS & in APEX Axis for non-Android configs for libraries that need to be
+ // included in non-Android OSes
+ // * excludes from the OS Axis for non-Android configs, to exclude libraries that should _not_
+ // be included in the non-Android OSes
+ if _, ok := lla.ConfigurableValues[OsAndInApexAxis]; ok {
+ inApexLabels := lla.ConfigurableValues[OsAndInApexAxis][ConditionsDefaultConfigKey]
+ for config, labels := range lla.ConfigurableValues[OsConfigurationAxis] {
+ // OsAndroid has already handled its excludes.
+ // We only need to copy the excludes from other arches, so if there are none, skip it.
+ if config == OsAndroid || len(labels.Excludes) == 0 {
+ continue
+ }
+ lla.ConfigurableValues[OsAndInApexAxis][config] = LabelList{
+ Includes: inApexLabels.Includes,
+ Excludes: labels.Excludes,
+ }
+ }
+ }
+
for axis, configToLabels := range lla.ConfigurableValues {
baseLabels := lla.Value.deepCopy()
for config, val := range configToLabels {
diff --git a/bp2build/cc_library_conversion_test.go b/bp2build/cc_library_conversion_test.go
index 4c86374..edb0c43 100644
--- a/bp2build/cc_library_conversion_test.go
+++ b/bp2build/cc_library_conversion_test.go
@@ -1409,6 +1409,7 @@
"strip": true,
"inject_bssl_hash": true,
"has_stubs": true,
+ "stubs_symbol_file": true,
"use_version_lib": true,
}
@@ -2710,7 +2711,8 @@
func TestCcLibraryStubs(t *testing.T) {
expectedBazelTargets := makeCcLibraryTargets("a", AttrNameToString{
- "has_stubs": `True`,
+ "has_stubs": `True`,
+ "stubs_symbol_file": `"a.map.txt"`,
})
expectedBazelTargets = append(expectedBazelTargets, makeCcStubSuiteTargets("a", AttrNameToString{
"soname": `"a.so"`,
@@ -2976,6 +2978,63 @@
})
}
+func TestCcLibraryExcludesLibsHost(t *testing.T) {
+ runCcLibraryTestCase(t, Bp2buildTestCase{
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Filesystem: map[string]string{
+ "bar.map.txt": "",
+ },
+ Blueprint: simpleModuleDoNotConvertBp2build("cc_library", "bazlib") + `
+cc_library {
+ name: "quxlib",
+ stubs: { symbol_file: "bar.map.txt", versions: ["current"] },
+ bazel_module: { bp2build_available: false },
+}
+cc_library {
+ name: "barlib",
+ stubs: { symbol_file: "bar.map.txt", versions: ["28", "29", "current"] },
+ bazel_module: { bp2build_available: false },
+}
+cc_library {
+ name: "foolib",
+ shared_libs: ["barlib", "quxlib"],
+ target: {
+ host: {
+ shared_libs: ["bazlib"],
+ exclude_shared_libs: ["barlib"],
+ },
+ },
+ include_build_directory: false,
+ bazel_module: { bp2build_available: true },
+}`,
+ ExpectedBazelTargets: makeCcLibraryTargets("foolib", AttrNameToString{
+ "implementation_dynamic_deps": `select({
+ "//build/bazel/platforms/os:darwin": [":bazlib"],
+ "//build/bazel/platforms/os:linux": [":bazlib"],
+ "//build/bazel/platforms/os:linux_bionic": [":bazlib"],
+ "//build/bazel/platforms/os:linux_musl": [":bazlib"],
+ "//build/bazel/platforms/os:windows": [":bazlib"],
+ "//conditions:default": [],
+ }) + select({
+ "//build/bazel/platforms/os:darwin": [":quxlib"],
+ "//build/bazel/platforms/os:linux": [":quxlib"],
+ "//build/bazel/platforms/os:linux_bionic": [":quxlib"],
+ "//build/bazel/platforms/os:linux_musl": [":quxlib"],
+ "//build/bazel/platforms/os:windows": [":quxlib"],
+ "//build/bazel/rules/apex:android-in_apex": [
+ ":barlib_stub_libs_current",
+ ":quxlib_stub_libs_current",
+ ],
+ "//conditions:default": [
+ ":barlib",
+ ":quxlib",
+ ],
+ })`,
+ }),
+ })
+}
+
func TestCcLibraryEscapeLdflags(t *testing.T) {
runCcLibraryTestCase(t, Bp2buildTestCase{
ModuleTypeUnderTest: "cc_library",
@@ -3543,3 +3602,46 @@
},
})
}
+
+func TestCcLibraryHeaderAbiChecker(t *testing.T) {
+ runCcLibraryTestCase(t, Bp2buildTestCase{
+ Description: "cc_library with header abi checker",
+ ModuleTypeUnderTest: "cc_library",
+ ModuleTypeUnderTestFactory: cc.LibraryFactory,
+ Blueprint: `cc_library {
+ name: "foo",
+ header_abi_checker: {
+ enabled: true,
+ symbol_file: "a.map.txt",
+ exclude_symbol_versions: [
+ "29",
+ "30",
+ ],
+ exclude_symbol_tags: [
+ "tag1",
+ "tag2",
+ ],
+ check_all_apis: true,
+ diff_flags: ["-allow-adding-removing-weak-symbols"],
+ },
+ include_build_directory: false,
+}`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_static", "foo_bp2build_cc_library_static", AttrNameToString{}),
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "abi_checker_enabled": `True`,
+ "abi_checker_symbol_file": `"a.map.txt"`,
+ "abi_checker_exclude_symbol_versions": `[
+ "29",
+ "30",
+ ]`,
+ "abi_checker_exclude_symbol_tags": `[
+ "tag1",
+ "tag2",
+ ]`,
+ "abi_checker_check_all_apis": `True`,
+ "abi_checker_diff_flags": `["-allow-adding-removing-weak-symbols"]`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/cc_library_shared_conversion_test.go b/bp2build/cc_library_shared_conversion_test.go
index b86f607..7e1d111 100644
--- a/bp2build/cc_library_shared_conversion_test.go
+++ b/bp2build/cc_library_shared_conversion_test.go
@@ -543,7 +543,8 @@
]`,
}),
MakeBazelTarget("cc_library_shared", "a", AttrNameToString{
- "has_stubs": `True`,
+ "has_stubs": `True`,
+ "stubs_symbol_file": `"a.map.txt"`,
}),
},
})
@@ -845,3 +846,43 @@
},
})
}
+
+func TestCcLibrarySharedHeaderAbiChecker(t *testing.T) {
+ runCcLibrarySharedTestCase(t, Bp2buildTestCase{
+ Description: "cc_library_shared with header abi checker",
+ Blueprint: `cc_library_shared {
+ name: "foo",
+ header_abi_checker: {
+ enabled: true,
+ symbol_file: "a.map.txt",
+ exclude_symbol_versions: [
+ "29",
+ "30",
+ ],
+ exclude_symbol_tags: [
+ "tag1",
+ "tag2",
+ ],
+ check_all_apis: true,
+ diff_flags: ["-allow-adding-removing-weak-symbols"],
+ },
+ include_build_directory: false,
+}`,
+ ExpectedBazelTargets: []string{
+ MakeBazelTarget("cc_library_shared", "foo", AttrNameToString{
+ "abi_checker_enabled": `True`,
+ "abi_checker_symbol_file": `"a.map.txt"`,
+ "abi_checker_exclude_symbol_versions": `[
+ "29",
+ "30",
+ ]`,
+ "abi_checker_exclude_symbol_tags": `[
+ "tag1",
+ "tag2",
+ ]`,
+ "abi_checker_check_all_apis": `True`,
+ "abi_checker_diff_flags": `["-allow-adding-removing-weak-symbols"]`,
+ }),
+ },
+ })
+}
diff --git a/bp2build/java_library_conversion_test.go b/bp2build/java_library_conversion_test.go
index 00056f8..e37fa62 100644
--- a/bp2build/java_library_conversion_test.go
+++ b/bp2build/java_library_conversion_test.go
@@ -53,11 +53,13 @@
ExpectedBazelTargets: []string{
MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
"srcs": `["a.java"]`,
- "deps": `[":java-lib-2"]`,
+ "deps": `[":java-lib-2-neverlink"]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
MakeBazelTarget("java_library", "java-lib-2", AttrNameToString{
"srcs": `["b.java"]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "java-lib-2"),
},
})
}
@@ -87,11 +89,12 @@
MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
"srcs": `["a.java"]`,
"deps": `[
- ":java-lib-2",
+ ":java-lib-2-neverlink",
":java-lib-3",
]`,
"exports": `[":java-lib-3"]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
})
}
@@ -113,6 +116,7 @@
MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
"exports": `[":java-lib-2"]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
})
}
@@ -152,6 +156,7 @@
MakeBazelTarget("java_library", "java-lib-1", AttrNameToString{
"plugins": `[":java-plugin-1"]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
}, func(ctx android.RegistrationContext) {
ctx.RegisterModuleType("java_plugin", java.PluginFactory)
@@ -170,6 +175,7 @@
"srcs": `["a.java"]`,
"javacopts": `["-source 11 -target 11"]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
})
}
@@ -193,6 +199,7 @@
]`,
"srcs": `["a.java"]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
})
}
@@ -212,6 +219,7 @@
"javacopts": `["-Xsuper-fast"]`,
"srcs": `["a.java"]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
})
}
@@ -232,6 +240,7 @@
"javacopts": `["-Xsuper-fast"]`,
"srcs": `["a.java"]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
})
}
@@ -265,6 +274,7 @@
":example_lib_logtags",
]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "example_lib"),
}})
}
@@ -286,6 +296,7 @@
"res/b.res",
]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
})
}
@@ -310,6 +321,7 @@
"res/dir1/b.res",
]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
})
}
@@ -330,6 +342,7 @@
"resource_strip_prefix": `"res"`,
"resources": `["res/a.res"]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
})
}
@@ -354,6 +367,7 @@
"res/dir1/b.res",
]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "java-lib-1"),
},
})
}
@@ -406,6 +420,7 @@
"b.java",
]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "example_lib"),
}})
}
@@ -435,6 +450,7 @@
"exports": `[":example_lib_java_aidl_library"]`,
"srcs": `["a.java"]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "example_lib"),
},
}, func(ctx android.RegistrationContext) {
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
@@ -490,6 +506,7 @@
":random_other_files",
]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "example_lib"),
MakeBazelTargetNoRestrictions("filegroup", "random_other_files", AttrNameToString{
"srcs": `[
"a.java",
@@ -529,6 +546,7 @@
MakeBazelTarget("java_library", "foo", AttrNameToString{
"exports": `[":foo_java_aidl_library"]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "foo"),
},
}, func(ctx android.RegistrationContext) {
ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
diff --git a/bp2build/java_library_host_conversion_test.go b/bp2build/java_library_host_conversion_test.go
index edd8690..14854c0 100644
--- a/bp2build/java_library_host_conversion_test.go
+++ b/bp2build/java_library_host_conversion_test.go
@@ -48,7 +48,15 @@
ExpectedBazelTargets: []string{
MakeBazelTarget("java_library", "java-lib-host-1", AttrNameToString{
"srcs": `["a.java"]`,
- "deps": `[":java-lib-host-2"]`,
+ "deps": `[":java-lib-host-2-neverlink"]`,
+ "target_compatible_with": `select({
+ "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ })`,
+ }),
+ MakeBazelTarget("java_library", "java-lib-host-1-neverlink", AttrNameToString{
+ "exports": `[":java-lib-host-1"]`,
+ "neverlink": `True`,
"target_compatible_with": `select({
"//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
"//conditions:default": [],
@@ -62,6 +70,14 @@
"//conditions:default": [],
})`,
}),
+ MakeBazelTarget("java_library", "java-lib-host-2-neverlink", AttrNameToString{
+ "exports": `[":java-lib-host-2"]`,
+ "neverlink": `True`,
+ "target_compatible_with": `select({
+ "//build/bazel/platforms/os:android": ["@platforms//:incompatible"],
+ "//conditions:default": [],
+ })`,
+ }),
},
})
}
diff --git a/bp2build/java_proto_conversion_test.go b/bp2build/java_proto_conversion_test.go
index df0df2f..d25b7c4 100644
--- a/bp2build/java_proto_conversion_test.go
+++ b/bp2build/java_proto_conversion_test.go
@@ -91,6 +91,7 @@
MakeBazelTarget("java_library", "java-protos", AttrNameToString{
"exports": fmt.Sprintf(`[":%s"]`, javaLibraryName),
}),
+ MakeNeverlinkDuplicateTarget("java_library", "java-protos"),
},
})
}
@@ -119,6 +120,7 @@
"exports": `[":java-protos_java_proto_lite"]`,
"javacopts": `["-source 1.7 -target 1.7"]`,
}),
+ MakeNeverlinkDuplicateTarget("java_library", "java-protos"),
},
})
}
diff --git a/bp2build/testing.go b/bp2build/testing.go
index 3750804..4e63d19 100644
--- a/bp2build/testing.go
+++ b/bp2build/testing.go
@@ -90,6 +90,7 @@
}
func RunBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
+ t.Helper()
bp2buildSetup := func(ctx *android.TestContext) {
registerModuleTypes(ctx)
ctx.RegisterForBazelConversion()
@@ -98,6 +99,7 @@
}
func RunApiBp2BuildTestCase(t *testing.T, registerModuleTypes func(ctx android.RegistrationContext), tc Bp2buildTestCase) {
+ t.Helper()
apiBp2BuildSetup := func(ctx *android.TestContext) {
registerModuleTypes(ctx)
ctx.RegisterForApiBazelConversion()
@@ -530,3 +532,10 @@
}
return MakeBazelTarget("cc_stub_suite", name+"_stub_libs", stubSuiteAttrs)
}
+
+func MakeNeverlinkDuplicateTarget(moduleType string, name string) string {
+ return MakeBazelTarget(moduleType, name+"-neverlink", AttrNameToString{
+ "neverlink": `True`,
+ "exports": `[":` + name + `"]`,
+ })
+}
diff --git a/cc/androidmk.go b/cc/androidmk.go
index 58bb57c..aaf21e9 100644
--- a/cc/androidmk.go
+++ b/cc/androidmk.go
@@ -227,27 +227,17 @@
}
}
-func (library *libraryDecorator) getAbiDiffsForAndroidMkDeps() []string {
- if library.static() {
- return nil
- }
- var abiDiffs []string
- if library.sAbiDiff.Valid() {
- abiDiffs = append(abiDiffs, library.sAbiDiff.String())
- }
- if library.prevSAbiDiff.Valid() {
- abiDiffs = append(abiDiffs, library.prevSAbiDiff.String())
- }
- return abiDiffs
-}
-
func (library *libraryDecorator) androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries *android.AndroidMkEntries) {
- entries.AddStrings("LOCAL_ADDITIONAL_DEPENDENCIES", library.getAbiDiffsForAndroidMkDeps()...)
+ if !library.static() {
+ entries.AddPaths("LOCAL_ADDITIONAL_DEPENDENCIES", library.sAbiDiff)
+ }
}
// TODO(ccross): remove this once apex/androidmk.go is converted to AndroidMkEntries
func (library *libraryDecorator) androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) {
- fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES +=", strings.Join(library.getAbiDiffsForAndroidMkDeps(), " "))
+ if !library.static() {
+ fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES +=", strings.Join(library.sAbiDiff.Strings(), " "))
+ }
}
func (library *libraryDecorator) AndroidMkEntries(ctx AndroidMkContext, entries *android.AndroidMkEntries) {
diff --git a/cc/builder.go b/cc/builder.go
index 46cea0b..0629406 100644
--- a/cc/builder.go
+++ b/cc/builder.go
@@ -292,12 +292,6 @@
},
"extraFlags", "referenceDump", "libName", "arch", "errorMessage")
- // Rule to unzip a reference abi dump.
- unzipRefSAbiDump = pctx.AndroidStaticRule("unzipRefSAbiDump",
- blueprint.RuleParams{
- Command: "gunzip -c $in > $out",
- })
-
// Rule to zip files.
zip = pctx.AndroidStaticRule("zip",
blueprint.RuleParams{
@@ -911,59 +905,17 @@
return android.OptionalPathForPath(outputFile)
}
-// unzipRefDump registers a build statement to unzip a reference abi dump.
-func unzipRefDump(ctx android.ModuleContext, zippedRefDump android.Path, baseName string) android.Path {
- outputFile := android.PathForModuleOut(ctx, baseName+"_ref.lsdump")
- ctx.Build(pctx, android.BuildParams{
- Rule: unzipRefSAbiDump,
- Description: "gunzip" + outputFile.Base(),
- Output: outputFile,
- Input: zippedRefDump,
- })
- return outputFile
-}
-
-// sourceAbiDiff registers a build statement to compare linked sAbi dump files (.lsdump).
-func sourceAbiDiff(ctx android.ModuleContext, inputDump, referenceDump android.Path,
- baseName string, diffFlags []string, prevVersion int,
- checkAllApis, isLlndkOrNdk, isVndkExt, previousVersionDiff bool) android.OptionalPath {
+func transformAbiDumpToAbiDiff(ctx android.ModuleContext, inputDump, referenceDump android.Path,
+ baseName, nameExt string, extraFlags []string, errorMessage string) android.Path {
var outputFile android.ModuleOutPath
- if previousVersionDiff {
- outputFile = android.PathForModuleOut(ctx, baseName+"."+strconv.Itoa(prevVersion)+".abidiff")
+ if nameExt != "" {
+ outputFile = android.PathForModuleOut(ctx, baseName+"."+nameExt+".abidiff")
} else {
outputFile = android.PathForModuleOut(ctx, baseName+".abidiff")
}
libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
- var extraFlags []string
- if checkAllApis {
- extraFlags = append(extraFlags, "-check-all-apis")
- } else {
- extraFlags = append(extraFlags,
- "-allow-unreferenced-changes",
- "-allow-unreferenced-elf-symbol-changes")
- }
-
- var errorMessage string
- if previousVersionDiff {
- errorMessage = "error: Please follow https://android.googlesource.com/platform/development/+/master/vndk/tools/header-checker/README.md#configure-cross_version-abi-check to resolve the ABI difference between your source code and version " + strconv.Itoa(prevVersion) + "."
- sourceVersion := prevVersion + 1
- extraFlags = append(extraFlags, "-target-version", strconv.Itoa(sourceVersion))
- } else {
- errorMessage = "error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l " + libName
- extraFlags = append(extraFlags, "-target-version", "current")
- }
-
- if isLlndkOrNdk {
- extraFlags = append(extraFlags, "-consider-opaque-types-different")
- }
- if isVndkExt || previousVersionDiff {
- extraFlags = append(extraFlags, "-allow-extensions")
- }
- // TODO(b/232891473): Simplify the above logic with diffFlags.
- extraFlags = append(extraFlags, diffFlags...)
-
ctx.Build(pctx, android.BuildParams{
Rule: sAbiDiff,
Description: "header-abi-diff " + outputFile.Base(),
@@ -978,7 +930,7 @@
"errorMessage": errorMessage,
},
})
- return android.OptionalPathForPath(outputFile)
+ return outputFile
}
// Generate a rule for extracting a table of contents from a shared library (.so)
diff --git a/cc/cc.go b/cc/cc.go
index 306e483..2ff5bba 100644
--- a/cc/cc.go
+++ b/cc/cc.go
@@ -1205,6 +1205,8 @@
return c
}
+// UseVndk() returns true if this module is built against VNDK.
+// This means the vendor and product variants of a module.
func (c *Module) UseVndk() bool {
return c.Properties.VndkVersion != ""
}
@@ -1298,6 +1300,9 @@
return false
}
+// IsVndk() returns true if this module has a vndk variant.
+// Note that IsVndk() returns true for all variants of vndk-enabled libraries. Not only vendor variant,
+// but also platform and product variants of vndk-enabled libraries return true for IsVndk().
func (c *Module) IsVndk() bool {
if vndkdep := c.vndkdep; vndkdep != nil {
return vndkdep.isVndk()
@@ -1376,6 +1381,13 @@
return false
}
+func (c *Module) IsStubsImplementationRequired() bool {
+ if lib := c.library; lib != nil {
+ return lib.isStubsImplementationRequired()
+ }
+ return false
+}
+
// If this is a stubs library, ImplementationModuleName returns the name of the module that contains
// the implementation. If it is an implementation library it returns its own name.
func (c *Module) ImplementationModuleName(ctx android.BaseModuleContext) string {
@@ -2302,28 +2314,23 @@
return nonvariantLibs, variantLibs
}
-func updateDepsWithApiImports(deps Deps, apiImports multitree.ApiImportInfo) Deps {
- for idx, lib := range deps.SharedLibs {
- deps.SharedLibs[idx] = GetReplaceModuleName(lib, apiImports.SharedLibs)
+func rewriteLibsForApiImports(c LinkableInterface, libs []string, replaceList map[string]string, config android.Config) ([]string, []string) {
+ nonVariantLibs := []string{}
+ variantLibs := []string{}
+
+ for _, lib := range libs {
+ replaceLibName := GetReplaceModuleName(lib, replaceList)
+ if replaceLibName == lib {
+ // Do not handle any libs which are not in API imports
+ nonVariantLibs = append(nonVariantLibs, replaceLibName)
+ } else if c.UseSdk() && inList(replaceLibName, *getNDKKnownLibs(config)) {
+ variantLibs = append(variantLibs, replaceLibName)
+ } else {
+ nonVariantLibs = append(nonVariantLibs, replaceLibName)
+ }
}
- for idx, lib := range deps.LateSharedLibs {
- deps.LateSharedLibs[idx] = GetReplaceModuleName(lib, apiImports.SharedLibs)
- }
-
- for idx, lib := range deps.RuntimeLibs {
- deps.RuntimeLibs[idx] = GetReplaceModuleName(lib, apiImports.SharedLibs)
- }
-
- for idx, lib := range deps.SystemSharedLibs {
- deps.SystemSharedLibs[idx] = GetReplaceModuleName(lib, apiImports.SharedLibs)
- }
-
- for idx, lib := range deps.ReexportSharedLibHeaders {
- deps.ReexportSharedLibHeaders[idx] = GetReplaceModuleName(lib, apiImports.SharedLibs)
- }
-
- return deps
+ return nonVariantLibs, variantLibs
}
func (c *Module) DepsMutator(actx android.BottomUpMutatorContext) {
@@ -2342,8 +2349,15 @@
deps := c.deps(ctx)
apiImportInfo := GetApiImports(c, actx)
+ apiNdkLibs := []string{}
+ apiLateNdkLibs := []string{}
+
if ctx.Os() == android.Android && c.Target().NativeBridge != android.NativeBridgeEnabled {
- deps = updateDepsWithApiImports(deps, apiImportInfo)
+ deps.SharedLibs, apiNdkLibs = rewriteLibsForApiImports(c, deps.SharedLibs, apiImportInfo.SharedLibs, ctx.Config())
+ deps.LateSharedLibs, apiLateNdkLibs = rewriteLibsForApiImports(c, deps.LateSharedLibs, apiImportInfo.SharedLibs, ctx.Config())
+ deps.SystemSharedLibs, _ = rewriteLibsForApiImports(c, deps.SystemSharedLibs, apiImportInfo.SharedLibs, ctx.Config())
+ deps.ReexportHeaderLibHeaders, _ = rewriteLibsForApiImports(c, deps.ReexportHeaderLibHeaders, apiImportInfo.SharedLibs, ctx.Config())
+ deps.ReexportSharedLibHeaders, _ = rewriteLibsForApiImports(c, deps.ReexportSharedLibHeaders, apiImportInfo.SharedLibs, ctx.Config())
}
c.Properties.AndroidMkSystemSharedLibs = deps.SystemSharedLibs
@@ -2530,12 +2544,20 @@
{Mutator: "version", Variation: version},
{Mutator: "link", Variation: "shared"},
}, ndkStubDepTag, variantNdkLibs...)
+ actx.AddVariationDependencies([]blueprint.Variation{
+ {Mutator: "version", Variation: version},
+ {Mutator: "link", Variation: "shared"},
+ }, ndkStubDepTag, apiNdkLibs...)
ndkLateStubDepTag := libraryDependencyTag{Kind: sharedLibraryDependency, Order: lateLibraryDependency, ndk: true, makeSuffix: "." + version}
actx.AddVariationDependencies([]blueprint.Variation{
{Mutator: "version", Variation: version},
{Mutator: "link", Variation: "shared"},
}, ndkLateStubDepTag, variantLateNdkLibs...)
+ actx.AddVariationDependencies([]blueprint.Variation{
+ {Mutator: "version", Variation: version},
+ {Mutator: "link", Variation: "shared"},
+ }, ndkLateStubDepTag, apiLateNdkLibs...)
if vndkdep := c.vndkdep; vndkdep != nil {
if vndkdep.isVndkExt() {
@@ -2589,6 +2611,10 @@
}
return
}
+ // TODO(b/244244438) : Remove this once all variants are implemented
+ if ccFrom, ok := from.(*Module); ok && ccFrom.isImportedApiLibrary() {
+ return
+ }
if from.SdkVersion() == "" {
// Platform code can link to anything
return
@@ -2615,6 +2641,10 @@
// the NDK.
return
}
+ if c.isImportedApiLibrary() {
+ // Imported library from the API surface is a stub library built against interface definition.
+ return
+ }
}
if strings.HasPrefix(ctx.ModuleName(), "libclang_rt.") && to.Module().Name() == "libc++" {
diff --git a/cc/config/global.go b/cc/config/global.go
index e5c0a8e..61151d1 100644
--- a/cc/config/global.go
+++ b/cc/config/global.go
@@ -222,7 +222,6 @@
// http://b/145211066
"-Wno-implicit-int-float-conversion",
// New warnings to be fixed after clang-r377782.
- "-Wno-sizeof-array-div", // http://b/148815709
"-Wno-tautological-overlap-compare", // http://b/148815696
// New warnings to be fixed after clang-r383902.
"-Wno-deprecated-copy", // http://b/153746672
@@ -240,12 +239,17 @@
// New warnings to be fixed after clang-r458507
"-Wno-error=unqualified-std-cast-call", // http://b/239662094
// New warnings to be fixed after clang-r468909
- "-Wno-error=array-parameter", // http://b/241941550
"-Wno-error=deprecated-builtins", // http://b/241601211
"-Wno-error=deprecated", // in external/googletest/googletest
+ // New warnings to be fixed after clang-r475365
+ "-Wno-error=single-bit-bitfield-constant-conversion", // http://b/243965903
+ "-Wno-error=incompatible-function-pointer-types", // http://b/257101299
+ "-Wno-error=enum-constexpr-conversion", // http://b/243964282
}
noOverrideExternalGlobalCflags = []string{
+ // http://b/148815709
+ "-Wno-sizeof-array-div",
// http://b/197240255
"-Wno-unused-but-set-variable",
"-Wno-unused-but-set-parameter",
@@ -253,6 +257,8 @@
"-Wno-bitwise-instead-of-logical",
// http://b/232926688
"-Wno-misleading-indentation",
+ // http://b/241941550
+ "-Wno-array-parameter",
}
// Extra cflags for external third-party projects to disable warnings that
@@ -292,8 +298,6 @@
llvmNextExtraCommonGlobalCflags = []string{
// New warnings to be fixed after clang-r475365
"-Wno-error=single-bit-bitfield-constant-conversion", // http://b/243965903
- // Skip deprecated flags.
- "-Wno-unused-command-line-argument",
}
IllegalFlags = []string{
@@ -307,8 +311,8 @@
// prebuilts/clang default settings.
ClangDefaultBase = "prebuilts/clang/host"
- ClangDefaultVersion = "clang-r468909b"
- ClangDefaultShortVersion = "15.0.3"
+ ClangDefaultVersion = "clang-r475365"
+ ClangDefaultShortVersion = "16.0.1"
// Directories with warnings from Android.bp files.
WarningAllowedProjects = []string{
@@ -349,6 +353,7 @@
// Default to zero initialization.
"-ftrivial-auto-var-init=zero",
"-enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang",
+ "-Wno-unused-command-line-argument",
}...)
exportedVars.ExportStringList("CommonGlobalCflags", bazelCommonGlobalCflags)
@@ -359,14 +364,14 @@
// Automatically initialize any uninitialized stack variables.
// Prefer zero-init if multiple options are set.
if ctx.Config().IsEnvTrue("AUTO_ZERO_INITIALIZE") {
- flags = append(flags, "-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang")
+ flags = append(flags, "-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang -Wno-unused-command-line-argument")
} else if ctx.Config().IsEnvTrue("AUTO_PATTERN_INITIALIZE") {
flags = append(flags, "-ftrivial-auto-var-init=pattern")
} else if ctx.Config().IsEnvTrue("AUTO_UNINITIALIZE") {
flags = append(flags, "-ftrivial-auto-var-init=uninitialized")
} else {
// Default to zero initialization.
- flags = append(flags, "-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang")
+ flags = append(flags, "-ftrivial-auto-var-init=zero -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang -Wno-unused-command-line-argument")
}
// Workaround for ccache with clang.
diff --git a/cc/library.go b/cc/library.go
index b639930..1cad6b9 100644
--- a/cc/library.go
+++ b/cc/library.go
@@ -71,6 +71,12 @@
// List versions to generate stubs libs for. The version name "current" is always
// implicitly added.
Versions []string
+
+ // Whether to not require the implementation of the library to be installed if a
+ // client of the stubs is installed. Defaults to true; set to false if the
+ // implementation is made available by some other means, e.g. in a Microdroid
+ // virtual machine.
+ Implementation_installable *bool
}
// set the name of the output
@@ -405,13 +411,15 @@
Additional_linker_inputs: linkerAttrs.additionalLinkerInputs,
- Strip: stripAttrsFromLinkerAttrs(&linkerAttrs),
- Features: baseAttributes.features,
+ Strip: stripAttrsFromLinkerAttrs(&linkerAttrs),
+ Features: baseAttributes.features,
+ bazelCcHeaderAbiCheckerAttributes: bp2buildParseAbiCheckerProps(ctx, m),
}
if compilerAttrs.stubsSymbolFile != nil && len(compilerAttrs.stubsVersions.Value) > 0 {
hasStubs := true
sharedTargetAttrs.Has_stubs.SetValue(&hasStubs)
+ sharedTargetAttrs.Stubs_symbol_file = compilerAttrs.stubsSymbolFile
}
sharedTargetAttrs.Suffix = compilerAttrs.suffix
@@ -796,10 +804,7 @@
sAbiOutputFile android.OptionalPath
// Source Abi Diff
- sAbiDiff android.OptionalPath
-
- // Source Abi Diff against previous SDK version
- prevSAbiDiff android.OptionalPath
+ sAbiDiff android.Paths
// Location of the static library in the sysroot. Empty if the library is
// not included in the NDK.
@@ -1339,6 +1344,7 @@
buildStubs() bool
setBuildStubs(isLatest bool)
hasStubsVariants() bool
+ isStubsImplementationRequired() bool
setStubsVersion(string)
stubsVersion() string
@@ -1728,7 +1734,6 @@
objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
-
objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.StaticLibObjs.sAbiDumpFiles...)
objs.sAbiDumpFiles = append(objs.sAbiDumpFiles, deps.WholeStaticLibObjs.sAbiDumpFiles...)
@@ -1789,10 +1794,8 @@
return library.coverageOutputFile
}
-// pathForVndkRefAbiDump returns an OptionalPath representing the path of the
-// reference abi dump for the given module. This is not guaranteed to be valid.
-func pathForVndkRefAbiDump(ctx android.ModuleInstallPathContext, version, fileName string,
- isNdk, isVndk, isGzip bool) android.OptionalPath {
+func getRefAbiDumpFile(ctx android.ModuleInstallPathContext,
+ versionedDumpDir, fileName string) android.OptionalPath {
currentArchType := ctx.Arch().ArchType
primaryArchType := ctx.Config().DevicePrimaryArchType()
@@ -1801,73 +1804,34 @@
archName += "_" + primaryArchType.String()
}
+ return android.ExistentPathForSource(ctx, versionedDumpDir, archName, "source-based",
+ fileName+".lsdump")
+}
+
+func getRefAbiDumpDir(isNdk, isVndk bool) string {
var dirName string
if isNdk {
dirName = "ndk"
} else if isVndk {
dirName = "vndk"
} else {
- dirName = "platform" // opt-in libs
+ dirName = "platform"
}
-
- binderBitness := ctx.DeviceConfig().BinderBitness()
-
- var ext string
- if isGzip {
- ext = ".lsdump.gz"
- } else {
- ext = ".lsdump"
- }
-
- return android.ExistentPathForSource(ctx, "prebuilts", "abi-dumps", dirName,
- version, binderBitness, archName, "source-based",
- fileName+ext)
+ return filepath.Join("prebuilts", "abi-dumps", dirName)
}
-func getRefAbiDumpFile(ctx ModuleContext, vndkVersion, fileName string) android.Path {
- // The logic must be consistent with classifySourceAbiDump.
- isNdk := ctx.isNdk(ctx.Config())
- isVndk := ctx.useVndk() && ctx.isVndk()
-
- refAbiDumpTextFile := pathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isVndk, false)
- refAbiDumpGzipFile := pathForVndkRefAbiDump(ctx, vndkVersion, fileName, isNdk, isVndk, true)
-
- if refAbiDumpTextFile.Valid() {
- if refAbiDumpGzipFile.Valid() {
- ctx.ModuleErrorf(
- "Two reference ABI dump files are found: %q and %q. Please delete the stale one.",
- refAbiDumpTextFile, refAbiDumpGzipFile)
- return nil
- }
- return refAbiDumpTextFile.Path()
- }
- if refAbiDumpGzipFile.Valid() {
- return unzipRefDump(ctx, refAbiDumpGzipFile.Path(), fileName)
- }
- return nil
-}
-
-func prevDumpRefVersion(ctx ModuleContext) int {
+func prevRefAbiDumpVersion(ctx ModuleContext, dumpDir string) int {
sdkVersionInt := ctx.Config().PlatformSdkVersion().FinalInt()
sdkVersionStr := ctx.Config().PlatformSdkVersion().String()
if ctx.Config().PlatformSdkFinal() {
return sdkVersionInt - 1
} else {
- var dirName string
-
- isNdk := ctx.isNdk(ctx.Config())
- if isNdk {
- dirName = "ndk"
- } else {
- dirName = "platform"
- }
-
// The platform SDK version can be upgraded before finalization while the corresponding abi dumps hasn't
// been generated. Thus the Cross-Version Check chooses PLATFORM_SDK_VERION - 1 as previous version.
// This situation could be identified by checking the existence of the PLATFORM_SDK_VERION dump directory.
- refDumpDir := android.ExistentPathForSource(ctx, "prebuilts", "abi-dumps", dirName, sdkVersionStr)
- if refDumpDir.Valid() {
+ versionedDumpDir := android.ExistentPathForSource(ctx, dumpDir, sdkVersionStr)
+ if versionedDumpDir.Valid() {
return sdkVersionInt
} else {
return sdkVersionInt - 1
@@ -1888,6 +1852,54 @@
}
}
+// sourceAbiDiff registers a build statement to compare linked sAbi dump files (.lsdump).
+func (library *libraryDecorator) sourceAbiDiff(ctx android.ModuleContext, referenceDump android.Path,
+ baseName, nameExt string, isLlndkOrNdk, allowExtensions bool,
+ sourceVersion, errorMessage string) {
+
+ sourceDump := library.sAbiOutputFile.Path()
+
+ extraFlags := []string{"-target-version", sourceVersion}
+ if Bool(library.Properties.Header_abi_checker.Check_all_apis) {
+ extraFlags = append(extraFlags, "-check-all-apis")
+ } else {
+ extraFlags = append(extraFlags,
+ "-allow-unreferenced-changes",
+ "-allow-unreferenced-elf-symbol-changes")
+ }
+ if isLlndkOrNdk {
+ extraFlags = append(extraFlags, "-consider-opaque-types-different")
+ }
+ if allowExtensions {
+ extraFlags = append(extraFlags, "-allow-extensions")
+ }
+ extraFlags = append(extraFlags, library.Properties.Header_abi_checker.Diff_flags...)
+
+ library.sAbiDiff = append(
+ library.sAbiDiff,
+ transformAbiDumpToAbiDiff(ctx, sourceDump, referenceDump,
+ baseName, nameExt, extraFlags, errorMessage))
+}
+
+func (library *libraryDecorator) crossVersionAbiDiff(ctx android.ModuleContext, referenceDump android.Path,
+ baseName string, isLlndkOrNdk bool, sourceVersion, prevVersion string) {
+
+ errorMessage := "error: Please follow https://android.googlesource.com/platform/development/+/master/vndk/tools/header-checker/README.md#configure-cross_version-abi-check to resolve the ABI difference between your source code and version " + prevVersion + "."
+
+ library.sourceAbiDiff(ctx, referenceDump, baseName, prevVersion,
+ isLlndkOrNdk, /* allowExtensions */ true, sourceVersion, errorMessage)
+}
+
+func (library *libraryDecorator) sameVersionAbiDiff(ctx android.ModuleContext, referenceDump android.Path,
+ baseName string, isLlndkOrNdk, allowExtensions bool) {
+
+ libName := strings.TrimSuffix(baseName, filepath.Ext(baseName))
+ errorMessage := "error: Please update ABI references with: $$ANDROID_BUILD_TOP/development/vndk/tools/header-checker/utils/create_reference_dumps.py -l " + libName
+
+ library.sourceAbiDiff(ctx, referenceDump, baseName, /* nameExt */ "",
+ isLlndkOrNdk, allowExtensions, "current", errorMessage)
+}
+
func (library *libraryDecorator) linkSAbiDumpFiles(ctx ModuleContext, objs Objects, fileName string, soFile android.Path) {
if library.sabi.shouldCreateSourceAbiDump() {
exportIncludeDirs := library.flagExporter.exportedIncludes(ctx)
@@ -1906,31 +1918,31 @@
addLsdumpPath(classifySourceAbiDump(ctx) + ":" + library.sAbiOutputFile.String())
+ // The logic must be consistent with classifySourceAbiDump.
isVndk := ctx.useVndk() && ctx.isVndk()
isNdk := ctx.isNdk(ctx.Config())
isLlndk := ctx.isImplementationForLLNDKPublic()
+ dumpDir := getRefAbiDumpDir(isNdk, isVndk)
+ binderBitness := ctx.DeviceConfig().BinderBitness()
// If NDK or PLATFORM library, check against previous version ABI.
if !isVndk {
- prevVersion := prevDumpRefVersion(ctx)
- prevRefAbiDumpFile := getRefAbiDumpFile(ctx, strconv.Itoa(prevVersion), fileName)
- if prevRefAbiDumpFile != nil {
- library.prevSAbiDiff = sourceAbiDiff(ctx, library.sAbiOutputFile.Path(),
- prevRefAbiDumpFile, fileName,
- library.Properties.Header_abi_checker.Diff_flags, prevVersion,
- Bool(library.Properties.Header_abi_checker.Check_all_apis),
- isLlndk || isNdk, ctx.IsVndkExt(), true)
+ prevVersionInt := prevRefAbiDumpVersion(ctx, dumpDir)
+ prevVersion := strconv.Itoa(prevVersionInt)
+ prevDumpDir := filepath.Join(dumpDir, prevVersion, binderBitness)
+ prevDumpFile := getRefAbiDumpFile(ctx, prevDumpDir, fileName)
+ if prevDumpFile.Valid() {
+ library.crossVersionAbiDiff(ctx, prevDumpFile.Path(),
+ fileName, isLlndk || isNdk,
+ strconv.Itoa(prevVersionInt+1), prevVersion)
}
}
-
+ // Check against the current version.
currVersion := currRefAbiDumpVersion(ctx, isVndk)
- refAbiDumpFile := getRefAbiDumpFile(ctx, currVersion, fileName)
- if refAbiDumpFile != nil {
- library.sAbiDiff = sourceAbiDiff(ctx, library.sAbiOutputFile.Path(),
- refAbiDumpFile, fileName,
- library.Properties.Header_abi_checker.Diff_flags,
- /* unused if not previousVersionDiff */ 0,
- Bool(library.Properties.Header_abi_checker.Check_all_apis),
- isLlndk || isNdk, ctx.IsVndkExt(), false)
+ currDumpDir := filepath.Join(dumpDir, currVersion, binderBitness)
+ currDumpFile := getRefAbiDumpFile(ctx, currDumpDir, fileName)
+ if currDumpFile.Valid() {
+ library.sameVersionAbiDiff(ctx, currDumpFile.Path(),
+ fileName, isLlndk || isNdk, ctx.IsVndkExt())
}
}
}
@@ -2298,6 +2310,10 @@
len(library.Properties.Stubs.Versions) > 0
}
+func (library *libraryDecorator) isStubsImplementationRequired() bool {
+ return BoolDefault(library.Properties.Stubs.Implementation_installable, true)
+}
+
func (library *libraryDecorator) stubsVersions(ctx android.BaseMutatorContext) []string {
if !library.hasStubsVariants() {
return nil
@@ -2746,6 +2762,29 @@
return outputFile
}
+func bp2buildParseAbiCheckerProps(ctx android.TopDownMutatorContext, module *Module) bazelCcHeaderAbiCheckerAttributes {
+ lib, ok := module.linker.(*libraryDecorator)
+ if !ok {
+ return bazelCcHeaderAbiCheckerAttributes{}
+ }
+
+ abiChecker := lib.Properties.Header_abi_checker
+
+ abiCheckerAttrs := bazelCcHeaderAbiCheckerAttributes{
+ Abi_checker_enabled: abiChecker.Enabled,
+ Abi_checker_exclude_symbol_versions: abiChecker.Exclude_symbol_versions,
+ Abi_checker_exclude_symbol_tags: abiChecker.Exclude_symbol_tags,
+ Abi_checker_check_all_apis: abiChecker.Check_all_apis,
+ Abi_checker_diff_flags: abiChecker.Diff_flags,
+ }
+ if abiChecker.Symbol_file != nil {
+ symbolFile := android.BazelLabelForModuleSrcSingle(ctx, *abiChecker.Symbol_file)
+ abiCheckerAttrs.Abi_checker_symbol_file = &symbolFile
+ }
+
+ return abiCheckerAttrs
+}
+
func sharedOrStaticLibraryBp2Build(ctx android.TopDownMutatorContext, module *Module, isStatic bool) {
baseAttributes := bp2BuildParseBaseProps(ctx, module)
compilerAttrs := baseAttributes.compilerAttributes
@@ -2852,10 +2891,13 @@
Features: baseAttributes.features,
Suffix: compilerAttrs.suffix,
+
+ bazelCcHeaderAbiCheckerAttributes: bp2buildParseAbiCheckerProps(ctx, module),
}
if compilerAttrs.stubsSymbolFile != nil && len(compilerAttrs.stubsVersions.Value) > 0 {
hasStubs := true
sharedLibAttrs.Has_stubs.SetValue(&hasStubs)
+ sharedLibAttrs.Stubs_symbol_file = compilerAttrs.stubsSymbolFile
}
attrs = sharedLibAttrs
}
@@ -2932,11 +2974,14 @@
Features bazel.StringListAttribute
- Has_stubs bazel.BoolAttribute
+ Has_stubs bazel.BoolAttribute
+ Stubs_symbol_file *string
Inject_bssl_hash bazel.BoolAttribute
Suffix bazel.StringAttribute
+
+ bazelCcHeaderAbiCheckerAttributes
}
type bazelCcStubSuiteAttributes struct {
@@ -2947,3 +2992,12 @@
Soname *string
Deps bazel.LabelListAttribute
}
+
+type bazelCcHeaderAbiCheckerAttributes struct {
+ Abi_checker_enabled *bool
+ Abi_checker_symbol_file *bazel.Label
+ Abi_checker_exclude_symbol_versions []string
+ Abi_checker_exclude_symbol_tags []string
+ Abi_checker_check_all_apis *bool
+ Abi_checker_diff_flags []string
+}
diff --git a/cc/library_stub.go b/cc/library_stub.go
index 043c03c..22e61a7 100644
--- a/cc/library_stub.go
+++ b/cc/library_stub.go
@@ -15,14 +15,17 @@
package cc
import (
+ "regexp"
"strings"
- "github.com/google/blueprint/proptools"
-
"android/soong/android"
"android/soong/multitree"
)
+var (
+ ndkVariantRegex = regexp.MustCompile("ndk\\.([a-zA-Z0-9]+)")
+)
+
func init() {
RegisterLibraryStubBuildComponents(android.InitRegistrationContext)
}
@@ -45,13 +48,17 @@
}
if m.UseVndk() && apiLibrary.hasLLNDKStubs() {
- // Add LLNDK dependencies
- for _, variant := range apiLibrary.properties.Variants {
- if variant == "llndk" {
- variantName := BuildApiVariantName(m.BaseModuleName(), "llndk", "")
- ctx.AddDependency(m, nil, variantName)
- break
- }
+ // Add LLNDK variant dependency
+ if inList("llndk", apiLibrary.properties.Variants) {
+ variantName := BuildApiVariantName(m.BaseModuleName(), "llndk", "")
+ ctx.AddDependency(m, nil, variantName)
+ }
+ } else if m.IsSdkVariant() {
+ // Add NDK variant dependencies
+ targetVariant := "ndk." + m.StubsVersion()
+ if inList(targetVariant, apiLibrary.properties.Variants) {
+ variantName := BuildApiVariantName(m.BaseModuleName(), targetVariant, "")
+ ctx.AddDependency(m, nil, variantName)
}
}
}
@@ -117,12 +124,31 @@
}
}
+func (d *apiLibraryDecorator) linkerInit(ctx BaseModuleContext) {
+ d.baseLinker.linkerInit(ctx)
+
+ if d.hasNDKStubs() {
+ // Set SDK version of module as current
+ ctx.Module().(*Module).Properties.Sdk_version = StringPtr("current")
+
+ // Add NDK stub as NDK known libs
+ name := ctx.ModuleName()
+
+ ndkKnownLibsLock.Lock()
+ ndkKnownLibs := getNDKKnownLibs(ctx.Config())
+ if !inList(name, *ndkKnownLibs) {
+ *ndkKnownLibs = append(*ndkKnownLibs, name)
+ }
+ ndkKnownLibsLock.Unlock()
+ }
+}
+
func (d *apiLibraryDecorator) link(ctx ModuleContext, flags Flags, deps PathDeps, objects Objects) android.Path {
m, _ := ctx.Module().(*Module)
var in android.Path
- if src := proptools.String(d.properties.Src); src != "" {
+ if src := String(d.properties.Src); src != "" {
in = android.PathForModuleSrc(ctx, src)
}
@@ -149,7 +175,7 @@
variantMod.exportProperties.Export_headers...)
// Export headers as system include dirs if specified. Mostly for libc
- if proptools.Bool(variantMod.exportProperties.Export_headers_as_system) {
+ if Bool(variantMod.exportProperties.Export_headers_as_system) {
d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs = append(
d.libraryDecorator.flagExporter.Properties.Export_system_include_dirs,
d.libraryDecorator.flagExporter.Properties.Export_include_dirs...)
@@ -157,6 +183,29 @@
}
}
}
+ } else if m.IsSdkVariant() {
+ // NDK Variant
+ apiVariantModule := BuildApiVariantName(m.BaseModuleName(), "ndk", m.StubsVersion())
+
+ var mod android.Module
+
+ ctx.VisitDirectDeps(func(depMod android.Module) {
+ if depMod.Name() == apiVariantModule {
+ mod = depMod
+ }
+ })
+
+ if mod != nil {
+ variantMod, ok := mod.(*CcApiVariant)
+ if ok {
+ in = variantMod.Src()
+
+ // Copy NDK properties to cc_api_library module
+ d.libraryDecorator.flagExporter.Properties.Export_include_dirs = append(
+ d.libraryDecorator.flagExporter.Properties.Export_include_dirs,
+ variantMod.exportProperties.Export_headers...)
+ }
+ }
}
// Flags reexported from dependencies. (e.g. vndk_prebuilt_shared)
@@ -214,6 +263,14 @@
// TODO(b/244244438) Create more version information for NDK and APEX variations
// NDK variants
+
+ if m.IsSdkVariant() {
+ // TODO(b/249193999) Do not check if module has NDK stubs once all NDK cc_api_library contains ndk variant of cc_api_variant.
+ if d.hasNDKStubs() {
+ return d.getNdkVersions()
+ }
+ }
+
if m.MinSdkVersion() == "" {
return nil
}
@@ -229,14 +286,30 @@
}
func (d *apiLibraryDecorator) hasLLNDKStubs() bool {
+ return inList("llndk", d.properties.Variants)
+}
+
+func (d *apiLibraryDecorator) hasNDKStubs() bool {
for _, variant := range d.properties.Variants {
- if strings.Contains(variant, "llndk") {
+ if ndkVariantRegex.MatchString(variant) {
return true
}
}
return false
}
+func (d *apiLibraryDecorator) getNdkVersions() []string {
+ ndkVersions := []string{}
+
+ for _, variant := range d.properties.Variants {
+ if match := ndkVariantRegex.FindStringSubmatch(variant); len(match) == 2 {
+ ndkVersions = append(ndkVersions, match[1])
+ }
+ }
+
+ return ndkVersions
+}
+
// 'cc_api_headers' is similar with 'cc_api_library', but which replaces
// header libraries. The module will replace any dependencies to existing
// original header libraries.
@@ -320,18 +393,18 @@
func (v *CcApiVariant) GenerateAndroidBuildActions(ctx android.ModuleContext) {
// No need to build
- if proptools.String(v.properties.Src) == "" {
+ if String(v.properties.Src) == "" {
ctx.PropertyErrorf("src", "src is a required property")
}
// Skip the existence check of the stub prebuilt file.
// The file is not guaranteed to exist during Soong analysis.
// Build orchestrator will be responsible for creating a connected ninja graph.
- v.src = android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), proptools.String(v.properties.Src))
+ v.src = android.MaybeExistentPathForSource(ctx, ctx.ModuleDir(), String(v.properties.Src))
}
func (v *CcApiVariant) Name() string {
- version := proptools.String(v.properties.Version)
+ version := String(v.properties.Version)
return BuildApiVariantName(v.BaseModuleName(), *v.properties.Variant, version)
}
@@ -349,8 +422,10 @@
}
// Implement ImageInterface to generate image variants
-func (v *CcApiVariant) ImageMutatorBegin(ctx android.BaseModuleContext) {}
-func (v *CcApiVariant) CoreVariantNeeded(ctx android.BaseModuleContext) bool { return false }
+func (v *CcApiVariant) ImageMutatorBegin(ctx android.BaseModuleContext) {}
+func (v *CcApiVariant) CoreVariantNeeded(ctx android.BaseModuleContext) bool {
+ return String(v.properties.Variant) == "ndk"
+}
func (v *CcApiVariant) RamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false }
func (v *CcApiVariant) VendorRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false }
func (v *CcApiVariant) DebugRamdiskVariantNeeded(ctx android.BaseModuleContext) bool { return false }
@@ -359,7 +434,7 @@
var variations []string
platformVndkVersion := ctx.DeviceConfig().PlatformVndkVersion()
- if proptools.String(v.properties.Variant) == "llndk" {
+ if String(v.properties.Variant) == "llndk" {
variations = append(variations, VendorVariationPrefix+platformVndkVersion)
variations = append(variations, ProductVariationPrefix+platformVndkVersion)
}
diff --git a/cc/library_stub_test.go b/cc/library_stub_test.go
index 8ce74c4..e372860 100644
--- a/cc/library_stub_test.go
+++ b/cc/library_stub_test.go
@@ -322,16 +322,188 @@
ctx := prepareForCcTest.RunTestWithBp(t, bp)
- libfoo := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Module()
+ binfoo := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Module()
libbarApiImport := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
libbarApiVariant := ctx.ModuleForTests("libbar.llndk.apiimport", "android_vendor.29_arm64_armv8-a").Module()
- android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, libfoo, libbarApiImport))
+ android.AssertBoolEquals(t, "Stub library from API surface should be linked", true, hasDirectDependency(t, ctx, binfoo, libbarApiImport))
android.AssertBoolEquals(t, "Stub library variant from API surface should be linked", true, hasDirectDependency(t, ctx, libbarApiImport, libbarApiVariant))
- libFooLibFlags := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Rule("ld").Args["libFlags"]
- android.AssertStringDoesContain(t, "Vendor binary should be linked with LLNDK variant source", libFooLibFlags, "libbar_llndk.so")
+ binFooLibFlags := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Rule("ld").Args["libFlags"]
+ android.AssertStringDoesContain(t, "Vendor binary should be linked with LLNDK variant source", binFooLibFlags, "libbar_llndk.so")
- libFooCFlags := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Rule("cc").Args["cFlags"]
- android.AssertStringDoesContain(t, "Vendor binary should include headers from the LLNDK variant source", libFooCFlags, "-Ilibbar_llndk_include")
+ binFooCFlags := ctx.ModuleForTests("binfoo", "android_vendor.29_arm64_armv8-a").Rule("cc").Args["cFlags"]
+ android.AssertStringDoesContain(t, "Vendor binary should include headers from the LLNDK variant source", binFooCFlags, "-Ilibbar_llndk_include")
+}
+
+func TestApiLibraryWithNdkVariant(t *testing.T) {
+ bp := `
+ cc_binary {
+ name: "binfoo",
+ sdk_version: "29",
+ srcs: ["binfoo.cc"],
+ shared_libs: ["libbar"],
+ stl: "c++_shared",
+ }
+
+ cc_binary {
+ name: "binbaz",
+ sdk_version: "30",
+ srcs: ["binbaz.cc"],
+ shared_libs: ["libbar"],
+ stl: "c++_shared",
+ }
+
+ cc_api_library {
+ name: "libbar",
+ // TODO(b/244244438) Remove src property once all variants are implemented.
+ src: "libbar.so",
+ variants: [
+ "ndk.29",
+ "ndk.30",
+ "ndk.current",
+ ],
+ }
+
+ cc_api_variant {
+ name: "libbar",
+ variant: "ndk",
+ version: "29",
+ src: "libbar_ndk_29.so",
+ export_headers: ["libbar_ndk_29_include"]
+ }
+
+ cc_api_variant {
+ name: "libbar",
+ variant: "ndk",
+ version: "30",
+ src: "libbar_ndk_30.so",
+ export_headers: ["libbar_ndk_30_include"]
+ }
+
+ cc_api_variant {
+ name: "libbar",
+ variant: "ndk",
+ version: "current",
+ src: "libbar_ndk_current.so",
+ export_headers: ["libbar_ndk_current_include"]
+ }
+
+ api_imports {
+ name: "api_imports",
+ shared_libs: [
+ "libbar",
+ ],
+ header_libs: [],
+ }
+ `
+
+ ctx := prepareForCcTest.RunTestWithBp(t, bp)
+
+ binfoo := ctx.ModuleForTests("binfoo", "android_arm64_armv8-a_sdk").Module()
+ libbarApiImportv29 := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_sdk_shared_29").Module()
+ libbarApiVariantv29 := ctx.ModuleForTests("libbar.ndk.29.apiimport", "android_arm64_armv8-a_sdk").Module()
+ libbarApiImportv30 := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_sdk_shared_30").Module()
+ libbarApiVariantv30 := ctx.ModuleForTests("libbar.ndk.30.apiimport", "android_arm64_armv8-a_sdk").Module()
+
+ android.AssertBoolEquals(t, "Stub library from API surface should be linked with target version", true, hasDirectDependency(t, ctx, binfoo, libbarApiImportv29))
+ android.AssertBoolEquals(t, "Stub library variant from API surface should be linked with target version", true, hasDirectDependency(t, ctx, libbarApiImportv29, libbarApiVariantv29))
+ android.AssertBoolEquals(t, "Stub library from API surface should not be linked with different version", false, hasDirectDependency(t, ctx, binfoo, libbarApiImportv30))
+ android.AssertBoolEquals(t, "Stub library variant from API surface should not be linked with different version", false, hasDirectDependency(t, ctx, libbarApiImportv29, libbarApiVariantv30))
+
+ binbaz := ctx.ModuleForTests("binbaz", "android_arm64_armv8-a_sdk").Module()
+
+ android.AssertBoolEquals(t, "Stub library from API surface should be linked with target version", true, hasDirectDependency(t, ctx, binbaz, libbarApiImportv30))
+ android.AssertBoolEquals(t, "Stub library from API surface should not be linked with different version", false, hasDirectDependency(t, ctx, binbaz, libbarApiImportv29))
+
+ binFooLibFlags := ctx.ModuleForTests("binfoo", "android_arm64_armv8-a_sdk").Rule("ld").Args["libFlags"]
+ android.AssertStringDoesContain(t, "Binary using sdk should be linked with NDK variant source", binFooLibFlags, "libbar_ndk_29.so")
+
+ binFooCFlags := ctx.ModuleForTests("binfoo", "android_arm64_armv8-a_sdk").Rule("cc").Args["cFlags"]
+ android.AssertStringDoesContain(t, "Binary using sdk should include headers from the NDK variant source", binFooCFlags, "-Ilibbar_ndk_29_include")
+}
+
+func TestApiLibraryWithMultipleVariants(t *testing.T) {
+ bp := `
+ cc_binary {
+ name: "binfoo",
+ sdk_version: "29",
+ srcs: ["binfoo.cc"],
+ shared_libs: ["libbar"],
+ stl: "c++_shared",
+ }
+
+ cc_binary {
+ name: "binbaz",
+ vendor: true,
+ srcs: ["binbaz.cc"],
+ shared_libs: ["libbar"],
+ }
+
+ cc_api_library {
+ name: "libbar",
+ // TODO(b/244244438) Remove src property once all variants are implemented.
+ src: "libbar.so",
+ vendor_available: true,
+ variants: [
+ "llndk",
+ "ndk.29",
+ "ndk.30",
+ "ndk.current",
+ ],
+ }
+
+ cc_api_variant {
+ name: "libbar",
+ variant: "ndk",
+ version: "29",
+ src: "libbar_ndk_29.so",
+ export_headers: ["libbar_ndk_29_include"]
+ }
+
+ cc_api_variant {
+ name: "libbar",
+ variant: "ndk",
+ version: "30",
+ src: "libbar_ndk_30.so",
+ export_headers: ["libbar_ndk_30_include"]
+ }
+
+ cc_api_variant {
+ name: "libbar",
+ variant: "ndk",
+ version: "current",
+ src: "libbar_ndk_current.so",
+ export_headers: ["libbar_ndk_current_include"]
+ }
+
+ cc_api_variant {
+ name: "libbar",
+ variant: "llndk",
+ src: "libbar_llndk.so",
+ export_headers: ["libbar_llndk_include"]
+ }
+
+ api_imports {
+ name: "api_imports",
+ shared_libs: [
+ "libbar",
+ ],
+ header_libs: [],
+ }
+ `
+ ctx := prepareForCcTest.RunTestWithBp(t, bp)
+
+ binfoo := ctx.ModuleForTests("binfoo", "android_arm64_armv8-a_sdk").Module()
+ libbarApiImportv29 := ctx.ModuleForTests("libbar.apiimport", "android_arm64_armv8-a_sdk_shared_29").Module()
+ libbarApiImportLlndk := ctx.ModuleForTests("libbar.apiimport", "android_vendor.29_arm64_armv8-a_shared").Module()
+
+ android.AssertBoolEquals(t, "Binary using SDK should be linked with API library from NDK variant", true, hasDirectDependency(t, ctx, binfoo, libbarApiImportv29))
+ android.AssertBoolEquals(t, "Binary using SDK should not be linked with API library from LLNDK variant", false, hasDirectDependency(t, ctx, binfoo, libbarApiImportLlndk))
+
+ binbaz := ctx.ModuleForTests("binbaz", "android_vendor.29_arm64_armv8-a").Module()
+
+ android.AssertBoolEquals(t, "Vendor binary should be linked with API library from LLNDK variant", true, hasDirectDependency(t, ctx, binbaz, libbarApiImportLlndk))
+ android.AssertBoolEquals(t, "Vendor binary should not be linked with API library from NDK variant", false, hasDirectDependency(t, ctx, binbaz, libbarApiImportv29))
+
}
diff --git a/cc/ndk_library.go b/cc/ndk_library.go
index d704e32..2473ba2 100644
--- a/cc/ndk_library.go
+++ b/cc/ndk_library.go
@@ -396,14 +396,14 @@
}
func (this *stubDecorator) diffAbi(ctx ModuleContext) {
- missingPrebuiltError := fmt.Sprintf(
- "Did not find prebuilt ABI dump for %q. Generate with "+
- "//development/tools/ndk/update_ndk_abi.sh.", this.libraryName(ctx))
-
// Catch any ABI changes compared to the checked-in definition of this API
// level.
abiDiffPath := android.PathForModuleOut(ctx, "abidiff.timestamp")
prebuiltAbiDump := this.findPrebuiltAbiDump(ctx, this.apiLevel)
+ missingPrebuiltError := fmt.Sprintf(
+ "Did not find prebuilt ABI dump for %q (%q). Generate with "+
+ "//development/tools/ndk/update_ndk_abi.sh.", this.libraryName(ctx),
+ prebuiltAbiDump.InvalidReason())
if !prebuiltAbiDump.Valid() {
ctx.Build(pctx, android.BuildParams{
Rule: android.ErrorRule,
diff --git a/cc/sdk.go b/cc/sdk.go
index a0d196b..3e50c9f 100644
--- a/cc/sdk.go
+++ b/cc/sdk.go
@@ -31,6 +31,7 @@
switch m := ctx.Module().(type) {
case LinkableInterface:
+ ccModule, isCcModule := ctx.Module().(*Module)
if m.AlwaysSdk() {
if !m.UseSdk() && !m.SplitPerApiLevel() {
ctx.ModuleErrorf("UseSdk() must return true when AlwaysSdk is set, did the factory forget to set Sdk_version?")
@@ -58,11 +59,32 @@
modules[1].(*Module).Properties.PreventInstall = true
}
ctx.AliasVariation("")
+ } else if isCcModule && ccModule.isImportedApiLibrary() {
+ apiLibrary, _ := ccModule.linker.(*apiLibraryDecorator)
+ if apiLibrary.hasNDKStubs() && ccModule.canUseSdk() {
+ // Handle cc_api_library module with NDK stubs and variants only which can use SDK
+ modules := ctx.CreateVariations("", "sdk")
+ modules[1].(*Module).Properties.IsSdkVariant = true
+ if ctx.Config().UnbundledBuildApps() {
+ // For an unbundled apps build, hide the platform variant from Make.
+ modules[0].(*Module).Properties.HideFromMake = true
+ modules[0].(*Module).Properties.PreventInstall = true
+ } else {
+ // For a platform build, mark the SDK variant so that it gets a ".sdk" suffix when
+ // exposed to Make.
+ modules[1].(*Module).Properties.SdkAndPlatformVariantVisibleToMake = true
+ modules[1].(*Module).Properties.PreventInstall = true
+ }
+ } else {
+ ccModule.Properties.Sdk_version = nil
+ ctx.CreateVariations("")
+ ctx.AliasVariation("")
+ }
} else {
- if m, ok := ctx.Module().(*Module); ok {
+ if isCcModule {
// Clear the sdk_version property for modules that don't have an SDK variant so
// later code doesn't get confused by it.
- m.Properties.Sdk_version = nil
+ ccModule.Properties.Sdk_version = nil
}
ctx.CreateVariations("")
ctx.AliasVariation("")
@@ -79,6 +101,11 @@
case *snapshotModule:
ctx.CreateVariations("")
case *CcApiVariant:
- ctx.CreateVariations("")
+ ccApiVariant, _ := ctx.Module().(*CcApiVariant)
+ if String(ccApiVariant.properties.Variant) == "ndk" {
+ ctx.CreateVariations("sdk")
+ } else {
+ ctx.CreateVariations("")
+ }
}
}
diff --git a/cmd/extract_apks/main.go b/cmd/extract_apks/main.go
index c420567..82db634 100644
--- a/cmd/extract_apks/main.go
+++ b/cmd/extract_apks/main.go
@@ -132,21 +132,21 @@
*android_bundle_proto.ApkDescription
}
-func (m apkDescriptionMatcher) matches(config TargetConfig) bool {
- return m.ApkDescription == nil || (apkTargetingMatcher{m.Targeting}).matches(config)
+func (m apkDescriptionMatcher) matches(config TargetConfig, allAbisMustMatch bool) bool {
+ return m.ApkDescription == nil || (apkTargetingMatcher{m.Targeting}).matches(config, allAbisMustMatch)
}
type apkTargetingMatcher struct {
*android_bundle_proto.ApkTargeting
}
-func (m apkTargetingMatcher) matches(config TargetConfig) bool {
+func (m apkTargetingMatcher) matches(config TargetConfig, allAbisMustMatch bool) bool {
return m.ApkTargeting == nil ||
(abiTargetingMatcher{m.AbiTargeting}.matches(config) &&
languageTargetingMatcher{m.LanguageTargeting}.matches(config) &&
screenDensityTargetingMatcher{m.ScreenDensityTargeting}.matches(config) &&
sdkVersionTargetingMatcher{m.SdkVersionTargeting}.matches(config) &&
- multiAbiTargetingMatcher{m.MultiAbiTargeting}.matches(config))
+ multiAbiTargetingMatcher{m.MultiAbiTargeting}.matches(config, allAbisMustMatch))
}
type languageTargetingMatcher struct {
@@ -215,33 +215,27 @@
}
}
- m = append(multiAbiValue{}, m...)
- sort.Slice(m, sortAbis(m))
- other = append(multiAbiValue{}, other...)
- sort.Slice(other, sortAbis(other))
+ sortedM := append(multiAbiValue{}, m...)
+ sort.Slice(sortedM, sortAbis(sortedM))
+ sortedOther := append(multiAbiValue{}, other...)
+ sort.Slice(sortedOther, sortAbis(sortedOther))
- for i := 0; i < min(len(m), len(other)); i++ {
- if multiAbiPriorities[m[i].Alias] > multiAbiPriorities[other[i].Alias] {
+ for i := 0; i < min(len(sortedM), len(sortedOther)); i++ {
+ if multiAbiPriorities[sortedM[i].Alias] > multiAbiPriorities[sortedOther[i].Alias] {
return 1
}
- if multiAbiPriorities[m[i].Alias] < multiAbiPriorities[other[i].Alias] {
+ if multiAbiPriorities[sortedM[i].Alias] < multiAbiPriorities[sortedOther[i].Alias] {
return -1
}
}
- if len(m) == len(other) {
- return 0
- }
- if len(m) > len(other) {
- return 1
- }
- return -1
+ return len(sortedM) - len(sortedOther)
}
// this logic should match the logic in bundletool at
// https://github.com/google/bundletool/blob/ae0fc0162fd80d92ef8f4ef4527c066f0106942f/src/main/java/com/android/tools/build/bundletool/device/MultiAbiMatcher.java#L43
// (note link is the commit at time of writing; but logic should always match the latest)
-func (t multiAbiTargetingMatcher) matches(config TargetConfig) bool {
+func (t multiAbiTargetingMatcher) matches(config TargetConfig, allAbisMustMatch bool) bool {
if t.MultiAbiTargeting == nil {
return true
}
@@ -250,12 +244,19 @@
}
multiAbiIsValid := func(m multiAbiValue) bool {
+ numValid := 0
for _, abi := range m {
- if _, ok := config.abis[abi.Alias]; !ok {
- return false
+ if _, ok := config.abis[abi.Alias]; ok {
+ numValid += 1
}
}
- return true
+ if numValid == 0 {
+ return false
+ } else if numValid > 0 && !allAbisMustMatch {
+ return true
+ } else {
+ return numValid == len(m)
+ }
}
// ensure that the current value is valid for our config
@@ -264,6 +265,7 @@
for _, multiAbi := range multiAbiSet {
if multiAbiIsValid(multiAbi.GetAbi()) {
valueSetContainsViableAbi = true
+ break
}
}
@@ -362,13 +364,13 @@
*android_bundle_proto.VariantTargeting
}
-func (m variantTargetingMatcher) matches(config TargetConfig) bool {
+func (m variantTargetingMatcher) matches(config TargetConfig, allAbisMustMatch bool) bool {
if m.VariantTargeting == nil {
return true
}
return sdkVersionTargetingMatcher{m.SdkVersionTargeting}.matches(config) &&
abiTargetingMatcher{m.AbiTargeting}.matches(config) &&
- multiAbiTargetingMatcher{m.MultiAbiTargeting}.matches(config) &&
+ multiAbiTargetingMatcher{m.MultiAbiTargeting}.matches(config, allAbisMustMatch) &&
screenDensityTargetingMatcher{m.ScreenDensityTargeting}.matches(config) &&
textureCompressionFormatTargetingMatcher{m.TextureCompressionFormatTargeting}.matches(config)
}
@@ -380,30 +382,42 @@
// Return all entries matching target configuration
func selectApks(toc Toc, targetConfig TargetConfig) SelectionResult {
- var result SelectionResult
- for _, variant := range (*toc).GetVariant() {
- if !(variantTargetingMatcher{variant.GetTargeting()}.matches(targetConfig)) {
- continue
- }
- for _, as := range variant.GetApkSet() {
- if !(moduleMetadataMatcher{as.ModuleMetadata}.matches(targetConfig)) {
+ checkMatching := func(allAbisMustMatch bool) SelectionResult {
+ var result SelectionResult
+ for _, variant := range (*toc).GetVariant() {
+ if !(variantTargetingMatcher{variant.GetTargeting()}.matches(targetConfig, allAbisMustMatch)) {
continue
}
- for _, apkdesc := range as.GetApkDescription() {
- if (apkDescriptionMatcher{apkdesc}).matches(targetConfig) {
- result.entries = append(result.entries, apkdesc.GetPath())
- // TODO(asmundak): As it turns out, moduleName which we get from
- // the ModuleMetadata matches the module names of the generated
- // entry paths just by coincidence, only for the split APKs. We
- // need to discuss this with bundletool folks.
- result.moduleName = as.GetModuleMetadata().GetName()
+ for _, as := range variant.GetApkSet() {
+ if !(moduleMetadataMatcher{as.ModuleMetadata}.matches(targetConfig)) {
+ continue
+ }
+ for _, apkdesc := range as.GetApkDescription() {
+ if (apkDescriptionMatcher{apkdesc}).matches(targetConfig, allAbisMustMatch) {
+ result.entries = append(result.entries, apkdesc.GetPath())
+ // TODO(asmundak): As it turns out, moduleName which we get from
+ // the ModuleMetadata matches the module names of the generated
+ // entry paths just by coincidence, only for the split APKs. We
+ // need to discuss this with bundletool folks.
+ result.moduleName = as.GetModuleMetadata().GetName()
+ }
+ }
+ // we allow only a single module, so bail out here if we found one
+ if result.moduleName != "" {
+ return result
}
}
- // we allow only a single module, so bail out here if we found one
- if result.moduleName != "" {
- return result
- }
}
+ return result
+ }
+ result := checkMatching(true)
+ if result.moduleName == "" {
+ // if there are no matches where all of the ABIs are available in the
+ // TargetConfig, then search again with a looser requirement of at
+ // least one matching ABI
+ // NOTE(b/260130686): this logic diverges from the logic in bundletool
+ // https://github.com/google/bundletool/blob/ae0fc0162fd80d92ef8f4ef4527c066f0106942f/src/main/java/com/android/tools/build/bundletool/device/MultiAbiMatcher.java#L43
+ result = checkMatching(false)
}
return result
}
diff --git a/cmd/extract_apks/main_test.go b/cmd/extract_apks/main_test.go
index c1d712d..9f52877 100644
--- a/cmd/extract_apks/main_test.go
+++ b/cmd/extract_apks/main_test.go
@@ -744,7 +744,11 @@
bp.Abi_X86_64: 0,
},
},
- expected: SelectionResult{},
+ expected: SelectionResult{
+ "base",
+ []string{
+ "standalones/standalone-x86.x86_64.apex",
+ }},
},
{
name: "multi-variant multi-target cross-target",
diff --git a/cmd/soong_build/main.go b/cmd/soong_build/main.go
index bc2d5cb..029bbb4 100644
--- a/cmd/soong_build/main.go
+++ b/cmd/soong_build/main.go
@@ -276,6 +276,7 @@
src != "BUILD" &&
src != "BUILD.bazel" &&
!strings.HasPrefix(src, "build/bazel") &&
+ !strings.HasPrefix(src, "external/bazel-skylib") &&
!strings.HasPrefix(src, "prebuilts/clang") {
ret = append(ret, src)
}
@@ -578,6 +579,17 @@
// FIXME: 'frameworks/compile/slang' has a filegroup error due to an escaping issue
excludes = append(excludes, "frameworks/compile/slang")
+ // FIXME(b/260809113): 'prebuilts/clang/host/linux-x86/clang-dev' is a tool-generated symlink directory that contains a BUILD file.
+ // The bazel files finder code doesn't traverse into symlink dirs, and hence is not aware of this BUILD file and exclude it accordingly
+ // during symlink forest generation when checking against keepExistingBuildFiles allowlist.
+ //
+ // This is necessary because globs in //prebuilts/clang/host/linux-x86/BUILD
+ // currently assume no subpackages (keepExistingBuildFile is not recursive for that directory).
+ //
+ // This is a bandaid until we the symlink forest logic can intelligently exclude BUILD files found in source symlink dirs according
+ // to the keepExistingBuildFile allowlist.
+ excludes = append(excludes, "prebuilts/clang/host/linux-x86/clang-dev")
+
return excludes
}
@@ -617,40 +629,41 @@
// symlink tree creation binary. Then the latter would not need to depend on
// the very heavy-weight machinery of soong_build .
func runSymlinkForestCreation(configuration android.Config, ctx *android.Context, extraNinjaDeps []string, metricsDir string) string {
- var ninjaDeps []string
- ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
-
- generatedRoot := shared.JoinPath(configuration.SoongOutDir(), "bp2build")
- workspaceRoot := shared.JoinPath(configuration.SoongOutDir(), "workspace")
-
- excludes := bazelArtifacts()
-
- if outDir[0] != '/' {
- excludes = append(excludes, outDir)
- }
-
- existingBazelRelatedFiles, err := getExistingBazelRelatedFiles(topDir)
- if err != nil {
- fmt.Fprintf(os.Stderr, "Error determining existing Bazel-related files: %s\n", err)
- os.Exit(1)
- }
-
- pathsToIgnoredBuildFiles := getPathsToIgnoredBuildFiles(configuration.Bp2buildPackageConfig, topDir, existingBazelRelatedFiles, configuration.IsEnvTrue("BP2BUILD_VERBOSE"))
- excludes = append(excludes, pathsToIgnoredBuildFiles...)
- excludes = append(excludes, getTemporaryExcludes()...)
-
- // PlantSymlinkForest() returns all the directories that were readdir()'ed.
- // Such a directory SHOULD be added to `ninjaDeps` so that a child directory
- // or file created/deleted under it would trigger an update of the symlink
- // forest.
ctx.EventHandler.Do("symlink_forest", func() {
- symlinkForestDeps := bp2build.PlantSymlinkForest(
- configuration.IsEnvTrue("BP2BUILD_VERBOSE"), topDir, workspaceRoot, generatedRoot, excludes)
- ninjaDeps = append(ninjaDeps, symlinkForestDeps...)
- })
+ var ninjaDeps []string
+ ninjaDeps = append(ninjaDeps, extraNinjaDeps...)
- writeDepFile(symlinkForestMarker, ctx.EventHandler, ninjaDeps)
- touch(shared.JoinPath(topDir, symlinkForestMarker))
+ generatedRoot := shared.JoinPath(configuration.SoongOutDir(), "bp2build")
+ workspaceRoot := shared.JoinPath(configuration.SoongOutDir(), "workspace")
+
+ excludes := bazelArtifacts()
+
+ if outDir[0] != '/' {
+ excludes = append(excludes, outDir)
+ }
+
+ existingBazelRelatedFiles, err := getExistingBazelRelatedFiles(topDir)
+ if err != nil {
+ fmt.Fprintf(os.Stderr, "Error determining existing Bazel-related files: %s\n", err)
+ os.Exit(1)
+ }
+
+ pathsToIgnoredBuildFiles := getPathsToIgnoredBuildFiles(configuration.Bp2buildPackageConfig, topDir, existingBazelRelatedFiles, configuration.IsEnvTrue("BP2BUILD_VERBOSE"))
+ excludes = append(excludes, pathsToIgnoredBuildFiles...)
+ excludes = append(excludes, getTemporaryExcludes()...)
+
+ // PlantSymlinkForest() returns all the directories that were readdir()'ed.
+ // Such a directory SHOULD be added to `ninjaDeps` so that a child directory
+ // or file created/deleted under it would trigger an update of the symlink forest.
+ ctx.EventHandler.Do("plant", func() {
+ symlinkForestDeps := bp2build.PlantSymlinkForest(
+ configuration.IsEnvTrue("BP2BUILD_VERBOSE"), topDir, workspaceRoot, generatedRoot, excludes)
+ ninjaDeps = append(ninjaDeps, symlinkForestDeps...)
+ })
+
+ writeDepFile(symlinkForestMarker, ctx.EventHandler, ninjaDeps)
+ touch(shared.JoinPath(topDir, symlinkForestMarker))
+ })
codegenMetrics := bp2build.ReadCodegenMetrics(metricsDir)
if codegenMetrics == nil {
m := bp2build.CreateCodegenMetrics()
diff --git a/cmd/soong_build/queryview.go b/cmd/soong_build/queryview.go
index cd1d6fb..a876522 100644
--- a/cmd/soong_build/queryview.go
+++ b/cmd/soong_build/queryview.go
@@ -15,6 +15,7 @@
package main
import (
+ "io/fs"
"io/ioutil"
"os"
"path/filepath"
@@ -35,6 +36,11 @@
filesToWrite := bp2build.CreateBazelFiles(ctx.Config(), ruleShims, res.BuildDirToTargets(),
ctx.Mode())
+ bazelRcFiles, err2 := CopyBazelRcFiles()
+ if err2 != nil {
+ return err2
+ }
+ filesToWrite = append(filesToWrite, bazelRcFiles...)
for _, f := range filesToWrite {
if err := writeReadOnlyFile(outDir, f); err != nil {
return err
@@ -44,6 +50,32 @@
return nil
}
+// CopyBazelRcFiles creates BazelFiles for all the bazelrc files under
+// build/bazel. They're needed because the rc files are still read when running
+// queryview, so they have to be in the queryview workspace.
+func CopyBazelRcFiles() ([]bp2build.BazelFile, error) {
+ result := make([]bp2build.BazelFile, 0)
+ err := filepath.WalkDir(filepath.Join(topDir, "build/bazel"), func(path string, info fs.DirEntry, err error) error {
+ if filepath.Ext(path) == ".bazelrc" {
+ contents, err := os.ReadFile(path)
+ if err != nil {
+ return err
+ }
+ path, err = filepath.Rel(topDir, path)
+ if err != nil {
+ return err
+ }
+ result = append(result, bp2build.BazelFile{
+ Dir: filepath.Dir(path),
+ Basename: filepath.Base(path),
+ Contents: string(contents),
+ })
+ }
+ return nil
+ })
+ return result, err
+}
+
// The auto-conversion directory should be read-only, sufficient for bazel query. The files
// are not intended to be edited by end users.
func writeReadOnlyFile(dir string, f bp2build.BazelFile) error {
diff --git a/cmd/soong_ui/main.go b/cmd/soong_ui/main.go
index 19166d2..f7689b9 100644
--- a/cmd/soong_ui/main.go
+++ b/cmd/soong_ui/main.go
@@ -183,6 +183,7 @@
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")
+ bp2buildMetricsFile := filepath.Join(logsDir, c.logsPrefix+"bp2build_metrics.pb")
build.PrintOutDirWarning(buildCtx, config)
@@ -210,6 +211,7 @@
files := []string{
buildErrorFile, // build error strings
rbeMetricsFile, // high level metrics related to remote build execution.
+ bp2buildMetricsFile, // high level metrics related to bp2build.
soongMetricsFile, // high level metrics related to this build system.
config.BazelMetricsDir(), // directory that contains a set of bazel metrics.
}
diff --git a/dexpreopt/config.go b/dexpreopt/config.go
index eefda19..609a29c 100644
--- a/dexpreopt/config.go
+++ b/dexpreopt/config.go
@@ -96,6 +96,8 @@
// quickly silence build errors. This flag should be used with caution and only as a temporary
// measure, as it masks real errors and affects performance.
RelaxUsesLibraryCheck bool
+
+ EnableUffdGc bool // preopt with the assumption that userfaultfd GC will be used on device.
}
var allPlatformSystemServerJarsKey = android.NewOnceKey("allPlatformSystemServerJars")
diff --git a/dexpreopt/dexpreopt.go b/dexpreopt/dexpreopt.go
index fdfd22e..e3404a5 100644
--- a/dexpreopt/dexpreopt.go
+++ b/dexpreopt/dexpreopt.go
@@ -495,6 +495,10 @@
cmd.FlagWithInput("--profile-file=", profile)
}
+ if global.EnableUffdGc {
+ cmd.Flag("--runtime-arg").Flag("-Xgc:CMC")
+ }
+
rule.Install(odexPath, odexInstallPath)
rule.Install(vdexPath, vdexInstallPath)
}
diff --git a/docs/perf.md b/docs/perf.md
index 694dcf1..5b53c8d 100644
--- a/docs/perf.md
+++ b/docs/perf.md
@@ -42,16 +42,29 @@
```
If the elapsed time is much longer than the critical path then additional
-parallelism on the build machine will improve total build times. If there are
+parallelism on the build machine will improve total build times. If there are
long individual times listed in the critical path then improving build times
for those steps or adjusting dependencies so that those steps can run earlier
in the build graph will improve total build times.
### Soong
-Soong can be traced and profiled using the standard Go tools. It understands
-the `-cpuprofile`, `-trace`, and `-memprofile` command line arguments, but we
-don't currently have an easy way to enable them in the context of a full build.
+Soong proper (i.e., `soong_build` executable that processes the blueprint
+files) can be traced and profiled using the standard Go tools. It understands
+the `-trace`, `-cpuprofile`, and `-memprofile` command line arguments.
+Setting `SOONG_PROFILE_CPU` and/or `SOONG_PROFILE_MEM` environment variables
+for the build enables respective profiling, e.g., running
+
+```shell
+SOONG_PROFILE_CPU=/tmp/foo m ..._
+```
+
+saves CPU profile for each Soong invocation in /tmp/foo._step_ file, where
+_step_ is Soong execution step. The main step is `build`. The others as
+`bp2build_files`, `bp2build_workspace`, `modulegraph`, `queryview`,
+`api_bp2build`, `soong_docs` (not all of them necessarily run during the build).
+The profiles can be inspected with `go tool pprof` from the command line or
+with _Run>Open Profiler Snapshot_ in IntelliJ IDEA.
### Kati
diff --git a/java/Android.bp b/java/Android.bp
index 0bf7a0b..27a0a38 100644
--- a/java/Android.bp
+++ b/java/Android.bp
@@ -91,6 +91,7 @@
"dexpreopt_config_test.go",
"droiddoc_test.go",
"droidstubs_test.go",
+ "fuzz_test.go",
"genrule_test.go",
"hiddenapi_singleton_test.go",
"jacoco_test.go",
@@ -103,6 +104,7 @@
"plugin_test.go",
"prebuilt_apis_test.go",
"proto_test.go",
+ "resourceshrinker_test.go",
"rro_test.go",
"sdk_test.go",
"sdk_library_test.go",
diff --git a/java/app_set.go b/java/app_set.go
index d8c2a8d..0f55b77 100644
--- a/java/app_set.go
+++ b/java/app_set.go
@@ -98,7 +98,7 @@
"x86_64": "X86_64",
}
-func SupportedAbis(ctx android.ModuleContext) []string {
+func SupportedAbis(ctx android.ModuleContext, excludeNativeBridgeAbis bool) []string {
abiName := func(targetIdx int, deviceArch string) string {
if abi, found := TargetCpuAbi[deviceArch]; found {
return abi
@@ -109,6 +109,9 @@
var result []string
for i, target := range ctx.Config().Targets[android.Android] {
+ if target.NativeBridge == android.NativeBridgeEnabled && excludeNativeBridgeAbis {
+ continue
+ }
result = append(result, abiName(i, target.Arch.ArchType.String()))
}
return result
@@ -135,7 +138,7 @@
ImplicitOutputs: android.WritablePaths{as.packedOutput, as.apkcertsFile},
Inputs: android.Paths{as.prebuilt.SingleSourcePath(ctx)},
Args: map[string]string{
- "abis": strings.Join(SupportedAbis(ctx), ","),
+ "abis": strings.Join(SupportedAbis(ctx, false), ","),
"allow-prereleased": strconv.FormatBool(proptools.Bool(as.properties.Prerelease)),
"screen-densities": screenDensities,
"sdk-version": ctx.Config().PlatformSdkVersion().String(),
diff --git a/java/dex.go b/java/dex.go
index de36b18..40ee99d 100644
--- a/java/dex.go
+++ b/java/dex.go
@@ -63,6 +63,7 @@
// classes referenced by the app manifest. Defaults to false.
No_aapt_flags *bool
+ // If true, optimize for size by removing unused resources. Defaults to false.
Shrink_resources *bool
// Flags to pass to proguard.
diff --git a/java/dexpreopt.go b/java/dexpreopt.go
index 0adaf99..77cbe9c 100644
--- a/java/dexpreopt.go
+++ b/java/dexpreopt.go
@@ -269,8 +269,10 @@
targets = append(targets, target)
}
}
- if isSystemServerJar && !d.isSDKLibrary {
- // If the module is not an SDK library and it's a system server jar, only preopt the primary arch.
+ if isSystemServerJar && moduleName(ctx) != "com.android.location.provider" {
+ // If the module is a system server jar, only preopt for the primary arch because the jar can
+ // only be loaded by system server. "com.android.location.provider" is a special case because
+ // it's also used by apps as a shared library.
targets = targets[:1]
}
}
diff --git a/java/dexpreopt_bootjars.go b/java/dexpreopt_bootjars.go
index b3faae8..3effff6 100644
--- a/java/dexpreopt_bootjars.go
+++ b/java/dexpreopt_bootjars.go
@@ -752,6 +752,10 @@
cmd.FlagWithArg("--instruction-set-features=", global.InstructionSetFeatures[arch])
}
+ if global.EnableUffdGc {
+ cmd.Flag("--runtime-arg").Flag("-Xgc:CMC")
+ }
+
if global.BootFlags != "" {
cmd.Flag(global.BootFlags)
}
diff --git a/java/droiddoc.go b/java/droiddoc.go
index 2173dae..8a291ad 100644
--- a/java/droiddoc.go
+++ b/java/droiddoc.go
@@ -304,6 +304,9 @@
flags = append(flags, "-I"+src.String())
}
+ minSdkVersion := j.MinSdkVersion(ctx).ApiLevel.FinalOrFutureInt()
+ flags = append(flags, fmt.Sprintf("--min_sdk_version=%v", minSdkVersion))
+
return strings.Join(flags, " "), deps
}
diff --git a/java/fuzz_test.go b/java/fuzz_test.go
index 0a2c945..186c3aa 100644
--- a/java/fuzz_test.go
+++ b/java/fuzz_test.go
@@ -65,9 +65,8 @@
osCommonTarget := result.Config.BuildOSCommonTarget.String()
- osCommonTargetWithSan := osCommonTarget + "_asan" + "_fuzzer"
- javac := result.ModuleForTests("foo", osCommonTargetWithSan).Rule("javac")
- combineJar := result.ModuleForTests("foo", osCommonTargetWithSan).Description("for javac")
+ javac := result.ModuleForTests("foo", osCommonTarget).Rule("javac")
+ combineJar := result.ModuleForTests("foo", osCommonTarget).Description("for javac")
if len(javac.Inputs) != 1 || javac.Inputs[0].String() != "a.java" {
t.Errorf(`foo inputs %v != ["a.java"]`, javac.Inputs)
@@ -85,11 +84,11 @@
}
ctx := result.TestContext
- foo := ctx.ModuleForTests("foo", osCommonTargetWithSan).Module().(*JavaFuzzLibrary)
+ foo := ctx.ModuleForTests("foo", osCommonTarget).Module().(*JavaFuzzLibrary)
- expected := "libjni.so"
+ expected := "lib64/libjni.so"
if runtime.GOOS == "darwin" {
- expected = "libjni.dylib"
+ expected = "lib64/libjni.dylib"
}
fooJniFilePaths := foo.jniFilePaths
diff --git a/java/java.go b/java/java.go
index 25b6349..e37a77e 100644
--- a/java/java.go
+++ b/java/java.go
@@ -764,6 +764,9 @@
// The list of permitted packages that need to be passed to the prebuilts as they are used to
// create the updatable-bcp-packages.txt file.
PermittedPackages []string
+
+ // The value of the min_sdk_version property, translated into a number where possible.
+ MinSdkVersion *string `supported_build_releases:"Tiramisu+"`
}
func (p *librarySdkMemberProperties) PopulateFromVariant(ctx android.SdkMemberContext, variant android.Module) {
@@ -774,6 +777,13 @@
p.AidlIncludeDirs = j.AidlIncludeDirs()
p.PermittedPackages = j.PermittedPackagesForUpdatableBootJars()
+
+ // If the min_sdk_version was set then add the canonical representation of the API level to the
+ // snapshot.
+ if j.deviceProperties.Min_sdk_version != nil {
+ canonical := android.ReplaceFinalizedCodenames(ctx.SdkModuleContext().Config(), j.minSdkVersion.ApiLevel.String())
+ p.MinSdkVersion = proptools.StringPtr(canonical)
+ }
}
func (p *librarySdkMemberProperties) AddToPropertySet(ctx android.SdkMemberContext, propertySet android.BpPropertySet) {
@@ -792,6 +802,10 @@
propertySet.AddProperty("jars", []string{snapshotRelativeJavaLibPath})
}
+ if p.MinSdkVersion != nil {
+ propertySet.AddProperty("min_sdk_version", *p.MinSdkVersion)
+ }
+
if len(p.PermittedPackages) > 0 {
propertySet.AddProperty("permitted_packages", p.PermittedPackages)
}
@@ -1648,7 +1662,7 @@
var srcFiles []android.Path
ctx.VisitDirectDepsWithTag(javaApiContributionTag, func(dep android.Module) {
provider := ctx.OtherModuleProvider(dep, JavaApiImportProvider).(JavaApiImportInfo)
- srcFiles = append(srcFiles, android.PathForModuleSrc(ctx, provider.ApiFile.String()))
+ srcFiles = append(srcFiles, android.PathForSource(ctx, provider.ApiFile.String()))
})
cmd := metalavaStubCmd(ctx, rule, srcFiles, homeDir)
@@ -1673,6 +1687,8 @@
TransformJavaToClasses(ctx, al.stubsJar, 0, android.Paths{},
android.Paths{al.stubsSrcJar}, flags, android.Paths{})
+
+ ctx.Phony(ctx.ModuleName(), al.stubsJar)
}
//
@@ -2606,7 +2622,7 @@
if m.properties.Libs != nil {
// TODO 244210934 ALIX Check if this else statement breaks presubmits get rid of it if it doesn't
- if strings.HasPrefix(ctx.ModuleType(), "java_binary") {
+ if strings.HasPrefix(ctx.ModuleType(), "java_binary") || strings.HasPrefix(ctx.ModuleType(), "java_library") {
for _, d := range m.properties.Libs {
neverlinkLabel := android.BazelLabelForModuleDepSingle(ctx, d)
neverlinkLabel.Label = neverlinkLabel.Label + "-neverlink"
@@ -2674,12 +2690,21 @@
Deps: deps,
Exports: depLabels.StaticDeps,
}
+ name := m.Name()
if !bp2BuildInfo.hasKotlinSrcs && len(m.properties.Common_srcs) == 0 {
props = bazel.BazelTargetModuleProperties{
Rule_class: "java_library",
Bzl_load_location: "//build/bazel/rules/java:library.bzl",
}
+
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name}, attrs)
+ neverlinkProp := true
+ neverLinkAttrs := &javaLibraryAttributes{
+ Exports: bazel.MakeSingleLabelListAttribute(bazel.Label{Label: ":" + name}),
+ Neverlink: bazel.BoolAttribute{Value: &neverlinkProp},
+ }
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name + "-neverlink"}, neverLinkAttrs)
} else {
attrs.Common_srcs = bazel.MakeLabelListAttribute(android.BazelLabelForModuleSrc(ctx, m.properties.Common_srcs))
@@ -2687,10 +2712,10 @@
Rule_class: "kt_jvm_library",
Bzl_load_location: "@rules_kotlin//kotlin:jvm_library.bzl",
}
+ // TODO (b/244210934): create neverlink-duplicate target once kt_jvm_library supports neverlink attribute
+ ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name}, attrs)
}
- name := m.Name()
- ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name}, attrs)
}
type javaBinaryHostAttributes struct {
diff --git a/java/java_test.go b/java/java_test.go
index 62c2845..ff15783 100644
--- a/java/java_test.go
+++ b/java/java_test.go
@@ -1370,6 +1370,39 @@
}
}
+func TestAidlFlagsMinSdkVersionDroidstubs(t *testing.T) {
+ bpTemplate := `
+ droidstubs {
+ name: "foo-stubs",
+ srcs: ["foo.aidl"],
+ %s
+ system_modules: "none",
+ }
+ `
+ testCases := []struct {
+ desc string
+ sdkVersionBp string
+ minSdkVersionExpected string
+ }{
+ {
+ desc: "sdk_version not set, module compiles against private platform APIs",
+ sdkVersionBp: ``,
+ minSdkVersionExpected: "10000",
+ },
+ {
+ desc: "sdk_version set to none, module does not build against an SDK",
+ sdkVersionBp: `sdk_version: "none",`,
+ minSdkVersionExpected: "10000",
+ },
+ }
+ for _, tc := range testCases {
+ ctx := prepareForJavaTest.RunTestWithBp(t, fmt.Sprintf(bpTemplate, tc.sdkVersionBp))
+ aidlCmd := ctx.ModuleForTests("foo-stubs", "android_common").Rule("aidl").RuleParams.Command
+ expected := "--min_sdk_version=" + tc.minSdkVersionExpected
+ android.AssertStringDoesContain(t, "aidl command conatins incorrect min_sdk_version for testCse: "+tc.desc, aidlCmd, expected)
+ }
+}
+
func TestAidlEnforcePermissions(t *testing.T) {
ctx, _ := testJava(t, `
java_library {
diff --git a/java/legacy_core_platform_api_usage.go b/java/legacy_core_platform_api_usage.go
index 1f374b4..6cb549e 100644
--- a/java/legacy_core_platform_api_usage.go
+++ b/java/legacy_core_platform_api_usage.go
@@ -53,15 +53,6 @@
"SettingsGoogleOverlayCoral",
"SettingsGoogleOverlayFlame",
"SettingsLib",
- "SettingsOverlayG020I",
- "SettingsOverlayG020I_VN",
- "SettingsOverlayG020J",
- "SettingsOverlayG020M",
- "SettingsOverlayG020N",
- "SettingsOverlayG020P",
- "SettingsOverlayG020Q",
- "SettingsOverlayG025H",
- "SettingsOverlayG5NZ6",
"SettingsRoboTests",
"SimContact",
"SimContacts",
diff --git a/java/resourceshrinker_test.go b/java/resourceshrinker_test.go
new file mode 100644
index 0000000..3bbf116
--- /dev/null
+++ b/java/resourceshrinker_test.go
@@ -0,0 +1,53 @@
+// Copyright 2022 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 java
+
+import (
+ "testing"
+
+ "android/soong/android"
+)
+
+func TestShrinkResourcesArgs(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ PrepareForTestWithJavaDefaultModules,
+ ).RunTestWithBp(t, `
+ android_app {
+ name: "app_shrink",
+ platform_apis: true,
+ optimize: {
+ shrink_resources: true,
+ }
+ }
+
+ android_app {
+ name: "app_no_shrink",
+ platform_apis: true,
+ optimize: {
+ shrink_resources: false,
+ }
+ }
+ `)
+
+ appShrink := result.ModuleForTests("app_shrink", "android_common")
+ appShrinkResources := appShrink.Rule("shrinkResources")
+ android.AssertStringDoesContain(t, "expected shrinker.xml in app_shrink resource shrinker flags",
+ appShrinkResources.Args["raw_resources"], "shrinker.xml")
+
+ appNoShrink := result.ModuleForTests("app_no_shrink", "android_common")
+ if appNoShrink.MaybeRule("shrinkResources").Rule != nil {
+ t.Errorf("unexpected shrinkResources rule for app_no_shrink")
+ }
+}
diff --git a/java/sdk_library.go b/java/sdk_library.go
index fad1df7..56e5550 100644
--- a/java/sdk_library.go
+++ b/java/sdk_library.go
@@ -1648,6 +1648,7 @@
// shared libs and static libs. So we need to add both of these libs to Libs property.
props.Libs = module.properties.Libs
props.Libs = append(props.Libs, module.properties.Static_libs...)
+ props.Libs = append(props.Libs, module.sdkLibraryProperties.Stub_only_libs...)
props.Aidl.Include_dirs = module.deviceProperties.Aidl.Include_dirs
props.Aidl.Local_include_dirs = module.deviceProperties.Aidl.Local_include_dirs
props.Java_version = module.properties.Java_version
diff --git a/java/sdk_library_test.go b/java/sdk_library_test.go
index 096bca8..210bfc3 100644
--- a/java/sdk_library_test.go
+++ b/java/sdk_library_test.go
@@ -1385,3 +1385,29 @@
}
`)
}
+
+func TestJavaSdkLibrary_StubOnlyLibs_PassedToDroidstubs(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ prepareForJavaTest,
+ PrepareForTestWithJavaSdkLibraryFiles,
+ FixtureWithLastReleaseApis("foo"),
+ ).RunTestWithBp(t, `
+ java_sdk_library {
+ name: "foo",
+ srcs: ["a.java"],
+ public: {
+ enabled: true,
+ },
+ stub_only_libs: ["bar-lib"],
+ }
+
+ java_library {
+ name: "bar-lib",
+ srcs: ["b.java"],
+ }
+ `)
+
+ // The foo.stubs.source should depend on bar-lib
+ fooStubsSources := result.ModuleForTests("foo.stubs.source", "android_common").Module().(*Droidstubs)
+ android.AssertStringListContains(t, "foo stubs should depend on bar-lib", fooStubsSources.Javadoc.properties.Libs, "bar-lib")
+}
diff --git a/java/testing.go b/java/testing.go
index 49430ee..ccbb638 100644
--- a/java/testing.go
+++ b/java/testing.go
@@ -74,6 +74,7 @@
// Needed for R8 rules on apps
"build/make/core/proguard.flags": nil,
"build/make/core/proguard_basic_keeps.flags": nil,
+ "prebuilts/cmdline-tools/shrinker.xml": nil,
}.AddToFixture(),
)
diff --git a/licenses/Android.bp b/licenses/Android.bp
index 54981e1..eabc303 100644
--- a/licenses/Android.bp
+++ b/licenses/Android.bp
@@ -839,84 +839,84 @@
license_kind {
name: "SPDX-license-identifier-LGPL",
- conditions: ["restricted_allows_dynamic_linking"],
+ conditions: ["restricted_if_statically_linked"],
}
license_kind {
name: "SPDX-license-identifier-LGPL-2.0",
- conditions: ["restricted_allows_dynamic_linking"],
+ conditions: ["restricted_if_statically_linked"],
url: "https://spdx.org/licenses/LGPL-2.0.html",
}
license_kind {
name: "SPDX-license-identifier-LGPL-2.0+",
- conditions: ["restricted_allows_dynamic_linking"],
+ conditions: ["restricted_if_statically_linked"],
url: "https://spdx.org/licenses/LGPL-2.0+.html",
}
license_kind {
name: "SPDX-license-identifier-LGPL-2.0-only",
- conditions: ["restricted_allows_dynamic_linking"],
+ conditions: ["restricted_if_statically_linked"],
url: "https://spdx.org/licenses/LGPL-2.0-only.html",
}
license_kind {
name: "SPDX-license-identifier-LGPL-2.0-or-later",
- conditions: ["restricted_allows_dynamic_linking"],
+ conditions: ["restricted_if_statically_linked"],
url: "https://spdx.org/licenses/LGPL-2.0-or-later.html",
}
license_kind {
name: "SPDX-license-identifier-LGPL-2.1",
- conditions: ["restricted_allows_dynamic_linking"],
+ conditions: ["restricted_if_statically_linked"],
url: "https://spdx.org/licenses/LGPL-2.1.html",
}
license_kind {
name: "SPDX-license-identifier-LGPL-2.1+",
- conditions: ["restricted_allows_dynamic_linking"],
+ conditions: ["restricted_if_statically_linked"],
url: "https://spdx.org/licenses/LGPL-2.1+.html",
}
license_kind {
name: "SPDX-license-identifier-LGPL-2.1-only",
- conditions: ["restricted_allows_dynamic_linking"],
+ conditions: ["restricted_if_statically_linked"],
url: "https://spdx.org/licenses/LGPL-2.1-only.html",
}
license_kind {
name: "SPDX-license-identifier-LGPL-2.1-or-later",
- conditions: ["restricted_allows_dynamic_linking"],
+ conditions: ["restricted_if_statically_linked"],
url: "https://spdx.org/licenses/LGPL-2.1-or-later.html",
}
license_kind {
name: "SPDX-license-identifier-LGPL-3.0",
- conditions: ["restricted_allows_dynamic_linking"],
+ conditions: ["restricted_if_statically_linked"],
url: "https://spdx.org/licenses/LGPL-3.0.html",
}
license_kind {
name: "SPDX-license-identifier-LGPL-3.0+",
- conditions: ["restricted_allows_dynamic_linking"],
+ conditions: ["restricted_if_statically_linked"],
url: "https://spdx.org/licenses/LGPL-3.0+.html",
}
license_kind {
name: "SPDX-license-identifier-LGPL-3.0-only",
- conditions: ["restricted_allows_dynamic_linking"],
+ conditions: ["restricted_if_statically_linked"],
url: "https://spdx.org/licenses/LGPL-3.0-only.html",
}
license_kind {
name: "SPDX-license-identifier-LGPL-3.0-or-later",
- conditions: ["restricted_allows_dynamic_linking"],
+ conditions: ["restricted_if_statically_linked"],
url: "https://spdx.org/licenses/LGPL-3.0-or-later.html",
}
license_kind {
name: "SPDX-license-identifier-LGPLLR",
- conditions: ["restricted_allows_dynamic_linking"],
+ conditions: ["restricted_if_statically_linked"],
url: "https://spdx.org/licenses/LGPLLR.html",
}
diff --git a/sdk/bootclasspath_fragment_sdk_test.go b/sdk/bootclasspath_fragment_sdk_test.go
index 1b64130..92ecd5e 100644
--- a/sdk/bootclasspath_fragment_sdk_test.go
+++ b/sdk/bootclasspath_fragment_sdk_test.go
@@ -358,6 +358,7 @@
visibility: ["//visibility:public"],
apex_available: ["myapex"],
jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"],
+ min_sdk_version: "2",
permitted_packages: ["mybootlib"],
}
@@ -877,6 +878,7 @@
visibility: ["//visibility:public"],
apex_available: ["myapex"],
jars: ["java_boot_libs/snapshot/jars/are/invalid/mybootlib.jar"],
+ min_sdk_version: "1",
permitted_packages: ["mybootlib"],
}
diff --git a/sdk/java_sdk_test.go b/sdk/java_sdk_test.go
index 51903ce3..2ade146 100644
--- a/sdk/java_sdk_test.go
+++ b/sdk/java_sdk_test.go
@@ -352,6 +352,73 @@
})
}
+func TestSnapshotWithJavaLibrary_MinSdkVersion(t *testing.T) {
+ runTest := func(t *testing.T, targetBuildRelease, minSdkVersion, expectedMinSdkVersion string) {
+ result := android.GroupFixturePreparers(
+ prepareForSdkTestWithJava,
+ android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
+ variables.Platform_version_active_codenames = []string{"S", "Tiramisu", "Unfinalized"}
+ }),
+ android.FixtureMergeEnv(map[string]string{
+ "SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE": targetBuildRelease,
+ }),
+ ).RunTestWithBp(t, fmt.Sprintf(`
+ sdk {
+ name: "mysdk",
+ java_header_libs: ["mylib"],
+ }
+
+ java_library {
+ name: "mylib",
+ srcs: ["Test.java"],
+ system_modules: "none",
+ sdk_version: "none",
+ compile_dex: true,
+ min_sdk_version: "%s",
+ }
+ `, minSdkVersion))
+
+ expectedMinSdkVersionLine := ""
+ if expectedMinSdkVersion != "" {
+ expectedMinSdkVersionLine = fmt.Sprintf(" min_sdk_version: %q,\n", expectedMinSdkVersion)
+ }
+
+ CheckSnapshot(t, result, "mysdk", "",
+ checkAndroidBpContents(fmt.Sprintf(`
+// This is auto-generated. DO NOT EDIT.
+
+java_import {
+ name: "mylib",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["//apex_available:platform"],
+ jars: ["java/mylib.jar"],
+%s}
+`, expectedMinSdkVersionLine)),
+ )
+ }
+
+ t.Run("min_sdk_version=S in S", func(t *testing.T) {
+ // min_sdk_version was not added to java_import until Tiramisu.
+ runTest(t, "S", "S", "")
+ })
+
+ t.Run("min_sdk_version=S in Tiramisu", func(t *testing.T) {
+ // The canonical form of S is 31.
+ runTest(t, "Tiramisu", "S", "31")
+ })
+
+ t.Run("min_sdk_version=24 in Tiramisu", func(t *testing.T) {
+ // A numerical min_sdk_version is already in canonical form.
+ runTest(t, "Tiramisu", "24", "24")
+ })
+
+ t.Run("min_sdk_version=Unfinalized in latest", func(t *testing.T) {
+ // An unfinalized min_sdk_version has no numeric value yet.
+ runTest(t, "", "Unfinalized", "Unfinalized")
+ })
+}
+
func TestSnapshotWithJavaSystemserverLibrary(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
diff --git a/sdk/sdk_test.go b/sdk/sdk_test.go
index 2f9aee9..108a664 100644
--- a/sdk/sdk_test.go
+++ b/sdk/sdk_test.go
@@ -409,60 +409,6 @@
)
})
- t.Run("SOONG_SDK_SNAPSHOT_PREFER=true", func(t *testing.T) {
- result := android.GroupFixturePreparers(
- preparer,
- android.FixtureMergeEnv(map[string]string{
- "SOONG_SDK_SNAPSHOT_PREFER": "true",
- }),
- ).RunTest(t)
-
- checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk-current.zip")
-
- CheckSnapshot(t, result, "mysdk", "",
- checkAndroidBpContents(`
-// This is auto-generated. DO NOT EDIT.
-
-java_import {
- name: "myjavalib",
- prefer: true,
- visibility: ["//visibility:public"],
- apex_available: ["//apex_available:platform"],
- jars: ["java/myjavalib.jar"],
-}
- `),
- )
- })
-
- t.Run("SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR=module:build_from_source", func(t *testing.T) {
- result := android.GroupFixturePreparers(
- preparer,
- android.FixtureMergeEnv(map[string]string{
- "SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR": "module:build_from_source",
- }),
- ).RunTest(t)
-
- checkZipFile(t, result, "out/soong/.intermediates/mysdk/common_os/mysdk-current.zip")
-
- CheckSnapshot(t, result, "mysdk", "",
- checkAndroidBpContents(`
-// This is auto-generated. DO NOT EDIT.
-
-java_import {
- name: "myjavalib",
- prefer: false,
- use_source_config_var: {
- config_namespace: "module",
- var_name: "build_from_source",
- },
- visibility: ["//visibility:public"],
- apex_available: ["//apex_available:platform"],
- jars: ["java/myjavalib.jar"],
-}
- `),
- )
- })
-
t.Run("SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE=S", func(t *testing.T) {
result := android.GroupFixturePreparers(
prepareForSdkTestWithJava,
diff --git a/sdk/systemserverclasspath_fragment_sdk_test.go b/sdk/systemserverclasspath_fragment_sdk_test.go
index 1ac405d..2a17cdc 100644
--- a/sdk/systemserverclasspath_fragment_sdk_test.go
+++ b/sdk/systemserverclasspath_fragment_sdk_test.go
@@ -120,6 +120,7 @@
visibility: ["//visibility:public"],
apex_available: ["myapex"],
jars: ["java_systemserver_libs/snapshot/jars/are/invalid/mylib.jar"],
+ min_sdk_version: "2",
permitted_packages: ["mylib"],
}
@@ -181,6 +182,7 @@
visibility: ["//visibility:public"],
apex_available: ["myapex"],
jars: ["java_systemserver_libs/snapshot/jars/are/invalid/mylib.jar"],
+ min_sdk_version: "2",
permitted_packages: ["mylib"],
}
diff --git a/sdk/update.go b/sdk/update.go
index 92a13fa..baa2033 100644
--- a/sdk/update.go
+++ b/sdk/update.go
@@ -34,41 +34,6 @@
// Environment variables that affect the generated snapshot
// ========================================================
//
-// SOONG_SDK_SNAPSHOT_PREFER
-// By default every module in the generated snapshot has prefer: false. Building it
-// with SOONG_SDK_SNAPSHOT_PREFER=true will force them to use prefer: true.
-//
-// SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR
-// If set this specifies the Soong config var that can be used to control whether the prebuilt
-// modules from the generated snapshot or the original source modules. Values must be a colon
-// separated pair of strings, the first of which is the Soong config namespace, and the second
-// is the name of the variable within that namespace.
-//
-// The config namespace and var name are used to set the `use_source_config_var` property. That
-// in turn will cause the generated prebuilts to use the soong config variable to select whether
-// source or the prebuilt is used.
-// e.g. If an sdk snapshot is built using:
-// m SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR=acme:build_from_source sdkextensions-sdk
-// Then the resulting snapshot will include:
-// use_source_config_var: {
-// config_namespace: "acme",
-// var_name: "build_from_source",
-// }
-//
-// Assuming that the config variable is defined in .mk using something like:
-// $(call add_soong_config_namespace,acme)
-// $(call add_soong_config_var_value,acme,build_from_source,true)
-//
-// Then when the snapshot is unpacked in the repository it will have the following behavior:
-// m droid - will use the sdkextensions-sdk prebuilts if present. Otherwise, it will use the
-// sources.
-// m SOONG_CONFIG_acme_build_from_source=true droid - will use the sdkextensions-sdk
-// sources, if present. Otherwise, it will use the prebuilts.
-//
-// This is a temporary mechanism to control the prefer flags and will be removed once a more
-// maintainable solution has been implemented.
-// TODO(b/174997203): Remove when no longer necessary.
-//
// SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE
// This allows the target build release (i.e. the release version of the build within which
// the snapshot will be used) of the snapshot to be specified. If unspecified then it defaults
@@ -2019,29 +1984,12 @@
// Do not add the prefer property if the member snapshot module is a source module type.
moduleCtx := ctx.sdkMemberContext
- config := moduleCtx.Config()
if !memberType.UsesSourceModuleTypeInSnapshot() {
- // Set the prefer based on the environment variable. This is a temporary work around to allow a
- // snapshot to be created that sets prefer: true.
- // TODO(b/174997203): Remove once the ability to select the modules to prefer can be done
- // dynamically at build time not at snapshot generation time.
- prefer := config.IsEnvTrue("SOONG_SDK_SNAPSHOT_PREFER")
-
// Set prefer. Setting this to false is not strictly required as that is the default but it does
// provide a convenient hook to post-process the generated Android.bp file, e.g. in tests to
// check the behavior when a prebuilt is preferred. It also makes it explicit what the default
// behavior is for the module.
- bpModule.insertAfter("name", "prefer", prefer)
-
- configVar := config.Getenv("SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR")
- if configVar != "" {
- parts := strings.Split(configVar, ":")
- cfp := android.ConfigVarProperties{
- Config_namespace: proptools.StringPtr(parts[0]),
- Var_name: proptools.StringPtr(parts[1]),
- }
- bpModule.insertAfter("prefer", "use_source_config_var", cfp)
- }
+ bpModule.insertAfter("name", "prefer", false)
}
variants := selectApexVariantsWhereAvailable(ctx, member.variants)
diff --git a/ui/build/dumpvars.go b/ui/build/dumpvars.go
index adc56ac..b3b3866 100644
--- a/ui/build/dumpvars.go
+++ b/ui/build/dumpvars.go
@@ -154,10 +154,7 @@
"HOST_CROSS_OS",
"BUILD_ID",
"OUT_DIR",
- "SOONG_SDK_SNAPSHOT_PREFER",
"SOONG_SDK_SNAPSHOT_TARGET_BUILD_RELEASE",
- "SOONG_SDK_SNAPSHOT_USE_SOURCE_CONFIG_VAR",
- "SOONG_SDK_SNAPSHOT_VERSION",
}
func Banner(make_vars map[string]string) string {
diff --git a/ui/build/soong.go b/ui/build/soong.go
index c0bee4e..abaf5ae 100644
--- a/ui/build/soong.go
+++ b/ui/build/soong.go
@@ -195,6 +195,12 @@
allArgs = append(allArgs, commonArgs...)
allArgs = append(allArgs, environmentArgs(config, name)...)
+ if profileCpu := os.Getenv("SOONG_PROFILE_CPU"); profileCpu != "" {
+ allArgs = append(allArgs, "--cpuprofile", profileCpu+"."+name)
+ }
+ if profileMem := os.Getenv("SOONG_PROFILE_MEM"); profileMem != "" {
+ allArgs = append(allArgs, "--memprofile", profileMem+"."+name)
+ }
allArgs = append(allArgs, "Android.bp")
return bootstrap.PrimaryBuilderInvocation{