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