blob: 499d7ae21f2d83355e961f1ab01e3550786a31ec [file] [log] [blame]
Colin Cross0fce0ba2021-01-08 16:40:12 -08001// Copyright 2021 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 "android/soong/android"
19 "fmt"
20 "path/filepath"
Colin Cross2e577f32021-01-22 13:06:25 -080021 "reflect"
Colin Cross0fce0ba2021-01-08 16:40:12 -080022 "strings"
23 "testing"
24)
25
26func TestVendorSnapshotCapture(t *testing.T) {
27 bp := `
28 cc_library {
29 name: "libvndk",
30 vendor_available: true,
31 product_available: true,
32 vndk: {
33 enabled: true,
34 },
35 nocrt: true,
36 }
37
38 cc_library {
39 name: "libvendor",
40 vendor: true,
41 nocrt: true,
42 }
43
44 cc_library {
45 name: "libvendor_available",
46 vendor_available: true,
47 nocrt: true,
48 }
49
50 cc_library_headers {
51 name: "libvendor_headers",
52 vendor_available: true,
53 nocrt: true,
54 }
55
56 cc_binary {
57 name: "vendor_bin",
58 vendor: true,
59 nocrt: true,
60 }
61
62 cc_binary {
63 name: "vendor_available_bin",
64 vendor_available: true,
65 nocrt: true,
66 }
67
68 toolchain_library {
69 name: "libb",
70 vendor_available: true,
71 src: "libb.a",
72 }
73
74 cc_object {
75 name: "obj",
76 vendor_available: true,
77 }
78
79 cc_library {
80 name: "libllndk",
81 llndk_stubs: "libllndk.llndk",
82 }
83
84 llndk_library {
85 name: "libllndk.llndk",
86 symbol_file: "",
87 }
88`
89 config := TestConfig(buildDir, android.Android, nil, bp, nil)
90 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
91 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
92 ctx := testCcWithConfig(t, config)
93
94 // Check Vendor snapshot output.
95
96 snapshotDir := "vendor-snapshot"
97 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
98 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
99
100 var jsonFiles []string
101
102 for _, arch := range [][]string{
103 []string{"arm64", "armv8-a"},
104 []string{"arm", "armv7-a-neon"},
105 } {
106 archType := arch[0]
107 archVariant := arch[1]
108 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
109
110 // For shared libraries, only non-VNDK vendor_available modules are captured
111 sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant)
112 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
113 checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
114 checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant)
115 jsonFiles = append(jsonFiles,
116 filepath.Join(sharedDir, "libvendor.so.json"),
117 filepath.Join(sharedDir, "libvendor_available.so.json"))
118
119 // LLNDK modules are not captured
120 checkSnapshotExclude(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", sharedDir, sharedVariant)
121
122 // For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
123 // Also cfi variants are captured, except for prebuilts like toolchain_library
124 staticVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static", archType, archVariant)
125 staticCfiVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static_cfi", archType, archVariant)
126 staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
127 checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
128 checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.a", staticDir, staticVariant)
129 checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.cfi.a", staticDir, staticCfiVariant)
130 checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.a", staticDir, staticVariant)
131 checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.cfi.a", staticDir, staticCfiVariant)
132 checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.a", staticDir, staticVariant)
133 checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.cfi.a", staticDir, staticCfiVariant)
134 jsonFiles = append(jsonFiles,
135 filepath.Join(staticDir, "libb.a.json"),
136 filepath.Join(staticDir, "libvndk.a.json"),
137 filepath.Join(staticDir, "libvndk.cfi.a.json"),
138 filepath.Join(staticDir, "libvendor.a.json"),
139 filepath.Join(staticDir, "libvendor.cfi.a.json"),
140 filepath.Join(staticDir, "libvendor_available.a.json"),
141 filepath.Join(staticDir, "libvendor_available.cfi.a.json"))
142
143 // For binary executables, all vendor:true and vendor_available modules are captured.
144 if archType == "arm64" {
145 binaryVariant := fmt.Sprintf("android_vendor.VER_%s_%s", archType, archVariant)
146 binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
147 checkSnapshot(t, ctx, snapshotSingleton, "vendor_bin", "vendor_bin", binaryDir, binaryVariant)
148 checkSnapshot(t, ctx, snapshotSingleton, "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant)
149 jsonFiles = append(jsonFiles,
150 filepath.Join(binaryDir, "vendor_bin.json"),
151 filepath.Join(binaryDir, "vendor_available_bin.json"))
152 }
153
154 // For header libraries, all vendor:true and vendor_available modules are captured.
155 headerDir := filepath.Join(snapshotVariantPath, archDir, "header")
156 jsonFiles = append(jsonFiles, filepath.Join(headerDir, "libvendor_headers.json"))
157
158 // For object modules, all vendor:true and vendor_available modules are captured.
159 objectVariant := fmt.Sprintf("android_vendor.VER_%s_%s", archType, archVariant)
160 objectDir := filepath.Join(snapshotVariantPath, archDir, "object")
161 checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant)
162 jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json"))
163 }
164
165 for _, jsonFile := range jsonFiles {
166 // verify all json files exist
167 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
168 t.Errorf("%q expected but not found", jsonFile)
169 }
170 }
171
172 // fake snapshot should have all outputs in the normal snapshot.
173 fakeSnapshotSingleton := ctx.SingletonForTests("vendor-fake-snapshot")
174 for _, output := range snapshotSingleton.AllOutputs() {
175 fakeOutput := strings.Replace(output, "/vendor-snapshot/", "/fake/vendor-snapshot/", 1)
176 if fakeSnapshotSingleton.MaybeOutput(fakeOutput).Rule == nil {
177 t.Errorf("%q expected but not found", fakeOutput)
178 }
179 }
180}
181
182func TestVendorSnapshotDirected(t *testing.T) {
183 bp := `
184 cc_library_shared {
185 name: "libvendor",
186 vendor: true,
187 nocrt: true,
188 }
189
190 cc_library_shared {
191 name: "libvendor_available",
192 vendor_available: true,
193 nocrt: true,
194 }
195
196 genrule {
197 name: "libfoo_gen",
198 cmd: "",
199 out: ["libfoo.so"],
200 }
201
202 cc_prebuilt_library_shared {
203 name: "libfoo",
204 vendor: true,
205 prefer: true,
206 srcs: [":libfoo_gen"],
207 }
208
209 cc_library_shared {
210 name: "libfoo",
211 vendor: true,
212 nocrt: true,
213 }
214`
215 config := TestConfig(buildDir, android.Android, nil, bp, nil)
216 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
217 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
218 config.TestProductVariables.DirectedVendorSnapshot = true
219 config.TestProductVariables.VendorSnapshotModules = make(map[string]bool)
220 config.TestProductVariables.VendorSnapshotModules["libvendor"] = true
221 config.TestProductVariables.VendorSnapshotModules["libfoo"] = true
222 ctx := testCcWithConfig(t, config)
223
224 // Check Vendor snapshot output.
225
226 snapshotDir := "vendor-snapshot"
227 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
228 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
229
230 var includeJsonFiles []string
231 var excludeJsonFiles []string
232
233 for _, arch := range [][]string{
234 []string{"arm64", "armv8-a"},
235 []string{"arm", "armv7-a-neon"},
236 } {
237 archType := arch[0]
238 archVariant := arch[1]
239 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
240
241 sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant)
242 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
243
244 // Included modules
245 checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
246 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json"))
247 // Check that snapshot captures "prefer: true" prebuilt
248 checkSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo", "libfoo.so", sharedDir, sharedVariant)
249 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libfoo.so.json"))
250
251 // Excluded modules
252 checkSnapshotExclude(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant)
253 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libvendor_available.so.json"))
254 }
255
256 // Verify that each json file for an included module has a rule.
257 for _, jsonFile := range includeJsonFiles {
258 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
259 t.Errorf("include json file %q not found", jsonFile)
260 }
261 }
262
263 // Verify that each json file for an excluded module has no rule.
264 for _, jsonFile := range excludeJsonFiles {
265 if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
266 t.Errorf("exclude json file %q found", jsonFile)
267 }
268 }
269}
270
271func TestVendorSnapshotUse(t *testing.T) {
272 frameworkBp := `
273 cc_library {
274 name: "libvndk",
275 vendor_available: true,
276 product_available: true,
277 vndk: {
278 enabled: true,
279 },
280 nocrt: true,
281 compile_multilib: "64",
282 }
283
284 cc_library {
285 name: "libvendor",
286 vendor: true,
287 nocrt: true,
288 no_libcrt: true,
289 stl: "none",
290 system_shared_libs: [],
291 compile_multilib: "64",
292 }
293
Colin Cross2e577f32021-01-22 13:06:25 -0800294 cc_library {
295 name: "libvendor_available",
296 vendor_available: true,
297 nocrt: true,
298 no_libcrt: true,
299 stl: "none",
300 system_shared_libs: [],
301 compile_multilib: "64",
302 }
303
Colin Cross0fce0ba2021-01-08 16:40:12 -0800304 cc_binary {
305 name: "bin",
306 vendor: true,
307 nocrt: true,
308 no_libcrt: true,
309 stl: "none",
310 system_shared_libs: [],
311 compile_multilib: "64",
312 }
313`
314
315 vndkBp := `
316 vndk_prebuilt_shared {
317 name: "libvndk",
318 version: "BOARD",
319 target_arch: "arm64",
320 vendor_available: true,
321 product_available: true,
322 vndk: {
323 enabled: true,
324 },
325 arch: {
326 arm64: {
327 srcs: ["libvndk.so"],
328 export_include_dirs: ["include/libvndk"],
329 },
330 },
331 }
Colin Crosse0edaf92021-01-11 17:31:17 -0800332
333 // old snapshot module which has to be ignored
334 vndk_prebuilt_shared {
335 name: "libvndk",
336 version: "OLD",
337 target_arch: "arm64",
338 vendor_available: true,
339 product_available: true,
340 vndk: {
341 enabled: true,
342 },
343 arch: {
344 arm64: {
345 srcs: ["libvndk.so"],
346 export_include_dirs: ["include/libvndk"],
347 },
348 },
349 }
Colin Cross0fce0ba2021-01-08 16:40:12 -0800350`
351
352 vendorProprietaryBp := `
353 cc_library {
354 name: "libvendor_without_snapshot",
355 vendor: true,
356 nocrt: true,
357 no_libcrt: true,
358 stl: "none",
359 system_shared_libs: [],
360 compile_multilib: "64",
361 }
362
363 cc_library_shared {
364 name: "libclient",
365 vendor: true,
366 nocrt: true,
367 no_libcrt: true,
368 stl: "none",
369 system_shared_libs: [],
Colin Cross2e577f32021-01-22 13:06:25 -0800370 shared_libs: ["libvndk", "libvendor_available"],
Colin Cross0fce0ba2021-01-08 16:40:12 -0800371 static_libs: ["libvendor", "libvendor_without_snapshot"],
372 compile_multilib: "64",
373 srcs: ["client.cpp"],
374 }
375
376 cc_binary {
377 name: "bin_without_snapshot",
378 vendor: true,
379 nocrt: true,
380 no_libcrt: true,
381 stl: "none",
382 system_shared_libs: [],
383 static_libs: ["libvndk"],
384 compile_multilib: "64",
385 srcs: ["bin.cpp"],
386 }
387
Colin Crosse0edaf92021-01-11 17:31:17 -0800388 vendor_snapshot {
389 name: "vendor_snapshot",
390 compile_multilib: "first",
391 version: "BOARD",
392 vndk_libs: [
393 "libvndk",
394 ],
395 static_libs: [
396 "libvendor",
397 "libvendor_available",
398 "libvndk",
399 ],
400 shared_libs: [
401 "libvendor",
402 "libvendor_available",
403 ],
404 binaries: [
405 "bin",
406 ],
407 }
408
Colin Cross0fce0ba2021-01-08 16:40:12 -0800409 vendor_snapshot_static {
410 name: "libvndk",
411 version: "BOARD",
412 target_arch: "arm64",
413 vendor: true,
414 arch: {
415 arm64: {
416 src: "libvndk.a",
417 export_include_dirs: ["include/libvndk"],
418 },
419 },
420 }
421
422 vendor_snapshot_shared {
423 name: "libvendor",
424 version: "BOARD",
425 target_arch: "arm64",
426 vendor: true,
427 arch: {
428 arm64: {
429 src: "libvendor.so",
430 export_include_dirs: ["include/libvendor"],
431 },
432 },
433 }
434
435 vendor_snapshot_static {
436 name: "libvendor",
437 version: "BOARD",
438 target_arch: "arm64",
439 vendor: true,
440 arch: {
441 arm64: {
442 src: "libvendor.a",
443 export_include_dirs: ["include/libvendor"],
444 },
445 },
446 }
447
Colin Cross2e577f32021-01-22 13:06:25 -0800448 vendor_snapshot_shared {
449 name: "libvendor_available",
Colin Crossa8890802021-01-22 14:06:33 -0800450 androidmk_suffix: ".vendor",
Colin Cross2e577f32021-01-22 13:06:25 -0800451 version: "BOARD",
452 target_arch: "arm64",
453 vendor: true,
454 arch: {
455 arm64: {
456 src: "libvendor_available.so",
457 export_include_dirs: ["include/libvendor"],
458 },
459 },
460 }
461
462 vendor_snapshot_static {
463 name: "libvendor_available",
Colin Crossa8890802021-01-22 14:06:33 -0800464 androidmk_suffix: ".vendor",
Colin Cross2e577f32021-01-22 13:06:25 -0800465 version: "BOARD",
466 target_arch: "arm64",
467 vendor: true,
468 arch: {
469 arm64: {
470 src: "libvendor_available.a",
471 export_include_dirs: ["include/libvendor"],
472 },
473 },
474 }
475
Colin Cross0fce0ba2021-01-08 16:40:12 -0800476 vendor_snapshot_binary {
477 name: "bin",
478 version: "BOARD",
479 target_arch: "arm64",
480 vendor: true,
481 arch: {
482 arm64: {
483 src: "bin",
484 },
485 },
486 }
Colin Crosse0edaf92021-01-11 17:31:17 -0800487
488 // old snapshot module which has to be ignored
489 vendor_snapshot_binary {
490 name: "bin",
491 version: "OLD",
492 target_arch: "arm64",
493 vendor: true,
494 arch: {
495 arm64: {
496 src: "bin",
497 },
498 },
499 }
Colin Cross0fce0ba2021-01-08 16:40:12 -0800500`
501 depsBp := GatherRequiredDepsForTest(android.Android)
502
503 mockFS := map[string][]byte{
504 "deps/Android.bp": []byte(depsBp),
505 "framework/Android.bp": []byte(frameworkBp),
506 "vendor/Android.bp": []byte(vendorProprietaryBp),
507 "vendor/bin": nil,
508 "vendor/bin.cpp": nil,
509 "vendor/client.cpp": nil,
510 "vendor/include/libvndk/a.h": nil,
511 "vendor/include/libvendor/b.h": nil,
512 "vendor/libvndk.a": nil,
513 "vendor/libvendor.a": nil,
514 "vendor/libvendor.so": nil,
515 "vndk/Android.bp": []byte(vndkBp),
516 "vndk/include/libvndk/a.h": nil,
517 "vndk/libvndk.so": nil,
518 }
519
520 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
521 config.TestProductVariables.DeviceVndkVersion = StringPtr("BOARD")
522 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
523 ctx := CreateTestContext(config)
524 ctx.Register()
525
526 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "vendor/Android.bp", "vndk/Android.bp"})
527 android.FailIfErrored(t, errs)
528 _, errs = ctx.PrepareBuildActions(config)
529 android.FailIfErrored(t, errs)
530
531 sharedVariant := "android_vendor.BOARD_arm64_armv8-a_shared"
532 staticVariant := "android_vendor.BOARD_arm64_armv8-a_static"
533 binaryVariant := "android_vendor.BOARD_arm64_armv8-a"
534
535 // libclient uses libvndk.vndk.BOARD.arm64, libvendor.vendor_static.BOARD.arm64, libvendor_without_snapshot
536 libclientCcFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("cc").Args["cFlags"]
537 for _, includeFlags := range []string{
538 "-Ivndk/include/libvndk", // libvndk
539 "-Ivendor/include/libvendor", // libvendor
540 } {
541 if !strings.Contains(libclientCcFlags, includeFlags) {
542 t.Errorf("flags for libclient must contain %#v, but was %#v.",
543 includeFlags, libclientCcFlags)
544 }
545 }
546
547 libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("ld").Args["libFlags"]
548 for _, input := range [][]string{
549 []string{sharedVariant, "libvndk.vndk.BOARD.arm64"},
550 []string{staticVariant, "libvendor.vendor_static.BOARD.arm64"},
551 []string{staticVariant, "libvendor_without_snapshot"},
552 } {
553 outputPaths := getOutputPaths(ctx, input[0] /* variant */, []string{input[1]} /* module name */)
554 if !strings.Contains(libclientLdFlags, outputPaths[0].String()) {
555 t.Errorf("libflags for libclient must contain %#v, but was %#v", outputPaths[0], libclientLdFlags)
556 }
557 }
558
Colin Cross2e577f32021-01-22 13:06:25 -0800559 libclientAndroidMkSharedLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkSharedLibs
560 if g, w := libclientAndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor"}; !reflect.DeepEqual(g, w) {
561 t.Errorf("wanted libclient AndroidMkSharedLibs %q, got %q", w, g)
562 }
563
564 libclientAndroidMkStaticLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkStaticLibs
565 if g, w := libclientAndroidMkStaticLibs, []string{"libvendor", "libvendor_without_snapshot"}; !reflect.DeepEqual(g, w) {
566 t.Errorf("wanted libclient AndroidMkStaticLibs %q, got %q", w, g)
567 }
568
Colin Cross0fce0ba2021-01-08 16:40:12 -0800569 // bin_without_snapshot uses libvndk.vendor_static.BOARD.arm64
570 binWithoutSnapshotCcFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("cc").Args["cFlags"]
571 if !strings.Contains(binWithoutSnapshotCcFlags, "-Ivendor/include/libvndk") {
572 t.Errorf("flags for bin_without_snapshot must contain %#v, but was %#v.",
573 "-Ivendor/include/libvndk", binWithoutSnapshotCcFlags)
574 }
575
576 binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("ld").Args["libFlags"]
577 libVndkStaticOutputPaths := getOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.BOARD.arm64"})
578 if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) {
579 t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v",
580 libVndkStaticOutputPaths[0], binWithoutSnapshotLdFlags)
581 }
582
583 // libvendor.so is installed by libvendor.vendor_shared.BOARD.arm64
584 ctx.ModuleForTests("libvendor.vendor_shared.BOARD.arm64", sharedVariant).Output("libvendor.so")
585
Colin Cross2e577f32021-01-22 13:06:25 -0800586 // libvendor_available.so is installed by libvendor_available.vendor_shared.BOARD.arm64
587 ctx.ModuleForTests("libvendor_available.vendor_shared.BOARD.arm64", sharedVariant).Output("libvendor_available.so")
588
Colin Cross0fce0ba2021-01-08 16:40:12 -0800589 // libvendor_without_snapshot.so is installed by libvendor_without_snapshot
590 ctx.ModuleForTests("libvendor_without_snapshot", sharedVariant).Output("libvendor_without_snapshot.so")
591
592 // bin is installed by bin.vendor_binary.BOARD.arm64
593 ctx.ModuleForTests("bin.vendor_binary.BOARD.arm64", binaryVariant).Output("bin")
594
595 // bin_without_snapshot is installed by bin_without_snapshot
596 ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Output("bin_without_snapshot")
597
Colin Cross2e577f32021-01-22 13:06:25 -0800598 // libvendor, libvendor_available and bin don't have vendor.BOARD variant
Colin Cross0fce0ba2021-01-08 16:40:12 -0800599 libvendorVariants := ctx.ModuleVariantsForTests("libvendor")
600 if inList(sharedVariant, libvendorVariants) {
601 t.Errorf("libvendor must not have variant %#v, but it does", sharedVariant)
602 }
603
Colin Cross2e577f32021-01-22 13:06:25 -0800604 libvendorAvailableVariants := ctx.ModuleVariantsForTests("libvendor_available")
605 if inList(sharedVariant, libvendorAvailableVariants) {
606 t.Errorf("libvendor_available must not have variant %#v, but it does", sharedVariant)
607 }
608
Colin Cross0fce0ba2021-01-08 16:40:12 -0800609 binVariants := ctx.ModuleVariantsForTests("bin")
610 if inList(binaryVariant, binVariants) {
611 t.Errorf("bin must not have variant %#v, but it does", sharedVariant)
612 }
613}
614
615func TestVendorSnapshotSanitizer(t *testing.T) {
616 bp := `
617 vendor_snapshot_static {
618 name: "libsnapshot",
619 vendor: true,
620 target_arch: "arm64",
621 version: "BOARD",
622 arch: {
623 arm64: {
624 src: "libsnapshot.a",
625 cfi: {
626 src: "libsnapshot.cfi.a",
627 }
628 },
629 },
630 }
631`
632 config := TestConfig(buildDir, android.Android, nil, bp, nil)
633 config.TestProductVariables.DeviceVndkVersion = StringPtr("BOARD")
634 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
635 ctx := testCcWithConfig(t, config)
636
637 // Check non-cfi and cfi variant.
638 staticVariant := "android_vendor.BOARD_arm64_armv8-a_static"
639 staticCfiVariant := "android_vendor.BOARD_arm64_armv8-a_static_cfi"
640
641 staticModule := ctx.ModuleForTests("libsnapshot.vendor_static.BOARD.arm64", staticVariant).Module().(*Module)
642 assertString(t, staticModule.outputFile.Path().Base(), "libsnapshot.a")
643
644 staticCfiModule := ctx.ModuleForTests("libsnapshot.vendor_static.BOARD.arm64", staticCfiVariant).Module().(*Module)
645 assertString(t, staticCfiModule.outputFile.Path().Base(), "libsnapshot.cfi.a")
646}
647
648func assertExcludeFromVendorSnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool) {
649 t.Helper()
650 m := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
651 if m.ExcludeFromVendorSnapshot() != expected {
652 t.Errorf("expected %q ExcludeFromVendorSnapshot to be %t", m.String(), expected)
653 }
654}
655
656func assertExcludeFromRecoverySnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool) {
657 t.Helper()
658 m := ctx.ModuleForTests(name, recoveryVariant).Module().(*Module)
659 if m.ExcludeFromRecoverySnapshot() != expected {
660 t.Errorf("expected %q ExcludeFromRecoverySnapshot to be %t", m.String(), expected)
661 }
662}
663
664func TestVendorSnapshotExclude(t *testing.T) {
665
666 // This test verifies that the exclude_from_vendor_snapshot property
667 // makes its way from the Android.bp source file into the module data
668 // structure. It also verifies that modules are correctly included or
669 // excluded in the vendor snapshot based on their path (framework or
670 // vendor) and the exclude_from_vendor_snapshot property.
671
672 frameworkBp := `
673 cc_library_shared {
674 name: "libinclude",
675 srcs: ["src/include.cpp"],
676 vendor_available: true,
677 }
678 cc_library_shared {
679 name: "libexclude",
680 srcs: ["src/exclude.cpp"],
681 vendor: true,
682 exclude_from_vendor_snapshot: true,
683 }
684 cc_library_shared {
685 name: "libavailable_exclude",
686 srcs: ["src/exclude.cpp"],
687 vendor_available: true,
688 exclude_from_vendor_snapshot: true,
689 }
690 `
691
692 vendorProprietaryBp := `
693 cc_library_shared {
694 name: "libvendor",
695 srcs: ["vendor.cpp"],
696 vendor: true,
697 }
698 `
699
700 depsBp := GatherRequiredDepsForTest(android.Android)
701
702 mockFS := map[string][]byte{
703 "deps/Android.bp": []byte(depsBp),
704 "framework/Android.bp": []byte(frameworkBp),
705 "framework/include.cpp": nil,
706 "framework/exclude.cpp": nil,
707 "device/Android.bp": []byte(vendorProprietaryBp),
708 "device/vendor.cpp": nil,
709 }
710
711 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
712 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
713 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
714 ctx := CreateTestContext(config)
715 ctx.Register()
716
717 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "device/Android.bp"})
718 android.FailIfErrored(t, errs)
719 _, errs = ctx.PrepareBuildActions(config)
720 android.FailIfErrored(t, errs)
721
722 // Test an include and exclude framework module.
723 assertExcludeFromVendorSnapshotIs(t, ctx, "libinclude", false)
724 assertExcludeFromVendorSnapshotIs(t, ctx, "libexclude", true)
725 assertExcludeFromVendorSnapshotIs(t, ctx, "libavailable_exclude", true)
726
727 // A vendor module is excluded, but by its path, not the
728 // exclude_from_vendor_snapshot property.
729 assertExcludeFromVendorSnapshotIs(t, ctx, "libvendor", false)
730
731 // Verify the content of the vendor snapshot.
732
733 snapshotDir := "vendor-snapshot"
734 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
735 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
736
737 var includeJsonFiles []string
738 var excludeJsonFiles []string
739
740 for _, arch := range [][]string{
741 []string{"arm64", "armv8-a"},
742 []string{"arm", "armv7-a-neon"},
743 } {
744 archType := arch[0]
745 archVariant := arch[1]
746 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
747
748 sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant)
749 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
750
751 // Included modules
752 checkSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
753 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
754
755 // Excluded modules
756 checkSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
757 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
758 checkSnapshotExclude(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
759 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json"))
760 checkSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
761 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
762 }
763
764 // Verify that each json file for an included module has a rule.
765 for _, jsonFile := range includeJsonFiles {
766 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
767 t.Errorf("include json file %q not found", jsonFile)
768 }
769 }
770
771 // Verify that each json file for an excluded module has no rule.
772 for _, jsonFile := range excludeJsonFiles {
773 if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
774 t.Errorf("exclude json file %q found", jsonFile)
775 }
776 }
777}
778
779func TestVendorSnapshotExcludeInVendorProprietaryPathErrors(t *testing.T) {
780
781 // This test verifies that using the exclude_from_vendor_snapshot
782 // property on a module in a vendor proprietary path generates an
783 // error. These modules are already excluded, so we prohibit using the
784 // property in this way, which could add to confusion.
785
786 vendorProprietaryBp := `
787 cc_library_shared {
788 name: "libvendor",
789 srcs: ["vendor.cpp"],
790 vendor: true,
791 exclude_from_vendor_snapshot: true,
792 }
793 `
794
795 depsBp := GatherRequiredDepsForTest(android.Android)
796
797 mockFS := map[string][]byte{
798 "deps/Android.bp": []byte(depsBp),
799 "device/Android.bp": []byte(vendorProprietaryBp),
800 "device/vendor.cpp": nil,
801 }
802
803 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
804 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
805 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
806 ctx := CreateTestContext(config)
807 ctx.Register()
808
809 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "device/Android.bp"})
810 android.FailIfErrored(t, errs)
811
812 _, errs = ctx.PrepareBuildActions(config)
813 android.CheckErrorsAgainstExpectations(t, errs, []string{
814 `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
815 `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
816 `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
817 `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
818 `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
819 `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
820 })
821}
822
823func TestRecoverySnapshotCapture(t *testing.T) {
824 bp := `
825 cc_library {
826 name: "libvndk",
827 vendor_available: true,
828 recovery_available: true,
829 product_available: true,
830 vndk: {
831 enabled: true,
832 },
833 nocrt: true,
834 }
835
836 cc_library {
837 name: "librecovery",
838 recovery: true,
839 nocrt: true,
840 }
841
842 cc_library {
843 name: "librecovery_available",
844 recovery_available: true,
845 nocrt: true,
846 }
847
848 cc_library_headers {
849 name: "librecovery_headers",
850 recovery_available: true,
851 nocrt: true,
852 }
853
854 cc_binary {
855 name: "recovery_bin",
856 recovery: true,
857 nocrt: true,
858 }
859
860 cc_binary {
861 name: "recovery_available_bin",
862 recovery_available: true,
863 nocrt: true,
864 }
865
866 toolchain_library {
867 name: "libb",
868 recovery_available: true,
869 src: "libb.a",
870 }
871
872 cc_object {
873 name: "obj",
874 recovery_available: true,
875 }
876`
877 config := TestConfig(buildDir, android.Android, nil, bp, nil)
878 config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current")
879 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
880 ctx := testCcWithConfig(t, config)
881
882 // Check Recovery snapshot output.
883
884 snapshotDir := "recovery-snapshot"
885 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
886 snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
887
888 var jsonFiles []string
889
890 for _, arch := range [][]string{
891 []string{"arm64", "armv8-a"},
892 } {
893 archType := arch[0]
894 archVariant := arch[1]
895 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
896
897 // For shared libraries, only recovery_available modules are captured.
898 sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
899 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
900 checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", sharedDir, sharedVariant)
901 checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
902 checkSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant)
903 jsonFiles = append(jsonFiles,
904 filepath.Join(sharedDir, "libvndk.so.json"),
905 filepath.Join(sharedDir, "librecovery.so.json"),
906 filepath.Join(sharedDir, "librecovery_available.so.json"))
907
908 // For static libraries, all recovery:true and recovery_available modules are captured.
909 staticVariant := fmt.Sprintf("android_recovery_%s_%s_static", archType, archVariant)
910 staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
911 checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
912 checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.a", staticDir, staticVariant)
913 checkSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.a", staticDir, staticVariant)
914 jsonFiles = append(jsonFiles,
915 filepath.Join(staticDir, "libb.a.json"),
916 filepath.Join(staticDir, "librecovery.a.json"),
917 filepath.Join(staticDir, "librecovery_available.a.json"))
918
919 // For binary executables, all recovery:true and recovery_available modules are captured.
920 if archType == "arm64" {
921 binaryVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant)
922 binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
923 checkSnapshot(t, ctx, snapshotSingleton, "recovery_bin", "recovery_bin", binaryDir, binaryVariant)
924 checkSnapshot(t, ctx, snapshotSingleton, "recovery_available_bin", "recovery_available_bin", binaryDir, binaryVariant)
925 jsonFiles = append(jsonFiles,
926 filepath.Join(binaryDir, "recovery_bin.json"),
927 filepath.Join(binaryDir, "recovery_available_bin.json"))
928 }
929
930 // For header libraries, all vendor:true and vendor_available modules are captured.
931 headerDir := filepath.Join(snapshotVariantPath, archDir, "header")
932 jsonFiles = append(jsonFiles, filepath.Join(headerDir, "librecovery_headers.json"))
933
934 // For object modules, all vendor:true and vendor_available modules are captured.
935 objectVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant)
936 objectDir := filepath.Join(snapshotVariantPath, archDir, "object")
937 checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant)
938 jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json"))
939 }
940
941 for _, jsonFile := range jsonFiles {
942 // verify all json files exist
943 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
944 t.Errorf("%q expected but not found", jsonFile)
945 }
946 }
947}
948
949func TestRecoverySnapshotExclude(t *testing.T) {
950 // This test verifies that the exclude_from_recovery_snapshot property
951 // makes its way from the Android.bp source file into the module data
952 // structure. It also verifies that modules are correctly included or
953 // excluded in the recovery snapshot based on their path (framework or
954 // vendor) and the exclude_from_recovery_snapshot property.
955
956 frameworkBp := `
957 cc_library_shared {
958 name: "libinclude",
959 srcs: ["src/include.cpp"],
960 recovery_available: true,
961 }
962 cc_library_shared {
963 name: "libexclude",
964 srcs: ["src/exclude.cpp"],
965 recovery: true,
966 exclude_from_recovery_snapshot: true,
967 }
968 cc_library_shared {
969 name: "libavailable_exclude",
970 srcs: ["src/exclude.cpp"],
971 recovery_available: true,
972 exclude_from_recovery_snapshot: true,
973 }
974 `
975
976 vendorProprietaryBp := `
977 cc_library_shared {
978 name: "librecovery",
979 srcs: ["recovery.cpp"],
980 recovery: true,
981 }
982 `
983
984 depsBp := GatherRequiredDepsForTest(android.Android)
985
986 mockFS := map[string][]byte{
987 "deps/Android.bp": []byte(depsBp),
988 "framework/Android.bp": []byte(frameworkBp),
989 "framework/include.cpp": nil,
990 "framework/exclude.cpp": nil,
991 "device/Android.bp": []byte(vendorProprietaryBp),
992 "device/recovery.cpp": nil,
993 }
994
995 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
996 config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current")
997 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
998 ctx := CreateTestContext(config)
999 ctx.Register()
1000
1001 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "device/Android.bp"})
1002 android.FailIfErrored(t, errs)
1003 _, errs = ctx.PrepareBuildActions(config)
1004 android.FailIfErrored(t, errs)
1005
1006 // Test an include and exclude framework module.
1007 assertExcludeFromRecoverySnapshotIs(t, ctx, "libinclude", false)
1008 assertExcludeFromRecoverySnapshotIs(t, ctx, "libexclude", true)
1009 assertExcludeFromRecoverySnapshotIs(t, ctx, "libavailable_exclude", true)
1010
1011 // A recovery module is excluded, but by its path, not the
1012 // exclude_from_recovery_snapshot property.
1013 assertExcludeFromRecoverySnapshotIs(t, ctx, "librecovery", false)
1014
1015 // Verify the content of the recovery snapshot.
1016
1017 snapshotDir := "recovery-snapshot"
1018 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
1019 snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
1020
1021 var includeJsonFiles []string
1022 var excludeJsonFiles []string
1023
1024 for _, arch := range [][]string{
1025 []string{"arm64", "armv8-a"},
1026 } {
1027 archType := arch[0]
1028 archVariant := arch[1]
1029 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
1030
1031 sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
1032 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
1033
1034 // Included modules
1035 checkSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
1036 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
1037
1038 // Excluded modules
1039 checkSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
1040 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
1041 checkSnapshotExclude(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
1042 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json"))
1043 checkSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
1044 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
1045 }
1046
1047 // Verify that each json file for an included module has a rule.
1048 for _, jsonFile := range includeJsonFiles {
1049 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
1050 t.Errorf("include json file %q not found", jsonFile)
1051 }
1052 }
1053
1054 // Verify that each json file for an excluded module has no rule.
1055 for _, jsonFile := range excludeJsonFiles {
1056 if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
1057 t.Errorf("exclude json file %q found", jsonFile)
1058 }
1059 }
1060}