aboutsummaryrefslogtreecommitdiffstats
path: root/cc/cc_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'cc/cc_test.go')
-rw-r--r--cc/cc_test.go620
1 files changed, 604 insertions, 16 deletions
diff --git a/cc/cc_test.go b/cc/cc_test.go
index 4d8c4fb2..19e4703b 100644
--- a/cc/cc_test.go
+++ b/cc/cc_test.go
@@ -22,6 +22,7 @@ import (
"io/ioutil"
"os"
"reflect"
+ "regexp"
"sort"
"strings"
"testing"
@@ -52,10 +53,7 @@ func TestMain(m *testing.M) {
os.Exit(run())
}
-func testCc(t *testing.T, bp string) *android.TestContext {
- config := android.TestArchConfig(buildDir, nil)
- config.ProductVariables.DeviceVndkVersion = StringPtr("current")
-
+func createTestContext(t *testing.T, config android.Config, bp string) *android.TestContext {
ctx := android.NewTestArchContext()
ctx.RegisterModuleType("cc_library", android.ModuleFactoryAdaptor(LibraryFactory))
ctx.RegisterModuleType("cc_library_shared", android.ModuleFactoryAdaptor(LibrarySharedFactory))
@@ -90,8 +88,8 @@ func testCc(t *testing.T, bp string) *android.TestContext {
cc_library {
name: "libc",
- no_libgcc : true,
- nocrt : true,
+ no_libgcc: true,
+ nocrt: true,
system_shared_libs: [],
}
llndk_library {
@@ -100,8 +98,8 @@ func testCc(t *testing.T, bp string) *android.TestContext {
}
cc_library {
name: "libm",
- no_libgcc : true,
- nocrt : true,
+ no_libgcc: true,
+ nocrt: true,
system_shared_libs: [],
}
llndk_library {
@@ -110,8 +108,8 @@ func testCc(t *testing.T, bp string) *android.TestContext {
}
cc_library {
name: "libdl",
- no_libgcc : true,
- nocrt : true,
+ no_libgcc: true,
+ nocrt: true,
system_shared_libs: [],
}
llndk_library {
@@ -142,6 +140,12 @@ func testCc(t *testing.T, bp string) *android.TestContext {
"my_include": nil,
})
+ return ctx
+}
+
+func testCcWithConfig(t *testing.T, bp string, config android.Config) *android.TestContext {
+ ctx := createTestContext(t, config, bp)
+
_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
failIfErrored(t, errs)
_, errs = ctx.PrepareBuildActions(config)
@@ -150,14 +154,56 @@ func testCc(t *testing.T, bp string) *android.TestContext {
return ctx
}
+func testCc(t *testing.T, bp string) *android.TestContext {
+ config := android.TestArchConfig(buildDir, nil)
+ config.ProductVariables.DeviceVndkVersion = StringPtr("current")
+ config.ProductVariables.Platform_vndk_version = StringPtr("VER")
+
+ return testCcWithConfig(t, bp, config)
+}
+
+func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
+ config := android.TestArchConfig(buildDir, nil)
+ config.ProductVariables.Platform_vndk_version = StringPtr("VER")
+
+ return testCcWithConfig(t, bp, config)
+}
+
+func testCcError(t *testing.T, pattern string, bp string) {
+ config := android.TestArchConfig(buildDir, nil)
+ config.ProductVariables.DeviceVndkVersion = StringPtr("current")
+ config.ProductVariables.Platform_vndk_version = StringPtr("VER")
+
+ ctx := createTestContext(t, config, bp)
+
+ _, errs := ctx.ParseFileList(".", []string{"Android.bp"})
+ if len(errs) > 0 {
+ failIfNoMatchingErrors(t, pattern, errs)
+ return
+ }
+
+ _, errs = ctx.PrepareBuildActions(config)
+ if len(errs) > 0 {
+ failIfNoMatchingErrors(t, pattern, errs)
+ return
+ }
+
+ t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
+}
+
+const (
+ coreVariant = "android_arm64_armv8-a_core_shared"
+ vendorVariant = "android_arm64_armv8-a_vendor_shared"
+)
+
func TestVendorSrc(t *testing.T) {
ctx := testCc(t, `
cc_library {
name: "libTest",
srcs: ["foo.c"],
- no_libgcc : true,
- nocrt : true,
- system_shared_libs : [],
+ no_libgcc: true,
+ nocrt: true,
+ system_shared_libs: [],
vendor_available: true,
target: {
vendor: {
@@ -167,7 +213,7 @@ func TestVendorSrc(t *testing.T) {
}
`)
- ld := ctx.ModuleForTests("libTest", "android_arm_armv7-a-neon_vendor_shared").Rule("ld")
+ ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
var objs []string
for _, o := range ld.Inputs {
objs = append(objs, o.Base())
@@ -177,6 +223,524 @@ func TestVendorSrc(t *testing.T) {
}
}
+func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
+ isVndkSp bool, extends string) {
+
+ mod := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
+ if !mod.hasVendorVariant() {
+ t.Error("%q must have vendor variant", name)
+ }
+
+ // Check library properties.
+ lib, ok := mod.compiler.(*libraryDecorator)
+ if !ok {
+ t.Errorf("%q must have libraryDecorator", name)
+ } else if lib.baseInstaller.subDir != subDir {
+ t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
+ lib.baseInstaller.subDir)
+ }
+
+ // Check VNDK properties.
+ if mod.vndkdep == nil {
+ t.Fatalf("%q must have `vndkdep`", name)
+ }
+ if !mod.isVndk() {
+ t.Errorf("%q isVndk() must equal to true", name)
+ }
+ if mod.isVndkSp() != isVndkSp {
+ t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
+ }
+
+ // Check VNDK extension properties.
+ isVndkExt := extends != ""
+ if mod.isVndkExt() != isVndkExt {
+ t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
+ }
+
+ if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
+ t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
+ }
+}
+
+func TestVndk(t *testing.T) {
+ ctx := testCc(t, `
+ cc_library {
+ name: "libvndk",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_private",
+ vendor_available: false,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_sp",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_sp_private",
+ vendor_available: false,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ nocrt: true,
+ }
+ `)
+
+ checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "")
+ checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "")
+ checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "")
+ checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "")
+}
+
+func TestVndkExt(t *testing.T) {
+ // This test checks the VNDK-Ext properties.
+ ctx := testCc(t, `
+ cc_library {
+ name: "libvndk",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_ext",
+ vendor: true,
+ vndk: {
+ enabled: true,
+ extends: "libvndk",
+ },
+ nocrt: true,
+ }
+ `)
+
+ checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk")
+}
+
+func TestVndkExtNoVndk(t *testing.T) {
+ // This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
+ ctx := testCcNoVndk(t, `
+ cc_library {
+ name: "libvndk",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_ext",
+ vendor: true,
+ vndk: {
+ enabled: true,
+ extends: "libvndk",
+ },
+ nocrt: true,
+ }
+ `)
+
+ // Ensures that the core variant of "libvndk_ext" can be found.
+ mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
+ if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
+ t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
+ }
+}
+
+func TestVndkExtError(t *testing.T) {
+ // This test ensures an error is emitted in ill-formed vndk-ext definition.
+ testCcError(t, "must set `vendor: true` to set `extends: \".*\"`", `
+ cc_library {
+ name: "libvndk",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_ext",
+ vndk: {
+ enabled: true,
+ extends: "libvndk",
+ },
+ nocrt: true,
+ }
+ `)
+
+ testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
+ cc_library {
+ name: "libvndk",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_ext",
+ vendor: true,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+ `)
+}
+
+func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
+ // This test ensures an error is emitted for inconsistent support_system_process.
+ testCcError(t, "module \".*\" with mismatched support_system_process", `
+ cc_library {
+ name: "libvndk",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_sp_ext",
+ vendor: true,
+ vndk: {
+ enabled: true,
+ extends: "libvndk",
+ support_system_process: true,
+ },
+ nocrt: true,
+ }
+ `)
+
+ testCcError(t, "module \".*\" with mismatched support_system_process", `
+ cc_library {
+ name: "libvndk_sp",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_ext",
+ vendor: true,
+ vndk: {
+ enabled: true,
+ extends: "libvndk_sp",
+ },
+ nocrt: true,
+ }
+ `)
+}
+
+func TestVndkExtVendorAvailableFalseError(t *testing.T) {
+ // This test ensures an error is emitted when a vndk-ext library extends a vndk library
+ // with `vendor_available: false`.
+ testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
+ cc_library {
+ name: "libvndk",
+ vendor_available: false,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_ext",
+ vendor: true,
+ vndk: {
+ enabled: true,
+ extends: "libvndk",
+ },
+ nocrt: true,
+ }
+ `)
+}
+
+func TestVendorModuleUsesVndkExt(t *testing.T) {
+ // This test ensures a vendor module can depend on a vndk-ext library.
+ testCc(t, `
+ cc_library {
+ name: "libvndk",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_ext",
+ vendor: true,
+ vndk: {
+ enabled: true,
+ extends: "libvndk",
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+
+ name: "libvndk_sp",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_sp_ext",
+ vendor: true,
+ vndk: {
+ enabled: true,
+ extends: "libvndk_sp",
+ support_system_process: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvendor",
+ vendor: true,
+ shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
+ nocrt: true,
+ }
+ `)
+}
+
+func TestVndkExtUsesVendorLib(t *testing.T) {
+ // This test ensures a vndk-ext library can depend on a vendor library.
+ testCc(t, `
+ cc_library {
+ name: "libvndk",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_ext",
+ vendor: true,
+ vndk: {
+ enabled: true,
+ extends: "libvndk",
+ },
+ shared_libs: ["libvendor"],
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvendor",
+ vendor: true,
+ nocrt: true,
+ }
+ `)
+}
+
+func TestVndkSpExtUsesVendorLibError(t *testing.T) {
+ // This test ensures an error is emitted if a vndk-sp-ext library depends on a vendor
+ // library.
+ testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
+ cc_library {
+ name: "libvndk_sp",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_sp_ext",
+ vendor: true,
+ vndk: {
+ enabled: true,
+ extends: "libvndk_sp",
+ support_system_process: true,
+ },
+ shared_libs: ["libvendor"], // Cause an error
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvendor",
+ vendor: true,
+ nocrt: true,
+ }
+ `)
+}
+
+func TestVndkUsesVndkExtError(t *testing.T) {
+ // This test ensures an error is emitted if a vndk/vndk-sp library depends on a
+ // vndk-ext/vndk-sp-ext library.
+ testCcError(t, "dependency \".*\" of \".*\" missing variant", `
+ cc_library {
+ name: "libvndk",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_ext",
+ vendor: true,
+ vndk: {
+ enabled: true,
+ extends: "libvndk",
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk2",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ shared_libs: ["libvndk_ext"],
+ nocrt: true,
+ }
+ `)
+
+ // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
+ // but target.vendor.shared_libs has not been supported yet.
+ testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
+ cc_library {
+ name: "libvndk",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_ext",
+ vendor: true,
+ vndk: {
+ enabled: true,
+ extends: "libvndk",
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk2",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ target: {
+ vendor: {
+ shared_libs: ["libvndk_ext"],
+ },
+ },
+ nocrt: true,
+ }
+ `)
+
+ testCcError(t, "dependency \".*\" of \".*\" missing variant", `
+ cc_library {
+ name: "libvndk_sp",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_sp_ext",
+ vendor: true,
+ vndk: {
+ enabled: true,
+ extends: "libvndk_sp",
+ support_system_process: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_sp_2",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ support_system_process: true,
+ },
+ shared_libs: ["libvndk_sp_ext"],
+ nocrt: true,
+ }
+ `)
+
+ // The pattern should be "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\""
+ // but target.vendor.shared_libs has not been supported yet.
+ testCcError(t, "unrecognized property \"target.vendor.shared_libs\"", `
+ cc_library {
+ name: "libvndk_sp",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_sp_ext",
+ vendor: true,
+ vndk: {
+ enabled: true,
+ extends: "libvndk_sp",
+ },
+ nocrt: true,
+ }
+
+ cc_library {
+ name: "libvndk_sp2",
+ vendor_available: true,
+ vndk: {
+ enabled: true,
+ },
+ target: {
+ vendor: {
+ shared_libs: ["libvndk_sp_ext"],
+ },
+ },
+ nocrt: true,
+ }
+ `)
+}
+
var (
str11 = "01234567891"
str10 = str11[:10]
@@ -499,6 +1063,7 @@ func TestLinkReordering(t *testing.T) {
}
}
}
+
func failIfErrored(t *testing.T, errs []error) {
if len(errs) > 0 {
for _, err := range errs {
@@ -508,6 +1073,29 @@ func failIfErrored(t *testing.T, errs []error) {
}
}
+func failIfNoMatchingErrors(t *testing.T, pattern string, errs []error) {
+ matcher, err := regexp.Compile(pattern)
+ if err != nil {
+ t.Errorf("failed to compile regular expression %q because %s", pattern, err)
+ }
+
+ found := false
+
+ for _, err := range errs {
+ if matcher.FindStringIndex(err.Error()) != nil {
+ found = true
+ break
+ }
+ }
+
+ if !found {
+ t.Errorf("missing the expected error %q (checked %d error(s))", pattern, len(errs))
+ for i, err := range errs {
+ t.Errorf("errs[%d] = %s", i, err)
+ }
+ }
+}
+
func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
for _, moduleName := range moduleNames {
module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
@@ -597,8 +1185,8 @@ func TestLlndkHeaders(t *testing.T) {
shared_libs: ["libllndk"],
vendor: true,
srcs: ["foo.c"],
- no_libgcc : true,
- nocrt : true,
+ no_libgcc: true,
+ nocrt: true,
}
`)