Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// Copyright 2018 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 apex
import (
2020-12-09 13:18:56 +01:00
"fmt"
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
"os"
2019-11-06 08:53:07 +01:00
"path"
2021-02-26 15:24:15 +01:00
"path/filepath"
2019-07-17 03:25:41 +02:00
"reflect"
2020-05-26 14:21:35 +02:00
"regexp"
2019-10-18 09:26:59 +02:00
"sort"
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
"strconv"
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
"strings"
"testing"
2018-12-19 09:12:36 +01:00
"github.com/google/blueprint/proptools"
"android/soong/android"
2020-09-02 10:23:38 +02:00
"android/soong/bpf"
2018-12-19 09:12:36 +01:00
"android/soong/cc"
2020-01-13 16:18:16 +01:00
"android/soong/dexpreopt"
2020-06-01 19:45:49 +02:00
prebuilt_etc "android/soong/etc"
2019-02-11 03:38:15 +01:00
"android/soong/java"
2020-11-17 14:21:02 +01:00
"android/soong/rust"
2020-06-01 19:45:49 +02:00
"android/soong/sh"
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
)
2019-08-09 05:57:43 +02:00
// names returns name list from white space separated string
func names ( s string ) ( ns [ ] string ) {
for _ , n := range strings . Split ( s , " " ) {
if len ( n ) > 0 {
ns = append ( ns , n )
}
}
return
}
2021-03-20 12:39:01 +01:00
func testApexError ( t * testing . T , pattern , bp string , preparers ... android . FixturePreparer ) {
2019-08-23 04:17:39 +02:00
t . Helper ( )
2021-03-29 02:50:31 +02:00
android . GroupFixturePreparers (
prepareForApexTest ,
android . GroupFixturePreparers ( preparers ... ) ,
) .
2021-03-08 16:07:14 +01:00
ExtendWithErrorHandler ( android . FixtureExpectsAtLeastOneErrorMatchingPattern ( pattern ) ) .
2021-03-20 12:39:01 +01:00
RunTestWithBp ( t , bp )
2019-06-27 04:30:33 +02:00
}
2021-03-20 12:39:01 +01:00
func testApex ( t * testing . T , bp string , preparers ... android . FixturePreparer ) * android . TestContext {
2019-08-23 04:17:39 +02:00
t . Helper ( )
2021-03-29 02:50:31 +02:00
optionalBpPreparer := android . NullFixturePreparer
2021-03-20 12:39:01 +01:00
if bp != "" {
2021-03-29 02:50:31 +02:00
optionalBpPreparer = android . FixtureWithRootAndroidBp ( bp )
2021-03-20 12:39:01 +01:00
}
2021-03-29 02:50:31 +02:00
result := android . GroupFixturePreparers (
prepareForApexTest ,
android . GroupFixturePreparers ( preparers ... ) ,
optionalBpPreparer ,
) . RunTest ( t )
2021-03-08 16:07:14 +01:00
return result . TestContext
2019-06-27 04:30:33 +02:00
}
2021-03-09 15:12:32 +01:00
func withFiles ( files android . MockFS ) android . FixturePreparer {
return files . AddToFixture ( )
2019-08-23 04:17:39 +02:00
}
2021-03-09 15:12:32 +01:00
func withTargets ( targets map [ android . OsType ] [ ] android . Target ) android . FixturePreparer {
return android . FixtureModifyConfig ( func ( config android . Config ) {
2019-08-23 04:17:39 +02:00
for k , v := range targets {
config . Targets [ k ] = v
}
2021-03-09 15:12:32 +01:00
} )
2019-08-23 04:17:39 +02:00
}
2020-02-06 09:33:20 +01:00
// withNativeBridgeTargets sets configuration with targets including:
// - X86_64 (primary)
// - X86 (secondary)
// - Arm64 on X86_64 (native bridge)
// - Arm on X86 (native bridge)
2021-03-09 15:12:32 +01:00
var withNativeBridgeEnabled = android . FixtureModifyConfig (
func ( config android . Config ) {
config . Targets [ android . Android ] = [ ] android . Target {
{ Os : android . Android , Arch : android . Arch { ArchType : android . X86_64 , ArchVariant : "silvermont" , Abi : [ ] string { "arm64-v8a" } } ,
NativeBridge : android . NativeBridgeDisabled , NativeBridgeHostArchName : "" , NativeBridgeRelativePath : "" } ,
{ Os : android . Android , Arch : android . Arch { ArchType : android . X86 , ArchVariant : "silvermont" , Abi : [ ] string { "armeabi-v7a" } } ,
NativeBridge : android . NativeBridgeDisabled , NativeBridgeHostArchName : "" , NativeBridgeRelativePath : "" } ,
{ Os : android . Android , Arch : android . Arch { ArchType : android . Arm64 , ArchVariant : "armv8-a" , Abi : [ ] string { "arm64-v8a" } } ,
NativeBridge : android . NativeBridgeEnabled , NativeBridgeHostArchName : "x86_64" , NativeBridgeRelativePath : "arm64" } ,
{ Os : android . Android , Arch : android . Arch { ArchType : android . Arm , ArchVariant : "armv7-a-neon" , Abi : [ ] string { "armeabi-v7a" } } ,
NativeBridge : android . NativeBridgeEnabled , NativeBridgeHostArchName : "x86" , NativeBridgeRelativePath : "arm" } ,
}
} ,
)
2020-02-06 09:33:20 +01:00
2021-03-09 15:12:32 +01:00
func withManifestPackageNameOverrides ( specs [ ] string ) android . FixturePreparer {
return android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . ManifestPackageNameOverrides = specs
} )
2020-02-28 08:51:07 +01:00
}
2021-03-09 15:12:32 +01:00
var withBinder32bit = android . FixtureModifyProductVariables (
func ( variables android . FixtureProductVariables ) {
variables . Binder32bit = proptools . BoolPtr ( true )
} ,
)
2019-10-18 09:26:59 +02:00
2021-03-09 15:12:32 +01:00
var withUnbundledBuild = android . FixtureModifyProductVariables (
func ( variables android . FixtureProductVariables ) {
variables . Unbundled_build = proptools . BoolPtr ( true )
} ,
)
2020-01-14 01:22:18 +01:00
2021-03-29 02:50:31 +02:00
// Legacy preparer used for running tests within the apex package.
//
// This includes everything that was needed to run any test in the apex package prior to the
// introduction of the test fixtures. Tests that are being converted to use fixtures directly
// rather than through the testApex...() methods should avoid using this and instead use the
// various preparers directly, using android.GroupFixturePreparers(...) to group them when
// necessary.
//
// deprecated
var prepareForApexTest = android . GroupFixturePreparers (
2021-03-08 10:47:16 +01:00
// General preparers in alphabetical order as test infrastructure will enforce correct
// registration order.
android . PrepareForTestWithAndroidBuildComponents ,
bpf . PrepareForTestWithBpf ,
cc . PrepareForTestWithCcBuildComponents ,
java . PrepareForTestWithJavaDefaultModules ,
prebuilt_etc . PrepareForTestWithPrebuiltEtc ,
rust . PrepareForTestWithRustDefaultModules ,
sh . PrepareForTestWithShBuildComponents ,
PrepareForTestWithApexBuildComponents ,
// Additional apex test specific preparers.
android . FixtureAddTextFile ( "system/sepolicy/Android.bp" , `
filegroup {
name : "myapex-file_contexts" ,
srcs : [
"apex/myapex-file_contexts" ,
] ,
}
` ) ,
2021-03-24 00:40:12 +01:00
prepareForTestWithMyapex ,
2021-03-08 10:47:16 +01:00
android . FixtureMergeMockFs ( android . MockFS {
2021-03-24 00:40:12 +01:00
"a.java" : nil ,
"PrebuiltAppFoo.apk" : nil ,
"PrebuiltAppFooPriv.apk" : nil ,
"apex_manifest.json" : nil ,
"AndroidManifest.xml" : nil ,
2021-03-08 10:47:16 +01:00
"system/sepolicy/apex/myapex.updatable-file_contexts" : nil ,
"system/sepolicy/apex/myapex2-file_contexts" : nil ,
"system/sepolicy/apex/otherapex-file_contexts" : nil ,
"system/sepolicy/apex/com.android.vndk-file_contexts" : nil ,
"system/sepolicy/apex/com.android.vndk.current-file_contexts" : nil ,
"mylib.cpp" : nil ,
"mytest.cpp" : nil ,
"mytest1.cpp" : nil ,
"mytest2.cpp" : nil ,
"mytest3.cpp" : nil ,
"myprebuilt" : nil ,
"my_include" : nil ,
"foo/bar/MyClass.java" : nil ,
"prebuilt.jar" : nil ,
"prebuilt.so" : nil ,
"vendor/foo/devkeys/test.x509.pem" : nil ,
"vendor/foo/devkeys/test.pk8" : nil ,
"testkey.x509.pem" : nil ,
"testkey.pk8" : nil ,
"testkey.override.x509.pem" : nil ,
"testkey.override.pk8" : nil ,
"vendor/foo/devkeys/testkey.avbpubkey" : nil ,
"vendor/foo/devkeys/testkey.pem" : nil ,
"NOTICE" : nil ,
"custom_notice" : nil ,
"custom_notice_for_static_lib" : nil ,
"testkey2.avbpubkey" : nil ,
"testkey2.pem" : nil ,
"myapex-arm64.apex" : nil ,
"myapex-arm.apex" : nil ,
"myapex.apks" : nil ,
"frameworks/base/api/current.txt" : nil ,
"framework/aidl/a.aidl" : nil ,
"build/make/core/proguard.flags" : nil ,
"build/make/core/proguard_basic_keeps.flags" : nil ,
"dummy.txt" : nil ,
"baz" : nil ,
"bar/baz" : nil ,
"testdata/baz" : nil ,
"AppSet.apks" : nil ,
"foo.rs" : nil ,
"libfoo.jar" : nil ,
"libbar.jar" : nil ,
} ,
) ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . DeviceVndkVersion = proptools . StringPtr ( "current" )
variables . DefaultAppCertificate = proptools . StringPtr ( "vendor/foo/devkeys/test" )
variables . CertificateOverrides = [ ] string { "myapex_keytest:myapex.certificate.override" }
variables . Platform_sdk_codename = proptools . StringPtr ( "Q" )
variables . Platform_sdk_final = proptools . BoolPtr ( false )
variables . Platform_version_active_codenames = [ ] string { "Q" }
2021-04-01 14:35:20 +02:00
variables . Platform_vndk_version = proptools . StringPtr ( "29" )
2021-03-08 10:47:16 +01:00
} ) ,
)
2021-03-24 00:40:12 +01:00
var prepareForTestWithMyapex = android . FixtureMergeMockFs ( android . MockFS {
"system/sepolicy/apex/myapex-file_contexts" : nil ,
} )
2020-02-27 05:50:06 +01:00
// ensure that 'result' equals 'expected'
func ensureEquals ( t * testing . T , result string , expected string ) {
t . Helper ( )
if result != expected {
t . Errorf ( "%q != %q" , expected , result )
}
}
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// ensure that 'result' contains 'expected'
func ensureContains ( t * testing . T , result string , expected string ) {
2019-06-27 04:30:33 +02:00
t . Helper ( )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
if ! strings . Contains ( result , expected ) {
t . Errorf ( "%q is not found in %q" , expected , result )
}
}
2020-05-28 00:15:11 +02:00
// ensure that 'result' contains 'expected' exactly one time
func ensureContainsOnce ( t * testing . T , result string , expected string ) {
t . Helper ( )
count := strings . Count ( result , expected )
if count != 1 {
t . Errorf ( "%q is found %d times (expected 1 time) in %q" , expected , count , result )
}
}
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// ensures that 'result' does not contain 'notExpected'
func ensureNotContains ( t * testing . T , result string , notExpected string ) {
2019-06-27 04:30:33 +02:00
t . Helper ( )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
if strings . Contains ( result , notExpected ) {
t . Errorf ( "%q is found in %q" , notExpected , result )
}
}
2020-05-28 01:36:07 +02:00
func ensureMatches ( t * testing . T , result string , expectedRex string ) {
ok , err := regexp . MatchString ( expectedRex , result )
if err != nil {
t . Fatalf ( "regexp failure trying to match %s against `%s` expression: %s" , result , expectedRex , err )
return
}
if ! ok {
t . Errorf ( "%s does not match regular expession %s" , result , expectedRex )
}
}
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
func ensureListContains ( t * testing . T , result [ ] string , expected string ) {
2019-06-27 04:30:33 +02:00
t . Helper ( )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
if ! android . InList ( expected , result ) {
t . Errorf ( "%q is not found in %v" , expected , result )
}
}
func ensureListNotContains ( t * testing . T , result [ ] string , notExpected string ) {
2019-06-27 04:30:33 +02:00
t . Helper ( )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
if android . InList ( notExpected , result ) {
t . Errorf ( "%q is found in %v" , notExpected , result )
}
}
2019-08-01 10:41:43 +02:00
func ensureListEmpty ( t * testing . T , result [ ] string ) {
t . Helper ( )
if len ( result ) > 0 {
t . Errorf ( "%q is expected to be empty" , result )
}
}
2020-11-26 14:32:26 +01:00
func ensureListNotEmpty ( t * testing . T , result [ ] string ) {
t . Helper ( )
if len ( result ) == 0 {
t . Errorf ( "%q is expected to be not empty" , result )
}
}
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// Minimal test
func TestBasicApex ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-02-07 08:27:23 +01:00
apex_defaults {
name : "myapex-defaults" ,
2019-02-13 13:33:49 +01:00
manifest : ":myapex.manifest" ,
androidManifest : ":myapex.androidmanifest" ,
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
key : "myapex.key" ,
2020-11-17 14:21:02 +01:00
binaries : [ "foo.rust" ] ,
2020-12-08 16:20:45 +01:00
native_shared_libs : [
"mylib" ,
"libfoo.ffi" ,
] ,
2020-11-17 14:21:02 +01:00
rust_dyn_libs : [ "libfoo.dylib.rust" ] ,
2019-01-18 23:37:31 +01:00
multilib : {
both : {
2020-11-17 14:21:02 +01:00
binaries : [ "foo" ] ,
2019-01-18 23:37:31 +01:00
}
2019-07-25 15:02:35 +02:00
} ,
2020-06-01 14:39:15 +02:00
java_libs : [
"myjar" ,
"myjar_dex" ,
] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
}
2019-02-07 08:27:23 +01:00
apex {
name : "myapex" ,
defaults : [ "myapex-defaults" ] ,
}
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
2019-02-13 13:33:49 +01:00
filegroup {
name : "myapex.manifest" ,
srcs : [ "apex_manifest.json" ] ,
}
filegroup {
name : "myapex.androidmanifest" ,
srcs : [ "AndroidManifest.xml" ] ,
}
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
2020-12-08 16:20:45 +01:00
shared_libs : [
"mylib2" ,
"libbar.ffi" ,
] ,
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
// TODO: remove //apex_available:platform
apex_available : [
"//apex_available:platform" ,
"myapex" ,
] ,
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
}
2019-01-18 23:37:31 +01:00
cc_binary {
name : "foo" ,
srcs : [ "mylib.cpp" ] ,
compile_multilib : "both" ,
multilib : {
lib32 : {
suffix : "32" ,
} ,
lib64 : {
suffix : "64" ,
} ,
} ,
symlinks : [ "foo_link_" ] ,
symlink_preferred_arch : true ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-07-29 02:37:46 +02:00
apex_available : [ "myapex" , "com.android.gki.*" ] ,
}
2020-11-17 14:21:02 +01:00
rust_binary {
2021-03-11 19:03:42 +01:00
name : "foo.rust" ,
2020-11-17 14:21:02 +01:00
srcs : [ "foo.rs" ] ,
rlibs : [ "libfoo.rlib.rust" ] ,
dylibs : [ "libfoo.dylib.rust" ] ,
apex_available : [ "myapex" ] ,
}
rust_library_rlib {
2021-03-11 19:03:42 +01:00
name : "libfoo.rlib.rust" ,
2020-11-17 14:21:02 +01:00
srcs : [ "foo.rs" ] ,
crate_name : "foo" ,
apex_available : [ "myapex" ] ,
2021-04-08 11:19:15 +02:00
shared_libs : [ "libfoo.shared_from_rust" ] ,
}
cc_library_shared {
name : "libfoo.shared_from_rust" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" ] ,
2020-11-17 14:21:02 +01:00
}
rust_library_dylib {
2021-03-11 19:03:42 +01:00
name : "libfoo.dylib.rust" ,
2020-11-17 14:21:02 +01:00
srcs : [ "foo.rs" ] ,
crate_name : "foo" ,
apex_available : [ "myapex" ] ,
}
2020-12-08 16:20:45 +01:00
rust_ffi_shared {
name : "libfoo.ffi" ,
srcs : [ "foo.rs" ] ,
crate_name : "foo" ,
apex_available : [ "myapex" ] ,
}
rust_ffi_shared {
name : "libbar.ffi" ,
srcs : [ "foo.rs" ] ,
crate_name : "bar" ,
apex_available : [ "myapex" ] ,
}
2020-07-29 02:37:46 +02:00
apex {
name : "com.android.gki.fake" ,
binaries : [ "foo" ] ,
key : "myapex.key" ,
file_contexts : ":myapex-file_contexts" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-01-18 23:37:31 +01:00
}
2020-04-07 16:25:44 +02:00
cc_library_shared {
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
name : "mylib2" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
2019-03-18 04:01:38 +01:00
notice : "custom_notice" ,
2020-03-17 11:16:40 +01:00
static_libs : [ "libstatic" ] ,
// TODO: remove //apex_available:platform
apex_available : [
"//apex_available:platform" ,
"myapex" ,
] ,
}
2020-04-07 16:25:44 +02:00
cc_prebuilt_library_shared {
name : "mylib2" ,
srcs : [ "prebuilt.so" ] ,
// TODO: remove //apex_available:platform
apex_available : [
"//apex_available:platform" ,
"myapex" ,
] ,
}
2020-03-17 11:16:40 +01:00
cc_library_static {
name : "libstatic" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
notice : "custom_notice_for_static_lib" ,
2020-01-10 16:12:39 +01:00
// TODO: remove //apex_available:platform
apex_available : [
"//apex_available:platform" ,
"myapex" ,
] ,
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
}
2019-07-25 15:02:35 +02:00
java_library {
name : "myjar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
2020-05-28 16:46:55 +02:00
stem : "myjar_stem" ,
2019-07-25 15:02:35 +02:00
sdk_version : "none" ,
system_modules : "none" ,
static_libs : [ "myotherjar" ] ,
2019-12-27 06:11:47 +01:00
libs : [ "mysharedjar" ] ,
2020-01-10 16:12:39 +01:00
// TODO: remove //apex_available:platform
apex_available : [
"//apex_available:platform" ,
"myapex" ,
] ,
2019-07-25 15:02:35 +02:00
}
2020-06-01 14:39:15 +02:00
dex_import {
name : "myjar_dex" ,
jars : [ "prebuilt.jar" ] ,
apex_available : [
"//apex_available:platform" ,
"myapex" ,
] ,
}
2019-07-25 15:02:35 +02:00
java_library {
name : "myotherjar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
sdk_version : "none" ,
system_modules : "none" ,
apex_available tracks static dependencies
This change fixes a bug that apex_available is not enforced for static
dependencies. For example, a module with 'apex_available:
["//apex_available:platform"]' was able to be statically linked to any
APEX. This was happening because the check was done on the modules that
are actually installed to an APEX. Static dependencies of the modules
were not counted as they are not installed to the APEX as files.
Fixing this bug by doing the check by traversing the tree in the method
checkApexAvailability.
This change includes a few number of related changes:
1) DepIsInSameApex implementation for cc.Module was changed as well.
Previuosly, it returned false only when the dependency is actually a
stub variant of a lib. Now, it returns false when the dependency has one
or more stub variants. To understand why, we need to recall that when
there is a dependency to a lib having stubs, we actually create two
dependencies: to the non-stub variant and to the stub variant during the
DepsMutator phase. And later in the build action generation phase, we
choose one of them depending on the context. Also recall that an APEX
variant is created only when DepIsInSameApex returns true. Given these,
with the previous implementatin of DepIsInSameApex, we did create apex
variants of the non-stub variant of the dependency, while not creating
the apex variant for the stub variant. This is not right; we needlessly
created the apex variant. The extra apex variant has caused no harm so
far, but since the apex_available check became more correct, it actually
breaks the build. To fix the issue, we stop creating the APEX variant
both for non-stub and stub variants.
2) platform variant is created regardless of the apex_available value.
This is required for the case when a library X that provides stub is in
an APEX A and is configured to be available only for A. In that case,
libs in other APEX can't use the stub library since the stub library is
mutated only for apex A. By creating the platform variant for the stub
library, it can be used from outside as the default dependency variation
is set to the platform variant when creating the APEX variations.
3) The ApexAvailableWhitelist is added with the dependencies that were
revealed with this change.
Exempt-From-Owner-Approval: cherry-pick from internal
Bug: 147671264
Test: m
Merged-In: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
(cherry picked from commit fa89944c79f19552e906b41fd03a4981903eee7e)
Change-Id: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
2020-01-30 18:49:53 +01:00
// TODO: remove //apex_available:platform
apex_available : [
"//apex_available:platform" ,
"myapex" ,
] ,
2019-07-25 15:02:35 +02:00
}
2019-12-27 06:11:47 +01:00
java_library {
name : "mysharedjar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
sdk_version : "none" ,
system_modules : "none" ,
}
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
` )
2021-03-29 01:42:57 +02:00
apexRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "apexRule" )
2019-04-01 04:15:50 +02:00
2020-06-10 17:35:03 +02:00
// Make sure that Android.mk is created
ab := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Module ( ) . ( * apexBundle )
2020-07-03 22:18:24 +02:00
data := android . AndroidMkDataForTest ( t , ctx , ab )
2020-06-10 17:35:03 +02:00
var builder strings . Builder
data . Custom ( & builder , ab . BaseModuleName ( ) , "TARGET_" , "" , data )
androidMk := builder . String ( )
ensureContains ( t , androidMk , "LOCAL_MODULE := mylib.myapex\n" )
ensureNotContains ( t , androidMk , "LOCAL_MODULE := mylib.com.android.myapex\n" )
2019-04-01 04:15:50 +02:00
optFlags := apexRule . Args [ "opt_flags" ]
ensureContains ( t , optFlags , "--pubkey vendor/foo/devkeys/testkey.avbpubkey" )
2019-06-18 22:09:13 +02:00
// Ensure that the NOTICE output is being packaged as an asset.
2021-03-29 01:21:08 +02:00
ensureContains ( t , optFlags , "--assets_dir out/soong/.intermediates/myapex/android_common_myapex_image/NOTICE" )
2019-04-01 04:15:50 +02:00
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
copyCmds := apexRule . Args [ "copy_commands" ]
// Ensure that main rule creates an output
ensureContains ( t , apexRule . Output . String ( ) , "myapex.apex.unsigned" )
// Ensure that apex variant is created for the direct dep
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
ensureListContains ( t , ctx . ModuleVariantsForTests ( "mylib" ) , "android_arm64_armv8-a_shared_apex10000" )
ensureListContains ( t , ctx . ModuleVariantsForTests ( "myjar" ) , "android_common_apex10000" )
ensureListContains ( t , ctx . ModuleVariantsForTests ( "myjar_dex" ) , "android_common_apex10000" )
2020-11-17 14:21:02 +01:00
ensureListContains ( t , ctx . ModuleVariantsForTests ( "foo.rust" ) , "android_arm64_armv8-a_apex10000" )
2020-12-08 16:20:45 +01:00
ensureListContains ( t , ctx . ModuleVariantsForTests ( "libfoo.ffi" ) , "android_arm64_armv8-a_shared_apex10000" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// Ensure that apex variant is created for the indirect dep
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
ensureListContains ( t , ctx . ModuleVariantsForTests ( "mylib2" ) , "android_arm64_armv8-a_shared_apex10000" )
ensureListContains ( t , ctx . ModuleVariantsForTests ( "myotherjar" ) , "android_common_apex10000" )
2020-11-17 14:21:02 +01:00
ensureListContains ( t , ctx . ModuleVariantsForTests ( "libfoo.rlib.rust" ) , "android_arm64_armv8-a_rlib_dylib-std_apex10000" )
ensureListContains ( t , ctx . ModuleVariantsForTests ( "libfoo.dylib.rust" ) , "android_arm64_armv8-a_dylib_apex10000" )
2020-12-08 16:20:45 +01:00
ensureListContains ( t , ctx . ModuleVariantsForTests ( "libbar.ffi" ) , "android_arm64_armv8-a_shared_apex10000" )
2021-04-08 11:19:15 +02:00
ensureListContains ( t , ctx . ModuleVariantsForTests ( "libfoo.shared_from_rust" ) , "android_arm64_armv8-a_shared_apex10000" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// Ensure that both direct and indirect deps are copied into apex
2018-11-30 02:12:15 +01:00
ensureContains ( t , copyCmds , "image.apex/lib64/mylib.so" )
ensureContains ( t , copyCmds , "image.apex/lib64/mylib2.so" )
2020-05-28 16:46:55 +02:00
ensureContains ( t , copyCmds , "image.apex/javalib/myjar_stem.jar" )
2020-06-01 14:39:15 +02:00
ensureContains ( t , copyCmds , "image.apex/javalib/myjar_dex.jar" )
2020-11-17 14:21:02 +01:00
ensureContains ( t , copyCmds , "image.apex/lib64/libfoo.dylib.rust.dylib.so" )
2020-12-08 16:20:45 +01:00
ensureContains ( t , copyCmds , "image.apex/lib64/libfoo.ffi.so" )
ensureContains ( t , copyCmds , "image.apex/lib64/libbar.ffi.so" )
2021-04-08 11:19:15 +02:00
ensureContains ( t , copyCmds , "image.apex/lib64/libfoo.shared_from_rust.so" )
2019-07-25 15:02:35 +02:00
// .. but not for java libs
ensureNotContains ( t , copyCmds , "image.apex/javalib/myotherjar.jar" )
2019-12-27 06:11:47 +01:00
ensureNotContains ( t , copyCmds , "image.apex/javalib/msharedjar.jar" )
2018-12-26 08:32:21 +01:00
2019-11-21 01:39:12 +01:00
// Ensure that the platform variant ends with _shared or _common
ensureListContains ( t , ctx . ModuleVariantsForTests ( "mylib" ) , "android_arm64_armv8-a_shared" )
ensureListContains ( t , ctx . ModuleVariantsForTests ( "mylib2" ) , "android_arm64_armv8-a_shared" )
2019-07-25 15:02:35 +02:00
ensureListContains ( t , ctx . ModuleVariantsForTests ( "myjar" ) , "android_common" )
ensureListContains ( t , ctx . ModuleVariantsForTests ( "myotherjar" ) , "android_common" )
2019-12-27 06:11:47 +01:00
ensureListContains ( t , ctx . ModuleVariantsForTests ( "mysharedjar" ) , "android_common" )
// Ensure that dynamic dependency to java libs are not included
ensureListNotContains ( t , ctx . ModuleVariantsForTests ( "mysharedjar" ) , "android_common_myapex" )
2019-01-18 23:37:31 +01:00
// Ensure that all symlinks are present.
found_foo_link_64 := false
found_foo := false
for _ , cmd := range strings . Split ( copyCmds , " && " ) {
2020-01-14 01:22:18 +01:00
if strings . HasPrefix ( cmd , "ln -sfn foo64" ) {
2019-01-18 23:37:31 +01:00
if strings . HasSuffix ( cmd , "bin/foo" ) {
found_foo = true
} else if strings . HasSuffix ( cmd , "bin/foo_link_64" ) {
found_foo_link_64 = true
}
}
}
good := found_foo && found_foo_link_64
if ! good {
t . Errorf ( "Could not find all expected symlinks! foo: %t, foo_link_64: %t. Command was %s" , found_foo , found_foo_link_64 , copyCmds )
}
2019-03-18 04:01:38 +01:00
2019-10-22 06:58:29 +02:00
mergeNoticesRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "mergeNoticesRule" )
2019-06-18 02:40:56 +02:00
noticeInputs := mergeNoticesRule . Inputs . Strings ( )
2020-03-17 11:16:40 +01:00
if len ( noticeInputs ) != 3 {
t . Errorf ( "number of input notice files: expected = 3, actual = %q" , len ( noticeInputs ) )
2019-03-18 04:01:38 +01:00
}
ensureListContains ( t , noticeInputs , "NOTICE" )
ensureListContains ( t , noticeInputs , "custom_notice" )
2020-03-17 11:16:40 +01:00
ensureListContains ( t , noticeInputs , "custom_notice_for_static_lib" )
2020-01-14 10:38:44 +01:00
2020-04-27 19:07:06 +02:00
fullDepsInfo := strings . Split ( ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Output ( "depsinfo/fulllist.txt" ) . Args [ "content" ] , "\\n" )
2020-05-14 16:15:01 +02:00
ensureListContains ( t , fullDepsInfo , " myjar(minSdkVersion:(no version)) <- myapex" )
ensureListContains ( t , fullDepsInfo , " mylib2(minSdkVersion:(no version)) <- mylib" )
ensureListContains ( t , fullDepsInfo , " myotherjar(minSdkVersion:(no version)) <- myjar" )
ensureListContains ( t , fullDepsInfo , " mysharedjar(minSdkVersion:(no version)) (external) <- myjar" )
2020-04-27 19:07:06 +02:00
flatDepsInfo := strings . Split ( ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Output ( "depsinfo/flatlist.txt" ) . Args [ "content" ] , "\\n" )
2020-05-14 16:15:01 +02:00
ensureListContains ( t , flatDepsInfo , "myjar(minSdkVersion:(no version))" )
ensureListContains ( t , flatDepsInfo , "mylib2(minSdkVersion:(no version))" )
ensureListContains ( t , flatDepsInfo , "myotherjar(minSdkVersion:(no version))" )
ensureListContains ( t , flatDepsInfo , "mysharedjar(minSdkVersion:(no version)) (external)" )
2018-11-30 02:12:15 +01:00
}
2019-12-16 14:32:06 +01:00
func TestDefaults ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-12-16 14:32:06 +01:00
apex_defaults {
name : "myapex-defaults" ,
key : "myapex.key" ,
prebuilts : [ "myetc" ] ,
native_shared_libs : [ "mylib" ] ,
java_libs : [ "myjar" ] ,
apps : [ "AppFoo" ] ,
2020-04-24 14:16:36 +02:00
rros : [ "rro" ] ,
2020-09-02 10:23:38 +02:00
bpfs : [ "bpf" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-12-16 14:32:06 +01:00
}
prebuilt_etc {
name : "myetc" ,
src : "myprebuilt" ,
}
apex {
name : "myapex" ,
defaults : [ "myapex-defaults" ] ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
2019-12-16 14:32:06 +01:00
}
java_library {
name : "myjar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
sdk_version : "none" ,
system_modules : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
2019-12-16 14:32:06 +01:00
}
android_app {
name : "AppFoo" ,
srcs : [ "foo/bar/MyClass.java" ] ,
sdk_version : "none" ,
system_modules : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
2019-12-16 14:32:06 +01:00
}
2020-04-24 14:16:36 +02:00
runtime_resource_overlay {
name : "rro" ,
theme : "blue" ,
}
2020-09-02 10:23:38 +02:00
bpf {
name : "bpf" ,
srcs : [ "bpf.c" , "bpf2.c" ] ,
}
2019-12-16 14:32:06 +01:00
` )
2020-01-23 06:36:59 +01:00
ensureExactContents ( t , ctx , "myapex" , "android_common_myapex_image" , [ ] string {
2019-12-16 14:32:06 +01:00
"etc/myetc" ,
"javalib/myjar.jar" ,
"lib64/mylib.so" ,
"app/AppFoo/AppFoo.apk" ,
2020-04-24 14:16:36 +02:00
"overlay/blue/rro.apk" ,
2020-09-02 10:23:38 +02:00
"etc/bpf/bpf.o" ,
"etc/bpf/bpf2.o" ,
2019-12-16 14:32:06 +01:00
} )
}
2019-11-01 18:52:25 +01:00
func TestApexManifest ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-11-01 18:52:25 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-11-01 18:52:25 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
` )
module := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" )
2019-11-12 05:03:50 +01:00
args := module . Rule ( "apexRule" ) . Args
if manifest := args [ "manifest" ] ; manifest != module . Output ( "apex_manifest.pb" ) . Output . String ( ) {
t . Error ( "manifest should be apex_manifest.pb, but " + manifest )
}
2019-11-01 18:52:25 +01:00
}
2021-05-27 20:28:27 +02:00
func TestApexManifestMinSdkVersion ( t * testing . T ) {
ctx := testApex ( t , `
apex_defaults {
name : "my_defaults" ,
key : "myapex.key" ,
product_specific : true ,
file_contexts : ":my-file-contexts" ,
updatable : false ,
}
apex {
name : "myapex_30" ,
min_sdk_version : "30" ,
defaults : [ "my_defaults" ] ,
}
apex {
name : "myapex_current" ,
min_sdk_version : "current" ,
defaults : [ "my_defaults" ] ,
}
apex {
name : "myapex_none" ,
defaults : [ "my_defaults" ] ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
filegroup {
name : "my-file-contexts" ,
srcs : [ "product_specific_file_contexts" ] ,
}
` , withFiles ( map [ string ] [ ] byte {
"product_specific_file_contexts" : nil ,
} ) , android . FixtureModifyProductVariables (
func ( variables android . FixtureProductVariables ) {
variables . Unbundled_build = proptools . BoolPtr ( true )
variables . Always_use_prebuilt_sdks = proptools . BoolPtr ( false )
} ) , android . FixtureMergeEnv ( map [ string ] string {
"UNBUNDLED_BUILD_TARGET_SDK_WITH_API_FINGERPRINT" : "true" ,
} ) )
testCases := [ ] struct {
module string
minSdkVersion string
} {
{
module : "myapex_30" ,
minSdkVersion : "30" ,
} ,
{
module : "myapex_current" ,
minSdkVersion : "Q.$$(cat out/soong/api_fingerprint.txt)" ,
} ,
{
module : "myapex_none" ,
minSdkVersion : "Q.$$(cat out/soong/api_fingerprint.txt)" ,
} ,
}
for _ , tc := range testCases {
module := ctx . ModuleForTests ( tc . module , "android_common_" + tc . module + "_image" )
args := module . Rule ( "apexRule" ) . Args
optFlags := args [ "opt_flags" ]
if ! strings . Contains ( optFlags , "--min_sdk_version " + tc . minSdkVersion ) {
t . Errorf ( "%s: Expected min_sdk_version=%s, got: %s" , tc . module , tc . minSdkVersion , optFlags )
}
}
}
2018-11-30 02:12:15 +01:00
func TestBasicZipApex ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2018-11-30 02:12:15 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
payload_type : "zip" ,
native_shared_libs : [ "mylib" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2018-11-30 02:12:15 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
shared_libs : [ "mylib2" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
2018-11-30 02:12:15 +01:00
}
cc_library {
name : "mylib2" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
2018-11-30 02:12:15 +01:00
}
` )
2019-10-22 06:58:29 +02:00
zipApexRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_zip" ) . Rule ( "zipApexRule" )
2018-11-30 02:12:15 +01:00
copyCmds := zipApexRule . Args [ "copy_commands" ]
// Ensure that main rule creates an output
ensureContains ( t , zipApexRule . Output . String ( ) , "myapex.zipapex.unsigned" )
// Ensure that APEX variant is created for the direct dep
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
ensureListContains ( t , ctx . ModuleVariantsForTests ( "mylib" ) , "android_arm64_armv8-a_shared_apex10000" )
2018-11-30 02:12:15 +01:00
// Ensure that APEX variant is created for the indirect dep
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
ensureListContains ( t , ctx . ModuleVariantsForTests ( "mylib2" ) , "android_arm64_armv8-a_shared_apex10000" )
2018-11-30 02:12:15 +01:00
// Ensure that both direct and indirect deps are copied into apex
ensureContains ( t , copyCmds , "image.zipapex/lib64/mylib.so" )
ensureContains ( t , copyCmds , "image.zipapex/lib64/mylib2.so" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
}
func TestApexWithStubs ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" , "mylib3" ] ,
2021-06-11 10:22:09 +02:00
binaries : [ "foo.rust" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
shared_libs : [ "mylib2" , "mylib3" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
}
cc_library {
name : "mylib2" ,
srcs : [ "mylib.cpp" ] ,
2018-12-13 10:37:29 +01:00
cflags : [ "-include mylib.h" ] ,
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
system_shared_libs : [ ] ,
stl : "none" ,
stubs : {
versions : [ "1" , "2" , "3" ] ,
} ,
}
cc_library {
name : "mylib3" ,
2018-12-07 14:42:47 +01:00
srcs : [ "mylib.cpp" ] ,
shared_libs : [ "mylib4" ] ,
system_shared_libs : [ ] ,
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
stl : "none" ,
stubs : {
versions : [ "10" , "11" , "12" ] ,
} ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
}
2018-12-07 14:42:47 +01:00
cc_library {
name : "mylib4" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
2018-12-07 14:42:47 +01:00
}
2021-06-11 10:22:09 +02:00
rust_binary {
name : "foo.rust" ,
srcs : [ "foo.rs" ] ,
shared_libs : [ "libfoo.shared_from_rust" ] ,
prefer_rlib : true ,
apex_available : [ "myapex" ] ,
}
cc_library_shared {
name : "libfoo.shared_from_rust" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
stubs : {
versions : [ "10" , "11" , "12" ] ,
} ,
}
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
` )
2019-10-22 06:58:29 +02:00
apexRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "apexRule" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
copyCmds := apexRule . Args [ "copy_commands" ]
// Ensure that direct non-stubs dep is always included
2018-11-30 02:12:15 +01:00
ensureContains ( t , copyCmds , "image.apex/lib64/mylib.so" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// Ensure that indirect stubs dep is not included
2018-11-30 02:12:15 +01:00
ensureNotContains ( t , copyCmds , "image.apex/lib64/mylib2.so" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// Ensure that direct stubs dep is included
2018-11-30 02:12:15 +01:00
ensureContains ( t , copyCmds , "image.apex/lib64/mylib3.so" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
mylibLdFlags := ctx . ModuleForTests ( "mylib" , "android_arm64_armv8-a_shared_apex10000" ) . Rule ( "ld" ) . Args [ "libFlags" ]
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// Ensure that mylib is linking with the latest version of stubs for mylib2
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
ensureContains ( t , mylibLdFlags , "mylib2/android_arm64_armv8-a_shared_current/mylib2.so" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// ... and not linking to the non-stub (impl) variant of mylib2
2019-12-27 06:11:47 +01:00
ensureNotContains ( t , mylibLdFlags , "mylib2/android_arm64_armv8-a_shared/mylib2.so" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// Ensure that mylib is linking with the non-stub (impl) of mylib3 (because mylib3 is in the same apex)
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
ensureContains ( t , mylibLdFlags , "mylib3/android_arm64_armv8-a_shared_apex10000/mylib3.so" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// .. and not linking to the stubs variant of mylib3
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
ensureNotContains ( t , mylibLdFlags , "mylib3/android_arm64_armv8-a_shared_12/mylib3.so" )
2018-12-13 10:37:29 +01:00
2021-09-10 08:20:39 +02:00
// Comment out this test. Now it fails after the optimization of sharing "cflags" in cc/cc.go
// is replaced by sharing of "cFlags" in cc/builder.go.
// The "cflags" contains "-include mylib.h", but cFlags contained only a reference to the
// module variable representing "cflags". So it was not detected by ensureNotContains.
// Now "cFlags" is a reference to a module variable like $flags1, which includes all previous
// content of "cflags". ModuleForTests...Args["cFlags"] returns the full string of $flags1,
// including the original cflags's "-include mylib.h".
//
2018-12-13 10:37:29 +01:00
// Ensure that stubs libs are built without -include flags
2021-09-10 08:20:39 +02:00
// mylib2Cflags := ctx.ModuleForTests("mylib2", "android_arm64_armv8-a_static").Rule("cc").Args["cFlags"]
// ensureNotContains(t, mylib2Cflags, "-include ")
2018-12-07 08:25:39 +01:00
// Ensure that genstub is invoked with --apex
2020-10-23 23:53:06 +02:00
ensureContains ( t , "--apex" , ctx . ModuleForTests ( "mylib2" , "android_arm64_armv8-a_shared_3" ) . Rule ( "genStubSrc" ) . Args [ "flags" ] )
2019-12-17 04:47:13 +01:00
2020-01-23 06:36:59 +01:00
ensureExactContents ( t , ctx , "myapex" , "android_common_myapex_image" , [ ] string {
2019-12-17 04:47:13 +01:00
"lib64/mylib.so" ,
"lib64/mylib3.so" ,
"lib64/mylib4.so" ,
2021-06-11 10:22:09 +02:00
"bin/foo.rust" ,
"lib64/libc++.so" , // by the implicit dependency from foo.rust
"lib64/liblog.so" , // by the implicit dependency from foo.rust
2019-12-17 04:47:13 +01:00
} )
2021-06-11 10:22:09 +02:00
// Ensure that stub dependency from a rust module is not included
ensureNotContains ( t , copyCmds , "image.apex/lib64/libfoo.shared_from_rust.so" )
// The rust module is linked to the stub cc library
rustDeps := ctx . ModuleForTests ( "foo.rust" , "android_arm64_armv8-a_apex10000" ) . Rule ( "rustc" ) . Args [ "linkFlags" ]
ensureContains ( t , rustDeps , "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so" )
ensureNotContains ( t , rustDeps , "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
}
2021-06-22 13:23:05 +02:00
func TestApexCanUsePrivateApis ( t * testing . T ) {
ctx := testApex ( t , `
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
binaries : [ "foo.rust" ] ,
updatable : false ,
platform_apis : true ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
shared_libs : [ "mylib2" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" ] ,
}
cc_library {
name : "mylib2" ,
srcs : [ "mylib.cpp" ] ,
cflags : [ "-include mylib.h" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
stubs : {
versions : [ "1" , "2" , "3" ] ,
} ,
}
rust_binary {
name : "foo.rust" ,
srcs : [ "foo.rs" ] ,
shared_libs : [ "libfoo.shared_from_rust" ] ,
prefer_rlib : true ,
apex_available : [ "myapex" ] ,
}
cc_library_shared {
name : "libfoo.shared_from_rust" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
stubs : {
versions : [ "10" , "11" , "12" ] ,
} ,
}
` )
apexRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "apexRule" )
copyCmds := apexRule . Args [ "copy_commands" ]
// Ensure that indirect stubs dep is not included
ensureNotContains ( t , copyCmds , "image.apex/lib64/mylib2.so" )
ensureNotContains ( t , copyCmds , "image.apex/lib64/libfoo.shared_from_rust.so" )
// Ensure that we are using non-stub variants of mylib2 and libfoo.shared_from_rust (because
// of the platform_apis: true)
mylibLdFlags := ctx . ModuleForTests ( "mylib" , "android_arm64_armv8-a_shared_apex10000_private" ) . Rule ( "ld" ) . Args [ "libFlags" ]
ensureNotContains ( t , mylibLdFlags , "mylib2/android_arm64_armv8-a_shared_current/mylib2.so" )
ensureContains ( t , mylibLdFlags , "mylib2/android_arm64_armv8-a_shared/mylib2.so" )
rustDeps := ctx . ModuleForTests ( "foo.rust" , "android_arm64_armv8-a_apex10000_private" ) . Rule ( "rustc" ) . Args [ "linkFlags" ]
ensureNotContains ( t , rustDeps , "libfoo.shared_from_rust/android_arm64_armv8-a_shared_current/libfoo.shared_from_rust.so" )
ensureContains ( t , rustDeps , "libfoo.shared_from_rust/android_arm64_armv8-a_shared/libfoo.shared_from_rust.so" )
}
2020-09-25 21:35:10 +02:00
func TestApexWithStubsWithMinSdkVersion ( t * testing . T ) {
t . Parallel ( )
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-09-25 21:35:10 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" , "mylib3" ] ,
min_sdk_version : "29" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
shared_libs : [ "mylib2" , "mylib3" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" ] ,
min_sdk_version : "28" ,
}
cc_library {
name : "mylib2" ,
srcs : [ "mylib.cpp" ] ,
cflags : [ "-include mylib.h" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
stubs : {
versions : [ "28" , "29" , "30" , "current" ] ,
} ,
min_sdk_version : "28" ,
}
cc_library {
name : "mylib3" ,
srcs : [ "mylib.cpp" ] ,
shared_libs : [ "mylib4" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
stubs : {
versions : [ "28" , "29" , "30" , "current" ] ,
} ,
apex_available : [ "myapex" ] ,
min_sdk_version : "28" ,
}
cc_library {
name : "mylib4" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" ] ,
min_sdk_version : "28" ,
}
` )
apexRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "apexRule" )
copyCmds := apexRule . Args [ "copy_commands" ]
// Ensure that direct non-stubs dep is always included
ensureContains ( t , copyCmds , "image.apex/lib64/mylib.so" )
// Ensure that indirect stubs dep is not included
ensureNotContains ( t , copyCmds , "image.apex/lib64/mylib2.so" )
// Ensure that direct stubs dep is included
ensureContains ( t , copyCmds , "image.apex/lib64/mylib3.so" )
mylibLdFlags := ctx . ModuleForTests ( "mylib" , "android_arm64_armv8-a_shared_apex29" ) . Rule ( "ld" ) . Args [ "libFlags" ]
APEX uses the latest version of the stub
Previously when an APEX whose min_sdk_version is set is linked to an
external library providing multiple versions of stubs, the
maximum version that is less than or equal to the min_sdk_version was
chosen. For example, if the versions of a library stubs are 28, 29, 30,
and 31, then APEX with min_sdk_version: 29 linked to the version 29 of
the stub.
This was to ensure that the APEX doesn't use any new APIs whose
existence can't be guaranteed.
This however imposes a severe restriction that the APEX can never use
new APIs even when the APIs are actually available: i.e. when the
APEX is running on a newer platform.
With the recent work about unguarded availability, using the future APIs
became much safer. When you use an API that is newer than your
min_sdk_version, the API is automatically declared as a weak symbol
(thus no link error at runtime), while the call to API is guaranteed to
be guarded with the `__builtin_available(...)` macro.
So, there really is no reason to use the old version of the stub. We can
always use the latest version of stub safely.
Bug: N/A
Test: m
Change-Id: Iaac0d8761d8929154527dc2e861a51ae31e23d49
2021-02-26 15:57:23 +01:00
// Ensure that mylib is linking with the latest version of stub for mylib2
ensureContains ( t , mylibLdFlags , "mylib2/android_arm64_armv8-a_shared_current/mylib2.so" )
2020-09-25 21:35:10 +02:00
// ... and not linking to the non-stub (impl) variant of mylib2
ensureNotContains ( t , mylibLdFlags , "mylib2/android_arm64_armv8-a_shared/mylib2.so" )
// Ensure that mylib is linking with the non-stub (impl) of mylib3 (because mylib3 is in the same apex)
ensureContains ( t , mylibLdFlags , "mylib3/android_arm64_armv8-a_shared_apex29/mylib3.so" )
// .. and not linking to the stubs variant of mylib3
ensureNotContains ( t , mylibLdFlags , "mylib3/android_arm64_armv8-a_shared_29/mylib3.so" )
// Ensure that stubs libs are built without -include flags
2020-10-23 23:53:06 +02:00
mylib2Cflags := ctx . ModuleForTests ( "mylib2" , "android_arm64_armv8-a_shared_29" ) . Rule ( "cc" ) . Args [ "cFlags" ]
2020-09-25 21:35:10 +02:00
ensureNotContains ( t , mylib2Cflags , "-include " )
// Ensure that genstub is invoked with --apex
2020-10-23 23:53:06 +02:00
ensureContains ( t , "--apex" , ctx . ModuleForTests ( "mylib2" , "android_arm64_armv8-a_shared_29" ) . Rule ( "genStubSrc" ) . Args [ "flags" ] )
2020-09-25 21:35:10 +02:00
ensureExactContents ( t , ctx , "myapex" , "android_common_myapex_image" , [ ] string {
"lib64/mylib.so" ,
"lib64/mylib3.so" ,
"lib64/mylib4.so" ,
} )
}
2021-02-04 18:28:22 +01:00
func TestApex_PlatformUsesLatestStubFromApex ( t * testing . T ) {
t . Parallel ( )
// myapex (Z)
// mylib -----------------.
// |
// otherapex (29) |
// libstub's versions: 29 Z current
// |
// <platform> |
// libplatform ----------------'
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2021-02-04 18:28:22 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
min_sdk_version : "Z" , // non-final
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
shared_libs : [ "libstub" ] ,
apex_available : [ "myapex" ] ,
min_sdk_version : "Z" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
apex {
name : "otherapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libstub" ] ,
min_sdk_version : "29" ,
}
cc_library {
name : "libstub" ,
srcs : [ "mylib.cpp" ] ,
stubs : {
versions : [ "29" , "Z" , "current" ] ,
} ,
apex_available : [ "otherapex" ] ,
min_sdk_version : "29" ,
}
// platform module depending on libstub from otherapex should use the latest stub("current")
cc_library {
name : "libplatform" ,
srcs : [ "mylib.cpp" ] ,
shared_libs : [ "libstub" ] ,
}
2021-03-08 12:28:25 +01:00
` ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . Platform_sdk_codename = proptools . StringPtr ( "Z" )
variables . Platform_sdk_final = proptools . BoolPtr ( false )
variables . Platform_version_active_codenames = [ ] string { "Z" }
} ) ,
)
2021-02-04 18:28:22 +01:00
APEX uses the latest version of the stub
Previously when an APEX whose min_sdk_version is set is linked to an
external library providing multiple versions of stubs, the
maximum version that is less than or equal to the min_sdk_version was
chosen. For example, if the versions of a library stubs are 28, 29, 30,
and 31, then APEX with min_sdk_version: 29 linked to the version 29 of
the stub.
This was to ensure that the APEX doesn't use any new APIs whose
existence can't be guaranteed.
This however imposes a severe restriction that the APEX can never use
new APIs even when the APIs are actually available: i.e. when the
APEX is running on a newer platform.
With the recent work about unguarded availability, using the future APIs
became much safer. When you use an API that is newer than your
min_sdk_version, the API is automatically declared as a weak symbol
(thus no link error at runtime), while the call to API is guaranteed to
be guarded with the `__builtin_available(...)` macro.
So, there really is no reason to use the old version of the stub. We can
always use the latest version of stub safely.
Bug: N/A
Test: m
Change-Id: Iaac0d8761d8929154527dc2e861a51ae31e23d49
2021-02-26 15:57:23 +01:00
// Ensure that mylib from myapex is built against the latest stub (current)
2021-02-04 18:28:22 +01:00
mylibCflags := ctx . ModuleForTests ( "mylib" , "android_arm64_armv8-a_static_apex10000" ) . Rule ( "cc" ) . Args [ "cFlags" ]
APEX uses the latest version of the stub
Previously when an APEX whose min_sdk_version is set is linked to an
external library providing multiple versions of stubs, the
maximum version that is less than or equal to the min_sdk_version was
chosen. For example, if the versions of a library stubs are 28, 29, 30,
and 31, then APEX with min_sdk_version: 29 linked to the version 29 of
the stub.
This was to ensure that the APEX doesn't use any new APIs whose
existence can't be guaranteed.
This however imposes a severe restriction that the APEX can never use
new APIs even when the APIs are actually available: i.e. when the
APEX is running on a newer platform.
With the recent work about unguarded availability, using the future APIs
became much safer. When you use an API that is newer than your
min_sdk_version, the API is automatically declared as a weak symbol
(thus no link error at runtime), while the call to API is guaranteed to
be guarded with the `__builtin_available(...)` macro.
So, there really is no reason to use the old version of the stub. We can
always use the latest version of stub safely.
Bug: N/A
Test: m
Change-Id: Iaac0d8761d8929154527dc2e861a51ae31e23d49
2021-02-26 15:57:23 +01:00
ensureContains ( t , mylibCflags , "-D__LIBSTUB_API__=10000 " )
2021-02-04 18:28:22 +01:00
mylibLdflags := ctx . ModuleForTests ( "mylib" , "android_arm64_armv8-a_shared_apex10000" ) . Rule ( "ld" ) . Args [ "libFlags" ]
APEX uses the latest version of the stub
Previously when an APEX whose min_sdk_version is set is linked to an
external library providing multiple versions of stubs, the
maximum version that is less than or equal to the min_sdk_version was
chosen. For example, if the versions of a library stubs are 28, 29, 30,
and 31, then APEX with min_sdk_version: 29 linked to the version 29 of
the stub.
This was to ensure that the APEX doesn't use any new APIs whose
existence can't be guaranteed.
This however imposes a severe restriction that the APEX can never use
new APIs even when the APIs are actually available: i.e. when the
APEX is running on a newer platform.
With the recent work about unguarded availability, using the future APIs
became much safer. When you use an API that is newer than your
min_sdk_version, the API is automatically declared as a weak symbol
(thus no link error at runtime), while the call to API is guaranteed to
be guarded with the `__builtin_available(...)` macro.
So, there really is no reason to use the old version of the stub. We can
always use the latest version of stub safely.
Bug: N/A
Test: m
Change-Id: Iaac0d8761d8929154527dc2e861a51ae31e23d49
2021-02-26 15:57:23 +01:00
ensureContains ( t , mylibLdflags , "libstub/android_arm64_armv8-a_shared_current/libstub.so " )
2021-02-04 18:28:22 +01:00
// Ensure that libplatform is built against latest stub ("current") of mylib3 from the apex
libplatformCflags := ctx . ModuleForTests ( "libplatform" , "android_arm64_armv8-a_static" ) . Rule ( "cc" ) . Args [ "cFlags" ]
ensureContains ( t , libplatformCflags , "-D__LIBSTUB_API__=10000 " ) // "current" maps to 10000
libplatformLdflags := ctx . ModuleForTests ( "libplatform" , "android_arm64_armv8-a_shared" ) . Rule ( "ld" ) . Args [ "libFlags" ]
ensureContains ( t , libplatformLdflags , "libstub/android_arm64_armv8-a_shared_current/libstub.so " )
}
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
func TestApexWithExplicitStubsDependency ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
apex {
2020-01-14 10:38:44 +01:00
name : "myapex2" ,
key : "myapex2.key" ,
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
native_shared_libs : [ "mylib" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
}
apex_key {
2020-01-14 10:38:44 +01:00
name : "myapex2.key" ,
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
shared_libs : [ "libfoo#10" ] ,
2020-02-07 09:25:49 +01:00
static_libs : [ "libbaz" ] ,
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex2" ] ,
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
}
cc_library {
name : "libfoo" ,
srcs : [ "mylib.cpp" ] ,
shared_libs : [ "libbar" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
stubs : {
versions : [ "10" , "20" , "30" ] ,
} ,
}
cc_library {
name : "libbar" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
}
2020-02-07 09:25:49 +01:00
cc_library_static {
name : "libbaz" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex2" ] ,
}
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
` )
2020-01-14 10:38:44 +01:00
apexRule := ctx . ModuleForTests ( "myapex2" , "android_common_myapex2_image" ) . Rule ( "apexRule" )
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
copyCmds := apexRule . Args [ "copy_commands" ]
// Ensure that direct non-stubs dep is always included
ensureContains ( t , copyCmds , "image.apex/lib64/mylib.so" )
// Ensure that indirect stubs dep is not included
ensureNotContains ( t , copyCmds , "image.apex/lib64/libfoo.so" )
// Ensure that dependency of stubs is not included
ensureNotContains ( t , copyCmds , "image.apex/lib64/libbar.so" )
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
mylibLdFlags := ctx . ModuleForTests ( "mylib" , "android_arm64_armv8-a_shared_apex10000" ) . Rule ( "ld" ) . Args [ "libFlags" ]
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
// Ensure that mylib is linking with version 10 of libfoo
2019-12-27 06:11:47 +01:00
ensureContains ( t , mylibLdFlags , "libfoo/android_arm64_armv8-a_shared_10/libfoo.so" )
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
// ... and not linking to the non-stub (impl) variant of libfoo
2019-12-27 06:11:47 +01:00
ensureNotContains ( t , mylibLdFlags , "libfoo/android_arm64_armv8-a_shared/libfoo.so" )
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
2019-12-27 06:11:47 +01:00
libFooStubsLdFlags := ctx . ModuleForTests ( "libfoo" , "android_arm64_armv8-a_shared_10" ) . Rule ( "ld" ) . Args [ "libFlags" ]
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
// Ensure that libfoo stubs is not linking to libbar (since it is a stubs)
ensureNotContains ( t , libFooStubsLdFlags , "libbar.so" )
2020-01-14 10:38:44 +01:00
2020-04-27 19:07:06 +02:00
fullDepsInfo := strings . Split ( ctx . ModuleForTests ( "myapex2" , "android_common_myapex2_image" ) . Output ( "depsinfo/fulllist.txt" ) . Args [ "content" ] , "\\n" )
2020-05-14 16:15:01 +02:00
ensureListContains ( t , fullDepsInfo , " libfoo(minSdkVersion:(no version)) (external) <- mylib" )
2020-02-07 09:25:49 +01:00
2020-04-27 19:07:06 +02:00
flatDepsInfo := strings . Split ( ctx . ModuleForTests ( "myapex2" , "android_common_myapex2_image" ) . Output ( "depsinfo/flatlist.txt" ) . Args [ "content" ] , "\\n" )
2020-05-14 16:15:01 +02:00
ensureListContains ( t , flatDepsInfo , "libfoo(minSdkVersion:(no version)) (external)" )
Don't create unnecessary APEX variations
This change fixes a problem that APEX variations are created for the
modules that actually shouldn't built for any APEX. For example,
consider this case.
apex { name: "myapex", native_shared_libs: ["mylib"],}
cc_library { name: "mylib", shared_libs: ["libfoo#10"],}
cc_library { name: "libfoo",
shared_libs: ["libbar"],
stubs: { versions: ["10"], }, }
cc_library { name: "libbar", ...}
Before this change, both the stubs and non-stubs variations of libfoo
were mutated with apexMuator, which is incorrect for the non-stubs
varia; there is no dependency chain from the apex "myapex" to the
non-stubs variation, but to the stubs variation due to the #10 syntax.
This was happening becauses we used the name of the module to determine
whether it should be built for APEX or not. Both stubs and non-stubs
variations have the same module name "libfoo".
Fixing this issue by recording the list of APEX variations required
directly on the module. So, the stubs variation of libfoo has myapex in
its apex variations list, but the non-stubs variation doesn't, and thus
apexMutator does not pick up the non-stubs variation.
Test: m (apex_test updated and passing)
Test: cherry-pick ag/5747464 and m
Change-Id: I31e618626809a828a55fff513ef5f81f79637afa
2018-12-10 17:35:25 +01:00
}
2019-08-09 05:57:43 +02:00
func TestApexWithRuntimeLibsDependency ( t * testing . T ) {
/ *
myapex
|
v ( runtime_libs )
mylib -- -- -- + -- -- -- > libfoo [ provides stub ]
|
` -- -- -- > libbar
* /
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-08-09 05:57:43 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-08-09 05:57:43 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
runtime_libs : [ "libfoo" , "libbar" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
2019-08-09 05:57:43 +02:00
}
cc_library {
name : "libfoo" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
stubs : {
versions : [ "10" , "20" , "30" ] ,
} ,
}
cc_library {
name : "libbar" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
2019-08-09 05:57:43 +02:00
}
` )
2019-10-22 06:58:29 +02:00
apexRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "apexRule" )
2019-08-09 05:57:43 +02:00
copyCmds := apexRule . Args [ "copy_commands" ]
// Ensure that direct non-stubs dep is always included
ensureContains ( t , copyCmds , "image.apex/lib64/mylib.so" )
// Ensure that indirect stubs dep is not included
ensureNotContains ( t , copyCmds , "image.apex/lib64/libfoo.so" )
// Ensure that runtime_libs dep in included
ensureContains ( t , copyCmds , "image.apex/lib64/libbar.so" )
2019-10-22 06:58:29 +02:00
apexManifestRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "apexManifestRule" )
2019-09-26 17:38:03 +02:00
ensureListEmpty ( t , names ( apexManifestRule . Args [ "provideNativeLibs" ] ) )
ensureListContains ( t , names ( apexManifestRule . Args [ "requireNativeLibs" ] ) , "libfoo.so" )
2019-08-09 05:57:43 +02:00
}
2021-03-09 02:44:06 +01:00
var prepareForTestOfRuntimeApexWithHwasan = android . GroupFixturePreparers (
cc . PrepareForTestWithCcBuildComponents ,
PrepareForTestWithApexBuildComponents ,
android . FixtureAddTextFile ( "bionic/apex/Android.bp" , `
2020-05-15 12:05:05 +02:00
apex {
name : "com.android.runtime" ,
key : "com.android.runtime.key" ,
native_shared_libs : [ "libc" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-05-15 12:05:05 +02:00
}
apex_key {
name : "com.android.runtime.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
2021-03-09 02:44:06 +01:00
` ) ,
android . FixtureAddFile ( "system/sepolicy/apex/com.android.runtime-file_contexts" , nil ) ,
)
2020-05-15 12:05:05 +02:00
2021-03-09 02:44:06 +01:00
func TestRuntimeApexShouldInstallHwasanIfLibcDependsOnIt ( t * testing . T ) {
2021-03-21 12:26:05 +01:00
result := android . GroupFixturePreparers ( prepareForTestOfRuntimeApexWithHwasan ) . RunTestWithBp ( t , `
2020-05-15 12:05:05 +02:00
cc_library {
name : "libc" ,
no_libcrt : true ,
nocrt : true ,
stl : "none" ,
system_shared_libs : [ ] ,
stubs : { versions : [ "1" ] } ,
apex_available : [ "com.android.runtime" ] ,
sanitize : {
hwaddress : true ,
}
}
cc_prebuilt_library_shared {
name : "libclang_rt.hwasan-aarch64-android" ,
no_libcrt : true ,
nocrt : true ,
stl : "none" ,
system_shared_libs : [ ] ,
srcs : [ "" ] ,
stubs : { versions : [ "1" ] } ,
sanitize : {
never : true ,
} ,
2021-03-09 02:44:06 +01:00
} ` )
ctx := result . TestContext
2020-05-15 12:05:05 +02:00
ensureExactContents ( t , ctx , "com.android.runtime" , "android_common_hwasan_com.android.runtime_image" , [ ] string {
"lib64/bionic/libc.so" ,
"lib64/bionic/libclang_rt.hwasan-aarch64-android.so" ,
} )
hwasan := ctx . ModuleForTests ( "libclang_rt.hwasan-aarch64-android" , "android_arm64_armv8-a_shared" )
installed := hwasan . Description ( "install libclang_rt.hwasan" )
ensureContains ( t , installed . Output . String ( ) , "/system/lib64/bootstrap/libclang_rt.hwasan-aarch64-android.so" )
symlink := hwasan . Description ( "install symlink libclang_rt.hwasan" )
ensureEquals ( t , symlink . Args [ "fromPath" ] , "/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so" )
ensureContains ( t , symlink . Output . String ( ) , "/system/lib64/libclang_rt.hwasan-aarch64-android.so" )
}
func TestRuntimeApexShouldInstallHwasanIfHwaddressSanitized ( t * testing . T ) {
2021-03-21 12:26:05 +01:00
result := android . GroupFixturePreparers (
2021-03-09 02:44:06 +01:00
prepareForTestOfRuntimeApexWithHwasan ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . SanitizeDevice = [ ] string { "hwaddress" }
} ) ,
) . RunTestWithBp ( t , `
2020-05-15 12:05:05 +02:00
cc_library {
name : "libc" ,
no_libcrt : true ,
nocrt : true ,
stl : "none" ,
system_shared_libs : [ ] ,
stubs : { versions : [ "1" ] } ,
apex_available : [ "com.android.runtime" ] ,
}
cc_prebuilt_library_shared {
name : "libclang_rt.hwasan-aarch64-android" ,
no_libcrt : true ,
nocrt : true ,
stl : "none" ,
system_shared_libs : [ ] ,
srcs : [ "" ] ,
stubs : { versions : [ "1" ] } ,
sanitize : {
never : true ,
} ,
}
2021-03-09 02:44:06 +01:00
` )
ctx := result . TestContext
2020-05-15 12:05:05 +02:00
ensureExactContents ( t , ctx , "com.android.runtime" , "android_common_hwasan_com.android.runtime_image" , [ ] string {
"lib64/bionic/libc.so" ,
"lib64/bionic/libclang_rt.hwasan-aarch64-android.so" ,
} )
hwasan := ctx . ModuleForTests ( "libclang_rt.hwasan-aarch64-android" , "android_arm64_armv8-a_shared" )
installed := hwasan . Description ( "install libclang_rt.hwasan" )
ensureContains ( t , installed . Output . String ( ) , "/system/lib64/bootstrap/libclang_rt.hwasan-aarch64-android.so" )
symlink := hwasan . Description ( "install symlink libclang_rt.hwasan" )
ensureEquals ( t , symlink . Args [ "fromPath" ] , "/apex/com.android.runtime/lib64/bionic/libclang_rt.hwasan-aarch64-android.so" )
ensureContains ( t , symlink . Output . String ( ) , "/system/lib64/libclang_rt.hwasan-aarch64-android.so" )
}
2019-08-09 05:57:43 +02:00
2020-03-21 15:21:46 +01:00
func TestApexDependsOnLLNDKTransitively ( t * testing . T ) {
testcases := [ ] struct {
name string
minSdkVersion string
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
apexVariant string
2020-03-21 15:21:46 +01:00
shouldLink string
shouldNotLink [ ] string
} {
{
APEX uses the latest version of the stub
Previously when an APEX whose min_sdk_version is set is linked to an
external library providing multiple versions of stubs, the
maximum version that is less than or equal to the min_sdk_version was
chosen. For example, if the versions of a library stubs are 28, 29, 30,
and 31, then APEX with min_sdk_version: 29 linked to the version 29 of
the stub.
This was to ensure that the APEX doesn't use any new APIs whose
existence can't be guaranteed.
This however imposes a severe restriction that the APEX can never use
new APIs even when the APIs are actually available: i.e. when the
APEX is running on a newer platform.
With the recent work about unguarded availability, using the future APIs
became much safer. When you use an API that is newer than your
min_sdk_version, the API is automatically declared as a weak symbol
(thus no link error at runtime), while the call to API is guaranteed to
be guarded with the `__builtin_available(...)` macro.
So, there really is no reason to use the old version of the stub. We can
always use the latest version of stub safely.
Bug: N/A
Test: m
Change-Id: Iaac0d8761d8929154527dc2e861a51ae31e23d49
2021-02-26 15:57:23 +01:00
name : "unspecified version links to the latest" ,
2020-04-15 04:03:39 +02:00
minSdkVersion : "" ,
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
apexVariant : "apex10000" ,
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
shouldLink : "current" ,
shouldNotLink : [ ] string { "29" , "30" } ,
2020-03-21 15:21:46 +01:00
} ,
{
APEX uses the latest version of the stub
Previously when an APEX whose min_sdk_version is set is linked to an
external library providing multiple versions of stubs, the
maximum version that is less than or equal to the min_sdk_version was
chosen. For example, if the versions of a library stubs are 28, 29, 30,
and 31, then APEX with min_sdk_version: 29 linked to the version 29 of
the stub.
This was to ensure that the APEX doesn't use any new APIs whose
existence can't be guaranteed.
This however imposes a severe restriction that the APEX can never use
new APIs even when the APIs are actually available: i.e. when the
APEX is running on a newer platform.
With the recent work about unguarded availability, using the future APIs
became much safer. When you use an API that is newer than your
min_sdk_version, the API is automatically declared as a weak symbol
(thus no link error at runtime), while the call to API is guaranteed to
be guarded with the `__builtin_available(...)` macro.
So, there really is no reason to use the old version of the stub. We can
always use the latest version of stub safely.
Bug: N/A
Test: m
Change-Id: Iaac0d8761d8929154527dc2e861a51ae31e23d49
2021-02-26 15:57:23 +01:00
name : "always use the latest" ,
2020-04-15 04:03:39 +02:00
minSdkVersion : "min_sdk_version: \"29\"," ,
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
apexVariant : "apex29" ,
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
shouldLink : "current" ,
shouldNotLink : [ ] string { "29" , "30" } ,
2020-03-21 15:21:46 +01:00
} ,
}
for _ , tc := range testcases {
t . Run ( tc . name , func ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-03-21 15:21:46 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-04-15 04:03:39 +02:00
` +tc.minSdkVersion+ `
2020-03-21 15:21:46 +01:00
}
2020-03-21 14:58:19 +01:00
2020-03-21 15:21:46 +01:00
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
2020-03-21 14:58:19 +01:00
2020-03-21 15:21:46 +01:00
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
vendor_available : true ,
shared_libs : [ "libbar" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" ] ,
2020-04-15 04:03:39 +02:00
min_sdk_version : "29" ,
2020-03-21 15:21:46 +01:00
}
2020-03-21 14:58:19 +01:00
2020-03-21 15:21:46 +01:00
cc_library {
name : "libbar" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
stubs : { versions : [ "29" , "30" ] } ,
2021-04-27 02:19:41 +02:00
llndk : {
symbol_file : "libbar.map.txt" ,
}
2020-03-21 15:21:46 +01:00
}
2021-03-08 12:28:25 +01:00
` ,
withUnbundledBuild ,
)
2020-03-21 15:21:46 +01:00
// Ensure that LLNDK dep is not included
ensureExactContents ( t , ctx , "myapex" , "android_common_myapex_image" , [ ] string {
"lib64/mylib.so" ,
} )
// Ensure that LLNDK dep is required
apexManifestRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "apexManifestRule" )
ensureListEmpty ( t , names ( apexManifestRule . Args [ "provideNativeLibs" ] ) )
ensureListContains ( t , names ( apexManifestRule . Args [ "requireNativeLibs" ] ) , "libbar.so" )
2021-04-27 04:08:49 +02:00
mylibLdFlags := ctx . ModuleForTests ( "mylib" , "android_arm64_armv8-a_shared_" + tc . apexVariant ) . Rule ( "ld" ) . Args [ "libFlags" ]
ensureContains ( t , mylibLdFlags , "libbar/android_arm64_armv8-a_shared_" + tc . shouldLink + "/libbar.so" )
2020-03-21 15:21:46 +01:00
for _ , ver := range tc . shouldNotLink {
2021-04-27 04:08:49 +02:00
ensureNotContains ( t , mylibLdFlags , "libbar/android_arm64_armv8-a_shared_" + ver + "/libbar.so" )
2020-03-21 15:21:46 +01:00
}
2019-08-20 10:30:57 +02:00
2021-04-27 04:08:49 +02:00
mylibCFlags := ctx . ModuleForTests ( "mylib" , "android_arm64_armv8-a_static_" + tc . apexVariant ) . Rule ( "cc" ) . Args [ "cFlags" ]
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
ver := tc . shouldLink
if tc . shouldLink == "current" {
ver = strconv . Itoa ( android . FutureApiLevelInt )
}
ensureContains ( t , mylibCFlags , "__LIBBAR_API__=" + ver )
2020-03-21 15:21:46 +01:00
} )
}
2019-08-20 10:30:57 +02:00
}
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
func TestApexWithSystemLibsStubs ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" , "mylib_shared" , "libdl" , "libm" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
2020-09-18 23:15:30 +02:00
system_shared_libs : [ "libc" , "libm" ] ,
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
shared_libs : [ "libdl#27" ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
}
cc_library_shared {
name : "mylib_shared" ,
srcs : [ "mylib.cpp" ] ,
shared_libs : [ "libdl#27" ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
}
2018-12-20 14:10:17 +01:00
cc_library {
name : "libBootstrap" ,
srcs : [ "mylib.cpp" ] ,
stl : "none" ,
bootstrap : true ,
}
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
` )
2019-10-22 06:58:29 +02:00
apexRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "apexRule" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
copyCmds := apexRule . Args [ "copy_commands" ]
// Ensure that mylib, libm, libdl are included.
2018-11-30 02:12:15 +01:00
ensureContains ( t , copyCmds , "image.apex/lib64/mylib.so" )
2018-12-20 14:10:17 +01:00
ensureContains ( t , copyCmds , "image.apex/lib64/bionic/libm.so" )
ensureContains ( t , copyCmds , "image.apex/lib64/bionic/libdl.so" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// Ensure that libc is not included (since it has stubs and not listed in native_shared_libs)
2018-12-20 14:10:17 +01:00
ensureNotContains ( t , copyCmds , "image.apex/lib64/bionic/libc.so" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
mylibLdFlags := ctx . ModuleForTests ( "mylib" , "android_arm64_armv8-a_shared_apex10000" ) . Rule ( "ld" ) . Args [ "libFlags" ]
mylibCFlags := ctx . ModuleForTests ( "mylib" , "android_arm64_armv8-a_static_apex10000" ) . Rule ( "cc" ) . Args [ "cFlags" ]
mylibSharedCFlags := ctx . ModuleForTests ( "mylib_shared" , "android_arm64_armv8-a_shared_apex10000" ) . Rule ( "cc" ) . Args [ "cFlags" ]
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// For dependency to libc
// Ensure that mylib is linking with the latest version of stubs
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
ensureContains ( t , mylibLdFlags , "libc/android_arm64_armv8-a_shared_current/libc.so" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// ... and not linking to the non-stub (impl) variant
2019-12-27 06:11:47 +01:00
ensureNotContains ( t , mylibLdFlags , "libc/android_arm64_armv8-a_shared/libc.so" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// ... Cflags from stub is correctly exported to mylib
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
ensureContains ( t , mylibCFlags , "__LIBC_API__=10000" )
ensureContains ( t , mylibSharedCFlags , "__LIBC_API__=10000" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// For dependency to libm
// Ensure that mylib is linking with the non-stub (impl) variant
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
ensureContains ( t , mylibLdFlags , "libm/android_arm64_armv8-a_shared_apex10000/libm.so" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// ... and not linking to the stub variant
2019-12-27 06:11:47 +01:00
ensureNotContains ( t , mylibLdFlags , "libm/android_arm64_armv8-a_shared_29/libm.so" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// ... and is not compiling with the stub
ensureNotContains ( t , mylibCFlags , "__LIBM_API__=29" )
ensureNotContains ( t , mylibSharedCFlags , "__LIBM_API__=29" )
// For dependency to libdl
// Ensure that mylib is linking with the specified version of stubs
2019-12-27 06:11:47 +01:00
ensureContains ( t , mylibLdFlags , "libdl/android_arm64_armv8-a_shared_27/libdl.so" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// ... and not linking to the other versions of stubs
2019-12-27 06:11:47 +01:00
ensureNotContains ( t , mylibLdFlags , "libdl/android_arm64_armv8-a_shared_28/libdl.so" )
ensureNotContains ( t , mylibLdFlags , "libdl/android_arm64_armv8-a_shared_29/libdl.so" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// ... and not linking to the non-stub (impl) variant
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
ensureNotContains ( t , mylibLdFlags , "libdl/android_arm64_armv8-a_shared_apex10000/libdl.so" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
// ... Cflags from stub is correctly exported to mylib
ensureContains ( t , mylibCFlags , "__LIBDL_API__=27" )
ensureContains ( t , mylibSharedCFlags , "__LIBDL_API__=27" )
2018-12-20 14:10:17 +01:00
// Ensure that libBootstrap is depending on the platform variant of bionic libs
2019-11-21 01:39:12 +01:00
libFlags := ctx . ModuleForTests ( "libBootstrap" , "android_arm64_armv8-a_shared" ) . Rule ( "ld" ) . Args [ "libFlags" ]
ensureContains ( t , libFlags , "libc/android_arm64_armv8-a_shared/libc.so" )
ensureContains ( t , libFlags , "libm/android_arm64_armv8-a_shared/libm.so" )
ensureContains ( t , libFlags , "libdl/android_arm64_armv8-a_shared/libdl.so" )
Stubs variant is used when building for APEX
When a native module is built for an APEX and is depending on a native
library having stubs (i.e. stubs.versions property is set), the stubs
variant is used unless the dependent lib is directly included in the
same APEX with the depending module.
Example:
apex {
name: "myapex",
native_shared_libs: ["libX", "libY"],
}
cc_library {
name: "libX",
shared_libs: ["libY", "libZ"],
}
cc_library {
name: "libY",
stubs: { versions: ["1", "2"], },
}
cc_library {
name: "libZ",
stubs: { versions: ["1", "2"], },
}
In this case, libX is linking to the impl variant of libY (that provides
private APIs) while libY is linking to the version 2 stubs of libZ. This is
because libY is directly included in the same apex via
native_shared_libs property, but libZ isn't.
Bug: 112672359
Test: apex_test added
Change-Id: If9871b70dc74a06bd828dd4cd1aeebd2e68b837c
2018-11-18 10:02:45 +01:00
}
2018-12-06 16:42:25 +01:00
2020-04-15 04:03:39 +02:00
func TestApexMinSdkVersion_NativeModulesShouldBeBuiltAgainstStubs ( t * testing . T ) {
APEX uses the latest version of the stub
Previously when an APEX whose min_sdk_version is set is linked to an
external library providing multiple versions of stubs, the
maximum version that is less than or equal to the min_sdk_version was
chosen. For example, if the versions of a library stubs are 28, 29, 30,
and 31, then APEX with min_sdk_version: 29 linked to the version 29 of
the stub.
This was to ensure that the APEX doesn't use any new APIs whose
existence can't be guaranteed.
This however imposes a severe restriction that the APEX can never use
new APIs even when the APIs are actually available: i.e. when the
APEX is running on a newer platform.
With the recent work about unguarded availability, using the future APIs
became much safer. When you use an API that is newer than your
min_sdk_version, the API is automatically declared as a weak symbol
(thus no link error at runtime), while the call to API is guaranteed to
be guarded with the `__builtin_available(...)` macro.
So, there really is no reason to use the old version of the stub. We can
always use the latest version of stub safely.
Bug: N/A
Test: m
Change-Id: Iaac0d8761d8929154527dc2e861a51ae31e23d49
2021-02-26 15:57:23 +01:00
// there are three links between liba --> libz.
// 1) myapex -> libx -> liba -> libz : this should be #30 link
2020-04-15 04:03:39 +02:00
// 2) otherapex -> liby -> liba -> libz : this should be #30 link
2020-02-26 14:45:42 +01:00
// 3) (platform) -> liba -> libz : this should be non-stub link
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-02-26 14:45:42 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libx" ] ,
2020-04-15 04:03:39 +02:00
min_sdk_version : "29" ,
2020-02-26 14:45:42 +01:00
}
apex {
name : "otherapex" ,
key : "myapex.key" ,
native_shared_libs : [ "liby" ] ,
2020-04-15 04:03:39 +02:00
min_sdk_version : "30" ,
2020-02-26 14:45:42 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libx" ,
shared_libs : [ "liba" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" ] ,
2020-04-15 04:03:39 +02:00
min_sdk_version : "29" ,
2020-02-26 14:45:42 +01:00
}
cc_library {
name : "liby" ,
shared_libs : [ "liba" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "otherapex" ] ,
2020-04-15 04:03:39 +02:00
min_sdk_version : "29" ,
2020-02-26 14:45:42 +01:00
}
cc_library {
name : "liba" ,
shared_libs : [ "libz" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [
"//apex_available:anyapex" ,
"//apex_available:platform" ,
] ,
2020-04-15 04:03:39 +02:00
min_sdk_version : "29" ,
2020-02-26 14:45:42 +01:00
}
cc_library {
name : "libz" ,
system_shared_libs : [ ] ,
stl : "none" ,
stubs : {
2020-04-15 04:03:39 +02:00
versions : [ "28" , "30" ] ,
2020-02-26 14:45:42 +01:00
} ,
}
2020-04-15 04:03:39 +02:00
` )
2020-02-26 14:45:42 +01:00
expectLink := func ( from , from_variant , to , to_variant string ) {
ldArgs := ctx . ModuleForTests ( from , "android_arm64_armv8-a_" + from_variant ) . Rule ( "ld" ) . Args [ "libFlags" ]
ensureContains ( t , ldArgs , "android_arm64_armv8-a_" + to_variant + "/" + to + ".so" )
}
expectNoLink := func ( from , from_variant , to , to_variant string ) {
ldArgs := ctx . ModuleForTests ( from , "android_arm64_armv8-a_" + from_variant ) . Rule ( "ld" ) . Args [ "libFlags" ]
ensureNotContains ( t , ldArgs , "android_arm64_armv8-a_" + to_variant + "/" + to + ".so" )
}
// platform liba is linked to non-stub version
expectLink ( "liba" , "shared" , "libz" , "shared" )
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
// liba in myapex is linked to current
expectLink ( "liba" , "shared_apex29" , "libz" , "shared_current" )
expectNoLink ( "liba" , "shared_apex29" , "libz" , "shared_30" )
APEX uses the latest version of the stub
Previously when an APEX whose min_sdk_version is set is linked to an
external library providing multiple versions of stubs, the
maximum version that is less than or equal to the min_sdk_version was
chosen. For example, if the versions of a library stubs are 28, 29, 30,
and 31, then APEX with min_sdk_version: 29 linked to the version 29 of
the stub.
This was to ensure that the APEX doesn't use any new APIs whose
existence can't be guaranteed.
This however imposes a severe restriction that the APEX can never use
new APIs even when the APIs are actually available: i.e. when the
APEX is running on a newer platform.
With the recent work about unguarded availability, using the future APIs
became much safer. When you use an API that is newer than your
min_sdk_version, the API is automatically declared as a weak symbol
(thus no link error at runtime), while the call to API is guaranteed to
be guarded with the `__builtin_available(...)` macro.
So, there really is no reason to use the old version of the stub. We can
always use the latest version of stub safely.
Bug: N/A
Test: m
Change-Id: Iaac0d8761d8929154527dc2e861a51ae31e23d49
2021-02-26 15:57:23 +01:00
expectNoLink ( "liba" , "shared_apex29" , "libz" , "shared_28" )
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
expectNoLink ( "liba" , "shared_apex29" , "libz" , "shared" )
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
// liba in otherapex is linked to current
expectLink ( "liba" , "shared_apex30" , "libz" , "shared_current" )
expectNoLink ( "liba" , "shared_apex30" , "libz" , "shared_30" )
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
expectNoLink ( "liba" , "shared_apex30" , "libz" , "shared_28" )
expectNoLink ( "liba" , "shared_apex30" , "libz" , "shared" )
2020-02-26 14:45:42 +01:00
}
2020-04-01 18:41:41 +02:00
func TestApexMinSdkVersion_SupportsCodeNames ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-04-01 18:41:41 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libx" ] ,
min_sdk_version : "R" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libx" ,
shared_libs : [ "libz" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" ] ,
2020-04-15 04:03:39 +02:00
min_sdk_version : "R" ,
2020-04-01 18:41:41 +02:00
}
cc_library {
name : "libz" ,
system_shared_libs : [ ] ,
stl : "none" ,
stubs : {
versions : [ "29" , "R" ] ,
} ,
}
2021-03-08 12:28:25 +01:00
` ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . Platform_version_active_codenames = [ ] string { "R" }
} ) ,
)
2020-04-01 18:41:41 +02:00
expectLink := func ( from , from_variant , to , to_variant string ) {
ldArgs := ctx . ModuleForTests ( from , "android_arm64_armv8-a_" + from_variant ) . Rule ( "ld" ) . Args [ "libFlags" ]
ensureContains ( t , ldArgs , "android_arm64_armv8-a_" + to_variant + "/" + to + ".so" )
}
expectNoLink := func ( from , from_variant , to , to_variant string ) {
ldArgs := ctx . ModuleForTests ( from , "android_arm64_armv8-a_" + from_variant ) . Rule ( "ld" ) . Args [ "libFlags" ]
ensureNotContains ( t , ldArgs , "android_arm64_armv8-a_" + to_variant + "/" + to + ".so" )
}
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
expectLink ( "libx" , "shared_apex10000" , "libz" , "shared_current" )
expectNoLink ( "libx" , "shared_apex10000" , "libz" , "shared_R" )
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
expectNoLink ( "libx" , "shared_apex10000" , "libz" , "shared_29" )
expectNoLink ( "libx" , "shared_apex10000" , "libz" , "shared" )
2020-04-01 18:41:41 +02:00
}
2021-06-23 03:23:16 +02:00
func TestApexMinSdkVersion_SupportsCodeNames_JavaLibs ( t * testing . T ) {
testApex ( t , `
apex {
name : "myapex" ,
key : "myapex.key" ,
java_libs : [ "libx" ] ,
min_sdk_version : "S" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
java_library {
name : "libx" ,
srcs : [ "a.java" ] ,
apex_available : [ "myapex" ] ,
sdk_version : "current" ,
min_sdk_version : "S" , // should be okay
}
` ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . Platform_version_active_codenames = [ ] string { "S" }
variables . Platform_sdk_codename = proptools . StringPtr ( "S" )
} ) ,
)
}
2020-04-15 04:03:39 +02:00
func TestApexMinSdkVersion_DefaultsToLatest ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-02-26 14:45:42 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libx" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-02-26 14:45:42 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libx" ,
shared_libs : [ "libz" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" ] ,
}
cc_library {
name : "libz" ,
system_shared_libs : [ ] ,
stl : "none" ,
stubs : {
versions : [ "1" , "2" ] ,
} ,
}
` )
expectLink := func ( from , from_variant , to , to_variant string ) {
ldArgs := ctx . ModuleForTests ( from , "android_arm64_armv8-a_" + from_variant ) . Rule ( "ld" ) . Args [ "libFlags" ]
ensureContains ( t , ldArgs , "android_arm64_armv8-a_" + to_variant + "/" + to + ".so" )
}
expectNoLink := func ( from , from_variant , to , to_variant string ) {
ldArgs := ctx . ModuleForTests ( from , "android_arm64_armv8-a_" + from_variant ) . Rule ( "ld" ) . Args [ "libFlags" ]
ensureNotContains ( t , ldArgs , "android_arm64_armv8-a_" + to_variant + "/" + to + ".so" )
}
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
expectLink ( "libx" , "shared_apex10000" , "libz" , "shared_current" )
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
expectNoLink ( "libx" , "shared_apex10000" , "libz" , "shared_1" )
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
expectNoLink ( "libx" , "shared_apex10000" , "libz" , "shared_2" )
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
expectNoLink ( "libx" , "shared_apex10000" , "libz" , "shared" )
2020-02-26 14:45:42 +01:00
}
2021-08-25 09:18:46 +02:00
func TestApexMinSdkVersion_crtobjectInVendorApex ( t * testing . T ) {
ctx := testApex ( t , `
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
updatable : false ,
vendor : true ,
min_sdk_version : "29" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
vendor_available : true ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" ] ,
min_sdk_version : "29" ,
}
` )
vendorVariant := "android_vendor.29_arm64_armv8-a"
// First check that the correct variant of crtbegin_so is used.
ldRule := ctx . ModuleForTests ( "mylib" , vendorVariant + "_shared_apex29" ) . Rule ( "ld" )
crtBegin := names ( ldRule . Args [ "crtBegin" ] )
ensureListContains ( t , crtBegin , "out/soong/.intermediates/" + cc . DefaultCcCommonTestModulesDir + "crtbegin_so/" + vendorVariant + "_apex29/crtbegin_so.o" )
// Ensure that the crtbegin_so used by the APEX is targeting 29
cflags := ctx . ModuleForTests ( "crtbegin_so" , vendorVariant + "_apex29" ) . Rule ( "cc" ) . Args [ "cFlags" ]
android . AssertStringDoesContain ( t , "cflags" , cflags , "-target aarch64-linux-android29" )
}
2020-02-26 14:45:42 +01:00
func TestPlatformUsesLatestStubsFromApexes ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-02-26 14:45:42 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libx" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-02-26 14:45:42 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libx" ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" ] ,
stubs : {
versions : [ "1" , "2" ] ,
} ,
}
cc_library {
name : "libz" ,
shared_libs : [ "libx" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
}
` )
expectLink := func ( from , from_variant , to , to_variant string ) {
2020-09-16 03:30:11 +02:00
t . Helper ( )
2020-02-26 14:45:42 +01:00
ldArgs := ctx . ModuleForTests ( from , "android_arm64_armv8-a_" + from_variant ) . Rule ( "ld" ) . Args [ "libFlags" ]
ensureContains ( t , ldArgs , "android_arm64_armv8-a_" + to_variant + "/" + to + ".so" )
}
expectNoLink := func ( from , from_variant , to , to_variant string ) {
2020-09-16 03:30:11 +02:00
t . Helper ( )
2020-02-26 14:45:42 +01:00
ldArgs := ctx . ModuleForTests ( from , "android_arm64_armv8-a_" + from_variant ) . Rule ( "ld" ) . Args [ "libFlags" ]
ensureNotContains ( t , ldArgs , "android_arm64_armv8-a_" + to_variant + "/" + to + ".so" )
}
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
expectLink ( "libz" , "shared" , "libx" , "shared_current" )
expectNoLink ( "libz" , "shared" , "libx" , "shared_2" )
2020-02-26 14:45:42 +01:00
expectNoLink ( "libz" , "shared" , "libz" , "shared_1" )
expectNoLink ( "libz" , "shared" , "libz" , "shared" )
}
2021-03-08 12:28:25 +01:00
var prepareForTestWithSantitizeHwaddress = android . FixtureModifyProductVariables (
func ( variables android . FixtureProductVariables ) {
variables . SanitizeDevice = [ ] string { "hwaddress" }
} ,
)
Enforce apex.min_sdk_version for bundled builds
Previously, when Q-targeting apexes are bundled-built, they are built
against the latest stubs.
It was because unwinder is linked dynamically in R and APIs are provided
by libc while Q apexes should run on Q where libc doesn't provide those
APIs. To make Q apexes run on Q device, libc++ should be linked with
static unwinder. But, because libc++ with static unwinder may cause problem
on HWASAN build, Q apexes were built against the latest stubs for bundled
build.
However, Q apexes should be built against Q stubs.
Now, only for HWASAN builds, Q apexes are built against the latest stubs
(and native modules are not linked with static unwinder).
Bug: 151912436
Test: TARGET_SANITIZE=hwaddress m
=> Q apexes(media, resolv, ..) are linked with the latest stubs
m
=> Q apexes are linked with Q stubs,
and Q apexes' libc++ is linked with static unwinder
Merged-In: If32f1b547e6d93e3955c7521eec8aef5851f908c
Change-Id: If32f1b547e6d93e3955c7521eec8aef5851f908c
(cherry picked from commit 7406660685a9a085c433ba7081cc6984f66fa732)
Exempt-From-Owner-Approval: cp from internal
Change-Id: If32f1b547e6d93e3955c7521eec8aef5851f908c
2020-03-19 20:29:24 +01:00
func TestQApexesUseLatestStubsInBundledBuildsAndHWASAN ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-02-26 14:45:42 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libx" ] ,
min_sdk_version : "29" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libx" ,
shared_libs : [ "libbar" ] ,
apex_available : [ "myapex" ] ,
2020-04-15 04:03:39 +02:00
min_sdk_version : "29" ,
2020-02-26 14:45:42 +01:00
}
cc_library {
name : "libbar" ,
stubs : {
versions : [ "29" , "30" ] ,
} ,
}
2021-03-08 12:28:25 +01:00
` ,
prepareForTestWithSantitizeHwaddress ,
)
2020-02-26 14:45:42 +01:00
expectLink := func ( from , from_variant , to , to_variant string ) {
ld := ctx . ModuleForTests ( from , "android_arm64_armv8-a_" + from_variant ) . Rule ( "ld" )
libFlags := ld . Args [ "libFlags" ]
ensureContains ( t , libFlags , "android_arm64_armv8-a_" + to_variant + "/" + to + ".so" )
}
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
expectLink ( "libx" , "shared_hwasan_apex29" , "libbar" , "shared_current" )
2020-02-26 14:45:42 +01:00
}
Enforce apex.min_sdk_version for bundled builds
Previously, when Q-targeting apexes are bundled-built, they are built
against the latest stubs.
It was because unwinder is linked dynamically in R and APIs are provided
by libc while Q apexes should run on Q where libc doesn't provide those
APIs. To make Q apexes run on Q device, libc++ should be linked with
static unwinder. But, because libc++ with static unwinder may cause problem
on HWASAN build, Q apexes were built against the latest stubs for bundled
build.
However, Q apexes should be built against Q stubs.
Now, only for HWASAN builds, Q apexes are built against the latest stubs
(and native modules are not linked with static unwinder).
Bug: 151912436
Test: TARGET_SANITIZE=hwaddress m
=> Q apexes(media, resolv, ..) are linked with the latest stubs
m
=> Q apexes are linked with Q stubs,
and Q apexes' libc++ is linked with static unwinder
Merged-In: If32f1b547e6d93e3955c7521eec8aef5851f908c
Change-Id: If32f1b547e6d93e3955c7521eec8aef5851f908c
(cherry picked from commit 7406660685a9a085c433ba7081cc6984f66fa732)
Exempt-From-Owner-Approval: cp from internal
Change-Id: If32f1b547e6d93e3955c7521eec8aef5851f908c
2020-03-19 20:29:24 +01:00
func TestQTargetApexUsesStaticUnwinder ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-02-26 14:45:42 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libx" ] ,
min_sdk_version : "29" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libx" ,
apex_available : [ "myapex" ] ,
2020-04-15 04:03:39 +02:00
min_sdk_version : "29" ,
2020-02-26 14:45:42 +01:00
}
Enforce apex.min_sdk_version for bundled builds
Previously, when Q-targeting apexes are bundled-built, they are built
against the latest stubs.
It was because unwinder is linked dynamically in R and APIs are provided
by libc while Q apexes should run on Q where libc doesn't provide those
APIs. To make Q apexes run on Q device, libc++ should be linked with
static unwinder. But, because libc++ with static unwinder may cause problem
on HWASAN build, Q apexes were built against the latest stubs for bundled
build.
However, Q apexes should be built against Q stubs.
Now, only for HWASAN builds, Q apexes are built against the latest stubs
(and native modules are not linked with static unwinder).
Bug: 151912436
Test: TARGET_SANITIZE=hwaddress m
=> Q apexes(media, resolv, ..) are linked with the latest stubs
m
=> Q apexes are linked with Q stubs,
and Q apexes' libc++ is linked with static unwinder
Merged-In: If32f1b547e6d93e3955c7521eec8aef5851f908c
Change-Id: If32f1b547e6d93e3955c7521eec8aef5851f908c
(cherry picked from commit 7406660685a9a085c433ba7081cc6984f66fa732)
Exempt-From-Owner-Approval: cp from internal
Change-Id: If32f1b547e6d93e3955c7521eec8aef5851f908c
2020-03-19 20:29:24 +01:00
` )
2020-02-26 14:45:42 +01:00
// ensure apex variant of c++ is linked with static unwinder
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
cm := ctx . ModuleForTests ( "libc++" , "android_arm64_armv8-a_shared_apex29" ) . Module ( ) . ( * cc . Module )
2021-01-14 04:18:53 +01:00
ensureListContains ( t , cm . Properties . AndroidMkStaticLibs , "libunwind" )
2020-02-26 14:45:42 +01:00
// note that platform variant is not.
cm = ctx . ModuleForTests ( "libc++" , "android_arm64_armv8-a_shared" ) . Module ( ) . ( * cc . Module )
2021-01-14 04:18:53 +01:00
ensureListNotContains ( t , cm . Properties . AndroidMkStaticLibs , "libunwind" )
2020-02-26 14:45:42 +01:00
}
2020-04-15 04:03:39 +02:00
func TestApexMinSdkVersion_ErrorIfIncompatibleVersion ( t * testing . T ) {
testApexError ( t , ` module "mylib".*: should support min_sdk_version\(29\) ` , `
2020-02-26 14:45:42 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
2020-04-15 04:03:39 +02:00
native_shared_libs : [ "mylib" ] ,
min_sdk_version : "29" ,
2020-02-26 14:45:42 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
2020-04-15 04:03:39 +02:00
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [
"myapex" ,
] ,
min_sdk_version : "30" ,
}
` )
2020-12-04 21:05:43 +01:00
testApexError ( t , ` module "libfoo.ffi".*: should support min_sdk_version\(29\) ` , `
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libfoo.ffi" ] ,
min_sdk_version : "29" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
rust_ffi_shared {
name : "libfoo.ffi" ,
srcs : [ "foo.rs" ] ,
crate_name : "foo" ,
apex_available : [
"myapex" ,
] ,
min_sdk_version : "30" ,
2020-04-15 04:03:39 +02:00
}
` )
2021-04-02 02:38:25 +02:00
testApexError ( t , ` module "libfoo".*: should support min_sdk_version\(29\) ` , `
apex {
name : "myapex" ,
key : "myapex.key" ,
java_libs : [ "libfoo" ] ,
min_sdk_version : "29" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
java_import {
name : "libfoo" ,
jars : [ "libfoo.jar" ] ,
apex_available : [
"myapex" ,
] ,
min_sdk_version : "30" ,
}
` )
2020-04-15 04:03:39 +02:00
}
func TestApexMinSdkVersion_Okay ( t * testing . T ) {
testApex ( t , `
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libfoo" ] ,
java_libs : [ "libbar" ] ,
min_sdk_version : "29" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libfoo" ,
srcs : [ "mylib.cpp" ] ,
shared_libs : [ "libfoo_dep" ] ,
apex_available : [ "myapex" ] ,
min_sdk_version : "29" ,
}
cc_library {
name : "libfoo_dep" ,
srcs : [ "mylib.cpp" ] ,
apex_available : [ "myapex" ] ,
min_sdk_version : "29" ,
}
java_library {
name : "libbar" ,
sdk_version : "current" ,
srcs : [ "a.java" ] ,
2021-04-02 02:38:25 +02:00
static_libs : [
"libbar_dep" ,
"libbar_import_dep" ,
] ,
2020-04-15 04:03:39 +02:00
apex_available : [ "myapex" ] ,
min_sdk_version : "29" ,
}
java_library {
name : "libbar_dep" ,
sdk_version : "current" ,
srcs : [ "a.java" ] ,
apex_available : [ "myapex" ] ,
min_sdk_version : "29" ,
}
2021-04-02 02:38:25 +02:00
java_import {
name : "libbar_import_dep" ,
jars : [ "libbar.jar" ] ,
apex_available : [ "myapex" ] ,
min_sdk_version : "29" ,
}
2020-02-26 14:45:42 +01:00
` )
}
2020-04-15 18:29:42 +02:00
func TestJavaStableSdkVersion ( t * testing . T ) {
testCases := [ ] struct {
name string
expectedError string
bp string
2021-03-15 10:39:13 +01:00
preparer android . FixturePreparer
2020-04-15 18:29:42 +02:00
} {
{
name : "Non-updatable apex with non-stable dep" ,
bp : `
apex {
name : "myapex" ,
java_libs : [ "myjar" ] ,
key : "myapex.key" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-04-15 18:29:42 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
java_library {
name : "myjar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
2021-03-05 01:00:01 +01:00
sdk_version : "test_current" ,
2020-04-15 18:29:42 +02:00
apex_available : [ "myapex" ] ,
}
` ,
} ,
{
name : "Updatable apex with stable dep" ,
bp : `
apex {
name : "myapex" ,
java_libs : [ "myjar" ] ,
key : "myapex.key" ,
updatable : true ,
min_sdk_version : "29" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
java_library {
name : "myjar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
sdk_version : "current" ,
apex_available : [ "myapex" ] ,
2020-04-15 04:03:39 +02:00
min_sdk_version : "29" ,
2020-04-15 18:29:42 +02:00
}
` ,
} ,
{
name : "Updatable apex with non-stable dep" ,
expectedError : "cannot depend on \"myjar\"" ,
bp : `
apex {
name : "myapex" ,
java_libs : [ "myjar" ] ,
key : "myapex.key" ,
updatable : true ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
java_library {
name : "myjar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
2021-03-05 01:00:01 +01:00
sdk_version : "test_current" ,
2020-04-15 18:29:42 +02:00
apex_available : [ "myapex" ] ,
}
` ,
} ,
2021-03-15 10:39:13 +01:00
{
name : "Updatable apex with non-stable legacy core platform dep" ,
expectedError : ` \Qcannot depend on "myjar-uses-legacy": non stable SDK core_platform_current - uses legacy core platform\E ` ,
bp : `
apex {
name : "myapex" ,
java_libs : [ "myjar-uses-legacy" ] ,
key : "myapex.key" ,
updatable : true ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
java_library {
name : "myjar-uses-legacy" ,
srcs : [ "foo/bar/MyClass.java" ] ,
sdk_version : "core_platform" ,
apex_available : [ "myapex" ] ,
}
` ,
preparer : java . FixtureUseLegacyCorePlatformApi ( "myjar-uses-legacy" ) ,
} ,
2020-04-15 18:29:42 +02:00
{
2021-03-05 01:00:01 +01:00
name : "Updatable apex with non-stable transitive dep" ,
// This is not actually detecting that the transitive dependency is unstable, rather it is
// detecting that the transitive dependency is building against a wider API surface than the
// module that depends on it is using.
2021-02-18 05:10:18 +01:00
expectedError : "compiles against Android API, but dependency \"transitive-jar\" is compiling against private API." ,
2020-04-15 18:29:42 +02:00
bp : `
apex {
name : "myapex" ,
java_libs : [ "myjar" ] ,
key : "myapex.key" ,
updatable : true ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
java_library {
name : "myjar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
sdk_version : "current" ,
apex_available : [ "myapex" ] ,
static_libs : [ "transitive-jar" ] ,
}
java_library {
name : "transitive-jar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
sdk_version : "core_platform" ,
apex_available : [ "myapex" ] ,
}
` ,
} ,
}
for _ , test := range testCases {
2021-03-15 10:39:13 +01:00
if test . name != "Updatable apex with non-stable legacy core platform dep" {
continue
}
2020-04-15 18:29:42 +02:00
t . Run ( test . name , func ( t * testing . T ) {
2021-03-15 10:39:13 +01:00
errorHandler := android . FixtureExpectsNoErrors
if test . expectedError != "" {
errorHandler = android . FixtureExpectsAtLeastOneErrorMatchingPattern ( test . expectedError )
2020-04-15 18:29:42 +02:00
}
2021-03-15 10:39:13 +01:00
android . GroupFixturePreparers (
java . PrepareForTestWithJavaDefaultModules ,
PrepareForTestWithApexBuildComponents ,
prepareForTestWithMyapex ,
android . OptionalFixturePreparer ( test . preparer ) ,
) .
ExtendWithErrorHandler ( errorHandler ) .
RunTestWithBp ( t , test . bp )
2020-04-15 18:29:42 +02:00
} )
}
}
2020-04-15 04:03:39 +02:00
func TestApexMinSdkVersion_ErrorIfDepIsNewer ( t * testing . T ) {
testApexError ( t , ` module "mylib2".*: should support min_sdk_version\(29\) for "myapex" ` , `
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
min_sdk_version : "29" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
shared_libs : [ "mylib2" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [
"myapex" ,
] ,
min_sdk_version : "29" ,
}
// indirect part of the apex
cc_library {
name : "mylib2" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [
"myapex" ,
] ,
min_sdk_version : "30" ,
}
` )
}
func TestApexMinSdkVersion_ErrorIfDepIsNewer_Java ( t * testing . T ) {
testApexError ( t , ` module "bar".*: should support min_sdk_version\(29\) for "myapex" ` , `
apex {
name : "myapex" ,
key : "myapex.key" ,
apps : [ "AppFoo" ] ,
min_sdk_version : "29" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
android_app {
name : "AppFoo" ,
srcs : [ "foo/bar/MyClass.java" ] ,
sdk_version : "current" ,
min_sdk_version : "29" ,
system_modules : "none" ,
stl : "none" ,
static_libs : [ "bar" ] ,
apex_available : [ "myapex" ] ,
}
java_library {
name : "bar" ,
sdk_version : "current" ,
srcs : [ "a.java" ] ,
apex_available : [ "myapex" ] ,
}
` )
}
func TestApexMinSdkVersion_OkayEvenWhenDepIsNewer_IfItSatisfiesApexMinSdkVersion ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-04-15 04:03:39 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
min_sdk_version : "29" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
// mylib in myapex will link to mylib2#current
2020-04-15 04:03:39 +02:00
// mylib in otherapex will link to mylib2(non-stub) in otherapex as well
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
shared_libs : [ "mylib2" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" , "otherapex" ] ,
min_sdk_version : "29" ,
}
cc_library {
name : "mylib2" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "otherapex" ] ,
stubs : { versions : [ "29" , "30" ] } ,
min_sdk_version : "30" ,
}
apex {
name : "otherapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" , "mylib2" ] ,
min_sdk_version : "30" ,
}
` )
expectLink := func ( from , from_variant , to , to_variant string ) {
ld := ctx . ModuleForTests ( from , "android_arm64_armv8-a_" + from_variant ) . Rule ( "ld" )
libFlags := ld . Args [ "libFlags" ]
ensureContains ( t , libFlags , "android_arm64_armv8-a_" + to_variant + "/" + to + ".so" )
}
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
expectLink ( "mylib" , "shared_apex29" , "mylib2" , "shared_current" )
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
expectLink ( "mylib" , "shared_apex30" , "mylib2" , "shared_apex30" )
2020-04-15 04:03:39 +02:00
}
2021-01-26 03:43:46 +01:00
func TestApexMinSdkVersion_WorksWithSdkCodename ( t * testing . T ) {
2021-03-08 12:28:25 +01:00
withSAsActiveCodeNames := android . FixtureModifyProductVariables (
func ( variables android . FixtureProductVariables ) {
variables . Platform_sdk_codename = proptools . StringPtr ( "S" )
variables . Platform_version_active_codenames = [ ] string { "S" }
} ,
)
2021-01-26 03:43:46 +01:00
testApexError ( t , ` libbar.*: should support min_sdk_version\(S\) ` , `
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libfoo" ] ,
min_sdk_version : "S" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libfoo" ,
shared_libs : [ "libbar" ] ,
apex_available : [ "myapex" ] ,
min_sdk_version : "29" ,
}
cc_library {
name : "libbar" ,
apex_available : [ "myapex" ] ,
}
` , withSAsActiveCodeNames )
}
func TestApexMinSdkVersion_WorksWithActiveCodenames ( t * testing . T ) {
2021-03-08 12:28:25 +01:00
withSAsActiveCodeNames := android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . Platform_sdk_codename = proptools . StringPtr ( "S" )
variables . Platform_version_active_codenames = [ ] string { "S" , "T" }
} )
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2021-01-26 03:43:46 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libfoo" ] ,
min_sdk_version : "S" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libfoo" ,
shared_libs : [ "libbar" ] ,
apex_available : [ "myapex" ] ,
min_sdk_version : "S" ,
}
cc_library {
name : "libbar" ,
stubs : {
symbol_file : "libbar.map.txt" ,
versions : [ "30" , "S" , "T" ] ,
} ,
}
` , withSAsActiveCodeNames )
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
// ensure libfoo is linked with current version of libbar stub
2021-01-26 03:43:46 +01:00
libfoo := ctx . ModuleForTests ( "libfoo" , "android_arm64_armv8-a_shared_apex10000" )
libFlags := libfoo . Rule ( "ld" ) . Args [ "libFlags" ]
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
ensureContains ( t , libFlags , "android_arm64_armv8-a_shared_current/libbar.so" )
2021-01-26 03:43:46 +01:00
}
2018-12-06 16:42:25 +01:00
func TestFilesInSubDir ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2018-12-06 16:42:25 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
2019-02-01 04:03:59 +01:00
native_shared_libs : [ "mylib" ] ,
binaries : [ "mybin" ] ,
2018-12-06 16:42:25 +01:00
prebuilts : [ "myetc" ] ,
2019-02-01 04:03:59 +01:00
compile_multilib : "both" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2018-12-06 16:42:25 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
prebuilt_etc {
name : "myetc" ,
src : "myprebuilt" ,
sub_dir : "foo/bar" ,
}
2019-02-01 04:03:59 +01:00
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
relative_install_path : "foo/bar" ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
2019-02-01 04:03:59 +01:00
}
cc_binary {
name : "mybin" ,
srcs : [ "mylib.cpp" ] ,
relative_install_path : "foo/bar" ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
2019-02-01 04:03:59 +01:00
}
2018-12-06 16:42:25 +01:00
` )
2019-10-22 06:58:29 +02:00
generateFsRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "generateFsConfig" )
2018-12-06 16:42:25 +01:00
dirs := strings . Split ( generateFsRule . Args [ "exec_paths" ] , " " )
2019-02-01 04:03:59 +01:00
// Ensure that the subdirectories are all listed
2018-12-06 16:42:25 +01:00
ensureListContains ( t , dirs , "etc" )
ensureListContains ( t , dirs , "etc/foo" )
ensureListContains ( t , dirs , "etc/foo/bar" )
2019-02-01 04:03:59 +01:00
ensureListContains ( t , dirs , "lib64" )
ensureListContains ( t , dirs , "lib64/foo" )
ensureListContains ( t , dirs , "lib64/foo/bar" )
ensureListContains ( t , dirs , "lib" )
ensureListContains ( t , dirs , "lib/foo" )
ensureListContains ( t , dirs , "lib/foo/bar" )
2019-03-15 10:10:35 +01:00
ensureListContains ( t , dirs , "bin" )
ensureListContains ( t , dirs , "bin/foo" )
ensureListContains ( t , dirs , "bin/foo/bar" )
2018-12-06 16:42:25 +01:00
}
2018-12-19 09:12:36 +01:00
2020-02-06 09:33:20 +01:00
func TestFilesInSubDirWhenNativeBridgeEnabled ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-02-06 09:33:20 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
multilib : {
both : {
native_shared_libs : [ "mylib" ] ,
binaries : [ "mybin" ] ,
} ,
} ,
compile_multilib : "both" ,
native_bridge_supported : true ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-02-06 09:33:20 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
relative_install_path : "foo/bar" ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" ] ,
native_bridge_supported : true ,
}
cc_binary {
name : "mybin" ,
relative_install_path : "foo/bar" ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" ] ,
native_bridge_supported : true ,
compile_multilib : "both" , // default is "first" for binary
multilib : {
lib64 : {
suffix : "64" ,
} ,
} ,
}
` , withNativeBridgeEnabled )
ensureExactContents ( t , ctx , "myapex" , "android_common_myapex_image" , [ ] string {
"bin/foo/bar/mybin" ,
"bin/foo/bar/mybin64" ,
"bin/arm/foo/bar/mybin" ,
"bin/arm64/foo/bar/mybin64" ,
"lib/foo/bar/mylib.so" ,
"lib/arm/foo/bar/mylib.so" ,
"lib64/foo/bar/mylib.so" ,
"lib64/arm64/foo/bar/mylib.so" ,
} )
}
2020-06-24 16:50:26 +02:00
func TestVendorApex ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-06-24 16:50:26 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
binaries : [ "mybin" ] ,
vendor : true ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-06-24 16:50:26 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_binary {
name : "mybin" ,
vendor : true ,
shared_libs : [ "libfoo" ] ,
}
cc_library {
name : "libfoo" ,
proprietary : true ,
}
` )
ensureExactContents ( t , ctx , "myapex" , "android_common_myapex_image" , [ ] string {
"bin/mybin" ,
"lib64/libfoo.so" ,
// TODO(b/159195575): Add an option to use VNDK libs from VNDK APEX
"lib64/libc++.so" ,
} )
apexBundle := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Module ( ) . ( * apexBundle )
2020-07-03 22:18:24 +02:00
data := android . AndroidMkDataForTest ( t , ctx , apexBundle )
2020-06-24 16:50:26 +02:00
name := apexBundle . BaseModuleName ( )
prefix := "TARGET_"
var builder strings . Builder
data . Custom ( & builder , name , prefix , "" , data )
2021-03-29 01:21:08 +02:00
androidMk := android . StringRelativeToTop ( ctx . Config ( ) , builder . String ( ) )
installPath := "out/target/product/test_device/vendor/apex"
2021-02-26 14:27:36 +01:00
ensureContains ( t , androidMk , "LOCAL_MODULE_PATH := " + installPath )
2020-07-29 09:00:54 +02:00
apexManifestRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "apexManifestRule" )
requireNativeLibs := names ( apexManifestRule . Args [ "requireNativeLibs" ] )
ensureListNotContains ( t , requireNativeLibs , ":vndk" )
2020-06-24 16:50:26 +02:00
}
2020-07-22 08:54:47 +02:00
func TestVendorApex_use_vndk_as_stable ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-07-22 08:54:47 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
binaries : [ "mybin" ] ,
vendor : true ,
use_vndk_as_stable : true ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-07-22 08:54:47 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_binary {
name : "mybin" ,
vendor : true ,
shared_libs : [ "libvndk" , "libvendor" ] ,
}
cc_library {
name : "libvndk" ,
vndk : {
enabled : true ,
} ,
vendor_available : true ,
2020-10-29 08:49:43 +01:00
product_available : true ,
2020-07-22 08:54:47 +02:00
}
cc_library {
name : "libvendor" ,
vendor : true ,
}
` )
2021-04-01 14:35:20 +02:00
vendorVariant := "android_vendor.29_arm64_armv8-a"
2020-07-22 08:54:47 +02:00
2021-03-29 01:42:57 +02:00
ldRule := ctx . ModuleForTests ( "mybin" , vendorVariant + "_apex10000" ) . Rule ( "ld" )
2020-07-22 08:54:47 +02:00
libs := names ( ldRule . Args [ "libFlags" ] )
// VNDK libs(libvndk/libc++) as they are
2021-03-29 01:21:08 +02:00
ensureListContains ( t , libs , "out/soong/.intermediates/libvndk/" + vendorVariant + "_shared/libvndk.so" )
ensureListContains ( t , libs , "out/soong/.intermediates/" + cc . DefaultCcCommonTestModulesDir + "libc++/" + vendorVariant + "_shared/libc++.so" )
2020-07-22 08:54:47 +02:00
// non-stable Vendor libs as APEX variants
2021-03-29 01:21:08 +02:00
ensureListContains ( t , libs , "out/soong/.intermediates/libvendor/" + vendorVariant + "_shared_apex10000/libvendor.so" )
2020-07-22 08:54:47 +02:00
// VNDK libs are not included when use_vndk_as_stable: true
ensureExactContents ( t , ctx , "myapex" , "android_common_myapex_image" , [ ] string {
"bin/mybin" ,
"lib64/libvendor.so" ,
} )
2020-07-29 09:00:54 +02:00
apexManifestRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "apexManifestRule" )
requireNativeLibs := names ( apexManifestRule . Args [ "requireNativeLibs" ] )
ensureListContains ( t , requireNativeLibs , ":vndk" )
2020-07-22 08:54:47 +02:00
}
2021-03-08 11:25:55 +01:00
func TestProductVariant ( t * testing . T ) {
ctx := testApex ( t , `
apex {
name : "myapex" ,
key : "myapex.key" ,
updatable : false ,
product_specific : true ,
binaries : [ "foo" ] ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_binary {
name : "foo" ,
product_available : true ,
apex_available : [ "myapex" ] ,
srcs : [ "foo.cpp" ] ,
}
2021-03-08 12:28:25 +01:00
` , android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . ProductVndkVersion = proptools . StringPtr ( "current" )
} ) ,
)
2021-03-08 11:25:55 +01:00
cflags := strings . Fields (
2021-04-01 14:35:20 +02:00
ctx . ModuleForTests ( "foo" , "android_product.29_arm64_armv8-a_apex10000" ) . Rule ( "cc" ) . Args [ "cFlags" ] )
2021-03-08 11:25:55 +01:00
ensureListContains ( t , cflags , "-D__ANDROID_VNDK__" )
ensureListContains ( t , cflags , "-D__ANDROID_APEX__" )
ensureListContains ( t , cflags , "-D__ANDROID_PRODUCT__" )
ensureListNotContains ( t , cflags , "-D__ANDROID_VENDOR__" )
}
2020-09-21 04:02:57 +02:00
func TestApex_withPrebuiltFirmware ( t * testing . T ) {
testCases := [ ] struct {
name string
additionalProp string
} {
{ "system apex with prebuilt_firmware" , "" } ,
{ "vendor apex with prebuilt_firmware" , "vendor: true," } ,
}
for _ , tc := range testCases {
t . Run ( tc . name , func ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-09-21 04:02:57 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
prebuilts : [ "myfirmware" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-09-21 04:02:57 +02:00
` +tc.additionalProp+ `
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
prebuilt_firmware {
name : "myfirmware" ,
src : "myfirmware.bin" ,
filename_from_src : true ,
` +tc.additionalProp+ `
}
` )
ensureExactContents ( t , ctx , "myapex" , "android_common_myapex_image" , [ ] string {
"etc/firmware/myfirmware.bin" ,
} )
} )
}
2020-08-26 15:11:53 +02:00
}
2020-06-25 10:14:25 +02:00
func TestAndroidMk_VendorApexRequired ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-06-25 10:14:25 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
vendor : true ,
native_shared_libs : [ "mylib" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-06-25 10:14:25 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
vendor_available : true ,
}
` )
apexBundle := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Module ( ) . ( * apexBundle )
2020-07-03 22:18:24 +02:00
data := android . AndroidMkDataForTest ( t , ctx , apexBundle )
2020-06-25 10:14:25 +02:00
name := apexBundle . BaseModuleName ( )
prefix := "TARGET_"
var builder strings . Builder
data . Custom ( & builder , name , prefix , "" , data )
androidMk := builder . String ( )
ensureContains ( t , androidMk , "LOCAL_REQUIRED_MODULES += libc.vendor libm.vendor libdl.vendor\n" )
}
2020-06-24 16:26:26 +02:00
func TestAndroidMkWritesCommonProperties ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-06-24 16:26:26 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
vintf_fragments : [ "fragment.xml" ] ,
init_rc : [ "init.rc" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-06-24 16:26:26 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_binary {
name : "mybin" ,
}
` )
apexBundle := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Module ( ) . ( * apexBundle )
2020-07-03 22:18:24 +02:00
data := android . AndroidMkDataForTest ( t , ctx , apexBundle )
2020-06-24 16:26:26 +02:00
name := apexBundle . BaseModuleName ( )
prefix := "TARGET_"
var builder strings . Builder
data . Custom ( & builder , name , prefix , "" , data )
androidMk := builder . String ( )
2021-04-16 22:41:59 +02:00
ensureContains ( t , androidMk , "LOCAL_FULL_VINTF_FRAGMENTS := fragment.xml\n" )
2021-04-06 16:35:10 +02:00
ensureContains ( t , androidMk , "LOCAL_FULL_INIT_RC := init.rc\n" )
2020-06-24 16:26:26 +02:00
}
2018-12-20 10:18:08 +01:00
func TestStaticLinking ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2018-12-20 10:18:08 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2018-12-20 10:18:08 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
stubs : {
versions : [ "1" , "2" , "3" ] ,
} ,
2020-01-10 16:12:39 +01:00
apex_available : [
"//apex_available:platform" ,
"myapex" ,
] ,
2018-12-20 10:18:08 +01:00
}
cc_binary {
name : "not_in_apex" ,
srcs : [ "mylib.cpp" ] ,
static_libs : [ "mylib" ] ,
static_executable : true ,
system_shared_libs : [ ] ,
stl : "none" ,
}
` )
2019-11-21 01:39:12 +01:00
ldFlags := ctx . ModuleForTests ( "not_in_apex" , "android_arm64_armv8-a" ) . Rule ( "ld" ) . Args [ "libFlags" ]
2018-12-20 10:18:08 +01:00
// Ensure that not_in_apex is linking with the static variant of mylib
2019-11-21 01:39:12 +01:00
ensureContains ( t , ldFlags , "mylib/android_arm64_armv8-a_static/mylib.a" )
2018-12-20 10:18:08 +01:00
}
2018-12-24 03:31:58 +01:00
func TestKeys ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2018-12-24 03:31:58 +01:00
apex {
2019-02-11 03:38:15 +01:00
name : "myapex_keytest" ,
2018-12-24 03:31:58 +01:00
key : "myapex.key" ,
2019-02-11 03:38:15 +01:00
certificate : ":myapex.certificate" ,
2018-12-24 03:31:58 +01:00
native_shared_libs : [ "mylib" ] ,
2019-11-19 18:26:02 +01:00
file_contexts : ":myapex-file_contexts" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2018-12-24 03:31:58 +01:00
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex_keytest" ] ,
2018-12-24 03:31:58 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
2019-02-11 03:38:15 +01:00
android_app_certificate {
name : "myapex.certificate" ,
certificate : "testkey" ,
}
android_app_certificate {
name : "myapex.certificate.override" ,
certificate : "testkey.override" ,
}
2018-12-24 03:31:58 +01:00
` )
// check the APEX keys
2019-03-14 18:13:21 +01:00
keys := ctx . ModuleForTests ( "myapex.key" , "android_common" ) . Module ( ) . ( * apexKey )
2018-12-24 03:31:58 +01:00
2020-12-21 18:11:10 +01:00
if keys . publicKeyFile . String ( ) != "vendor/foo/devkeys/testkey.avbpubkey" {
t . Errorf ( "public key %q is not %q" , keys . publicKeyFile . String ( ) ,
2018-12-24 03:31:58 +01:00
"vendor/foo/devkeys/testkey.avbpubkey" )
}
2020-12-21 18:11:10 +01:00
if keys . privateKeyFile . String ( ) != "vendor/foo/devkeys/testkey.pem" {
t . Errorf ( "private key %q is not %q" , keys . privateKeyFile . String ( ) ,
2018-12-24 03:31:58 +01:00
"vendor/foo/devkeys/testkey.pem" )
}
2019-02-11 03:38:15 +01:00
// check the APK certs. It should be overridden to myapex.certificate.override
2019-10-22 06:58:29 +02:00
certs := ctx . ModuleForTests ( "myapex_keytest" , "android_common_myapex_keytest_image" ) . Rule ( "signapk" ) . Args [ "certificates" ]
2019-02-11 03:38:15 +01:00
if certs != "testkey.override.x509.pem testkey.override.pk8" {
2018-12-24 03:31:58 +01:00
t . Errorf ( "cert and private key %q are not %q" , certs ,
2019-02-11 03:38:15 +01:00
"testkey.override.509.pem testkey.override.pk8" )
2018-12-24 03:31:58 +01:00
}
}
2019-01-19 11:24:06 +01:00
2019-12-17 06:30:11 +01:00
func TestCertificate ( t * testing . T ) {
t . Run ( "if unspecified, it defaults to DefaultAppCertificate" , func ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-12-17 06:30:11 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-12-17 06:30:11 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
} ` )
rule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "signapk" )
expected := "vendor/foo/devkeys/test.x509.pem vendor/foo/devkeys/test.pk8"
if actual := rule . Args [ "certificates" ] ; actual != expected {
t . Errorf ( "certificates should be %q, not %q" , expected , actual )
}
} )
t . Run ( "override when unspecified" , func ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-12-17 06:30:11 +01:00
apex {
name : "myapex_keytest" ,
key : "myapex.key" ,
file_contexts : ":myapex-file_contexts" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-12-17 06:30:11 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
android_app_certificate {
name : "myapex.certificate.override" ,
certificate : "testkey.override" ,
} ` )
rule := ctx . ModuleForTests ( "myapex_keytest" , "android_common_myapex_keytest_image" ) . Rule ( "signapk" )
expected := "testkey.override.x509.pem testkey.override.pk8"
if actual := rule . Args [ "certificates" ] ; actual != expected {
t . Errorf ( "certificates should be %q, not %q" , expected , actual )
}
} )
t . Run ( "if specified as :module, it respects the prop" , func ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-12-17 06:30:11 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
certificate : ":myapex.certificate" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-12-17 06:30:11 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
android_app_certificate {
name : "myapex.certificate" ,
certificate : "testkey" ,
} ` )
rule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "signapk" )
expected := "testkey.x509.pem testkey.pk8"
if actual := rule . Args [ "certificates" ] ; actual != expected {
t . Errorf ( "certificates should be %q, not %q" , expected , actual )
}
} )
t . Run ( "override when specifiec as <:module>" , func ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-12-17 06:30:11 +01:00
apex {
name : "myapex_keytest" ,
key : "myapex.key" ,
file_contexts : ":myapex-file_contexts" ,
certificate : ":myapex.certificate" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-12-17 06:30:11 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
android_app_certificate {
name : "myapex.certificate.override" ,
certificate : "testkey.override" ,
} ` )
rule := ctx . ModuleForTests ( "myapex_keytest" , "android_common_myapex_keytest_image" ) . Rule ( "signapk" )
expected := "testkey.override.x509.pem testkey.override.pk8"
if actual := rule . Args [ "certificates" ] ; actual != expected {
t . Errorf ( "certificates should be %q, not %q" , expected , actual )
}
} )
t . Run ( "if specified as name, finds it from DefaultDevKeyDir" , func ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-12-17 06:30:11 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
certificate : "testkey" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-12-17 06:30:11 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
} ` )
rule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "signapk" )
expected := "vendor/foo/devkeys/testkey.x509.pem vendor/foo/devkeys/testkey.pk8"
if actual := rule . Args [ "certificates" ] ; actual != expected {
t . Errorf ( "certificates should be %q, not %q" , expected , actual )
}
} )
t . Run ( "override when specified as <name>" , func ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-12-17 06:30:11 +01:00
apex {
name : "myapex_keytest" ,
key : "myapex.key" ,
file_contexts : ":myapex-file_contexts" ,
certificate : "testkey" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-12-17 06:30:11 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
android_app_certificate {
name : "myapex.certificate.override" ,
certificate : "testkey.override" ,
} ` )
rule := ctx . ModuleForTests ( "myapex_keytest" , "android_common_myapex_keytest_image" ) . Rule ( "signapk" )
expected := "testkey.override.x509.pem testkey.override.pk8"
if actual := rule . Args [ "certificates" ] ; actual != expected {
t . Errorf ( "certificates should be %q, not %q" , expected , actual )
}
} )
}
2019-01-19 11:24:06 +01:00
func TestMacro ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-01-19 11:24:06 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
2020-03-02 09:44:33 +01:00
native_shared_libs : [ "mylib" , "mylib2" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-01-19 11:24:06 +01:00
}
apex {
name : "otherapex" ,
key : "myapex.key" ,
2020-03-02 09:44:33 +01:00
native_shared_libs : [ "mylib" , "mylib2" ] ,
2020-03-06 19:45:53 +01:00
min_sdk_version : "29" ,
2019-01-19 11:24:06 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [
"myapex" ,
"otherapex" ,
] ,
2020-03-21 15:20:55 +01:00
recovery_available : true ,
2020-04-15 04:03:39 +02:00
min_sdk_version : "29" ,
2019-01-19 11:24:06 +01:00
}
2020-03-02 09:44:33 +01:00
cc_library {
name : "mylib2" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [
"myapex" ,
"otherapex" ,
] ,
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
static_libs : [ "mylib3" ] ,
recovery_available : true ,
min_sdk_version : "29" ,
}
cc_library {
name : "mylib3" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [
"myapex" ,
"otherapex" ,
] ,
recovery_available : true ,
2020-04-15 04:03:39 +02:00
min_sdk_version : "29" ,
2020-03-02 09:44:33 +01:00
}
2019-01-19 11:24:06 +01:00
` )
2020-03-02 09:44:33 +01:00
// non-APEX variant does not have __ANDROID_APEX__ defined
2019-11-21 01:39:12 +01:00
mylibCFlags := ctx . ModuleForTests ( "mylib" , "android_arm64_armv8-a_static" ) . Rule ( "cc" ) . Args [ "cFlags" ]
2019-10-30 00:29:25 +01:00
ensureNotContains ( t , mylibCFlags , "-D__ANDROID_APEX__" )
2020-11-18 00:29:36 +01:00
ensureNotContains ( t , mylibCFlags , "-D__ANDROID_APEX_MIN_SDK_VERSION__" )
2020-03-02 09:44:33 +01:00
2020-03-06 19:45:53 +01:00
// APEX variant has __ANDROID_APEX__ and __ANDROID_APEX_SDK__ defined
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
mylibCFlags = ctx . ModuleForTests ( "mylib" , "android_arm64_armv8-a_static_apex10000" ) . Rule ( "cc" ) . Args [ "cFlags" ]
2020-03-02 09:44:33 +01:00
ensureContains ( t , mylibCFlags , "-D__ANDROID_APEX__" )
2020-11-18 00:29:36 +01:00
ensureContains ( t , mylibCFlags , "-D__ANDROID_APEX_MIN_SDK_VERSION__=10000" )
2020-03-02 09:44:33 +01:00
2020-03-06 19:45:53 +01:00
// APEX variant has __ANDROID_APEX__ and __ANDROID_APEX_SDK__ defined
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
mylibCFlags = ctx . ModuleForTests ( "mylib" , "android_arm64_armv8-a_static_apex29" ) . Rule ( "cc" ) . Args [ "cFlags" ]
2020-03-02 09:44:33 +01:00
ensureContains ( t , mylibCFlags , "-D__ANDROID_APEX__" )
2020-11-18 00:29:36 +01:00
ensureContains ( t , mylibCFlags , "-D__ANDROID_APEX_MIN_SDK_VERSION__=29" )
2019-01-19 11:24:06 +01:00
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
// When a cc_library sets use_apex_name_macro: true each apex gets a unique variant and
// each variant defines additional macros to distinguish which apex variant it is built for
// non-APEX variant does not have __ANDROID_APEX__ defined
mylibCFlags = ctx . ModuleForTests ( "mylib3" , "android_arm64_armv8-a_static" ) . Rule ( "cc" ) . Args [ "cFlags" ]
ensureNotContains ( t , mylibCFlags , "-D__ANDROID_APEX__" )
2020-11-18 00:29:36 +01:00
// recovery variant does not set __ANDROID_APEX_MIN_SDK_VERSION__
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
mylibCFlags = ctx . ModuleForTests ( "mylib3" , "android_recovery_arm64_armv8-a_static" ) . Rule ( "cc" ) . Args [ "cFlags" ]
ensureNotContains ( t , mylibCFlags , "-D__ANDROID_APEX__" )
2020-11-18 00:29:36 +01:00
ensureNotContains ( t , mylibCFlags , "-D__ANDROID_APEX_MIN_SDK_VERSION__" )
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
2020-03-02 09:44:33 +01:00
// non-APEX variant does not have __ANDROID_APEX__ defined
mylibCFlags = ctx . ModuleForTests ( "mylib2" , "android_arm64_armv8-a_static" ) . Rule ( "cc" ) . Args [ "cFlags" ]
ensureNotContains ( t , mylibCFlags , "-D__ANDROID_APEX__" )
2020-11-18 00:29:36 +01:00
// recovery variant does not set __ANDROID_APEX_MIN_SDK_VERSION__
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
mylibCFlags = ctx . ModuleForTests ( "mylib2" , "android_recovery_arm64_armv8-a_static" ) . Rule ( "cc" ) . Args [ "cFlags" ]
2020-03-21 15:20:55 +01:00
ensureNotContains ( t , mylibCFlags , "-D__ANDROID_APEX__" )
2020-11-18 00:29:36 +01:00
ensureNotContains ( t , mylibCFlags , "-D__ANDROID_APEX_MIN_SDK_VERSION__" )
2019-01-19 11:24:06 +01:00
}
2019-01-28 08:16:54 +01:00
func TestHeaderLibsDependency ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-01-28 08:16:54 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-01-28 08:16:54 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library_headers {
name : "mylib_headers" ,
export_include_dirs : [ "my_include" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available tracks static dependencies
This change fixes a bug that apex_available is not enforced for static
dependencies. For example, a module with 'apex_available:
["//apex_available:platform"]' was able to be statically linked to any
APEX. This was happening because the check was done on the modules that
are actually installed to an APEX. Static dependencies of the modules
were not counted as they are not installed to the APEX as files.
Fixing this bug by doing the check by traversing the tree in the method
checkApexAvailability.
This change includes a few number of related changes:
1) DepIsInSameApex implementation for cc.Module was changed as well.
Previuosly, it returned false only when the dependency is actually a
stub variant of a lib. Now, it returns false when the dependency has one
or more stub variants. To understand why, we need to recall that when
there is a dependency to a lib having stubs, we actually create two
dependencies: to the non-stub variant and to the stub variant during the
DepsMutator phase. And later in the build action generation phase, we
choose one of them depending on the context. Also recall that an APEX
variant is created only when DepIsInSameApex returns true. Given these,
with the previous implementatin of DepIsInSameApex, we did create apex
variants of the non-stub variant of the dependency, while not creating
the apex variant for the stub variant. This is not right; we needlessly
created the apex variant. The extra apex variant has caused no harm so
far, but since the apex_available check became more correct, it actually
breaks the build. To fix the issue, we stop creating the APEX variant
both for non-stub and stub variants.
2) platform variant is created regardless of the apex_available value.
This is required for the case when a library X that provides stub is in
an APEX A and is configured to be available only for A. In that case,
libs in other APEX can't use the stub library since the stub library is
mutated only for apex A. By creating the platform variant for the stub
library, it can be used from outside as the default dependency variation
is set to the platform variant when creating the APEX variations.
3) The ApexAvailableWhitelist is added with the dependencies that were
revealed with this change.
Exempt-From-Owner-Approval: cherry-pick from internal
Bug: 147671264
Test: m
Merged-In: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
(cherry picked from commit fa89944c79f19552e906b41fd03a4981903eee7e)
Change-Id: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
2020-01-30 18:49:53 +01:00
apex_available : [ "myapex" ] ,
2019-01-28 08:16:54 +01:00
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
header_libs : [ "mylib_headers" ] ,
export_header_lib_headers : [ "mylib_headers" ] ,
stubs : {
versions : [ "1" , "2" , "3" ] ,
} ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
2019-01-28 08:16:54 +01:00
}
cc_library {
name : "otherlib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
shared_libs : [ "mylib" ] ,
}
` )
2019-11-21 01:39:12 +01:00
cFlags := ctx . ModuleForTests ( "otherlib" , "android_arm64_armv8-a_static" ) . Rule ( "cc" ) . Args [ "cFlags" ]
2019-01-28 08:16:54 +01:00
// Ensure that the include path of the header lib is exported to 'otherlib'
ensureContains ( t , cFlags , "-Imy_include" )
}
2019-01-30 03:07:33 +01:00
2020-01-14 01:22:18 +01:00
type fileInApex struct {
path string // path in apex
2020-01-23 06:36:59 +01:00
src string // src path
2020-01-14 01:22:18 +01:00
isLink bool
}
2020-01-23 06:36:59 +01:00
func getFiles ( t * testing . T , ctx * android . TestContext , moduleName , variant string ) [ ] fileInApex {
2019-10-18 09:26:59 +02:00
t . Helper ( )
2020-01-23 06:36:59 +01:00
apexRule := ctx . ModuleForTests ( moduleName , variant ) . Rule ( "apexRule" )
2019-10-18 09:26:59 +02:00
copyCmds := apexRule . Args [ "copy_commands" ]
imageApexDir := "/image.apex/"
2020-01-14 01:22:18 +01:00
var ret [ ] fileInApex
2019-10-18 09:26:59 +02:00
for _ , cmd := range strings . Split ( copyCmds , "&&" ) {
cmd = strings . TrimSpace ( cmd )
if cmd == "" {
continue
}
terms := strings . Split ( cmd , " " )
2020-01-23 06:36:59 +01:00
var dst , src string
2020-01-14 01:22:18 +01:00
var isLink bool
2019-10-18 09:26:59 +02:00
switch terms [ 0 ] {
case "mkdir" :
case "cp" :
2020-01-14 01:22:18 +01:00
if len ( terms ) != 3 && len ( terms ) != 4 {
2019-10-18 09:26:59 +02:00
t . Fatal ( "copyCmds contains invalid cp command" , cmd )
}
2020-01-14 01:22:18 +01:00
dst = terms [ len ( terms ) - 1 ]
2020-01-23 06:36:59 +01:00
src = terms [ len ( terms ) - 2 ]
2020-01-14 01:22:18 +01:00
isLink = false
case "ln" :
if len ( terms ) != 3 && len ( terms ) != 4 {
// ln LINK TARGET or ln -s LINK TARGET
t . Fatal ( "copyCmds contains invalid ln command" , cmd )
}
dst = terms [ len ( terms ) - 1 ]
2020-01-23 06:36:59 +01:00
src = terms [ len ( terms ) - 2 ]
2020-01-14 01:22:18 +01:00
isLink = true
default :
t . Fatalf ( "copyCmds should contain mkdir/cp commands only: %q" , cmd )
}
if dst != "" {
2019-10-18 09:26:59 +02:00
index := strings . Index ( dst , imageApexDir )
if index == - 1 {
t . Fatal ( "copyCmds should copy a file to image.apex/" , cmd )
}
dstFile := dst [ index + len ( imageApexDir ) : ]
2020-01-23 06:36:59 +01:00
ret = append ( ret , fileInApex { path : dstFile , src : src , isLink : isLink } )
2019-10-18 09:26:59 +02:00
}
}
2020-01-14 01:22:18 +01:00
return ret
}
2020-01-23 06:36:59 +01:00
func ensureExactContents ( t * testing . T , ctx * android . TestContext , moduleName , variant string , files [ ] string ) {
t . Helper ( )
2020-01-14 01:22:18 +01:00
var failed bool
var surplus [ ] string
filesMatched := make ( map [ string ] bool )
2020-01-23 06:36:59 +01:00
for _ , file := range getFiles ( t , ctx , moduleName , variant ) {
2020-02-27 05:31:56 +01:00
mactchFound := false
2020-01-14 01:22:18 +01:00
for _ , expected := range files {
if matched , _ := path . Match ( expected , file . path ) ; matched {
filesMatched [ expected ] = true
2020-02-27 05:31:56 +01:00
mactchFound = true
break
2020-01-14 01:22:18 +01:00
}
}
2020-02-27 05:31:56 +01:00
if ! mactchFound {
surplus = append ( surplus , file . path )
}
2020-01-14 01:22:18 +01:00
}
2019-10-18 09:26:59 +02:00
if len ( surplus ) > 0 {
2019-11-06 08:53:07 +01:00
sort . Strings ( surplus )
2019-10-18 09:26:59 +02:00
t . Log ( "surplus files" , surplus )
failed = true
}
2019-11-06 08:53:07 +01:00
if len ( files ) > len ( filesMatched ) {
var missing [ ] string
for _ , expected := range files {
if ! filesMatched [ expected ] {
missing = append ( missing , expected )
}
}
sort . Strings ( missing )
2019-10-18 09:26:59 +02:00
t . Log ( "missing files" , missing )
failed = true
}
if failed {
t . Fail ( )
}
}
2019-08-23 04:17:39 +02:00
func TestVndkApexCurrent ( t * testing . T ) {
2021-06-23 18:53:43 +02:00
commonFiles := [ ] string {
2020-02-27 05:31:56 +01:00
"lib/libc++.so" ,
"lib64/libc++.so" ,
2021-04-01 14:35:20 +02:00
"etc/llndk.libraries.29.txt" ,
"etc/vndkcore.libraries.29.txt" ,
"etc/vndksp.libraries.29.txt" ,
"etc/vndkprivate.libraries.29.txt" ,
"etc/vndkproduct.libraries.29.txt" ,
2021-06-23 18:53:43 +02:00
}
testCases := [ ] struct {
vndkVersion string
expectedFiles [ ] string
} {
{
vndkVersion : "current" ,
expectedFiles : append ( commonFiles ,
"lib/libvndk.so" ,
"lib/libvndksp.so" ,
"lib64/libvndk.so" ,
"lib64/libvndksp.so" ) ,
} ,
{
vndkVersion : "" ,
expectedFiles : append ( commonFiles ,
// Legacy VNDK APEX contains only VNDK-SP files (of core variant)
"lib/libvndksp.so" ,
"lib64/libvndksp.so" ) ,
} ,
}
for _ , tc := range testCases {
t . Run ( "VNDK.current with DeviceVndkVersion=" + tc . vndkVersion , func ( t * testing . T ) {
ctx := testApex ( t , `
apex_vndk {
name : "com.android.vndk.current" ,
key : "com.android.vndk.current.key" ,
updatable : false ,
}
apex_key {
name : "com.android.vndk.current.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libvndk" ,
srcs : [ "mylib.cpp" ] ,
vendor_available : true ,
product_available : true ,
vndk : {
enabled : true ,
} ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "com.android.vndk.current" ] ,
}
cc_library {
name : "libvndksp" ,
srcs : [ "mylib.cpp" ] ,
vendor_available : true ,
product_available : true ,
vndk : {
enabled : true ,
support_system_process : true ,
} ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "com.android.vndk.current" ] ,
}
// VNDK-Ext should not cause any problems
cc_library {
name : "libvndk.ext" ,
srcs : [ "mylib2.cpp" ] ,
vendor : true ,
vndk : {
enabled : true ,
extends : "libvndk" ,
} ,
system_shared_libs : [ ] ,
stl : "none" ,
}
cc_library {
name : "libvndksp.ext" ,
srcs : [ "mylib2.cpp" ] ,
vendor : true ,
vndk : {
enabled : true ,
support_system_process : true ,
extends : "libvndksp" ,
} ,
system_shared_libs : [ ] ,
stl : "none" ,
}
` + vndkLibrariesTxtFiles ( "current" ) , android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . DeviceVndkVersion = proptools . StringPtr ( tc . vndkVersion )
} ) )
ensureExactContents ( t , ctx , "com.android.vndk.current" , "android_common_image" , tc . expectedFiles )
} )
}
2019-08-23 04:17:39 +02:00
}
func TestVndkApexWithPrebuilt ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-08-23 04:17:39 +02:00
apex_vndk {
2021-03-02 19:15:29 +01:00
name : "com.android.vndk.current" ,
key : "com.android.vndk.current.key" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-08-23 04:17:39 +02:00
}
apex_key {
2021-03-02 19:15:29 +01:00
name : "com.android.vndk.current.key" ,
2019-08-23 04:17:39 +02:00
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_prebuilt_library_shared {
2019-10-18 09:26:59 +02:00
name : "libvndk" ,
srcs : [ "libvndk.so" ] ,
vendor_available : true ,
2020-10-29 08:49:43 +01:00
product_available : true ,
2019-10-18 09:26:59 +02:00
vndk : {
enabled : true ,
} ,
system_shared_libs : [ ] ,
stl : "none" ,
2021-03-02 19:15:29 +01:00
apex_available : [ "com.android.vndk.current" ] ,
2019-10-18 09:26:59 +02:00
}
cc_prebuilt_library_shared {
name : "libvndk.arm" ,
srcs : [ "libvndk.arm.so" ] ,
2019-08-23 04:17:39 +02:00
vendor_available : true ,
2020-10-29 08:49:43 +01:00
product_available : true ,
2019-08-23 04:17:39 +02:00
vndk : {
enabled : true ,
} ,
2019-10-18 09:26:59 +02:00
enabled : false ,
arch : {
arm : {
enabled : true ,
} ,
} ,
2019-08-23 04:17:39 +02:00
system_shared_libs : [ ] ,
stl : "none" ,
2021-03-02 19:15:29 +01:00
apex_available : [ "com.android.vndk.current" ] ,
2019-08-23 04:17:39 +02:00
}
2019-11-06 08:53:07 +01:00
` + vndkLibrariesTxtFiles ( "current" ) ,
withFiles ( map [ string ] [ ] byte {
"libvndk.so" : nil ,
"libvndk.arm.so" : nil ,
} ) )
2021-03-02 19:15:29 +01:00
ensureExactContents ( t , ctx , "com.android.vndk.current" , "android_common_image" , [ ] string {
2019-10-18 09:26:59 +02:00
"lib/libvndk.so" ,
"lib/libvndk.arm.so" ,
"lib64/libvndk.so" ,
2020-02-27 05:31:56 +01:00
"lib/libc++.so" ,
"lib64/libc++.so" ,
2019-11-06 08:53:07 +01:00
"etc/*" ,
2019-10-18 09:26:59 +02:00
} )
2019-08-23 04:17:39 +02:00
}
2019-11-06 08:53:07 +01:00
func vndkLibrariesTxtFiles ( vers ... string ) ( result string ) {
for _ , v := range vers {
if v == "current" {
2020-12-07 04:44:03 +01:00
for _ , txt := range [ ] string { "llndk" , "vndkcore" , "vndksp" , "vndkprivate" , "vndkproduct" } {
2019-11-06 08:53:07 +01:00
result += `
2020-12-28 22:50:21 +01:00
` + txt + ` _libraries_txt {
2019-11-06 08:53:07 +01:00
name : "` + txt + `.libraries.txt" ,
}
`
}
} else {
2020-12-07 04:44:03 +01:00
for _ , txt := range [ ] string { "llndk" , "vndkcore" , "vndksp" , "vndkprivate" , "vndkproduct" } {
2019-11-06 08:53:07 +01:00
result += `
prebuilt_etc {
name : "` + txt + `.libraries.` + v + `.txt" ,
src : "dummy.txt" ,
}
`
}
}
}
return
}
2019-08-23 04:17:39 +02:00
func TestVndkApexVersion ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-08-23 04:17:39 +02:00
apex_vndk {
2021-03-02 19:15:29 +01:00
name : "com.android.vndk.v27" ,
2019-08-23 04:17:39 +02:00
key : "myapex.key" ,
2019-11-19 18:26:02 +01:00
file_contexts : ":myapex-file_contexts" ,
2019-08-23 04:17:39 +02:00
vndk_version : "27" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-08-23 04:17:39 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
2019-10-18 09:26:59 +02:00
vndk_prebuilt_shared {
name : "libvndk27" ,
version : "27" ,
2019-08-23 04:17:39 +02:00
vendor_available : true ,
2020-10-29 08:49:43 +01:00
product_available : true ,
2019-08-23 04:17:39 +02:00
vndk : {
enabled : true ,
} ,
2019-10-18 09:26:59 +02:00
target_arch : "arm64" ,
arch : {
arm : {
srcs : [ "libvndk27_arm.so" ] ,
} ,
arm64 : {
srcs : [ "libvndk27_arm64.so" ] ,
} ,
} ,
2021-03-02 19:15:29 +01:00
apex_available : [ "com.android.vndk.v27" ] ,
2019-08-23 04:17:39 +02:00
}
vndk_prebuilt_shared {
name : "libvndk27" ,
version : "27" ,
vendor_available : true ,
2020-10-29 08:49:43 +01:00
product_available : true ,
2019-08-23 04:17:39 +02:00
vndk : {
enabled : true ,
} ,
2019-10-18 09:26:59 +02:00
target_arch : "x86_64" ,
arch : {
x86 : {
srcs : [ "libvndk27_x86.so" ] ,
} ,
x86_64 : {
srcs : [ "libvndk27_x86_64.so" ] ,
} ,
} ,
2019-11-06 08:53:07 +01:00
}
` + vndkLibrariesTxtFiles ( "27" ) ,
withFiles ( map [ string ] [ ] byte {
"libvndk27_arm.so" : nil ,
"libvndk27_arm64.so" : nil ,
"libvndk27_x86.so" : nil ,
"libvndk27_x86_64.so" : nil ,
} ) )
2019-08-23 04:17:39 +02:00
2021-03-02 19:15:29 +01:00
ensureExactContents ( t , ctx , "com.android.vndk.v27" , "android_common_image" , [ ] string {
2019-10-18 09:26:59 +02:00
"lib/libvndk27_arm.so" ,
"lib64/libvndk27_arm64.so" ,
2019-11-06 08:53:07 +01:00
"etc/*" ,
2019-10-18 09:26:59 +02:00
} )
2019-08-23 04:17:39 +02:00
}
2019-10-01 13:02:42 +02:00
func TestVndkApexNameRule ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-10-01 13:02:42 +02:00
apex_vndk {
2021-03-02 19:15:29 +01:00
name : "com.android.vndk.current" ,
2019-10-01 13:02:42 +02:00
key : "myapex.key" ,
2019-11-19 18:26:02 +01:00
file_contexts : ":myapex-file_contexts" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-10-01 13:02:42 +02:00
}
apex_vndk {
2021-03-02 19:15:29 +01:00
name : "com.android.vndk.v28" ,
2019-10-01 13:02:42 +02:00
key : "myapex.key" ,
2019-11-19 18:26:02 +01:00
file_contexts : ":myapex-file_contexts" ,
2019-10-01 13:02:42 +02:00
vndk_version : "28" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-10-01 13:02:42 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
2019-11-06 08:53:07 +01:00
} ` + vndkLibrariesTxtFiles ( "28" , "current" ) )
2019-10-01 13:02:42 +02:00
assertApexName := func ( expected , moduleName string ) {
2020-01-23 06:36:59 +01:00
bundle := ctx . ModuleForTests ( moduleName , "android_common_image" ) . Module ( ) . ( * apexBundle )
2019-10-01 13:02:42 +02:00
actual := proptools . String ( bundle . properties . Apex_name )
if ! reflect . DeepEqual ( actual , expected ) {
t . Errorf ( "Got '%v', expected '%v'" , actual , expected )
}
}
2021-04-01 14:35:20 +02:00
assertApexName ( "com.android.vndk.v29" , "com.android.vndk.current" )
2021-03-02 19:15:29 +01:00
assertApexName ( "com.android.vndk.v28" , "com.android.vndk.v28" )
2019-10-01 13:02:42 +02:00
}
2019-08-23 04:17:39 +02:00
func TestVndkApexSkipsNativeBridgeSupportedModules ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-08-23 04:17:39 +02:00
apex_vndk {
2021-03-02 19:15:29 +01:00
name : "com.android.vndk.current" ,
key : "com.android.vndk.current.key" ,
2019-11-19 18:26:02 +01:00
file_contexts : ":myapex-file_contexts" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-08-23 04:17:39 +02:00
}
apex_key {
2021-03-02 19:15:29 +01:00
name : "com.android.vndk.current.key" ,
2019-08-23 04:17:39 +02:00
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libvndk" ,
srcs : [ "mylib.cpp" ] ,
vendor_available : true ,
2020-10-29 08:49:43 +01:00
product_available : true ,
2019-08-23 04:17:39 +02:00
native_bridge_supported : true ,
host_supported : true ,
vndk : {
enabled : true ,
} ,
system_shared_libs : [ ] ,
stl : "none" ,
2021-03-02 19:15:29 +01:00
apex_available : [ "com.android.vndk.current" ] ,
2019-08-23 04:17:39 +02:00
}
2021-03-02 19:15:29 +01:00
` + vndkLibrariesTxtFiles ( "current" ) ,
withNativeBridgeEnabled )
2019-08-23 04:17:39 +02:00
2021-03-02 19:15:29 +01:00
ensureExactContents ( t , ctx , "com.android.vndk.current" , "android_common_image" , [ ] string {
2019-10-18 09:26:59 +02:00
"lib/libvndk.so" ,
"lib64/libvndk.so" ,
2020-02-27 05:31:56 +01:00
"lib/libc++.so" ,
"lib64/libc++.so" ,
2019-11-06 08:53:07 +01:00
"etc/*" ,
2019-10-18 09:26:59 +02:00
} )
2019-08-23 04:17:39 +02:00
}
func TestVndkApexDoesntSupportNativeBridgeSupported ( t * testing . T ) {
2021-03-02 19:15:29 +01:00
testApexError ( t , ` module "com.android.vndk.current" .*: native_bridge_supported: .* doesn't support native bridge binary ` , `
2019-08-23 04:17:39 +02:00
apex_vndk {
2021-03-02 19:15:29 +01:00
name : "com.android.vndk.current" ,
key : "com.android.vndk.current.key" ,
2019-11-19 18:26:02 +01:00
file_contexts : ":myapex-file_contexts" ,
2019-08-23 04:17:39 +02:00
native_bridge_supported : true ,
}
apex_key {
2021-03-02 19:15:29 +01:00
name : "com.android.vndk.current.key" ,
2019-08-23 04:17:39 +02:00
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libvndk" ,
srcs : [ "mylib.cpp" ] ,
vendor_available : true ,
2020-10-29 08:49:43 +01:00
product_available : true ,
2019-08-23 04:17:39 +02:00
native_bridge_supported : true ,
host_supported : true ,
vndk : {
enabled : true ,
} ,
system_shared_libs : [ ] ,
stl : "none" ,
}
` )
}
2019-10-18 09:26:59 +02:00
func TestVndkApexWithBinder32 ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-10-18 09:26:59 +02:00
apex_vndk {
2021-03-02 19:15:29 +01:00
name : "com.android.vndk.v27" ,
2019-10-18 09:26:59 +02:00
key : "myapex.key" ,
2019-11-19 18:26:02 +01:00
file_contexts : ":myapex-file_contexts" ,
2019-10-18 09:26:59 +02:00
vndk_version : "27" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-10-18 09:26:59 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
vndk_prebuilt_shared {
name : "libvndk27" ,
version : "27" ,
target_arch : "arm" ,
vendor_available : true ,
2020-10-29 08:49:43 +01:00
product_available : true ,
2019-10-18 09:26:59 +02:00
vndk : {
enabled : true ,
} ,
arch : {
arm : {
srcs : [ "libvndk27.so" ] ,
}
} ,
}
vndk_prebuilt_shared {
name : "libvndk27" ,
version : "27" ,
target_arch : "arm" ,
binder32bit : true ,
vendor_available : true ,
2020-10-29 08:49:43 +01:00
product_available : true ,
2019-10-18 09:26:59 +02:00
vndk : {
enabled : true ,
} ,
arch : {
arm : {
srcs : [ "libvndk27binder32.so" ] ,
}
} ,
2021-03-02 19:15:29 +01:00
apex_available : [ "com.android.vndk.v27" ] ,
2019-10-18 09:26:59 +02:00
}
2019-11-06 08:53:07 +01:00
` + vndkLibrariesTxtFiles ( "27" ) ,
2019-10-18 09:26:59 +02:00
withFiles ( map [ string ] [ ] byte {
"libvndk27.so" : nil ,
"libvndk27binder32.so" : nil ,
} ) ,
withBinder32bit ,
withTargets ( map [ android . OsType ] [ ] android . Target {
android . Android : [ ] android . Target {
2020-02-06 09:33:20 +01:00
{ Os : android . Android , Arch : android . Arch { ArchType : android . Arm , ArchVariant : "armv7-a-neon" , Abi : [ ] string { "armeabi-v7a" } } ,
NativeBridge : android . NativeBridgeDisabled , NativeBridgeHostArchName : "" , NativeBridgeRelativePath : "" } ,
2019-10-18 09:26:59 +02:00
} ,
} ) ,
)
2021-03-02 19:15:29 +01:00
ensureExactContents ( t , ctx , "com.android.vndk.v27" , "android_common_image" , [ ] string {
2019-10-18 09:26:59 +02:00
"lib/libvndk27binder32.so" ,
2019-11-06 08:53:07 +01:00
"etc/*" ,
2019-10-18 09:26:59 +02:00
} )
}
2020-06-15 07:59:42 +02:00
func TestVndkApexShouldNotProvideNativeLibs ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-06-15 07:59:42 +02:00
apex_vndk {
2021-03-02 19:15:29 +01:00
name : "com.android.vndk.current" ,
key : "com.android.vndk.current.key" ,
2020-06-15 07:59:42 +02:00
file_contexts : ":myapex-file_contexts" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-06-15 07:59:42 +02:00
}
apex_key {
2021-03-02 19:15:29 +01:00
name : "com.android.vndk.current.key" ,
2020-06-15 07:59:42 +02:00
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libz" ,
vendor_available : true ,
2020-10-29 08:49:43 +01:00
product_available : true ,
2020-06-15 07:59:42 +02:00
vndk : {
enabled : true ,
} ,
stubs : {
symbol_file : "libz.map.txt" ,
versions : [ "30" ] ,
}
}
` + vndkLibrariesTxtFiles ( "current" ) , withFiles ( map [ string ] [ ] byte {
"libz.map.txt" : nil ,
} ) )
2021-03-02 19:15:29 +01:00
apexManifestRule := ctx . ModuleForTests ( "com.android.vndk.current" , "android_common_image" ) . Rule ( "apexManifestRule" )
2020-06-15 07:59:42 +02:00
provideNativeLibs := names ( apexManifestRule . Args [ "provideNativeLibs" ] )
ensureListEmpty ( t , provideNativeLibs )
}
2019-08-01 10:41:43 +02:00
func TestDependenciesInApexManifest ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-08-01 10:41:43 +02:00
apex {
name : "myapex_nodep" ,
key : "myapex.key" ,
native_shared_libs : [ "lib_nodep" ] ,
compile_multilib : "both" ,
2019-11-19 18:26:02 +01:00
file_contexts : ":myapex-file_contexts" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-08-01 10:41:43 +02:00
}
apex {
name : "myapex_dep" ,
key : "myapex.key" ,
native_shared_libs : [ "lib_dep" ] ,
compile_multilib : "both" ,
2019-11-19 18:26:02 +01:00
file_contexts : ":myapex-file_contexts" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-08-01 10:41:43 +02:00
}
apex {
name : "myapex_provider" ,
key : "myapex.key" ,
native_shared_libs : [ "libfoo" ] ,
compile_multilib : "both" ,
2019-11-19 18:26:02 +01:00
file_contexts : ":myapex-file_contexts" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-08-01 10:41:43 +02:00
}
apex {
name : "myapex_selfcontained" ,
key : "myapex.key" ,
native_shared_libs : [ "lib_dep" , "libfoo" ] ,
compile_multilib : "both" ,
2019-11-19 18:26:02 +01:00
file_contexts : ":myapex-file_contexts" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-08-01 10:41:43 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "lib_nodep" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex_nodep" ] ,
2019-08-01 10:41:43 +02:00
}
cc_library {
name : "lib_dep" ,
srcs : [ "mylib.cpp" ] ,
shared_libs : [ "libfoo" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [
"myapex_dep" ,
"myapex_provider" ,
"myapex_selfcontained" ,
] ,
2019-08-01 10:41:43 +02:00
}
cc_library {
name : "libfoo" ,
srcs : [ "mytest.cpp" ] ,
stubs : {
versions : [ "1" ] ,
} ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [
"myapex_provider" ,
"myapex_selfcontained" ,
] ,
2019-08-01 10:41:43 +02:00
}
` )
2019-09-26 17:38:03 +02:00
var apexManifestRule android . TestingBuildParams
2019-08-01 10:41:43 +02:00
var provideNativeLibs , requireNativeLibs [ ] string
2019-10-22 06:58:29 +02:00
apexManifestRule = ctx . ModuleForTests ( "myapex_nodep" , "android_common_myapex_nodep_image" ) . Rule ( "apexManifestRule" )
2019-09-26 17:38:03 +02:00
provideNativeLibs = names ( apexManifestRule . Args [ "provideNativeLibs" ] )
requireNativeLibs = names ( apexManifestRule . Args [ "requireNativeLibs" ] )
2019-08-01 10:41:43 +02:00
ensureListEmpty ( t , provideNativeLibs )
ensureListEmpty ( t , requireNativeLibs )
2019-10-22 06:58:29 +02:00
apexManifestRule = ctx . ModuleForTests ( "myapex_dep" , "android_common_myapex_dep_image" ) . Rule ( "apexManifestRule" )
2019-09-26 17:38:03 +02:00
provideNativeLibs = names ( apexManifestRule . Args [ "provideNativeLibs" ] )
requireNativeLibs = names ( apexManifestRule . Args [ "requireNativeLibs" ] )
2019-08-01 10:41:43 +02:00
ensureListEmpty ( t , provideNativeLibs )
ensureListContains ( t , requireNativeLibs , "libfoo.so" )
2019-10-22 06:58:29 +02:00
apexManifestRule = ctx . ModuleForTests ( "myapex_provider" , "android_common_myapex_provider_image" ) . Rule ( "apexManifestRule" )
2019-09-26 17:38:03 +02:00
provideNativeLibs = names ( apexManifestRule . Args [ "provideNativeLibs" ] )
requireNativeLibs = names ( apexManifestRule . Args [ "requireNativeLibs" ] )
2019-08-01 10:41:43 +02:00
ensureListContains ( t , provideNativeLibs , "libfoo.so" )
ensureListEmpty ( t , requireNativeLibs )
2019-10-22 06:58:29 +02:00
apexManifestRule = ctx . ModuleForTests ( "myapex_selfcontained" , "android_common_myapex_selfcontained_image" ) . Rule ( "apexManifestRule" )
2019-09-26 17:38:03 +02:00
provideNativeLibs = names ( apexManifestRule . Args [ "provideNativeLibs" ] )
requireNativeLibs = names ( apexManifestRule . Args [ "requireNativeLibs" ] )
2019-08-01 10:41:43 +02:00
ensureListContains ( t , provideNativeLibs , "libfoo.so" )
ensureListEmpty ( t , requireNativeLibs )
}
2019-09-26 17:38:03 +02:00
func TestApexName ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-09-26 17:38:03 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
apex_name : "com.android.myapex" ,
2020-02-05 09:19:28 +01:00
native_shared_libs : [ "mylib" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-09-26 17:38:03 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
2020-02-05 09:19:28 +01:00
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [
"//apex_available:platform" ,
"myapex" ,
] ,
}
2019-09-26 17:38:03 +02:00
` )
2021-06-24 15:37:13 +02:00
module := ctx . ModuleForTests ( "myapex" , "android_common_com.android.myapex_image" )
2019-09-26 17:38:03 +02:00
apexManifestRule := module . Rule ( "apexManifestRule" )
ensureContains ( t , apexManifestRule . Args [ "opt" ] , "-v name com.android.myapex" )
apexRule := module . Rule ( "apexRule" )
ensureContains ( t , apexRule . Args [ "opt_flags" ] , "--do_not_check_keyname" )
2020-02-05 09:19:28 +01:00
2021-06-24 15:37:13 +02:00
apexBundle := module . Module ( ) . ( * apexBundle )
2020-07-03 22:18:24 +02:00
data := android . AndroidMkDataForTest ( t , ctx , apexBundle )
2020-02-05 09:19:28 +01:00
name := apexBundle . BaseModuleName ( )
prefix := "TARGET_"
var builder strings . Builder
data . Custom ( & builder , name , prefix , "" , data )
androidMk := builder . String ( )
ensureContains ( t , androidMk , "LOCAL_MODULE := mylib.myapex\n" )
ensureNotContains ( t , androidMk , "LOCAL_MODULE := mylib.com.android.myapex\n" )
2019-09-26 17:38:03 +02:00
}
2019-02-07 22:20:53 +01:00
func TestNonTestApex ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-02-07 22:20:53 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib_common" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-02-07 22:20:53 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib_common" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [
"//apex_available:platform" ,
"myapex" ,
] ,
2019-02-07 22:20:53 +01:00
}
` )
2019-10-22 06:58:29 +02:00
module := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" )
2019-02-07 22:20:53 +01:00
apexRule := module . Rule ( "apexRule" )
copyCmds := apexRule . Args [ "copy_commands" ]
if apex , ok := module . Module ( ) . ( * apexBundle ) ; ! ok || apex . testApex {
t . Log ( "Apex was a test apex!" )
t . Fail ( )
}
// Ensure that main rule creates an output
ensureContains ( t , apexRule . Output . String ( ) , "myapex.apex.unsigned" )
// Ensure that apex variant is created for the direct dep
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
ensureListContains ( t , ctx . ModuleVariantsForTests ( "mylib_common" ) , "android_arm64_armv8-a_shared_apex10000" )
2019-02-07 22:20:53 +01:00
// Ensure that both direct and indirect deps are copied into apex
ensureContains ( t , copyCmds , "image.apex/lib64/mylib_common.so" )
2019-11-21 01:39:12 +01:00
// Ensure that the platform variant ends with _shared
ensureListContains ( t , ctx . ModuleVariantsForTests ( "mylib_common" ) , "android_arm64_armv8-a_shared" )
2019-02-07 22:20:53 +01:00
2020-09-16 03:30:11 +02:00
if ! ctx . ModuleForTests ( "mylib_common" , "android_arm64_armv8-a_shared_apex10000" ) . Module ( ) . ( * cc . Module ) . InAnyApex ( ) {
2019-02-07 22:20:53 +01:00
t . Log ( "Found mylib_common not in any apex!" )
t . Fail ( )
}
}
func TestTestApex ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-02-07 22:20:53 +01:00
apex_test {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib_common_test" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-02-07 22:20:53 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib_common_test" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
// TODO: remove //apex_available:platform
apex_available : [
"//apex_available:platform" ,
"myapex" ,
] ,
2019-02-07 22:20:53 +01:00
}
` )
2019-10-22 06:58:29 +02:00
module := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" )
2019-02-07 22:20:53 +01:00
apexRule := module . Rule ( "apexRule" )
copyCmds := apexRule . Args [ "copy_commands" ]
if apex , ok := module . Module ( ) . ( * apexBundle ) ; ! ok || ! apex . testApex {
t . Log ( "Apex was not a test apex!" )
t . Fail ( )
}
// Ensure that main rule creates an output
ensureContains ( t , apexRule . Output . String ( ) , "myapex.apex.unsigned" )
// Ensure that apex variant is created for the direct dep
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
ensureListContains ( t , ctx . ModuleVariantsForTests ( "mylib_common_test" ) , "android_arm64_armv8-a_shared_apex10000" )
2019-02-07 22:20:53 +01:00
// Ensure that both direct and indirect deps are copied into apex
ensureContains ( t , copyCmds , "image.apex/lib64/mylib_common_test.so" )
2019-11-21 01:39:12 +01:00
// Ensure that the platform variant ends with _shared
ensureListContains ( t , ctx . ModuleVariantsForTests ( "mylib_common_test" ) , "android_arm64_armv8-a_shared" )
2019-02-07 22:20:53 +01:00
}
2019-01-30 03:07:33 +01:00
func TestApexWithTarget ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-01-30 03:07:33 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-01-30 03:07:33 +01:00
multilib : {
first : {
native_shared_libs : [ "mylib_common" ] ,
}
} ,
target : {
android : {
multilib : {
first : {
native_shared_libs : [ "mylib" ] ,
}
}
} ,
host : {
multilib : {
first : {
native_shared_libs : [ "mylib2" ] ,
}
}
}
}
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-01-10 16:12:39 +01:00
// TODO: remove //apex_available:platform
apex_available : [
"//apex_available:platform" ,
"myapex" ,
] ,
2019-01-30 03:07:33 +01:00
}
cc_library {
name : "mylib_common" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
compile_multilib : "first" ,
2020-01-10 16:12:39 +01:00
// TODO: remove //apex_available:platform
apex_available : [
"//apex_available:platform" ,
"myapex" ,
] ,
2019-01-30 03:07:33 +01:00
}
cc_library {
name : "mylib2" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
compile_multilib : "first" ,
}
` )
2019-10-22 06:58:29 +02:00
apexRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "apexRule" )
2019-01-30 03:07:33 +01:00
copyCmds := apexRule . Args [ "copy_commands" ]
// Ensure that main rule creates an output
ensureContains ( t , apexRule . Output . String ( ) , "myapex.apex.unsigned" )
// Ensure that apex variant is created for the direct dep
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
ensureListContains ( t , ctx . ModuleVariantsForTests ( "mylib" ) , "android_arm64_armv8-a_shared_apex10000" )
ensureListContains ( t , ctx . ModuleVariantsForTests ( "mylib_common" ) , "android_arm64_armv8-a_shared_apex10000" )
ensureListNotContains ( t , ctx . ModuleVariantsForTests ( "mylib2" ) , "android_arm64_armv8-a_shared_apex10000" )
2019-01-30 03:07:33 +01:00
// Ensure that both direct and indirect deps are copied into apex
ensureContains ( t , copyCmds , "image.apex/lib64/mylib.so" )
ensureContains ( t , copyCmds , "image.apex/lib64/mylib_common.so" )
ensureNotContains ( t , copyCmds , "image.apex/lib64/mylib2.so" )
2019-11-21 01:39:12 +01:00
// Ensure that the platform variant ends with _shared
ensureListContains ( t , ctx . ModuleVariantsForTests ( "mylib" ) , "android_arm64_armv8-a_shared" )
ensureListContains ( t , ctx . ModuleVariantsForTests ( "mylib_common" ) , "android_arm64_armv8-a_shared" )
ensureListContains ( t , ctx . ModuleVariantsForTests ( "mylib2" ) , "android_arm64_armv8-a_shared" )
2019-01-30 03:07:33 +01:00
}
2019-02-05 16:16:29 +01:00
2020-12-14 10:44:04 +01:00
func TestApexWithArch ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-12-14 10:44:04 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-12-14 10:44:04 +01:00
arch : {
arm64 : {
native_shared_libs : [ "mylib.arm64" ] ,
} ,
x86_64 : {
native_shared_libs : [ "mylib.x64" ] ,
} ,
}
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib.arm64" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
// TODO: remove //apex_available:platform
apex_available : [
"//apex_available:platform" ,
"myapex" ,
] ,
}
cc_library {
name : "mylib.x64" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
// TODO: remove //apex_available:platform
apex_available : [
"//apex_available:platform" ,
"myapex" ,
] ,
}
` )
apexRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "apexRule" )
copyCmds := apexRule . Args [ "copy_commands" ]
// Ensure that apex variant is created for the direct dep
ensureListContains ( t , ctx . ModuleVariantsForTests ( "mylib.arm64" ) , "android_arm64_armv8-a_shared_apex10000" )
ensureListNotContains ( t , ctx . ModuleVariantsForTests ( "mylib.x64" ) , "android_arm64_armv8-a_shared_apex10000" )
// Ensure that both direct and indirect deps are copied into apex
ensureContains ( t , copyCmds , "image.apex/lib64/mylib.arm64.so" )
ensureNotContains ( t , copyCmds , "image.apex/lib64/mylib.x64.so" )
}
2019-02-05 16:16:29 +01:00
func TestApexWithShBinary ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-02-05 16:16:29 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
binaries : [ "myscript" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-02-05 16:16:29 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
sh_binary {
name : "myscript" ,
src : "mylib.cpp" ,
filename : "myscript.sh" ,
sub_dir : "script" ,
}
` )
2019-10-22 06:58:29 +02:00
apexRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "apexRule" )
2019-02-05 16:16:29 +01:00
copyCmds := apexRule . Args [ "copy_commands" ]
ensureContains ( t , copyCmds , "image.apex/bin/script/myscript.sh" )
}
2019-03-14 18:13:21 +01:00
2019-11-19 17:49:42 +01:00
func TestApexInVariousPartition ( t * testing . T ) {
testcases := [ ] struct {
propName , parition , flattenedPartition string
} {
{ "" , "system" , "system_ext" } ,
{ "product_specific: true" , "product" , "product" } ,
{ "soc_specific: true" , "vendor" , "vendor" } ,
{ "proprietary: true" , "vendor" , "vendor" } ,
{ "vendor: true" , "vendor" , "vendor" } ,
{ "system_ext_specific: true" , "system_ext" , "system_ext" } ,
}
for _ , tc := range testcases {
t . Run ( tc . propName + ":" + tc . parition , func ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-11-19 17:49:42 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-11-19 17:49:42 +01:00
` +tc.propName+ `
}
2019-03-14 18:13:21 +01:00
2019-11-19 17:49:42 +01:00
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
` )
2019-03-14 18:13:21 +01:00
2019-11-19 17:49:42 +01:00
apex := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Module ( ) . ( * apexBundle )
2021-03-29 01:21:08 +02:00
expected := "out/soong/target/product/test_device/" + tc . parition + "/apex"
actual := apex . installDir . RelativeToTop ( ) . String ( )
2019-11-19 17:49:42 +01:00
if actual != expected {
t . Errorf ( "wrong install path. expected %q. actual %q" , expected , actual )
}
2019-03-14 18:13:21 +01:00
2019-11-19 17:49:42 +01:00
flattened := ctx . ModuleForTests ( "myapex" , "android_common_myapex_flattened" ) . Module ( ) . ( * apexBundle )
2021-03-29 01:21:08 +02:00
expected = "out/soong/target/product/test_device/" + tc . flattenedPartition + "/apex"
actual = flattened . installDir . RelativeToTop ( ) . String ( )
2019-11-19 17:49:42 +01:00
if actual != expected {
t . Errorf ( "wrong install path. expected %q. actual %q" , expected , actual )
}
} )
2019-03-14 18:13:21 +01:00
}
}
2019-03-20 17:11:21 +01:00
2020-06-24 12:33:06 +02:00
func TestFileContexts_FindInDefaultLocationIfNotSet ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-06-24 12:33:06 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-06-24 12:33:06 +02:00
}
2019-11-19 18:26:02 +01:00
2020-06-24 12:33:06 +02:00
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
2019-11-19 18:26:02 +01:00
` )
module := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" )
2020-06-24 12:33:06 +02:00
rule := module . Output ( "file_contexts" )
ensureContains ( t , rule . RuleParams . Command , "cat system/sepolicy/apex/myapex-file_contexts" )
}
2019-11-19 18:26:02 +01:00
2020-06-24 12:33:06 +02:00
func TestFileContexts_ShouldBeUnderSystemSepolicyForSystemApexes ( t * testing . T ) {
2019-11-19 18:26:02 +01:00
testApexError ( t , ` "myapex" .*: file_contexts: should be under system/sepolicy ` , `
2020-06-24 12:33:06 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
file_contexts : "my_own_file_contexts" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-06-24 12:33:06 +02:00
}
2019-11-19 18:26:02 +01:00
2020-06-24 12:33:06 +02:00
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
2019-11-19 18:26:02 +01:00
` , withFiles ( map [ string ] [ ] byte {
"my_own_file_contexts" : nil ,
} ) )
2020-06-24 12:33:06 +02:00
}
2019-11-19 18:26:02 +01:00
2020-06-24 12:33:06 +02:00
func TestFileContexts_ProductSpecificApexes ( t * testing . T ) {
2019-11-19 18:26:02 +01:00
testApexError ( t , ` "myapex" .*: file_contexts: cannot find ` , `
2020-06-24 12:33:06 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
product_specific : true ,
file_contexts : "product_specific_file_contexts" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-06-24 12:33:06 +02:00
}
2019-11-19 18:26:02 +01:00
2020-06-24 12:33:06 +02:00
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
2019-11-19 18:26:02 +01:00
` )
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-06-24 12:33:06 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
product_specific : true ,
file_contexts : "product_specific_file_contexts" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-06-24 12:33:06 +02:00
}
2019-11-19 18:26:02 +01:00
2020-06-24 12:33:06 +02:00
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
2019-11-19 18:26:02 +01:00
` , withFiles ( map [ string ] [ ] byte {
"product_specific_file_contexts" : nil ,
} ) )
2020-06-24 12:33:06 +02:00
module := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" )
rule := module . Output ( "file_contexts" )
ensureContains ( t , rule . RuleParams . Command , "cat product_specific_file_contexts" )
}
2019-11-19 18:26:02 +01:00
2020-06-24 12:33:06 +02:00
func TestFileContexts_SetViaFileGroup ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-06-24 12:33:06 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
product_specific : true ,
file_contexts : ":my-file-contexts" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-06-24 12:33:06 +02:00
}
2019-11-19 18:26:02 +01:00
2020-06-24 12:33:06 +02:00
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
2019-11-19 18:26:02 +01:00
2020-06-24 12:33:06 +02:00
filegroup {
name : "my-file-contexts" ,
srcs : [ "product_specific_file_contexts" ] ,
}
2019-11-19 18:26:02 +01:00
` , withFiles ( map [ string ] [ ] byte {
"product_specific_file_contexts" : nil ,
} ) )
2020-06-24 12:33:06 +02:00
module := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" )
rule := module . Output ( "file_contexts" )
ensureContains ( t , rule . RuleParams . Command , "cat product_specific_file_contexts" )
2019-11-19 18:26:02 +01:00
}
2019-03-20 17:11:21 +01:00
func TestApexKeyFromOtherModule ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-03-20 17:11:21 +01:00
apex_key {
name : "myapex.key" ,
public_key : ":my.avbpubkey" ,
private_key : ":my.pem" ,
product_specific : true ,
}
filegroup {
name : "my.avbpubkey" ,
srcs : [ "testkey2.avbpubkey" ] ,
}
filegroup {
name : "my.pem" ,
srcs : [ "testkey2.pem" ] ,
}
` )
apex_key := ctx . ModuleForTests ( "myapex.key" , "android_common" ) . Module ( ) . ( * apexKey )
expected_pubkey := "testkey2.avbpubkey"
2020-12-21 18:11:10 +01:00
actual_pubkey := apex_key . publicKeyFile . String ( )
2019-03-20 17:11:21 +01:00
if actual_pubkey != expected_pubkey {
t . Errorf ( "wrong public key path. expected %q. actual %q" , expected_pubkey , actual_pubkey )
}
expected_privkey := "testkey2.pem"
2020-12-21 18:11:10 +01:00
actual_privkey := apex_key . privateKeyFile . String ( )
2019-03-20 17:11:21 +01:00
if actual_privkey != expected_privkey {
t . Errorf ( "wrong private key path. expected %q. actual %q" , expected_privkey , actual_privkey )
}
}
2019-03-26 23:07:36 +01:00
func TestPrebuilt ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-03-26 23:07:36 +01:00
prebuilt_apex {
name : "myapex" ,
2019-03-29 06:23:10 +01:00
arch : {
arm64 : {
src : "myapex-arm64.apex" ,
} ,
arm : {
src : "myapex-arm.apex" ,
} ,
} ,
2019-03-26 23:07:36 +01:00
}
` )
2021-06-15 20:09:41 +02:00
prebuilt := ctx . ModuleForTests ( "myapex" , "android_common_myapex" ) . Module ( ) . ( * Prebuilt )
2019-03-26 23:07:36 +01:00
2019-03-29 06:23:10 +01:00
expectedInput := "myapex-arm64.apex"
if prebuilt . inputApex . String ( ) != expectedInput {
t . Errorf ( "inputApex invalid. expected: %q, actual: %q" , expectedInput , prebuilt . inputApex . String ( ) )
}
2019-03-26 23:07:36 +01:00
}
2019-04-04 19:09:48 +02:00
2021-03-01 18:27:16 +01:00
func TestPrebuiltMissingSrc ( t * testing . T ) {
2021-06-15 20:09:41 +02:00
testApexError ( t , ` module "myapex" variant "android_common_myapex".*: prebuilt_apex does not support "arm64_armv8-a" ` , `
2021-03-01 18:27:16 +01:00
prebuilt_apex {
name : "myapex" ,
}
` )
}
2019-04-04 19:09:48 +02:00
func TestPrebuiltFilenameOverride ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-04-04 19:09:48 +02:00
prebuilt_apex {
name : "myapex" ,
src : "myapex-arm.apex" ,
filename : "notmyapex.apex" ,
}
` )
2021-06-15 20:09:41 +02:00
p := ctx . ModuleForTests ( "myapex" , "android_common_myapex" ) . Module ( ) . ( * Prebuilt )
2019-04-04 19:09:48 +02:00
expected := "notmyapex.apex"
if p . installFilename != expected {
t . Errorf ( "installFilename invalid. expected: %q, actual: %q" , expected , p . installFilename )
}
}
2019-06-25 20:20:53 +02:00
2021-09-08 18:48:28 +02:00
func TestApexSetFilenameOverride ( t * testing . T ) {
testApex ( t , `
apex_set {
name : "com.company.android.myapex" ,
apex_name : "com.android.myapex" ,
set : "company-myapex.apks" ,
filename : "com.company.android.myapex.apex"
}
` ) . ModuleForTests ( "com.company.android.myapex" , "android_common_com.android.myapex" )
testApex ( t , `
apex_set {
name : "com.company.android.myapex" ,
apex_name : "com.android.myapex" ,
set : "company-myapex.apks" ,
filename : "com.company.android.myapex.capex"
}
` ) . ModuleForTests ( "com.company.android.myapex" , "android_common_com.android.myapex" )
testApexError ( t , ` filename should end in .apex or .capex for apex_set ` , `
apex_set {
name : "com.company.android.myapex" ,
apex_name : "com.android.myapex" ,
set : "company-myapex.apks" ,
filename : "some-random-suffix"
}
` )
}
2019-07-17 03:25:41 +02:00
func TestPrebuiltOverrides ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-07-17 03:25:41 +02:00
prebuilt_apex {
name : "myapex.prebuilt" ,
src : "myapex-arm.apex" ,
overrides : [
"myapex" ,
] ,
}
` )
2021-06-15 20:09:41 +02:00
p := ctx . ModuleForTests ( "myapex.prebuilt" , "android_common_myapex.prebuilt" ) . Module ( ) . ( * Prebuilt )
2019-07-17 03:25:41 +02:00
expected := [ ] string { "myapex" }
2020-07-03 22:18:24 +02:00
actual := android . AndroidMkEntriesForTest ( t , ctx , p ) [ 0 ] . EntryMap [ "LOCAL_OVERRIDES_MODULES" ]
2019-07-17 03:25:41 +02:00
if ! reflect . DeepEqual ( actual , expected ) {
2019-11-14 09:17:03 +01:00
t . Errorf ( "Incorrect LOCAL_OVERRIDES_MODULES value '%s', expected '%s'" , actual , expected )
2019-07-17 03:25:41 +02:00
}
}
2021-06-24 15:37:13 +02:00
func TestPrebuiltApexName ( t * testing . T ) {
testApex ( t , `
prebuilt_apex {
name : "com.company.android.myapex" ,
apex_name : "com.android.myapex" ,
src : "company-myapex-arm.apex" ,
}
` ) . ModuleForTests ( "com.company.android.myapex" , "android_common_com.android.myapex" )
testApex ( t , `
apex_set {
name : "com.company.android.myapex" ,
apex_name : "com.android.myapex" ,
set : "company-myapex.apks" ,
}
` ) . ModuleForTests ( "com.company.android.myapex" , "android_common_com.android.myapex" )
}
func TestPrebuiltApexNameWithPlatformBootclasspath ( t * testing . T ) {
_ = android . GroupFixturePreparers (
java . PrepareForTestWithJavaDefaultModules ,
PrepareForTestWithApexBuildComponents ,
android . FixtureWithRootAndroidBp ( `
platform_bootclasspath {
name : "platform-bootclasspath" ,
fragments : [
{
apex : "com.android.art" ,
module : "art-bootclasspath-fragment" ,
} ,
] ,
}
prebuilt_apex {
name : "com.company.android.art" ,
apex_name : "com.android.art" ,
src : "com.company.android.art-arm.apex" ,
exported_bootclasspath_fragments : [ "art-bootclasspath-fragment" ] ,
}
prebuilt_bootclasspath_fragment {
name : "art-bootclasspath-fragment" ,
2021-08-06 18:49:46 +02:00
image_name : "art" ,
2021-06-24 15:37:13 +02:00
contents : [ "core-oj" ] ,
2021-07-19 14:23:40 +02:00
hidden_api : {
annotation_flags : "my-bootclasspath-fragment/annotation-flags.csv" ,
metadata : "my-bootclasspath-fragment/metadata.csv" ,
index : "my-bootclasspath-fragment/index.csv" ,
stub_flags : "my-bootclasspath-fragment/stub-flags.csv" ,
all_flags : "my-bootclasspath-fragment/all-flags.csv" ,
} ,
2021-06-24 15:37:13 +02:00
}
java_import {
name : "core-oj" ,
jars : [ "prebuilt.jar" ] ,
}
` ) ,
) . RunTest ( t )
}
2021-01-26 12:42:39 +01:00
// These tests verify that the prebuilt_apex/deapexer to java_import wiring allows for the
// propagation of paths to dex implementation jars from the former to the latter.
2020-11-02 18:32:38 +01:00
func TestPrebuiltExportDexImplementationJars ( t * testing . T ) {
2021-04-12 21:02:36 +02:00
transform := android . NullFixturePreparer
2020-11-02 18:32:38 +01:00
2021-02-05 17:44:03 +01:00
checkDexJarBuildPath := func ( t * testing . T , ctx * android . TestContext , name string ) {
2021-09-15 04:34:04 +02:00
t . Helper ( )
2020-11-02 18:32:38 +01:00
// Make sure the import has been given the correct path to the dex jar.
2021-02-01 22:59:03 +01:00
p := ctx . ModuleForTests ( name , "android_common_myapex" ) . Module ( ) . ( java . UsesLibraryDependency )
2021-09-15 04:34:04 +02:00
dexJarBuildPath := p . DexJarBuildPath ( ) . PathOrNil ( )
2021-02-26 12:09:39 +01:00
stem := android . RemoveOptionalPrebuiltPrefix ( name )
2021-07-07 18:13:11 +02:00
android . AssertStringEquals ( t , "DexJarBuildPath should be apex-related path." ,
".intermediates/myapex.deapexer/android_common/deapexer/javalib/" + stem + ".jar" ,
android . NormalizePathForTesting ( dexJarBuildPath ) )
}
checkDexJarInstallPath := func ( t * testing . T , ctx * android . TestContext , name string ) {
2021-09-15 04:34:04 +02:00
t . Helper ( )
2021-07-07 18:13:11 +02:00
// Make sure the import has been given the correct path to the dex jar.
p := ctx . ModuleForTests ( name , "android_common_myapex" ) . Module ( ) . ( java . UsesLibraryDependency )
dexJarBuildPath := p . DexJarInstallPath ( )
stem := android . RemoveOptionalPrebuiltPrefix ( name )
android . AssertStringEquals ( t , "DexJarInstallPath should be apex-related path." ,
"target/product/test_device/apex/myapex/javalib/" + stem + ".jar" ,
android . NormalizePathForTesting ( dexJarBuildPath ) )
2020-11-02 18:32:38 +01:00
}
2021-02-26 12:09:39 +01:00
ensureNoSourceVariant := func ( t * testing . T , ctx * android . TestContext , name string ) {
2021-09-15 04:34:04 +02:00
t . Helper ( )
2020-11-02 18:32:38 +01:00
// Make sure that an apex variant is not created for the source module.
2021-07-07 18:13:11 +02:00
android . AssertArrayString ( t , "Check if there is no source variant" ,
[ ] string { "android_common" } ,
ctx . ModuleVariantsForTests ( name ) )
2020-11-02 18:32:38 +01:00
}
t . Run ( "prebuilt only" , func ( t * testing . T ) {
bp := `
prebuilt_apex {
name : "myapex" ,
arch : {
arm64 : {
src : "myapex-arm64.apex" ,
} ,
arm : {
src : "myapex-arm.apex" ,
} ,
} ,
2021-02-26 12:09:39 +01:00
exported_java_libs : [ "libfoo" , "libbar" ] ,
2020-11-02 18:32:38 +01:00
}
java_import {
name : "libfoo" ,
jars : [ "libfoo.jar" ] ,
}
2021-02-26 12:09:39 +01:00
java_sdk_library_import {
name : "libbar" ,
public : {
jars : [ "libbar.jar" ] ,
} ,
}
2020-11-02 18:32:38 +01:00
`
// Make sure that dexpreopt can access dex implementation files from the prebuilt.
ctx := testDexpreoptWithApexes ( t , bp , "" , transform )
2021-09-17 02:44:12 +02:00
deapexerName := deapexerModuleName ( "myapex" )
android . AssertStringEquals ( t , "APEX module name from deapexer name" , "myapex" , apexModuleName ( deapexerName ) )
2021-02-26 19:21:56 +01:00
// Make sure that the deapexer has the correct input APEX.
2021-09-17 02:44:12 +02:00
deapexer := ctx . ModuleForTests ( deapexerName , "android_common" )
2021-02-26 19:21:56 +01:00
rule := deapexer . Rule ( "deapexer" )
if expected , actual := [ ] string { "myapex-arm64.apex" } , android . NormalizePathsForTesting ( rule . Implicits ) ; ! reflect . DeepEqual ( expected , actual ) {
t . Errorf ( "expected: %q, found: %q" , expected , actual )
2021-03-01 18:09:32 +01:00
}
// Make sure that the prebuilt_apex has the correct input APEX.
2021-06-15 20:09:41 +02:00
prebuiltApex := ctx . ModuleForTests ( "myapex" , "android_common_myapex" )
2021-03-01 18:09:32 +01:00
rule = prebuiltApex . Rule ( "android/soong/android.Cp" )
if expected , actual := "myapex-arm64.apex" , android . NormalizePathForTesting ( rule . Input ) ; ! reflect . DeepEqual ( expected , actual ) {
t . Errorf ( "expected: %q, found: %q" , expected , actual )
2021-02-26 19:21:56 +01:00
}
2021-02-05 17:44:03 +01:00
checkDexJarBuildPath ( t , ctx , "libfoo" )
2021-07-07 18:13:11 +02:00
checkDexJarInstallPath ( t , ctx , "libfoo" )
2021-02-26 12:09:39 +01:00
checkDexJarBuildPath ( t , ctx , "libbar" )
2021-07-07 18:13:11 +02:00
checkDexJarInstallPath ( t , ctx , "libbar" )
2020-11-02 18:32:38 +01:00
} )
t . Run ( "prebuilt with source preferred" , func ( t * testing . T ) {
bp := `
prebuilt_apex {
name : "myapex" ,
arch : {
arm64 : {
src : "myapex-arm64.apex" ,
} ,
arm : {
src : "myapex-arm.apex" ,
} ,
} ,
2021-02-26 12:09:39 +01:00
exported_java_libs : [ "libfoo" , "libbar" ] ,
2020-11-02 18:32:38 +01:00
}
java_import {
name : "libfoo" ,
jars : [ "libfoo.jar" ] ,
}
java_library {
name : "libfoo" ,
}
2021-02-26 12:09:39 +01:00
java_sdk_library_import {
name : "libbar" ,
public : {
jars : [ "libbar.jar" ] ,
} ,
}
java_sdk_library {
name : "libbar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
unsafe_ignore_missing_latest_api : true ,
}
2020-11-02 18:32:38 +01:00
`
// Make sure that dexpreopt can access dex implementation files from the prebuilt.
ctx := testDexpreoptWithApexes ( t , bp , "" , transform )
2021-02-05 17:44:03 +01:00
checkDexJarBuildPath ( t , ctx , "prebuilt_libfoo" )
2021-07-07 18:13:11 +02:00
checkDexJarInstallPath ( t , ctx , "prebuilt_libfoo" )
2021-02-26 12:09:39 +01:00
ensureNoSourceVariant ( t , ctx , "libfoo" )
checkDexJarBuildPath ( t , ctx , "prebuilt_libbar" )
2021-07-07 18:13:11 +02:00
checkDexJarInstallPath ( t , ctx , "prebuilt_libbar" )
2021-02-26 12:09:39 +01:00
ensureNoSourceVariant ( t , ctx , "libbar" )
2020-11-02 18:32:38 +01:00
} )
t . Run ( "prebuilt preferred with source" , func ( t * testing . T ) {
bp := `
prebuilt_apex {
name : "myapex" ,
arch : {
arm64 : {
src : "myapex-arm64.apex" ,
} ,
arm : {
src : "myapex-arm.apex" ,
} ,
} ,
2021-02-26 12:09:39 +01:00
exported_java_libs : [ "libfoo" , "libbar" ] ,
2020-11-02 18:32:38 +01:00
}
java_import {
name : "libfoo" ,
2021-01-26 12:42:39 +01:00
prefer : true ,
2020-11-02 18:32:38 +01:00
jars : [ "libfoo.jar" ] ,
}
java_library {
name : "libfoo" ,
}
2021-02-26 12:09:39 +01:00
java_sdk_library_import {
name : "libbar" ,
prefer : true ,
public : {
jars : [ "libbar.jar" ] ,
} ,
}
java_sdk_library {
name : "libbar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
unsafe_ignore_missing_latest_api : true ,
}
2020-11-02 18:32:38 +01:00
`
// Make sure that dexpreopt can access dex implementation files from the prebuilt.
ctx := testDexpreoptWithApexes ( t , bp , "" , transform )
2021-02-05 17:44:03 +01:00
checkDexJarBuildPath ( t , ctx , "prebuilt_libfoo" )
2021-07-07 18:13:11 +02:00
checkDexJarInstallPath ( t , ctx , "prebuilt_libfoo" )
2021-02-26 12:09:39 +01:00
ensureNoSourceVariant ( t , ctx , "libfoo" )
checkDexJarBuildPath ( t , ctx , "prebuilt_libbar" )
2021-07-07 18:13:11 +02:00
checkDexJarInstallPath ( t , ctx , "prebuilt_libbar" )
2021-02-26 12:09:39 +01:00
ensureNoSourceVariant ( t , ctx , "libbar" )
2020-11-02 18:32:38 +01:00
} )
}
2021-01-17 22:05:12 +01:00
func TestBootDexJarsFromSourcesAndPrebuilts ( t * testing . T ) {
2021-05-14 08:52:42 +02:00
preparer := android . GroupFixturePreparers (
2021-08-06 18:49:46 +02:00
java . FixtureConfigureApexBootJars ( "myapex:libfoo" , "myapex:libbar" ) ,
2021-05-14 08:52:42 +02:00
// Make sure that the frameworks/base/Android.bp file exists as otherwise hidden API encoding
// is disabled.
android . FixtureAddTextFile ( "frameworks/base/Android.bp" , "" ) ,
)
2021-01-17 22:05:12 +01:00
2021-02-26 15:24:15 +01:00
checkBootDexJarPath := func ( t * testing . T , ctx * android . TestContext , stem string , bootDexJarPath string ) {
t . Helper ( )
2021-04-27 20:36:57 +02:00
s := ctx . ModuleForTests ( "platform-bootclasspath" , "android_common" )
2021-01-17 22:05:12 +01:00
foundLibfooJar := false
2021-02-26 15:24:15 +01:00
base := stem + ".jar"
2021-01-17 22:05:12 +01:00
for _ , output := range s . AllOutputs ( ) {
2021-02-26 15:24:15 +01:00
if filepath . Base ( output ) == base {
2021-01-17 22:05:12 +01:00
foundLibfooJar = true
buildRule := s . Output ( output )
2021-03-31 00:32:51 +02:00
android . AssertStringEquals ( t , "boot dex jar path" , bootDexJarPath , buildRule . Input . String ( ) )
2021-01-17 22:05:12 +01:00
}
}
if ! foundLibfooJar {
2021-08-26 15:07:24 +02:00
t . Errorf ( "Rule for libfoo.jar missing in dex_bootjars singleton outputs %q" , android . StringPathsRelativeToTop ( ctx . Config ( ) . SoongOutDir ( ) , s . AllOutputs ( ) ) )
2021-01-17 22:05:12 +01:00
}
}
2021-07-19 14:11:24 +02:00
checkHiddenAPIIndexFromClassesInputs := func ( t * testing . T , ctx * android . TestContext , expectedIntermediateInputs string ) {
2021-02-26 15:24:15 +01:00
t . Helper ( )
2021-04-12 18:24:36 +02:00
platformBootclasspath := ctx . ModuleForTests ( "platform-bootclasspath" , "android_common" )
2021-06-07 22:36:01 +02:00
var rule android . TestingBuildParams
rule = platformBootclasspath . Output ( "hiddenapi-monolithic/index-from-classes.csv" )
java . CheckHiddenAPIRuleInputs ( t , "intermediate index" , expectedIntermediateInputs , rule )
2021-02-03 21:06:33 +01:00
}
2021-07-19 14:11:24 +02:00
checkHiddenAPIIndexFromFlagsInputs := func ( t * testing . T , ctx * android . TestContext , expectedIntermediateInputs string ) {
t . Helper ( )
platformBootclasspath := ctx . ModuleForTests ( "platform-bootclasspath" , "android_common" )
var rule android . TestingBuildParams
rule = platformBootclasspath . Output ( "hiddenapi-index.csv" )
java . CheckHiddenAPIRuleInputs ( t , "monolithic index" , expectedIntermediateInputs , rule )
}
2021-06-16 02:42:33 +02:00
fragment := java . ApexVariantReference {
Apex : proptools . StringPtr ( "myapex" ) ,
Module : proptools . StringPtr ( "my-bootclasspath-fragment" ) ,
}
2021-01-17 22:05:12 +01:00
t . Run ( "prebuilt only" , func ( t * testing . T ) {
bp := `
prebuilt_apex {
name : "myapex" ,
arch : {
arm64 : {
src : "myapex-arm64.apex" ,
} ,
arm : {
src : "myapex-arm.apex" ,
} ,
} ,
2021-06-16 02:42:33 +02:00
exported_bootclasspath_fragments : [ "my-bootclasspath-fragment" ] ,
}
prebuilt_bootclasspath_fragment {
name : "my-bootclasspath-fragment" ,
contents : [ "libfoo" , "libbar" ] ,
apex_available : [ "myapex" ] ,
2021-07-19 14:23:40 +02:00
hidden_api : {
annotation_flags : "my-bootclasspath-fragment/annotation-flags.csv" ,
metadata : "my-bootclasspath-fragment/metadata.csv" ,
index : "my-bootclasspath-fragment/index.csv" ,
2021-08-10 17:14:16 +02:00
signature_patterns : "my-bootclasspath-fragment/signature-patterns.csv" ,
filtered_stub_flags : "my-bootclasspath-fragment/filtered-stub-flags.csv" ,
filtered_flags : "my-bootclasspath-fragment/filtered-flags.csv" ,
2021-07-19 14:23:40 +02:00
} ,
2021-01-17 22:05:12 +01:00
}
java_import {
name : "libfoo" ,
jars : [ "libfoo.jar" ] ,
apex_available : [ "myapex" ] ,
2021-08-06 18:49:46 +02:00
permitted_packages : [ "foo" ] ,
2021-01-17 22:05:12 +01:00
}
2021-02-26 15:24:15 +01:00
java_sdk_library_import {
name : "libbar" ,
public : {
jars : [ "libbar.jar" ] ,
} ,
apex_available : [ "myapex" ] ,
2021-06-16 02:42:33 +02:00
shared_library : false ,
2021-08-06 18:49:46 +02:00
permitted_packages : [ "bar" ] ,
2021-02-26 15:24:15 +01:00
}
2021-01-17 22:05:12 +01:00
`
2021-06-16 02:42:33 +02:00
ctx := testDexpreoptWithApexes ( t , bp , "" , preparer , fragment )
2021-03-31 00:32:51 +02:00
checkBootDexJarPath ( t , ctx , "libfoo" , "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar" )
checkBootDexJarPath ( t , ctx , "libbar" , "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar" )
2021-02-03 21:06:33 +01:00
2021-05-14 11:38:00 +02:00
// Verify the correct module jars contribute to the hiddenapi index file.
2021-07-19 14:23:40 +02:00
checkHiddenAPIIndexFromClassesInputs ( t , ctx , ` ` )
2021-07-19 14:11:24 +02:00
checkHiddenAPIIndexFromFlagsInputs ( t , ctx , `
2021-07-19 14:23:40 +02:00
my - bootclasspath - fragment / index . csv
2021-07-19 14:11:24 +02:00
out / soong / . intermediates / frameworks / base / boot / platform - bootclasspath / android_common / hiddenapi - monolithic / index - from - classes . csv
` )
2021-01-17 22:05:12 +01:00
} )
2021-04-06 17:00:22 +02:00
t . Run ( "apex_set only" , func ( t * testing . T ) {
bp := `
apex_set {
name : "myapex" ,
set : "myapex.apks" ,
2021-06-16 02:42:33 +02:00
exported_bootclasspath_fragments : [ "my-bootclasspath-fragment" ] ,
}
prebuilt_bootclasspath_fragment {
name : "my-bootclasspath-fragment" ,
contents : [ "libfoo" , "libbar" ] ,
apex_available : [ "myapex" ] ,
2021-07-19 14:23:40 +02:00
hidden_api : {
annotation_flags : "my-bootclasspath-fragment/annotation-flags.csv" ,
metadata : "my-bootclasspath-fragment/metadata.csv" ,
index : "my-bootclasspath-fragment/index.csv" ,
2021-08-10 17:14:16 +02:00
signature_patterns : "my-bootclasspath-fragment/signature-patterns.csv" ,
filtered_stub_flags : "my-bootclasspath-fragment/filtered-stub-flags.csv" ,
filtered_flags : "my-bootclasspath-fragment/filtered-flags.csv" ,
2021-07-19 14:23:40 +02:00
} ,
2021-04-06 17:00:22 +02:00
}
java_import {
name : "libfoo" ,
jars : [ "libfoo.jar" ] ,
apex_available : [ "myapex" ] ,
2021-08-06 18:49:46 +02:00
permitted_packages : [ "foo" ] ,
2021-04-06 17:00:22 +02:00
}
java_sdk_library_import {
name : "libbar" ,
public : {
jars : [ "libbar.jar" ] ,
} ,
apex_available : [ "myapex" ] ,
2021-06-16 02:42:33 +02:00
shared_library : false ,
2021-08-06 18:49:46 +02:00
permitted_packages : [ "bar" ] ,
2021-04-06 17:00:22 +02:00
}
`
2021-06-16 02:42:33 +02:00
ctx := testDexpreoptWithApexes ( t , bp , "" , preparer , fragment )
2021-04-06 17:00:22 +02:00
checkBootDexJarPath ( t , ctx , "libfoo" , "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar" )
checkBootDexJarPath ( t , ctx , "libbar" , "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar" )
2021-05-14 11:38:00 +02:00
// Verify the correct module jars contribute to the hiddenapi index file.
2021-07-19 14:23:40 +02:00
checkHiddenAPIIndexFromClassesInputs ( t , ctx , ` ` )
2021-07-19 14:11:24 +02:00
checkHiddenAPIIndexFromFlagsInputs ( t , ctx , `
2021-07-19 14:23:40 +02:00
my - bootclasspath - fragment / index . csv
2021-07-19 14:11:24 +02:00
out / soong / . intermediates / frameworks / base / boot / platform - bootclasspath / android_common / hiddenapi - monolithic / index - from - classes . csv
` )
2021-04-06 17:00:22 +02:00
} )
2021-01-17 22:05:12 +01:00
t . Run ( "prebuilt with source library preferred" , func ( t * testing . T ) {
bp := `
prebuilt_apex {
name : "myapex" ,
arch : {
arm64 : {
src : "myapex-arm64.apex" ,
} ,
arm : {
src : "myapex-arm.apex" ,
} ,
} ,
2021-06-16 02:42:33 +02:00
exported_bootclasspath_fragments : [ "my-bootclasspath-fragment" ] ,
}
prebuilt_bootclasspath_fragment {
name : "my-bootclasspath-fragment" ,
contents : [ "libfoo" , "libbar" ] ,
apex_available : [ "myapex" ] ,
2021-07-19 14:23:40 +02:00
hidden_api : {
annotation_flags : "my-bootclasspath-fragment/annotation-flags.csv" ,
metadata : "my-bootclasspath-fragment/metadata.csv" ,
index : "my-bootclasspath-fragment/index.csv" ,
stub_flags : "my-bootclasspath-fragment/stub-flags.csv" ,
all_flags : "my-bootclasspath-fragment/all-flags.csv" ,
} ,
2021-01-17 22:05:12 +01:00
}
java_import {
name : "libfoo" ,
jars : [ "libfoo.jar" ] ,
apex_available : [ "myapex" ] ,
}
java_library {
name : "libfoo" ,
srcs : [ "foo/bar/MyClass.java" ] ,
apex_available : [ "myapex" ] ,
}
2021-02-26 15:24:15 +01:00
java_sdk_library_import {
name : "libbar" ,
public : {
jars : [ "libbar.jar" ] ,
} ,
apex_available : [ "myapex" ] ,
2021-06-16 02:42:33 +02:00
shared_library : false ,
2021-02-26 15:24:15 +01:00
}
java_sdk_library {
name : "libbar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
unsafe_ignore_missing_latest_api : true ,
apex_available : [ "myapex" ] ,
}
2021-01-17 22:05:12 +01:00
`
// In this test the source (java_library) libfoo is active since the
// prebuilt (java_import) defaults to prefer:false. However the
// prebuilt_apex module always depends on the prebuilt, and so it doesn't
// find the dex boot jar in it. We either need to disable the source libfoo
// or make the prebuilt libfoo preferred.
2021-06-16 02:42:33 +02:00
testDexpreoptWithApexes ( t , bp , "module libfoo does not provide a dex boot jar" , preparer , fragment )
2021-08-20 21:18:16 +02:00
// dexbootjar check is skipped if AllowMissingDependencies is true
preparerAllowMissingDeps := android . GroupFixturePreparers (
preparer ,
android . PrepareForTestWithAllowMissingDependencies ,
)
testDexpreoptWithApexes ( t , bp , "" , preparerAllowMissingDeps , fragment )
2021-01-17 22:05:12 +01:00
} )
t . Run ( "prebuilt library preferred with source" , func ( t * testing . T ) {
bp := `
prebuilt_apex {
name : "myapex" ,
arch : {
arm64 : {
src : "myapex-arm64.apex" ,
} ,
arm : {
src : "myapex-arm.apex" ,
} ,
} ,
2021-06-16 02:42:33 +02:00
exported_bootclasspath_fragments : [ "my-bootclasspath-fragment" ] ,
}
prebuilt_bootclasspath_fragment {
name : "my-bootclasspath-fragment" ,
contents : [ "libfoo" , "libbar" ] ,
apex_available : [ "myapex" ] ,
2021-07-19 14:23:40 +02:00
hidden_api : {
annotation_flags : "my-bootclasspath-fragment/annotation-flags.csv" ,
metadata : "my-bootclasspath-fragment/metadata.csv" ,
index : "my-bootclasspath-fragment/index.csv" ,
2021-08-10 17:14:16 +02:00
signature_patterns : "my-bootclasspath-fragment/signature-patterns.csv" ,
filtered_stub_flags : "my-bootclasspath-fragment/filtered-stub-flags.csv" ,
filtered_flags : "my-bootclasspath-fragment/filtered-flags.csv" ,
2021-07-19 14:23:40 +02:00
} ,
2021-01-17 22:05:12 +01:00
}
java_import {
name : "libfoo" ,
prefer : true ,
jars : [ "libfoo.jar" ] ,
apex_available : [ "myapex" ] ,
2021-08-06 18:49:46 +02:00
permitted_packages : [ "foo" ] ,
2021-01-17 22:05:12 +01:00
}
java_library {
name : "libfoo" ,
srcs : [ "foo/bar/MyClass.java" ] ,
apex_available : [ "myapex" ] ,
}
2021-02-26 15:24:15 +01:00
java_sdk_library_import {
name : "libbar" ,
prefer : true ,
public : {
jars : [ "libbar.jar" ] ,
} ,
apex_available : [ "myapex" ] ,
2021-06-16 02:42:33 +02:00
shared_library : false ,
2021-08-06 18:49:46 +02:00
permitted_packages : [ "bar" ] ,
2021-02-26 15:24:15 +01:00
}
java_sdk_library {
name : "libbar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
unsafe_ignore_missing_latest_api : true ,
apex_available : [ "myapex" ] ,
}
2021-01-17 22:05:12 +01:00
`
2021-06-16 02:42:33 +02:00
ctx := testDexpreoptWithApexes ( t , bp , "" , preparer , fragment )
2021-03-31 00:32:51 +02:00
checkBootDexJarPath ( t , ctx , "libfoo" , "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar" )
checkBootDexJarPath ( t , ctx , "libbar" , "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar" )
2021-02-03 21:06:33 +01:00
2021-05-14 11:38:00 +02:00
// Verify the correct module jars contribute to the hiddenapi index file.
2021-07-19 14:23:40 +02:00
checkHiddenAPIIndexFromClassesInputs ( t , ctx , ` ` )
2021-07-19 14:11:24 +02:00
checkHiddenAPIIndexFromFlagsInputs ( t , ctx , `
2021-07-19 14:23:40 +02:00
my - bootclasspath - fragment / index . csv
2021-07-19 14:11:24 +02:00
out / soong / . intermediates / frameworks / base / boot / platform - bootclasspath / android_common / hiddenapi - monolithic / index - from - classes . csv
` )
2021-01-17 22:05:12 +01:00
} )
t . Run ( "prebuilt with source apex preferred" , func ( t * testing . T ) {
bp := `
apex {
name : "myapex" ,
key : "myapex.key" ,
2021-02-26 15:24:15 +01:00
java_libs : [ "libfoo" , "libbar" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2021-01-17 22:05:12 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
prebuilt_apex {
name : "myapex" ,
arch : {
arm64 : {
src : "myapex-arm64.apex" ,
} ,
arm : {
src : "myapex-arm.apex" ,
} ,
} ,
2021-06-16 02:42:33 +02:00
exported_bootclasspath_fragments : [ "my-bootclasspath-fragment" ] ,
}
prebuilt_bootclasspath_fragment {
name : "my-bootclasspath-fragment" ,
contents : [ "libfoo" , "libbar" ] ,
apex_available : [ "myapex" ] ,
2021-07-19 14:23:40 +02:00
hidden_api : {
annotation_flags : "my-bootclasspath-fragment/annotation-flags.csv" ,
metadata : "my-bootclasspath-fragment/metadata.csv" ,
index : "my-bootclasspath-fragment/index.csv" ,
2021-08-10 17:14:16 +02:00
signature_patterns : "my-bootclasspath-fragment/signature-patterns.csv" ,
filtered_stub_flags : "my-bootclasspath-fragment/filtered-stub-flags.csv" ,
filtered_flags : "my-bootclasspath-fragment/filtered-flags.csv" ,
2021-07-19 14:23:40 +02:00
} ,
2021-01-17 22:05:12 +01:00
}
java_import {
name : "libfoo" ,
jars : [ "libfoo.jar" ] ,
apex_available : [ "myapex" ] ,
}
java_library {
name : "libfoo" ,
srcs : [ "foo/bar/MyClass.java" ] ,
apex_available : [ "myapex" ] ,
2021-08-06 18:49:46 +02:00
permitted_packages : [ "foo" ] ,
2021-01-17 22:05:12 +01:00
}
2021-02-26 15:24:15 +01:00
java_sdk_library_import {
name : "libbar" ,
public : {
jars : [ "libbar.jar" ] ,
} ,
apex_available : [ "myapex" ] ,
2021-06-16 02:42:33 +02:00
shared_library : false ,
2021-02-26 15:24:15 +01:00
}
java_sdk_library {
name : "libbar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
unsafe_ignore_missing_latest_api : true ,
apex_available : [ "myapex" ] ,
2021-08-06 18:49:46 +02:00
permitted_packages : [ "bar" ] ,
2021-02-26 15:24:15 +01:00
}
2021-01-17 22:05:12 +01:00
`
2021-06-16 02:42:33 +02:00
ctx := testDexpreoptWithApexes ( t , bp , "" , preparer , fragment )
2021-03-31 00:32:51 +02:00
checkBootDexJarPath ( t , ctx , "libfoo" , "out/soong/.intermediates/libfoo/android_common_apex10000/hiddenapi/libfoo.jar" )
checkBootDexJarPath ( t , ctx , "libbar" , "out/soong/.intermediates/libbar/android_common_myapex/hiddenapi/libbar.jar" )
2021-02-03 21:06:33 +01:00
2021-05-14 11:38:00 +02:00
// Verify the correct module jars contribute to the hiddenapi index file.
2021-07-19 14:23:40 +02:00
checkHiddenAPIIndexFromClassesInputs ( t , ctx , ` ` )
2021-07-19 14:11:24 +02:00
checkHiddenAPIIndexFromFlagsInputs ( t , ctx , `
2021-07-19 14:23:40 +02:00
my - bootclasspath - fragment / index . csv
2021-07-19 14:11:24 +02:00
out / soong / . intermediates / frameworks / base / boot / platform - bootclasspath / android_common / hiddenapi - monolithic / index - from - classes . csv
` )
2021-01-17 22:05:12 +01:00
} )
t . Run ( "prebuilt preferred with source apex disabled" , func ( t * testing . T ) {
bp := `
apex {
name : "myapex" ,
enabled : false ,
key : "myapex.key" ,
2021-04-12 18:24:18 +02:00
java_libs : [ "libfoo" , "libbar" ] ,
2021-01-17 22:05:12 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
prebuilt_apex {
name : "myapex" ,
arch : {
arm64 : {
src : "myapex-arm64.apex" ,
} ,
arm : {
src : "myapex-arm.apex" ,
} ,
} ,
2021-06-16 02:42:33 +02:00
exported_bootclasspath_fragments : [ "my-bootclasspath-fragment" ] ,
}
prebuilt_bootclasspath_fragment {
name : "my-bootclasspath-fragment" ,
contents : [ "libfoo" , "libbar" ] ,
apex_available : [ "myapex" ] ,
2021-07-19 14:23:40 +02:00
hidden_api : {
annotation_flags : "my-bootclasspath-fragment/annotation-flags.csv" ,
metadata : "my-bootclasspath-fragment/metadata.csv" ,
index : "my-bootclasspath-fragment/index.csv" ,
2021-08-10 17:14:16 +02:00
signature_patterns : "my-bootclasspath-fragment/signature-patterns.csv" ,
filtered_stub_flags : "my-bootclasspath-fragment/filtered-stub-flags.csv" ,
filtered_flags : "my-bootclasspath-fragment/filtered-flags.csv" ,
2021-07-19 14:23:40 +02:00
} ,
2021-01-17 22:05:12 +01:00
}
java_import {
name : "libfoo" ,
prefer : true ,
jars : [ "libfoo.jar" ] ,
apex_available : [ "myapex" ] ,
2021-08-06 18:49:46 +02:00
permitted_packages : [ "foo" ] ,
2021-01-17 22:05:12 +01:00
}
java_library {
name : "libfoo" ,
srcs : [ "foo/bar/MyClass.java" ] ,
apex_available : [ "myapex" ] ,
}
2021-02-26 15:24:15 +01:00
java_sdk_library_import {
name : "libbar" ,
prefer : true ,
public : {
jars : [ "libbar.jar" ] ,
} ,
apex_available : [ "myapex" ] ,
2021-06-16 02:42:33 +02:00
shared_library : false ,
2021-08-06 18:49:46 +02:00
permitted_packages : [ "bar" ] ,
2021-02-26 15:24:15 +01:00
}
java_sdk_library {
name : "libbar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
unsafe_ignore_missing_latest_api : true ,
apex_available : [ "myapex" ] ,
}
2021-01-17 22:05:12 +01:00
`
2021-06-16 02:42:33 +02:00
ctx := testDexpreoptWithApexes ( t , bp , "" , preparer , fragment )
2021-03-31 00:32:51 +02:00
checkBootDexJarPath ( t , ctx , "libfoo" , "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libfoo.jar" )
checkBootDexJarPath ( t , ctx , "libbar" , "out/soong/.intermediates/myapex.deapexer/android_common/deapexer/javalib/libbar.jar" )
2021-02-03 21:06:33 +01:00
2021-05-14 11:38:00 +02:00
// Verify the correct module jars contribute to the hiddenapi index file.
2021-07-19 14:23:40 +02:00
checkHiddenAPIIndexFromClassesInputs ( t , ctx , ` ` )
2021-07-19 14:11:24 +02:00
checkHiddenAPIIndexFromFlagsInputs ( t , ctx , `
2021-07-19 14:23:40 +02:00
my - bootclasspath - fragment / index . csv
2021-07-19 14:11:24 +02:00
out / soong / . intermediates / frameworks / base / boot / platform - bootclasspath / android_common / hiddenapi - monolithic / index - from - classes . csv
` )
2021-01-17 22:05:12 +01:00
} )
}
2019-06-26 13:48:34 +02:00
func TestApexWithTests ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-06-26 13:48:34 +02:00
apex_test {
name : "myapex" ,
key : "myapex.key" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-06-26 13:48:34 +02:00
tests : [
"mytest" ,
2019-06-28 16:41:19 +02:00
"mytests" ,
2019-06-26 13:48:34 +02:00
] ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
2020-05-13 00:26:55 +02:00
filegroup {
name : "fg" ,
srcs : [
"baz" ,
"bar/baz"
] ,
}
2019-06-26 13:48:34 +02:00
cc_test {
name : "mytest" ,
gtest : false ,
srcs : [ "mytest.cpp" ] ,
relative_install_path : "test" ,
2020-05-04 03:31:32 +02:00
shared_libs : [ "mylib" ] ,
2019-06-26 13:48:34 +02:00
system_shared_libs : [ ] ,
static_executable : true ,
stl : "none" ,
2020-05-13 00:26:55 +02:00
data : [ ":fg" ] ,
2019-06-26 13:48:34 +02:00
}
2019-06-28 16:41:19 +02:00
2020-05-04 03:31:32 +02:00
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
}
2020-05-28 00:15:11 +02:00
filegroup {
name : "fg2" ,
srcs : [
"testdata/baz"
] ,
}
2019-06-28 16:41:19 +02:00
cc_test {
name : "mytests" ,
gtest : false ,
srcs : [
"mytest1.cpp" ,
"mytest2.cpp" ,
"mytest3.cpp" ,
] ,
test_per_src : true ,
relative_install_path : "test" ,
system_shared_libs : [ ] ,
static_executable : true ,
stl : "none" ,
2020-05-28 00:15:11 +02:00
data : [
":fg" ,
":fg2" ,
] ,
2019-06-28 16:41:19 +02:00
}
2019-06-26 13:48:34 +02:00
` )
2019-10-22 06:58:29 +02:00
apexRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "apexRule" )
2019-06-26 13:48:34 +02:00
copyCmds := apexRule . Args [ "copy_commands" ]
2020-05-04 03:31:32 +02:00
// Ensure that test dep (and their transitive dependencies) are copied into apex.
2019-06-26 13:48:34 +02:00
ensureContains ( t , copyCmds , "image.apex/bin/test/mytest" )
2020-05-04 03:31:32 +02:00
ensureContains ( t , copyCmds , "image.apex/lib64/mylib.so" )
2019-06-28 16:41:19 +02:00
2020-05-13 00:26:55 +02:00
//Ensure that test data are copied into apex.
ensureContains ( t , copyCmds , "image.apex/bin/test/baz" )
ensureContains ( t , copyCmds , "image.apex/bin/test/bar/baz" )
2019-06-28 16:41:19 +02:00
// Ensure that test deps built with `test_per_src` are copied into apex.
ensureContains ( t , copyCmds , "image.apex/bin/test/mytest1" )
ensureContains ( t , copyCmds , "image.apex/bin/test/mytest2" )
ensureContains ( t , copyCmds , "image.apex/bin/test/mytest3" )
2019-07-29 17:22:59 +02:00
// Ensure the module is correctly translated.
2020-05-20 18:57:08 +02:00
bundle := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Module ( ) . ( * apexBundle )
2020-07-03 22:18:24 +02:00
data := android . AndroidMkDataForTest ( t , ctx , bundle )
2020-05-20 18:57:08 +02:00
name := bundle . BaseModuleName ( )
2019-07-29 17:22:59 +02:00
prefix := "TARGET_"
var builder strings . Builder
data . Custom ( & builder , name , prefix , "" , data )
androidMk := builder . String ( )
2019-10-18 09:26:59 +02:00
ensureContains ( t , androidMk , "LOCAL_MODULE := mytest.myapex\n" )
ensureContains ( t , androidMk , "LOCAL_MODULE := mytest1.myapex\n" )
ensureContains ( t , androidMk , "LOCAL_MODULE := mytest2.myapex\n" )
ensureContains ( t , androidMk , "LOCAL_MODULE := mytest3.myapex\n" )
2019-11-12 05:03:50 +01:00
ensureContains ( t , androidMk , "LOCAL_MODULE := apex_manifest.pb.myapex\n" )
2019-10-18 09:26:59 +02:00
ensureContains ( t , androidMk , "LOCAL_MODULE := apex_pubkey.myapex\n" )
2019-07-29 17:22:59 +02:00
ensureContains ( t , androidMk , "LOCAL_MODULE := myapex\n" )
2020-05-20 18:57:08 +02:00
flatBundle := ctx . ModuleForTests ( "myapex" , "android_common_myapex_flattened" ) . Module ( ) . ( * apexBundle )
2020-07-03 22:18:24 +02:00
data = android . AndroidMkDataForTest ( t , ctx , flatBundle )
2020-05-20 18:57:08 +02:00
data . Custom ( & builder , name , prefix , "" , data )
flatAndroidMk := builder . String ( )
2020-05-28 00:15:11 +02:00
ensureContainsOnce ( t , flatAndroidMk , "LOCAL_TEST_DATA := :baz :bar/baz\n" )
ensureContainsOnce ( t , flatAndroidMk , "LOCAL_TEST_DATA := :testdata/baz\n" )
2019-06-26 13:48:34 +02:00
}
2019-12-05 08:27:44 +01:00
func TestInstallExtraFlattenedApexes ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-12-05 08:27:44 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-12-05 08:27:44 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
2021-03-08 12:28:25 +01:00
` ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . InstallExtraFlattenedApexes = proptools . BoolPtr ( true )
} ) ,
)
2019-12-05 08:27:44 +01:00
ab := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Module ( ) . ( * apexBundle )
2020-01-14 10:38:44 +01:00
ensureListContains ( t , ab . requiredDeps , "myapex.flattened" )
2020-07-03 22:18:24 +02:00
mk := android . AndroidMkDataForTest ( t , ctx , ab )
2019-12-05 08:27:44 +01:00
var builder strings . Builder
mk . Custom ( & builder , ab . Name ( ) , "TARGET_" , "" , mk )
androidMk := builder . String ( )
ensureContains ( t , androidMk , "LOCAL_REQUIRED_MODULES += myapex.flattened" )
}
2019-08-23 04:18:57 +02:00
func TestErrorsIfDepsAreNotEnabled ( t * testing . T ) {
testApexError ( t , ` module "myapex" .* depends on disabled module "libfoo" ` , `
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libfoo" ] ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libfoo" ,
stl : "none" ,
system_shared_libs : [ ] ,
enabled : false ,
2020-03-09 22:23:13 +01:00
apex_available : [ "myapex" ] ,
2019-08-23 04:18:57 +02:00
}
` )
testApexError ( t , ` module "myapex" .* depends on disabled module "myjar" ` , `
apex {
name : "myapex" ,
key : "myapex.key" ,
java_libs : [ "myjar" ] ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
java_library {
name : "myjar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
sdk_version : "none" ,
system_modules : "none" ,
enabled : false ,
2020-03-09 22:23:13 +01:00
apex_available : [ "myapex" ] ,
2019-08-23 04:18:57 +02:00
}
` )
}
2021-01-11 19:58:54 +01:00
func TestApexWithJavaImport ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2021-01-11 19:58:54 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
java_libs : [ "myjavaimport" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2021-01-11 19:58:54 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
java_import {
name : "myjavaimport" ,
apex_available : [ "myapex" ] ,
jars : [ "my.jar" ] ,
compile_dex : true ,
}
` )
module := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" )
apexRule := module . Rule ( "apexRule" )
copyCmds := apexRule . Args [ "copy_commands" ]
ensureContains ( t , copyCmds , "image.apex/javalib/myjavaimport.jar" )
}
2019-08-27 06:55:42 +02:00
func TestApexWithApps ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-08-27 06:55:42 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
apps : [
"AppFoo" ,
2019-10-17 05:54:30 +02:00
"AppFooPriv" ,
2019-08-27 06:55:42 +02:00
] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-08-27 06:55:42 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
android_app {
name : "AppFoo" ,
srcs : [ "foo/bar/MyClass.java" ] ,
2020-02-15 19:38:00 +01:00
sdk_version : "current" ,
2019-08-27 06:55:42 +02:00
system_modules : "none" ,
2019-11-08 07:53:48 +01:00
jni_libs : [ "libjni" ] ,
2020-02-15 19:38:00 +01:00
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
2019-08-27 06:55:42 +02:00
}
2019-10-17 05:54:30 +02:00
android_app {
name : "AppFooPriv" ,
srcs : [ "foo/bar/MyClass.java" ] ,
2020-02-15 19:38:00 +01:00
sdk_version : "current" ,
2019-10-17 05:54:30 +02:00
system_modules : "none" ,
privileged : true ,
2020-02-15 19:38:00 +01:00
stl : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
2019-10-17 05:54:30 +02:00
}
2019-11-08 07:53:48 +01:00
cc_library_shared {
name : "libjni" ,
srcs : [ "mylib.cpp" ] ,
2020-02-25 08:59:29 +01:00
shared_libs : [ "libfoo" ] ,
stl : "none" ,
system_shared_libs : [ ] ,
apex_available : [ "myapex" ] ,
sdk_version : "current" ,
}
cc_library_shared {
name : "libfoo" ,
2019-11-08 07:53:48 +01:00
stl : "none" ,
system_shared_libs : [ ] ,
apex_available tracks static dependencies
This change fixes a bug that apex_available is not enforced for static
dependencies. For example, a module with 'apex_available:
["//apex_available:platform"]' was able to be statically linked to any
APEX. This was happening because the check was done on the modules that
are actually installed to an APEX. Static dependencies of the modules
were not counted as they are not installed to the APEX as files.
Fixing this bug by doing the check by traversing the tree in the method
checkApexAvailability.
This change includes a few number of related changes:
1) DepIsInSameApex implementation for cc.Module was changed as well.
Previuosly, it returned false only when the dependency is actually a
stub variant of a lib. Now, it returns false when the dependency has one
or more stub variants. To understand why, we need to recall that when
there is a dependency to a lib having stubs, we actually create two
dependencies: to the non-stub variant and to the stub variant during the
DepsMutator phase. And later in the build action generation phase, we
choose one of them depending on the context. Also recall that an APEX
variant is created only when DepIsInSameApex returns true. Given these,
with the previous implementatin of DepIsInSameApex, we did create apex
variants of the non-stub variant of the dependency, while not creating
the apex variant for the stub variant. This is not right; we needlessly
created the apex variant. The extra apex variant has caused no harm so
far, but since the apex_available check became more correct, it actually
breaks the build. To fix the issue, we stop creating the APEX variant
both for non-stub and stub variants.
2) platform variant is created regardless of the apex_available value.
This is required for the case when a library X that provides stub is in
an APEX A and is configured to be available only for A. In that case,
libs in other APEX can't use the stub library since the stub library is
mutated only for apex A. By creating the platform variant for the stub
library, it can be used from outside as the default dependency variation
is set to the platform variant when creating the APEX variations.
3) The ApexAvailableWhitelist is added with the dependencies that were
revealed with this change.
Exempt-From-Owner-Approval: cherry-pick from internal
Bug: 147671264
Test: m
Merged-In: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
(cherry picked from commit fa89944c79f19552e906b41fd03a4981903eee7e)
Change-Id: Iaedc05494085ff4e8af227a6392bdd0c338b8e6e
2020-01-30 18:49:53 +01:00
apex_available : [ "myapex" ] ,
2020-02-15 19:38:00 +01:00
sdk_version : "current" ,
2019-11-08 07:53:48 +01:00
}
2019-08-27 06:55:42 +02:00
` )
2019-10-22 06:58:29 +02:00
module := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" )
2019-08-27 06:55:42 +02:00
apexRule := module . Rule ( "apexRule" )
copyCmds := apexRule . Args [ "copy_commands" ]
ensureContains ( t , copyCmds , "image.apex/app/AppFoo/AppFoo.apk" )
2019-10-17 05:54:30 +02:00
ensureContains ( t , copyCmds , "image.apex/priv-app/AppFooPriv/AppFooPriv.apk" )
2019-11-11 02:14:32 +01:00
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
appZipRule := ctx . ModuleForTests ( "AppFoo" , "android_common_apex10000" ) . Description ( "zip jni libs" )
2020-02-25 08:59:29 +01:00
// JNI libraries are uncompressed
2019-11-11 02:14:32 +01:00
if args := appZipRule . Args [ "jarArgs" ] ; ! strings . Contains ( args , "-L 0" ) {
2020-02-25 08:59:29 +01:00
t . Errorf ( "jni libs are not uncompressed for AppFoo" )
}
// JNI libraries including transitive deps are
for _ , jni := range [ ] string { "libjni" , "libfoo" } {
2021-03-30 20:44:07 +02:00
jniOutput := ctx . ModuleForTests ( jni , "android_arm64_armv8-a_sdk_shared_apex10000" ) . Module ( ) . ( * cc . Module ) . OutputFile ( ) . RelativeToTop ( )
2020-02-25 08:59:29 +01:00
// ... embedded inside APK (jnilibs.zip)
ensureListContains ( t , appZipRule . Implicits . Strings ( ) , jniOutput . String ( ) )
// ... and not directly inside the APEX
ensureNotContains ( t , copyCmds , "image.apex/lib64/" + jni + ".so" )
2019-11-11 02:14:32 +01:00
}
2019-10-27 01:29:22 +02:00
}
func TestApexWithAppImports ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-10-27 01:29:22 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
apps : [
"AppFooPrebuilt" ,
"AppFooPrivPrebuilt" ,
] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-10-27 01:29:22 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
android_app_import {
name : "AppFooPrebuilt" ,
apk : "PrebuiltAppFoo.apk" ,
presigned : true ,
dex_preopt : {
enabled : false ,
} ,
2020-04-21 15:34:28 +02:00
apex_available : [ "myapex" ] ,
2019-10-27 01:29:22 +02:00
}
android_app_import {
name : "AppFooPrivPrebuilt" ,
apk : "PrebuiltAppFooPriv.apk" ,
privileged : true ,
presigned : true ,
dex_preopt : {
enabled : false ,
} ,
2020-03-23 12:21:11 +01:00
filename : "AwesomePrebuiltAppFooPriv.apk" ,
2020-04-21 15:34:28 +02:00
apex_available : [ "myapex" ] ,
2019-10-27 01:29:22 +02:00
}
` )
2019-10-22 06:58:29 +02:00
module := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" )
2019-10-27 01:29:22 +02:00
apexRule := module . Rule ( "apexRule" )
copyCmds := apexRule . Args [ "copy_commands" ]
2019-08-27 06:55:42 +02:00
2019-10-27 01:29:22 +02:00
ensureContains ( t , copyCmds , "image.apex/app/AppFooPrebuilt/AppFooPrebuilt.apk" )
2020-03-23 12:21:11 +01:00
ensureContains ( t , copyCmds , "image.apex/priv-app/AppFooPrivPrebuilt/AwesomePrebuiltAppFooPriv.apk" )
}
func TestApexWithAppImportsPrefer ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-03-23 12:21:11 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
apps : [
"AppFoo" ,
] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-03-23 12:21:11 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
android_app {
name : "AppFoo" ,
srcs : [ "foo/bar/MyClass.java" ] ,
sdk_version : "none" ,
system_modules : "none" ,
apex_available : [ "myapex" ] ,
}
android_app_import {
name : "AppFoo" ,
apk : "AppFooPrebuilt.apk" ,
filename : "AppFooPrebuilt.apk" ,
presigned : true ,
prefer : true ,
2020-04-21 15:34:28 +02:00
apex_available : [ "myapex" ] ,
2020-03-23 12:21:11 +01:00
}
` , withFiles ( map [ string ] [ ] byte {
"AppFooPrebuilt.apk" : nil ,
} ) )
ensureExactContents ( t , ctx , "myapex" , "android_common_myapex_image" , [ ] string {
2021-03-08 05:11:48 +01:00
"app/AppFoo/AppFooPrebuilt.apk" ,
2020-03-23 12:21:11 +01:00
} )
2019-08-27 06:55:42 +02:00
}
2019-12-20 23:58:03 +01:00
func TestApexWithTestHelperApp ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-12-20 23:58:03 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
apps : [
"TesterHelpAppFoo" ,
] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-12-20 23:58:03 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
android_test_helper_app {
name : "TesterHelpAppFoo" ,
srcs : [ "foo/bar/MyClass.java" ] ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
2019-12-20 23:58:03 +01:00
}
` )
module := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" )
apexRule := module . Rule ( "apexRule" )
copyCmds := apexRule . Args [ "copy_commands" ]
ensureContains ( t , copyCmds , "image.apex/app/TesterHelpAppFoo/TesterHelpAppFoo.apk" )
}
2019-11-13 02:50:48 +01:00
func TestApexPropertiesShouldBeDefaultable ( t * testing . T ) {
// libfoo's apex_available comes from cc_defaults
2020-10-22 03:08:35 +02:00
testApexError ( t , ` requires "libfoo" that doesn't list the APEX under 'apex_available'. ` , `
2019-11-13 02:50:48 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libfoo" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-11-13 02:50:48 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
apex {
name : "otherapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libfoo" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-11-13 02:50:48 +01:00
}
cc_defaults {
name : "libfoo-defaults" ,
apex_available : [ "otherapex" ] ,
}
cc_library {
name : "libfoo" ,
defaults : [ "libfoo-defaults" ] ,
stl : "none" ,
system_shared_libs : [ ] ,
} ` )
}
2020-03-30 18:54:29 +02:00
func TestApexAvailable_DirectDep ( t * testing . T ) {
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
// libfoo is not available to myapex, but only to otherapex
2020-10-22 03:08:35 +02:00
testApexError ( t , "requires \"libfoo\" that doesn't list the APEX under 'apex_available'." , `
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libfoo" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
apex {
name : "otherapex" ,
key : "otherapex.key" ,
native_shared_libs : [ "libfoo" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
}
apex_key {
name : "otherapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libfoo" ,
stl : "none" ,
system_shared_libs : [ ] ,
apex_available : [ "otherapex" ] ,
} ` )
2020-03-30 18:54:29 +02:00
}
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
2020-03-30 18:54:29 +02:00
func TestApexAvailable_IndirectDep ( t * testing . T ) {
2020-03-09 22:23:13 +01:00
// libbbaz is an indirect dep
Friendly error message on apex_available and min_sdk_version checks
1) suggest a fix at the end of the message
2) add new lines around the dependency path so that they are visually
separated from rest of the error message
Bug: N/A
Test: m with an intentional break
error: bionic/apex/Android.bp:32:1: module "com.android.runtime" variant "android_common_com.android.runtime_image": "libutils_headers" requires "libsystem_headers" that doesn't list the APEX under 'apex_available'.
Dependency path:
via tag apex.dependencyTag: { name:executable payload:true}
-> crash_dump{os:android,image:,arch:arm_armv8-a,sdk:,apex:apex10000}
via tag cc.libraryDependencyTag: { Kind:staticLibraryDependency Order:normalLibraryDependency wholeStatic:false reexportFlags:false explicitlyVersioned:false dataLib:false ndk:false staticUnwinder:false makeSuffix: skipApexAllowedDependenciesCheck:false excludeInApex:false}
-> libtombstoned_client_static{os:android,image:,arch:arm_armv8-a,sdk:,link:static,apex:apex10000}
via tag cc.libraryDependencyTag: { Kind:staticLibraryDependency Order:normalLibraryDependency wholeStatic:true reexportFlags:true explicitlyVersioned:false dataLib:false ndk:false staticUnwinder:false makeSuffix: skipApexAllowedDependenciesCheck:false excludeInApex:false}
-> libcutils{os:android,image:,arch:arm_armv8-a,sdk:,link:static,asan:,apex:apex10000}
via tag cc.libraryDependencyTag: { Kind:headerLibraryDependency Order:normalLibraryDependency wholeStatic:false reexportFlags:false explicitlyVersioned:false dataLib:false ndk:false staticUnwinder:false makeSuffix: skipApexAllowedDependenciesCheck:false excludeInApex:false}
-> libutils_headers{os:android,image:,arch:arm_armv8-a,sdk:,asan:,apex:apex10000}
via tag cc.libraryDependencyTag: { Kind:headerLibraryDependency Order:normalLibraryDependency wholeStatic:false reexportFlags:true explicitlyVersioned:false dataLib:false ndk:false staticUnwinder:false makeSuffix: skipApexAllowedDependenciesCheck:false excludeInApex:false}
-> libsystem_headers{os:android,image:,arch:arm_armv8-a,sdk:,asan:,apex:apex10000}
Consider adding "com.android.runtime" to 'apex_available' property of "libsystem_headers"
Change-Id: I09f92c3086ea433780133a33ba0ad73baee6dc41
2021-03-04 05:03:10 +01:00
testApexError ( t , ` requires "libbaz" that doesn ' t list the APEX under ' apex_available ' . \ n \ nDependency path :
2020-07-28 06:26:48 +02:00
. * via tag apex \ . dependencyTag . * name : sharedLib . *
2020-03-30 18:58:21 +02:00
. * - > libfoo . * link : shared . *
2020-07-28 06:26:48 +02:00
. * via tag cc \ . libraryDependencyTag . * Kind : sharedLibraryDependency . *
2020-03-30 18:58:21 +02:00
. * - > libbar . * link : shared . *
2020-07-28 06:26:48 +02:00
. * via tag cc \ . libraryDependencyTag . * Kind : sharedLibraryDependency . *
2020-03-31 16:23:40 +02:00
. * - > libbaz . * link : shared . * ` , `
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libfoo" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libfoo" ,
stl : "none" ,
shared_libs : [ "libbar" ] ,
system_shared_libs : [ ] ,
2020-03-09 22:23:13 +01:00
apex_available : [ "myapex" ] ,
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
}
cc_library {
name : "libbar" ,
stl : "none" ,
2020-03-09 22:23:13 +01:00
shared_libs : [ "libbaz" ] ,
system_shared_libs : [ ] ,
apex_available : [ "myapex" ] ,
}
cc_library {
name : "libbaz" ,
stl : "none" ,
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
system_shared_libs : [ ] ,
} ` )
2020-03-30 18:54:29 +02:00
}
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
2020-03-30 18:54:29 +02:00
func TestApexAvailable_InvalidApexName ( t * testing . T ) {
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
testApexError ( t , "\"otherapex\" is not a valid module name" , `
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libfoo" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libfoo" ,
stl : "none" ,
system_shared_libs : [ ] ,
apex_available : [ "otherapex" ] ,
} ` )
2020-03-30 18:54:29 +02:00
testApex ( t , `
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libfoo" , "libbar" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libfoo" ,
stl : "none" ,
system_shared_libs : [ ] ,
2020-03-01 09:29:06 +01:00
runtime_libs : [ "libbaz" ] ,
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
apex_available : [ "myapex" ] ,
}
cc_library {
name : "libbar" ,
stl : "none" ,
system_shared_libs : [ ] ,
apex_available : [ "//apex_available:anyapex" ] ,
2020-03-01 09:29:06 +01:00
}
cc_library {
name : "libbaz" ,
stl : "none" ,
system_shared_libs : [ ] ,
stubs : {
versions : [ "10" , "20" , "30" ] ,
} ,
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
} ` )
2020-03-30 18:54:29 +02:00
}
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
mark platform un-availability
A module is marked unavailable for platform when 1) it does not have
"//apex_available:platform" in its apex_available property, or 2)
it depends on another module that is unavailable for platform.
In that case, LOCAL_NOT_AVAILABLE_FOR_PLATFORM is set to true for the
module in the Make world. Later, that flag is used to ensure that there
is no module with the flag is installed to the device.
The reason why this isn't entirely done in Soong is because Soong
doesn't know if a module will be installed to the device or not. To
explain this, let's have an example.
cc_test { name: "mytest", static_libs: ["libfoo"]}
cc_library_static { name: "libfoo", static_libs: ["libbar"]}
cc_library { name: "libbar", apex_available: ["com.android.xxx"]}
Here, libbar is not available for platform, but is used by libfoo which
is available for platform (apex_available defaults to
"//apex_available:platform"). libfoo is again depended on by mytest
which again is available for platform. The use of libbar should be
allowed in the context of test; we don't want to make libbar available
to platform just for the dependency from test because it will allow
non-test uses of the library as well.
Soong by itself can't tell whether libfoo and libbar are used only in the
context of a test. There could be another module depending them, e.g.,
cc_library_shared { name: "mylib", static_libs: ["libfoo"] }
can exist and it might be installed to the device, in which case
we really should trigger an error.
Since Make has the knowledge of what's installed and what's not,
the check should be done there.
Bug: 153073816
Test: m
Test: remove "//apex_available:platform" from libmdnssd (it is currently
installed to /system/lib), and check that `m system_image` fails
Change-Id: Ia304cc5f41f173229e8a154e90cea4dce46dcebe
2020-04-07 09:37:39 +02:00
func TestApexAvailable_CheckForPlatform ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
mark platform un-availability
A module is marked unavailable for platform when 1) it does not have
"//apex_available:platform" in its apex_available property, or 2)
it depends on another module that is unavailable for platform.
In that case, LOCAL_NOT_AVAILABLE_FOR_PLATFORM is set to true for the
module in the Make world. Later, that flag is used to ensure that there
is no module with the flag is installed to the device.
The reason why this isn't entirely done in Soong is because Soong
doesn't know if a module will be installed to the device or not. To
explain this, let's have an example.
cc_test { name: "mytest", static_libs: ["libfoo"]}
cc_library_static { name: "libfoo", static_libs: ["libbar"]}
cc_library { name: "libbar", apex_available: ["com.android.xxx"]}
Here, libbar is not available for platform, but is used by libfoo which
is available for platform (apex_available defaults to
"//apex_available:platform"). libfoo is again depended on by mytest
which again is available for platform. The use of libbar should be
allowed in the context of test; we don't want to make libbar available
to platform just for the dependency from test because it will allow
non-test uses of the library as well.
Soong by itself can't tell whether libfoo and libbar are used only in the
context of a test. There could be another module depending them, e.g.,
cc_library_shared { name: "mylib", static_libs: ["libfoo"] }
can exist and it might be installed to the device, in which case
we really should trigger an error.
Since Make has the knowledge of what's installed and what's not,
the check should be done there.
Bug: 153073816
Test: m
Test: remove "//apex_available:platform" from libmdnssd (it is currently
installed to /system/lib), and check that `m system_image` fails
Change-Id: Ia304cc5f41f173229e8a154e90cea4dce46dcebe
2020-04-07 09:37:39 +02:00
native_shared_libs : [ "libbar" , "libbaz" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libfoo" ,
stl : "none" ,
system_shared_libs : [ ] ,
mark platform un-availability
A module is marked unavailable for platform when 1) it does not have
"//apex_available:platform" in its apex_available property, or 2)
it depends on another module that is unavailable for platform.
In that case, LOCAL_NOT_AVAILABLE_FOR_PLATFORM is set to true for the
module in the Make world. Later, that flag is used to ensure that there
is no module with the flag is installed to the device.
The reason why this isn't entirely done in Soong is because Soong
doesn't know if a module will be installed to the device or not. To
explain this, let's have an example.
cc_test { name: "mytest", static_libs: ["libfoo"]}
cc_library_static { name: "libfoo", static_libs: ["libbar"]}
cc_library { name: "libbar", apex_available: ["com.android.xxx"]}
Here, libbar is not available for platform, but is used by libfoo which
is available for platform (apex_available defaults to
"//apex_available:platform"). libfoo is again depended on by mytest
which again is available for platform. The use of libbar should be
allowed in the context of test; we don't want to make libbar available
to platform just for the dependency from test because it will allow
non-test uses of the library as well.
Soong by itself can't tell whether libfoo and libbar are used only in the
context of a test. There could be another module depending them, e.g.,
cc_library_shared { name: "mylib", static_libs: ["libfoo"] }
can exist and it might be installed to the device, in which case
we really should trigger an error.
Since Make has the knowledge of what's installed and what's not,
the check should be done there.
Bug: 153073816
Test: m
Test: remove "//apex_available:platform" from libmdnssd (it is currently
installed to /system/lib), and check that `m system_image` fails
Change-Id: Ia304cc5f41f173229e8a154e90cea4dce46dcebe
2020-04-07 09:37:39 +02:00
shared_libs : [ "libbar" ] ,
apex_available : [ "//apex_available:platform" ] ,
}
cc_library {
name : "libfoo2" ,
stl : "none" ,
system_shared_libs : [ ] ,
shared_libs : [ "libbaz" ] ,
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
apex_available : [ "//apex_available:platform" ] ,
mark platform un-availability
A module is marked unavailable for platform when 1) it does not have
"//apex_available:platform" in its apex_available property, or 2)
it depends on another module that is unavailable for platform.
In that case, LOCAL_NOT_AVAILABLE_FOR_PLATFORM is set to true for the
module in the Make world. Later, that flag is used to ensure that there
is no module with the flag is installed to the device.
The reason why this isn't entirely done in Soong is because Soong
doesn't know if a module will be installed to the device or not. To
explain this, let's have an example.
cc_test { name: "mytest", static_libs: ["libfoo"]}
cc_library_static { name: "libfoo", static_libs: ["libbar"]}
cc_library { name: "libbar", apex_available: ["com.android.xxx"]}
Here, libbar is not available for platform, but is used by libfoo which
is available for platform (apex_available defaults to
"//apex_available:platform"). libfoo is again depended on by mytest
which again is available for platform. The use of libbar should be
allowed in the context of test; we don't want to make libbar available
to platform just for the dependency from test because it will allow
non-test uses of the library as well.
Soong by itself can't tell whether libfoo and libbar are used only in the
context of a test. There could be another module depending them, e.g.,
cc_library_shared { name: "mylib", static_libs: ["libfoo"] }
can exist and it might be installed to the device, in which case
we really should trigger an error.
Since Make has the knowledge of what's installed and what's not,
the check should be done there.
Bug: 153073816
Test: m
Test: remove "//apex_available:platform" from libmdnssd (it is currently
installed to /system/lib), and check that `m system_image` fails
Change-Id: Ia304cc5f41f173229e8a154e90cea4dce46dcebe
2020-04-07 09:37:39 +02:00
}
cc_library {
name : "libbar" ,
stl : "none" ,
system_shared_libs : [ ] ,
apex_available : [ "myapex" ] ,
}
cc_library {
name : "libbaz" ,
stl : "none" ,
system_shared_libs : [ ] ,
apex_available : [ "myapex" ] ,
stubs : {
versions : [ "1" ] ,
} ,
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
} ` )
mark platform un-availability
A module is marked unavailable for platform when 1) it does not have
"//apex_available:platform" in its apex_available property, or 2)
it depends on another module that is unavailable for platform.
In that case, LOCAL_NOT_AVAILABLE_FOR_PLATFORM is set to true for the
module in the Make world. Later, that flag is used to ensure that there
is no module with the flag is installed to the device.
The reason why this isn't entirely done in Soong is because Soong
doesn't know if a module will be installed to the device or not. To
explain this, let's have an example.
cc_test { name: "mytest", static_libs: ["libfoo"]}
cc_library_static { name: "libfoo", static_libs: ["libbar"]}
cc_library { name: "libbar", apex_available: ["com.android.xxx"]}
Here, libbar is not available for platform, but is used by libfoo which
is available for platform (apex_available defaults to
"//apex_available:platform"). libfoo is again depended on by mytest
which again is available for platform. The use of libbar should be
allowed in the context of test; we don't want to make libbar available
to platform just for the dependency from test because it will allow
non-test uses of the library as well.
Soong by itself can't tell whether libfoo and libbar are used only in the
context of a test. There could be another module depending them, e.g.,
cc_library_shared { name: "mylib", static_libs: ["libfoo"] }
can exist and it might be installed to the device, in which case
we really should trigger an error.
Since Make has the knowledge of what's installed and what's not,
the check should be done there.
Bug: 153073816
Test: m
Test: remove "//apex_available:platform" from libmdnssd (it is currently
installed to /system/lib), and check that `m system_image` fails
Change-Id: Ia304cc5f41f173229e8a154e90cea4dce46dcebe
2020-04-07 09:37:39 +02:00
// libfoo shouldn't be available to platform even though it has "//apex_available:platform",
// because it depends on libbar which isn't available to platform
libfoo := ctx . ModuleForTests ( "libfoo" , "android_arm64_armv8-a_shared" ) . Module ( ) . ( * cc . Module )
if libfoo . NotAvailableForPlatform ( ) != true {
t . Errorf ( "%q shouldn't be available to platform" , libfoo . String ( ) )
}
// libfoo2 however can be available to platform because it depends on libbaz which provides
// stubs
libfoo2 := ctx . ModuleForTests ( "libfoo2" , "android_arm64_armv8-a_shared" ) . Module ( ) . ( * cc . Module )
if libfoo2 . NotAvailableForPlatform ( ) == true {
t . Errorf ( "%q should be available to platform" , libfoo2 . String ( ) )
}
2020-03-30 18:54:29 +02:00
}
2019-10-07 08:47:24 +02:00
2020-03-30 18:54:29 +02:00
func TestApexAvailable_CreatedForApex ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-10-07 08:47:24 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "libfoo" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-10-07 08:47:24 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "libfoo" ,
stl : "none" ,
system_shared_libs : [ ] ,
apex_available : [ "myapex" ] ,
static : {
apex_available : [ "//apex_available:platform" ] ,
} ,
} ` )
mark platform un-availability
A module is marked unavailable for platform when 1) it does not have
"//apex_available:platform" in its apex_available property, or 2)
it depends on another module that is unavailable for platform.
In that case, LOCAL_NOT_AVAILABLE_FOR_PLATFORM is set to true for the
module in the Make world. Later, that flag is used to ensure that there
is no module with the flag is installed to the device.
The reason why this isn't entirely done in Soong is because Soong
doesn't know if a module will be installed to the device or not. To
explain this, let's have an example.
cc_test { name: "mytest", static_libs: ["libfoo"]}
cc_library_static { name: "libfoo", static_libs: ["libbar"]}
cc_library { name: "libbar", apex_available: ["com.android.xxx"]}
Here, libbar is not available for platform, but is used by libfoo which
is available for platform (apex_available defaults to
"//apex_available:platform"). libfoo is again depended on by mytest
which again is available for platform. The use of libbar should be
allowed in the context of test; we don't want to make libbar available
to platform just for the dependency from test because it will allow
non-test uses of the library as well.
Soong by itself can't tell whether libfoo and libbar are used only in the
context of a test. There could be another module depending them, e.g.,
cc_library_shared { name: "mylib", static_libs: ["libfoo"] }
can exist and it might be installed to the device, in which case
we really should trigger an error.
Since Make has the knowledge of what's installed and what's not,
the check should be done there.
Bug: 153073816
Test: m
Test: remove "//apex_available:platform" from libmdnssd (it is currently
installed to /system/lib), and check that `m system_image` fails
Change-Id: Ia304cc5f41f173229e8a154e90cea4dce46dcebe
2020-04-07 09:37:39 +02:00
libfooShared := ctx . ModuleForTests ( "libfoo" , "android_arm64_armv8-a_shared" ) . Module ( ) . ( * cc . Module )
if libfooShared . NotAvailableForPlatform ( ) != true {
t . Errorf ( "%q shouldn't be available to platform" , libfooShared . String ( ) )
}
libfooStatic := ctx . ModuleForTests ( "libfoo" , "android_arm64_armv8-a_static" ) . Module ( ) . ( * cc . Module )
if libfooStatic . NotAvailableForPlatform ( ) != false {
t . Errorf ( "%q should be available to platform" , libfooStatic . String ( ) )
}
Add apex_available to control the availablity of a module to APEXes
apex_available property controls the availability of a module to APEXes.
For example, `apex_available: ["myapex", "otherapex"]` makes the module
available only to the two APEXes: myapex and otherapex, and nothing
else, even to the platform.
If the module is intended to be available to any APEX, then a pseudo
name "//apex_available:anyapex" can be used.
If the module is intended to be available to the platform, then another
pseudo name "//apex_available:platform" is used.
For now, if unspecified, this property defaults to ["//apex_available:platform",
"//apex_available:anyapex"], which means the module is available to everybody.
This will be reduced to ["//apex_available:platform"], when marking for
apex_available for existing modules are finished.
Bug: 139870423
Bug: 128708192
Test: m
Change-Id: Id4b233c3056c7858f984cbf9427cfac4118b2682
2019-09-30 09:04:35 +02:00
}
2019-11-15 10:40:32 +01:00
func TestOverrideApex ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-11-15 10:40:32 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
apps : [ "app" ] ,
2021-08-26 16:10:06 +02:00
bpfs : [ "bpf" ] ,
2021-08-27 00:44:43 +02:00
prebuilts : [ "myetc" ] ,
2019-12-20 02:32:06 +01:00
overrides : [ "oldapex" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-11-15 10:40:32 +01:00
}
override_apex {
name : "override_myapex" ,
base : "myapex" ,
apps : [ "override_app" ] ,
2021-08-26 16:10:06 +02:00
bpfs : [ "override_bpf" ] ,
2021-08-27 00:44:43 +02:00
prebuilts : [ "override_myetc" ] ,
2019-12-20 02:32:06 +01:00
overrides : [ "unknownapex" ] ,
2020-02-20 06:29:28 +01:00
logging_parent : "com.foo.bar" ,
2020-03-15 21:01:05 +01:00
package_name : "test.overridden.package" ,
2021-04-21 01:21:24 +02:00
key : "mynewapex.key" ,
certificate : ":myapex.certificate" ,
2019-11-15 10:40:32 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
2021-04-21 01:21:24 +02:00
apex_key {
name : "mynewapex.key" ,
public_key : "testkey2.avbpubkey" ,
private_key : "testkey2.pem" ,
}
android_app_certificate {
name : "myapex.certificate" ,
certificate : "testkey" ,
}
2019-11-15 10:40:32 +01:00
android_app {
name : "app" ,
srcs : [ "foo/bar/MyClass.java" ] ,
package_name : "foo" ,
sdk_version : "none" ,
system_modules : "none" ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
2019-11-15 10:40:32 +01:00
}
override_android_app {
name : "override_app" ,
base : "app" ,
package_name : "bar" ,
}
2021-08-26 16:10:06 +02:00
bpf {
name : "bpf" ,
srcs : [ "bpf.c" ] ,
}
bpf {
name : "override_bpf" ,
srcs : [ "override_bpf.c" ] ,
}
2021-08-27 00:44:43 +02:00
prebuilt_etc {
name : "myetc" ,
src : "myprebuilt" ,
}
prebuilt_etc {
name : "override_myetc" ,
src : "override_myprebuilt" ,
}
2020-03-03 03:45:41 +01:00
` , withManifestPackageNameOverrides ( [ ] string { "myapex:com.android.myapex" } ) )
2019-11-15 10:40:32 +01:00
2019-12-05 05:20:58 +01:00
originalVariant := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Module ( ) . ( android . OverridableModule )
overriddenVariant := ctx . ModuleForTests ( "myapex" , "android_common_override_myapex_myapex_image" ) . Module ( ) . ( android . OverridableModule )
if originalVariant . GetOverriddenBy ( ) != "" {
t . Errorf ( "GetOverriddenBy should be empty, but was %q" , originalVariant . GetOverriddenBy ( ) )
}
if overriddenVariant . GetOverriddenBy ( ) != "override_myapex" {
t . Errorf ( "GetOverriddenBy should be \"override_myapex\", but was %q" , overriddenVariant . GetOverriddenBy ( ) )
}
2019-11-15 10:40:32 +01:00
module := ctx . ModuleForTests ( "myapex" , "android_common_override_myapex_myapex_image" )
apexRule := module . Rule ( "apexRule" )
copyCmds := apexRule . Args [ "copy_commands" ]
ensureNotContains ( t , copyCmds , "image.apex/app/app/app.apk" )
2020-03-23 12:21:11 +01:00
ensureContains ( t , copyCmds , "image.apex/app/override_app/override_app.apk" )
2019-11-22 23:50:42 +01:00
2021-08-26 16:10:06 +02:00
ensureNotContains ( t , copyCmds , "image.apex/etc/bpf/bpf.o" )
ensureContains ( t , copyCmds , "image.apex/etc/bpf/override_bpf.o" )
2021-08-27 00:44:43 +02:00
ensureNotContains ( t , copyCmds , "image.apex/etc/myetc" )
ensureContains ( t , copyCmds , "image.apex/etc/override_myetc" )
2019-11-22 23:50:42 +01:00
apexBundle := module . Module ( ) . ( * apexBundle )
name := apexBundle . Name ( )
if name != "override_myapex" {
t . Errorf ( "name should be \"override_myapex\", but was %q" , name )
}
2020-02-20 06:29:28 +01:00
if apexBundle . overridableProperties . Logging_parent != "com.foo.bar" {
t . Errorf ( "override_myapex should have logging parent (com.foo.bar), but was %q." , apexBundle . overridableProperties . Logging_parent )
}
2020-03-03 03:45:41 +01:00
optFlags := apexRule . Args [ "opt_flags" ]
2020-03-15 21:01:05 +01:00
ensureContains ( t , optFlags , "--override_apk_package_name test.overridden.package" )
2021-04-21 01:21:24 +02:00
ensureContains ( t , optFlags , "--pubkey testkey2.avbpubkey" )
signApkRule := module . Rule ( "signapk" )
ensureEquals ( t , signApkRule . Args [ "certificates" ] , "testkey.x509.pem testkey.pk8" )
2020-03-03 03:45:41 +01:00
2020-07-03 22:18:24 +02:00
data := android . AndroidMkDataForTest ( t , ctx , apexBundle )
2019-11-22 23:50:42 +01:00
var builder strings . Builder
data . Custom ( & builder , name , "TARGET_" , "" , data )
androidMk := builder . String ( )
2019-11-18 07:39:01 +01:00
ensureContains ( t , androidMk , "LOCAL_MODULE := override_app.override_myapex" )
2021-08-26 16:10:06 +02:00
ensureContains ( t , androidMk , "LOCAL_MODULE := override_bpf.o.override_myapex" )
2019-11-22 23:50:42 +01:00
ensureContains ( t , androidMk , "LOCAL_MODULE := apex_manifest.pb.override_myapex" )
ensureContains ( t , androidMk , "LOCAL_MODULE_STEM := override_myapex.apex" )
2019-12-20 02:32:06 +01:00
ensureContains ( t , androidMk , "LOCAL_OVERRIDES_MODULES := unknownapex myapex" )
2019-11-22 23:50:42 +01:00
ensureNotContains ( t , androidMk , "LOCAL_MODULE := app.myapex" )
2021-08-26 16:10:06 +02:00
ensureNotContains ( t , androidMk , "LOCAL_MODULE := bpf.myapex" )
2019-11-18 07:39:01 +01:00
ensureNotContains ( t , androidMk , "LOCAL_MODULE := override_app.myapex" )
2019-11-22 23:50:42 +01:00
ensureNotContains ( t , androidMk , "LOCAL_MODULE := apex_manifest.pb.myapex" )
ensureNotContains ( t , androidMk , "LOCAL_MODULE_STEM := myapex.apex" )
2019-11-15 10:40:32 +01:00
}
2019-11-12 05:03:50 +01:00
func TestLegacyAndroid10Support ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-11-12 05:03:50 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
2020-02-13 02:13:25 +01:00
native_shared_libs : [ "mylib" ] ,
2020-03-12 10:37:20 +01:00
min_sdk_version : "29" ,
2019-11-12 05:03:50 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
2020-02-13 02:13:25 +01:00
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
stl : "libc++" ,
system_shared_libs : [ ] ,
apex_available : [ "myapex" ] ,
2020-04-15 04:03:39 +02:00
min_sdk_version : "29" ,
2020-02-13 02:13:25 +01:00
}
` , withUnbundledBuild )
2019-11-12 05:03:50 +01:00
module := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" )
args := module . Rule ( "apexRule" ) . Args
ensureContains ( t , args [ "opt_flags" ] , "--manifest_json " + module . Output ( "apex_manifest.json" ) . Output . String ( ) )
2020-01-15 00:50:25 +01:00
ensureNotContains ( t , args [ "opt_flags" ] , "--no_hashtree" )
2020-02-13 02:13:25 +01:00
// The copies of the libraries in the apex should have one more dependency than
// the ones outside the apex, namely the unwinder. Ideally we should check
// the dependency names directly here but for some reason the names are blank in
// this test.
for _ , lib := range [ ] string { "libc++" , "mylib" } {
Reland: Deduplicate APEX variants that would build identically
APEX variants that share the same SDK version and updatability
almost always use identical command line arguments to build but
with different intermediates directories. This causes unnecessary
build time and disk space for duplicated work.
Deduplicate APEX variants that would build identically. Create
aliases from the per-APEX variations to the new shared variations
so that the APEX modules can continue to depend on them via the
APEX name as the variation.
This has one significant change in behavior. Before this change,
if an APEX had two libraries in its direct dependencies and one
of those libraries depended on the other, and the second library
had stubs, then the first library would depend on the implementation
of the second library and not the stubs. After this change, if
the first library is also present in a second APEX but the second
library is not, then the common variant shared between the two
APEXes would use the stubs, not the implementation.
In a correctly configured set of build rules this change will
be irrelevant, because if the compilation worked for the second
APEX using stubs then it will work for the common variant using
stubs. However, if an incorrect change to the build rules is
made this could lead to confusing errors, as a previously-working
common variant could suddenly stop building when a module is added
to a new APEX without its dependencies that require implementation
APIs to compile.
This change reduces the number of modules in an AOSP arm64-userdebug
build by 3% (52242 to 50586), reduces the number of variants of the
libcutils module from 74 to 53, and reduces the number of variants
of the massive libart[d] modules from 44 to 32.
This relands I0529837476a253c32b3dfb98dcccf107427c742c with a fix
to always mark permissions XML files of java_sdk_library modules as
unique per apex since they contain the APEX filename, and a fix
to UpdateUniqueApexVariationsForDeps to check ApexInfo.InApexes
instead of DepIsInSameApex to check if two modules are in the same
apex to account for a module that depends on another in a way that
doesn't normally include the dependency in the APEX (e.g. a libs
property), but the dependency is directly included in the APEX.
Bug: 164216768
Test: go test ./build/soong/apex/...
Change-Id: I2ae170601f764e5b88d0be2e0e6adc84e3a4d9cc
2020-08-11 21:17:01 +02:00
apexImplicits := ctx . ModuleForTests ( lib , "android_arm64_armv8-a_shared_apex29" ) . Rule ( "ld" ) . Implicits
2020-02-13 02:13:25 +01:00
nonApexImplicits := ctx . ModuleForTests ( lib , "android_arm64_armv8-a_shared" ) . Rule ( "ld" ) . Implicits
if len ( apexImplicits ) != len ( nonApexImplicits ) + 1 {
t . Errorf ( "%q missing unwinder dep" , lib )
}
}
2019-11-12 05:03:50 +01:00
}
2021-03-08 16:07:14 +01:00
var filesForSdkLibrary = android . MockFS {
2020-05-26 14:21:35 +02:00
"api/current.txt" : nil ,
"api/removed.txt" : nil ,
"api/system-current.txt" : nil ,
"api/system-removed.txt" : nil ,
"api/test-current.txt" : nil ,
"api/test-removed.txt" : nil ,
2020-06-12 18:46:39 +02:00
2020-12-21 18:10:01 +01:00
"100/public/api/foo.txt" : nil ,
"100/public/api/foo-removed.txt" : nil ,
"100/system/api/foo.txt" : nil ,
"100/system/api/foo-removed.txt" : nil ,
2020-06-12 18:46:39 +02:00
// For java_sdk_library_import
"a.jar" : nil ,
2020-05-26 14:21:35 +02:00
}
2019-12-18 07:34:32 +01:00
func TestJavaSDKLibrary ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-12-18 07:34:32 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
java_libs : [ "foo" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-12-18 07:34:32 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
java_sdk_library {
name : "foo" ,
srcs : [ "a.java" ] ,
api_packages : [ "foo" ] ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
2019-12-18 07:34:32 +01:00
}
2020-12-21 18:10:01 +01:00
prebuilt_apis {
name : "sdk" ,
api_dirs : [ "100" ] ,
}
2020-05-26 14:21:35 +02:00
` , withFiles ( filesForSdkLibrary ) )
2019-12-18 07:34:32 +01:00
// java_sdk_library installs both impl jar and permission XML
2020-01-23 06:36:59 +01:00
ensureExactContents ( t , ctx , "myapex" , "android_common_myapex_image" , [ ] string {
2019-12-18 07:34:32 +01:00
"javalib/foo.jar" ,
"etc/permissions/foo.xml" ,
} )
// Permission XML should point to the activated path of impl jar of java_sdk_library
2020-02-17 09:28:10 +01:00
sdkLibrary := ctx . ModuleForTests ( "foo.xml" , "android_common_myapex" ) . Rule ( "java_sdk_xml" )
ensureContains ( t , sdkLibrary . RuleParams . Command , ` <library name=\"foo\" file=\"/apex/myapex/javalib/foo.jar\" ` )
2019-12-18 07:34:32 +01:00
}
2020-05-26 14:21:35 +02:00
func TestJavaSDKLibrary_WithinApex ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-05-26 14:21:35 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
java_libs : [ "foo" , "bar" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-05-26 14:21:35 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
java_sdk_library {
name : "foo" ,
srcs : [ "a.java" ] ,
api_packages : [ "foo" ] ,
apex_available : [ "myapex" ] ,
sdk_version : "none" ,
system_modules : "none" ,
}
java_library {
name : "bar" ,
srcs : [ "a.java" ] ,
libs : [ "foo" ] ,
apex_available : [ "myapex" ] ,
sdk_version : "none" ,
system_modules : "none" ,
}
2020-12-21 18:10:01 +01:00
prebuilt_apis {
name : "sdk" ,
api_dirs : [ "100" ] ,
}
2020-05-26 14:21:35 +02:00
` , withFiles ( filesForSdkLibrary ) )
// java_sdk_library installs both impl jar and permission XML
ensureExactContents ( t , ctx , "myapex" , "android_common_myapex_image" , [ ] string {
"javalib/bar.jar" ,
"javalib/foo.jar" ,
"etc/permissions/foo.xml" ,
} )
// The bar library should depend on the implementation jar.
barLibrary := ctx . ModuleForTests ( "bar" , "android_common_myapex" ) . Rule ( "javac" )
2021-03-29 01:29:53 +02:00
if expected , actual := ` ^-classpath [^:]*/turbine-combined/foo\.jar$ ` , barLibrary . Args [ "classpath" ] ; ! regexp . MustCompile ( expected ) . MatchString ( actual ) {
2020-05-26 14:21:35 +02:00
t . Errorf ( "expected %q, found %#q" , expected , actual )
}
}
func TestJavaSDKLibrary_CrossBoundary ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-05-26 14:21:35 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
java_libs : [ "foo" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-05-26 14:21:35 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
java_sdk_library {
name : "foo" ,
srcs : [ "a.java" ] ,
api_packages : [ "foo" ] ,
apex_available : [ "myapex" ] ,
sdk_version : "none" ,
system_modules : "none" ,
}
java_library {
name : "bar" ,
srcs : [ "a.java" ] ,
libs : [ "foo" ] ,
sdk_version : "none" ,
system_modules : "none" ,
}
2020-12-21 18:10:01 +01:00
prebuilt_apis {
name : "sdk" ,
api_dirs : [ "100" ] ,
}
2020-05-26 14:21:35 +02:00
` , withFiles ( filesForSdkLibrary ) )
// java_sdk_library installs both impl jar and permission XML
ensureExactContents ( t , ctx , "myapex" , "android_common_myapex_image" , [ ] string {
"javalib/foo.jar" ,
"etc/permissions/foo.xml" ,
} )
// The bar library should depend on the stubs jar.
barLibrary := ctx . ModuleForTests ( "bar" , "android_common" ) . Rule ( "javac" )
2021-03-29 01:29:53 +02:00
if expected , actual := ` ^-classpath [^:]*/turbine-combined/foo\.stubs\.jar$ ` , barLibrary . Args [ "classpath" ] ; ! regexp . MustCompile ( expected ) . MatchString ( actual ) {
2020-05-26 14:21:35 +02:00
t . Errorf ( "expected %q, found %#q" , expected , actual )
}
}
2020-06-12 18:46:39 +02:00
func TestJavaSDKLibrary_ImportPreferred ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-12-21 18:10:01 +01:00
prebuilt_apis {
name : "sdk" ,
api_dirs : [ "100" ] ,
} ` ,
2020-06-12 18:46:39 +02:00
withFiles ( map [ string ] [ ] byte {
"apex/a.java" : nil ,
"apex/apex_manifest.json" : nil ,
"apex/Android.bp" : [ ] byte ( `
package {
default_visibility : [ "//visibility:private" ] ,
}
apex {
name : "myapex" ,
key : "myapex.key" ,
java_libs : [ "foo" , "bar" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-06-12 18:46:39 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
java_library {
name : "bar" ,
srcs : [ "a.java" ] ,
libs : [ "foo" ] ,
apex_available : [ "myapex" ] ,
sdk_version : "none" ,
system_modules : "none" ,
}
` ) ,
"source/a.java" : nil ,
"source/api/current.txt" : nil ,
"source/api/removed.txt" : nil ,
"source/Android.bp" : [ ] byte ( `
package {
default_visibility : [ "//visibility:private" ] ,
}
java_sdk_library {
name : "foo" ,
visibility : [ "//apex" ] ,
srcs : [ "a.java" ] ,
api_packages : [ "foo" ] ,
apex_available : [ "myapex" ] ,
sdk_version : "none" ,
system_modules : "none" ,
public : {
enabled : true ,
} ,
}
` ) ,
"prebuilt/a.jar" : nil ,
"prebuilt/Android.bp" : [ ] byte ( `
package {
default_visibility : [ "//visibility:private" ] ,
}
java_sdk_library_import {
name : "foo" ,
visibility : [ "//apex" , "//source" ] ,
apex_available : [ "myapex" ] ,
prefer : true ,
public : {
jars : [ "a.jar" ] ,
} ,
}
` ) ,
2020-12-21 18:10:01 +01:00
} ) , withFiles ( filesForSdkLibrary ) ,
2020-06-12 18:46:39 +02:00
)
// java_sdk_library installs both impl jar and permission XML
ensureExactContents ( t , ctx , "myapex" , "android_common_myapex_image" , [ ] string {
"javalib/bar.jar" ,
"javalib/foo.jar" ,
"etc/permissions/foo.xml" ,
} )
// The bar library should depend on the implementation jar.
barLibrary := ctx . ModuleForTests ( "bar" , "android_common_myapex" ) . Rule ( "javac" )
2021-03-29 01:29:53 +02:00
if expected , actual := ` ^-classpath [^:]*/turbine-combined/foo\.impl\.jar$ ` , barLibrary . Args [ "classpath" ] ; ! regexp . MustCompile ( expected ) . MatchString ( actual ) {
2020-06-12 18:46:39 +02:00
t . Errorf ( "expected %q, found %#q" , expected , actual )
}
}
func TestJavaSDKLibrary_ImportOnly ( t * testing . T ) {
testApexError ( t , ` java_libs: "foo" is not configured to be compiled into dex ` , `
apex {
name : "myapex" ,
key : "myapex.key" ,
java_libs : [ "foo" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-06-12 18:46:39 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
java_sdk_library_import {
name : "foo" ,
apex_available : [ "myapex" ] ,
prefer : true ,
public : {
jars : [ "a.jar" ] ,
} ,
}
` , withFiles ( filesForSdkLibrary ) )
}
2020-01-27 18:01:16 +01:00
func TestCompatConfig ( t * testing . T ) {
2021-03-29 02:50:31 +02:00
result := android . GroupFixturePreparers (
prepareForApexTest ,
java . PrepareForTestWithPlatformCompatConfig ,
) . RunTestWithBp ( t , `
2020-01-27 18:01:16 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
2021-03-15 20:32:23 +01:00
compat_configs : [ "myjar-platform-compat-config" ] ,
2020-01-27 18:01:16 +01:00
java_libs : [ "myjar" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-01-27 18:01:16 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
platform_compat_config {
name : "myjar-platform-compat-config" ,
src : ":myjar" ,
}
java_library {
name : "myjar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
sdk_version : "none" ,
system_modules : "none" ,
apex_available : [ "myapex" ] ,
}
2021-03-16 16:06:54 +01:00
// Make sure that a preferred prebuilt does not affect the apex contents.
prebuilt_platform_compat_config {
name : "myjar-platform-compat-config" ,
metadata : "compat-config/metadata.xml" ,
prefer : true ,
}
2020-01-27 18:01:16 +01:00
` )
2021-03-09 04:08:05 +01:00
ctx := result . TestContext
2020-01-27 18:01:16 +01:00
ensureExactContents ( t , ctx , "myapex" , "android_common_myapex_image" , [ ] string {
"etc/compatconfig/myjar-platform-compat-config.xml" ,
"javalib/myjar.jar" ,
} )
}
2019-12-16 03:47:12 +01:00
func TestRejectNonInstallableJavaLibrary ( t * testing . T ) {
testApexError ( t , ` "myjar" is not configured to be compiled into dex ` , `
apex {
name : "myapex" ,
key : "myapex.key" ,
java_libs : [ "myjar" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-12-16 03:47:12 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
java_library {
name : "myjar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
sdk_version : "none" ,
system_modules : "none" ,
2020-02-11 01:16:01 +01:00
compile_dex : false ,
2020-03-09 22:23:13 +01:00
apex_available : [ "myapex" ] ,
2019-12-16 03:47:12 +01:00
}
` )
}
2019-12-30 08:56:33 +01:00
func TestCarryRequiredModuleNames ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2019-12-30 08:56:33 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2019-12-30 08:56:33 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
required : [ "a" , "b" ] ,
host_required : [ "c" , "d" ] ,
target_required : [ "e" , "f" ] ,
2020-01-10 16:12:39 +01:00
apex_available : [ "myapex" ] ,
2019-12-30 08:56:33 +01:00
}
` )
apexBundle := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Module ( ) . ( * apexBundle )
2020-07-03 22:18:24 +02:00
data := android . AndroidMkDataForTest ( t , ctx , apexBundle )
2019-12-30 08:56:33 +01:00
name := apexBundle . BaseModuleName ( )
prefix := "TARGET_"
var builder strings . Builder
data . Custom ( & builder , name , prefix , "" , data )
androidMk := builder . String ( )
ensureContains ( t , androidMk , "LOCAL_REQUIRED_MODULES += a b\n" )
ensureContains ( t , androidMk , "LOCAL_HOST_REQUIRED_MODULES += c d\n" )
ensureContains ( t , androidMk , "LOCAL_TARGET_REQUIRED_MODULES += e f\n" )
}
2020-01-14 01:22:18 +01:00
func TestSymlinksFromApexToSystem ( t * testing . T ) {
bp := `
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
java_libs : [ "myjar" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-01-14 01:22:18 +01:00
}
2020-02-19 08:29:35 +01:00
apex {
name : "myapex.updatable" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
java_libs : [ "myjar" ] ,
updatable : true ,
2020-04-27 05:10:30 +02:00
min_sdk_version : "current" ,
2020-02-19 08:29:35 +01:00
}
2020-01-14 01:22:18 +01:00
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
shared_libs : [ "myotherlib" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [
"myapex" ,
2020-02-19 08:29:35 +01:00
"myapex.updatable" ,
2020-01-14 01:22:18 +01:00
"//apex_available:platform" ,
] ,
2020-04-15 04:03:39 +02:00
min_sdk_version : "current" ,
2020-01-14 01:22:18 +01:00
}
cc_library {
name : "myotherlib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [
"myapex" ,
2020-02-19 08:29:35 +01:00
"myapex.updatable" ,
2020-01-14 01:22:18 +01:00
"//apex_available:platform" ,
] ,
2020-04-15 04:03:39 +02:00
min_sdk_version : "current" ,
2020-01-14 01:22:18 +01:00
}
java_library {
name : "myjar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
sdk_version : "none" ,
system_modules : "none" ,
libs : [ "myotherjar" ] ,
apex_available : [
"myapex" ,
2020-02-19 08:29:35 +01:00
"myapex.updatable" ,
2020-01-14 01:22:18 +01:00
"//apex_available:platform" ,
] ,
2020-04-15 04:03:39 +02:00
min_sdk_version : "current" ,
2020-01-14 01:22:18 +01:00
}
java_library {
name : "myotherjar" ,
srcs : [ "foo/bar/MyClass.java" ] ,
sdk_version : "none" ,
system_modules : "none" ,
apex_available : [
"myapex" ,
2020-02-19 08:29:35 +01:00
"myapex.updatable" ,
2020-01-14 01:22:18 +01:00
"//apex_available:platform" ,
] ,
2020-04-15 04:03:39 +02:00
min_sdk_version : "current" ,
2020-01-14 01:22:18 +01:00
}
`
ensureRealfileExists := func ( t * testing . T , files [ ] fileInApex , file string ) {
for _ , f := range files {
if f . path == file {
if f . isLink {
t . Errorf ( "%q is not a real file" , file )
}
return
}
}
t . Errorf ( "%q is not found" , file )
}
ensureSymlinkExists := func ( t * testing . T , files [ ] fileInApex , file string ) {
for _ , f := range files {
if f . path == file {
if ! f . isLink {
t . Errorf ( "%q is not a symlink" , file )
}
return
}
}
t . Errorf ( "%q is not found" , file )
}
2020-02-19 08:29:35 +01:00
// For unbundled build, symlink shouldn't exist regardless of whether an APEX
// is updatable or not
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , bp , withUnbundledBuild )
2020-01-23 06:36:59 +01:00
files := getFiles ( t , ctx , "myapex" , "android_common_myapex_image" )
2020-01-14 01:22:18 +01:00
ensureRealfileExists ( t , files , "javalib/myjar.jar" )
ensureRealfileExists ( t , files , "lib64/mylib.so" )
ensureRealfileExists ( t , files , "lib64/myotherlib.so" )
2020-02-19 08:29:35 +01:00
files = getFiles ( t , ctx , "myapex.updatable" , "android_common_myapex.updatable_image" )
ensureRealfileExists ( t , files , "javalib/myjar.jar" )
ensureRealfileExists ( t , files , "lib64/mylib.so" )
ensureRealfileExists ( t , files , "lib64/myotherlib.so" )
// For bundled build, symlink to the system for the non-updatable APEXes only
2021-02-17 02:55:47 +01:00
ctx = testApex ( t , bp )
2020-01-23 06:36:59 +01:00
files = getFiles ( t , ctx , "myapex" , "android_common_myapex_image" )
2020-01-14 01:22:18 +01:00
ensureRealfileExists ( t , files , "javalib/myjar.jar" )
ensureRealfileExists ( t , files , "lib64/mylib.so" )
ensureSymlinkExists ( t , files , "lib64/myotherlib.so" ) // this is symlink
2020-02-19 08:29:35 +01:00
files = getFiles ( t , ctx , "myapex.updatable" , "android_common_myapex.updatable_image" )
ensureRealfileExists ( t , files , "javalib/myjar.jar" )
ensureRealfileExists ( t , files , "lib64/mylib.so" )
ensureRealfileExists ( t , files , "lib64/myotherlib.so" ) // this is a real file
2020-01-14 01:22:18 +01:00
}
2020-07-23 14:09:18 +02:00
func TestSymlinksFromApexToSystemRequiredModuleNames ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-07-23 14:09:18 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-07-23 14:09:18 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library_shared {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
shared_libs : [ "myotherlib" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [
"myapex" ,
"//apex_available:platform" ,
] ,
}
cc_prebuilt_library_shared {
name : "myotherlib" ,
srcs : [ "prebuilt.so" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [
"myapex" ,
"//apex_available:platform" ,
] ,
}
` )
apexBundle := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Module ( ) . ( * apexBundle )
2020-07-03 22:18:24 +02:00
data := android . AndroidMkDataForTest ( t , ctx , apexBundle )
2020-07-23 14:09:18 +02:00
var builder strings . Builder
data . Custom ( & builder , apexBundle . BaseModuleName ( ) , "TARGET_" , "" , data )
androidMk := builder . String ( )
// `myotherlib` is added to `myapex` as symlink
ensureContains ( t , androidMk , "LOCAL_MODULE := mylib.myapex\n" )
ensureNotContains ( t , androidMk , "LOCAL_MODULE := prebuilt_myotherlib.myapex\n" )
ensureNotContains ( t , androidMk , "LOCAL_MODULE := myotherlib.myapex\n" )
// `myapex` should have `myotherlib` in its required line, not `prebuilt_myotherlib`
2021-01-20 12:33:11 +01:00
ensureContains ( t , androidMk , "LOCAL_REQUIRED_MODULES += mylib.myapex:64 myotherlib:64 apex_manifest.pb.myapex apex_pubkey.myapex\n" )
2020-07-23 14:09:18 +02:00
}
2020-02-27 05:50:06 +01:00
func TestApexWithJniLibs ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-02-27 05:50:06 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
jni_libs : [ "mylib" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-02-27 05:50:06 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
shared_libs : [ "mylib2" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" ] ,
}
cc_library {
name : "mylib2" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" ] ,
}
` )
rule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "apexManifestRule" )
// Notice mylib2.so (transitive dep) is not added as a jni_lib
ensureEquals ( t , rule . Args [ "opt" ] , "-a jniLibs mylib.so" )
ensureExactContents ( t , ctx , "myapex" , "android_common_myapex_image" , [ ] string {
"lib64/mylib.so" ,
"lib64/mylib2.so" ,
} )
}
2020-04-17 06:43:10 +02:00
func TestApexMutatorsDontRunIfDisabled ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-04-17 06:43:10 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-04-17 06:43:10 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
2021-03-08 12:28:25 +01:00
` ,
android . FixtureModifyConfig ( func ( config android . Config ) {
delete ( config . Targets , android . Android )
config . AndroidCommonTarget = android . Target { }
} ) ,
)
2020-04-17 06:43:10 +02:00
if expected , got := [ ] string { "" } , ctx . ModuleVariantsForTests ( "myapex" ) ; ! reflect . DeepEqual ( expected , got ) {
t . Errorf ( "Expected variants: %v, but got: %v" , expected , got )
}
}
2020-02-28 07:22:21 +01:00
func TestAppBundle ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-02-28 07:22:21 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
apps : [ "AppFoo" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-02-28 07:22:21 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
android_app {
name : "AppFoo" ,
srcs : [ "foo/bar/MyClass.java" ] ,
sdk_version : "none" ,
system_modules : "none" ,
apex_available : [ "myapex" ] ,
}
2020-02-28 08:51:07 +01:00
` , withManifestPackageNameOverrides ( [ ] string { "AppFoo:com.android.foo" } ) )
2020-02-28 07:22:21 +01:00
2020-11-13 20:48:42 +01:00
bundleConfigRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Output ( "bundle_config.json" )
2020-02-28 07:22:21 +01:00
content := bundleConfigRule . Args [ "content" ]
ensureContains ( t , content , ` "compression": { "uncompressed_glob":["apex_payload.img","apex_manifest.*"]} ` )
2020-02-28 08:51:07 +01:00
ensureContains ( t , content , ` "apex_config": { "apex_embedded_apk_config":[ { "package_name":"com.android.foo","path":"app/AppFoo/AppFoo.apk"}]} ` )
2020-02-28 07:22:21 +01:00
}
2020-05-28 01:36:07 +02:00
func TestAppSetBundle ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-05-28 01:36:07 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
apps : [ "AppSet" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-05-28 01:36:07 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
android_app_set {
name : "AppSet" ,
set : "AppSet.apks" ,
} ` )
mod := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" )
2020-11-13 20:48:42 +01:00
bundleConfigRule := mod . Output ( "bundle_config.json" )
2020-05-28 01:36:07 +02:00
content := bundleConfigRule . Args [ "content" ]
ensureContains ( t , content , ` "compression": { "uncompressed_glob":["apex_payload.img","apex_manifest.*"]} ` )
s := mod . Rule ( "apexRule" ) . Args [ "copy_commands" ]
copyCmds := regexp . MustCompile ( " *&& *" ) . Split ( s , - 1 )
if len ( copyCmds ) != 3 {
t . Fatalf ( "Expected 3 commands, got %d in:\n%s" , len ( copyCmds ) , s )
}
ensureMatches ( t , copyCmds [ 0 ] , "^rm -rf .*/app/AppSet$" )
ensureMatches ( t , copyCmds [ 1 ] , "^mkdir -p .*/app/AppSet$" )
ensureMatches ( t , copyCmds [ 2 ] , "^unzip .*-d .*/app/AppSet .*/AppSet.zip$" )
}
2020-07-25 00:35:40 +02:00
func TestAppSetBundlePrebuilt ( t * testing . T ) {
2021-04-06 17:09:30 +02:00
bp := `
2020-07-25 00:35:40 +02:00
apex_set {
name : "myapex" ,
filename : "foo_v2.apex" ,
sanitized : {
none : { set : "myapex.apks" , } ,
hwaddress : { set : "myapex.hwasan.apks" , } ,
} ,
2021-04-06 17:09:30 +02:00
}
`
ctx := testApex ( t , bp , prepareForTestWithSantitizeHwaddress )
2020-07-25 00:35:40 +02:00
2021-04-06 17:09:30 +02:00
// Check that the extractor produces the correct output file from the correct input file.
extractorOutput := "out/soong/.intermediates/myapex.apex.extractor/android_common/extracted/myapex.hwasan.apks"
2020-07-25 00:35:40 +02:00
2021-04-06 17:09:30 +02:00
m := ctx . ModuleForTests ( "myapex.apex.extractor" , "android_common" )
extractedApex := m . Output ( extractorOutput )
2020-07-25 00:35:40 +02:00
2021-04-06 17:09:30 +02:00
android . AssertArrayString ( t , "extractor input" , [ ] string { "myapex.hwasan.apks" } , extractedApex . Inputs . Strings ( ) )
// Ditto for the apex.
2021-06-15 20:09:41 +02:00
m = ctx . ModuleForTests ( "myapex" , "android_common_myapex" )
copiedApex := m . Output ( "out/soong/.intermediates/myapex/android_common_myapex/foo_v2.apex" )
2021-04-06 17:09:30 +02:00
android . AssertStringEquals ( t , "myapex input" , extractorOutput , copiedApex . Input . String ( ) )
2020-07-25 00:35:40 +02:00
}
2021-06-16 02:42:33 +02:00
func testNoUpdatableJarsInBootImage ( t * testing . T , errmsg string , preparer android . FixturePreparer , fragments ... java . ApexVariantReference ) {
2020-01-13 16:18:16 +01:00
t . Helper ( )
2020-05-19 13:00:52 +02:00
bp := `
java_library {
name : "some-updatable-apex-lib" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
apex_available : [
"some-updatable-apex" ,
] ,
2021-08-06 18:49:46 +02:00
permitted_packages : [ "some.updatable.apex.lib" ] ,
2020-05-19 13:00:52 +02:00
}
java_library {
name : "some-non-updatable-apex-lib" ,
srcs : [ "a.java" ] ,
apex_available : [
"some-non-updatable-apex" ,
] ,
2021-06-16 02:42:33 +02:00
compile_dex : true ,
2021-08-06 18:49:46 +02:00
permitted_packages : [ "some.non.updatable.apex.lib" ] ,
2021-06-16 02:42:33 +02:00
}
bootclasspath_fragment {
name : "some-non-updatable-fragment" ,
contents : [ "some-non-updatable-apex-lib" ] ,
apex_available : [
"some-non-updatable-apex" ,
] ,
2020-05-19 13:00:52 +02:00
}
java_library {
name : "some-platform-lib" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
installable : true ,
}
java_library {
name : "some-art-lib" ,
srcs : [ "a.java" ] ,
sdk_version : "current" ,
apex_available : [
2021-01-26 12:59:35 +01:00
"com.android.art.debug" ,
2020-05-19 13:00:52 +02:00
] ,
hostdex : true ,
2021-06-07 14:28:19 +02:00
compile_dex : true ,
2020-05-19 13:00:52 +02:00
}
apex {
name : "some-updatable-apex" ,
key : "some-updatable-apex.key" ,
java_libs : [ "some-updatable-apex-lib" ] ,
updatable : true ,
min_sdk_version : "current" ,
}
apex {
name : "some-non-updatable-apex" ,
key : "some-non-updatable-apex.key" ,
2021-06-16 02:42:33 +02:00
bootclasspath_fragments : [ "some-non-updatable-fragment" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-05-19 13:00:52 +02:00
}
apex_key {
name : "some-updatable-apex.key" ,
}
apex_key {
name : "some-non-updatable-apex.key" ,
}
apex {
2021-01-26 12:59:35 +01:00
name : "com.android.art.debug" ,
key : "com.android.art.debug.key" ,
2021-06-16 02:42:33 +02:00
bootclasspath_fragments : [ "art-bootclasspath-fragment" ] ,
2020-05-19 13:00:52 +02:00
updatable : true ,
min_sdk_version : "current" ,
}
2021-04-27 13:42:20 +02:00
bootclasspath_fragment {
name : "art-bootclasspath-fragment" ,
image_name : "art" ,
contents : [ "some-art-lib" ] ,
apex_available : [
"com.android.art.debug" ,
] ,
}
2020-05-19 13:00:52 +02:00
apex_key {
2021-01-26 12:59:35 +01:00
name : "com.android.art.debug.key" ,
2020-05-19 13:00:52 +02:00
}
2020-01-13 16:18:16 +01:00
filegroup {
name : "some-updatable-apex-file_contexts" ,
srcs : [
"system/sepolicy/apex/some-updatable-apex-file_contexts" ,
] ,
}
2020-04-22 19:05:58 +02:00
filegroup {
name : "some-non-updatable-apex-file_contexts" ,
srcs : [
"system/sepolicy/apex/some-non-updatable-apex-file_contexts" ,
] ,
}
2020-01-13 16:18:16 +01:00
`
2020-12-10 20:15:49 +01:00
2021-06-16 02:42:33 +02:00
testDexpreoptWithApexes ( t , bp , errmsg , preparer , fragments ... )
2020-12-10 20:15:49 +01:00
}
2021-06-16 02:42:33 +02:00
func testDexpreoptWithApexes ( t * testing . T , bp , errmsg string , preparer android . FixturePreparer , fragments ... java . ApexVariantReference ) * android . TestContext {
2020-12-10 20:15:49 +01:00
t . Helper ( )
2021-03-31 00:32:51 +02:00
fs := android . MockFS {
"a.java" : nil ,
"a.jar" : nil ,
"apex_manifest.json" : nil ,
"AndroidManifest.xml" : nil ,
2021-01-17 22:05:12 +01:00
"system/sepolicy/apex/myapex-file_contexts" : nil ,
2021-01-26 12:59:35 +01:00
"system/sepolicy/apex/some-updatable-apex-file_contexts" : nil ,
"system/sepolicy/apex/some-non-updatable-apex-file_contexts" : nil ,
"system/sepolicy/apex/com.android.art.debug-file_contexts" : nil ,
2021-01-17 22:05:12 +01:00
"framework/aidl/a.aidl" : nil ,
2020-01-13 16:18:16 +01:00
}
2021-03-31 00:32:51 +02:00
errorHandler := android . FixtureExpectsNoErrors
if errmsg != "" {
errorHandler = android . FixtureExpectsAtLeastOneErrorMatchingPattern ( errmsg )
2020-01-13 16:18:16 +01:00
}
2020-11-02 18:32:38 +01:00
2021-03-31 00:32:51 +02:00
result := android . GroupFixturePreparers (
cc . PrepareForTestWithCcDefaultModules ,
java . PrepareForTestWithHiddenApiBuildComponents ,
java . PrepareForTestWithJavaDefaultModules ,
java . PrepareForTestWithJavaSdkLibraryFiles ,
PrepareForTestWithApexBuildComponents ,
2021-04-12 21:02:36 +02:00
preparer ,
2021-03-31 00:32:51 +02:00
fs . AddToFixture ( ) ,
2021-06-16 02:42:33 +02:00
android . FixtureModifyMockFS ( func ( fs android . MockFS ) {
if _ , ok := fs [ "frameworks/base/boot/Android.bp" ] ; ! ok {
insert := ""
for _ , fragment := range fragments {
insert += fmt . Sprintf ( "{apex: %q, module: %q},\n" , * fragment . Apex , * fragment . Module )
}
fs [ "frameworks/base/boot/Android.bp" ] = [ ] byte ( fmt . Sprintf ( `
platform_bootclasspath {
name : "platform-bootclasspath" ,
fragments : [
% s
] ,
}
` , insert ) )
2021-04-12 18:24:18 +02:00
}
2021-06-16 02:42:33 +02:00
} ) ,
2021-03-31 00:32:51 +02:00
) .
ExtendWithErrorHandler ( errorHandler ) .
RunTestWithBp ( t , bp )
return result . TestContext
2020-01-13 16:18:16 +01:00
}
2020-04-27 05:10:30 +02:00
func TestUpdatable_should_set_min_sdk_version ( t * testing . T ) {
testApexError ( t , ` "myapex" .*: updatable: updatable APEXes should set min_sdk_version ` , `
apex {
name : "myapex" ,
key : "myapex.key" ,
updatable : true ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
` )
}
2021-02-16 12:40:16 +01:00
func TestUpdatableDefault_should_set_min_sdk_version ( t * testing . T ) {
testApexError ( t , ` "myapex" .*: updatable: updatable APEXes should set min_sdk_version ` , `
apex {
name : "myapex" ,
key : "myapex.key" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
` )
}
2021-06-15 17:49:50 +02:00
func TestUpdatable_should_not_set_generate_classpaths_proto ( t * testing . T ) {
testApexError ( t , ` "mysystemserverclasspathfragment" .* it must not set generate_classpaths_proto to false ` , `
apex {
name : "myapex" ,
key : "myapex.key" ,
systemserverclasspath_fragments : [
"mysystemserverclasspathfragment" ,
] ,
min_sdk_version : "29" ,
updatable : true ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
java_library {
name : "foo" ,
srcs : [ "b.java" ] ,
min_sdk_version : "29" ,
installable : true ,
apex_available : [
"myapex" ,
] ,
}
systemserverclasspath_fragment {
name : "mysystemserverclasspathfragment" ,
generate_classpaths_proto : false ,
contents : [
"foo" ,
] ,
apex_available : [
"myapex" ,
] ,
}
2021-08-06 18:49:46 +02:00
` ,
dexpreopt . FixtureSetApexSystemServerJars ( "myapex:foo" ) ,
)
2021-06-15 17:49:50 +02:00
}
2020-01-13 16:18:16 +01:00
func TestNoUpdatableJarsInBootImage ( t * testing . T ) {
2021-04-12 21:02:36 +02:00
// Set the BootJars in dexpreopt.GlobalConfig and productVariables to the same value. This can
// result in an invalid configuration as it does not set the ArtApexJars and allows art apex
// modules to be included in the BootJars.
prepareSetBootJars := func ( bootJars ... string ) android . FixturePreparer {
return android . GroupFixturePreparers (
dexpreopt . FixtureSetBootJars ( bootJars ... ) ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . BootJars = android . CreateTestConfiguredJarList ( bootJars )
} ) ,
)
}
// Set the ArtApexJars and BootJars in dexpreopt.GlobalConfig and productVariables all to the
// same value. This can result in an invalid configuration as it allows non art apex jars to be
// specified in the ArtApexJars configuration.
prepareSetArtJars := func ( bootJars ... string ) android . FixturePreparer {
return android . GroupFixturePreparers (
dexpreopt . FixtureSetArtBootJars ( bootJars ... ) ,
dexpreopt . FixtureSetBootJars ( bootJars ... ) ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . BootJars = android . CreateTestConfiguredJarList ( bootJars )
} ) ,
)
}
2020-04-22 19:05:58 +02:00
2020-05-19 13:00:52 +02:00
t . Run ( "updatable jar from ART apex in the ART boot image => ok" , func ( t * testing . T ) {
2021-08-06 18:49:46 +02:00
preparer := android . GroupFixturePreparers (
java . FixtureConfigureBootJars ( "com.android.art.debug:some-art-lib" ) ,
java . FixtureConfigureApexBootJars ( "some-non-updatable-apex:some-non-updatable-apex-lib" ) ,
)
fragments := [ ] java . ApexVariantReference {
{
Apex : proptools . StringPtr ( "com.android.art.debug" ) ,
Module : proptools . StringPtr ( "art-bootclasspath-fragment" ) ,
} ,
{
Apex : proptools . StringPtr ( "some-non-updatable-apex" ) ,
Module : proptools . StringPtr ( "some-non-updatable-fragment" ) ,
} ,
2021-06-16 02:42:33 +02:00
}
2021-08-06 18:49:46 +02:00
testNoUpdatableJarsInBootImage ( t , "" , preparer , fragments ... )
2020-05-19 13:00:52 +02:00
} )
2020-01-13 16:18:16 +01:00
2020-05-19 13:00:52 +02:00
t . Run ( "updatable jar from ART apex in the framework boot image => error" , func ( t * testing . T ) {
2021-04-12 21:02:36 +02:00
err := ` module "some-art-lib" from updatable apexes \["com.android.art.debug"\] is not allowed in the framework boot image `
// Update the dexpreopt BootJars directly.
2021-08-06 18:49:46 +02:00
preparer := android . GroupFixturePreparers (
prepareSetBootJars ( "com.android.art.debug:some-art-lib" ) ,
java . FixtureConfigureApexBootJars ( "some-non-updatable-apex:some-non-updatable-apex-lib" ) ,
)
2021-04-12 21:02:36 +02:00
testNoUpdatableJarsInBootImage ( t , err , preparer )
2020-05-19 13:00:52 +02:00
} )
2020-01-13 16:18:16 +01:00
2020-05-19 13:00:52 +02:00
t . Run ( "updatable jar from some other apex in the ART boot image => error" , func ( t * testing . T ) {
2021-04-27 13:42:20 +02:00
err := ` ArtApexJars expects this to be in apex "some-updatable-apex" but this is only in apexes.*"com.android.art.debug" `
2021-04-12 21:02:36 +02:00
// Update the dexpreopt ArtApexJars directly.
preparer := prepareSetArtJars ( "some-updatable-apex:some-updatable-apex-lib" )
testNoUpdatableJarsInBootImage ( t , err , preparer )
2020-05-19 13:00:52 +02:00
} )
2020-04-22 19:05:58 +02:00
2020-05-19 13:00:52 +02:00
t . Run ( "non-updatable jar from some other apex in the ART boot image => error" , func ( t * testing . T ) {
2021-04-27 13:42:20 +02:00
err := ` ArtApexJars expects this to be in apex "some-non-updatable-apex" but this is only in apexes.*"com.android.art.debug" `
2021-04-12 21:02:36 +02:00
// Update the dexpreopt ArtApexJars directly.
preparer := prepareSetArtJars ( "some-non-updatable-apex:some-non-updatable-apex-lib" )
testNoUpdatableJarsInBootImage ( t , err , preparer )
2020-05-19 13:00:52 +02:00
} )
2020-01-13 16:18:16 +01:00
2020-05-19 13:00:52 +02:00
t . Run ( "updatable jar from some other apex in the framework boot image => error" , func ( t * testing . T ) {
2021-04-12 21:02:36 +02:00
err := ` module "some-updatable-apex-lib" from updatable apexes \["some-updatable-apex"\] is not allowed in the framework boot image `
2021-08-06 18:49:46 +02:00
preparer := android . GroupFixturePreparers (
java . FixtureConfigureBootJars ( "some-updatable-apex:some-updatable-apex-lib" ) ,
java . FixtureConfigureApexBootJars ( "some-non-updatable-apex:some-non-updatable-apex-lib" ) ,
)
2021-04-12 21:02:36 +02:00
testNoUpdatableJarsInBootImage ( t , err , preparer )
2020-05-19 13:00:52 +02:00
} )
2020-01-13 16:18:16 +01:00
2020-05-19 13:00:52 +02:00
t . Run ( "non-updatable jar from some other apex in the framework boot image => ok" , func ( t * testing . T ) {
2021-08-06 18:49:46 +02:00
preparer := java . FixtureConfigureApexBootJars ( "some-non-updatable-apex:some-non-updatable-apex-lib" )
2021-06-16 02:42:33 +02:00
fragment := java . ApexVariantReference {
Apex : proptools . StringPtr ( "some-non-updatable-apex" ) ,
Module : proptools . StringPtr ( "some-non-updatable-fragment" ) ,
}
testNoUpdatableJarsInBootImage ( t , "" , preparer , fragment )
2020-05-19 13:00:52 +02:00
} )
2020-04-22 19:05:58 +02:00
2020-05-19 13:00:52 +02:00
t . Run ( "nonexistent jar in the ART boot image => error" , func ( t * testing . T ) {
2021-04-12 18:24:18 +02:00
err := ` "platform-bootclasspath" depends on undefined module "nonexistent" `
2021-04-12 21:02:36 +02:00
preparer := java . FixtureConfigureBootJars ( "platform:nonexistent" )
testNoUpdatableJarsInBootImage ( t , err , preparer )
2020-05-19 13:00:52 +02:00
} )
2020-01-13 16:18:16 +01:00
2020-05-19 13:00:52 +02:00
t . Run ( "nonexistent jar in the framework boot image => error" , func ( t * testing . T ) {
2021-04-12 18:24:18 +02:00
err := ` "platform-bootclasspath" depends on undefined module "nonexistent" `
2021-04-12 21:02:36 +02:00
preparer := java . FixtureConfigureBootJars ( "platform:nonexistent" )
testNoUpdatableJarsInBootImage ( t , err , preparer )
2020-05-19 13:00:52 +02:00
} )
2020-01-13 16:18:16 +01:00
2020-05-19 13:00:52 +02:00
t . Run ( "platform jar in the ART boot image => error" , func ( t * testing . T ) {
2021-04-27 13:42:20 +02:00
err := ` ArtApexJars is invalid as it requests a platform variant of "some-platform-lib" `
2021-04-12 21:02:36 +02:00
// Update the dexpreopt ArtApexJars directly.
preparer := prepareSetArtJars ( "platform:some-platform-lib" )
testNoUpdatableJarsInBootImage ( t , err , preparer )
2020-05-19 13:00:52 +02:00
} )
2020-01-13 16:18:16 +01:00
2020-05-19 13:00:52 +02:00
t . Run ( "platform jar in the framework boot image => ok" , func ( t * testing . T ) {
2021-08-06 18:49:46 +02:00
preparer := android . GroupFixturePreparers (
java . FixtureConfigureBootJars ( "platform:some-platform-lib" ) ,
java . FixtureConfigureApexBootJars ( "some-non-updatable-apex:some-non-updatable-apex-lib" ) ,
)
fragments := [ ] java . ApexVariantReference {
{
Apex : proptools . StringPtr ( "some-non-updatable-apex" ) ,
Module : proptools . StringPtr ( "some-non-updatable-fragment" ) ,
} ,
}
testNoUpdatableJarsInBootImage ( t , "" , preparer , fragments ... )
2020-05-19 13:00:52 +02:00
} )
2020-11-02 18:32:38 +01:00
}
func TestDexpreoptAccessDexFilesFromPrebuiltApex ( t * testing . T ) {
2021-08-06 18:49:46 +02:00
preparer := java . FixtureConfigureApexBootJars ( "myapex:libfoo" )
2020-11-02 18:32:38 +01:00
t . Run ( "prebuilt no source" , func ( t * testing . T ) {
2021-06-16 02:42:33 +02:00
fragment := java . ApexVariantReference {
Apex : proptools . StringPtr ( "myapex" ) ,
Module : proptools . StringPtr ( "my-bootclasspath-fragment" ) ,
2020-11-02 18:32:38 +01:00
}
testDexpreoptWithApexes ( t , `
prebuilt_apex {
name : "myapex" ,
arch : {
arm64 : {
src : "myapex-arm64.apex" ,
} ,
arm : {
src : "myapex-arm.apex" ,
} ,
} ,
2021-06-16 02:42:33 +02:00
exported_bootclasspath_fragments : [ "my-bootclasspath-fragment" ] ,
}
2020-11-02 18:32:38 +01:00
2021-06-16 02:42:33 +02:00
prebuilt_bootclasspath_fragment {
name : "my-bootclasspath-fragment" ,
contents : [ "libfoo" ] ,
apex_available : [ "myapex" ] ,
2021-07-19 14:23:40 +02:00
hidden_api : {
annotation_flags : "my-bootclasspath-fragment/annotation-flags.csv" ,
metadata : "my-bootclasspath-fragment/metadata.csv" ,
index : "my-bootclasspath-fragment/index.csv" ,
2021-08-10 17:14:16 +02:00
signature_patterns : "my-bootclasspath-fragment/signature-patterns.csv" ,
filtered_stub_flags : "my-bootclasspath-fragment/filtered-stub-flags.csv" ,
filtered_flags : "my-bootclasspath-fragment/filtered-flags.csv" ,
2021-07-19 14:23:40 +02:00
} ,
2021-06-16 02:42:33 +02:00
}
java_import {
name : "libfoo" ,
jars : [ "libfoo.jar" ] ,
apex_available : [ "myapex" ] ,
2021-08-06 18:49:46 +02:00
permitted_packages : [ "libfoo" ] ,
2021-06-16 02:42:33 +02:00
}
` , "" , preparer , fragment )
2020-11-02 18:32:38 +01:00
} )
2020-01-13 16:18:16 +01:00
}
2021-07-21 15:23:52 +02:00
func testApexPermittedPackagesRules ( t * testing . T , errmsg , bp string , bootJars [ ] string , rules [ ] android . Rule ) {
2020-06-05 22:14:03 +02:00
t . Helper ( )
bp += `
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
} `
2021-03-31 00:07:52 +02:00
fs := android . MockFS {
2020-06-05 22:14:03 +02:00
"lib1/src/A.java" : nil ,
"lib2/src/B.java" : nil ,
"system/sepolicy/apex/myapex-file_contexts" : nil ,
}
2021-03-31 00:07:52 +02:00
errorHandler := android . FixtureExpectsNoErrors
if errmsg != "" {
errorHandler = android . FixtureExpectsAtLeastOneErrorMatchingPattern ( errmsg )
2020-10-30 01:09:13 +01:00
}
2020-06-05 22:14:03 +02:00
2021-03-31 00:07:52 +02:00
android . GroupFixturePreparers (
android . PrepareForTestWithAndroidBuildComponents ,
java . PrepareForTestWithJavaBuildComponents ,
PrepareForTestWithApexBuildComponents ,
android . PrepareForTestWithNeverallowRules ( rules ) ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
2021-07-21 15:23:52 +02:00
apexBootJars := make ( [ ] string , 0 , len ( bootJars ) )
for _ , apexBootJar := range bootJars {
apexBootJars = append ( apexBootJars , "myapex:" + apexBootJar )
2021-03-31 00:07:52 +02:00
}
2021-07-21 15:23:52 +02:00
variables . ApexBootJars = android . CreateTestConfiguredJarList ( apexBootJars )
2021-03-31 00:07:52 +02:00
} ) ,
fs . AddToFixture ( ) ,
) .
ExtendWithErrorHandler ( errorHandler ) .
RunTestWithBp ( t , bp )
2020-06-05 22:14:03 +02:00
}
func TestApexPermittedPackagesRules ( t * testing . T ) {
testcases := [ ] struct {
name string
expectedError string
bp string
bootJars [ ] string
modulesPackages map [ string ] [ ] string
} {
{
name : "Non-Bootclasspath apex jar not satisfying allowed module packages." ,
expectedError : "" ,
bp : `
java_library {
name : "bcp_lib1" ,
srcs : [ "lib1/src/*.java" ] ,
permitted_packages : [ "foo.bar" ] ,
apex_available : [ "myapex" ] ,
sdk_version : "none" ,
system_modules : "none" ,
}
java_library {
name : "nonbcp_lib2" ,
srcs : [ "lib2/src/*.java" ] ,
apex_available : [ "myapex" ] ,
permitted_packages : [ "a.b" ] ,
sdk_version : "none" ,
system_modules : "none" ,
}
apex {
name : "myapex" ,
key : "myapex.key" ,
java_libs : [ "bcp_lib1" , "nonbcp_lib2" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-06-05 22:14:03 +02:00
} ` ,
bootJars : [ ] string { "bcp_lib1" } ,
modulesPackages : map [ string ] [ ] string {
"myapex" : [ ] string {
"foo.bar" ,
} ,
} ,
} ,
{
name : "Bootclasspath apex jar not satisfying allowed module packages." ,
expectedError : ` module "bcp_lib2" .* which is restricted because jars that are part of the myapex module may only allow these packages: foo.bar. Please jarjar or move code around. ` ,
bp : `
java_library {
name : "bcp_lib1" ,
srcs : [ "lib1/src/*.java" ] ,
apex_available : [ "myapex" ] ,
permitted_packages : [ "foo.bar" ] ,
sdk_version : "none" ,
system_modules : "none" ,
}
java_library {
name : "bcp_lib2" ,
srcs : [ "lib2/src/*.java" ] ,
apex_available : [ "myapex" ] ,
permitted_packages : [ "foo.bar" , "bar.baz" ] ,
sdk_version : "none" ,
system_modules : "none" ,
}
apex {
name : "myapex" ,
key : "myapex.key" ,
java_libs : [ "bcp_lib1" , "bcp_lib2" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-06-05 22:14:03 +02:00
}
` ,
bootJars : [ ] string { "bcp_lib1" , "bcp_lib2" } ,
modulesPackages : map [ string ] [ ] string {
"myapex" : [ ] string {
"foo.bar" ,
} ,
} ,
} ,
}
for _ , tc := range testcases {
t . Run ( tc . name , func ( t * testing . T ) {
rules := createApexPermittedPackagesRules ( tc . modulesPackages )
testApexPermittedPackagesRules ( t , tc . expectedError , tc . bp , tc . bootJars , rules )
} )
}
}
2020-04-13 09:19:48 +02:00
func TestTestFor ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-04-13 09:19:48 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" , "myprivlib" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-04-13 09:19:48 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
stubs : {
versions : [ "1" ] ,
} ,
apex_available : [ "myapex" ] ,
}
cc_library {
name : "myprivlib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" ] ,
}
cc_test {
name : "mytest" ,
gtest : false ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
2020-12-04 10:02:13 +01:00
shared_libs : [ "mylib" , "myprivlib" , "mytestlib" ] ,
2020-04-13 09:19:48 +02:00
test_for : [ "myapex" ]
}
2020-12-04 10:02:13 +01:00
cc_library {
name : "mytestlib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
shared_libs : [ "mylib" , "myprivlib" ] ,
stl : "none" ,
test_for : [ "myapex" ] ,
}
cc_benchmark {
name : "mybench" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
shared_libs : [ "mylib" , "myprivlib" ] ,
stl : "none" ,
test_for : [ "myapex" ] ,
}
2020-04-13 09:19:48 +02:00
` )
2021-03-25 02:25:06 +01:00
ensureLinkedLibIs := func ( mod , variant , linkedLib , expectedVariant string ) {
2021-03-29 01:42:57 +02:00
ldFlags := strings . Split ( ctx . ModuleForTests ( mod , variant ) . Rule ( "ld" ) . Args [ "libFlags" ] , " " )
2021-03-25 02:25:06 +01:00
mylibLdFlags := android . FilterListPred ( ldFlags , func ( s string ) bool { return strings . HasPrefix ( s , linkedLib ) } )
android . AssertArrayString ( t , "unexpected " + linkedLib + " link library for " + mod , [ ] string { linkedLib + expectedVariant } , mylibLdFlags )
}
// These modules are tests for the apex, therefore are linked to the
2020-04-13 09:19:48 +02:00
// actual implementation of mylib instead of its stub.
2021-03-25 02:25:06 +01:00
ensureLinkedLibIs ( "mytest" , "android_arm64_armv8-a" , "out/soong/.intermediates/mylib/" , "android_arm64_armv8-a_shared/mylib.so" )
ensureLinkedLibIs ( "mytestlib" , "android_arm64_armv8-a_shared" , "out/soong/.intermediates/mylib/" , "android_arm64_armv8-a_shared/mylib.so" )
ensureLinkedLibIs ( "mybench" , "android_arm64_armv8-a" , "out/soong/.intermediates/mylib/" , "android_arm64_armv8-a_shared/mylib.so" )
}
func TestIndirectTestFor ( t * testing . T ) {
ctx := testApex ( t , `
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" , "myprivlib" ] ,
updatable : false ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
stubs : {
versions : [ "1" ] ,
} ,
apex_available : [ "myapex" ] ,
}
cc_library {
name : "myprivlib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
shared_libs : [ "mylib" ] ,
apex_available : [ "myapex" ] ,
}
cc_library {
name : "mytestlib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
shared_libs : [ "myprivlib" ] ,
stl : "none" ,
test_for : [ "myapex" ] ,
}
` )
ensureLinkedLibIs := func ( mod , variant , linkedLib , expectedVariant string ) {
2021-03-29 01:42:57 +02:00
ldFlags := strings . Split ( ctx . ModuleForTests ( mod , variant ) . Rule ( "ld" ) . Args [ "libFlags" ] , " " )
2021-03-25 02:25:06 +01:00
mylibLdFlags := android . FilterListPred ( ldFlags , func ( s string ) bool { return strings . HasPrefix ( s , linkedLib ) } )
android . AssertArrayString ( t , "unexpected " + linkedLib + " link library for " + mod , [ ] string { linkedLib + expectedVariant } , mylibLdFlags )
}
// The platform variant of mytestlib links to the platform variant of the
// internal myprivlib.
ensureLinkedLibIs ( "mytestlib" , "android_arm64_armv8-a_shared" , "out/soong/.intermediates/myprivlib/" , "android_arm64_armv8-a_shared/myprivlib.so" )
// The platform variant of myprivlib links to the platform variant of mylib
// and bypasses its stubs.
ensureLinkedLibIs ( "myprivlib" , "android_arm64_armv8-a_shared" , "out/soong/.intermediates/mylib/" , "android_arm64_armv8-a_shared/mylib.so" )
2020-04-13 09:19:48 +02:00
}
2021-03-27 16:18:31 +01:00
func TestTestForForLibInOtherApex ( t * testing . T ) {
// This case is only allowed for known overlapping APEXes, i.e. the ART APEXes.
_ = testApex ( t , `
apex {
name : "com.android.art" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
updatable : false ,
}
apex {
name : "com.android.art.debug" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" , "mytestlib" ] ,
updatable : false ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
stubs : {
versions : [ "1" ] ,
} ,
apex_available : [ "com.android.art" , "com.android.art.debug" ] ,
}
cc_library {
name : "mytestlib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
shared_libs : [ "mylib" ] ,
stl : "none" ,
apex_available : [ "com.android.art.debug" ] ,
test_for : [ "com.android.art" ] ,
}
` ,
android . MockFS {
"system/sepolicy/apex/com.android.art-file_contexts" : nil ,
"system/sepolicy/apex/com.android.art.debug-file_contexts" : nil ,
} . AddToFixture ( ) )
}
2020-05-14 23:15:24 +02:00
// TODO(jungjw): Move this to proptools
func intPtr ( i int ) * int {
return & i
}
func TestApexSet ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-05-14 23:15:24 +02:00
apex_set {
name : "myapex" ,
set : "myapex.apks" ,
filename : "foo_v2.apex" ,
overrides : [ "foo" ] ,
}
2021-03-08 12:28:25 +01:00
` ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . Platform_sdk_version = intPtr ( 30 )
} ) ,
android . FixtureModifyConfig ( func ( config android . Config ) {
config . Targets [ android . Android ] = [ ] android . Target {
{ Os : android . Android , Arch : android . Arch { ArchType : android . Arm , ArchVariant : "armv7-a-neon" , Abi : [ ] string { "armeabi-v7a" } } } ,
{ Os : android . Android , Arch : android . Arch { ArchType : android . Arm64 , ArchVariant : "armv8-a" , Abi : [ ] string { "arm64-v8a" } } } ,
}
} ) ,
)
2020-05-14 23:15:24 +02:00
2021-04-06 17:09:30 +02:00
m := ctx . ModuleForTests ( "myapex.apex.extractor" , "android_common" )
2020-05-14 23:15:24 +02:00
// Check extract_apks tool parameters.
2021-04-06 17:09:30 +02:00
extractedApex := m . Output ( "extracted/myapex.apks" )
2020-05-14 23:15:24 +02:00
actual := extractedApex . Args [ "abis" ]
expected := "ARMEABI_V7A,ARM64_V8A"
if actual != expected {
t . Errorf ( "Unexpected abis parameter - expected %q vs actual %q" , expected , actual )
}
actual = extractedApex . Args [ "sdk-version" ]
expected = "30"
if actual != expected {
t . Errorf ( "Unexpected abis parameter - expected %q vs actual %q" , expected , actual )
}
2021-06-15 20:09:41 +02:00
m = ctx . ModuleForTests ( "myapex" , "android_common_myapex" )
2020-05-14 23:15:24 +02:00
a := m . Module ( ) . ( * ApexSet )
expectedOverrides := [ ] string { "foo" }
2020-07-03 22:18:24 +02:00
actualOverrides := android . AndroidMkEntriesForTest ( t , ctx , a ) [ 0 ] . EntryMap [ "LOCAL_OVERRIDES_MODULES" ]
2020-05-14 23:15:24 +02:00
if ! reflect . DeepEqual ( actualOverrides , expectedOverrides ) {
t . Errorf ( "Incorrect LOCAL_OVERRIDES_MODULES - expected %q vs actual %q" , expectedOverrides , actualOverrides )
}
}
2020-05-10 08:16:24 +02:00
func TestNoStaticLinkingToStubsLib ( t * testing . T ) {
testApexError ( t , ` .*required by "mylib" is a native library providing stub.* ` , `
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-05-10 08:16:24 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
static_libs : [ "otherlib" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" ] ,
}
cc_library {
name : "otherlib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
stubs : {
versions : [ "1" , "2" , "3" ] ,
} ,
apex_available : [ "myapex" ] ,
}
` )
}
2020-06-12 10:26:31 +02:00
func TestApexKeysTxt ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-06-12 10:26:31 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-06-12 10:26:31 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
prebuilt_apex {
name : "myapex" ,
prefer : true ,
arch : {
arm64 : {
src : "myapex-arm64.apex" ,
} ,
arm : {
src : "myapex-arm.apex" ,
} ,
} ,
}
apex_set {
name : "myapex_set" ,
set : "myapex.apks" ,
filename : "myapex_set.apex" ,
overrides : [ "myapex" ] ,
}
` )
apexKeysText := ctx . SingletonForTests ( "apex_keys_text" )
content := apexKeysText . MaybeDescription ( "apexkeys.txt" ) . BuildParams . Args [ "content" ]
ensureContains ( t , content , ` name="myapex_set.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" partition="system" ` )
2020-06-18 12:34:42 +02:00
ensureContains ( t , content , ` name="myapex.apex" public_key="PRESIGNED" private_key="PRESIGNED" container_certificate="PRESIGNED" container_private_key="PRESIGNED" partition="system" ` )
2020-06-12 10:26:31 +02:00
}
2020-06-20 05:47:47 +02:00
func TestAllowedFiles ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-06-20 05:47:47 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
apps : [ "app" ] ,
allowed_files : "allowed.txt" ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-06-20 05:47:47 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
android_app {
name : "app" ,
srcs : [ "foo/bar/MyClass.java" ] ,
package_name : "foo" ,
sdk_version : "none" ,
system_modules : "none" ,
apex_available : [ "myapex" ] ,
}
` , withFiles ( map [ string ] [ ] byte {
"sub/Android.bp" : [ ] byte ( `
override_apex {
name : "override_myapex" ,
base : "myapex" ,
apps : [ "override_app" ] ,
allowed_files : ":allowed" ,
}
// Overridable "path" property should be referenced indirectly
filegroup {
name : "allowed" ,
srcs : [ "allowed.txt" ] ,
}
override_android_app {
name : "override_app" ,
base : "app" ,
package_name : "bar" ,
}
` ) ,
} ) )
rule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "diffApexContentRule" )
if expected , actual := "allowed.txt" , rule . Args [ "allowed_files_file" ] ; expected != actual {
t . Errorf ( "allowed_files_file: expected %q but got %q" , expected , actual )
}
rule2 := ctx . ModuleForTests ( "myapex" , "android_common_override_myapex_myapex_image" ) . Rule ( "diffApexContentRule" )
if expected , actual := "sub/allowed.txt" , rule2 . Args [ "allowed_files_file" ] ; expected != actual {
t . Errorf ( "allowed_files_file: expected %q but got %q" , expected , actual )
}
}
2020-07-06 23:56:01 +02:00
func TestNonPreferredPrebuiltDependency ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
testApex ( t , `
2020-07-06 23:56:01 +02:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-07-06 23:56:01 +02:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
stubs : {
2020-07-23 07:32:17 +02:00
versions : [ "current" ] ,
2020-07-06 23:56:01 +02:00
} ,
apex_available : [ "myapex" ] ,
}
cc_prebuilt_library_shared {
name : "mylib" ,
prefer : false ,
srcs : [ "prebuilt.so" ] ,
stubs : {
2020-07-23 07:32:17 +02:00
versions : [ "current" ] ,
2020-07-06 23:56:01 +02:00
} ,
apex_available : [ "myapex" ] ,
}
` )
}
2020-11-26 14:32:26 +01:00
func TestCompressedApex ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-11-26 14:32:26 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
compressible : true ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-11-26 14:32:26 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
2021-03-08 12:28:25 +01:00
` ,
android . FixtureModifyProductVariables ( func ( variables android . FixtureProductVariables ) {
variables . CompressedApex = proptools . BoolPtr ( true )
} ) ,
)
2020-11-26 14:32:26 +01:00
compressRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "compressRule" )
ensureContains ( t , compressRule . Output . String ( ) , "myapex.capex.unsigned" )
signApkRule := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Description ( "sign compressedApex" )
ensureEquals ( t , signApkRule . Input . String ( ) , compressRule . Output . String ( ) )
// Make sure output of bundle is .capex
ab := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Module ( ) . ( * apexBundle )
ensureContains ( t , ab . outputFile . String ( ) , "myapex.capex" )
// Verify android.mk rules
2020-07-03 22:18:24 +02:00
data := android . AndroidMkDataForTest ( t , ctx , ab )
2020-11-26 14:32:26 +01:00
var builder strings . Builder
data . Custom ( & builder , ab . BaseModuleName ( ) , "TARGET_" , "" , data )
androidMk := builder . String ( )
ensureContains ( t , androidMk , "LOCAL_MODULE_STEM := myapex.capex\n" )
}
2020-12-02 16:03:42 +01:00
func TestPreferredPrebuiltSharedLibDep ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-12-02 16:03:42 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-12-02 16:03:42 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
apex_available : [ "myapex" ] ,
shared_libs : [ "otherlib" ] ,
system_shared_libs : [ ] ,
}
cc_library {
name : "otherlib" ,
srcs : [ "mylib.cpp" ] ,
stubs : {
versions : [ "current" ] ,
} ,
}
cc_prebuilt_library_shared {
name : "otherlib" ,
prefer : true ,
srcs : [ "prebuilt.so" ] ,
stubs : {
versions : [ "current" ] ,
} ,
}
` )
ab := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Module ( ) . ( * apexBundle )
2020-07-03 22:18:24 +02:00
data := android . AndroidMkDataForTest ( t , ctx , ab )
2020-12-02 16:03:42 +01:00
var builder strings . Builder
data . Custom ( & builder , ab . BaseModuleName ( ) , "TARGET_" , "" , data )
androidMk := builder . String ( )
// The make level dependency needs to be on otherlib - prebuilt_otherlib isn't
// a thing there.
ensureContains ( t , androidMk , "LOCAL_REQUIRED_MODULES += otherlib\n" )
}
2020-12-03 09:28:25 +01:00
func TestExcludeDependency ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , `
2020-12-03 09:28:25 +01:00
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-12-03 09:28:25 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" ] ,
shared_libs : [ "mylib2" ] ,
target : {
apex : {
exclude_shared_libs : [ "mylib2" ] ,
} ,
} ,
}
cc_library {
name : "mylib2" ,
srcs : [ "mylib.cpp" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
}
` )
// Check if mylib is linked to mylib2 for the non-apex target
ldFlags := ctx . ModuleForTests ( "mylib" , "android_arm64_armv8-a_shared" ) . Rule ( "ld" ) . Args [ "libFlags" ]
ensureContains ( t , ldFlags , "mylib2/android_arm64_armv8-a_shared/mylib2.so" )
// Make sure that the link doesn't occur for the apex target
ldFlags = ctx . ModuleForTests ( "mylib" , "android_arm64_armv8-a_shared_apex10000" ) . Rule ( "ld" ) . Args [ "libFlags" ]
ensureNotContains ( t , ldFlags , "mylib2/android_arm64_armv8-a_shared_apex10000/mylib2.so" )
// It shouldn't appear in the copy cmd as well.
copyCmds := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Rule ( "apexRule" ) . Args [ "copy_commands" ]
ensureNotContains ( t , copyCmds , "image.apex/lib64/mylib2.so" )
}
2020-12-09 13:18:56 +01:00
func TestPrebuiltStubLibDep ( t * testing . T ) {
bpBase := `
apex {
name : "myapex" ,
key : "myapex.key" ,
native_shared_libs : [ "mylib" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-12-09 13:18:56 +01:00
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_library {
name : "mylib" ,
srcs : [ "mylib.cpp" ] ,
apex_available : [ "myapex" ] ,
shared_libs : [ "stublib" ] ,
system_shared_libs : [ ] ,
}
apex {
name : "otherapex" ,
enabled : % s ,
key : "myapex.key" ,
native_shared_libs : [ "stublib" ] ,
2021-02-16 12:40:16 +01:00
updatable : false ,
2020-12-09 13:18:56 +01:00
}
`
stublibSourceBp := `
cc_library {
name : "stublib" ,
srcs : [ "mylib.cpp" ] ,
apex_available : [ "otherapex" ] ,
system_shared_libs : [ ] ,
stl : "none" ,
stubs : {
versions : [ "1" ] ,
} ,
}
`
stublibPrebuiltBp := `
cc_prebuilt_library_shared {
name : "stublib" ,
srcs : [ "prebuilt.so" ] ,
apex_available : [ "otherapex" ] ,
stubs : {
versions : [ "1" ] ,
} ,
% s
}
`
tests := [ ] struct {
name string
stublibBp string
usePrebuilt bool
modNames [ ] string // Modules to collect AndroidMkEntries for
otherApexEnabled [ ] string
} {
{
name : "only_source" ,
stublibBp : stublibSourceBp ,
usePrebuilt : false ,
modNames : [ ] string { "stublib" } ,
otherApexEnabled : [ ] string { "true" , "false" } ,
} ,
{
name : "source_preferred" ,
stublibBp : stublibSourceBp + fmt . Sprintf ( stublibPrebuiltBp , "" ) ,
usePrebuilt : false ,
modNames : [ ] string { "stublib" , "prebuilt_stublib" } ,
otherApexEnabled : [ ] string { "true" , "false" } ,
} ,
{
name : "prebuilt_preferred" ,
stublibBp : stublibSourceBp + fmt . Sprintf ( stublibPrebuiltBp , "prefer: true," ) ,
usePrebuilt : true ,
modNames : [ ] string { "stublib" , "prebuilt_stublib" } ,
otherApexEnabled : [ ] string { "false" } , // No "true" since APEX cannot depend on prebuilt.
} ,
{
name : "only_prebuilt" ,
stublibBp : fmt . Sprintf ( stublibPrebuiltBp , "" ) ,
usePrebuilt : true ,
modNames : [ ] string { "stublib" } ,
otherApexEnabled : [ ] string { "false" } , // No "true" since APEX cannot depend on prebuilt.
} ,
}
for _ , test := range tests {
t . Run ( test . name , func ( t * testing . T ) {
for _ , otherApexEnabled := range test . otherApexEnabled {
t . Run ( "otherapex_enabled_" + otherApexEnabled , func ( t * testing . T ) {
2021-02-17 02:55:47 +01:00
ctx := testApex ( t , fmt . Sprintf ( bpBase , otherApexEnabled ) + test . stublibBp )
2020-12-09 13:18:56 +01:00
type modAndMkEntries struct {
mod * cc . Module
mkEntries android . AndroidMkEntries
}
entries := [ ] * modAndMkEntries { }
// Gather shared lib modules that are installable
for _ , modName := range test . modNames {
for _ , variant := range ctx . ModuleVariantsForTests ( modName ) {
if ! strings . HasPrefix ( variant , "android_arm64_armv8-a_shared" ) {
continue
}
mod := ctx . ModuleForTests ( modName , variant ) . Module ( ) . ( * cc . Module )
2020-12-16 19:20:23 +01:00
if ! mod . Enabled ( ) || mod . IsHideFromMake ( ) {
2020-12-09 13:18:56 +01:00
continue
}
2020-07-03 22:18:24 +02:00
for _ , ent := range android . AndroidMkEntriesForTest ( t , ctx , mod ) {
2020-12-09 13:18:56 +01:00
if ent . Disabled {
continue
}
entries = append ( entries , & modAndMkEntries {
mod : mod ,
mkEntries : ent ,
} )
}
}
}
var entry * modAndMkEntries = nil
for _ , ent := range entries {
if strings . Join ( ent . mkEntries . EntryMap [ "LOCAL_MODULE" ] , "," ) == "stublib" {
if entry != nil {
t . Errorf ( "More than one AndroidMk entry for \"stublib\": %s and %s" , entry . mod , ent . mod )
} else {
entry = ent
}
}
}
if entry == nil {
t . Errorf ( "AndroidMk entry for \"stublib\" missing" )
} else {
isPrebuilt := entry . mod . Prebuilt ( ) != nil
if isPrebuilt != test . usePrebuilt {
t . Errorf ( "Wrong module for \"stublib\" AndroidMk entry: got prebuilt %t, want prebuilt %t" , isPrebuilt , test . usePrebuilt )
}
if ! entry . mod . IsStubs ( ) {
t . Errorf ( "Module for \"stublib\" AndroidMk entry isn't a stub: %s" , entry . mod )
}
if entry . mkEntries . EntryMap [ "LOCAL_NOT_AVAILABLE_FOR_PLATFORM" ] != nil {
t . Errorf ( "AndroidMk entry for \"stublib\" has LOCAL_NOT_AVAILABLE_FOR_PLATFORM set: %+v" , entry . mkEntries )
}
2020-12-14 01:20:00 +01:00
cflags := entry . mkEntries . EntryMap [ "LOCAL_EXPORT_CFLAGS" ]
"current" is implicitly added to stubs.versions
So far, when a library `libfoo` has `stubs.versions: ["10", "11"]`, then
`shared_libs: ["libfoo"]` is linked to the version 11 of the stub.
This requires the author of `libfoo` to manually update the property
whenever a new version is introduced. Otherwise, clients are not able
to use the newly added APIs because the latest stub is for an old
version.
This change eliminates the need for manual updating. "current" version
is always implicitly added to `stubs.versions`. It is added even when
nothing is set on the property, if `stubs.symbol_file` is set. i.e.
```
cc_library {
name: "libfoo",
stubs: {
symbol_file: "libfoo.map.txt",
// no versions: [...] needed
},
}
cc_library {
name: "a_client",
shared_libs: ["libfoo"],
apex_available: ["myapex"],
min_sdk_version: "29",
}
apex {
name: "myapex",
native_shared_libraries: ["a_client"],
min_sdk_version: "29",
}
```
`a_client` links to the "current" stub of `libfoo` that has all symbols
shown in the map file.
Note that, above doesn't mean that the client has unlimited access to
APIs that are introduced even after the min_sdk_version of the client
(29 in this example). The use of such APIs still has to be guarded with
`__builtin_available` check.
Bug: N/A
Test: m
Change-Id: I70bb1600c18e74d36c6b24c3569d2149f02aaf96
2021-03-17 12:21:35 +01:00
expected := "-D__STUBLIB_API__=10000"
2020-12-14 01:20:00 +01:00
if ! android . InList ( expected , cflags ) {
t . Errorf ( "LOCAL_EXPORT_CFLAGS expected to have %q, but got %q" , expected , cflags )
}
2020-12-09 13:18:56 +01:00
}
} )
}
} )
}
}
2021-05-21 21:57:29 +02:00
func TestHostApexInHostOnlyBuild ( t * testing . T ) {
testApex ( t , `
apex {
name : "myapex" ,
host_supported : true ,
key : "myapex.key" ,
updatable : false ,
payload_type : "zip" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
` ,
android . FixtureModifyConfig ( func ( config android . Config ) {
// We may not have device targets in all builds, e.g. in
// prebuilts/build-tools/build-prebuilts.sh
config . Targets [ android . Android ] = [ ] android . Target { }
} ) )
}
2021-05-26 03:16:02 +02:00
func TestApexJavaCoverage ( t * testing . T ) {
bp := `
apex {
name : "myapex" ,
key : "myapex.key" ,
java_libs : [ "mylib" ] ,
bootclasspath_fragments : [ "mybootclasspathfragment" ] ,
systemserverclasspath_fragments : [ "mysystemserverclasspathfragment" ] ,
updatable : false ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
java_library {
name : "mylib" ,
srcs : [ "mylib.java" ] ,
apex_available : [ "myapex" ] ,
compile_dex : true ,
}
bootclasspath_fragment {
name : "mybootclasspathfragment" ,
contents : [ "mybootclasspathlib" ] ,
apex_available : [ "myapex" ] ,
}
java_library {
name : "mybootclasspathlib" ,
srcs : [ "mybootclasspathlib.java" ] ,
apex_available : [ "myapex" ] ,
compile_dex : true ,
}
systemserverclasspath_fragment {
name : "mysystemserverclasspathfragment" ,
contents : [ "mysystemserverclasspathlib" ] ,
apex_available : [ "myapex" ] ,
}
java_library {
name : "mysystemserverclasspathlib" ,
srcs : [ "mysystemserverclasspathlib.java" ] ,
apex_available : [ "myapex" ] ,
compile_dex : true ,
}
`
result := android . GroupFixturePreparers (
PrepareForTestWithApexBuildComponents ,
prepareForTestWithMyapex ,
java . PrepareForTestWithJavaDefaultModules ,
android . PrepareForTestWithAndroidBuildComponents ,
android . FixtureWithRootAndroidBp ( bp ) ,
2021-08-06 18:49:46 +02:00
dexpreopt . FixtureSetApexBootJars ( "myapex:mybootclasspathlib" ) ,
dexpreopt . FixtureSetApexSystemServerJars ( "myapex:mysystemserverclasspathlib" ) ,
2021-05-26 03:16:02 +02:00
android . FixtureMergeEnv ( map [ string ] string {
"EMMA_INSTRUMENT" : "true" ,
} ) ,
) . RunTest ( t )
// Make sure jacoco ran on both mylib and mybootclasspathlib
if result . ModuleForTests ( "mylib" , "android_common_apex10000" ) . MaybeRule ( "jacoco" ) . Rule == nil {
t . Errorf ( "Failed to find jacoco rule for mylib" )
}
if result . ModuleForTests ( "mybootclasspathlib" , "android_common_apex10000" ) . MaybeRule ( "jacoco" ) . Rule == nil {
t . Errorf ( "Failed to find jacoco rule for mybootclasspathlib" )
}
if result . ModuleForTests ( "mysystemserverclasspathlib" , "android_common_apex10000" ) . MaybeRule ( "jacoco" ) . Rule == nil {
t . Errorf ( "Failed to find jacoco rule for mysystemserverclasspathlib" )
}
}
2021-08-03 09:52:17 +02:00
func TestProhibitStaticExecutable ( t * testing . T ) {
testApexError ( t , ` executable mybin is static ` , `
apex {
name : "myapex" ,
key : "myapex.key" ,
binaries : [ "mybin" ] ,
min_sdk_version : "29" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
cc_binary {
name : "mybin" ,
srcs : [ "mylib.cpp" ] ,
relative_install_path : "foo/bar" ,
static_executable : true ,
system_shared_libs : [ ] ,
stl : "none" ,
apex_available : [ "myapex" ] ,
2021-08-03 06:36:09 +02:00
min_sdk_version : "29" ,
}
` )
testApexError ( t , ` executable mybin.rust is static ` , `
apex {
name : "myapex" ,
key : "myapex.key" ,
binaries : [ "mybin.rust" ] ,
min_sdk_version : "29" ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
rust_binary {
name : "mybin.rust" ,
srcs : [ "foo.rs" ] ,
static_executable : true ,
apex_available : [ "myapex" ] ,
min_sdk_version : "29" ,
2021-08-03 09:52:17 +02:00
}
` )
}
2021-09-30 11:34:26 +02:00
func TestAndroidMk_DexpreoptBuiltInstalledForApex ( t * testing . T ) {
ctx := testApex ( t , `
apex {
name : "myapex" ,
key : "myapex.key" ,
updatable : false ,
java_libs : [ "foo" ] ,
}
apex_key {
name : "myapex.key" ,
public_key : "testkey.avbpubkey" ,
private_key : "testkey.pem" ,
}
java_library {
name : "foo" ,
srcs : [ "foo.java" ] ,
apex_available : [ "myapex" ] ,
installable : true ,
}
` ,
dexpreopt . FixtureSetApexSystemServerJars ( "myapex:foo" ) ,
)
apexBundle := ctx . ModuleForTests ( "myapex" , "android_common_myapex_image" ) . Module ( ) . ( * apexBundle )
data := android . AndroidMkDataForTest ( t , ctx , apexBundle )
var builder strings . Builder
data . Custom ( & builder , apexBundle . BaseModuleName ( ) , "TARGET_" , "" , data )
androidMk := builder . String ( )
ensureContains ( t , androidMk , "LOCAL_REQUIRED_MODULES += foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.odex foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.vdex" )
}
func TestAndroidMk_DexpreoptBuiltInstalledForApex_Prebuilt ( t * testing . T ) {
ctx := testApex ( t , `
prebuilt_apex {
name : "myapex" ,
arch : {
arm64 : {
src : "myapex-arm64.apex" ,
} ,
arm : {
src : "myapex-arm.apex" ,
} ,
} ,
exported_java_libs : [ "foo" ] ,
}
java_import {
name : "foo" ,
jars : [ "foo.jar" ] ,
installable : true ,
}
` ,
dexpreopt . FixtureSetApexSystemServerJars ( "myapex:foo" ) ,
)
prebuilt := ctx . ModuleForTests ( "myapex" , "android_common_myapex" ) . Module ( ) . ( * Prebuilt )
entriesList := android . AndroidMkEntriesForTest ( t , ctx , prebuilt )
mainModuleEntries := entriesList [ 0 ]
android . AssertArrayString ( t ,
"LOCAL_REQUIRED_MODULES" ,
mainModuleEntries . EntryMap [ "LOCAL_REQUIRED_MODULES" ] ,
[ ] string {
"foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.odex" ,
"foo-dexpreopt-arm64-apex@myapex@javalib@foo.jar@classes.vdex" ,
} )
}
2019-06-25 20:20:53 +02:00
func TestMain ( m * testing . M ) {
2021-03-29 01:21:08 +02:00
os . Exit ( m . Run ( ) )
2019-06-25 20:20:53 +02:00
}