Add support for native bridge trait
Adds a native bridge trait that if required will cause a
cc_library_header module to generate a cc_prebuilt_library_headers with
native_bridge_supported: true. It will fail if the cc_library_header's
native bridge variant would produce native bridge specific properties,
distinct from the other architecture variants, in the generated
cc_prebuilt_library_headers.
Bug: 195754365
Test: m nothing
Change-Id: I282fbb9095de6c6af57cca4eb4260e2c6c2da8cc
diff --git a/cc/Android.bp b/cc/Android.bp
index bff2761..190d55e 100644
--- a/cc/Android.bp
+++ b/cc/Android.bp
@@ -63,6 +63,7 @@
"library.go",
"library_headers.go",
"library_sdk_member.go",
+ "native_bridge_sdk_trait.go",
"object.go",
"test.go",
"toolchain_library.go",
diff --git a/cc/library_headers.go b/cc/library_headers.go
index 14b90c1..b335035 100644
--- a/cc/library_headers.go
+++ b/cc/library_headers.go
@@ -33,6 +33,9 @@
PropertyName: "native_header_libs",
SupportsSdk: true,
HostOsDependent: true,
+ Traits: []android.SdkMemberTrait{
+ nativeBridgeSdkTrait,
+ },
},
prebuiltModuleType: "cc_prebuilt_library_headers",
noOutputFiles: true,
diff --git a/cc/library_sdk_member.go b/cc/library_sdk_member.go
index 559e940..bed7954 100644
--- a/cc/library_sdk_member.go
+++ b/cc/library_sdk_member.go
@@ -75,8 +75,33 @@
}
func (mt *librarySdkMemberType) AddDependencies(ctx android.SdkDependencyContext, dependencyTag blueprint.DependencyTag, names []string) {
- targets := ctx.MultiTargets()
+ // The base set of targets which does not include native bridge targets.
+ defaultTargets := ctx.MultiTargets()
+
+ // The lazily created list of native bridge targets.
+ var includeNativeBridgeTargets []android.Target
+
for _, lib := range names {
+ targets := defaultTargets
+
+ // If native bridge support is required in the sdk snapshot then add native bridge targets to
+ // the basic list of targets that are required.
+ nativeBridgeSupport := ctx.RequiresTrait(lib, nativeBridgeSdkTrait)
+ if nativeBridgeSupport && ctx.Device() {
+ // If not already computed then compute the list of native bridge targets.
+ if includeNativeBridgeTargets == nil {
+ includeNativeBridgeTargets = append([]android.Target{}, defaultTargets...)
+ allAndroidTargets := ctx.Config().Targets[android.Android]
+ for _, possibleNativeBridgeTarget := range allAndroidTargets {
+ if possibleNativeBridgeTarget.NativeBridge == android.NativeBridgeEnabled {
+ includeNativeBridgeTargets = append(includeNativeBridgeTargets, possibleNativeBridgeTarget)
+ }
+ }
+ }
+
+ // Include the native bridge targets as well.
+ targets = includeNativeBridgeTargets
+ }
for _, target := range targets {
name, version := StubsLibNameAndVersion(lib)
if version == "" {
@@ -122,6 +147,10 @@
ccModule := member.Variants()[0].(*Module)
+ if ctx.RequiresTrait(nativeBridgeSdkTrait) {
+ pbm.AddProperty("native_bridge_supported", true)
+ }
+
if proptools.Bool(ccModule.Properties.Recovery_available) {
pbm.AddProperty("recovery_available", true)
}
@@ -436,7 +465,11 @@
exportedIncludeDirs, exportedGeneratedIncludeDirs := android.FilterPathListPredicate(
exportedInfo.IncludeDirs, isGeneratedHeaderDirectory)
- p.archSubDir = ccModule.Target().Arch.ArchType.String()
+ target := ccModule.Target()
+ p.archSubDir = target.Arch.ArchType.String()
+ if target.NativeBridge == android.NativeBridgeEnabled {
+ p.archSubDir += "_native_bridge"
+ }
// Make sure that the include directories are unique.
p.ExportedIncludeDirs = android.FirstUniquePaths(exportedIncludeDirs)
diff --git a/cc/native_bridge_sdk_trait.go b/cc/native_bridge_sdk_trait.go
new file mode 100644
index 0000000..1326d57
--- /dev/null
+++ b/cc/native_bridge_sdk_trait.go
@@ -0,0 +1,33 @@
+// Copyright 2021 Google Inc. All rights reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package cc
+
+import "android/soong/android"
+
+// This file contains support for the native bridge sdk trait.
+
+func init() {
+ android.RegisterSdkMemberTrait(nativeBridgeSdkTrait)
+}
+
+type nativeBridgeSdkTraitStruct struct {
+ android.SdkMemberTraitBase
+}
+
+var nativeBridgeSdkTrait android.SdkMemberTrait = &nativeBridgeSdkTraitStruct{
+ SdkMemberTraitBase: android.SdkMemberTraitBase{
+ PropertyName: "native_bridge_support",
+ },
+}
diff --git a/sdk/cc_sdk_test.go b/sdk/cc_sdk_test.go
index 25e35fc..da90c6d 100644
--- a/sdk/cc_sdk_test.go
+++ b/sdk/cc_sdk_test.go
@@ -32,6 +32,23 @@
"some/where/stubslib.map.txt": nil,
}
+// Adds a native bridge target to the configured list of targets.
+var prepareForTestWithNativeBridgeTarget = android.FixtureModifyConfig(func(config android.Config) {
+ config.Targets[android.Android] = append(config.Targets[android.Android], android.Target{
+ Os: android.Android,
+ Arch: android.Arch{
+ ArchType: android.Arm64,
+ ArchVariant: "armv8-a",
+ CpuVariant: "cpu",
+ Abi: nil,
+ ArchFeatures: nil,
+ },
+ NativeBridge: android.NativeBridgeEnabled,
+ NativeBridgeHostArchName: "x86_64",
+ NativeBridgeRelativePath: "native_bridge",
+ })
+})
+
func testSdkWithCc(t *testing.T, bp string) *android.TestResult {
t.Helper()
return testSdkWithFs(t, bp, ccTestFs)
@@ -1979,6 +1996,91 @@
)
}
+func TestSnapshotWithCcHeadersLibraryAndNativeBridgeSupport(t *testing.T) {
+ result := android.GroupFixturePreparers(
+ cc.PrepareForTestWithCcDefaultModules,
+ PrepareForTestWithSdkBuildComponents,
+ ccTestFs.AddToFixture(),
+ prepareForTestWithNativeBridgeTarget,
+ ).RunTestWithBp(t, `
+ sdk {
+ name: "mysdk",
+ native_header_libs: ["mynativeheaders"],
+ traits: {
+ native_bridge_support: ["mynativeheaders"],
+ },
+ }
+
+ cc_library_headers {
+ name: "mynativeheaders",
+ export_include_dirs: ["myinclude"],
+ stl: "none",
+ system_shared_libs: [],
+ native_bridge_supported: true,
+ }
+ `)
+
+ CheckSnapshot(t, result, "mysdk", "",
+ checkUnversionedAndroidBpContents(`
+// This is auto-generated. DO NOT EDIT.
+
+cc_prebuilt_library_headers {
+ name: "mynativeheaders",
+ prefer: false,
+ visibility: ["//visibility:public"],
+ apex_available: ["//apex_available:platform"],
+ native_bridge_supported: true,
+ stl: "none",
+ compile_multilib: "both",
+ system_shared_libs: [],
+ export_include_dirs: ["include/myinclude"],
+}
+`),
+ checkAllCopyRules(`
+myinclude/Test.h -> include/myinclude/Test.h
+`),
+ )
+}
+
+// TestSnapshotWithCcHeadersLibrary_DetectsNativeBridgeSpecificProperties verifies that when a
+// module that has different output files for a native bridge target requests the native bridge
+// variants are copied into the sdk snapshot that it reports an error.
+func TestSnapshotWithCcHeadersLibrary_DetectsNativeBridgeSpecificProperties(t *testing.T) {
+ android.GroupFixturePreparers(
+ cc.PrepareForTestWithCcDefaultModules,
+ PrepareForTestWithSdkBuildComponents,
+ ccTestFs.AddToFixture(),
+ prepareForTestWithNativeBridgeTarget,
+ ).ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(
+ `\QArchitecture variant "arm64_native_bridge" of sdk member "mynativeheaders" has properties distinct from other variants; this is not yet supported. The properties are:
+ export_include_dirs: [
+ "arm64_native_bridge/include/myinclude_nativebridge",
+ "arm64_native_bridge/include/myinclude",
+ ],\E`)).
+ RunTestWithBp(t, `
+ sdk {
+ name: "mysdk",
+ native_header_libs: ["mynativeheaders"],
+ traits: {
+ native_bridge_support: ["mynativeheaders"],
+ },
+ }
+
+ cc_library_headers {
+ name: "mynativeheaders",
+ export_include_dirs: ["myinclude"],
+ stl: "none",
+ system_shared_libs: [],
+ native_bridge_supported: true,
+ target: {
+ native_bridge: {
+ export_include_dirs: ["myinclude_nativebridge"],
+ },
+ },
+ }
+ `)
+}
+
func TestHostSnapshotWithCcHeadersLibrary(t *testing.T) {
result := testSdkWithCc(t, `
sdk {