1// Copyright 2020 The Android Open Source Project 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package rust 16 17import ( 18 "strings" 19 "testing" 20 21 "android/soong/android" 22 "android/soong/cc" 23) 24 25// Test that cc modules can depend on vendor_available rust_ffi_static libraries. 26func TestVendorLinkage(t *testing.T) { 27 ctx := testRust(t, ` 28 cc_binary { 29 name: "fizz_vendor_available", 30 static_libs: [ 31 "libfoo_vendor", 32 ], 33 vendor_available: true, 34 } 35 cc_binary { 36 name: "fizz_soc_specific", 37 static_libs: ["libfoo_vendor"], 38 soc_specific: true, 39 } 40 rust_ffi_static { 41 name: "libfoo_vendor", 42 crate_name: "foo", 43 srcs: ["foo.rs"], 44 vendor_available: true, 45 } 46 `) 47 48 vendorBinary := ctx.ModuleForTests(t, "fizz_vendor_available", "android_vendor_arm64_armv8-a").Module().(*cc.Module) 49 50 if android.InList("libfoo_vendor.vendor", vendorBinary.Properties.AndroidMkStaticLibs) { 51 t.Errorf("vendorBinary should not have a staticlib dependency on libfoo_vendor.vendor: %#v", vendorBinary.Properties.AndroidMkStaticLibs) 52 } 53} 54 55// Test that variants which use the vndk emit the appropriate cfg flag. 56func TestImageCfgFlag(t *testing.T) { 57 ctx := testRust(t, ` 58 rust_ffi_shared { 59 name: "libfoo", 60 crate_name: "foo", 61 srcs: ["foo.rs"], 62 vendor_available: true, 63 product_available: true, 64 } 65 `) 66 67 vendor := ctx.ModuleForTests(t, "libfoo", "android_vendor_arm64_armv8-a_shared").Rule("rustc") 68 69 if !strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_vndk'") { 70 t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"]) 71 } 72 if !strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_vendor'") { 73 t.Errorf("missing \"--cfg 'android_vendor'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"]) 74 } 75 if strings.Contains(vendor.Args["rustcFlags"], "--cfg 'android_product'") { 76 t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo vendor variant, rustcFlags: %#v", vendor.Args["rustcFlags"]) 77 } 78 79 product := ctx.ModuleForTests(t, "libfoo", "android_product_arm64_armv8-a_shared").Rule("rustc") 80 if !strings.Contains(product.Args["rustcFlags"], "--cfg 'android_vndk'") { 81 t.Errorf("missing \"--cfg 'android_vndk'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"]) 82 } 83 if strings.Contains(product.Args["rustcFlags"], "--cfg 'android_vendor'") { 84 t.Errorf("unexpected \"--cfg 'android_vendor'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"]) 85 } 86 if !strings.Contains(product.Args["rustcFlags"], "--cfg 'android_product'") { 87 t.Errorf("missing \"--cfg 'android_product'\" for libfoo product variant, rustcFlags: %#v", product.Args["rustcFlags"]) 88 } 89 90 system := ctx.ModuleForTests(t, "libfoo", "android_arm64_armv8-a_shared").Rule("rustc") 91 if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_vndk'") { 92 t.Errorf("unexpected \"--cfg 'android_vndk'\" for libfoo system variant, rustcFlags: %#v", system.Args["rustcFlags"]) 93 } 94 if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_vendor'") { 95 t.Errorf("unexpected \"--cfg 'android_vendor'\" for libfoo system variant, rustcFlags: %#v", system.Args["rustcFlags"]) 96 } 97 if strings.Contains(system.Args["rustcFlags"], "--cfg 'android_product'") { 98 t.Errorf("unexpected \"--cfg 'android_product'\" for libfoo system variant, rustcFlags: %#v", product.Args["rustcFlags"]) 99 } 100 101} 102 103// Test that cc modules can link against vendor_ramdisk_available rust_ffi_static libraries. 104func TestVendorRamdiskLinkage(t *testing.T) { 105 ctx := testRust(t, ` 106 cc_library_shared { 107 name: "libcc_vendor_ramdisk", 108 static_libs: [ 109 "libfoo_vendor_ramdisk", 110 ], 111 system_shared_libs: [], 112 vendor_ramdisk_available: true, 113 } 114 rust_ffi_static { 115 name: "libfoo_vendor_ramdisk", 116 crate_name: "foo", 117 srcs: ["foo.rs"], 118 vendor_ramdisk_available: true, 119 } 120 `) 121 122 vendorRamdiskLibrary := ctx.ModuleForTests(t, "libcc_vendor_ramdisk", "android_vendor_ramdisk_arm64_armv8-a_shared").Module().(*cc.Module) 123 124 if android.InList("libfoo_vendor_ramdisk.vendor_ramdisk", vendorRamdiskLibrary.Properties.AndroidMkStaticLibs) { 125 t.Errorf("libcc_vendor_ramdisk should not have a dependency on the libfoo_vendor_ramdisk static library") 126 } 127} 128 129// Test that prebuilt libraries cannot be made vendor available. 130func TestForbiddenVendorLinkage(t *testing.T) { 131 testRustError(t, "Rust prebuilt modules not supported for non-system images.", ` 132 rust_prebuilt_library { 133 name: "librust_prebuilt", 134 crate_name: "rust_prebuilt", 135 rlib: { 136 srcs: ["libtest.rlib"], 137 }, 138 dylib: { 139 srcs: ["libtest.so"], 140 }, 141 vendor: true, 142 } 143 `) 144} 145 146func checkInstallPartition(t *testing.T, ctx *android.TestContext, name, variant, expected string) { 147 mod := ctx.ModuleForTests(t, name, variant).Module().(*Module) 148 partitionDefined := false 149 checkPartition := func(specific bool, partition string) { 150 if specific { 151 if expected != partition && !partitionDefined { 152 // The variant is installed to the 'partition' 153 t.Errorf("%s variant of %q must not be installed to %s partition", variant, name, partition) 154 } 155 partitionDefined = true 156 } else { 157 // The variant is not installed to the 'partition' 158 if expected == partition { 159 t.Errorf("%s variant of %q must be installed to %s partition", variant, name, partition) 160 } 161 } 162 } 163 socSpecific := func(m *Module) bool { 164 return m.SocSpecific() 165 } 166 deviceSpecific := func(m *Module) bool { 167 return m.DeviceSpecific() 168 } 169 productSpecific := func(m *Module) bool { 170 return m.ProductSpecific() || m.productSpecificModuleContext() 171 } 172 systemExtSpecific := func(m *Module) bool { 173 return m.SystemExtSpecific() 174 } 175 checkPartition(socSpecific(mod), "vendor") 176 checkPartition(deviceSpecific(mod), "odm") 177 checkPartition(productSpecific(mod), "product") 178 checkPartition(systemExtSpecific(mod), "system_ext") 179 if !partitionDefined && expected != "system" { 180 t.Errorf("%s variant of %q is expected to be installed to %s partition,"+ 181 " but installed to system partition", variant, name, expected) 182 } 183} 184 185func TestInstallPartition(t *testing.T) { 186 t.Parallel() 187 t.Helper() 188 ctx := testRust(t, ` 189 rust_binary { 190 name: "sample_system", 191 crate_name: "sample", 192 srcs: ["foo.rs"], 193 } 194 rust_binary { 195 name: "sample_system_ext", 196 crate_name: "sample", 197 srcs: ["foo.rs"], 198 system_ext_specific: true, 199 } 200 rust_binary { 201 name: "sample_product", 202 crate_name: "sample", 203 srcs: ["foo.rs"], 204 product_specific: true, 205 } 206 rust_binary { 207 name: "sample_vendor", 208 crate_name: "sample", 209 srcs: ["foo.rs"], 210 vendor: true, 211 } 212 rust_binary { 213 name: "sample_odm", 214 crate_name: "sample", 215 srcs: ["foo.rs"], 216 device_specific: true, 217 } 218 rust_binary { 219 name: "sample_all_available", 220 crate_name: "sample", 221 srcs: ["foo.rs"], 222 vendor_available: true, 223 product_available: true, 224 } 225 `) 226 227 checkInstallPartition(t, ctx, "sample_system", binaryCoreVariant, "system") 228 checkInstallPartition(t, ctx, "sample_system_ext", binaryCoreVariant, "system_ext") 229 checkInstallPartition(t, ctx, "sample_product", binaryProductVariant, "product") 230 checkInstallPartition(t, ctx, "sample_vendor", binaryVendorVariant, "vendor") 231 checkInstallPartition(t, ctx, "sample_odm", binaryVendorVariant, "odm") 232 233 checkInstallPartition(t, ctx, "sample_all_available", binaryCoreVariant, "system") 234} 235