1// Copyright 2017 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	"fmt"
19	"os"
20	"path/filepath"
21	"reflect"
22	"regexp"
23	"strings"
24	"testing"
25
26	"android/soong/android"
27)
28
29func TestMain(m *testing.M) {
30	os.Exit(m.Run())
31}
32
33var prepareForCcTest = android.GroupFixturePreparers(
34	PrepareForTestWithCcIncludeVndk,
35	android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
36		variables.DeviceVndkVersion = StringPtr("current")
37		variables.ProductVndkVersion = StringPtr("current")
38		variables.Platform_vndk_version = StringPtr("29")
39	}),
40)
41
42// testCcWithConfig runs tests using the prepareForCcTest
43//
44// See testCc for an explanation as to how to stop using this deprecated method.
45//
46// deprecated
47func testCcWithConfig(t *testing.T, config android.Config) *android.TestContext {
48	t.Helper()
49	result := prepareForCcTest.RunTestWithConfig(t, config)
50	return result.TestContext
51}
52
53// testCc runs tests using the prepareForCcTest
54//
55// Do not add any new usages of this, instead use the prepareForCcTest directly as it makes it much
56// easier to customize the test behavior.
57//
58// If it is necessary to customize the behavior of an existing test that uses this then please first
59// convert the test to using prepareForCcTest first and then in a following change add the
60// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify
61// that it did not change the test behavior unexpectedly.
62//
63// deprecated
64func testCc(t *testing.T, bp string) *android.TestContext {
65	t.Helper()
66	result := prepareForCcTest.RunTestWithBp(t, bp)
67	return result.TestContext
68}
69
70// testCcNoVndk runs tests using the prepareForCcTest
71//
72// See testCc for an explanation as to how to stop using this deprecated method.
73//
74// deprecated
75func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
76	t.Helper()
77	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
78	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
79
80	return testCcWithConfig(t, config)
81}
82
83// testCcNoProductVndk runs tests using the prepareForCcTest
84//
85// See testCc for an explanation as to how to stop using this deprecated method.
86//
87// deprecated
88func testCcNoProductVndk(t *testing.T, bp string) *android.TestContext {
89	t.Helper()
90	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
91	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
92	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
93
94	return testCcWithConfig(t, config)
95}
96
97// testCcErrorWithConfig runs tests using the prepareForCcTest
98//
99// See testCc for an explanation as to how to stop using this deprecated method.
100//
101// deprecated
102func testCcErrorWithConfig(t *testing.T, pattern string, config android.Config) {
103	t.Helper()
104
105	prepareForCcTest.
106		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
107		RunTestWithConfig(t, config)
108}
109
110// testCcError runs tests using the prepareForCcTest
111//
112// See testCc for an explanation as to how to stop using this deprecated method.
113//
114// deprecated
115func testCcError(t *testing.T, pattern string, bp string) {
116	t.Helper()
117	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
118	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
119	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
120	testCcErrorWithConfig(t, pattern, config)
121	return
122}
123
124// testCcErrorProductVndk runs tests using the prepareForCcTest
125//
126// See testCc for an explanation as to how to stop using this deprecated method.
127//
128// deprecated
129func testCcErrorProductVndk(t *testing.T, pattern string, bp string) {
130	t.Helper()
131	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
132	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
133	config.TestProductVariables.ProductVndkVersion = StringPtr("current")
134	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
135	testCcErrorWithConfig(t, pattern, config)
136	return
137}
138
139const (
140	coreVariant     = "android_arm64_armv8-a_shared"
141	vendorVariant   = "android_vendor.29_arm64_armv8-a_shared"
142	productVariant  = "android_product.29_arm64_armv8-a_shared"
143	recoveryVariant = "android_recovery_arm64_armv8-a_shared"
144)
145
146// Test that the PrepareForTestWithCcDefaultModules provides all the files that it uses by
147// running it in a fixture that requires all source files to exist.
148func TestPrepareForTestWithCcDefaultModules(t *testing.T) {
149	android.GroupFixturePreparers(
150		PrepareForTestWithCcDefaultModules,
151		android.PrepareForTestDisallowNonExistentPaths,
152	).RunTest(t)
153}
154
155func TestFuchsiaDeps(t *testing.T) {
156	t.Helper()
157
158	bp := `
159		cc_library {
160			name: "libTest",
161			srcs: ["foo.c"],
162			target: {
163				fuchsia: {
164					srcs: ["bar.c"],
165				},
166			},
167		}`
168
169	result := android.GroupFixturePreparers(
170		prepareForCcTest,
171		PrepareForTestOnFuchsia,
172	).RunTestWithBp(t, bp)
173
174	rt := false
175	fb := false
176
177	ld := result.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
178	implicits := ld.Implicits
179	for _, lib := range implicits {
180		if strings.Contains(lib.Rel(), "libcompiler_rt") {
181			rt = true
182		}
183
184		if strings.Contains(lib.Rel(), "libbioniccompat") {
185			fb = true
186		}
187	}
188
189	if !rt || !fb {
190		t.Errorf("fuchsia libs must link libcompiler_rt and libbioniccompat")
191	}
192}
193
194func TestFuchsiaTargetDecl(t *testing.T) {
195	t.Helper()
196
197	bp := `
198		cc_library {
199			name: "libTest",
200			srcs: ["foo.c"],
201			target: {
202				fuchsia: {
203					srcs: ["bar.c"],
204				},
205			},
206		}`
207
208	result := android.GroupFixturePreparers(
209		prepareForCcTest,
210		PrepareForTestOnFuchsia,
211	).RunTestWithBp(t, bp)
212	ld := result.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
213	var objs []string
214	for _, o := range ld.Inputs {
215		objs = append(objs, o.Base())
216	}
217	android.AssertArrayString(t, "libTest inputs", []string{"foo.o", "bar.o"}, objs)
218}
219
220func TestVendorSrc(t *testing.T) {
221	ctx := testCc(t, `
222		cc_library {
223			name: "libTest",
224			srcs: ["foo.c"],
225			no_libcrt: true,
226			nocrt: true,
227			system_shared_libs: [],
228			vendor_available: true,
229			target: {
230				vendor: {
231					srcs: ["bar.c"],
232				},
233			},
234		}
235	`)
236
237	ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
238	var objs []string
239	for _, o := range ld.Inputs {
240		objs = append(objs, o.Base())
241	}
242	if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
243		t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
244	}
245}
246
247func checkInstallPartition(t *testing.T, ctx *android.TestContext, name, variant, expected string) {
248	mod := ctx.ModuleForTests(name, variant).Module().(*Module)
249	partitionDefined := false
250	checkPartition := func(specific bool, partition string) {
251		if specific {
252			if expected != partition && !partitionDefined {
253				// The variant is installed to the 'partition'
254				t.Errorf("%s variant of %q must not be installed to %s partition", variant, name, partition)
255			}
256			partitionDefined = true
257		} else {
258			// The variant is not installed to the 'partition'
259			if expected == partition {
260				t.Errorf("%s variant of %q must be installed to %s partition", variant, name, partition)
261			}
262		}
263	}
264	socSpecific := func(m *Module) bool {
265		return m.SocSpecific() || m.socSpecificModuleContext()
266	}
267	deviceSpecific := func(m *Module) bool {
268		return m.DeviceSpecific() || m.deviceSpecificModuleContext()
269	}
270	productSpecific := func(m *Module) bool {
271		return m.ProductSpecific() || m.productSpecificModuleContext()
272	}
273	systemExtSpecific := func(m *Module) bool {
274		return m.SystemExtSpecific()
275	}
276	checkPartition(socSpecific(mod), "vendor")
277	checkPartition(deviceSpecific(mod), "odm")
278	checkPartition(productSpecific(mod), "product")
279	checkPartition(systemExtSpecific(mod), "system_ext")
280	if !partitionDefined && expected != "system" {
281		t.Errorf("%s variant of %q is expected to be installed to %s partition,"+
282			" but installed to system partition", variant, name, expected)
283	}
284}
285
286func TestInstallPartition(t *testing.T) {
287	t.Helper()
288	ctx := prepareForCcTest.RunTestWithBp(t, `
289		cc_library {
290			name: "libsystem",
291		}
292		cc_library {
293			name: "libsystem_ext",
294			system_ext_specific: true,
295		}
296		cc_library {
297			name: "libproduct",
298			product_specific: true,
299		}
300		cc_library {
301			name: "libvendor",
302			vendor: true,
303		}
304		cc_library {
305			name: "libodm",
306			device_specific: true,
307		}
308		cc_library {
309			name: "liball_available",
310			vendor_available: true,
311			product_available: true,
312		}
313		cc_library {
314			name: "libsystem_ext_all_available",
315			system_ext_specific: true,
316			vendor_available: true,
317			product_available: true,
318		}
319		cc_library {
320			name: "liball_available_odm",
321			odm_available: true,
322			product_available: true,
323		}
324		cc_library {
325			name: "libproduct_vendoravailable",
326			product_specific: true,
327			vendor_available: true,
328		}
329		cc_library {
330			name: "libproduct_odmavailable",
331			product_specific: true,
332			odm_available: true,
333		}
334	`).TestContext
335
336	checkInstallPartition(t, ctx, "libsystem", coreVariant, "system")
337	checkInstallPartition(t, ctx, "libsystem_ext", coreVariant, "system_ext")
338	checkInstallPartition(t, ctx, "libproduct", productVariant, "product")
339	checkInstallPartition(t, ctx, "libvendor", vendorVariant, "vendor")
340	checkInstallPartition(t, ctx, "libodm", vendorVariant, "odm")
341
342	checkInstallPartition(t, ctx, "liball_available", coreVariant, "system")
343	checkInstallPartition(t, ctx, "liball_available", productVariant, "product")
344	checkInstallPartition(t, ctx, "liball_available", vendorVariant, "vendor")
345
346	checkInstallPartition(t, ctx, "libsystem_ext_all_available", coreVariant, "system_ext")
347	checkInstallPartition(t, ctx, "libsystem_ext_all_available", productVariant, "product")
348	checkInstallPartition(t, ctx, "libsystem_ext_all_available", vendorVariant, "vendor")
349
350	checkInstallPartition(t, ctx, "liball_available_odm", coreVariant, "system")
351	checkInstallPartition(t, ctx, "liball_available_odm", productVariant, "product")
352	checkInstallPartition(t, ctx, "liball_available_odm", vendorVariant, "odm")
353
354	checkInstallPartition(t, ctx, "libproduct_vendoravailable", productVariant, "product")
355	checkInstallPartition(t, ctx, "libproduct_vendoravailable", vendorVariant, "vendor")
356
357	checkInstallPartition(t, ctx, "libproduct_odmavailable", productVariant, "product")
358	checkInstallPartition(t, ctx, "libproduct_odmavailable", vendorVariant, "odm")
359}
360
361func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
362	isVndkSp bool, extends string, variant string) {
363
364	t.Helper()
365
366	mod := ctx.ModuleForTests(name, variant).Module().(*Module)
367
368	// Check library properties.
369	lib, ok := mod.compiler.(*libraryDecorator)
370	if !ok {
371		t.Errorf("%q must have libraryDecorator", name)
372	} else if lib.baseInstaller.subDir != subDir {
373		t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
374			lib.baseInstaller.subDir)
375	}
376
377	// Check VNDK properties.
378	if mod.vndkdep == nil {
379		t.Fatalf("%q must have `vndkdep`", name)
380	}
381	if !mod.IsVndk() {
382		t.Errorf("%q IsVndk() must equal to true", name)
383	}
384	if mod.IsVndkSp() != isVndkSp {
385		t.Errorf("%q IsVndkSp() must equal to %t", name, isVndkSp)
386	}
387
388	// Check VNDK extension properties.
389	isVndkExt := extends != ""
390	if mod.IsVndkExt() != isVndkExt {
391		t.Errorf("%q IsVndkExt() must equal to %t", name, isVndkExt)
392	}
393
394	if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
395		t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
396	}
397}
398
399func checkSnapshotIncludeExclude(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string, include bool, fake bool) {
400	t.Helper()
401	mod := ctx.ModuleForTests(moduleName, variant)
402	outputFiles := mod.OutputFiles(t, "")
403	if len(outputFiles) != 1 {
404		t.Errorf("%q must have single output\n", moduleName)
405		return
406	}
407	snapshotPath := filepath.Join(subDir, snapshotFilename)
408
409	if include {
410		out := singleton.Output(snapshotPath)
411		if fake {
412			if out.Rule == nil {
413				t.Errorf("Missing rule for module %q output file %q", moduleName, outputFiles[0])
414			}
415		} else {
416			if out.Input.String() != outputFiles[0].String() {
417				t.Errorf("The input of snapshot %q must be %q, but %q", moduleName, out.Input.String(), outputFiles[0])
418			}
419		}
420	} else {
421		out := singleton.MaybeOutput(snapshotPath)
422		if out.Rule != nil {
423			t.Errorf("There must be no rule for module %q output file %q", moduleName, outputFiles[0])
424		}
425	}
426}
427
428func checkSnapshot(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string) {
429	t.Helper()
430	checkSnapshotIncludeExclude(t, ctx, singleton, moduleName, snapshotFilename, subDir, variant, true, false)
431}
432
433func checkSnapshotExclude(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string) {
434	t.Helper()
435	checkSnapshotIncludeExclude(t, ctx, singleton, moduleName, snapshotFilename, subDir, variant, false, false)
436}
437
438func checkSnapshotRule(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string) {
439	t.Helper()
440	checkSnapshotIncludeExclude(t, ctx, singleton, moduleName, snapshotFilename, subDir, variant, true, true)
441}
442
443func checkWriteFileOutput(t *testing.T, params android.TestingBuildParams, expected []string) {
444	t.Helper()
445	content := android.ContentFromFileRuleForTests(t, params)
446	actual := strings.FieldsFunc(content, func(r rune) bool { return r == '\n' })
447	assertArrayString(t, actual, expected)
448}
449
450func checkVndkOutput(t *testing.T, ctx *android.TestContext, output string, expected []string) {
451	t.Helper()
452	vndkSnapshot := ctx.SingletonForTests("vndk-snapshot")
453	checkWriteFileOutput(t, vndkSnapshot.Output(output), expected)
454}
455
456func checkVndkLibrariesOutput(t *testing.T, ctx *android.TestContext, module string, expected []string) {
457	t.Helper()
458	got := ctx.ModuleForTests(module, "").Module().(*vndkLibrariesTxt).fileNames
459	assertArrayString(t, got, expected)
460}
461
462func TestVndk(t *testing.T) {
463	bp := `
464		cc_library {
465			name: "libvndk",
466			vendor_available: true,
467			vndk: {
468				enabled: true,
469			},
470			nocrt: true,
471		}
472
473		cc_library {
474			name: "libvndk_private",
475			vendor_available: true,
476			vndk: {
477				enabled: true,
478				private: true,
479			},
480			nocrt: true,
481			stem: "libvndk-private",
482		}
483
484		cc_library {
485			name: "libvndk_product",
486			vendor_available: true,
487			product_available: true,
488			vndk: {
489				enabled: true,
490			},
491			nocrt: true,
492			target: {
493				vendor: {
494					cflags: ["-DTEST"],
495				},
496				product: {
497					cflags: ["-DTEST"],
498				},
499			},
500		}
501
502		cc_library {
503			name: "libvndk_sp",
504			vendor_available: true,
505			vndk: {
506				enabled: true,
507				support_system_process: true,
508			},
509			nocrt: true,
510			suffix: "-x",
511		}
512
513		cc_library {
514			name: "libvndk_sp_private",
515			vendor_available: true,
516			vndk: {
517				enabled: true,
518				support_system_process: true,
519				private: true,
520			},
521			nocrt: true,
522			target: {
523				vendor: {
524					suffix: "-x",
525				},
526			},
527		}
528
529		cc_library {
530			name: "libvndk_sp_product_private",
531			vendor_available: true,
532			product_available: true,
533			vndk: {
534				enabled: true,
535				support_system_process: true,
536				private: true,
537			},
538			nocrt: true,
539			target: {
540				vendor: {
541					suffix: "-x",
542				},
543				product: {
544					suffix: "-x",
545				},
546			},
547		}
548
549		cc_library {
550			name: "libllndk",
551			llndk: {
552				symbol_file: "libllndk.map.txt",
553				export_llndk_headers: ["libllndk_headers"],
554			}
555		}
556
557		cc_library {
558			name: "libclang_rt.hwasan-llndk",
559			llndk: {
560				symbol_file: "libclang_rt.hwasan.map.txt",
561			}
562		}
563
564		cc_library_headers {
565			name: "libllndk_headers",
566			llndk: {
567				llndk_headers: true,
568			},
569			export_include_dirs: ["include"],
570		}
571
572		llndk_libraries_txt {
573			name: "llndk.libraries.txt",
574		}
575		vndkcore_libraries_txt {
576			name: "vndkcore.libraries.txt",
577		}
578		vndksp_libraries_txt {
579			name: "vndksp.libraries.txt",
580		}
581		vndkprivate_libraries_txt {
582			name: "vndkprivate.libraries.txt",
583		}
584		vndkproduct_libraries_txt {
585			name: "vndkproduct.libraries.txt",
586		}
587		vndkcorevariant_libraries_txt {
588			name: "vndkcorevariant.libraries.txt",
589			insert_vndk_version: false,
590		}
591	`
592
593	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
594	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
595	config.TestProductVariables.ProductVndkVersion = StringPtr("current")
596	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
597
598	ctx := testCcWithConfig(t, config)
599
600	// subdir == "" because VNDK libs are not supposed to be installed separately.
601	// They are installed as part of VNDK APEX instead.
602	checkVndkModule(t, ctx, "libvndk", "", false, "", vendorVariant)
603	checkVndkModule(t, ctx, "libvndk_private", "", false, "", vendorVariant)
604	checkVndkModule(t, ctx, "libvndk_product", "", false, "", vendorVariant)
605	checkVndkModule(t, ctx, "libvndk_sp", "", true, "", vendorVariant)
606	checkVndkModule(t, ctx, "libvndk_sp_private", "", true, "", vendorVariant)
607	checkVndkModule(t, ctx, "libvndk_sp_product_private", "", true, "", vendorVariant)
608
609	checkVndkModule(t, ctx, "libvndk_product", "", false, "", productVariant)
610	checkVndkModule(t, ctx, "libvndk_sp_product_private", "", true, "", productVariant)
611
612	// Check VNDK snapshot output.
613	snapshotDir := "vndk-snapshot"
614	snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
615
616	vndkLibPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
617		"arm64", "armv8-a"))
618	vndkLib2ndPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
619		"arm", "armv7-a-neon"))
620
621	vndkCoreLibPath := filepath.Join(vndkLibPath, "shared", "vndk-core")
622	vndkSpLibPath := filepath.Join(vndkLibPath, "shared", "vndk-sp")
623	llndkLibPath := filepath.Join(vndkLibPath, "shared", "llndk-stub")
624
625	vndkCoreLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-core")
626	vndkSpLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-sp")
627	llndkLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "llndk-stub")
628
629	variant := "android_vendor.29_arm64_armv8-a_shared"
630	variant2nd := "android_vendor.29_arm_armv7-a-neon_shared"
631
632	snapshotSingleton := ctx.SingletonForTests("vndk-snapshot")
633
634	checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", vndkCoreLibPath, variant)
635	checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", vndkCoreLib2ndPath, variant2nd)
636	checkSnapshot(t, ctx, snapshotSingleton, "libvndk_product", "libvndk_product.so", vndkCoreLibPath, variant)
637	checkSnapshot(t, ctx, snapshotSingleton, "libvndk_product", "libvndk_product.so", vndkCoreLib2ndPath, variant2nd)
638	checkSnapshot(t, ctx, snapshotSingleton, "libvndk_sp", "libvndk_sp-x.so", vndkSpLibPath, variant)
639	checkSnapshot(t, ctx, snapshotSingleton, "libvndk_sp", "libvndk_sp-x.so", vndkSpLib2ndPath, variant2nd)
640	checkSnapshot(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", llndkLibPath, variant)
641	checkSnapshot(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", llndkLib2ndPath, variant2nd)
642
643	snapshotConfigsPath := filepath.Join(snapshotVariantPath, "configs")
644	checkSnapshot(t, ctx, snapshotSingleton, "llndk.libraries.txt", "llndk.libraries.txt", snapshotConfigsPath, "")
645	checkSnapshot(t, ctx, snapshotSingleton, "vndkcore.libraries.txt", "vndkcore.libraries.txt", snapshotConfigsPath, "")
646	checkSnapshot(t, ctx, snapshotSingleton, "vndksp.libraries.txt", "vndksp.libraries.txt", snapshotConfigsPath, "")
647	checkSnapshot(t, ctx, snapshotSingleton, "vndkprivate.libraries.txt", "vndkprivate.libraries.txt", snapshotConfigsPath, "")
648	checkSnapshot(t, ctx, snapshotSingleton, "vndkproduct.libraries.txt", "vndkproduct.libraries.txt", snapshotConfigsPath, "")
649
650	checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{
651		"LLNDK: libc.so",
652		"LLNDK: libdl.so",
653		"LLNDK: libft2.so",
654		"LLNDK: libllndk.so",
655		"LLNDK: libm.so",
656		"VNDK-SP: libc++.so",
657		"VNDK-SP: libvndk_sp-x.so",
658		"VNDK-SP: libvndk_sp_private-x.so",
659		"VNDK-SP: libvndk_sp_product_private-x.so",
660		"VNDK-core: libvndk-private.so",
661		"VNDK-core: libvndk.so",
662		"VNDK-core: libvndk_product.so",
663		"VNDK-private: libft2.so",
664		"VNDK-private: libvndk-private.so",
665		"VNDK-private: libvndk_sp_private-x.so",
666		"VNDK-private: libvndk_sp_product_private-x.so",
667		"VNDK-product: libc++.so",
668		"VNDK-product: libvndk_product.so",
669		"VNDK-product: libvndk_sp_product_private-x.so",
670	})
671	checkVndkLibrariesOutput(t, ctx, "llndk.libraries.txt", []string{"libc.so", "libclang_rt.hwasan-llndk.so", "libdl.so", "libft2.so", "libllndk.so", "libm.so"})
672	checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt", []string{"libvndk-private.so", "libvndk.so", "libvndk_product.so"})
673	checkVndkLibrariesOutput(t, ctx, "vndksp.libraries.txt", []string{"libc++.so", "libvndk_sp-x.so", "libvndk_sp_private-x.so", "libvndk_sp_product_private-x.so"})
674	checkVndkLibrariesOutput(t, ctx, "vndkprivate.libraries.txt", []string{"libft2.so", "libvndk-private.so", "libvndk_sp_private-x.so", "libvndk_sp_product_private-x.so"})
675	checkVndkLibrariesOutput(t, ctx, "vndkproduct.libraries.txt", []string{"libc++.so", "libvndk_product.so", "libvndk_sp_product_private-x.so"})
676	checkVndkLibrariesOutput(t, ctx, "vndkcorevariant.libraries.txt", nil)
677}
678
679func TestVndkWithHostSupported(t *testing.T) {
680	ctx := testCc(t, `
681		cc_library {
682			name: "libvndk_host_supported",
683			vendor_available: true,
684			product_available: true,
685			vndk: {
686				enabled: true,
687			},
688			host_supported: true,
689		}
690
691		cc_library {
692			name: "libvndk_host_supported_but_disabled_on_device",
693			vendor_available: true,
694			product_available: true,
695			vndk: {
696				enabled: true,
697			},
698			host_supported: true,
699			enabled: false,
700			target: {
701				host: {
702					enabled: true,
703				}
704			}
705		}
706
707		vndkcore_libraries_txt {
708			name: "vndkcore.libraries.txt",
709		}
710	`)
711
712	checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt", []string{"libvndk_host_supported.so"})
713}
714
715func TestVndkLibrariesTxtAndroidMk(t *testing.T) {
716	bp := `
717		llndk_libraries_txt {
718			name: "llndk.libraries.txt",
719			insert_vndk_version: true,
720		}`
721	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
722	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
723	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
724	ctx := testCcWithConfig(t, config)
725
726	module := ctx.ModuleForTests("llndk.libraries.txt", "")
727	entries := android.AndroidMkEntriesForTest(t, ctx, module.Module())[0]
728	assertArrayString(t, entries.EntryMap["LOCAL_MODULE_STEM"], []string{"llndk.libraries.29.txt"})
729}
730
731func TestVndkUsingCoreVariant(t *testing.T) {
732	bp := `
733		cc_library {
734			name: "libvndk",
735			vendor_available: true,
736			product_available: true,
737			vndk: {
738				enabled: true,
739			},
740			nocrt: true,
741		}
742
743		cc_library {
744			name: "libvndk_sp",
745			vendor_available: true,
746			product_available: true,
747			vndk: {
748				enabled: true,
749				support_system_process: true,
750			},
751			nocrt: true,
752		}
753
754		cc_library {
755			name: "libvndk2",
756			vendor_available: true,
757			product_available: true,
758			vndk: {
759				enabled: true,
760				private: true,
761			},
762			nocrt: true,
763		}
764
765		vndkcorevariant_libraries_txt {
766			name: "vndkcorevariant.libraries.txt",
767			insert_vndk_version: false,
768		}
769	`
770
771	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
772	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
773	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
774	config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
775
776	setVndkMustUseVendorVariantListForTest(config, []string{"libvndk"})
777
778	ctx := testCcWithConfig(t, config)
779
780	checkVndkLibrariesOutput(t, ctx, "vndkcorevariant.libraries.txt", []string{"libc++.so", "libvndk2.so", "libvndk_sp.so"})
781}
782
783func TestDataLibs(t *testing.T) {
784	bp := `
785		cc_test_library {
786			name: "test_lib",
787			srcs: ["test_lib.cpp"],
788			gtest: false,
789		}
790
791		cc_test {
792			name: "main_test",
793			data_libs: ["test_lib"],
794			gtest: false,
795		}
796 `
797
798	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
799	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
800	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
801	config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
802
803	ctx := testCcWithConfig(t, config)
804	module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
805	testBinary := module.(*Module).linker.(*testBinary)
806	outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
807	if err != nil {
808		t.Errorf("Expected cc_test to produce output files, error: %s", err)
809		return
810	}
811	if len(outputFiles) != 1 {
812		t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
813		return
814	}
815	if len(testBinary.dataPaths()) != 1 {
816		t.Errorf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths())
817		return
818	}
819
820	outputPath := outputFiles[0].String()
821	testBinaryPath := testBinary.dataPaths()[0].SrcPath.String()
822
823	if !strings.HasSuffix(outputPath, "/main_test") {
824		t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
825		return
826	}
827	if !strings.HasSuffix(testBinaryPath, "/test_lib.so") {
828		t.Errorf("expected test data file to be 'test_lib.so', but was '%s'", testBinaryPath)
829		return
830	}
831}
832
833func TestDataLibsRelativeInstallPath(t *testing.T) {
834	bp := `
835		cc_test_library {
836			name: "test_lib",
837			srcs: ["test_lib.cpp"],
838			relative_install_path: "foo/bar/baz",
839			gtest: false,
840		}
841
842		cc_test {
843			name: "main_test",
844			data_libs: ["test_lib"],
845			gtest: false,
846		}
847 `
848
849	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
850	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
851	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
852	config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
853
854	ctx := testCcWithConfig(t, config)
855	module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
856	testBinary := module.(*Module).linker.(*testBinary)
857	outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
858	if err != nil {
859		t.Fatalf("Expected cc_test to produce output files, error: %s", err)
860	}
861	if len(outputFiles) != 1 {
862		t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
863	}
864	if len(testBinary.dataPaths()) != 1 {
865		t.Errorf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths())
866	}
867
868	outputPath := outputFiles[0].String()
869
870	if !strings.HasSuffix(outputPath, "/main_test") {
871		t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
872	}
873	entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
874	if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
875		t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
876			" but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
877	}
878}
879
880func TestVndkWhenVndkVersionIsNotSet(t *testing.T) {
881	ctx := testCcNoVndk(t, `
882		cc_library {
883			name: "libvndk",
884			vendor_available: true,
885			product_available: true,
886			vndk: {
887				enabled: true,
888			},
889			nocrt: true,
890		}
891		cc_library {
892			name: "libvndk-private",
893			vendor_available: true,
894			product_available: true,
895			vndk: {
896				enabled: true,
897				private: true,
898			},
899			nocrt: true,
900		}
901
902		cc_library {
903			name: "libllndk",
904			llndk: {
905				symbol_file: "libllndk.map.txt",
906				export_llndk_headers: ["libllndk_headers"],
907			}
908		}
909
910		cc_library_headers {
911			name: "libllndk_headers",
912			llndk: {
913				symbol_file: "libllndk.map.txt",
914			},
915			export_include_dirs: ["include"],
916		}
917	`)
918
919	checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{
920		"LLNDK: libc.so",
921		"LLNDK: libdl.so",
922		"LLNDK: libft2.so",
923		"LLNDK: libllndk.so",
924		"LLNDK: libm.so",
925		"VNDK-SP: libc++.so",
926		"VNDK-core: libvndk-private.so",
927		"VNDK-core: libvndk.so",
928		"VNDK-private: libft2.so",
929		"VNDK-private: libvndk-private.so",
930		"VNDK-product: libc++.so",
931		"VNDK-product: libvndk-private.so",
932		"VNDK-product: libvndk.so",
933	})
934}
935
936func TestVndkModuleError(t *testing.T) {
937	// Check the error message for vendor_available and product_available properties.
938	testCcErrorProductVndk(t, "vndk: vendor_available must be set to true when `vndk: {enabled: true}`", `
939		cc_library {
940			name: "libvndk",
941			vndk: {
942				enabled: true,
943			},
944			nocrt: true,
945		}
946	`)
947
948	testCcErrorProductVndk(t, "vndk: vendor_available must be set to true when `vndk: {enabled: true}`", `
949		cc_library {
950			name: "libvndk",
951			product_available: true,
952			vndk: {
953				enabled: true,
954			},
955			nocrt: true,
956		}
957	`)
958
959	testCcErrorProductVndk(t, "product properties must have the same values with the vendor properties for VNDK modules", `
960		cc_library {
961			name: "libvndkprop",
962			vendor_available: true,
963			product_available: true,
964			vndk: {
965				enabled: true,
966			},
967			nocrt: true,
968			target: {
969				vendor: {
970					cflags: ["-DTEST",],
971				},
972			},
973		}
974	`)
975}
976
977func TestVndkDepError(t *testing.T) {
978	// Check whether an error is emitted when a VNDK lib depends on a system lib.
979	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
980		cc_library {
981			name: "libvndk",
982			vendor_available: true,
983			product_available: true,
984			vndk: {
985				enabled: true,
986			},
987			shared_libs: ["libfwk"],  // Cause error
988			nocrt: true,
989		}
990
991		cc_library {
992			name: "libfwk",
993			nocrt: true,
994		}
995	`)
996
997	// Check whether an error is emitted when a VNDK lib depends on a vendor lib.
998	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
999		cc_library {
1000			name: "libvndk",
1001			vendor_available: true,
1002			product_available: true,
1003			vndk: {
1004				enabled: true,
1005			},
1006			shared_libs: ["libvendor"],  // Cause error
1007			nocrt: true,
1008		}
1009
1010		cc_library {
1011			name: "libvendor",
1012			vendor: true,
1013			nocrt: true,
1014		}
1015	`)
1016
1017	// Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
1018	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1019		cc_library {
1020			name: "libvndk_sp",
1021			vendor_available: true,
1022			product_available: true,
1023			vndk: {
1024				enabled: true,
1025				support_system_process: true,
1026			},
1027			shared_libs: ["libfwk"],  // Cause error
1028			nocrt: true,
1029		}
1030
1031		cc_library {
1032			name: "libfwk",
1033			nocrt: true,
1034		}
1035	`)
1036
1037	// Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
1038	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1039		cc_library {
1040			name: "libvndk_sp",
1041			vendor_available: true,
1042			product_available: true,
1043			vndk: {
1044				enabled: true,
1045				support_system_process: true,
1046			},
1047			shared_libs: ["libvendor"],  // Cause error
1048			nocrt: true,
1049		}
1050
1051		cc_library {
1052			name: "libvendor",
1053			vendor: true,
1054			nocrt: true,
1055		}
1056	`)
1057
1058	// Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
1059	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1060		cc_library {
1061			name: "libvndk_sp",
1062			vendor_available: true,
1063			product_available: true,
1064			vndk: {
1065				enabled: true,
1066				support_system_process: true,
1067			},
1068			shared_libs: ["libvndk"],  // Cause error
1069			nocrt: true,
1070		}
1071
1072		cc_library {
1073			name: "libvndk",
1074			vendor_available: true,
1075			product_available: true,
1076			vndk: {
1077				enabled: true,
1078			},
1079			nocrt: true,
1080		}
1081	`)
1082
1083	// Check whether an error is emitted when a VNDK lib depends on a non-VNDK lib.
1084	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1085		cc_library {
1086			name: "libvndk",
1087			vendor_available: true,
1088			product_available: true,
1089			vndk: {
1090				enabled: true,
1091			},
1092			shared_libs: ["libnonvndk"],
1093			nocrt: true,
1094		}
1095
1096		cc_library {
1097			name: "libnonvndk",
1098			vendor_available: true,
1099			nocrt: true,
1100		}
1101	`)
1102
1103	// Check whether an error is emitted when a VNDK-private lib depends on a non-VNDK lib.
1104	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1105		cc_library {
1106			name: "libvndkprivate",
1107			vendor_available: true,
1108			product_available: true,
1109			vndk: {
1110				enabled: true,
1111				private: true,
1112			},
1113			shared_libs: ["libnonvndk"],
1114			nocrt: true,
1115		}
1116
1117		cc_library {
1118			name: "libnonvndk",
1119			vendor_available: true,
1120			nocrt: true,
1121		}
1122	`)
1123
1124	// Check whether an error is emitted when a VNDK-sp lib depends on a non-VNDK lib.
1125	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1126		cc_library {
1127			name: "libvndksp",
1128			vendor_available: true,
1129			product_available: true,
1130			vndk: {
1131				enabled: true,
1132				support_system_process: true,
1133			},
1134			shared_libs: ["libnonvndk"],
1135			nocrt: true,
1136		}
1137
1138		cc_library {
1139			name: "libnonvndk",
1140			vendor_available: true,
1141			nocrt: true,
1142		}
1143	`)
1144
1145	// Check whether an error is emitted when a VNDK-sp-private lib depends on a non-VNDK lib.
1146	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1147		cc_library {
1148			name: "libvndkspprivate",
1149			vendor_available: true,
1150			product_available: true,
1151			vndk: {
1152				enabled: true,
1153				support_system_process: true,
1154				private: true,
1155			},
1156			shared_libs: ["libnonvndk"],
1157			nocrt: true,
1158		}
1159
1160		cc_library {
1161			name: "libnonvndk",
1162			vendor_available: true,
1163			nocrt: true,
1164		}
1165	`)
1166}
1167
1168func TestDoubleLoadbleDep(t *testing.T) {
1169	// okay to link : LLNDK -> double_loadable VNDK
1170	testCc(t, `
1171		cc_library {
1172			name: "libllndk",
1173			shared_libs: ["libdoubleloadable"],
1174			llndk: {
1175				symbol_file: "libllndk.map.txt",
1176			}
1177		}
1178
1179		cc_library {
1180			name: "libdoubleloadable",
1181			vendor_available: true,
1182			product_available: true,
1183			vndk: {
1184				enabled: true,
1185			},
1186			double_loadable: true,
1187		}
1188	`)
1189	// okay to link : LLNDK -> VNDK-SP
1190	testCc(t, `
1191		cc_library {
1192			name: "libllndk",
1193			shared_libs: ["libvndksp"],
1194			llndk: {
1195				symbol_file: "libllndk.map.txt",
1196			}
1197		}
1198
1199		cc_library {
1200			name: "libvndksp",
1201			vendor_available: true,
1202			product_available: true,
1203			vndk: {
1204				enabled: true,
1205				support_system_process: true,
1206			},
1207		}
1208	`)
1209	// okay to link : double_loadable -> double_loadable
1210	testCc(t, `
1211		cc_library {
1212			name: "libdoubleloadable1",
1213			shared_libs: ["libdoubleloadable2"],
1214			vendor_available: true,
1215			double_loadable: true,
1216		}
1217
1218		cc_library {
1219			name: "libdoubleloadable2",
1220			vendor_available: true,
1221			double_loadable: true,
1222		}
1223	`)
1224	// okay to link : double_loadable VNDK -> double_loadable VNDK private
1225	testCc(t, `
1226		cc_library {
1227			name: "libdoubleloadable",
1228			vendor_available: true,
1229			product_available: true,
1230			vndk: {
1231				enabled: true,
1232			},
1233			double_loadable: true,
1234			shared_libs: ["libnondoubleloadable"],
1235		}
1236
1237		cc_library {
1238			name: "libnondoubleloadable",
1239			vendor_available: true,
1240			product_available: true,
1241			vndk: {
1242				enabled: true,
1243				private: true,
1244			},
1245			double_loadable: true,
1246		}
1247	`)
1248	// okay to link : LLNDK -> core-only -> vendor_available & double_loadable
1249	testCc(t, `
1250		cc_library {
1251			name: "libllndk",
1252			shared_libs: ["libcoreonly"],
1253			llndk: {
1254				symbol_file: "libllndk.map.txt",
1255			}
1256		}
1257
1258		cc_library {
1259			name: "libcoreonly",
1260			shared_libs: ["libvendoravailable"],
1261		}
1262
1263		// indirect dependency of LLNDK
1264		cc_library {
1265			name: "libvendoravailable",
1266			vendor_available: true,
1267			double_loadable: true,
1268		}
1269	`)
1270}
1271
1272func TestDoubleLoadableDepError(t *testing.T) {
1273	// Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib.
1274	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
1275		cc_library {
1276			name: "libllndk",
1277			shared_libs: ["libnondoubleloadable"],
1278			llndk: {
1279				symbol_file: "libllndk.map.txt",
1280			}
1281		}
1282
1283		cc_library {
1284			name: "libnondoubleloadable",
1285			vendor_available: true,
1286			product_available: true,
1287			vndk: {
1288				enabled: true,
1289			},
1290		}
1291	`)
1292
1293	// Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib.
1294	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
1295		cc_library {
1296			name: "libllndk",
1297			no_libcrt: true,
1298			shared_libs: ["libnondoubleloadable"],
1299			llndk: {
1300				symbol_file: "libllndk.map.txt",
1301			}
1302		}
1303
1304		cc_library {
1305			name: "libnondoubleloadable",
1306			vendor_available: true,
1307		}
1308	`)
1309
1310	// Check whether an error is emitted when a LLNDK depends on a non-double_loadable indirectly.
1311	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
1312		cc_library {
1313			name: "libllndk",
1314			shared_libs: ["libcoreonly"],
1315			llndk: {
1316				symbol_file: "libllndk.map.txt",
1317			}
1318		}
1319
1320		cc_library {
1321			name: "libcoreonly",
1322			shared_libs: ["libvendoravailable"],
1323		}
1324
1325		// indirect dependency of LLNDK
1326		cc_library {
1327			name: "libvendoravailable",
1328			vendor_available: true,
1329		}
1330	`)
1331
1332	// The error is not from 'client' but from 'libllndk'
1333	testCcError(t, "module \"libllndk\".* links a library \"libnondoubleloadable\".*double_loadable", `
1334		cc_library {
1335			name: "client",
1336			vendor_available: true,
1337			double_loadable: true,
1338			shared_libs: ["libllndk"],
1339		}
1340		cc_library {
1341			name: "libllndk",
1342			shared_libs: ["libnondoubleloadable"],
1343			llndk: {
1344				symbol_file: "libllndk.map.txt",
1345			}
1346		}
1347		cc_library {
1348			name: "libnondoubleloadable",
1349			vendor_available: true,
1350		}
1351	`)
1352}
1353
1354func TestCheckVndkMembershipBeforeDoubleLoadable(t *testing.T) {
1355	testCcError(t, "module \"libvndksp\" variant .*: .*: VNDK-SP must only depend on VNDK-SP", `
1356		cc_library {
1357			name: "libvndksp",
1358			shared_libs: ["libanothervndksp"],
1359			vendor_available: true,
1360			product_available: true,
1361			vndk: {
1362				enabled: true,
1363				support_system_process: true,
1364			}
1365		}
1366
1367		cc_library {
1368			name: "libllndk",
1369			shared_libs: ["libanothervndksp"],
1370		}
1371
1372		cc_library {
1373			name: "libanothervndksp",
1374			vendor_available: true,
1375		}
1376	`)
1377}
1378
1379func TestVndkExt(t *testing.T) {
1380	// This test checks the VNDK-Ext properties.
1381	bp := `
1382		cc_library {
1383			name: "libvndk",
1384			vendor_available: true,
1385			product_available: true,
1386			vndk: {
1387				enabled: true,
1388			},
1389			nocrt: true,
1390		}
1391		cc_library {
1392			name: "libvndk2",
1393			vendor_available: true,
1394			product_available: true,
1395			vndk: {
1396				enabled: true,
1397			},
1398			target: {
1399				vendor: {
1400					suffix: "-suffix",
1401				},
1402				product: {
1403					suffix: "-suffix",
1404				},
1405			},
1406			nocrt: true,
1407		}
1408
1409		cc_library {
1410			name: "libvndk_ext",
1411			vendor: true,
1412			vndk: {
1413				enabled: true,
1414				extends: "libvndk",
1415			},
1416			nocrt: true,
1417		}
1418
1419		cc_library {
1420			name: "libvndk2_ext",
1421			vendor: true,
1422			vndk: {
1423				enabled: true,
1424				extends: "libvndk2",
1425			},
1426			nocrt: true,
1427		}
1428
1429		cc_library {
1430			name: "libvndk_ext_product",
1431			product_specific: true,
1432			vndk: {
1433				enabled: true,
1434				extends: "libvndk",
1435			},
1436			nocrt: true,
1437		}
1438
1439		cc_library {
1440			name: "libvndk2_ext_product",
1441			product_specific: true,
1442			vndk: {
1443				enabled: true,
1444				extends: "libvndk2",
1445			},
1446			nocrt: true,
1447		}
1448	`
1449	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
1450	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
1451	config.TestProductVariables.ProductVndkVersion = StringPtr("current")
1452	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
1453
1454	ctx := testCcWithConfig(t, config)
1455
1456	checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk", vendorVariant)
1457	checkVndkModule(t, ctx, "libvndk_ext_product", "vndk", false, "libvndk", productVariant)
1458
1459	mod_vendor := ctx.ModuleForTests("libvndk2_ext", vendorVariant).Module().(*Module)
1460	assertString(t, mod_vendor.outputFile.Path().Base(), "libvndk2-suffix.so")
1461
1462	mod_product := ctx.ModuleForTests("libvndk2_ext_product", productVariant).Module().(*Module)
1463	assertString(t, mod_product.outputFile.Path().Base(), "libvndk2-suffix.so")
1464}
1465
1466func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
1467	// This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
1468	ctx := testCcNoVndk(t, `
1469		cc_library {
1470			name: "libvndk",
1471			vendor_available: true,
1472			product_available: true,
1473			vndk: {
1474				enabled: true,
1475			},
1476			nocrt: true,
1477		}
1478
1479		cc_library {
1480			name: "libvndk_ext",
1481			vendor: true,
1482			vndk: {
1483				enabled: true,
1484				extends: "libvndk",
1485			},
1486			nocrt: true,
1487		}
1488	`)
1489
1490	// Ensures that the core variant of "libvndk_ext" can be found.
1491	mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
1492	if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
1493		t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
1494	}
1495}
1496
1497func TestVndkExtWithoutProductVndkVersion(t *testing.T) {
1498	// This test checks the VNDK-Ext properties when PRODUCT_PRODUCT_VNDK_VERSION is not set.
1499	ctx := testCcNoProductVndk(t, `
1500		cc_library {
1501			name: "libvndk",
1502			vendor_available: true,
1503			product_available: true,
1504			vndk: {
1505				enabled: true,
1506			},
1507			nocrt: true,
1508		}
1509
1510		cc_library {
1511			name: "libvndk_ext_product",
1512			product_specific: true,
1513			vndk: {
1514				enabled: true,
1515				extends: "libvndk",
1516			},
1517			nocrt: true,
1518		}
1519	`)
1520
1521	// Ensures that the core variant of "libvndk_ext_product" can be found.
1522	mod := ctx.ModuleForTests("libvndk_ext_product", coreVariant).Module().(*Module)
1523	if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
1524		t.Errorf("\"libvndk_ext_product\" must extend from \"libvndk\" but get %q", extends)
1525	}
1526}
1527
1528func TestVndkExtError(t *testing.T) {
1529	// This test ensures an error is emitted in ill-formed vndk-ext definition.
1530	testCcError(t, "must set `vendor: true` or `product_specific: true` to set `extends: \".*\"`", `
1531		cc_library {
1532			name: "libvndk",
1533			vendor_available: true,
1534			product_available: true,
1535			vndk: {
1536				enabled: true,
1537			},
1538			nocrt: true,
1539		}
1540
1541		cc_library {
1542			name: "libvndk_ext",
1543			vndk: {
1544				enabled: true,
1545				extends: "libvndk",
1546			},
1547			nocrt: true,
1548		}
1549	`)
1550
1551	testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
1552		cc_library {
1553			name: "libvndk",
1554			vendor_available: true,
1555			product_available: true,
1556			vndk: {
1557				enabled: true,
1558			},
1559			nocrt: true,
1560		}
1561
1562		cc_library {
1563			name: "libvndk_ext",
1564			vendor: true,
1565			vndk: {
1566				enabled: true,
1567			},
1568			nocrt: true,
1569		}
1570	`)
1571
1572	testCcErrorProductVndk(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
1573		cc_library {
1574			name: "libvndk",
1575			vendor_available: true,
1576			product_available: true,
1577			vndk: {
1578				enabled: true,
1579			},
1580			nocrt: true,
1581		}
1582
1583		cc_library {
1584			name: "libvndk_ext_product",
1585			product_specific: true,
1586			vndk: {
1587				enabled: true,
1588			},
1589			nocrt: true,
1590		}
1591	`)
1592
1593	testCcErrorProductVndk(t, "must not set at the same time as `vndk: {extends: \"\\.\\.\\.\"}`", `
1594		cc_library {
1595			name: "libvndk",
1596			vendor_available: true,
1597			product_available: true,
1598			vndk: {
1599				enabled: true,
1600			},
1601			nocrt: true,
1602		}
1603
1604		cc_library {
1605			name: "libvndk_ext_product",
1606			product_specific: true,
1607			vendor_available: true,
1608			product_available: true,
1609			vndk: {
1610				enabled: true,
1611				extends: "libvndk",
1612			},
1613			nocrt: true,
1614		}
1615	`)
1616}
1617
1618func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
1619	// This test ensures an error is emitted for inconsistent support_system_process.
1620	testCcError(t, "module \".*\" with mismatched support_system_process", `
1621		cc_library {
1622			name: "libvndk",
1623			vendor_available: true,
1624			product_available: true,
1625			vndk: {
1626				enabled: true,
1627			},
1628			nocrt: true,
1629		}
1630
1631		cc_library {
1632			name: "libvndk_sp_ext",
1633			vendor: true,
1634			vndk: {
1635				enabled: true,
1636				extends: "libvndk",
1637				support_system_process: true,
1638			},
1639			nocrt: true,
1640		}
1641	`)
1642
1643	testCcError(t, "module \".*\" with mismatched support_system_process", `
1644		cc_library {
1645			name: "libvndk_sp",
1646			vendor_available: true,
1647			product_available: true,
1648			vndk: {
1649				enabled: true,
1650				support_system_process: true,
1651			},
1652			nocrt: true,
1653		}
1654
1655		cc_library {
1656			name: "libvndk_ext",
1657			vendor: true,
1658			vndk: {
1659				enabled: true,
1660				extends: "libvndk_sp",
1661			},
1662			nocrt: true,
1663		}
1664	`)
1665}
1666
1667func TestVndkExtVendorAvailableFalseError(t *testing.T) {
1668	// This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
1669	// with `private: true`.
1670	testCcError(t, "`extends` refers module \".*\" which has `private: true`", `
1671		cc_library {
1672			name: "libvndk",
1673			vendor_available: true,
1674			product_available: true,
1675			vndk: {
1676				enabled: true,
1677				private: true,
1678			},
1679			nocrt: true,
1680		}
1681
1682		cc_library {
1683			name: "libvndk_ext",
1684			vendor: true,
1685			vndk: {
1686				enabled: true,
1687				extends: "libvndk",
1688			},
1689			nocrt: true,
1690		}
1691	`)
1692
1693	testCcErrorProductVndk(t, "`extends` refers module \".*\" which has `private: true`", `
1694		cc_library {
1695			name: "libvndk",
1696			vendor_available: true,
1697			product_available: true,
1698			vndk: {
1699				enabled: true,
1700				private: true,
1701			},
1702			nocrt: true,
1703		}
1704
1705		cc_library {
1706			name: "libvndk_ext_product",
1707			product_specific: true,
1708			vndk: {
1709				enabled: true,
1710				extends: "libvndk",
1711			},
1712			nocrt: true,
1713		}
1714	`)
1715}
1716
1717func TestVendorModuleUseVndkExt(t *testing.T) {
1718	// This test ensures a vendor module can depend on a VNDK-Ext library.
1719	testCc(t, `
1720		cc_library {
1721			name: "libvndk",
1722			vendor_available: true,
1723			product_available: true,
1724			vndk: {
1725				enabled: true,
1726			},
1727			nocrt: true,
1728		}
1729
1730		cc_library {
1731			name: "libvndk_ext",
1732			vendor: true,
1733			vndk: {
1734				enabled: true,
1735				extends: "libvndk",
1736			},
1737			nocrt: true,
1738		}
1739
1740		cc_library {
1741			name: "libvndk_sp",
1742			vendor_available: true,
1743			product_available: true,
1744			vndk: {
1745				enabled: true,
1746				support_system_process: true,
1747			},
1748			nocrt: true,
1749		}
1750
1751		cc_library {
1752			name: "libvndk_sp_ext",
1753			vendor: true,
1754			vndk: {
1755				enabled: true,
1756				extends: "libvndk_sp",
1757				support_system_process: true,
1758			},
1759			nocrt: true,
1760		}
1761
1762		cc_library {
1763			name: "libvendor",
1764			vendor: true,
1765			shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
1766			nocrt: true,
1767		}
1768	`)
1769}
1770
1771func TestVndkExtUseVendorLib(t *testing.T) {
1772	// This test ensures a VNDK-Ext library can depend on a vendor library.
1773	testCc(t, `
1774		cc_library {
1775			name: "libvndk",
1776			vendor_available: true,
1777			product_available: true,
1778			vndk: {
1779				enabled: true,
1780			},
1781			nocrt: true,
1782		}
1783
1784		cc_library {
1785			name: "libvndk_ext",
1786			vendor: true,
1787			vndk: {
1788				enabled: true,
1789				extends: "libvndk",
1790			},
1791			shared_libs: ["libvendor"],
1792			nocrt: true,
1793		}
1794
1795		cc_library {
1796			name: "libvendor",
1797			vendor: true,
1798			nocrt: true,
1799		}
1800	`)
1801
1802	// This test ensures a VNDK-SP-Ext library can depend on a vendor library.
1803	testCc(t, `
1804		cc_library {
1805			name: "libvndk_sp",
1806			vendor_available: true,
1807			product_available: true,
1808			vndk: {
1809				enabled: true,
1810				support_system_process: true,
1811			},
1812			nocrt: true,
1813		}
1814
1815		cc_library {
1816			name: "libvndk_sp_ext",
1817			vendor: true,
1818			vndk: {
1819				enabled: true,
1820				extends: "libvndk_sp",
1821				support_system_process: true,
1822			},
1823			shared_libs: ["libvendor"],  // Cause an error
1824			nocrt: true,
1825		}
1826
1827		cc_library {
1828			name: "libvendor",
1829			vendor: true,
1830			nocrt: true,
1831		}
1832	`)
1833}
1834
1835func TestProductVndkExtDependency(t *testing.T) {
1836	bp := `
1837		cc_library {
1838			name: "libvndk",
1839			vendor_available: true,
1840			product_available: true,
1841			vndk: {
1842				enabled: true,
1843			},
1844			nocrt: true,
1845		}
1846
1847		cc_library {
1848			name: "libvndk_ext_product",
1849			product_specific: true,
1850			vndk: {
1851				enabled: true,
1852				extends: "libvndk",
1853			},
1854			shared_libs: ["libproduct_for_vndklibs"],
1855			nocrt: true,
1856		}
1857
1858		cc_library {
1859			name: "libvndk_sp",
1860			vendor_available: true,
1861			product_available: true,
1862			vndk: {
1863				enabled: true,
1864				support_system_process: true,
1865			},
1866			nocrt: true,
1867		}
1868
1869		cc_library {
1870			name: "libvndk_sp_ext_product",
1871			product_specific: true,
1872			vndk: {
1873				enabled: true,
1874				extends: "libvndk_sp",
1875				support_system_process: true,
1876			},
1877			shared_libs: ["libproduct_for_vndklibs"],
1878			nocrt: true,
1879		}
1880
1881		cc_library {
1882			name: "libproduct",
1883			product_specific: true,
1884			shared_libs: ["libvndk_ext_product", "libvndk_sp_ext_product"],
1885			nocrt: true,
1886		}
1887
1888		cc_library {
1889			name: "libproduct_for_vndklibs",
1890			product_specific: true,
1891			nocrt: true,
1892		}
1893	`
1894	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
1895	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
1896	config.TestProductVariables.ProductVndkVersion = StringPtr("current")
1897	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
1898
1899	testCcWithConfig(t, config)
1900}
1901
1902func TestVndkSpExtUseVndkError(t *testing.T) {
1903	// This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
1904	// library.
1905	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1906		cc_library {
1907			name: "libvndk",
1908			vendor_available: true,
1909			product_available: true,
1910			vndk: {
1911				enabled: true,
1912			},
1913			nocrt: true,
1914		}
1915
1916		cc_library {
1917			name: "libvndk_sp",
1918			vendor_available: true,
1919			product_available: true,
1920			vndk: {
1921				enabled: true,
1922				support_system_process: true,
1923			},
1924			nocrt: true,
1925		}
1926
1927		cc_library {
1928			name: "libvndk_sp_ext",
1929			vendor: true,
1930			vndk: {
1931				enabled: true,
1932				extends: "libvndk_sp",
1933				support_system_process: true,
1934			},
1935			shared_libs: ["libvndk"],  // Cause an error
1936			nocrt: true,
1937		}
1938	`)
1939
1940	// This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
1941	// library.
1942	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1943		cc_library {
1944			name: "libvndk",
1945			vendor_available: true,
1946			product_available: true,
1947			vndk: {
1948				enabled: true,
1949			},
1950			nocrt: true,
1951		}
1952
1953		cc_library {
1954			name: "libvndk_ext",
1955			vendor: true,
1956			vndk: {
1957				enabled: true,
1958				extends: "libvndk",
1959			},
1960			nocrt: true,
1961		}
1962
1963		cc_library {
1964			name: "libvndk_sp",
1965			vendor_available: true,
1966			product_available: true,
1967			vndk: {
1968				enabled: true,
1969				support_system_process: true,
1970			},
1971			nocrt: true,
1972		}
1973
1974		cc_library {
1975			name: "libvndk_sp_ext",
1976			vendor: true,
1977			vndk: {
1978				enabled: true,
1979				extends: "libvndk_sp",
1980				support_system_process: true,
1981			},
1982			shared_libs: ["libvndk_ext"],  // Cause an error
1983			nocrt: true,
1984		}
1985	`)
1986}
1987
1988func TestVndkUseVndkExtError(t *testing.T) {
1989	// This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
1990	// VNDK-Ext/VNDK-SP-Ext library.
1991	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1992		cc_library {
1993			name: "libvndk",
1994			vendor_available: true,
1995			product_available: true,
1996			vndk: {
1997				enabled: true,
1998			},
1999			nocrt: true,
2000		}
2001
2002		cc_library {
2003			name: "libvndk_ext",
2004			vendor: true,
2005			vndk: {
2006				enabled: true,
2007				extends: "libvndk",
2008			},
2009			nocrt: true,
2010		}
2011
2012		cc_library {
2013			name: "libvndk2",
2014			vendor_available: true,
2015			product_available: true,
2016			vndk: {
2017				enabled: true,
2018			},
2019			shared_libs: ["libvndk_ext"],
2020			nocrt: true,
2021		}
2022	`)
2023
2024	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
2025		cc_library {
2026			name: "libvndk",
2027			vendor_available: true,
2028			product_available: true,
2029			vndk: {
2030				enabled: true,
2031			},
2032			nocrt: true,
2033		}
2034
2035		cc_library {
2036			name: "libvndk_ext",
2037			vendor: true,
2038			vndk: {
2039				enabled: true,
2040				extends: "libvndk",
2041			},
2042			nocrt: true,
2043		}
2044
2045		cc_library {
2046			name: "libvndk2",
2047			vendor_available: true,
2048			vndk: {
2049				enabled: true,
2050			},
2051			target: {
2052				vendor: {
2053					shared_libs: ["libvndk_ext"],
2054				},
2055			},
2056			nocrt: true,
2057		}
2058	`)
2059
2060	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
2061		cc_library {
2062			name: "libvndk_sp",
2063			vendor_available: true,
2064			product_available: true,
2065			vndk: {
2066				enabled: true,
2067				support_system_process: true,
2068			},
2069			nocrt: true,
2070		}
2071
2072		cc_library {
2073			name: "libvndk_sp_ext",
2074			vendor: true,
2075			vndk: {
2076				enabled: true,
2077				extends: "libvndk_sp",
2078				support_system_process: true,
2079			},
2080			nocrt: true,
2081		}
2082
2083		cc_library {
2084			name: "libvndk_sp_2",
2085			vendor_available: true,
2086			product_available: true,
2087			vndk: {
2088				enabled: true,
2089				support_system_process: true,
2090			},
2091			shared_libs: ["libvndk_sp_ext"],
2092			nocrt: true,
2093		}
2094	`)
2095
2096	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
2097		cc_library {
2098			name: "libvndk_sp",
2099			vendor_available: true,
2100			product_available: true,
2101			vndk: {
2102				enabled: true,
2103			},
2104			nocrt: true,
2105		}
2106
2107		cc_library {
2108			name: "libvndk_sp_ext",
2109			vendor: true,
2110			vndk: {
2111				enabled: true,
2112				extends: "libvndk_sp",
2113			},
2114			nocrt: true,
2115		}
2116
2117		cc_library {
2118			name: "libvndk_sp2",
2119			vendor_available: true,
2120			vndk: {
2121				enabled: true,
2122			},
2123			target: {
2124				vendor: {
2125					shared_libs: ["libvndk_sp_ext"],
2126				},
2127			},
2128			nocrt: true,
2129		}
2130	`)
2131}
2132
2133func TestEnforceProductVndkVersion(t *testing.T) {
2134	bp := `
2135		cc_library {
2136			name: "libllndk",
2137			llndk: {
2138				symbol_file: "libllndk.map.txt",
2139			}
2140		}
2141		cc_library {
2142			name: "libvndk",
2143			vendor_available: true,
2144			product_available: true,
2145			vndk: {
2146				enabled: true,
2147			},
2148			nocrt: true,
2149		}
2150		cc_library {
2151			name: "libvndk_sp",
2152			vendor_available: true,
2153			product_available: true,
2154			vndk: {
2155				enabled: true,
2156				support_system_process: true,
2157			},
2158			nocrt: true,
2159		}
2160		cc_library {
2161			name: "libva",
2162			vendor_available: true,
2163			nocrt: true,
2164		}
2165		cc_library {
2166			name: "libpa",
2167			product_available: true,
2168			nocrt: true,
2169		}
2170		cc_library {
2171			name: "libboth_available",
2172			vendor_available: true,
2173			product_available: true,
2174			nocrt: true,
2175			srcs: ["foo.c"],
2176			target: {
2177				vendor: {
2178					suffix: "-vendor",
2179				},
2180				product: {
2181					suffix: "-product",
2182				},
2183			}
2184		}
2185		cc_library {
2186			name: "libproduct_va",
2187			product_specific: true,
2188			vendor_available: true,
2189			nocrt: true,
2190		}
2191		cc_library {
2192			name: "libprod",
2193			product_specific: true,
2194			shared_libs: [
2195				"libllndk",
2196				"libvndk",
2197				"libvndk_sp",
2198				"libpa",
2199				"libboth_available",
2200				"libproduct_va",
2201			],
2202			nocrt: true,
2203		}
2204		cc_library {
2205			name: "libvendor",
2206			vendor: true,
2207			shared_libs: [
2208				"libllndk",
2209				"libvndk",
2210				"libvndk_sp",
2211				"libva",
2212				"libboth_available",
2213				"libproduct_va",
2214			],
2215			nocrt: true,
2216		}
2217	`
2218
2219	ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
2220
2221	checkVndkModule(t, ctx, "libvndk", "", false, "", productVariant)
2222	checkVndkModule(t, ctx, "libvndk_sp", "", true, "", productVariant)
2223
2224	mod_vendor := ctx.ModuleForTests("libboth_available", vendorVariant).Module().(*Module)
2225	assertString(t, mod_vendor.outputFile.Path().Base(), "libboth_available-vendor.so")
2226
2227	mod_product := ctx.ModuleForTests("libboth_available", productVariant).Module().(*Module)
2228	assertString(t, mod_product.outputFile.Path().Base(), "libboth_available-product.so")
2229
2230	ensureStringContains := func(t *testing.T, str string, substr string) {
2231		t.Helper()
2232		if !strings.Contains(str, substr) {
2233			t.Errorf("%q is not found in %v", substr, str)
2234		}
2235	}
2236	ensureStringNotContains := func(t *testing.T, str string, substr string) {
2237		t.Helper()
2238		if strings.Contains(str, substr) {
2239			t.Errorf("%q is found in %v", substr, str)
2240		}
2241	}
2242
2243	// _static variant is used since _shared reuses *.o from the static variant
2244	vendor_static := ctx.ModuleForTests("libboth_available", strings.Replace(vendorVariant, "_shared", "_static", 1))
2245	product_static := ctx.ModuleForTests("libboth_available", strings.Replace(productVariant, "_shared", "_static", 1))
2246
2247	vendor_cflags := vendor_static.Rule("cc").Args["cFlags"]
2248	ensureStringContains(t, vendor_cflags, "-D__ANDROID_VNDK__")
2249	ensureStringContains(t, vendor_cflags, "-D__ANDROID_VENDOR__")
2250	ensureStringNotContains(t, vendor_cflags, "-D__ANDROID_PRODUCT__")
2251
2252	product_cflags := product_static.Rule("cc").Args["cFlags"]
2253	ensureStringContains(t, product_cflags, "-D__ANDROID_VNDK__")
2254	ensureStringContains(t, product_cflags, "-D__ANDROID_PRODUCT__")
2255	ensureStringNotContains(t, product_cflags, "-D__ANDROID_VENDOR__")
2256}
2257
2258func TestEnforceProductVndkVersionErrors(t *testing.T) {
2259	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.29", `
2260		cc_library {
2261			name: "libprod",
2262			product_specific: true,
2263			shared_libs: [
2264				"libvendor",
2265			],
2266			nocrt: true,
2267		}
2268		cc_library {
2269			name: "libvendor",
2270			vendor: true,
2271			nocrt: true,
2272		}
2273	`)
2274	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.29", `
2275		cc_library {
2276			name: "libprod",
2277			product_specific: true,
2278			shared_libs: [
2279				"libsystem",
2280			],
2281			nocrt: true,
2282		}
2283		cc_library {
2284			name: "libsystem",
2285			nocrt: true,
2286		}
2287	`)
2288	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.29", `
2289		cc_library {
2290			name: "libprod",
2291			product_specific: true,
2292			shared_libs: [
2293				"libva",
2294			],
2295			nocrt: true,
2296		}
2297		cc_library {
2298			name: "libva",
2299			vendor_available: true,
2300			nocrt: true,
2301		}
2302	`)
2303	testCcErrorProductVndk(t, "non-VNDK module should not link to \".*\" which has `private: true`", `
2304		cc_library {
2305			name: "libprod",
2306			product_specific: true,
2307			shared_libs: [
2308				"libvndk_private",
2309			],
2310			nocrt: true,
2311		}
2312		cc_library {
2313			name: "libvndk_private",
2314			vendor_available: true,
2315			product_available: true,
2316			vndk: {
2317				enabled: true,
2318				private: true,
2319			},
2320			nocrt: true,
2321		}
2322	`)
2323	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.29", `
2324		cc_library {
2325			name: "libprod",
2326			product_specific: true,
2327			shared_libs: [
2328				"libsystem_ext",
2329			],
2330			nocrt: true,
2331		}
2332		cc_library {
2333			name: "libsystem_ext",
2334			system_ext_specific: true,
2335			nocrt: true,
2336		}
2337	`)
2338	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:", `
2339		cc_library {
2340			name: "libsystem",
2341			shared_libs: [
2342				"libproduct_va",
2343			],
2344			nocrt: true,
2345		}
2346		cc_library {
2347			name: "libproduct_va",
2348			product_specific: true,
2349			vendor_available: true,
2350			nocrt: true,
2351		}
2352	`)
2353}
2354
2355func TestMakeLinkType(t *testing.T) {
2356	bp := `
2357		cc_library {
2358			name: "libvndk",
2359			vendor_available: true,
2360			product_available: true,
2361			vndk: {
2362				enabled: true,
2363			},
2364		}
2365		cc_library {
2366			name: "libvndksp",
2367			vendor_available: true,
2368			product_available: true,
2369			vndk: {
2370				enabled: true,
2371				support_system_process: true,
2372			},
2373		}
2374		cc_library {
2375			name: "libvndkprivate",
2376			vendor_available: true,
2377			product_available: true,
2378			vndk: {
2379				enabled: true,
2380				private: true,
2381			},
2382		}
2383		cc_library {
2384			name: "libvendor",
2385			vendor: true,
2386		}
2387		cc_library {
2388			name: "libvndkext",
2389			vendor: true,
2390			vndk: {
2391				enabled: true,
2392				extends: "libvndk",
2393			},
2394		}
2395		vndk_prebuilt_shared {
2396			name: "prevndk",
2397			version: "27",
2398			target_arch: "arm",
2399			binder32bit: true,
2400			vendor_available: true,
2401			product_available: true,
2402			vndk: {
2403				enabled: true,
2404			},
2405			arch: {
2406				arm: {
2407					srcs: ["liba.so"],
2408				},
2409			},
2410		}
2411		cc_library {
2412			name: "libllndk",
2413			llndk: {
2414				symbol_file: "libllndk.map.txt",
2415			}
2416		}
2417		cc_library {
2418			name: "libllndkprivate",
2419			llndk: {
2420				symbol_file: "libllndkprivate.map.txt",
2421				private: true,
2422			}
2423		}
2424
2425		llndk_libraries_txt {
2426			name: "llndk.libraries.txt",
2427		}
2428		vndkcore_libraries_txt {
2429			name: "vndkcore.libraries.txt",
2430		}
2431		vndksp_libraries_txt {
2432			name: "vndksp.libraries.txt",
2433		}
2434		vndkprivate_libraries_txt {
2435			name: "vndkprivate.libraries.txt",
2436		}
2437		vndkcorevariant_libraries_txt {
2438			name: "vndkcorevariant.libraries.txt",
2439			insert_vndk_version: false,
2440		}
2441	`
2442
2443	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
2444	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
2445	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
2446	// native:vndk
2447	ctx := testCcWithConfig(t, config)
2448
2449	checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt",
2450		[]string{"libvndk.so", "libvndkprivate.so"})
2451	checkVndkLibrariesOutput(t, ctx, "vndksp.libraries.txt",
2452		[]string{"libc++.so", "libvndksp.so"})
2453	checkVndkLibrariesOutput(t, ctx, "llndk.libraries.txt",
2454		[]string{"libc.so", "libdl.so", "libft2.so", "libllndk.so", "libllndkprivate.so", "libm.so"})
2455	checkVndkLibrariesOutput(t, ctx, "vndkprivate.libraries.txt",
2456		[]string{"libft2.so", "libllndkprivate.so", "libvndkprivate.so"})
2457
2458	vendorVariant27 := "android_vendor.27_arm64_armv8-a_shared"
2459
2460	tests := []struct {
2461		variant  string
2462		name     string
2463		expected string
2464	}{
2465		{vendorVariant, "libvndk", "native:vndk"},
2466		{vendorVariant, "libvndksp", "native:vndk"},
2467		{vendorVariant, "libvndkprivate", "native:vndk_private"},
2468		{vendorVariant, "libvendor", "native:vendor"},
2469		{vendorVariant, "libvndkext", "native:vendor"},
2470		{vendorVariant, "libllndk", "native:vndk"},
2471		{vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vndk"},
2472		{coreVariant, "libvndk", "native:platform"},
2473		{coreVariant, "libvndkprivate", "native:platform"},
2474		{coreVariant, "libllndk", "native:platform"},
2475	}
2476	for _, test := range tests {
2477		t.Run(test.name, func(t *testing.T) {
2478			module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module)
2479			assertString(t, module.makeLinkType, test.expected)
2480		})
2481	}
2482}
2483
2484var staticLinkDepOrderTestCases = []struct {
2485	// This is a string representation of a map[moduleName][]moduleDependency .
2486	// It models the dependencies declared in an Android.bp file.
2487	inStatic string
2488
2489	// This is a string representation of a map[moduleName][]moduleDependency .
2490	// It models the dependencies declared in an Android.bp file.
2491	inShared string
2492
2493	// allOrdered is a string representation of a map[moduleName][]moduleDependency .
2494	// The keys of allOrdered specify which modules we would like to check.
2495	// The values of allOrdered specify the expected result (of the transitive closure of all
2496	// dependencies) for each module to test
2497	allOrdered string
2498
2499	// outOrdered is a string representation of a map[moduleName][]moduleDependency .
2500	// The keys of outOrdered specify which modules we would like to check.
2501	// The values of outOrdered specify the expected result (of the ordered linker command line)
2502	// for each module to test.
2503	outOrdered string
2504}{
2505	// Simple tests
2506	{
2507		inStatic:   "",
2508		outOrdered: "",
2509	},
2510	{
2511		inStatic:   "a:",
2512		outOrdered: "a:",
2513	},
2514	{
2515		inStatic:   "a:b; b:",
2516		outOrdered: "a:b; b:",
2517	},
2518	// Tests of reordering
2519	{
2520		// diamond example
2521		inStatic:   "a:d,b,c; b:d; c:d; d:",
2522		outOrdered: "a:b,c,d; b:d; c:d; d:",
2523	},
2524	{
2525		// somewhat real example
2526		inStatic:   "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
2527		outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
2528	},
2529	{
2530		// multiple reorderings
2531		inStatic:   "a:b,c,d,e; d:b; e:c",
2532		outOrdered: "a:d,b,e,c; d:b; e:c",
2533	},
2534	{
2535		// should reorder without adding new transitive dependencies
2536		inStatic:   "bin:lib2,lib1;             lib1:lib2,liboptional",
2537		allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
2538		outOrdered: "bin:lib1,lib2;             lib1:lib2,liboptional",
2539	},
2540	{
2541		// multiple levels of dependencies
2542		inStatic:   "a:b,c,d,e,f,g,h; f:b,c,d; b:c,d; c:d",
2543		allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
2544		outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
2545	},
2546	// shared dependencies
2547	{
2548		// Note that this test doesn't recurse, to minimize the amount of logic it tests.
2549		// So, we don't actually have to check that a shared dependency of c will change the order
2550		// of a library that depends statically on b and on c.  We only need to check that if c has
2551		// a shared dependency on b, that that shows up in allOrdered.
2552		inShared:   "c:b",
2553		allOrdered: "c:b",
2554		outOrdered: "c:",
2555	},
2556	{
2557		// This test doesn't actually include any shared dependencies but it's a reminder of what
2558		// the second phase of the above test would look like
2559		inStatic:   "a:b,c; c:b",
2560		allOrdered: "a:c,b; c:b",
2561		outOrdered: "a:c,b; c:b",
2562	},
2563	// tiebreakers for when two modules specifying different orderings and there is no dependency
2564	// to dictate an order
2565	{
2566		// if the tie is between two modules at the end of a's deps, then a's order wins
2567		inStatic:   "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
2568		outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
2569	},
2570	{
2571		// if the tie is between two modules at the start of a's deps, then c's order is used
2572		inStatic:   "a1:d,e,b1,c1; b1:d,e; c1:e,d;   a2:d,e,b2,c2; b2:d,e; c2:d,e",
2573		outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d;   a2:b2,c2,d,e; b2:d,e; c2:d,e",
2574	},
2575	// Tests involving duplicate dependencies
2576	{
2577		// simple duplicate
2578		inStatic:   "a:b,c,c,b",
2579		outOrdered: "a:c,b",
2580	},
2581	{
2582		// duplicates with reordering
2583		inStatic:   "a:b,c,d,c; c:b",
2584		outOrdered: "a:d,c,b",
2585	},
2586	// Tests to confirm the nonexistence of infinite loops.
2587	// These cases should never happen, so as long as the test terminates and the
2588	// result is deterministic then that should be fine.
2589	{
2590		inStatic:   "a:a",
2591		outOrdered: "a:a",
2592	},
2593	{
2594		inStatic:   "a:b;   b:c;   c:a",
2595		allOrdered: "a:b,c; b:c,a; c:a,b",
2596		outOrdered: "a:b;   b:c;   c:a",
2597	},
2598	{
2599		inStatic:   "a:b,c;   b:c,a;   c:a,b",
2600		allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
2601		outOrdered: "a:c,b;   b:a,c;   c:b,a",
2602	},
2603}
2604
2605// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
2606func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
2607	// convert from "a:b,c; d:e" to "a:b,c;d:e"
2608	strippedText := strings.Replace(text, " ", "", -1)
2609	if len(strippedText) < 1 {
2610		return []android.Path{}, make(map[android.Path][]android.Path, 0)
2611	}
2612	allDeps = make(map[android.Path][]android.Path, 0)
2613
2614	// convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
2615	moduleTexts := strings.Split(strippedText, ";")
2616
2617	outputForModuleName := func(moduleName string) android.Path {
2618		return android.PathForTesting(moduleName)
2619	}
2620
2621	for _, moduleText := range moduleTexts {
2622		// convert from "a:b,c" to ["a", "b,c"]
2623		components := strings.Split(moduleText, ":")
2624		if len(components) != 2 {
2625			panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
2626		}
2627		moduleName := components[0]
2628		moduleOutput := outputForModuleName(moduleName)
2629		modulesInOrder = append(modulesInOrder, moduleOutput)
2630
2631		depString := components[1]
2632		// convert from "b,c" to ["b", "c"]
2633		depNames := strings.Split(depString, ",")
2634		if len(depString) < 1 {
2635			depNames = []string{}
2636		}
2637		var deps []android.Path
2638		for _, depName := range depNames {
2639			deps = append(deps, outputForModuleName(depName))
2640		}
2641		allDeps[moduleOutput] = deps
2642	}
2643	return modulesInOrder, allDeps
2644}
2645
2646func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
2647	for _, moduleName := range moduleNames {
2648		module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
2649		output := module.outputFile.Path().RelativeToTop()
2650		paths = append(paths, output)
2651	}
2652	return paths
2653}
2654
2655func TestStaticLibDepReordering(t *testing.T) {
2656	ctx := testCc(t, `
2657	cc_library {
2658		name: "a",
2659		static_libs: ["b", "c", "d"],
2660		stl: "none",
2661	}
2662	cc_library {
2663		name: "b",
2664		stl: "none",
2665	}
2666	cc_library {
2667		name: "c",
2668		static_libs: ["b"],
2669		stl: "none",
2670	}
2671	cc_library {
2672		name: "d",
2673		stl: "none",
2674	}
2675
2676	`)
2677
2678	variant := "android_arm64_armv8-a_static"
2679	moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
2680	actual := ctx.ModuleProvider(moduleA, StaticLibraryInfoProvider).(StaticLibraryInfo).
2681		TransitiveStaticLibrariesForOrdering.ToList().RelativeToTop()
2682	expected := getOutputPaths(ctx, variant, []string{"a", "c", "b", "d"})
2683
2684	if !reflect.DeepEqual(actual, expected) {
2685		t.Errorf("staticDeps orderings were not propagated correctly"+
2686			"\nactual:   %v"+
2687			"\nexpected: %v",
2688			actual,
2689			expected,
2690		)
2691	}
2692}
2693
2694func TestStaticLibDepReorderingWithShared(t *testing.T) {
2695	ctx := testCc(t, `
2696	cc_library {
2697		name: "a",
2698		static_libs: ["b", "c"],
2699		stl: "none",
2700	}
2701	cc_library {
2702		name: "b",
2703		stl: "none",
2704	}
2705	cc_library {
2706		name: "c",
2707		shared_libs: ["b"],
2708		stl: "none",
2709	}
2710
2711	`)
2712
2713	variant := "android_arm64_armv8-a_static"
2714	moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
2715	actual := ctx.ModuleProvider(moduleA, StaticLibraryInfoProvider).(StaticLibraryInfo).
2716		TransitiveStaticLibrariesForOrdering.ToList().RelativeToTop()
2717	expected := getOutputPaths(ctx, variant, []string{"a", "c", "b"})
2718
2719	if !reflect.DeepEqual(actual, expected) {
2720		t.Errorf("staticDeps orderings did not account for shared libs"+
2721			"\nactual:   %v"+
2722			"\nexpected: %v",
2723			actual,
2724			expected,
2725		)
2726	}
2727}
2728
2729func checkEquals(t *testing.T, message string, expected, actual interface{}) {
2730	t.Helper()
2731	if !reflect.DeepEqual(actual, expected) {
2732		t.Errorf(message+
2733			"\nactual:   %v"+
2734			"\nexpected: %v",
2735			actual,
2736			expected,
2737		)
2738	}
2739}
2740
2741func TestLlndkLibrary(t *testing.T) {
2742	result := prepareForCcTest.RunTestWithBp(t, `
2743	cc_library {
2744		name: "libllndk",
2745		stubs: { versions: ["1", "2"] },
2746		llndk: {
2747			symbol_file: "libllndk.map.txt",
2748		},
2749		export_include_dirs: ["include"],
2750	}
2751
2752	cc_prebuilt_library_shared {
2753		name: "libllndkprebuilt",
2754		stubs: { versions: ["1", "2"] },
2755		llndk: {
2756			symbol_file: "libllndkprebuilt.map.txt",
2757		},
2758	}
2759
2760	cc_library {
2761		name: "libllndk_with_external_headers",
2762		stubs: { versions: ["1", "2"] },
2763		llndk: {
2764			symbol_file: "libllndk.map.txt",
2765			export_llndk_headers: ["libexternal_llndk_headers"],
2766		},
2767		header_libs: ["libexternal_headers"],
2768		export_header_lib_headers: ["libexternal_headers"],
2769	}
2770	cc_library_headers {
2771		name: "libexternal_headers",
2772		export_include_dirs: ["include"],
2773		vendor_available: true,
2774	}
2775	cc_library_headers {
2776		name: "libexternal_llndk_headers",
2777		export_include_dirs: ["include_llndk"],
2778		llndk: {
2779			symbol_file: "libllndk.map.txt",
2780		},
2781		vendor_available: true,
2782	}
2783
2784	cc_library {
2785		name: "libllndk_with_override_headers",
2786		stubs: { versions: ["1", "2"] },
2787		llndk: {
2788			symbol_file: "libllndk.map.txt",
2789			override_export_include_dirs: ["include_llndk"],
2790		},
2791		export_include_dirs: ["include"],
2792	}
2793	`)
2794	actual := result.ModuleVariantsForTests("libllndk")
2795	for i := 0; i < len(actual); i++ {
2796		if !strings.HasPrefix(actual[i], "android_vendor.29_") {
2797			actual = append(actual[:i], actual[i+1:]...)
2798			i--
2799		}
2800	}
2801	expected := []string{
2802		"android_vendor.29_arm64_armv8-a_shared_1",
2803		"android_vendor.29_arm64_armv8-a_shared_2",
2804		"android_vendor.29_arm64_armv8-a_shared_current",
2805		"android_vendor.29_arm64_armv8-a_shared",
2806		"android_vendor.29_arm_armv7-a-neon_shared_1",
2807		"android_vendor.29_arm_armv7-a-neon_shared_2",
2808		"android_vendor.29_arm_armv7-a-neon_shared_current",
2809		"android_vendor.29_arm_armv7-a-neon_shared",
2810	}
2811	android.AssertArrayString(t, "variants for llndk stubs", expected, actual)
2812
2813	params := result.ModuleForTests("libllndk", "android_vendor.29_arm_armv7-a-neon_shared").Description("generate stub")
2814	android.AssertSame(t, "use VNDK version for default stubs", "current", params.Args["apiLevel"])
2815
2816	params = result.ModuleForTests("libllndk", "android_vendor.29_arm_armv7-a-neon_shared_1").Description("generate stub")
2817	android.AssertSame(t, "override apiLevel for versioned stubs", "1", params.Args["apiLevel"])
2818
2819	checkExportedIncludeDirs := func(module, variant string, expectedDirs ...string) {
2820		t.Helper()
2821		m := result.ModuleForTests(module, variant).Module()
2822		f := result.ModuleProvider(m, FlagExporterInfoProvider).(FlagExporterInfo)
2823		android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
2824			expectedDirs, f.IncludeDirs)
2825	}
2826
2827	checkExportedIncludeDirs("libllndk", "android_arm64_armv8-a_shared", "include")
2828	checkExportedIncludeDirs("libllndk", "android_vendor.29_arm64_armv8-a_shared", "include")
2829	checkExportedIncludeDirs("libllndk_with_external_headers", "android_arm64_armv8-a_shared", "include")
2830	checkExportedIncludeDirs("libllndk_with_external_headers", "android_vendor.29_arm64_armv8-a_shared", "include_llndk")
2831	checkExportedIncludeDirs("libllndk_with_override_headers", "android_arm64_armv8-a_shared", "include")
2832	checkExportedIncludeDirs("libllndk_with_override_headers", "android_vendor.29_arm64_armv8-a_shared", "include_llndk")
2833}
2834
2835func TestLlndkHeaders(t *testing.T) {
2836	ctx := testCc(t, `
2837	cc_library_headers {
2838		name: "libllndk_headers",
2839		export_include_dirs: ["my_include"],
2840		llndk: {
2841			llndk_headers: true,
2842		},
2843	}
2844	cc_library {
2845		name: "libllndk",
2846		llndk: {
2847			symbol_file: "libllndk.map.txt",
2848			export_llndk_headers: ["libllndk_headers"],
2849		}
2850	}
2851
2852	cc_library {
2853		name: "libvendor",
2854		shared_libs: ["libllndk"],
2855		vendor: true,
2856		srcs: ["foo.c"],
2857		no_libcrt: true,
2858		nocrt: true,
2859	}
2860	`)
2861
2862	// _static variant is used since _shared reuses *.o from the static variant
2863	cc := ctx.ModuleForTests("libvendor", "android_vendor.29_arm_armv7-a-neon_static").Rule("cc")
2864	cflags := cc.Args["cFlags"]
2865	if !strings.Contains(cflags, "-Imy_include") {
2866		t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
2867	}
2868}
2869
2870func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
2871	actual := module.Properties.AndroidMkRuntimeLibs
2872	if !reflect.DeepEqual(actual, expected) {
2873		t.Errorf("incorrect runtime_libs for shared libs"+
2874			"\nactual:   %v"+
2875			"\nexpected: %v",
2876			actual,
2877			expected,
2878		)
2879	}
2880}
2881
2882const runtimeLibAndroidBp = `
2883	cc_library {
2884		name: "liball_available",
2885		vendor_available: true,
2886		product_available: true,
2887		no_libcrt : true,
2888		nocrt : true,
2889		system_shared_libs : [],
2890	}
2891	cc_library {
2892		name: "libvendor_available1",
2893		vendor_available: true,
2894		runtime_libs: ["liball_available"],
2895		no_libcrt : true,
2896		nocrt : true,
2897		system_shared_libs : [],
2898	}
2899	cc_library {
2900		name: "libvendor_available2",
2901		vendor_available: true,
2902		runtime_libs: ["liball_available"],
2903		target: {
2904			vendor: {
2905				exclude_runtime_libs: ["liball_available"],
2906			}
2907		},
2908		no_libcrt : true,
2909		nocrt : true,
2910		system_shared_libs : [],
2911	}
2912	cc_library {
2913		name: "libproduct_vendor",
2914		product_specific: true,
2915		vendor_available: true,
2916		no_libcrt : true,
2917		nocrt : true,
2918		system_shared_libs : [],
2919	}
2920	cc_library {
2921		name: "libcore",
2922		runtime_libs: ["liball_available"],
2923		no_libcrt : true,
2924		nocrt : true,
2925		system_shared_libs : [],
2926	}
2927	cc_library {
2928		name: "libvendor1",
2929		vendor: true,
2930		no_libcrt : true,
2931		nocrt : true,
2932		system_shared_libs : [],
2933	}
2934	cc_library {
2935		name: "libvendor2",
2936		vendor: true,
2937		runtime_libs: ["liball_available", "libvendor1", "libproduct_vendor"],
2938		no_libcrt : true,
2939		nocrt : true,
2940		system_shared_libs : [],
2941	}
2942	cc_library {
2943		name: "libproduct_available1",
2944		product_available: true,
2945		runtime_libs: ["liball_available"],
2946		no_libcrt : true,
2947		nocrt : true,
2948		system_shared_libs : [],
2949	}
2950	cc_library {
2951		name: "libproduct1",
2952		product_specific: true,
2953		no_libcrt : true,
2954		nocrt : true,
2955		system_shared_libs : [],
2956	}
2957	cc_library {
2958		name: "libproduct2",
2959		product_specific: true,
2960		runtime_libs: ["liball_available", "libproduct1", "libproduct_vendor"],
2961		no_libcrt : true,
2962		nocrt : true,
2963		system_shared_libs : [],
2964	}
2965`
2966
2967func TestRuntimeLibs(t *testing.T) {
2968	ctx := testCc(t, runtimeLibAndroidBp)
2969
2970	// runtime_libs for core variants use the module names without suffixes.
2971	variant := "android_arm64_armv8-a_shared"
2972
2973	module := ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
2974	checkRuntimeLibs(t, []string{"liball_available"}, module)
2975
2976	module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
2977	checkRuntimeLibs(t, []string{"liball_available"}, module)
2978
2979	module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
2980	checkRuntimeLibs(t, []string{"liball_available"}, module)
2981
2982	// runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
2983	// and vendor variants.
2984	variant = "android_vendor.29_arm64_armv8-a_shared"
2985
2986	module = ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
2987	checkRuntimeLibs(t, []string{"liball_available.vendor"}, module)
2988
2989	module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
2990	checkRuntimeLibs(t, []string{"liball_available.vendor", "libvendor1", "libproduct_vendor.vendor"}, module)
2991
2992	// runtime_libs for product variants have '.product' suffixes if the modules have both core
2993	// and product variants.
2994	variant = "android_product.29_arm64_armv8-a_shared"
2995
2996	module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
2997	checkRuntimeLibs(t, []string{"liball_available.product"}, module)
2998
2999	module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module)
3000	checkRuntimeLibs(t, []string{"liball_available.product", "libproduct1", "libproduct_vendor"}, module)
3001}
3002
3003func TestExcludeRuntimeLibs(t *testing.T) {
3004	ctx := testCc(t, runtimeLibAndroidBp)
3005
3006	variant := "android_arm64_armv8-a_shared"
3007	module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
3008	checkRuntimeLibs(t, []string{"liball_available"}, module)
3009
3010	variant = "android_vendor.29_arm64_armv8-a_shared"
3011	module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
3012	checkRuntimeLibs(t, nil, module)
3013}
3014
3015func TestRuntimeLibsNoVndk(t *testing.T) {
3016	ctx := testCcNoVndk(t, runtimeLibAndroidBp)
3017
3018	// If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
3019
3020	variant := "android_arm64_armv8-a_shared"
3021
3022	module := ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
3023	checkRuntimeLibs(t, []string{"liball_available"}, module)
3024
3025	module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
3026	checkRuntimeLibs(t, []string{"liball_available", "libvendor1", "libproduct_vendor"}, module)
3027
3028	module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module)
3029	checkRuntimeLibs(t, []string{"liball_available", "libproduct1", "libproduct_vendor"}, module)
3030}
3031
3032func checkStaticLibs(t *testing.T, expected []string, module *Module) {
3033	t.Helper()
3034	actual := module.Properties.AndroidMkStaticLibs
3035	if !reflect.DeepEqual(actual, expected) {
3036		t.Errorf("incorrect static_libs"+
3037			"\nactual:   %v"+
3038			"\nexpected: %v",
3039			actual,
3040			expected,
3041		)
3042	}
3043}
3044
3045const staticLibAndroidBp = `
3046	cc_library {
3047		name: "lib1",
3048	}
3049	cc_library {
3050		name: "lib2",
3051		static_libs: ["lib1"],
3052	}
3053`
3054
3055func TestStaticLibDepExport(t *testing.T) {
3056	ctx := testCc(t, staticLibAndroidBp)
3057
3058	// Check the shared version of lib2.
3059	variant := "android_arm64_armv8-a_shared"
3060	module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
3061	checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins-aarch64-android"}, module)
3062
3063	// Check the static version of lib2.
3064	variant = "android_arm64_armv8-a_static"
3065	module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
3066	// libc++_static is linked additionally.
3067	checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins-aarch64-android"}, module)
3068}
3069
3070var compilerFlagsTestCases = []struct {
3071	in  string
3072	out bool
3073}{
3074	{
3075		in:  "a",
3076		out: false,
3077	},
3078	{
3079		in:  "-a",
3080		out: true,
3081	},
3082	{
3083		in:  "-Ipath/to/something",
3084		out: false,
3085	},
3086	{
3087		in:  "-isystempath/to/something",
3088		out: false,
3089	},
3090	{
3091		in:  "--coverage",
3092		out: false,
3093	},
3094	{
3095		in:  "-include a/b",
3096		out: true,
3097	},
3098	{
3099		in:  "-include a/b c/d",
3100		out: false,
3101	},
3102	{
3103		in:  "-DMACRO",
3104		out: true,
3105	},
3106	{
3107		in:  "-DMAC RO",
3108		out: false,
3109	},
3110	{
3111		in:  "-a -b",
3112		out: false,
3113	},
3114	{
3115		in:  "-DMACRO=definition",
3116		out: true,
3117	},
3118	{
3119		in:  "-DMACRO=defi nition",
3120		out: true, // TODO(jiyong): this should be false
3121	},
3122	{
3123		in:  "-DMACRO(x)=x + 1",
3124		out: true,
3125	},
3126	{
3127		in:  "-DMACRO=\"defi nition\"",
3128		out: true,
3129	},
3130}
3131
3132type mockContext struct {
3133	BaseModuleContext
3134	result bool
3135}
3136
3137func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
3138	// CheckBadCompilerFlags calls this function when the flag should be rejected
3139	ctx.result = false
3140}
3141
3142func TestCompilerFlags(t *testing.T) {
3143	for _, testCase := range compilerFlagsTestCases {
3144		ctx := &mockContext{result: true}
3145		CheckBadCompilerFlags(ctx, "", []string{testCase.in})
3146		if ctx.result != testCase.out {
3147			t.Errorf("incorrect output:")
3148			t.Errorf("     input: %#v", testCase.in)
3149			t.Errorf("  expected: %#v", testCase.out)
3150			t.Errorf("       got: %#v", ctx.result)
3151		}
3152	}
3153}
3154
3155func TestRecovery(t *testing.T) {
3156	ctx := testCc(t, `
3157		cc_library_shared {
3158			name: "librecovery",
3159			recovery: true,
3160		}
3161		cc_library_shared {
3162			name: "librecovery32",
3163			recovery: true,
3164			compile_multilib:"32",
3165		}
3166		cc_library_shared {
3167			name: "libHalInRecovery",
3168			recovery_available: true,
3169			vendor: true,
3170		}
3171	`)
3172
3173	variants := ctx.ModuleVariantsForTests("librecovery")
3174	const arm64 = "android_recovery_arm64_armv8-a_shared"
3175	if len(variants) != 1 || !android.InList(arm64, variants) {
3176		t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
3177	}
3178
3179	variants = ctx.ModuleVariantsForTests("librecovery32")
3180	if android.InList(arm64, variants) {
3181		t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
3182	}
3183
3184	recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
3185	if !recoveryModule.Platform() {
3186		t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
3187	}
3188}
3189
3190func TestDataLibsPrebuiltSharedTestLibrary(t *testing.T) {
3191	bp := `
3192		cc_prebuilt_test_library_shared {
3193			name: "test_lib",
3194			relative_install_path: "foo/bar/baz",
3195			srcs: ["srcpath/dontusethispath/baz.so"],
3196		}
3197
3198		cc_test {
3199			name: "main_test",
3200			data_libs: ["test_lib"],
3201			gtest: false,
3202		}
3203 `
3204
3205	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
3206	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
3207	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
3208	config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
3209
3210	ctx := testCcWithConfig(t, config)
3211	module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
3212	testBinary := module.(*Module).linker.(*testBinary)
3213	outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
3214	if err != nil {
3215		t.Fatalf("Expected cc_test to produce output files, error: %s", err)
3216	}
3217	if len(outputFiles) != 1 {
3218		t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
3219	}
3220	if len(testBinary.dataPaths()) != 1 {
3221		t.Errorf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths())
3222	}
3223
3224	outputPath := outputFiles[0].String()
3225
3226	if !strings.HasSuffix(outputPath, "/main_test") {
3227		t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
3228	}
3229	entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
3230	if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
3231		t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
3232			" but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
3233	}
3234}
3235
3236func TestVersionedStubs(t *testing.T) {
3237	ctx := testCc(t, `
3238		cc_library_shared {
3239			name: "libFoo",
3240			srcs: ["foo.c"],
3241			stubs: {
3242				symbol_file: "foo.map.txt",
3243				versions: ["1", "2", "3"],
3244			},
3245		}
3246
3247		cc_library_shared {
3248			name: "libBar",
3249			srcs: ["bar.c"],
3250			shared_libs: ["libFoo#1"],
3251		}`)
3252
3253	variants := ctx.ModuleVariantsForTests("libFoo")
3254	expectedVariants := []string{
3255		"android_arm64_armv8-a_shared",
3256		"android_arm64_armv8-a_shared_1",
3257		"android_arm64_armv8-a_shared_2",
3258		"android_arm64_armv8-a_shared_3",
3259		"android_arm64_armv8-a_shared_current",
3260		"android_arm_armv7-a-neon_shared",
3261		"android_arm_armv7-a-neon_shared_1",
3262		"android_arm_armv7-a-neon_shared_2",
3263		"android_arm_armv7-a-neon_shared_3",
3264		"android_arm_armv7-a-neon_shared_current",
3265	}
3266	variantsMismatch := false
3267	if len(variants) != len(expectedVariants) {
3268		variantsMismatch = true
3269	} else {
3270		for _, v := range expectedVariants {
3271			if !inList(v, variants) {
3272				variantsMismatch = false
3273			}
3274		}
3275	}
3276	if variantsMismatch {
3277		t.Errorf("variants of libFoo expected:\n")
3278		for _, v := range expectedVariants {
3279			t.Errorf("%q\n", v)
3280		}
3281		t.Errorf(", but got:\n")
3282		for _, v := range variants {
3283			t.Errorf("%q\n", v)
3284		}
3285	}
3286
3287	libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("ld")
3288	libFlags := libBarLinkRule.Args["libFlags"]
3289	libFoo1StubPath := "libFoo/android_arm64_armv8-a_shared_1/libFoo.so"
3290	if !strings.Contains(libFlags, libFoo1StubPath) {
3291		t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
3292	}
3293
3294	libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("cc")
3295	cFlags := libBarCompileRule.Args["cFlags"]
3296	libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
3297	if !strings.Contains(cFlags, libFoo1VersioningMacro) {
3298		t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
3299	}
3300}
3301
3302func TestVersioningMacro(t *testing.T) {
3303	for _, tc := range []struct{ moduleName, expected string }{
3304		{"libc", "__LIBC_API__"},
3305		{"libfoo", "__LIBFOO_API__"},
3306		{"libfoo@1", "__LIBFOO_1_API__"},
3307		{"libfoo-v1", "__LIBFOO_V1_API__"},
3308		{"libfoo.v1", "__LIBFOO_V1_API__"},
3309	} {
3310		checkEquals(t, tc.moduleName, tc.expected, versioningMacroName(tc.moduleName))
3311	}
3312}
3313
3314func TestStaticExecutable(t *testing.T) {
3315	ctx := testCc(t, `
3316		cc_binary {
3317			name: "static_test",
3318			srcs: ["foo.c", "baz.o"],
3319			static_executable: true,
3320		}`)
3321
3322	variant := "android_arm64_armv8-a"
3323	binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
3324	libFlags := binModuleRule.Args["libFlags"]
3325	systemStaticLibs := []string{"libc.a", "libm.a"}
3326	for _, lib := range systemStaticLibs {
3327		if !strings.Contains(libFlags, lib) {
3328			t.Errorf("Static lib %q was not found in %q", lib, libFlags)
3329		}
3330	}
3331	systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
3332	for _, lib := range systemSharedLibs {
3333		if strings.Contains(libFlags, lib) {
3334			t.Errorf("Shared lib %q was found in %q", lib, libFlags)
3335		}
3336	}
3337}
3338
3339func TestStaticDepsOrderWithStubs(t *testing.T) {
3340	ctx := testCc(t, `
3341		cc_binary {
3342			name: "mybin",
3343			srcs: ["foo.c"],
3344			static_libs: ["libfooC", "libfooB"],
3345			static_executable: true,
3346			stl: "none",
3347		}
3348
3349		cc_library {
3350			name: "libfooB",
3351			srcs: ["foo.c"],
3352			shared_libs: ["libfooC"],
3353			stl: "none",
3354		}
3355
3356		cc_library {
3357			name: "libfooC",
3358			srcs: ["foo.c"],
3359			stl: "none",
3360			stubs: {
3361				versions: ["1"],
3362			},
3363		}`)
3364
3365	mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a").Rule("ld")
3366	actual := mybin.Implicits[:2]
3367	expected := getOutputPaths(ctx, "android_arm64_armv8-a_static", []string{"libfooB", "libfooC"})
3368
3369	if !reflect.DeepEqual(actual, expected) {
3370		t.Errorf("staticDeps orderings were not propagated correctly"+
3371			"\nactual:   %v"+
3372			"\nexpected: %v",
3373			actual,
3374			expected,
3375		)
3376	}
3377}
3378
3379func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) {
3380	testCcError(t, `module "libA" .* depends on disabled module "libB"`, `
3381		cc_library {
3382			name: "libA",
3383			srcs: ["foo.c"],
3384			shared_libs: ["libB"],
3385			stl: "none",
3386		}
3387
3388		cc_library {
3389			name: "libB",
3390			srcs: ["foo.c"],
3391			enabled: false,
3392			stl: "none",
3393		}
3394	`)
3395}
3396
3397// Simple smoke test for the cc_fuzz target that ensures the rule compiles
3398// correctly.
3399func TestFuzzTarget(t *testing.T) {
3400	ctx := testCc(t, `
3401		cc_fuzz {
3402			name: "fuzz_smoke_test",
3403			srcs: ["foo.c"],
3404		}`)
3405
3406	variant := "android_arm64_armv8-a_fuzzer"
3407	ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
3408}
3409
3410func TestAidl(t *testing.T) {
3411}
3412
3413func assertString(t *testing.T, got, expected string) {
3414	t.Helper()
3415	if got != expected {
3416		t.Errorf("expected %q got %q", expected, got)
3417	}
3418}
3419
3420func assertArrayString(t *testing.T, got, expected []string) {
3421	t.Helper()
3422	if len(got) != len(expected) {
3423		t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got)
3424		return
3425	}
3426	for i := range got {
3427		if got[i] != expected[i] {
3428			t.Errorf("expected %d-th %q (%q) got %q (%q)",
3429				i, expected[i], expected, got[i], got)
3430			return
3431		}
3432	}
3433}
3434
3435func assertMapKeys(t *testing.T, m map[string]string, expected []string) {
3436	t.Helper()
3437	assertArrayString(t, android.SortedStringKeys(m), expected)
3438}
3439
3440func TestDefaults(t *testing.T) {
3441	ctx := testCc(t, `
3442		cc_defaults {
3443			name: "defaults",
3444			srcs: ["foo.c"],
3445			static: {
3446				srcs: ["bar.c"],
3447			},
3448			shared: {
3449				srcs: ["baz.c"],
3450			},
3451			bazel_module: {
3452				bp2build_available: true,
3453			},
3454		}
3455
3456		cc_library_static {
3457			name: "libstatic",
3458			defaults: ["defaults"],
3459		}
3460
3461		cc_library_shared {
3462			name: "libshared",
3463			defaults: ["defaults"],
3464		}
3465
3466		cc_library {
3467			name: "libboth",
3468			defaults: ["defaults"],
3469		}
3470
3471		cc_binary {
3472			name: "binary",
3473			defaults: ["defaults"],
3474		}`)
3475
3476	pathsToBase := func(paths android.Paths) []string {
3477		var ret []string
3478		for _, p := range paths {
3479			ret = append(ret, p.Base())
3480		}
3481		return ret
3482	}
3483
3484	shared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Rule("ld")
3485	if g, w := pathsToBase(shared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
3486		t.Errorf("libshared ld rule wanted %q, got %q", w, g)
3487	}
3488	bothShared := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_shared").Rule("ld")
3489	if g, w := pathsToBase(bothShared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
3490		t.Errorf("libboth ld rule wanted %q, got %q", w, g)
3491	}
3492	binary := ctx.ModuleForTests("binary", "android_arm64_armv8-a").Rule("ld")
3493	if g, w := pathsToBase(binary.Inputs), []string{"foo.o"}; !reflect.DeepEqual(w, g) {
3494		t.Errorf("binary ld rule wanted %q, got %q", w, g)
3495	}
3496
3497	static := ctx.ModuleForTests("libstatic", "android_arm64_armv8-a_static").Rule("ar")
3498	if g, w := pathsToBase(static.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
3499		t.Errorf("libstatic ar rule wanted %q, got %q", w, g)
3500	}
3501	bothStatic := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_static").Rule("ar")
3502	if g, w := pathsToBase(bothStatic.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
3503		t.Errorf("libboth ar rule wanted %q, got %q", w, g)
3504	}
3505}
3506
3507func TestProductVariableDefaults(t *testing.T) {
3508	bp := `
3509		cc_defaults {
3510			name: "libfoo_defaults",
3511			srcs: ["foo.c"],
3512			cppflags: ["-DFOO"],
3513			product_variables: {
3514				debuggable: {
3515					cppflags: ["-DBAR"],
3516				},
3517			},
3518		}
3519
3520		cc_library {
3521			name: "libfoo",
3522			defaults: ["libfoo_defaults"],
3523		}
3524	`
3525
3526	result := android.GroupFixturePreparers(
3527		prepareForCcTest,
3528		android.PrepareForTestWithVariables,
3529
3530		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3531			variables.Debuggable = BoolPtr(true)
3532		}),
3533	).RunTestWithBp(t, bp)
3534
3535	libfoo := result.Module("libfoo", "android_arm64_armv8-a_static").(*Module)
3536	android.AssertStringListContains(t, "cppflags", libfoo.flags.Local.CppFlags, "-DBAR")
3537}
3538
3539func TestEmptyWholeStaticLibsAllowMissingDependencies(t *testing.T) {
3540	t.Parallel()
3541	bp := `
3542		cc_library_static {
3543			name: "libfoo",
3544			srcs: ["foo.c"],
3545			whole_static_libs: ["libbar"],
3546		}
3547
3548		cc_library_static {
3549			name: "libbar",
3550			whole_static_libs: ["libmissing"],
3551		}
3552	`
3553
3554	result := android.GroupFixturePreparers(
3555		prepareForCcTest,
3556		android.PrepareForTestWithAllowMissingDependencies,
3557	).RunTestWithBp(t, bp)
3558
3559	libbar := result.ModuleForTests("libbar", "android_arm64_armv8-a_static").Output("libbar.a")
3560	android.AssertDeepEquals(t, "libbar rule", android.ErrorRule, libbar.Rule)
3561
3562	android.AssertStringDoesContain(t, "libbar error", libbar.Args["error"], "missing dependencies: libmissing")
3563
3564	libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Output("libfoo.a")
3565	android.AssertStringListContains(t, "libfoo.a dependencies", libfoo.Inputs.Strings(), libbar.Output.String())
3566}
3567
3568func TestInstallSharedLibs(t *testing.T) {
3569	bp := `
3570		cc_binary {
3571			name: "bin",
3572			host_supported: true,
3573			shared_libs: ["libshared"],
3574			runtime_libs: ["libruntime"],
3575			srcs: [":gen"],
3576		}
3577
3578		cc_library_shared {
3579			name: "libshared",
3580			host_supported: true,
3581			shared_libs: ["libtransitive"],
3582		}
3583
3584		cc_library_shared {
3585			name: "libtransitive",
3586			host_supported: true,
3587		}
3588
3589		cc_library_shared {
3590			name: "libruntime",
3591			host_supported: true,
3592		}
3593
3594		cc_binary_host {
3595			name: "tool",
3596			srcs: ["foo.cpp"],
3597		}
3598
3599		genrule {
3600			name: "gen",
3601			tools: ["tool"],
3602			out: ["gen.cpp"],
3603			cmd: "$(location tool) $(out)",
3604		}
3605	`
3606
3607	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
3608	ctx := testCcWithConfig(t, config)
3609
3610	hostBin := ctx.ModuleForTests("bin", config.BuildOSTarget.String()).Description("install")
3611	hostShared := ctx.ModuleForTests("libshared", config.BuildOSTarget.String()+"_shared").Description("install")
3612	hostRuntime := ctx.ModuleForTests("libruntime", config.BuildOSTarget.String()+"_shared").Description("install")
3613	hostTransitive := ctx.ModuleForTests("libtransitive", config.BuildOSTarget.String()+"_shared").Description("install")
3614	hostTool := ctx.ModuleForTests("tool", config.BuildOSTarget.String()).Description("install")
3615
3616	if g, w := hostBin.Implicits.Strings(), hostShared.Output.String(); !android.InList(w, g) {
3617		t.Errorf("expected host bin dependency %q, got %q", w, g)
3618	}
3619
3620	if g, w := hostBin.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
3621		t.Errorf("expected host bin dependency %q, got %q", w, g)
3622	}
3623
3624	if g, w := hostShared.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
3625		t.Errorf("expected host bin dependency %q, got %q", w, g)
3626	}
3627
3628	if g, w := hostBin.Implicits.Strings(), hostRuntime.Output.String(); !android.InList(w, g) {
3629		t.Errorf("expected host bin dependency %q, got %q", w, g)
3630	}
3631
3632	if g, w := hostBin.Implicits.Strings(), hostTool.Output.String(); android.InList(w, g) {
3633		t.Errorf("expected no host bin dependency %q, got %q", w, g)
3634	}
3635
3636	deviceBin := ctx.ModuleForTests("bin", "android_arm64_armv8-a").Description("install")
3637	deviceShared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Description("install")
3638	deviceTransitive := ctx.ModuleForTests("libtransitive", "android_arm64_armv8-a_shared").Description("install")
3639	deviceRuntime := ctx.ModuleForTests("libruntime", "android_arm64_armv8-a_shared").Description("install")
3640
3641	if g, w := deviceBin.OrderOnly.Strings(), deviceShared.Output.String(); !android.InList(w, g) {
3642		t.Errorf("expected device bin dependency %q, got %q", w, g)
3643	}
3644
3645	if g, w := deviceBin.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
3646		t.Errorf("expected device bin dependency %q, got %q", w, g)
3647	}
3648
3649	if g, w := deviceShared.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
3650		t.Errorf("expected device bin dependency %q, got %q", w, g)
3651	}
3652
3653	if g, w := deviceBin.OrderOnly.Strings(), deviceRuntime.Output.String(); !android.InList(w, g) {
3654		t.Errorf("expected device bin dependency %q, got %q", w, g)
3655	}
3656
3657	if g, w := deviceBin.OrderOnly.Strings(), hostTool.Output.String(); android.InList(w, g) {
3658		t.Errorf("expected no device bin dependency %q, got %q", w, g)
3659	}
3660
3661}
3662
3663func TestStubsLibReexportsHeaders(t *testing.T) {
3664	ctx := testCc(t, `
3665		cc_library_shared {
3666			name: "libclient",
3667			srcs: ["foo.c"],
3668			shared_libs: ["libfoo#1"],
3669		}
3670
3671		cc_library_shared {
3672			name: "libfoo",
3673			srcs: ["foo.c"],
3674			shared_libs: ["libbar"],
3675			export_shared_lib_headers: ["libbar"],
3676			stubs: {
3677				symbol_file: "foo.map.txt",
3678				versions: ["1", "2", "3"],
3679			},
3680		}
3681
3682		cc_library_shared {
3683			name: "libbar",
3684			export_include_dirs: ["include/libbar"],
3685			srcs: ["foo.c"],
3686		}`)
3687
3688	cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
3689
3690	if !strings.Contains(cFlags, "-Iinclude/libbar") {
3691		t.Errorf("expected %q in cflags, got %q", "-Iinclude/libbar", cFlags)
3692	}
3693}
3694
3695func TestAidlFlagsPassedToTheAidlCompiler(t *testing.T) {
3696	ctx := testCc(t, `
3697		cc_library {
3698			name: "libfoo",
3699			srcs: ["a/Foo.aidl"],
3700			aidl: { flags: ["-Werror"], },
3701		}
3702	`)
3703
3704	libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
3705	manifest := android.RuleBuilderSboxProtoForTests(t, libfoo.Output("aidl.sbox.textproto"))
3706	aidlCommand := manifest.Commands[0].GetCommand()
3707	expectedAidlFlag := "-Werror"
3708	if !strings.Contains(aidlCommand, expectedAidlFlag) {
3709		t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
3710	}
3711}
3712
3713func TestMinSdkVersionInClangTriple(t *testing.T) {
3714	ctx := testCc(t, `
3715		cc_library_shared {
3716			name: "libfoo",
3717			srcs: ["foo.c"],
3718			min_sdk_version: "29",
3719		}`)
3720
3721	cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
3722	android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android29")
3723}
3724
3725type MemtagNoteType int
3726
3727const (
3728	None MemtagNoteType = iota + 1
3729	Sync
3730	Async
3731)
3732
3733func (t MemtagNoteType) str() string {
3734	switch t {
3735	case None:
3736		return "none"
3737	case Sync:
3738		return "sync"
3739	case Async:
3740		return "async"
3741	default:
3742		panic("invalid note type")
3743	}
3744}
3745
3746func checkHasMemtagNote(t *testing.T, m android.TestingModule, expected MemtagNoteType) {
3747	note_async := "note_memtag_heap_async"
3748	note_sync := "note_memtag_heap_sync"
3749
3750	found := None
3751	implicits := m.Rule("ld").Implicits
3752	for _, lib := range implicits {
3753		if strings.Contains(lib.Rel(), note_async) {
3754			found = Async
3755			break
3756		} else if strings.Contains(lib.Rel(), note_sync) {
3757			found = Sync
3758			break
3759		}
3760	}
3761
3762	if found != expected {
3763		t.Errorf("Wrong Memtag note in target %q: found %q, expected %q", m.Module().(*Module).Name(), found.str(), expected.str())
3764	}
3765}
3766
3767var prepareForTestWithMemtagHeap = android.GroupFixturePreparers(
3768	android.FixtureModifyMockFS(func(fs android.MockFS) {
3769		templateBp := `
3770		cc_test {
3771			name: "%[1]s_test",
3772			gtest: false,
3773		}
3774
3775		cc_test {
3776			name: "%[1]s_test_false",
3777			gtest: false,
3778			sanitize: { memtag_heap: false },
3779		}
3780
3781		cc_test {
3782			name: "%[1]s_test_true",
3783			gtest: false,
3784			sanitize: { memtag_heap: true },
3785		}
3786
3787		cc_test {
3788			name: "%[1]s_test_true_nodiag",
3789			gtest: false,
3790			sanitize: { memtag_heap: true, diag: { memtag_heap: false }  },
3791		}
3792
3793		cc_test {
3794			name: "%[1]s_test_true_diag",
3795			gtest: false,
3796			sanitize: { memtag_heap: true, diag: { memtag_heap: true }  },
3797		}
3798
3799		cc_binary {
3800			name: "%[1]s_binary",
3801		}
3802
3803		cc_binary {
3804			name: "%[1]s_binary_false",
3805			sanitize: { memtag_heap: false },
3806		}
3807
3808		cc_binary {
3809			name: "%[1]s_binary_true",
3810			sanitize: { memtag_heap: true },
3811		}
3812
3813		cc_binary {
3814			name: "%[1]s_binary_true_nodiag",
3815			sanitize: { memtag_heap: true, diag: { memtag_heap: false }  },
3816		}
3817
3818		cc_binary {
3819			name: "%[1]s_binary_true_diag",
3820			sanitize: { memtag_heap: true, diag: { memtag_heap: true }  },
3821		}
3822		`
3823		subdirDefaultBp := fmt.Sprintf(templateBp, "default")
3824		subdirExcludeBp := fmt.Sprintf(templateBp, "exclude")
3825		subdirSyncBp := fmt.Sprintf(templateBp, "sync")
3826		subdirAsyncBp := fmt.Sprintf(templateBp, "async")
3827
3828		fs.Merge(android.MockFS{
3829			"subdir_default/Android.bp": []byte(subdirDefaultBp),
3830			"subdir_exclude/Android.bp": []byte(subdirExcludeBp),
3831			"subdir_sync/Android.bp":    []byte(subdirSyncBp),
3832			"subdir_async/Android.bp":   []byte(subdirAsyncBp),
3833		})
3834	}),
3835	android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3836		variables.MemtagHeapExcludePaths = []string{"subdir_exclude"}
3837		// "subdir_exclude" is covered by both include and exclude paths. Exclude wins.
3838		variables.MemtagHeapSyncIncludePaths = []string{"subdir_sync", "subdir_exclude"}
3839		variables.MemtagHeapAsyncIncludePaths = []string{"subdir_async", "subdir_exclude"}
3840	}),
3841)
3842
3843func TestSanitizeMemtagHeap(t *testing.T) {
3844	variant := "android_arm64_armv8-a"
3845
3846	result := android.GroupFixturePreparers(
3847		prepareForCcTest,
3848		prepareForTestWithMemtagHeap,
3849	).RunTest(t)
3850	ctx := result.TestContext
3851
3852	checkHasMemtagNote(t, ctx.ModuleForTests("default_test", variant), Sync)
3853	checkHasMemtagNote(t, ctx.ModuleForTests("default_test_false", variant), None)
3854	checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true", variant), Async)
3855	checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_nodiag", variant), Async)
3856	checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_diag", variant), Sync)
3857
3858	checkHasMemtagNote(t, ctx.ModuleForTests("default_binary", variant), None)
3859	checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_false", variant), None)
3860	checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true", variant), Async)
3861	checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_nodiag", variant), Async)
3862	checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_diag", variant), Sync)
3863
3864	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test", variant), Sync)
3865	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_false", variant), None)
3866	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true", variant), Async)
3867	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_nodiag", variant), Async)
3868	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_diag", variant), Sync)
3869
3870	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary", variant), None)
3871	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_false", variant), None)
3872	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true", variant), Async)
3873	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_nodiag", variant), Async)
3874	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_diag", variant), Sync)
3875
3876	checkHasMemtagNote(t, ctx.ModuleForTests("async_test", variant), Sync)
3877	checkHasMemtagNote(t, ctx.ModuleForTests("async_test_false", variant), None)
3878	checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true", variant), Async)
3879	checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_nodiag", variant), Async)
3880	checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_diag", variant), Sync)
3881
3882	checkHasMemtagNote(t, ctx.ModuleForTests("async_binary", variant), Async)
3883	checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_false", variant), None)
3884	checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true", variant), Async)
3885	checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_nodiag", variant), Async)
3886	checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_diag", variant), Sync)
3887
3888	checkHasMemtagNote(t, ctx.ModuleForTests("sync_test", variant), Sync)
3889	checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_false", variant), None)
3890	checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true", variant), Sync)
3891	checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_nodiag", variant), Async)
3892	checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_diag", variant), Sync)
3893
3894	checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary", variant), Sync)
3895	checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_false", variant), None)
3896	checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true", variant), Sync)
3897	checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_nodiag", variant), Async)
3898	checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_diag", variant), Sync)
3899}
3900
3901func TestSanitizeMemtagHeapWithSanitizeDevice(t *testing.T) {
3902	variant := "android_arm64_armv8-a"
3903
3904	result := android.GroupFixturePreparers(
3905		prepareForCcTest,
3906		prepareForTestWithMemtagHeap,
3907		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3908			variables.SanitizeDevice = []string{"memtag_heap"}
3909		}),
3910	).RunTest(t)
3911	ctx := result.TestContext
3912
3913	checkHasMemtagNote(t, ctx.ModuleForTests("default_test", variant), Sync)
3914	checkHasMemtagNote(t, ctx.ModuleForTests("default_test_false", variant), None)
3915	checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true", variant), Async)
3916	checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_nodiag", variant), Async)
3917	checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_diag", variant), Sync)
3918
3919	checkHasMemtagNote(t, ctx.ModuleForTests("default_binary", variant), Async)
3920	checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_false", variant), None)
3921	checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true", variant), Async)
3922	checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_nodiag", variant), Async)
3923	checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_diag", variant), Sync)
3924
3925	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test", variant), Sync)
3926	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_false", variant), None)
3927	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true", variant), Async)
3928	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_nodiag", variant), Async)
3929	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_diag", variant), Sync)
3930
3931	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary", variant), None)
3932	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_false", variant), None)
3933	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true", variant), Async)
3934	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_nodiag", variant), Async)
3935	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_diag", variant), Sync)
3936
3937	checkHasMemtagNote(t, ctx.ModuleForTests("async_test", variant), Sync)
3938	checkHasMemtagNote(t, ctx.ModuleForTests("async_test_false", variant), None)
3939	checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true", variant), Async)
3940	checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_nodiag", variant), Async)
3941	checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_diag", variant), Sync)
3942
3943	checkHasMemtagNote(t, ctx.ModuleForTests("async_binary", variant), Async)
3944	checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_false", variant), None)
3945	checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true", variant), Async)
3946	checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_nodiag", variant), Async)
3947	checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_diag", variant), Sync)
3948
3949	checkHasMemtagNote(t, ctx.ModuleForTests("sync_test", variant), Sync)
3950	checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_false", variant), None)
3951	checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true", variant), Sync)
3952	checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_nodiag", variant), Async)
3953	checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_diag", variant), Sync)
3954
3955	checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary", variant), Sync)
3956	checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_false", variant), None)
3957	checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true", variant), Sync)
3958	checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_nodiag", variant), Async)
3959	checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_diag", variant), Sync)
3960}
3961
3962func TestSanitizeMemtagHeapWithSanitizeDeviceDiag(t *testing.T) {
3963	variant := "android_arm64_armv8-a"
3964
3965	result := android.GroupFixturePreparers(
3966		prepareForCcTest,
3967		prepareForTestWithMemtagHeap,
3968		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
3969			variables.SanitizeDevice = []string{"memtag_heap"}
3970			variables.SanitizeDeviceDiag = []string{"memtag_heap"}
3971		}),
3972	).RunTest(t)
3973	ctx := result.TestContext
3974
3975	checkHasMemtagNote(t, ctx.ModuleForTests("default_test", variant), Sync)
3976	checkHasMemtagNote(t, ctx.ModuleForTests("default_test_false", variant), None)
3977	checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true", variant), Sync)
3978	checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_nodiag", variant), Async)
3979	checkHasMemtagNote(t, ctx.ModuleForTests("default_test_true_diag", variant), Sync)
3980
3981	checkHasMemtagNote(t, ctx.ModuleForTests("default_binary", variant), Sync)
3982	checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_false", variant), None)
3983	checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true", variant), Sync)
3984	checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_nodiag", variant), Async)
3985	checkHasMemtagNote(t, ctx.ModuleForTests("default_binary_true_diag", variant), Sync)
3986
3987	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test", variant), Sync)
3988	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_false", variant), None)
3989	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true", variant), Sync)
3990	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_nodiag", variant), Async)
3991	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_test_true_diag", variant), Sync)
3992
3993	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary", variant), None)
3994	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_false", variant), None)
3995	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true", variant), Sync)
3996	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_nodiag", variant), Async)
3997	checkHasMemtagNote(t, ctx.ModuleForTests("exclude_binary_true_diag", variant), Sync)
3998
3999	checkHasMemtagNote(t, ctx.ModuleForTests("async_test", variant), Sync)
4000	checkHasMemtagNote(t, ctx.ModuleForTests("async_test_false", variant), None)
4001	checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true", variant), Sync)
4002	checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_nodiag", variant), Async)
4003	checkHasMemtagNote(t, ctx.ModuleForTests("async_test_true_diag", variant), Sync)
4004
4005	checkHasMemtagNote(t, ctx.ModuleForTests("async_binary", variant), Sync)
4006	checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_false", variant), None)
4007	checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true", variant), Sync)
4008	checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_nodiag", variant), Async)
4009	checkHasMemtagNote(t, ctx.ModuleForTests("async_binary_true_diag", variant), Sync)
4010
4011	checkHasMemtagNote(t, ctx.ModuleForTests("sync_test", variant), Sync)
4012	checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_false", variant), None)
4013	checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true", variant), Sync)
4014	checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_nodiag", variant), Async)
4015	checkHasMemtagNote(t, ctx.ModuleForTests("sync_test_true_diag", variant), Sync)
4016
4017	checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary", variant), Sync)
4018	checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_false", variant), None)
4019	checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true", variant), Sync)
4020	checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_nodiag", variant), Async)
4021	checkHasMemtagNote(t, ctx.ModuleForTests("sync_binary_true_diag", variant), Sync)
4022}
4023
4024func TestIncludeDirsExporting(t *testing.T) {
4025
4026	// Trim spaces from the beginning, end and immediately after any newline characters. Leaves
4027	// embedded newline characters alone.
4028	trimIndentingSpaces := func(s string) string {
4029		return strings.TrimSpace(regexp.MustCompile("(^|\n)\\s+").ReplaceAllString(s, "$1"))
4030	}
4031
4032	checkPaths := func(t *testing.T, message string, expected string, paths android.Paths) {
4033		t.Helper()
4034		expected = trimIndentingSpaces(expected)
4035		actual := trimIndentingSpaces(strings.Join(android.FirstUniqueStrings(android.NormalizePathsForTesting(paths)), "\n"))
4036		if expected != actual {
4037			t.Errorf("%s: expected:\n%s\n actual:\n%s\n", message, expected, actual)
4038		}
4039	}
4040
4041	type exportedChecker func(t *testing.T, name string, exported FlagExporterInfo)
4042
4043	checkIncludeDirs := func(t *testing.T, ctx *android.TestContext, module android.Module, checkers ...exportedChecker) {
4044		t.Helper()
4045		exported := ctx.ModuleProvider(module, FlagExporterInfoProvider).(FlagExporterInfo)
4046		name := module.Name()
4047
4048		for _, checker := range checkers {
4049			checker(t, name, exported)
4050		}
4051	}
4052
4053	expectedIncludeDirs := func(expectedPaths string) exportedChecker {
4054		return func(t *testing.T, name string, exported FlagExporterInfo) {
4055			t.Helper()
4056			checkPaths(t, fmt.Sprintf("%s: include dirs", name), expectedPaths, exported.IncludeDirs)
4057		}
4058	}
4059
4060	expectedSystemIncludeDirs := func(expectedPaths string) exportedChecker {
4061		return func(t *testing.T, name string, exported FlagExporterInfo) {
4062			t.Helper()
4063			checkPaths(t, fmt.Sprintf("%s: system include dirs", name), expectedPaths, exported.SystemIncludeDirs)
4064		}
4065	}
4066
4067	expectedGeneratedHeaders := func(expectedPaths string) exportedChecker {
4068		return func(t *testing.T, name string, exported FlagExporterInfo) {
4069			t.Helper()
4070			checkPaths(t, fmt.Sprintf("%s: generated headers", name), expectedPaths, exported.GeneratedHeaders)
4071		}
4072	}
4073
4074	expectedOrderOnlyDeps := func(expectedPaths string) exportedChecker {
4075		return func(t *testing.T, name string, exported FlagExporterInfo) {
4076			t.Helper()
4077			checkPaths(t, fmt.Sprintf("%s: order only deps", name), expectedPaths, exported.Deps)
4078		}
4079	}
4080
4081	genRuleModules := `
4082		genrule {
4083			name: "genrule_foo",
4084			cmd: "generate-foo",
4085			out: [
4086				"generated_headers/foo/generated_header.h",
4087			],
4088			export_include_dirs: [
4089				"generated_headers",
4090			],
4091		}
4092
4093		genrule {
4094			name: "genrule_bar",
4095			cmd: "generate-bar",
4096			out: [
4097				"generated_headers/bar/generated_header.h",
4098			],
4099			export_include_dirs: [
4100				"generated_headers",
4101			],
4102		}
4103	`
4104
4105	t.Run("ensure exported include dirs are not automatically re-exported from shared_libs", func(t *testing.T) {
4106		ctx := testCc(t, genRuleModules+`
4107		cc_library {
4108			name: "libfoo",
4109			srcs: ["foo.c"],
4110			export_include_dirs: ["foo/standard"],
4111			export_system_include_dirs: ["foo/system"],
4112			generated_headers: ["genrule_foo"],
4113			export_generated_headers: ["genrule_foo"],
4114		}
4115
4116		cc_library {
4117			name: "libbar",
4118			srcs: ["bar.c"],
4119			shared_libs: ["libfoo"],
4120			export_include_dirs: ["bar/standard"],
4121			export_system_include_dirs: ["bar/system"],
4122			generated_headers: ["genrule_bar"],
4123			export_generated_headers: ["genrule_bar"],
4124		}
4125		`)
4126		foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
4127		checkIncludeDirs(t, ctx, foo,
4128			expectedIncludeDirs(`
4129				foo/standard
4130				.intermediates/genrule_foo/gen/generated_headers
4131			`),
4132			expectedSystemIncludeDirs(`foo/system`),
4133			expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
4134			expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
4135		)
4136
4137		bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
4138		checkIncludeDirs(t, ctx, bar,
4139			expectedIncludeDirs(`
4140				bar/standard
4141				.intermediates/genrule_bar/gen/generated_headers
4142			`),
4143			expectedSystemIncludeDirs(`bar/system`),
4144			expectedGeneratedHeaders(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
4145			expectedOrderOnlyDeps(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
4146		)
4147	})
4148
4149	t.Run("ensure exported include dirs are automatically re-exported from whole_static_libs", func(t *testing.T) {
4150		ctx := testCc(t, genRuleModules+`
4151		cc_library {
4152			name: "libfoo",
4153			srcs: ["foo.c"],
4154			export_include_dirs: ["foo/standard"],
4155			export_system_include_dirs: ["foo/system"],
4156			generated_headers: ["genrule_foo"],
4157			export_generated_headers: ["genrule_foo"],
4158		}
4159
4160		cc_library {
4161			name: "libbar",
4162			srcs: ["bar.c"],
4163			whole_static_libs: ["libfoo"],
4164			export_include_dirs: ["bar/standard"],
4165			export_system_include_dirs: ["bar/system"],
4166			generated_headers: ["genrule_bar"],
4167			export_generated_headers: ["genrule_bar"],
4168		}
4169		`)
4170		foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
4171		checkIncludeDirs(t, ctx, foo,
4172			expectedIncludeDirs(`
4173				foo/standard
4174				.intermediates/genrule_foo/gen/generated_headers
4175			`),
4176			expectedSystemIncludeDirs(`foo/system`),
4177			expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
4178			expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
4179		)
4180
4181		bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
4182		checkIncludeDirs(t, ctx, bar,
4183			expectedIncludeDirs(`
4184				bar/standard
4185				foo/standard
4186				.intermediates/genrule_foo/gen/generated_headers
4187				.intermediates/genrule_bar/gen/generated_headers
4188			`),
4189			expectedSystemIncludeDirs(`
4190				bar/system
4191				foo/system
4192			`),
4193			expectedGeneratedHeaders(`
4194				.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
4195				.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
4196			`),
4197			expectedOrderOnlyDeps(`
4198				.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
4199				.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
4200			`),
4201		)
4202	})
4203
4204	t.Run("ensure only aidl headers are exported", func(t *testing.T) {
4205		ctx := testCc(t, genRuleModules+`
4206		cc_library_shared {
4207			name: "libfoo",
4208			srcs: [
4209				"foo.c",
4210				"b.aidl",
4211				"a.proto",
4212			],
4213			aidl: {
4214				export_aidl_headers: true,
4215			}
4216		}
4217		`)
4218		foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
4219		checkIncludeDirs(t, ctx, foo,
4220			expectedIncludeDirs(`
4221				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl
4222			`),
4223			expectedSystemIncludeDirs(``),
4224			expectedGeneratedHeaders(`
4225				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
4226				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
4227				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
4228			`),
4229			expectedOrderOnlyDeps(`
4230				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
4231				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
4232				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
4233			`),
4234		)
4235	})
4236
4237	t.Run("ensure only proto headers are exported", func(t *testing.T) {
4238		ctx := testCc(t, genRuleModules+`
4239		cc_library_shared {
4240			name: "libfoo",
4241			srcs: [
4242				"foo.c",
4243				"b.aidl",
4244				"a.proto",
4245			],
4246			proto: {
4247				export_proto_headers: true,
4248			}
4249		}
4250		`)
4251		foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
4252		checkIncludeDirs(t, ctx, foo,
4253			expectedIncludeDirs(`
4254				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto
4255			`),
4256			expectedSystemIncludeDirs(``),
4257			expectedGeneratedHeaders(`
4258				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
4259			`),
4260			expectedOrderOnlyDeps(`
4261				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
4262			`),
4263		)
4264	})
4265
4266	t.Run("ensure only sysprop headers are exported", func(t *testing.T) {
4267		ctx := testCc(t, genRuleModules+`
4268		cc_library_shared {
4269			name: "libfoo",
4270			srcs: [
4271				"foo.c",
4272				"a.sysprop",
4273				"b.aidl",
4274				"a.proto",
4275			],
4276		}
4277		`)
4278		foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
4279		checkIncludeDirs(t, ctx, foo,
4280			expectedIncludeDirs(`
4281				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include
4282			`),
4283			expectedSystemIncludeDirs(``),
4284			expectedGeneratedHeaders(`
4285				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/a.sysprop.h
4286			`),
4287			expectedOrderOnlyDeps(`
4288				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/a.sysprop.h
4289				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/public/include/a.sysprop.h
4290			`),
4291		)
4292	})
4293}
4294