blob: 659b6931c3de821ae68e38b6e622c5d4424ab326 [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
Colin Cross0fce0ba2021-01-08 16:40:12 -0800231
232 for _, arch := range [][]string{
233 []string{"arm64", "armv8-a"},
234 []string{"arm", "armv7-a-neon"},
235 } {
236 archType := arch[0]
237 archVariant := arch[1]
238 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
239
240 sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant)
241 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
242
243 // Included modules
244 checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
245 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json"))
246 // Check that snapshot captures "prefer: true" prebuilt
247 checkSnapshot(t, ctx, snapshotSingleton, "prebuilt_libfoo", "libfoo.so", sharedDir, sharedVariant)
248 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libfoo.so.json"))
249
Jose Galmes0a942a02021-02-03 14:23:15 -0800250 // Excluded modules. Modules not included in the directed vendor snapshot
251 // are still include as fake modules.
252 checkSnapshotRule(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant)
253 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libvendor_available.so.json"))
Colin Cross0fce0ba2021-01-08 16:40:12 -0800254 }
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 }
Colin Cross0fce0ba2021-01-08 16:40:12 -0800262}
263
264func TestVendorSnapshotUse(t *testing.T) {
265 frameworkBp := `
266 cc_library {
267 name: "libvndk",
268 vendor_available: true,
269 product_available: true,
270 vndk: {
271 enabled: true,
272 },
273 nocrt: true,
274 compile_multilib: "64",
275 }
276
277 cc_library {
278 name: "libvendor",
279 vendor: true,
280 nocrt: true,
281 no_libcrt: true,
282 stl: "none",
283 system_shared_libs: [],
284 compile_multilib: "64",
285 }
286
Colin Cross2e577f32021-01-22 13:06:25 -0800287 cc_library {
288 name: "libvendor_available",
289 vendor_available: true,
290 nocrt: true,
291 no_libcrt: true,
292 stl: "none",
293 system_shared_libs: [],
294 compile_multilib: "64",
295 }
296
Colin Cross0fce0ba2021-01-08 16:40:12 -0800297 cc_binary {
298 name: "bin",
299 vendor: true,
300 nocrt: true,
301 no_libcrt: true,
302 stl: "none",
303 system_shared_libs: [],
304 compile_multilib: "64",
305 }
306`
307
308 vndkBp := `
309 vndk_prebuilt_shared {
310 name: "libvndk",
311 version: "BOARD",
312 target_arch: "arm64",
313 vendor_available: true,
314 product_available: true,
315 vndk: {
316 enabled: true,
317 },
318 arch: {
319 arm64: {
320 srcs: ["libvndk.so"],
321 export_include_dirs: ["include/libvndk"],
322 },
323 },
324 }
Colin Crosse0edaf92021-01-11 17:31:17 -0800325
326 // old snapshot module which has to be ignored
327 vndk_prebuilt_shared {
328 name: "libvndk",
329 version: "OLD",
330 target_arch: "arm64",
331 vendor_available: true,
332 product_available: true,
333 vndk: {
334 enabled: true,
335 },
336 arch: {
337 arm64: {
338 srcs: ["libvndk.so"],
339 export_include_dirs: ["include/libvndk"],
340 },
341 },
342 }
Colin Cross0fce0ba2021-01-08 16:40:12 -0800343`
344
345 vendorProprietaryBp := `
346 cc_library {
347 name: "libvendor_without_snapshot",
348 vendor: true,
349 nocrt: true,
350 no_libcrt: true,
351 stl: "none",
352 system_shared_libs: [],
353 compile_multilib: "64",
354 }
355
356 cc_library_shared {
357 name: "libclient",
358 vendor: true,
359 nocrt: true,
360 no_libcrt: true,
361 stl: "none",
362 system_shared_libs: [],
Colin Cross2e577f32021-01-22 13:06:25 -0800363 shared_libs: ["libvndk", "libvendor_available"],
Colin Cross0fce0ba2021-01-08 16:40:12 -0800364 static_libs: ["libvendor", "libvendor_without_snapshot"],
365 compile_multilib: "64",
366 srcs: ["client.cpp"],
367 }
368
369 cc_binary {
370 name: "bin_without_snapshot",
371 vendor: true,
372 nocrt: true,
373 no_libcrt: true,
374 stl: "none",
375 system_shared_libs: [],
376 static_libs: ["libvndk"],
377 compile_multilib: "64",
378 srcs: ["bin.cpp"],
379 }
380
Colin Crosse0edaf92021-01-11 17:31:17 -0800381 vendor_snapshot {
382 name: "vendor_snapshot",
383 compile_multilib: "first",
384 version: "BOARD",
385 vndk_libs: [
386 "libvndk",
387 ],
388 static_libs: [
389 "libvendor",
390 "libvendor_available",
391 "libvndk",
392 ],
393 shared_libs: [
394 "libvendor",
395 "libvendor_available",
396 ],
397 binaries: [
398 "bin",
399 ],
400 }
401
Colin Cross0fce0ba2021-01-08 16:40:12 -0800402 vendor_snapshot_static {
403 name: "libvndk",
404 version: "BOARD",
405 target_arch: "arm64",
406 vendor: true,
407 arch: {
408 arm64: {
409 src: "libvndk.a",
410 export_include_dirs: ["include/libvndk"],
411 },
412 },
413 }
414
415 vendor_snapshot_shared {
416 name: "libvendor",
417 version: "BOARD",
418 target_arch: "arm64",
419 vendor: true,
420 arch: {
421 arm64: {
422 src: "libvendor.so",
423 export_include_dirs: ["include/libvendor"],
424 },
425 },
426 }
427
428 vendor_snapshot_static {
429 name: "libvendor",
430 version: "BOARD",
431 target_arch: "arm64",
432 vendor: true,
433 arch: {
434 arm64: {
435 src: "libvendor.a",
436 export_include_dirs: ["include/libvendor"],
437 },
438 },
439 }
440
Colin Cross2e577f32021-01-22 13:06:25 -0800441 vendor_snapshot_shared {
442 name: "libvendor_available",
Colin Crossa8890802021-01-22 14:06:33 -0800443 androidmk_suffix: ".vendor",
Colin Cross2e577f32021-01-22 13:06:25 -0800444 version: "BOARD",
445 target_arch: "arm64",
446 vendor: true,
447 arch: {
448 arm64: {
449 src: "libvendor_available.so",
450 export_include_dirs: ["include/libvendor"],
451 },
452 },
453 }
454
455 vendor_snapshot_static {
456 name: "libvendor_available",
Colin Crossa8890802021-01-22 14:06:33 -0800457 androidmk_suffix: ".vendor",
Colin Cross2e577f32021-01-22 13:06:25 -0800458 version: "BOARD",
459 target_arch: "arm64",
460 vendor: true,
461 arch: {
462 arm64: {
463 src: "libvendor_available.a",
464 export_include_dirs: ["include/libvendor"],
465 },
466 },
467 }
468
Colin Cross0fce0ba2021-01-08 16:40:12 -0800469 vendor_snapshot_binary {
470 name: "bin",
471 version: "BOARD",
472 target_arch: "arm64",
473 vendor: true,
474 arch: {
475 arm64: {
476 src: "bin",
477 },
478 },
479 }
Colin Crosse0edaf92021-01-11 17:31:17 -0800480
481 // old snapshot module which has to be ignored
482 vendor_snapshot_binary {
483 name: "bin",
484 version: "OLD",
485 target_arch: "arm64",
486 vendor: true,
487 arch: {
488 arm64: {
489 src: "bin",
490 },
491 },
492 }
Colin Cross0fce0ba2021-01-08 16:40:12 -0800493`
494 depsBp := GatherRequiredDepsForTest(android.Android)
495
496 mockFS := map[string][]byte{
497 "deps/Android.bp": []byte(depsBp),
498 "framework/Android.bp": []byte(frameworkBp),
499 "vendor/Android.bp": []byte(vendorProprietaryBp),
500 "vendor/bin": nil,
501 "vendor/bin.cpp": nil,
502 "vendor/client.cpp": nil,
503 "vendor/include/libvndk/a.h": nil,
504 "vendor/include/libvendor/b.h": nil,
505 "vendor/libvndk.a": nil,
506 "vendor/libvendor.a": nil,
507 "vendor/libvendor.so": nil,
508 "vndk/Android.bp": []byte(vndkBp),
509 "vndk/include/libvndk/a.h": nil,
510 "vndk/libvndk.so": nil,
511 }
512
513 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
514 config.TestProductVariables.DeviceVndkVersion = StringPtr("BOARD")
515 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
516 ctx := CreateTestContext(config)
517 ctx.Register()
518
519 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "vendor/Android.bp", "vndk/Android.bp"})
520 android.FailIfErrored(t, errs)
521 _, errs = ctx.PrepareBuildActions(config)
522 android.FailIfErrored(t, errs)
523
524 sharedVariant := "android_vendor.BOARD_arm64_armv8-a_shared"
525 staticVariant := "android_vendor.BOARD_arm64_armv8-a_static"
526 binaryVariant := "android_vendor.BOARD_arm64_armv8-a"
527
528 // libclient uses libvndk.vndk.BOARD.arm64, libvendor.vendor_static.BOARD.arm64, libvendor_without_snapshot
529 libclientCcFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("cc").Args["cFlags"]
530 for _, includeFlags := range []string{
531 "-Ivndk/include/libvndk", // libvndk
532 "-Ivendor/include/libvendor", // libvendor
533 } {
534 if !strings.Contains(libclientCcFlags, includeFlags) {
535 t.Errorf("flags for libclient must contain %#v, but was %#v.",
536 includeFlags, libclientCcFlags)
537 }
538 }
539
540 libclientLdFlags := ctx.ModuleForTests("libclient", sharedVariant).Rule("ld").Args["libFlags"]
541 for _, input := range [][]string{
542 []string{sharedVariant, "libvndk.vndk.BOARD.arm64"},
543 []string{staticVariant, "libvendor.vendor_static.BOARD.arm64"},
544 []string{staticVariant, "libvendor_without_snapshot"},
545 } {
546 outputPaths := getOutputPaths(ctx, input[0] /* variant */, []string{input[1]} /* module name */)
547 if !strings.Contains(libclientLdFlags, outputPaths[0].String()) {
548 t.Errorf("libflags for libclient must contain %#v, but was %#v", outputPaths[0], libclientLdFlags)
549 }
550 }
551
Colin Cross2e577f32021-01-22 13:06:25 -0800552 libclientAndroidMkSharedLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkSharedLibs
553 if g, w := libclientAndroidMkSharedLibs, []string{"libvndk.vendor", "libvendor_available.vendor"}; !reflect.DeepEqual(g, w) {
554 t.Errorf("wanted libclient AndroidMkSharedLibs %q, got %q", w, g)
555 }
556
557 libclientAndroidMkStaticLibs := ctx.ModuleForTests("libclient", sharedVariant).Module().(*Module).Properties.AndroidMkStaticLibs
558 if g, w := libclientAndroidMkStaticLibs, []string{"libvendor", "libvendor_without_snapshot"}; !reflect.DeepEqual(g, w) {
559 t.Errorf("wanted libclient AndroidMkStaticLibs %q, got %q", w, g)
560 }
561
Colin Cross0fce0ba2021-01-08 16:40:12 -0800562 // bin_without_snapshot uses libvndk.vendor_static.BOARD.arm64
563 binWithoutSnapshotCcFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("cc").Args["cFlags"]
564 if !strings.Contains(binWithoutSnapshotCcFlags, "-Ivendor/include/libvndk") {
565 t.Errorf("flags for bin_without_snapshot must contain %#v, but was %#v.",
566 "-Ivendor/include/libvndk", binWithoutSnapshotCcFlags)
567 }
568
569 binWithoutSnapshotLdFlags := ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Rule("ld").Args["libFlags"]
570 libVndkStaticOutputPaths := getOutputPaths(ctx, staticVariant, []string{"libvndk.vendor_static.BOARD.arm64"})
571 if !strings.Contains(binWithoutSnapshotLdFlags, libVndkStaticOutputPaths[0].String()) {
572 t.Errorf("libflags for bin_without_snapshot must contain %#v, but was %#v",
573 libVndkStaticOutputPaths[0], binWithoutSnapshotLdFlags)
574 }
575
576 // libvendor.so is installed by libvendor.vendor_shared.BOARD.arm64
577 ctx.ModuleForTests("libvendor.vendor_shared.BOARD.arm64", sharedVariant).Output("libvendor.so")
578
Colin Cross2e577f32021-01-22 13:06:25 -0800579 // libvendor_available.so is installed by libvendor_available.vendor_shared.BOARD.arm64
580 ctx.ModuleForTests("libvendor_available.vendor_shared.BOARD.arm64", sharedVariant).Output("libvendor_available.so")
581
Colin Cross0fce0ba2021-01-08 16:40:12 -0800582 // libvendor_without_snapshot.so is installed by libvendor_without_snapshot
583 ctx.ModuleForTests("libvendor_without_snapshot", sharedVariant).Output("libvendor_without_snapshot.so")
584
585 // bin is installed by bin.vendor_binary.BOARD.arm64
586 ctx.ModuleForTests("bin.vendor_binary.BOARD.arm64", binaryVariant).Output("bin")
587
588 // bin_without_snapshot is installed by bin_without_snapshot
589 ctx.ModuleForTests("bin_without_snapshot", binaryVariant).Output("bin_without_snapshot")
590
Colin Cross2e577f32021-01-22 13:06:25 -0800591 // libvendor, libvendor_available and bin don't have vendor.BOARD variant
Colin Cross0fce0ba2021-01-08 16:40:12 -0800592 libvendorVariants := ctx.ModuleVariantsForTests("libvendor")
593 if inList(sharedVariant, libvendorVariants) {
594 t.Errorf("libvendor must not have variant %#v, but it does", sharedVariant)
595 }
596
Colin Cross2e577f32021-01-22 13:06:25 -0800597 libvendorAvailableVariants := ctx.ModuleVariantsForTests("libvendor_available")
598 if inList(sharedVariant, libvendorAvailableVariants) {
599 t.Errorf("libvendor_available must not have variant %#v, but it does", sharedVariant)
600 }
601
Colin Cross0fce0ba2021-01-08 16:40:12 -0800602 binVariants := ctx.ModuleVariantsForTests("bin")
603 if inList(binaryVariant, binVariants) {
604 t.Errorf("bin must not have variant %#v, but it does", sharedVariant)
605 }
606}
607
608func TestVendorSnapshotSanitizer(t *testing.T) {
609 bp := `
610 vendor_snapshot_static {
611 name: "libsnapshot",
612 vendor: true,
613 target_arch: "arm64",
614 version: "BOARD",
615 arch: {
616 arm64: {
617 src: "libsnapshot.a",
618 cfi: {
619 src: "libsnapshot.cfi.a",
620 }
621 },
622 },
623 }
624`
625 config := TestConfig(buildDir, android.Android, nil, bp, nil)
626 config.TestProductVariables.DeviceVndkVersion = StringPtr("BOARD")
627 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
628 ctx := testCcWithConfig(t, config)
629
630 // Check non-cfi and cfi variant.
631 staticVariant := "android_vendor.BOARD_arm64_armv8-a_static"
632 staticCfiVariant := "android_vendor.BOARD_arm64_armv8-a_static_cfi"
633
634 staticModule := ctx.ModuleForTests("libsnapshot.vendor_static.BOARD.arm64", staticVariant).Module().(*Module)
635 assertString(t, staticModule.outputFile.Path().Base(), "libsnapshot.a")
636
637 staticCfiModule := ctx.ModuleForTests("libsnapshot.vendor_static.BOARD.arm64", staticCfiVariant).Module().(*Module)
638 assertString(t, staticCfiModule.outputFile.Path().Base(), "libsnapshot.cfi.a")
639}
640
641func assertExcludeFromVendorSnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool) {
642 t.Helper()
643 m := ctx.ModuleForTests(name, vendorVariant).Module().(*Module)
644 if m.ExcludeFromVendorSnapshot() != expected {
645 t.Errorf("expected %q ExcludeFromVendorSnapshot to be %t", m.String(), expected)
646 }
647}
648
649func assertExcludeFromRecoverySnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool) {
650 t.Helper()
651 m := ctx.ModuleForTests(name, recoveryVariant).Module().(*Module)
652 if m.ExcludeFromRecoverySnapshot() != expected {
653 t.Errorf("expected %q ExcludeFromRecoverySnapshot to be %t", m.String(), expected)
654 }
655}
656
657func TestVendorSnapshotExclude(t *testing.T) {
658
659 // This test verifies that the exclude_from_vendor_snapshot property
660 // makes its way from the Android.bp source file into the module data
661 // structure. It also verifies that modules are correctly included or
662 // excluded in the vendor snapshot based on their path (framework or
663 // vendor) and the exclude_from_vendor_snapshot property.
664
665 frameworkBp := `
666 cc_library_shared {
667 name: "libinclude",
668 srcs: ["src/include.cpp"],
669 vendor_available: true,
670 }
671 cc_library_shared {
672 name: "libexclude",
673 srcs: ["src/exclude.cpp"],
674 vendor: true,
675 exclude_from_vendor_snapshot: true,
676 }
677 cc_library_shared {
678 name: "libavailable_exclude",
679 srcs: ["src/exclude.cpp"],
680 vendor_available: true,
681 exclude_from_vendor_snapshot: true,
682 }
683 `
684
685 vendorProprietaryBp := `
686 cc_library_shared {
687 name: "libvendor",
688 srcs: ["vendor.cpp"],
689 vendor: true,
690 }
691 `
692
693 depsBp := GatherRequiredDepsForTest(android.Android)
694
695 mockFS := map[string][]byte{
696 "deps/Android.bp": []byte(depsBp),
697 "framework/Android.bp": []byte(frameworkBp),
698 "framework/include.cpp": nil,
699 "framework/exclude.cpp": nil,
700 "device/Android.bp": []byte(vendorProprietaryBp),
701 "device/vendor.cpp": nil,
702 }
703
704 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
705 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
706 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
707 ctx := CreateTestContext(config)
708 ctx.Register()
709
710 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "device/Android.bp"})
711 android.FailIfErrored(t, errs)
712 _, errs = ctx.PrepareBuildActions(config)
713 android.FailIfErrored(t, errs)
714
715 // Test an include and exclude framework module.
716 assertExcludeFromVendorSnapshotIs(t, ctx, "libinclude", false)
717 assertExcludeFromVendorSnapshotIs(t, ctx, "libexclude", true)
718 assertExcludeFromVendorSnapshotIs(t, ctx, "libavailable_exclude", true)
719
720 // A vendor module is excluded, but by its path, not the
721 // exclude_from_vendor_snapshot property.
722 assertExcludeFromVendorSnapshotIs(t, ctx, "libvendor", false)
723
724 // Verify the content of the vendor snapshot.
725
726 snapshotDir := "vendor-snapshot"
727 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
728 snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
729
730 var includeJsonFiles []string
731 var excludeJsonFiles []string
732
733 for _, arch := range [][]string{
734 []string{"arm64", "armv8-a"},
735 []string{"arm", "armv7-a-neon"},
736 } {
737 archType := arch[0]
738 archVariant := arch[1]
739 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
740
741 sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant)
742 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
743
744 // Included modules
745 checkSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
746 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
747
748 // Excluded modules
749 checkSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
750 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
751 checkSnapshotExclude(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
752 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libvendor.so.json"))
753 checkSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
754 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
755 }
756
757 // Verify that each json file for an included module has a rule.
758 for _, jsonFile := range includeJsonFiles {
759 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
760 t.Errorf("include json file %q not found", jsonFile)
761 }
762 }
763
764 // Verify that each json file for an excluded module has no rule.
765 for _, jsonFile := range excludeJsonFiles {
766 if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
767 t.Errorf("exclude json file %q found", jsonFile)
768 }
769 }
770}
771
772func TestVendorSnapshotExcludeInVendorProprietaryPathErrors(t *testing.T) {
773
774 // This test verifies that using the exclude_from_vendor_snapshot
775 // property on a module in a vendor proprietary path generates an
776 // error. These modules are already excluded, so we prohibit using the
777 // property in this way, which could add to confusion.
778
779 vendorProprietaryBp := `
780 cc_library_shared {
781 name: "libvendor",
782 srcs: ["vendor.cpp"],
783 vendor: true,
784 exclude_from_vendor_snapshot: true,
785 }
786 `
787
788 depsBp := GatherRequiredDepsForTest(android.Android)
789
790 mockFS := map[string][]byte{
791 "deps/Android.bp": []byte(depsBp),
792 "device/Android.bp": []byte(vendorProprietaryBp),
793 "device/vendor.cpp": nil,
794 }
795
796 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
797 config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
798 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
799 ctx := CreateTestContext(config)
800 ctx.Register()
801
802 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "device/Android.bp"})
803 android.FailIfErrored(t, errs)
804
805 _, errs = ctx.PrepareBuildActions(config)
806 android.CheckErrorsAgainstExpectations(t, errs, []string{
807 `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
808 `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
809 `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
810 `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
811 `module "libvendor\{.+,image:vendor.+,arch:arm64_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
812 `module "libvendor\{.+,image:vendor.+,arch:arm_.+\}" in vendor proprietary path "device" may not use "exclude_from_vendor_snapshot: true"`,
813 })
814}
815
816func TestRecoverySnapshotCapture(t *testing.T) {
817 bp := `
818 cc_library {
819 name: "libvndk",
820 vendor_available: true,
821 recovery_available: true,
822 product_available: true,
823 vndk: {
824 enabled: true,
825 },
826 nocrt: true,
827 }
828
829 cc_library {
830 name: "librecovery",
831 recovery: true,
832 nocrt: true,
833 }
834
835 cc_library {
836 name: "librecovery_available",
837 recovery_available: true,
838 nocrt: true,
839 }
840
841 cc_library_headers {
842 name: "librecovery_headers",
843 recovery_available: true,
844 nocrt: true,
845 }
846
847 cc_binary {
848 name: "recovery_bin",
849 recovery: true,
850 nocrt: true,
851 }
852
853 cc_binary {
854 name: "recovery_available_bin",
855 recovery_available: true,
856 nocrt: true,
857 }
858
859 toolchain_library {
860 name: "libb",
861 recovery_available: true,
862 src: "libb.a",
863 }
864
865 cc_object {
866 name: "obj",
867 recovery_available: true,
868 }
869`
870 config := TestConfig(buildDir, android.Android, nil, bp, nil)
871 config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current")
872 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
873 ctx := testCcWithConfig(t, config)
874
875 // Check Recovery snapshot output.
876
877 snapshotDir := "recovery-snapshot"
878 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
879 snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
880
881 var jsonFiles []string
882
883 for _, arch := range [][]string{
884 []string{"arm64", "armv8-a"},
885 } {
886 archType := arch[0]
887 archVariant := arch[1]
888 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
889
890 // For shared libraries, only recovery_available modules are captured.
891 sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
892 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
893 checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", sharedDir, sharedVariant)
894 checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
895 checkSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.so", sharedDir, sharedVariant)
896 jsonFiles = append(jsonFiles,
897 filepath.Join(sharedDir, "libvndk.so.json"),
898 filepath.Join(sharedDir, "librecovery.so.json"),
899 filepath.Join(sharedDir, "librecovery_available.so.json"))
900
901 // For static libraries, all recovery:true and recovery_available modules are captured.
902 staticVariant := fmt.Sprintf("android_recovery_%s_%s_static", archType, archVariant)
903 staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
904 checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
905 checkSnapshot(t, ctx, snapshotSingleton, "librecovery", "librecovery.a", staticDir, staticVariant)
906 checkSnapshot(t, ctx, snapshotSingleton, "librecovery_available", "librecovery_available.a", staticDir, staticVariant)
907 jsonFiles = append(jsonFiles,
908 filepath.Join(staticDir, "libb.a.json"),
909 filepath.Join(staticDir, "librecovery.a.json"),
910 filepath.Join(staticDir, "librecovery_available.a.json"))
911
912 // For binary executables, all recovery:true and recovery_available modules are captured.
913 if archType == "arm64" {
914 binaryVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant)
915 binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
916 checkSnapshot(t, ctx, snapshotSingleton, "recovery_bin", "recovery_bin", binaryDir, binaryVariant)
917 checkSnapshot(t, ctx, snapshotSingleton, "recovery_available_bin", "recovery_available_bin", binaryDir, binaryVariant)
918 jsonFiles = append(jsonFiles,
919 filepath.Join(binaryDir, "recovery_bin.json"),
920 filepath.Join(binaryDir, "recovery_available_bin.json"))
921 }
922
923 // For header libraries, all vendor:true and vendor_available modules are captured.
924 headerDir := filepath.Join(snapshotVariantPath, archDir, "header")
925 jsonFiles = append(jsonFiles, filepath.Join(headerDir, "librecovery_headers.json"))
926
927 // For object modules, all vendor:true and vendor_available modules are captured.
928 objectVariant := fmt.Sprintf("android_recovery_%s_%s", archType, archVariant)
929 objectDir := filepath.Join(snapshotVariantPath, archDir, "object")
930 checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant)
931 jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json"))
932 }
933
934 for _, jsonFile := range jsonFiles {
935 // verify all json files exist
936 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
937 t.Errorf("%q expected but not found", jsonFile)
938 }
939 }
940}
941
942func TestRecoverySnapshotExclude(t *testing.T) {
943 // This test verifies that the exclude_from_recovery_snapshot property
944 // makes its way from the Android.bp source file into the module data
945 // structure. It also verifies that modules are correctly included or
946 // excluded in the recovery snapshot based on their path (framework or
947 // vendor) and the exclude_from_recovery_snapshot property.
948
949 frameworkBp := `
950 cc_library_shared {
951 name: "libinclude",
952 srcs: ["src/include.cpp"],
953 recovery_available: true,
954 }
955 cc_library_shared {
956 name: "libexclude",
957 srcs: ["src/exclude.cpp"],
958 recovery: true,
959 exclude_from_recovery_snapshot: true,
960 }
961 cc_library_shared {
962 name: "libavailable_exclude",
963 srcs: ["src/exclude.cpp"],
964 recovery_available: true,
965 exclude_from_recovery_snapshot: true,
966 }
967 `
968
969 vendorProprietaryBp := `
970 cc_library_shared {
971 name: "librecovery",
972 srcs: ["recovery.cpp"],
973 recovery: true,
974 }
975 `
976
977 depsBp := GatherRequiredDepsForTest(android.Android)
978
979 mockFS := map[string][]byte{
980 "deps/Android.bp": []byte(depsBp),
981 "framework/Android.bp": []byte(frameworkBp),
982 "framework/include.cpp": nil,
983 "framework/exclude.cpp": nil,
984 "device/Android.bp": []byte(vendorProprietaryBp),
985 "device/recovery.cpp": nil,
986 }
987
988 config := TestConfig(buildDir, android.Android, nil, "", mockFS)
989 config.TestProductVariables.RecoverySnapshotVersion = StringPtr("current")
990 config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
991 ctx := CreateTestContext(config)
992 ctx.Register()
993
994 _, errs := ctx.ParseFileList(".", []string{"deps/Android.bp", "framework/Android.bp", "device/Android.bp"})
995 android.FailIfErrored(t, errs)
996 _, errs = ctx.PrepareBuildActions(config)
997 android.FailIfErrored(t, errs)
998
999 // Test an include and exclude framework module.
1000 assertExcludeFromRecoverySnapshotIs(t, ctx, "libinclude", false)
1001 assertExcludeFromRecoverySnapshotIs(t, ctx, "libexclude", true)
1002 assertExcludeFromRecoverySnapshotIs(t, ctx, "libavailable_exclude", true)
1003
1004 // A recovery module is excluded, but by its path, not the
1005 // exclude_from_recovery_snapshot property.
1006 assertExcludeFromRecoverySnapshotIs(t, ctx, "librecovery", false)
1007
1008 // Verify the content of the recovery snapshot.
1009
1010 snapshotDir := "recovery-snapshot"
1011 snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
1012 snapshotSingleton := ctx.SingletonForTests("recovery-snapshot")
1013
1014 var includeJsonFiles []string
1015 var excludeJsonFiles []string
1016
1017 for _, arch := range [][]string{
1018 []string{"arm64", "armv8-a"},
1019 } {
1020 archType := arch[0]
1021 archVariant := arch[1]
1022 archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
1023
1024 sharedVariant := fmt.Sprintf("android_recovery_%s_%s_shared", archType, archVariant)
1025 sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
1026
1027 // Included modules
1028 checkSnapshot(t, ctx, snapshotSingleton, "libinclude", "libinclude.so", sharedDir, sharedVariant)
1029 includeJsonFiles = append(includeJsonFiles, filepath.Join(sharedDir, "libinclude.so.json"))
1030
1031 // Excluded modules
1032 checkSnapshotExclude(t, ctx, snapshotSingleton, "libexclude", "libexclude.so", sharedDir, sharedVariant)
1033 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libexclude.so.json"))
1034 checkSnapshotExclude(t, ctx, snapshotSingleton, "librecovery", "librecovery.so", sharedDir, sharedVariant)
1035 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "librecovery.so.json"))
1036 checkSnapshotExclude(t, ctx, snapshotSingleton, "libavailable_exclude", "libavailable_exclude.so", sharedDir, sharedVariant)
1037 excludeJsonFiles = append(excludeJsonFiles, filepath.Join(sharedDir, "libavailable_exclude.so.json"))
1038 }
1039
1040 // Verify that each json file for an included module has a rule.
1041 for _, jsonFile := range includeJsonFiles {
1042 if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
1043 t.Errorf("include json file %q not found", jsonFile)
1044 }
1045 }
1046
1047 // Verify that each json file for an excluded module has no rule.
1048 for _, jsonFile := range excludeJsonFiles {
1049 if snapshotSingleton.MaybeOutput(jsonFile).Rule != nil {
1050 t.Errorf("exclude json file %q found", jsonFile)
1051 }
1052 }
1053}