1// Copyright 2019 Google Inc. All rights reserved. 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 cc 16 17import ( 18 "testing" 19 20 "android/soong/android" 21 22 "github.com/google/blueprint" 23) 24 25var prepareForPrebuiltTest = android.GroupFixturePreparers( 26 prepareForCcTest, 27 android.PrepareForTestWithAndroidMk, 28) 29 30func testPrebuilt(t *testing.T, bp string, fs android.MockFS, handlers ...android.FixturePreparer) *android.TestContext { 31 result := android.GroupFixturePreparers( 32 prepareForPrebuiltTest, 33 fs.AddToFixture(), 34 android.GroupFixturePreparers(handlers...), 35 ).RunTestWithBp(t, bp) 36 37 return result.TestContext 38} 39 40type configCustomizer func(config android.Config) 41 42func TestPrebuilt(t *testing.T) { 43 bp := ` 44 cc_library { 45 name: "liba", 46 } 47 48 cc_prebuilt_library_shared { 49 name: "liba", 50 srcs: ["liba.so"], 51 } 52 53 cc_library { 54 name: "libb", 55 } 56 57 cc_prebuilt_library_static { 58 name: "libb", 59 srcs: ["libb.a"], 60 } 61 62 cc_library_shared { 63 name: "libd", 64 } 65 66 cc_prebuilt_library_shared { 67 name: "libd", 68 srcs: ["libd.so"], 69 } 70 71 cc_library_static { 72 name: "libe", 73 } 74 75 cc_prebuilt_library_static { 76 name: "libe", 77 srcs: ["libe.a"], 78 } 79 80 cc_library { 81 name: "libf", 82 } 83 84 cc_prebuilt_library { 85 name: "libf", 86 static: { 87 srcs: ["libf.a"], 88 }, 89 shared: { 90 srcs: ["libf.so"], 91 }, 92 } 93 94 cc_object { 95 name: "crtx", 96 } 97 98 cc_prebuilt_object { 99 name: "crtx", 100 srcs: ["crtx.o"], 101 } 102 ` 103 104 ctx := testPrebuilt(t, bp, map[string][]byte{ 105 "liba.so": nil, 106 "libb.a": nil, 107 "libd.so": nil, 108 "libe.a": nil, 109 "libf.a": nil, 110 "libf.so": nil, 111 "crtx.o": nil, 112 }) 113 114 // Verify that all the modules exist and that their dependencies were connected correctly 115 liba := ctx.ModuleForTests("liba", "android_arm64_armv8-a_shared").Module() 116 libb := ctx.ModuleForTests("libb", "android_arm64_armv8-a_static").Module() 117 libd := ctx.ModuleForTests("libd", "android_arm64_armv8-a_shared").Module() 118 libe := ctx.ModuleForTests("libe", "android_arm64_armv8-a_static").Module() 119 libfStatic := ctx.ModuleForTests("libf", "android_arm64_armv8-a_static").Module() 120 libfShared := ctx.ModuleForTests("libf", "android_arm64_armv8-a_shared").Module() 121 crtx := ctx.ModuleForTests("crtx", "android_arm64_armv8-a").Module() 122 123 prebuiltLiba := ctx.ModuleForTests("prebuilt_liba", "android_arm64_armv8-a_shared").Module() 124 prebuiltLibb := ctx.ModuleForTests("prebuilt_libb", "android_arm64_armv8-a_static").Module() 125 prebuiltLibd := ctx.ModuleForTests("prebuilt_libd", "android_arm64_armv8-a_shared").Module() 126 prebuiltLibe := ctx.ModuleForTests("prebuilt_libe", "android_arm64_armv8-a_static").Module() 127 prebuiltLibfStatic := ctx.ModuleForTests("prebuilt_libf", "android_arm64_armv8-a_static").Module() 128 prebuiltLibfShared := ctx.ModuleForTests("prebuilt_libf", "android_arm64_armv8-a_shared").Module() 129 prebuiltCrtx := ctx.ModuleForTests("prebuilt_crtx", "android_arm64_armv8-a").Module() 130 131 hasDep := func(m android.Module, wantDep android.Module) bool { 132 t.Helper() 133 var found bool 134 ctx.VisitDirectDeps(m, func(dep blueprint.Module) { 135 if dep == wantDep { 136 found = true 137 } 138 }) 139 return found 140 } 141 142 if !hasDep(liba, prebuiltLiba) { 143 t.Errorf("liba missing dependency on prebuilt_liba") 144 } 145 146 if !hasDep(libb, prebuiltLibb) { 147 t.Errorf("libb missing dependency on prebuilt_libb") 148 } 149 150 if !hasDep(libd, prebuiltLibd) { 151 t.Errorf("libd missing dependency on prebuilt_libd") 152 } 153 154 if !hasDep(libe, prebuiltLibe) { 155 t.Errorf("libe missing dependency on prebuilt_libe") 156 } 157 158 if !hasDep(libfStatic, prebuiltLibfStatic) { 159 t.Errorf("libf static missing dependency on prebuilt_libf") 160 } 161 162 if !hasDep(libfShared, prebuiltLibfShared) { 163 t.Errorf("libf shared missing dependency on prebuilt_libf") 164 } 165 166 if !hasDep(crtx, prebuiltCrtx) { 167 t.Errorf("crtx missing dependency on prebuilt_crtx") 168 } 169} 170 171func TestPrebuiltLibraryShared(t *testing.T) { 172 ctx := testPrebuilt(t, ` 173 cc_prebuilt_library_shared { 174 name: "libtest", 175 srcs: ["libf.so"], 176 strip: { 177 none: true, 178 }, 179 } 180 `, map[string][]byte{ 181 "libf.so": nil, 182 }) 183 184 shared := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared").Module().(*Module) 185 assertString(t, shared.OutputFile().Path().Base(), "libtest.so") 186} 187 188func TestPrebuiltLibraryStatic(t *testing.T) { 189 ctx := testPrebuilt(t, ` 190 cc_prebuilt_library_static { 191 name: "libtest", 192 srcs: ["libf.a"], 193 } 194 `, map[string][]byte{ 195 "libf.a": nil, 196 }) 197 198 static := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static").Module().(*Module) 199 assertString(t, static.OutputFile().Path().Base(), "libf.a") 200} 201 202func TestPrebuiltLibrary(t *testing.T) { 203 ctx := testPrebuilt(t, ` 204 cc_prebuilt_library { 205 name: "libtest", 206 static: { 207 srcs: ["libf.a"], 208 }, 209 shared: { 210 srcs: ["libf.so"], 211 }, 212 strip: { 213 none: true, 214 }, 215 } 216 `, map[string][]byte{ 217 "libf.a": nil, 218 "libf.so": nil, 219 }) 220 221 shared := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared").Module().(*Module) 222 assertString(t, shared.OutputFile().Path().Base(), "libtest.so") 223 224 static := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static").Module().(*Module) 225 assertString(t, static.OutputFile().Path().Base(), "libf.a") 226} 227 228func TestPrebuiltLibraryStem(t *testing.T) { 229 ctx := testPrebuilt(t, ` 230 cc_prebuilt_library { 231 name: "libfoo", 232 stem: "libbar", 233 static: { 234 srcs: ["libfoo.a"], 235 }, 236 shared: { 237 srcs: ["libfoo.so"], 238 }, 239 strip: { 240 none: true, 241 }, 242 } 243 `, map[string][]byte{ 244 "libfoo.a": nil, 245 "libfoo.so": nil, 246 }) 247 248 static := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Module().(*Module) 249 assertString(t, static.OutputFile().Path().Base(), "libfoo.a") 250 251 shared := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*Module) 252 assertString(t, shared.OutputFile().Path().Base(), "libbar.so") 253} 254 255func TestPrebuiltLibrarySharedStem(t *testing.T) { 256 ctx := testPrebuilt(t, ` 257 cc_prebuilt_library_shared { 258 name: "libfoo", 259 stem: "libbar", 260 srcs: ["libfoo.so"], 261 strip: { 262 none: true, 263 }, 264 } 265 `, map[string][]byte{ 266 "libfoo.so": nil, 267 }) 268 269 shared := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module().(*Module) 270 assertString(t, shared.OutputFile().Path().Base(), "libbar.so") 271} 272 273func TestPrebuiltSymlinkedHostBinary(t *testing.T) { 274 if android.BuildOs != android.Linux { 275 t.Skipf("Skipping host prebuilt testing that is only supported on %s not %s", android.Linux, android.BuildOs) 276 } 277 278 ctx := testPrebuilt(t, ` 279 cc_prebuilt_library_shared { 280 name: "libfoo", 281 device_supported: false, 282 host_supported: true, 283 target: { 284 linux_glibc_x86_64: { 285 srcs: ["linux_glibc_x86_64/lib64/libfoo.so"], 286 }, 287 }, 288 } 289 290 cc_prebuilt_binary { 291 name: "foo", 292 device_supported: false, 293 host_supported: true, 294 shared_libs: ["libfoo"], 295 target: { 296 linux_glibc_x86_64: { 297 srcs: ["linux_glibc_x86_64/bin/foo"], 298 }, 299 }, 300 } 301 `, map[string][]byte{ 302 "libfoo.so": nil, 303 "foo": nil, 304 }) 305 306 fooRule := ctx.ModuleForTests("foo", "linux_glibc_x86_64").Rule("Symlink") 307 assertString(t, fooRule.Output.String(), "out/soong/.intermediates/foo/linux_glibc_x86_64/foo") 308 assertString(t, fooRule.Args["fromPath"], "$$PWD/linux_glibc_x86_64/bin/foo") 309 310 var libfooDep android.Path 311 for _, dep := range fooRule.Implicits { 312 if dep.Base() == "libfoo.so" { 313 libfooDep = dep 314 break 315 } 316 } 317 assertString(t, libfooDep.String(), "out/soong/.intermediates/libfoo/linux_glibc_x86_64_shared/libfoo.so") 318} 319 320func TestPrebuiltLibrarySanitized(t *testing.T) { 321 bp := `cc_prebuilt_library { 322 name: "libtest", 323 static: { 324 sanitized: { none: { srcs: ["libf.a"], }, hwaddress: { srcs: ["libf.hwasan.a"], }, }, 325 }, 326 shared: { 327 sanitized: { none: { srcs: ["libf.so"], }, hwaddress: { srcs: ["hwasan/libf.so"], }, }, 328 }, 329 } 330 cc_prebuilt_library_static { 331 name: "libtest_static", 332 sanitized: { none: { srcs: ["libf.a"], }, hwaddress: { srcs: ["libf.hwasan.a"], }, }, 333 } 334 cc_prebuilt_library_shared { 335 name: "libtest_shared", 336 sanitized: { none: { srcs: ["libf.so"], }, hwaddress: { srcs: ["hwasan/libf.so"], }, }, 337 }` 338 339 fs := map[string][]byte{ 340 "libf.a": nil, 341 "libf.hwasan.a": nil, 342 "libf.so": nil, 343 "hwasan/libf.so": nil, 344 } 345 346 // Without SANITIZE_TARGET. 347 ctx := testPrebuilt(t, bp, fs) 348 349 shared_rule := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared").Rule("android/soong/cc.strip") 350 assertString(t, shared_rule.Input.String(), "libf.so") 351 352 static := ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static").Module().(*Module) 353 assertString(t, static.OutputFile().Path().Base(), "libf.a") 354 355 shared_rule2 := ctx.ModuleForTests("libtest_shared", "android_arm64_armv8-a_shared").Rule("android/soong/cc.strip") 356 assertString(t, shared_rule2.Input.String(), "libf.so") 357 358 static2 := ctx.ModuleForTests("libtest_static", "android_arm64_armv8-a_static").Module().(*Module) 359 assertString(t, static2.OutputFile().Path().Base(), "libf.a") 360 361 // With SANITIZE_TARGET=hwaddress 362 ctx = testPrebuilt(t, bp, fs, 363 android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) { 364 variables.SanitizeDevice = []string{"hwaddress"} 365 }), 366 ) 367 368 shared_rule = ctx.ModuleForTests("libtest", "android_arm64_armv8-a_shared_hwasan").Rule("android/soong/cc.strip") 369 assertString(t, shared_rule.Input.String(), "hwasan/libf.so") 370 371 static = ctx.ModuleForTests("libtest", "android_arm64_armv8-a_static_hwasan").Module().(*Module) 372 assertString(t, static.OutputFile().Path().Base(), "libf.hwasan.a") 373 374 shared_rule2 = ctx.ModuleForTests("libtest_shared", "android_arm64_armv8-a_shared_hwasan").Rule("android/soong/cc.strip") 375 assertString(t, shared_rule2.Input.String(), "hwasan/libf.so") 376 377 static2 = ctx.ModuleForTests("libtest_static", "android_arm64_armv8-a_static_hwasan").Module().(*Module) 378 assertString(t, static2.OutputFile().Path().Base(), "libf.hwasan.a") 379} 380