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	"io/ioutil"
20	"os"
21	"path/filepath"
22	"reflect"
23	"sort"
24	"strings"
25	"testing"
26
27	"android/soong/android"
28)
29
30var buildDir string
31
32func setUp() {
33	var err error
34	buildDir, err = ioutil.TempDir("", "soong_cc_test")
35	if err != nil {
36		panic(err)
37	}
38}
39
40func tearDown() {
41	os.RemoveAll(buildDir)
42}
43
44func TestMain(m *testing.M) {
45	run := func() int {
46		setUp()
47		defer tearDown()
48
49		return m.Run()
50	}
51
52	os.Exit(run())
53}
54
55func testCcWithConfig(t *testing.T, config android.Config) *android.TestContext {
56	t.Helper()
57	ctx := CreateTestContext()
58	ctx.Register(config)
59
60	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
61	android.FailIfErrored(t, errs)
62	_, errs = ctx.PrepareBuildActions(config)
63	android.FailIfErrored(t, errs)
64
65	return ctx
66}
67
68func testCc(t *testing.T, bp string) *android.TestContext {
69	t.Helper()
70	config := TestConfig(buildDir, android.Android, nil, bp, nil)
71	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
72	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
73
74	return testCcWithConfig(t, config)
75}
76
77func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
78	t.Helper()
79	config := TestConfig(buildDir, android.Android, nil, bp, nil)
80	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
81
82	return testCcWithConfig(t, config)
83}
84
85func testCcErrorWithConfig(t *testing.T, pattern string, config android.Config) {
86	t.Helper()
87
88	ctx := CreateTestContext()
89	ctx.Register(config)
90
91	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
92	if len(errs) > 0 {
93		android.FailIfNoMatchingErrors(t, pattern, errs)
94		return
95	}
96
97	_, errs = ctx.PrepareBuildActions(config)
98	if len(errs) > 0 {
99		android.FailIfNoMatchingErrors(t, pattern, errs)
100		return
101	}
102
103	t.Fatalf("missing expected error %q (0 errors are returned)", pattern)
104}
105
106func testCcError(t *testing.T, pattern string, bp string) {
107	config := TestConfig(buildDir, android.Android, nil, bp, nil)
108	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
109	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
110	testCcErrorWithConfig(t, pattern, config)
111	return
112}
113
114func testCcErrorProductVndk(t *testing.T, pattern string, bp string) {
115	config := TestConfig(buildDir, android.Android, nil, bp, nil)
116	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
117	config.TestProductVariables.ProductVndkVersion = StringPtr("current")
118	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
119	testCcErrorWithConfig(t, pattern, config)
120	return
121}
122
123const (
124	coreVariant     = "android_arm64_armv8-a_shared"
125	vendorVariant   = "android_vendor.VER_arm64_armv8-a_shared"
126	productVariant  = "android_product.VER_arm64_armv8-a_shared"
127	recoveryVariant = "android_recovery_arm64_armv8-a_shared"
128)
129
130func TestFuchsiaDeps(t *testing.T) {
131	t.Helper()
132
133	bp := `
134		cc_library {
135			name: "libTest",
136			srcs: ["foo.c"],
137			target: {
138				fuchsia: {
139					srcs: ["bar.c"],
140				},
141			},
142		}`
143
144	config := TestConfig(buildDir, android.Fuchsia, nil, bp, nil)
145	ctx := testCcWithConfig(t, config)
146
147	rt := false
148	fb := false
149
150	ld := ctx.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
151	implicits := ld.Implicits
152	for _, lib := range implicits {
153		if strings.Contains(lib.Rel(), "libcompiler_rt") {
154			rt = true
155		}
156
157		if strings.Contains(lib.Rel(), "libbioniccompat") {
158			fb = true
159		}
160	}
161
162	if !rt || !fb {
163		t.Errorf("fuchsia libs must link libcompiler_rt and libbioniccompat")
164	}
165}
166
167func TestFuchsiaTargetDecl(t *testing.T) {
168	t.Helper()
169
170	bp := `
171		cc_library {
172			name: "libTest",
173			srcs: ["foo.c"],
174			target: {
175				fuchsia: {
176					srcs: ["bar.c"],
177				},
178			},
179		}`
180
181	config := TestConfig(buildDir, android.Fuchsia, nil, bp, nil)
182	ctx := testCcWithConfig(t, config)
183	ld := ctx.ModuleForTests("libTest", "fuchsia_arm64_shared").Rule("ld")
184	var objs []string
185	for _, o := range ld.Inputs {
186		objs = append(objs, o.Base())
187	}
188	if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
189		t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
190	}
191}
192
193func TestVendorSrc(t *testing.T) {
194	ctx := testCc(t, `
195		cc_library {
196			name: "libTest",
197			srcs: ["foo.c"],
198			no_libcrt: true,
199			nocrt: true,
200			system_shared_libs: [],
201			vendor_available: true,
202			target: {
203				vendor: {
204					srcs: ["bar.c"],
205				},
206			},
207		}
208	`)
209
210	ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
211	var objs []string
212	for _, o := range ld.Inputs {
213		objs = append(objs, o.Base())
214	}
215	if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
216		t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
217	}
218}
219
220func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
221	isVndkSp bool, extends string, variant string) {
222
223	t.Helper()
224
225	mod := ctx.ModuleForTests(name, variant).Module().(*Module)
226	if !mod.HasVendorVariant() {
227		t.Errorf("%q must have variant %q", name, variant)
228	}
229
230	// Check library properties.
231	lib, ok := mod.compiler.(*libraryDecorator)
232	if !ok {
233		t.Errorf("%q must have libraryDecorator", name)
234	} else if lib.baseInstaller.subDir != subDir {
235		t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
236			lib.baseInstaller.subDir)
237	}
238
239	// Check VNDK properties.
240	if mod.vndkdep == nil {
241		t.Fatalf("%q must have `vndkdep`", name)
242	}
243	if !mod.IsVndk() {
244		t.Errorf("%q IsVndk() must equal to true", name)
245	}
246	if mod.isVndkSp() != isVndkSp {
247		t.Errorf("%q isVndkSp() must equal to %t", name, isVndkSp)
248	}
249
250	// Check VNDK extension properties.
251	isVndkExt := extends != ""
252	if mod.isVndkExt() != isVndkExt {
253		t.Errorf("%q isVndkExt() must equal to %t", name, isVndkExt)
254	}
255
256	if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
257		t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
258	}
259}
260
261func checkSnapshot(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string) {
262	mod, ok := ctx.ModuleForTests(moduleName, variant).Module().(android.OutputFileProducer)
263	if !ok {
264		t.Errorf("%q must have output\n", moduleName)
265		return
266	}
267	outputFiles, err := mod.OutputFiles("")
268	if err != nil || len(outputFiles) != 1 {
269		t.Errorf("%q must have single output\n", moduleName)
270		return
271	}
272	snapshotPath := filepath.Join(subDir, snapshotFilename)
273
274	out := singleton.Output(snapshotPath)
275	if out.Input.String() != outputFiles[0].String() {
276		t.Errorf("The input of snapshot %q must be %q, but %q", moduleName, out.Input.String(), outputFiles[0])
277	}
278}
279
280func checkWriteFileOutput(t *testing.T, params android.TestingBuildParams, expected []string) {
281	t.Helper()
282	assertString(t, params.Rule.String(), android.WriteFile.String())
283	actual := strings.FieldsFunc(strings.ReplaceAll(params.Args["content"], "\\n", "\n"), func(r rune) bool { return r == '\n' })
284	assertArrayString(t, actual, expected)
285}
286
287func checkVndkOutput(t *testing.T, ctx *android.TestContext, output string, expected []string) {
288	t.Helper()
289	vndkSnapshot := ctx.SingletonForTests("vndk-snapshot")
290	checkWriteFileOutput(t, vndkSnapshot.Output(output), expected)
291}
292
293func checkVndkLibrariesOutput(t *testing.T, ctx *android.TestContext, module string, expected []string) {
294	t.Helper()
295	vndkLibraries := ctx.ModuleForTests(module, "")
296
297	var output string
298	if module != "vndkcorevariant.libraries.txt" {
299		output = insertVndkVersion(module, "VER")
300	} else {
301		output = module
302	}
303
304	checkWriteFileOutput(t, vndkLibraries.Output(output), expected)
305}
306
307func TestVndk(t *testing.T) {
308	bp := `
309		cc_library {
310			name: "libvndk",
311			vendor_available: true,
312			vndk: {
313				enabled: true,
314			},
315			nocrt: true,
316		}
317
318		cc_library {
319			name: "libvndk_private",
320			vendor_available: false,
321			vndk: {
322				enabled: true,
323			},
324			nocrt: true,
325			stem: "libvndk-private",
326		}
327
328		cc_library {
329			name: "libvndk_sp",
330			vendor_available: true,
331			vndk: {
332				enabled: true,
333				support_system_process: true,
334			},
335			nocrt: true,
336			suffix: "-x",
337		}
338
339		cc_library {
340			name: "libvndk_sp_private",
341			vendor_available: false,
342			vndk: {
343				enabled: true,
344				support_system_process: true,
345			},
346			nocrt: true,
347			target: {
348				vendor: {
349					suffix: "-x",
350				},
351			},
352		}
353		vndk_libraries_txt {
354			name: "llndk.libraries.txt",
355		}
356		vndk_libraries_txt {
357			name: "vndkcore.libraries.txt",
358		}
359		vndk_libraries_txt {
360			name: "vndksp.libraries.txt",
361		}
362		vndk_libraries_txt {
363			name: "vndkprivate.libraries.txt",
364		}
365		vndk_libraries_txt {
366			name: "vndkcorevariant.libraries.txt",
367		}
368	`
369
370	config := TestConfig(buildDir, android.Android, nil, bp, nil)
371	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
372	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
373
374	ctx := testCcWithConfig(t, config)
375
376	checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "", vendorVariant)
377	checkVndkModule(t, ctx, "libvndk_private", "vndk-VER", false, "", vendorVariant)
378	checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "", vendorVariant)
379	checkVndkModule(t, ctx, "libvndk_sp_private", "vndk-sp-VER", true, "", vendorVariant)
380
381	// Check VNDK snapshot output.
382
383	snapshotDir := "vndk-snapshot"
384	snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
385
386	vndkLibPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
387		"arm64", "armv8-a"))
388	vndkLib2ndPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
389		"arm", "armv7-a-neon"))
390
391	vndkCoreLibPath := filepath.Join(vndkLibPath, "shared", "vndk-core")
392	vndkSpLibPath := filepath.Join(vndkLibPath, "shared", "vndk-sp")
393	vndkCoreLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-core")
394	vndkSpLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-sp")
395
396	variant := "android_vendor.VER_arm64_armv8-a_shared"
397	variant2nd := "android_vendor.VER_arm_armv7-a-neon_shared"
398
399	snapshotSingleton := ctx.SingletonForTests("vndk-snapshot")
400
401	checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", vndkCoreLibPath, variant)
402	checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", vndkCoreLib2ndPath, variant2nd)
403	checkSnapshot(t, ctx, snapshotSingleton, "libvndk_sp", "libvndk_sp-x.so", vndkSpLibPath, variant)
404	checkSnapshot(t, ctx, snapshotSingleton, "libvndk_sp", "libvndk_sp-x.so", vndkSpLib2ndPath, variant2nd)
405
406	snapshotConfigsPath := filepath.Join(snapshotVariantPath, "configs")
407	checkSnapshot(t, ctx, snapshotSingleton, "llndk.libraries.txt", "llndk.libraries.txt", snapshotConfigsPath, "")
408	checkSnapshot(t, ctx, snapshotSingleton, "vndkcore.libraries.txt", "vndkcore.libraries.txt", snapshotConfigsPath, "")
409	checkSnapshot(t, ctx, snapshotSingleton, "vndksp.libraries.txt", "vndksp.libraries.txt", snapshotConfigsPath, "")
410	checkSnapshot(t, ctx, snapshotSingleton, "vndkprivate.libraries.txt", "vndkprivate.libraries.txt", snapshotConfigsPath, "")
411
412	checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{
413		"LLNDK: libc.so",
414		"LLNDK: libdl.so",
415		"LLNDK: libft2.so",
416		"LLNDK: libm.so",
417		"VNDK-SP: libc++.so",
418		"VNDK-SP: libvndk_sp-x.so",
419		"VNDK-SP: libvndk_sp_private-x.so",
420		"VNDK-core: libvndk-private.so",
421		"VNDK-core: libvndk.so",
422		"VNDK-private: libft2.so",
423		"VNDK-private: libvndk-private.so",
424		"VNDK-private: libvndk_sp_private-x.so",
425	})
426	checkVndkLibrariesOutput(t, ctx, "llndk.libraries.txt", []string{"libc.so", "libdl.so", "libft2.so", "libm.so"})
427	checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt", []string{"libvndk-private.so", "libvndk.so"})
428	checkVndkLibrariesOutput(t, ctx, "vndkprivate.libraries.txt", []string{"libft2.so", "libvndk-private.so", "libvndk_sp_private-x.so"})
429	checkVndkLibrariesOutput(t, ctx, "vndksp.libraries.txt", []string{"libc++.so", "libvndk_sp-x.so", "libvndk_sp_private-x.so"})
430	checkVndkLibrariesOutput(t, ctx, "vndkcorevariant.libraries.txt", nil)
431}
432
433func TestVndkWithHostSupported(t *testing.T) {
434	ctx := testCc(t, `
435		cc_library {
436			name: "libvndk_host_supported",
437			vendor_available: true,
438			vndk: {
439				enabled: true,
440			},
441			host_supported: true,
442		}
443
444		cc_library {
445			name: "libvndk_host_supported_but_disabled_on_device",
446			vendor_available: true,
447			vndk: {
448				enabled: true,
449			},
450			host_supported: true,
451			enabled: false,
452			target: {
453				host: {
454					enabled: true,
455				}
456			}
457		}
458
459		vndk_libraries_txt {
460			name: "vndkcore.libraries.txt",
461		}
462	`)
463
464	checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt", []string{"libvndk_host_supported.so"})
465}
466
467func TestVndkLibrariesTxtAndroidMk(t *testing.T) {
468	bp := `
469		vndk_libraries_txt {
470			name: "llndk.libraries.txt",
471		}`
472	config := TestConfig(buildDir, android.Android, nil, bp, nil)
473	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
474	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
475	ctx := testCcWithConfig(t, config)
476
477	module := ctx.ModuleForTests("llndk.libraries.txt", "")
478	entries := android.AndroidMkEntriesForTest(t, config, "", module.Module())[0]
479	assertArrayString(t, entries.EntryMap["LOCAL_MODULE_STEM"], []string{"llndk.libraries.VER.txt"})
480}
481
482func TestVndkUsingCoreVariant(t *testing.T) {
483	bp := `
484		cc_library {
485			name: "libvndk",
486			vendor_available: true,
487			vndk: {
488				enabled: true,
489			},
490			nocrt: true,
491		}
492
493		cc_library {
494			name: "libvndk_sp",
495			vendor_available: true,
496			vndk: {
497				enabled: true,
498				support_system_process: true,
499			},
500			nocrt: true,
501		}
502
503		cc_library {
504			name: "libvndk2",
505			vendor_available: false,
506			vndk: {
507				enabled: true,
508			},
509			nocrt: true,
510		}
511
512		vndk_libraries_txt {
513			name: "vndkcorevariant.libraries.txt",
514		}
515	`
516
517	config := TestConfig(buildDir, android.Android, nil, bp, nil)
518	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
519	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
520	config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
521
522	setVndkMustUseVendorVariantListForTest(config, []string{"libvndk"})
523
524	ctx := testCcWithConfig(t, config)
525
526	checkVndkLibrariesOutput(t, ctx, "vndkcorevariant.libraries.txt", []string{"libc++.so", "libvndk2.so", "libvndk_sp.so"})
527}
528
529func TestDataLibs(t *testing.T) {
530	bp := `
531		cc_test_library {
532			name: "test_lib",
533			srcs: ["test_lib.cpp"],
534			gtest: false,
535		}
536
537		cc_test {
538			name: "main_test",
539			data_libs: ["test_lib"],
540			gtest: false,
541		}
542 `
543
544	config := TestConfig(buildDir, android.Android, nil, bp, nil)
545	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
546	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
547	config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
548
549	ctx := testCcWithConfig(t, config)
550	module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
551	testBinary := module.(*Module).linker.(*testBinary)
552	outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
553	if err != nil {
554		t.Errorf("Expected cc_test to produce output files, error: %s", err)
555		return
556	}
557	if len(outputFiles) != 1 {
558		t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
559		return
560	}
561	if len(testBinary.dataPaths()) != 1 {
562		t.Errorf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths())
563		return
564	}
565
566	outputPath := outputFiles[0].String()
567	testBinaryPath := testBinary.dataPaths()[0].SrcPath.String()
568
569	if !strings.HasSuffix(outputPath, "/main_test") {
570		t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
571		return
572	}
573	if !strings.HasSuffix(testBinaryPath, "/test_lib.so") {
574		t.Errorf("expected test data file to be 'test_lib.so', but was '%s'", testBinaryPath)
575		return
576	}
577}
578
579func TestDataLibsRelativeInstallPath(t *testing.T) {
580	bp := `
581		cc_test_library {
582			name: "test_lib",
583			srcs: ["test_lib.cpp"],
584			relative_install_path: "foo/bar/baz",
585			gtest: false,
586		}
587
588		cc_test {
589			name: "main_test",
590			data_libs: ["test_lib"],
591			gtest: false,
592		}
593 `
594
595	config := TestConfig(buildDir, android.Android, nil, bp, nil)
596	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
597	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
598	config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
599
600	ctx := testCcWithConfig(t, config)
601	module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
602	testBinary := module.(*Module).linker.(*testBinary)
603	outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
604	if err != nil {
605		t.Fatalf("Expected cc_test to produce output files, error: %s", err)
606	}
607	if len(outputFiles) != 1 {
608		t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
609	}
610	if len(testBinary.dataPaths()) != 1 {
611		t.Errorf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths())
612	}
613
614	outputPath := outputFiles[0].String()
615
616	if !strings.HasSuffix(outputPath, "/main_test") {
617		t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
618	}
619	entries := android.AndroidMkEntriesForTest(t, config, "", module)[0]
620	if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
621		t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
622			" but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
623	}
624}
625
626func TestVndkWhenVndkVersionIsNotSet(t *testing.T) {
627	ctx := testCcNoVndk(t, `
628		cc_library {
629			name: "libvndk",
630			vendor_available: true,
631			vndk: {
632				enabled: true,
633			},
634			nocrt: true,
635		}
636	`)
637
638	checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{
639		"LLNDK: libc.so",
640		"LLNDK: libdl.so",
641		"LLNDK: libft2.so",
642		"LLNDK: libm.so",
643		"VNDK-SP: libc++.so",
644		"VNDK-core: libvndk.so",
645		"VNDK-private: libft2.so",
646	})
647}
648
649func TestVndkDepError(t *testing.T) {
650	// Check whether an error is emitted when a VNDK lib depends on a system lib.
651	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
652		cc_library {
653			name: "libvndk",
654			vendor_available: true,
655			vndk: {
656				enabled: true,
657			},
658			shared_libs: ["libfwk"],  // Cause error
659			nocrt: true,
660		}
661
662		cc_library {
663			name: "libfwk",
664			nocrt: true,
665		}
666	`)
667
668	// Check whether an error is emitted when a VNDK lib depends on a vendor lib.
669	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
670		cc_library {
671			name: "libvndk",
672			vendor_available: true,
673			vndk: {
674				enabled: true,
675			},
676			shared_libs: ["libvendor"],  // Cause error
677			nocrt: true,
678		}
679
680		cc_library {
681			name: "libvendor",
682			vendor: true,
683			nocrt: true,
684		}
685	`)
686
687	// Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
688	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
689		cc_library {
690			name: "libvndk_sp",
691			vendor_available: true,
692			vndk: {
693				enabled: true,
694				support_system_process: true,
695			},
696			shared_libs: ["libfwk"],  // Cause error
697			nocrt: true,
698		}
699
700		cc_library {
701			name: "libfwk",
702			nocrt: true,
703		}
704	`)
705
706	// Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
707	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
708		cc_library {
709			name: "libvndk_sp",
710			vendor_available: true,
711			vndk: {
712				enabled: true,
713				support_system_process: true,
714			},
715			shared_libs: ["libvendor"],  // Cause error
716			nocrt: true,
717		}
718
719		cc_library {
720			name: "libvendor",
721			vendor: true,
722			nocrt: true,
723		}
724	`)
725
726	// Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
727	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
728		cc_library {
729			name: "libvndk_sp",
730			vendor_available: true,
731			vndk: {
732				enabled: true,
733				support_system_process: true,
734			},
735			shared_libs: ["libvndk"],  // Cause error
736			nocrt: true,
737		}
738
739		cc_library {
740			name: "libvndk",
741			vendor_available: true,
742			vndk: {
743				enabled: true,
744			},
745			nocrt: true,
746		}
747	`)
748
749	// Check whether an error is emitted when a VNDK lib depends on a non-VNDK lib.
750	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
751		cc_library {
752			name: "libvndk",
753			vendor_available: true,
754			vndk: {
755				enabled: true,
756			},
757			shared_libs: ["libnonvndk"],
758			nocrt: true,
759		}
760
761		cc_library {
762			name: "libnonvndk",
763			vendor_available: true,
764			nocrt: true,
765		}
766	`)
767
768	// Check whether an error is emitted when a VNDK-private lib depends on a non-VNDK lib.
769	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
770		cc_library {
771			name: "libvndkprivate",
772			vendor_available: false,
773			vndk: {
774				enabled: true,
775			},
776			shared_libs: ["libnonvndk"],
777			nocrt: true,
778		}
779
780		cc_library {
781			name: "libnonvndk",
782			vendor_available: true,
783			nocrt: true,
784		}
785	`)
786
787	// Check whether an error is emitted when a VNDK-sp lib depends on a non-VNDK lib.
788	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
789		cc_library {
790			name: "libvndksp",
791			vendor_available: true,
792			vndk: {
793				enabled: true,
794				support_system_process: true,
795			},
796			shared_libs: ["libnonvndk"],
797			nocrt: true,
798		}
799
800		cc_library {
801			name: "libnonvndk",
802			vendor_available: true,
803			nocrt: true,
804		}
805	`)
806
807	// Check whether an error is emitted when a VNDK-sp-private lib depends on a non-VNDK lib.
808	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
809		cc_library {
810			name: "libvndkspprivate",
811			vendor_available: false,
812			vndk: {
813				enabled: true,
814				support_system_process: true,
815			},
816			shared_libs: ["libnonvndk"],
817			nocrt: true,
818		}
819
820		cc_library {
821			name: "libnonvndk",
822			vendor_available: true,
823			nocrt: true,
824		}
825	`)
826}
827
828func TestDoubleLoadbleDep(t *testing.T) {
829	// okay to link : LLNDK -> double_loadable VNDK
830	testCc(t, `
831		cc_library {
832			name: "libllndk",
833			shared_libs: ["libdoubleloadable"],
834		}
835
836		llndk_library {
837			name: "libllndk",
838			symbol_file: "",
839		}
840
841		cc_library {
842			name: "libdoubleloadable",
843			vendor_available: true,
844			vndk: {
845				enabled: true,
846			},
847			double_loadable: true,
848		}
849	`)
850	// okay to link : LLNDK -> VNDK-SP
851	testCc(t, `
852		cc_library {
853			name: "libllndk",
854			shared_libs: ["libvndksp"],
855		}
856
857		llndk_library {
858			name: "libllndk",
859			symbol_file: "",
860		}
861
862		cc_library {
863			name: "libvndksp",
864			vendor_available: true,
865			vndk: {
866				enabled: true,
867				support_system_process: true,
868			},
869		}
870	`)
871	// okay to link : double_loadable -> double_loadable
872	testCc(t, `
873		cc_library {
874			name: "libdoubleloadable1",
875			shared_libs: ["libdoubleloadable2"],
876			vendor_available: true,
877			double_loadable: true,
878		}
879
880		cc_library {
881			name: "libdoubleloadable2",
882			vendor_available: true,
883			double_loadable: true,
884		}
885	`)
886	// okay to link : double_loadable VNDK -> double_loadable VNDK private
887	testCc(t, `
888		cc_library {
889			name: "libdoubleloadable",
890			vendor_available: true,
891			vndk: {
892				enabled: true,
893			},
894			double_loadable: true,
895			shared_libs: ["libnondoubleloadable"],
896		}
897
898		cc_library {
899			name: "libnondoubleloadable",
900			vendor_available: false,
901			vndk: {
902				enabled: true,
903			},
904			double_loadable: true,
905		}
906	`)
907	// okay to link : LLNDK -> core-only -> vendor_available & double_loadable
908	testCc(t, `
909		cc_library {
910			name: "libllndk",
911			shared_libs: ["libcoreonly"],
912		}
913
914		llndk_library {
915			name: "libllndk",
916			symbol_file: "",
917		}
918
919		cc_library {
920			name: "libcoreonly",
921			shared_libs: ["libvendoravailable"],
922		}
923
924		// indirect dependency of LLNDK
925		cc_library {
926			name: "libvendoravailable",
927			vendor_available: true,
928			double_loadable: true,
929		}
930	`)
931}
932
933func TestVendorSnapshot(t *testing.T) {
934	bp := `
935	cc_library {
936		name: "libvndk",
937		vendor_available: true,
938		vndk: {
939			enabled: true,
940		},
941		nocrt: true,
942	}
943
944	cc_library {
945		name: "libvendor",
946		vendor: true,
947		nocrt: true,
948	}
949
950	cc_library {
951		name: "libvendor_available",
952		vendor_available: true,
953		nocrt: true,
954	}
955
956	cc_library_headers {
957		name: "libvendor_headers",
958		vendor_available: true,
959		nocrt: true,
960	}
961
962	cc_binary {
963		name: "vendor_bin",
964		vendor: true,
965		nocrt: true,
966	}
967
968	cc_binary {
969		name: "vendor_available_bin",
970		vendor_available: true,
971		nocrt: true,
972	}
973
974	toolchain_library {
975		name: "libb",
976		vendor_available: true,
977		src: "libb.a",
978	}
979
980	cc_object {
981		name: "obj",
982		vendor_available: true,
983	}
984`
985	config := TestConfig(buildDir, android.Android, nil, bp, nil)
986	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
987	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
988	ctx := testCcWithConfig(t, config)
989
990	// Check Vendor snapshot output.
991
992	snapshotDir := "vendor-snapshot"
993	snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
994	snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
995
996	var jsonFiles []string
997
998	for _, arch := range [][]string{
999		[]string{"arm64", "armv8-a"},
1000		[]string{"arm", "armv7-a-neon"},
1001	} {
1002		archType := arch[0]
1003		archVariant := arch[1]
1004		archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
1005
1006		// For shared libraries, only non-VNDK vendor_available modules are captured
1007		sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant)
1008		sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
1009		checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
1010		checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant)
1011		jsonFiles = append(jsonFiles,
1012			filepath.Join(sharedDir, "libvendor.so.json"),
1013			filepath.Join(sharedDir, "libvendor_available.so.json"))
1014
1015		// For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
1016		staticVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static", archType, archVariant)
1017		staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
1018		checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
1019		checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.a", staticDir, staticVariant)
1020		checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.a", staticDir, staticVariant)
1021		checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.a", staticDir, staticVariant)
1022		jsonFiles = append(jsonFiles,
1023			filepath.Join(staticDir, "libb.a.json"),
1024			filepath.Join(staticDir, "libvndk.a.json"),
1025			filepath.Join(staticDir, "libvendor.a.json"),
1026			filepath.Join(staticDir, "libvendor_available.a.json"))
1027
1028		// For binary executables, all vendor:true and vendor_available modules are captured.
1029		if archType == "arm64" {
1030			binaryVariant := fmt.Sprintf("android_vendor.VER_%s_%s", archType, archVariant)
1031			binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
1032			checkSnapshot(t, ctx, snapshotSingleton, "vendor_bin", "vendor_bin", binaryDir, binaryVariant)
1033			checkSnapshot(t, ctx, snapshotSingleton, "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant)
1034			jsonFiles = append(jsonFiles,
1035				filepath.Join(binaryDir, "vendor_bin.json"),
1036				filepath.Join(binaryDir, "vendor_available_bin.json"))
1037		}
1038
1039		// For header libraries, all vendor:true and vendor_available modules are captured.
1040		headerDir := filepath.Join(snapshotVariantPath, archDir, "header")
1041		jsonFiles = append(jsonFiles, filepath.Join(headerDir, "libvendor_headers.json"))
1042
1043		// For object modules, all vendor:true and vendor_available modules are captured.
1044		objectVariant := fmt.Sprintf("android_vendor.VER_%s_%s", archType, archVariant)
1045		objectDir := filepath.Join(snapshotVariantPath, archDir, "object")
1046		checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant)
1047		jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json"))
1048	}
1049
1050	for _, jsonFile := range jsonFiles {
1051		// verify all json files exist
1052		if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
1053			t.Errorf("%q expected but not found", jsonFile)
1054		}
1055	}
1056}
1057
1058func TestDoubleLoadableDepError(t *testing.T) {
1059	// Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib.
1060	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
1061		cc_library {
1062			name: "libllndk",
1063			shared_libs: ["libnondoubleloadable"],
1064		}
1065
1066		llndk_library {
1067			name: "libllndk",
1068			symbol_file: "",
1069		}
1070
1071		cc_library {
1072			name: "libnondoubleloadable",
1073			vendor_available: true,
1074			vndk: {
1075				enabled: true,
1076			},
1077		}
1078	`)
1079
1080	// Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib.
1081	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
1082		cc_library {
1083			name: "libllndk",
1084			no_libcrt: true,
1085			shared_libs: ["libnondoubleloadable"],
1086		}
1087
1088		llndk_library {
1089			name: "libllndk",
1090			symbol_file: "",
1091		}
1092
1093		cc_library {
1094			name: "libnondoubleloadable",
1095			vendor_available: true,
1096		}
1097	`)
1098
1099	// Check whether an error is emitted when a double_loadable lib depends on a non-double_loadable vendor_available lib.
1100	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
1101		cc_library {
1102			name: "libdoubleloadable",
1103			vendor_available: true,
1104			double_loadable: true,
1105			shared_libs: ["libnondoubleloadable"],
1106		}
1107
1108		cc_library {
1109			name: "libnondoubleloadable",
1110			vendor_available: true,
1111		}
1112	`)
1113
1114	// Check whether an error is emitted when a double_loadable lib depends on a non-double_loadable VNDK lib.
1115	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
1116		cc_library {
1117			name: "libdoubleloadable",
1118			vendor_available: true,
1119			double_loadable: true,
1120			shared_libs: ["libnondoubleloadable"],
1121		}
1122
1123		cc_library {
1124			name: "libnondoubleloadable",
1125			vendor_available: true,
1126			vndk: {
1127				enabled: true,
1128			},
1129		}
1130	`)
1131
1132	// Check whether an error is emitted when a double_loadable VNDK depends on a non-double_loadable VNDK private lib.
1133	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
1134		cc_library {
1135			name: "libdoubleloadable",
1136			vendor_available: true,
1137			vndk: {
1138				enabled: true,
1139			},
1140			double_loadable: true,
1141			shared_libs: ["libnondoubleloadable"],
1142		}
1143
1144		cc_library {
1145			name: "libnondoubleloadable",
1146			vendor_available: false,
1147			vndk: {
1148				enabled: true,
1149			},
1150		}
1151	`)
1152
1153	// Check whether an error is emitted when a LLNDK depends on a non-double_loadable indirectly.
1154	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
1155		cc_library {
1156			name: "libllndk",
1157			shared_libs: ["libcoreonly"],
1158		}
1159
1160		llndk_library {
1161			name: "libllndk",
1162			symbol_file: "",
1163		}
1164
1165		cc_library {
1166			name: "libcoreonly",
1167			shared_libs: ["libvendoravailable"],
1168		}
1169
1170		// indirect dependency of LLNDK
1171		cc_library {
1172			name: "libvendoravailable",
1173			vendor_available: true,
1174		}
1175	`)
1176}
1177
1178func TestVndkExt(t *testing.T) {
1179	// This test checks the VNDK-Ext properties.
1180	bp := `
1181		cc_library {
1182			name: "libvndk",
1183			vendor_available: true,
1184			vndk: {
1185				enabled: true,
1186			},
1187			nocrt: true,
1188		}
1189		cc_library {
1190			name: "libvndk2",
1191			vendor_available: true,
1192			vndk: {
1193				enabled: true,
1194			},
1195			target: {
1196				vendor: {
1197					suffix: "-suffix",
1198				},
1199			},
1200			nocrt: true,
1201		}
1202
1203		cc_library {
1204			name: "libvndk_ext",
1205			vendor: true,
1206			vndk: {
1207				enabled: true,
1208				extends: "libvndk",
1209			},
1210			nocrt: true,
1211		}
1212
1213		cc_library {
1214			name: "libvndk2_ext",
1215			vendor: true,
1216			vndk: {
1217				enabled: true,
1218				extends: "libvndk2",
1219			},
1220			nocrt: true,
1221		}
1222
1223		cc_library {
1224			name: "libvndk_ext_product",
1225			product_specific: true,
1226			vndk: {
1227				enabled: true,
1228				extends: "libvndk",
1229			},
1230			nocrt: true,
1231		}
1232
1233		cc_library {
1234			name: "libvndk2_ext_product",
1235			product_specific: true,
1236			vndk: {
1237				enabled: true,
1238				extends: "libvndk2",
1239			},
1240			nocrt: true,
1241		}
1242	`
1243	config := TestConfig(buildDir, android.Android, nil, bp, nil)
1244	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
1245	config.TestProductVariables.ProductVndkVersion = StringPtr("current")
1246	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
1247
1248	ctx := testCcWithConfig(t, config)
1249
1250	checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk", vendorVariant)
1251	checkVndkModule(t, ctx, "libvndk_ext_product", "vndk", false, "libvndk", productVariant)
1252
1253	mod_vendor := ctx.ModuleForTests("libvndk2_ext", vendorVariant).Module().(*Module)
1254	assertString(t, mod_vendor.outputFile.Path().Base(), "libvndk2-suffix.so")
1255
1256	mod_product := ctx.ModuleForTests("libvndk2_ext_product", productVariant).Module().(*Module)
1257	assertString(t, mod_product.outputFile.Path().Base(), "libvndk2-suffix.so")
1258}
1259
1260func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
1261	// This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
1262	ctx := testCcNoVndk(t, `
1263		cc_library {
1264			name: "libvndk",
1265			vendor_available: true,
1266			vndk: {
1267				enabled: true,
1268			},
1269			nocrt: true,
1270		}
1271
1272		cc_library {
1273			name: "libvndk_ext",
1274			vendor: true,
1275			vndk: {
1276				enabled: true,
1277				extends: "libvndk",
1278			},
1279			nocrt: true,
1280		}
1281	`)
1282
1283	// Ensures that the core variant of "libvndk_ext" can be found.
1284	mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
1285	if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
1286		t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
1287	}
1288}
1289
1290func TestVndkExtWithoutProductVndkVersion(t *testing.T) {
1291	// This test checks the VNDK-Ext properties when PRODUCT_PRODUCT_VNDK_VERSION is not set.
1292	ctx := testCc(t, `
1293		cc_library {
1294			name: "libvndk",
1295			vendor_available: true,
1296			vndk: {
1297				enabled: true,
1298			},
1299			nocrt: true,
1300		}
1301
1302		cc_library {
1303			name: "libvndk_ext_product",
1304			product_specific: true,
1305			vndk: {
1306				enabled: true,
1307				extends: "libvndk",
1308			},
1309			nocrt: true,
1310		}
1311	`)
1312
1313	// Ensures that the core variant of "libvndk_ext_product" can be found.
1314	mod := ctx.ModuleForTests("libvndk_ext_product", coreVariant).Module().(*Module)
1315	if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
1316		t.Errorf("\"libvndk_ext_product\" must extend from \"libvndk\" but get %q", extends)
1317	}
1318}
1319
1320func TestVndkExtError(t *testing.T) {
1321	// This test ensures an error is emitted in ill-formed vndk-ext definition.
1322	testCcError(t, "must set `vendor: true` or `product_specific: true` to set `extends: \".*\"`", `
1323		cc_library {
1324			name: "libvndk",
1325			vendor_available: true,
1326			vndk: {
1327				enabled: true,
1328			},
1329			nocrt: true,
1330		}
1331
1332		cc_library {
1333			name: "libvndk_ext",
1334			vndk: {
1335				enabled: true,
1336				extends: "libvndk",
1337			},
1338			nocrt: true,
1339		}
1340	`)
1341
1342	testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
1343		cc_library {
1344			name: "libvndk",
1345			vendor_available: true,
1346			vndk: {
1347				enabled: true,
1348			},
1349			nocrt: true,
1350		}
1351
1352		cc_library {
1353			name: "libvndk_ext",
1354			vendor: true,
1355			vndk: {
1356				enabled: true,
1357			},
1358			nocrt: true,
1359		}
1360	`)
1361
1362	testCcErrorProductVndk(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
1363		cc_library {
1364			name: "libvndk",
1365			vendor_available: true,
1366			vndk: {
1367				enabled: true,
1368			},
1369			nocrt: true,
1370		}
1371
1372		cc_library {
1373			name: "libvndk_ext_product",
1374			product_specific: true,
1375			vndk: {
1376				enabled: true,
1377			},
1378			nocrt: true,
1379		}
1380	`)
1381
1382	testCcErrorProductVndk(t, "must not set at the same time as `vndk: {extends: \"\\.\\.\\.\"}`", `
1383		cc_library {
1384			name: "libvndk",
1385			vendor_available: true,
1386			vndk: {
1387				enabled: true,
1388			},
1389			nocrt: true,
1390		}
1391
1392		cc_library {
1393			name: "libvndk_ext_product",
1394			product_specific: true,
1395			vendor_available: true,
1396			vndk: {
1397				enabled: true,
1398				extends: "libvndk",
1399			},
1400			nocrt: true,
1401		}
1402	`)
1403}
1404
1405func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
1406	// This test ensures an error is emitted for inconsistent support_system_process.
1407	testCcError(t, "module \".*\" with mismatched support_system_process", `
1408		cc_library {
1409			name: "libvndk",
1410			vendor_available: true,
1411			vndk: {
1412				enabled: true,
1413			},
1414			nocrt: true,
1415		}
1416
1417		cc_library {
1418			name: "libvndk_sp_ext",
1419			vendor: true,
1420			vndk: {
1421				enabled: true,
1422				extends: "libvndk",
1423				support_system_process: true,
1424			},
1425			nocrt: true,
1426		}
1427	`)
1428
1429	testCcError(t, "module \".*\" with mismatched support_system_process", `
1430		cc_library {
1431			name: "libvndk_sp",
1432			vendor_available: true,
1433			vndk: {
1434				enabled: true,
1435				support_system_process: true,
1436			},
1437			nocrt: true,
1438		}
1439
1440		cc_library {
1441			name: "libvndk_ext",
1442			vendor: true,
1443			vndk: {
1444				enabled: true,
1445				extends: "libvndk_sp",
1446			},
1447			nocrt: true,
1448		}
1449	`)
1450}
1451
1452func TestVndkExtVendorAvailableFalseError(t *testing.T) {
1453	// This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
1454	// with `vendor_available: false`.
1455	testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
1456		cc_library {
1457			name: "libvndk",
1458			vendor_available: false,
1459			vndk: {
1460				enabled: true,
1461			},
1462			nocrt: true,
1463		}
1464
1465		cc_library {
1466			name: "libvndk_ext",
1467			vendor: true,
1468			vndk: {
1469				enabled: true,
1470				extends: "libvndk",
1471			},
1472			nocrt: true,
1473		}
1474	`)
1475
1476	testCcErrorProductVndk(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
1477		cc_library {
1478			name: "libvndk",
1479			vendor_available: false,
1480			vndk: {
1481				enabled: true,
1482			},
1483			nocrt: true,
1484		}
1485
1486		cc_library {
1487			name: "libvndk_ext_product",
1488			product_specific: true,
1489			vndk: {
1490				enabled: true,
1491				extends: "libvndk",
1492			},
1493			nocrt: true,
1494		}
1495	`)
1496}
1497
1498func TestVendorModuleUseVndkExt(t *testing.T) {
1499	// This test ensures a vendor module can depend on a VNDK-Ext library.
1500	testCc(t, `
1501		cc_library {
1502			name: "libvndk",
1503			vendor_available: true,
1504			vndk: {
1505				enabled: true,
1506			},
1507			nocrt: true,
1508		}
1509
1510		cc_library {
1511			name: "libvndk_ext",
1512			vendor: true,
1513			vndk: {
1514				enabled: true,
1515				extends: "libvndk",
1516			},
1517			nocrt: true,
1518		}
1519
1520		cc_library {
1521			name: "libvndk_sp",
1522			vendor_available: true,
1523			vndk: {
1524				enabled: true,
1525				support_system_process: true,
1526			},
1527			nocrt: true,
1528		}
1529
1530		cc_library {
1531			name: "libvndk_sp_ext",
1532			vendor: true,
1533			vndk: {
1534				enabled: true,
1535				extends: "libvndk_sp",
1536				support_system_process: true,
1537			},
1538			nocrt: true,
1539		}
1540
1541		cc_library {
1542			name: "libvendor",
1543			vendor: true,
1544			shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
1545			nocrt: true,
1546		}
1547	`)
1548}
1549
1550func TestVndkExtUseVendorLib(t *testing.T) {
1551	// This test ensures a VNDK-Ext library can depend on a vendor library.
1552	testCc(t, `
1553		cc_library {
1554			name: "libvndk",
1555			vendor_available: true,
1556			vndk: {
1557				enabled: true,
1558			},
1559			nocrt: true,
1560		}
1561
1562		cc_library {
1563			name: "libvndk_ext",
1564			vendor: true,
1565			vndk: {
1566				enabled: true,
1567				extends: "libvndk",
1568			},
1569			shared_libs: ["libvendor"],
1570			nocrt: true,
1571		}
1572
1573		cc_library {
1574			name: "libvendor",
1575			vendor: true,
1576			nocrt: true,
1577		}
1578	`)
1579
1580	// This test ensures a VNDK-SP-Ext library can depend on a vendor library.
1581	testCc(t, `
1582		cc_library {
1583			name: "libvndk_sp",
1584			vendor_available: true,
1585			vndk: {
1586				enabled: true,
1587				support_system_process: true,
1588			},
1589			nocrt: true,
1590		}
1591
1592		cc_library {
1593			name: "libvndk_sp_ext",
1594			vendor: true,
1595			vndk: {
1596				enabled: true,
1597				extends: "libvndk_sp",
1598				support_system_process: true,
1599			},
1600			shared_libs: ["libvendor"],  // Cause an error
1601			nocrt: true,
1602		}
1603
1604		cc_library {
1605			name: "libvendor",
1606			vendor: true,
1607			nocrt: true,
1608		}
1609	`)
1610}
1611
1612func TestProductVndkExtDependency(t *testing.T) {
1613	bp := `
1614		cc_library {
1615			name: "libvndk",
1616			vendor_available: true,
1617			vndk: {
1618				enabled: true,
1619			},
1620			nocrt: true,
1621		}
1622
1623		cc_library {
1624			name: "libvndk_ext_product",
1625			product_specific: true,
1626			vndk: {
1627				enabled: true,
1628				extends: "libvndk",
1629			},
1630			shared_libs: ["libproduct_for_vndklibs"],
1631			nocrt: true,
1632		}
1633
1634		cc_library {
1635			name: "libvndk_sp",
1636			vendor_available: true,
1637			vndk: {
1638				enabled: true,
1639				support_system_process: true,
1640			},
1641			nocrt: true,
1642		}
1643
1644		cc_library {
1645			name: "libvndk_sp_ext_product",
1646			product_specific: true,
1647			vndk: {
1648				enabled: true,
1649				extends: "libvndk_sp",
1650				support_system_process: true,
1651			},
1652			shared_libs: ["libproduct_for_vndklibs"],
1653			nocrt: true,
1654		}
1655
1656		cc_library {
1657			name: "libproduct",
1658			product_specific: true,
1659			shared_libs: ["libvndk_ext_product", "libvndk_sp_ext_product"],
1660			nocrt: true,
1661		}
1662
1663		cc_library {
1664			name: "libproduct_for_vndklibs",
1665			product_specific: true,
1666			nocrt: true,
1667		}
1668	`
1669	config := TestConfig(buildDir, android.Android, nil, bp, nil)
1670	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
1671	config.TestProductVariables.ProductVndkVersion = StringPtr("current")
1672	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
1673
1674	testCcWithConfig(t, config)
1675}
1676
1677func TestVndkSpExtUseVndkError(t *testing.T) {
1678	// This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
1679	// library.
1680	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1681		cc_library {
1682			name: "libvndk",
1683			vendor_available: true,
1684			vndk: {
1685				enabled: true,
1686			},
1687			nocrt: true,
1688		}
1689
1690		cc_library {
1691			name: "libvndk_sp",
1692			vendor_available: true,
1693			vndk: {
1694				enabled: true,
1695				support_system_process: true,
1696			},
1697			nocrt: true,
1698		}
1699
1700		cc_library {
1701			name: "libvndk_sp_ext",
1702			vendor: true,
1703			vndk: {
1704				enabled: true,
1705				extends: "libvndk_sp",
1706				support_system_process: true,
1707			},
1708			shared_libs: ["libvndk"],  // Cause an error
1709			nocrt: true,
1710		}
1711	`)
1712
1713	// This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
1714	// library.
1715	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1716		cc_library {
1717			name: "libvndk",
1718			vendor_available: true,
1719			vndk: {
1720				enabled: true,
1721			},
1722			nocrt: true,
1723		}
1724
1725		cc_library {
1726			name: "libvndk_ext",
1727			vendor: true,
1728			vndk: {
1729				enabled: true,
1730				extends: "libvndk",
1731			},
1732			nocrt: true,
1733		}
1734
1735		cc_library {
1736			name: "libvndk_sp",
1737			vendor_available: true,
1738			vndk: {
1739				enabled: true,
1740				support_system_process: true,
1741			},
1742			nocrt: true,
1743		}
1744
1745		cc_library {
1746			name: "libvndk_sp_ext",
1747			vendor: true,
1748			vndk: {
1749				enabled: true,
1750				extends: "libvndk_sp",
1751				support_system_process: true,
1752			},
1753			shared_libs: ["libvndk_ext"],  // Cause an error
1754			nocrt: true,
1755		}
1756	`)
1757}
1758
1759func TestVndkUseVndkExtError(t *testing.T) {
1760	// This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
1761	// VNDK-Ext/VNDK-SP-Ext library.
1762	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1763		cc_library {
1764			name: "libvndk",
1765			vendor_available: true,
1766			vndk: {
1767				enabled: true,
1768			},
1769			nocrt: true,
1770		}
1771
1772		cc_library {
1773			name: "libvndk_ext",
1774			vendor: true,
1775			vndk: {
1776				enabled: true,
1777				extends: "libvndk",
1778			},
1779			nocrt: true,
1780		}
1781
1782		cc_library {
1783			name: "libvndk2",
1784			vendor_available: true,
1785			vndk: {
1786				enabled: true,
1787			},
1788			shared_libs: ["libvndk_ext"],
1789			nocrt: true,
1790		}
1791	`)
1792
1793	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1794		cc_library {
1795			name: "libvndk",
1796			vendor_available: true,
1797			vndk: {
1798				enabled: true,
1799			},
1800			nocrt: true,
1801		}
1802
1803		cc_library {
1804			name: "libvndk_ext",
1805			vendor: true,
1806			vndk: {
1807				enabled: true,
1808				extends: "libvndk",
1809			},
1810			nocrt: true,
1811		}
1812
1813		cc_library {
1814			name: "libvndk2",
1815			vendor_available: true,
1816			vndk: {
1817				enabled: true,
1818			},
1819			target: {
1820				vendor: {
1821					shared_libs: ["libvndk_ext"],
1822				},
1823			},
1824			nocrt: true,
1825		}
1826	`)
1827
1828	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1829		cc_library {
1830			name: "libvndk_sp",
1831			vendor_available: true,
1832			vndk: {
1833				enabled: true,
1834				support_system_process: true,
1835			},
1836			nocrt: true,
1837		}
1838
1839		cc_library {
1840			name: "libvndk_sp_ext",
1841			vendor: true,
1842			vndk: {
1843				enabled: true,
1844				extends: "libvndk_sp",
1845				support_system_process: true,
1846			},
1847			nocrt: true,
1848		}
1849
1850		cc_library {
1851			name: "libvndk_sp_2",
1852			vendor_available: true,
1853			vndk: {
1854				enabled: true,
1855				support_system_process: true,
1856			},
1857			shared_libs: ["libvndk_sp_ext"],
1858			nocrt: true,
1859		}
1860	`)
1861
1862	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1863		cc_library {
1864			name: "libvndk_sp",
1865			vendor_available: true,
1866			vndk: {
1867				enabled: true,
1868			},
1869			nocrt: true,
1870		}
1871
1872		cc_library {
1873			name: "libvndk_sp_ext",
1874			vendor: true,
1875			vndk: {
1876				enabled: true,
1877				extends: "libvndk_sp",
1878			},
1879			nocrt: true,
1880		}
1881
1882		cc_library {
1883			name: "libvndk_sp2",
1884			vendor_available: true,
1885			vndk: {
1886				enabled: true,
1887			},
1888			target: {
1889				vendor: {
1890					shared_libs: ["libvndk_sp_ext"],
1891				},
1892			},
1893			nocrt: true,
1894		}
1895	`)
1896}
1897
1898func TestEnforceProductVndkVersion(t *testing.T) {
1899	bp := `
1900		cc_library {
1901			name: "libllndk",
1902		}
1903		llndk_library {
1904			name: "libllndk",
1905			symbol_file: "",
1906		}
1907		cc_library {
1908			name: "libvndk",
1909			vendor_available: true,
1910			vndk: {
1911				enabled: true,
1912			},
1913			nocrt: true,
1914		}
1915		cc_library {
1916			name: "libvndk_sp",
1917			vendor_available: true,
1918			vndk: {
1919				enabled: true,
1920				support_system_process: true,
1921			},
1922			nocrt: true,
1923		}
1924		cc_library {
1925			name: "libva",
1926			vendor_available: true,
1927			nocrt: true,
1928		}
1929		cc_library {
1930			name: "libproduct_va",
1931			product_specific: true,
1932			vendor_available: true,
1933			nocrt: true,
1934		}
1935		cc_library {
1936			name: "libprod",
1937			product_specific: true,
1938			shared_libs: [
1939				"libllndk",
1940				"libvndk",
1941				"libvndk_sp",
1942				"libva",
1943				"libproduct_va",
1944			],
1945			nocrt: true,
1946		}
1947		cc_library {
1948			name: "libvendor",
1949			vendor: true,
1950			shared_libs: [
1951				"libllndk",
1952				"libvndk",
1953				"libvndk_sp",
1954				"libva",
1955				"libproduct_va",
1956			],
1957			nocrt: true,
1958		}
1959	`
1960
1961	config := TestConfig(buildDir, android.Android, nil, bp, nil)
1962	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
1963	config.TestProductVariables.ProductVndkVersion = StringPtr("current")
1964	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
1965
1966	ctx := testCcWithConfig(t, config)
1967
1968	checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "", productVariant)
1969	checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "", productVariant)
1970}
1971
1972func TestEnforceProductVndkVersionErrors(t *testing.T) {
1973	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.VER", `
1974		cc_library {
1975			name: "libprod",
1976			product_specific: true,
1977			shared_libs: [
1978				"libvendor",
1979			],
1980			nocrt: true,
1981		}
1982		cc_library {
1983			name: "libvendor",
1984			vendor: true,
1985			nocrt: true,
1986		}
1987	`)
1988	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.VER", `
1989		cc_library {
1990			name: "libprod",
1991			product_specific: true,
1992			shared_libs: [
1993				"libsystem",
1994			],
1995			nocrt: true,
1996		}
1997		cc_library {
1998			name: "libsystem",
1999			nocrt: true,
2000		}
2001	`)
2002	testCcErrorProductVndk(t, "Vendor module that is not VNDK should not link to \".*\" which is marked as `vendor_available: false`", `
2003		cc_library {
2004			name: "libprod",
2005			product_specific: true,
2006			shared_libs: [
2007				"libvndk_private",
2008			],
2009			nocrt: true,
2010		}
2011		cc_library {
2012			name: "libvndk_private",
2013			vendor_available: false,
2014			vndk: {
2015				enabled: true,
2016			},
2017			nocrt: true,
2018		}
2019	`)
2020	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.VER", `
2021		cc_library {
2022			name: "libprod",
2023			product_specific: true,
2024			shared_libs: [
2025				"libsystem_ext",
2026			],
2027			nocrt: true,
2028		}
2029		cc_library {
2030			name: "libsystem_ext",
2031			system_ext_specific: true,
2032			nocrt: true,
2033		}
2034	`)
2035	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:", `
2036		cc_library {
2037			name: "libsystem",
2038			shared_libs: [
2039				"libproduct_va",
2040			],
2041			nocrt: true,
2042		}
2043		cc_library {
2044			name: "libproduct_va",
2045			product_specific: true,
2046			vendor_available: true,
2047			nocrt: true,
2048		}
2049	`)
2050}
2051
2052func TestMakeLinkType(t *testing.T) {
2053	bp := `
2054		cc_library {
2055			name: "libvndk",
2056			vendor_available: true,
2057			vndk: {
2058				enabled: true,
2059			},
2060		}
2061		cc_library {
2062			name: "libvndksp",
2063			vendor_available: true,
2064			vndk: {
2065				enabled: true,
2066				support_system_process: true,
2067			},
2068		}
2069		cc_library {
2070			name: "libvndkprivate",
2071			vendor_available: false,
2072			vndk: {
2073				enabled: true,
2074			},
2075		}
2076		cc_library {
2077			name: "libvendor",
2078			vendor: true,
2079		}
2080		cc_library {
2081			name: "libvndkext",
2082			vendor: true,
2083			vndk: {
2084				enabled: true,
2085				extends: "libvndk",
2086			},
2087		}
2088		vndk_prebuilt_shared {
2089			name: "prevndk",
2090			version: "27",
2091			target_arch: "arm",
2092			binder32bit: true,
2093			vendor_available: true,
2094			vndk: {
2095				enabled: true,
2096			},
2097			arch: {
2098				arm: {
2099					srcs: ["liba.so"],
2100				},
2101			},
2102		}
2103		cc_library {
2104			name: "libllndk",
2105		}
2106		llndk_library {
2107			name: "libllndk",
2108			symbol_file: "",
2109		}
2110		cc_library {
2111			name: "libllndkprivate",
2112		}
2113		llndk_library {
2114			name: "libllndkprivate",
2115			vendor_available: false,
2116			symbol_file: "",
2117		}`
2118
2119	config := TestConfig(buildDir, android.Android, nil, bp, nil)
2120	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
2121	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
2122	// native:vndk
2123	ctx := testCcWithConfig(t, config)
2124
2125	assertMapKeys(t, vndkCoreLibraries(config),
2126		[]string{"libvndk", "libvndkprivate"})
2127	assertMapKeys(t, vndkSpLibraries(config),
2128		[]string{"libc++", "libvndksp"})
2129	assertMapKeys(t, llndkLibraries(config),
2130		[]string{"libc", "libdl", "libft2", "libllndk", "libllndkprivate", "libm"})
2131	assertMapKeys(t, vndkPrivateLibraries(config),
2132		[]string{"libft2", "libllndkprivate", "libvndkprivate"})
2133
2134	vendorVariant27 := "android_vendor.27_arm64_armv8-a_shared"
2135
2136	tests := []struct {
2137		variant  string
2138		name     string
2139		expected string
2140	}{
2141		{vendorVariant, "libvndk", "native:vndk"},
2142		{vendorVariant, "libvndksp", "native:vndk"},
2143		{vendorVariant, "libvndkprivate", "native:vndk_private"},
2144		{vendorVariant, "libvendor", "native:vendor"},
2145		{vendorVariant, "libvndkext", "native:vendor"},
2146		{vendorVariant, "libllndk.llndk", "native:vndk"},
2147		{vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vndk"},
2148		{coreVariant, "libvndk", "native:platform"},
2149		{coreVariant, "libvndkprivate", "native:platform"},
2150		{coreVariant, "libllndk", "native:platform"},
2151	}
2152	for _, test := range tests {
2153		t.Run(test.name, func(t *testing.T) {
2154			module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module)
2155			assertString(t, module.makeLinkType, test.expected)
2156		})
2157	}
2158}
2159
2160var (
2161	str11 = "01234567891"
2162	str10 = str11[:10]
2163	str9  = str11[:9]
2164	str5  = str11[:5]
2165	str4  = str11[:4]
2166)
2167
2168var splitListForSizeTestCases = []struct {
2169	in   []string
2170	out  [][]string
2171	size int
2172}{
2173	{
2174		in:   []string{str10},
2175		out:  [][]string{{str10}},
2176		size: 10,
2177	},
2178	{
2179		in:   []string{str9},
2180		out:  [][]string{{str9}},
2181		size: 10,
2182	},
2183	{
2184		in:   []string{str5},
2185		out:  [][]string{{str5}},
2186		size: 10,
2187	},
2188	{
2189		in:   []string{str11},
2190		out:  nil,
2191		size: 10,
2192	},
2193	{
2194		in:   []string{str10, str10},
2195		out:  [][]string{{str10}, {str10}},
2196		size: 10,
2197	},
2198	{
2199		in:   []string{str9, str10},
2200		out:  [][]string{{str9}, {str10}},
2201		size: 10,
2202	},
2203	{
2204		in:   []string{str10, str9},
2205		out:  [][]string{{str10}, {str9}},
2206		size: 10,
2207	},
2208	{
2209		in:   []string{str5, str4},
2210		out:  [][]string{{str5, str4}},
2211		size: 10,
2212	},
2213	{
2214		in:   []string{str5, str4, str5},
2215		out:  [][]string{{str5, str4}, {str5}},
2216		size: 10,
2217	},
2218	{
2219		in:   []string{str5, str4, str5, str4},
2220		out:  [][]string{{str5, str4}, {str5, str4}},
2221		size: 10,
2222	},
2223	{
2224		in:   []string{str5, str4, str5, str5},
2225		out:  [][]string{{str5, str4}, {str5}, {str5}},
2226		size: 10,
2227	},
2228	{
2229		in:   []string{str5, str5, str5, str4},
2230		out:  [][]string{{str5}, {str5}, {str5, str4}},
2231		size: 10,
2232	},
2233	{
2234		in:   []string{str9, str11},
2235		out:  nil,
2236		size: 10,
2237	},
2238	{
2239		in:   []string{str11, str9},
2240		out:  nil,
2241		size: 10,
2242	},
2243}
2244
2245func TestSplitListForSize(t *testing.T) {
2246	for _, testCase := range splitListForSizeTestCases {
2247		out, _ := splitListForSize(android.PathsForTesting(testCase.in...), testCase.size)
2248
2249		var outStrings [][]string
2250
2251		if len(out) > 0 {
2252			outStrings = make([][]string, len(out))
2253			for i, o := range out {
2254				outStrings[i] = o.Strings()
2255			}
2256		}
2257
2258		if !reflect.DeepEqual(outStrings, testCase.out) {
2259			t.Errorf("incorrect output:")
2260			t.Errorf("     input: %#v", testCase.in)
2261			t.Errorf("      size: %d", testCase.size)
2262			t.Errorf("  expected: %#v", testCase.out)
2263			t.Errorf("       got: %#v", outStrings)
2264		}
2265	}
2266}
2267
2268var staticLinkDepOrderTestCases = []struct {
2269	// This is a string representation of a map[moduleName][]moduleDependency .
2270	// It models the dependencies declared in an Android.bp file.
2271	inStatic string
2272
2273	// This is a string representation of a map[moduleName][]moduleDependency .
2274	// It models the dependencies declared in an Android.bp file.
2275	inShared string
2276
2277	// allOrdered is a string representation of a map[moduleName][]moduleDependency .
2278	// The keys of allOrdered specify which modules we would like to check.
2279	// The values of allOrdered specify the expected result (of the transitive closure of all
2280	// dependencies) for each module to test
2281	allOrdered string
2282
2283	// outOrdered is a string representation of a map[moduleName][]moduleDependency .
2284	// The keys of outOrdered specify which modules we would like to check.
2285	// The values of outOrdered specify the expected result (of the ordered linker command line)
2286	// for each module to test.
2287	outOrdered string
2288}{
2289	// Simple tests
2290	{
2291		inStatic:   "",
2292		outOrdered: "",
2293	},
2294	{
2295		inStatic:   "a:",
2296		outOrdered: "a:",
2297	},
2298	{
2299		inStatic:   "a:b; b:",
2300		outOrdered: "a:b; b:",
2301	},
2302	// Tests of reordering
2303	{
2304		// diamond example
2305		inStatic:   "a:d,b,c; b:d; c:d; d:",
2306		outOrdered: "a:b,c,d; b:d; c:d; d:",
2307	},
2308	{
2309		// somewhat real example
2310		inStatic:   "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
2311		outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
2312	},
2313	{
2314		// multiple reorderings
2315		inStatic:   "a:b,c,d,e; d:b; e:c",
2316		outOrdered: "a:d,b,e,c; d:b; e:c",
2317	},
2318	{
2319		// should reorder without adding new transitive dependencies
2320		inStatic:   "bin:lib2,lib1;             lib1:lib2,liboptional",
2321		allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
2322		outOrdered: "bin:lib1,lib2;             lib1:lib2,liboptional",
2323	},
2324	{
2325		// multiple levels of dependencies
2326		inStatic:   "a:b,c,d,e,f,g,h; f:b,c,d; b:c,d; c:d",
2327		allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
2328		outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
2329	},
2330	// shared dependencies
2331	{
2332		// Note that this test doesn't recurse, to minimize the amount of logic it tests.
2333		// So, we don't actually have to check that a shared dependency of c will change the order
2334		// of a library that depends statically on b and on c.  We only need to check that if c has
2335		// a shared dependency on b, that that shows up in allOrdered.
2336		inShared:   "c:b",
2337		allOrdered: "c:b",
2338		outOrdered: "c:",
2339	},
2340	{
2341		// This test doesn't actually include any shared dependencies but it's a reminder of what
2342		// the second phase of the above test would look like
2343		inStatic:   "a:b,c; c:b",
2344		allOrdered: "a:c,b; c:b",
2345		outOrdered: "a:c,b; c:b",
2346	},
2347	// tiebreakers for when two modules specifying different orderings and there is no dependency
2348	// to dictate an order
2349	{
2350		// if the tie is between two modules at the end of a's deps, then a's order wins
2351		inStatic:   "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
2352		outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
2353	},
2354	{
2355		// if the tie is between two modules at the start of a's deps, then c's order is used
2356		inStatic:   "a1:d,e,b1,c1; b1:d,e; c1:e,d;   a2:d,e,b2,c2; b2:d,e; c2:d,e",
2357		outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d;   a2:b2,c2,d,e; b2:d,e; c2:d,e",
2358	},
2359	// Tests involving duplicate dependencies
2360	{
2361		// simple duplicate
2362		inStatic:   "a:b,c,c,b",
2363		outOrdered: "a:c,b",
2364	},
2365	{
2366		// duplicates with reordering
2367		inStatic:   "a:b,c,d,c; c:b",
2368		outOrdered: "a:d,c,b",
2369	},
2370	// Tests to confirm the nonexistence of infinite loops.
2371	// These cases should never happen, so as long as the test terminates and the
2372	// result is deterministic then that should be fine.
2373	{
2374		inStatic:   "a:a",
2375		outOrdered: "a:a",
2376	},
2377	{
2378		inStatic:   "a:b;   b:c;   c:a",
2379		allOrdered: "a:b,c; b:c,a; c:a,b",
2380		outOrdered: "a:b;   b:c;   c:a",
2381	},
2382	{
2383		inStatic:   "a:b,c;   b:c,a;   c:a,b",
2384		allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
2385		outOrdered: "a:c,b;   b:a,c;   c:b,a",
2386	},
2387}
2388
2389// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
2390func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
2391	// convert from "a:b,c; d:e" to "a:b,c;d:e"
2392	strippedText := strings.Replace(text, " ", "", -1)
2393	if len(strippedText) < 1 {
2394		return []android.Path{}, make(map[android.Path][]android.Path, 0)
2395	}
2396	allDeps = make(map[android.Path][]android.Path, 0)
2397
2398	// convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
2399	moduleTexts := strings.Split(strippedText, ";")
2400
2401	outputForModuleName := func(moduleName string) android.Path {
2402		return android.PathForTesting(moduleName)
2403	}
2404
2405	for _, moduleText := range moduleTexts {
2406		// convert from "a:b,c" to ["a", "b,c"]
2407		components := strings.Split(moduleText, ":")
2408		if len(components) != 2 {
2409			panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
2410		}
2411		moduleName := components[0]
2412		moduleOutput := outputForModuleName(moduleName)
2413		modulesInOrder = append(modulesInOrder, moduleOutput)
2414
2415		depString := components[1]
2416		// convert from "b,c" to ["b", "c"]
2417		depNames := strings.Split(depString, ",")
2418		if len(depString) < 1 {
2419			depNames = []string{}
2420		}
2421		var deps []android.Path
2422		for _, depName := range depNames {
2423			deps = append(deps, outputForModuleName(depName))
2424		}
2425		allDeps[moduleOutput] = deps
2426	}
2427	return modulesInOrder, allDeps
2428}
2429
2430func TestLinkReordering(t *testing.T) {
2431	for _, testCase := range staticLinkDepOrderTestCases {
2432		errs := []string{}
2433
2434		// parse testcase
2435		_, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
2436		expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
2437		if testCase.allOrdered == "" {
2438			// allow the test case to skip specifying allOrdered
2439			testCase.allOrdered = testCase.outOrdered
2440		}
2441		_, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
2442		_, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
2443
2444		// For each module whose post-reordered dependencies were specified, validate that
2445		// reordering the inputs produces the expected outputs.
2446		for _, moduleName := range expectedModuleNames {
2447			moduleDeps := givenTransitiveDeps[moduleName]
2448			givenSharedDeps := givenAllSharedDeps[moduleName]
2449			orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
2450
2451			correctAllOrdered := expectedAllDeps[moduleName]
2452			if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
2453				errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
2454					"\nin static:%q"+
2455					"\nin shared:%q"+
2456					"\nmodule:   %v"+
2457					"\nexpected: %s"+
2458					"\nactual:   %s",
2459					testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
2460			}
2461
2462			correctOutputDeps := expectedTransitiveDeps[moduleName]
2463			if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
2464				errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
2465					"\nin static:%q"+
2466					"\nin shared:%q"+
2467					"\nmodule:   %v"+
2468					"\nexpected: %s"+
2469					"\nactual:   %s",
2470					testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
2471			}
2472		}
2473
2474		if len(errs) > 0 {
2475			sort.Strings(errs)
2476			for _, err := range errs {
2477				t.Error(err)
2478			}
2479		}
2480	}
2481}
2482
2483func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
2484	for _, moduleName := range moduleNames {
2485		module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
2486		output := module.outputFile.Path()
2487		paths = append(paths, output)
2488	}
2489	return paths
2490}
2491
2492func TestStaticLibDepReordering(t *testing.T) {
2493	ctx := testCc(t, `
2494	cc_library {
2495		name: "a",
2496		static_libs: ["b", "c", "d"],
2497		stl: "none",
2498	}
2499	cc_library {
2500		name: "b",
2501		stl: "none",
2502	}
2503	cc_library {
2504		name: "c",
2505		static_libs: ["b"],
2506		stl: "none",
2507	}
2508	cc_library {
2509		name: "d",
2510		stl: "none",
2511	}
2512
2513	`)
2514
2515	variant := "android_arm64_armv8-a_static"
2516	moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
2517	actual := moduleA.depsInLinkOrder
2518	expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
2519
2520	if !reflect.DeepEqual(actual, expected) {
2521		t.Errorf("staticDeps orderings were not propagated correctly"+
2522			"\nactual:   %v"+
2523			"\nexpected: %v",
2524			actual,
2525			expected,
2526		)
2527	}
2528}
2529
2530func TestStaticLibDepReorderingWithShared(t *testing.T) {
2531	ctx := testCc(t, `
2532	cc_library {
2533		name: "a",
2534		static_libs: ["b", "c"],
2535		stl: "none",
2536	}
2537	cc_library {
2538		name: "b",
2539		stl: "none",
2540	}
2541	cc_library {
2542		name: "c",
2543		shared_libs: ["b"],
2544		stl: "none",
2545	}
2546
2547	`)
2548
2549	variant := "android_arm64_armv8-a_static"
2550	moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
2551	actual := moduleA.depsInLinkOrder
2552	expected := getOutputPaths(ctx, variant, []string{"c", "b"})
2553
2554	if !reflect.DeepEqual(actual, expected) {
2555		t.Errorf("staticDeps orderings did not account for shared libs"+
2556			"\nactual:   %v"+
2557			"\nexpected: %v",
2558			actual,
2559			expected,
2560		)
2561	}
2562}
2563
2564func checkEquals(t *testing.T, message string, expected, actual interface{}) {
2565	if !reflect.DeepEqual(actual, expected) {
2566		t.Errorf(message+
2567			"\nactual:   %v"+
2568			"\nexpected: %v",
2569			actual,
2570			expected,
2571		)
2572	}
2573}
2574
2575func TestLlndkLibrary(t *testing.T) {
2576	ctx := testCc(t, `
2577	cc_library {
2578		name: "libllndk",
2579		stubs: { versions: ["1", "2"] },
2580	}
2581	llndk_library {
2582		name: "libllndk",
2583	}
2584	`)
2585	actual := ctx.ModuleVariantsForTests("libllndk.llndk")
2586	expected := []string{
2587		"android_vendor.VER_arm64_armv8-a_shared",
2588		"android_vendor.VER_arm64_armv8-a_shared_1",
2589		"android_vendor.VER_arm64_armv8-a_shared_2",
2590		"android_vendor.VER_arm_armv7-a-neon_shared",
2591		"android_vendor.VER_arm_armv7-a-neon_shared_1",
2592		"android_vendor.VER_arm_armv7-a-neon_shared_2",
2593	}
2594	checkEquals(t, "variants for llndk stubs", expected, actual)
2595
2596	params := ctx.ModuleForTests("libllndk.llndk", "android_vendor.VER_arm_armv7-a-neon_shared").Description("generate stub")
2597	checkEquals(t, "use VNDK version for default stubs", "current", params.Args["apiLevel"])
2598
2599	params = ctx.ModuleForTests("libllndk.llndk", "android_vendor.VER_arm_armv7-a-neon_shared_1").Description("generate stub")
2600	checkEquals(t, "override apiLevel for versioned stubs", "1", params.Args["apiLevel"])
2601}
2602
2603func TestLlndkHeaders(t *testing.T) {
2604	ctx := testCc(t, `
2605	llndk_headers {
2606		name: "libllndk_headers",
2607		export_include_dirs: ["my_include"],
2608	}
2609	llndk_library {
2610		name: "libllndk",
2611		export_llndk_headers: ["libllndk_headers"],
2612	}
2613	cc_library {
2614		name: "libvendor",
2615		shared_libs: ["libllndk"],
2616		vendor: true,
2617		srcs: ["foo.c"],
2618		no_libcrt: true,
2619		nocrt: true,
2620	}
2621	`)
2622
2623	// _static variant is used since _shared reuses *.o from the static variant
2624	cc := ctx.ModuleForTests("libvendor", "android_vendor.VER_arm_armv7-a-neon_static").Rule("cc")
2625	cflags := cc.Args["cFlags"]
2626	if !strings.Contains(cflags, "-Imy_include") {
2627		t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
2628	}
2629}
2630
2631func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
2632	actual := module.Properties.AndroidMkRuntimeLibs
2633	if !reflect.DeepEqual(actual, expected) {
2634		t.Errorf("incorrect runtime_libs for shared libs"+
2635			"\nactual:   %v"+
2636			"\nexpected: %v",
2637			actual,
2638			expected,
2639		)
2640	}
2641}
2642
2643const runtimeLibAndroidBp = `
2644	cc_library {
2645		name: "libvendor_available1",
2646		vendor_available: true,
2647		no_libcrt : true,
2648		nocrt : true,
2649		system_shared_libs : [],
2650	}
2651	cc_library {
2652		name: "libvendor_available2",
2653		vendor_available: true,
2654		runtime_libs: ["libvendor_available1"],
2655		no_libcrt : true,
2656		nocrt : true,
2657		system_shared_libs : [],
2658	}
2659	cc_library {
2660		name: "libvendor_available3",
2661		vendor_available: true,
2662		runtime_libs: ["libvendor_available1"],
2663		target: {
2664			vendor: {
2665				exclude_runtime_libs: ["libvendor_available1"],
2666			}
2667		},
2668		no_libcrt : true,
2669		nocrt : true,
2670		system_shared_libs : [],
2671	}
2672	cc_library {
2673		name: "libcore",
2674		runtime_libs: ["libvendor_available1"],
2675		no_libcrt : true,
2676		nocrt : true,
2677		system_shared_libs : [],
2678	}
2679	cc_library {
2680		name: "libvendor1",
2681		vendor: true,
2682		no_libcrt : true,
2683		nocrt : true,
2684		system_shared_libs : [],
2685	}
2686	cc_library {
2687		name: "libvendor2",
2688		vendor: true,
2689		runtime_libs: ["libvendor_available1", "libvendor1"],
2690		no_libcrt : true,
2691		nocrt : true,
2692		system_shared_libs : [],
2693	}
2694`
2695
2696func TestRuntimeLibs(t *testing.T) {
2697	ctx := testCc(t, runtimeLibAndroidBp)
2698
2699	// runtime_libs for core variants use the module names without suffixes.
2700	variant := "android_arm64_armv8-a_shared"
2701
2702	module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
2703	checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
2704
2705	module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
2706	checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
2707
2708	// runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
2709	// and vendor variants.
2710	variant = "android_vendor.VER_arm64_armv8-a_shared"
2711
2712	module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
2713	checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
2714
2715	module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
2716	checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
2717}
2718
2719func TestExcludeRuntimeLibs(t *testing.T) {
2720	ctx := testCc(t, runtimeLibAndroidBp)
2721
2722	variant := "android_arm64_armv8-a_shared"
2723	module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
2724	checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
2725
2726	variant = "android_vendor.VER_arm64_armv8-a_shared"
2727	module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
2728	checkRuntimeLibs(t, nil, module)
2729}
2730
2731func TestRuntimeLibsNoVndk(t *testing.T) {
2732	ctx := testCcNoVndk(t, runtimeLibAndroidBp)
2733
2734	// If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
2735
2736	variant := "android_arm64_armv8-a_shared"
2737
2738	module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
2739	checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
2740
2741	module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
2742	checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
2743}
2744
2745func checkStaticLibs(t *testing.T, expected []string, module *Module) {
2746	t.Helper()
2747	actual := module.Properties.AndroidMkStaticLibs
2748	if !reflect.DeepEqual(actual, expected) {
2749		t.Errorf("incorrect static_libs"+
2750			"\nactual:   %v"+
2751			"\nexpected: %v",
2752			actual,
2753			expected,
2754		)
2755	}
2756}
2757
2758const staticLibAndroidBp = `
2759	cc_library {
2760		name: "lib1",
2761	}
2762	cc_library {
2763		name: "lib2",
2764		static_libs: ["lib1"],
2765	}
2766`
2767
2768func TestStaticLibDepExport(t *testing.T) {
2769	ctx := testCc(t, staticLibAndroidBp)
2770
2771	// Check the shared version of lib2.
2772	variant := "android_arm64_armv8-a_shared"
2773	module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
2774	checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic"}, module)
2775
2776	// Check the static version of lib2.
2777	variant = "android_arm64_armv8-a_static"
2778	module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
2779	// libc++_static is linked additionally.
2780	checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic"}, module)
2781}
2782
2783var compilerFlagsTestCases = []struct {
2784	in  string
2785	out bool
2786}{
2787	{
2788		in:  "a",
2789		out: false,
2790	},
2791	{
2792		in:  "-a",
2793		out: true,
2794	},
2795	{
2796		in:  "-Ipath/to/something",
2797		out: false,
2798	},
2799	{
2800		in:  "-isystempath/to/something",
2801		out: false,
2802	},
2803	{
2804		in:  "--coverage",
2805		out: false,
2806	},
2807	{
2808		in:  "-include a/b",
2809		out: true,
2810	},
2811	{
2812		in:  "-include a/b c/d",
2813		out: false,
2814	},
2815	{
2816		in:  "-DMACRO",
2817		out: true,
2818	},
2819	{
2820		in:  "-DMAC RO",
2821		out: false,
2822	},
2823	{
2824		in:  "-a -b",
2825		out: false,
2826	},
2827	{
2828		in:  "-DMACRO=definition",
2829		out: true,
2830	},
2831	{
2832		in:  "-DMACRO=defi nition",
2833		out: true, // TODO(jiyong): this should be false
2834	},
2835	{
2836		in:  "-DMACRO(x)=x + 1",
2837		out: true,
2838	},
2839	{
2840		in:  "-DMACRO=\"defi nition\"",
2841		out: true,
2842	},
2843}
2844
2845type mockContext struct {
2846	BaseModuleContext
2847	result bool
2848}
2849
2850func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
2851	// CheckBadCompilerFlags calls this function when the flag should be rejected
2852	ctx.result = false
2853}
2854
2855func TestCompilerFlags(t *testing.T) {
2856	for _, testCase := range compilerFlagsTestCases {
2857		ctx := &mockContext{result: true}
2858		CheckBadCompilerFlags(ctx, "", []string{testCase.in})
2859		if ctx.result != testCase.out {
2860			t.Errorf("incorrect output:")
2861			t.Errorf("     input: %#v", testCase.in)
2862			t.Errorf("  expected: %#v", testCase.out)
2863			t.Errorf("       got: %#v", ctx.result)
2864		}
2865	}
2866}
2867
2868func TestVendorPublicLibraries(t *testing.T) {
2869	ctx := testCc(t, `
2870	cc_library_headers {
2871		name: "libvendorpublic_headers",
2872		export_include_dirs: ["my_include"],
2873	}
2874	vendor_public_library {
2875		name: "libvendorpublic",
2876		symbol_file: "",
2877		export_public_headers: ["libvendorpublic_headers"],
2878	}
2879	cc_library {
2880		name: "libvendorpublic",
2881		srcs: ["foo.c"],
2882		vendor: true,
2883		no_libcrt: true,
2884		nocrt: true,
2885	}
2886
2887	cc_library {
2888		name: "libsystem",
2889		shared_libs: ["libvendorpublic"],
2890		vendor: false,
2891		srcs: ["foo.c"],
2892		no_libcrt: true,
2893		nocrt: true,
2894	}
2895	cc_library {
2896		name: "libvendor",
2897		shared_libs: ["libvendorpublic"],
2898		vendor: true,
2899		srcs: ["foo.c"],
2900		no_libcrt: true,
2901		nocrt: true,
2902	}
2903	`)
2904
2905	coreVariant := "android_arm64_armv8-a_shared"
2906	vendorVariant := "android_vendor.VER_arm64_armv8-a_shared"
2907
2908	// test if header search paths are correctly added
2909	// _static variant is used since _shared reuses *.o from the static variant
2910	cc := ctx.ModuleForTests("libsystem", strings.Replace(coreVariant, "_shared", "_static", 1)).Rule("cc")
2911	cflags := cc.Args["cFlags"]
2912	if !strings.Contains(cflags, "-Imy_include") {
2913		t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
2914	}
2915
2916	// test if libsystem is linked to the stub
2917	ld := ctx.ModuleForTests("libsystem", coreVariant).Rule("ld")
2918	libflags := ld.Args["libFlags"]
2919	stubPaths := getOutputPaths(ctx, coreVariant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
2920	if !strings.Contains(libflags, stubPaths[0].String()) {
2921		t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
2922	}
2923
2924	// test if libvendor is linked to the real shared lib
2925	ld = ctx.ModuleForTests("libvendor", vendorVariant).Rule("ld")
2926	libflags = ld.Args["libFlags"]
2927	stubPaths = getOutputPaths(ctx, vendorVariant, []string{"libvendorpublic"})
2928	if !strings.Contains(libflags, stubPaths[0].String()) {
2929		t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
2930	}
2931
2932}
2933
2934func TestRecovery(t *testing.T) {
2935	ctx := testCc(t, `
2936		cc_library_shared {
2937			name: "librecovery",
2938			recovery: true,
2939		}
2940		cc_library_shared {
2941			name: "librecovery32",
2942			recovery: true,
2943			compile_multilib:"32",
2944		}
2945		cc_library_shared {
2946			name: "libHalInRecovery",
2947			recovery_available: true,
2948			vendor: true,
2949		}
2950	`)
2951
2952	variants := ctx.ModuleVariantsForTests("librecovery")
2953	const arm64 = "android_recovery_arm64_armv8-a_shared"
2954	if len(variants) != 1 || !android.InList(arm64, variants) {
2955		t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
2956	}
2957
2958	variants = ctx.ModuleVariantsForTests("librecovery32")
2959	if android.InList(arm64, variants) {
2960		t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
2961	}
2962
2963	recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
2964	if !recoveryModule.Platform() {
2965		t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
2966	}
2967}
2968
2969func TestDataLibsPrebuiltSharedTestLibrary(t *testing.T) {
2970	bp := `
2971		cc_prebuilt_test_library_shared {
2972			name: "test_lib",
2973			relative_install_path: "foo/bar/baz",
2974			srcs: ["srcpath/dontusethispath/baz.so"],
2975		}
2976
2977		cc_test {
2978			name: "main_test",
2979			data_libs: ["test_lib"],
2980			gtest: false,
2981		}
2982 `
2983
2984	config := TestConfig(buildDir, android.Android, nil, bp, nil)
2985	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
2986	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
2987	config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
2988
2989	ctx := testCcWithConfig(t, config)
2990	module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
2991	testBinary := module.(*Module).linker.(*testBinary)
2992	outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
2993	if err != nil {
2994		t.Fatalf("Expected cc_test to produce output files, error: %s", err)
2995	}
2996	if len(outputFiles) != 1 {
2997		t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
2998	}
2999	if len(testBinary.dataPaths()) != 1 {
3000		t.Errorf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths())
3001	}
3002
3003	outputPath := outputFiles[0].String()
3004
3005	if !strings.HasSuffix(outputPath, "/main_test") {
3006		t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
3007	}
3008	entries := android.AndroidMkEntriesForTest(t, config, "", module)[0]
3009	if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
3010		t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
3011			" but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
3012	}
3013}
3014
3015func TestVersionedStubs(t *testing.T) {
3016	ctx := testCc(t, `
3017		cc_library_shared {
3018			name: "libFoo",
3019			srcs: ["foo.c"],
3020			stubs: {
3021				symbol_file: "foo.map.txt",
3022				versions: ["1", "2", "3"],
3023			},
3024		}
3025
3026		cc_library_shared {
3027			name: "libBar",
3028			srcs: ["bar.c"],
3029			shared_libs: ["libFoo#1"],
3030		}`)
3031
3032	variants := ctx.ModuleVariantsForTests("libFoo")
3033	expectedVariants := []string{
3034		"android_arm64_armv8-a_shared",
3035		"android_arm64_armv8-a_shared_1",
3036		"android_arm64_armv8-a_shared_2",
3037		"android_arm64_armv8-a_shared_3",
3038		"android_arm_armv7-a-neon_shared",
3039		"android_arm_armv7-a-neon_shared_1",
3040		"android_arm_armv7-a-neon_shared_2",
3041		"android_arm_armv7-a-neon_shared_3",
3042	}
3043	variantsMismatch := false
3044	if len(variants) != len(expectedVariants) {
3045		variantsMismatch = true
3046	} else {
3047		for _, v := range expectedVariants {
3048			if !inList(v, variants) {
3049				variantsMismatch = false
3050			}
3051		}
3052	}
3053	if variantsMismatch {
3054		t.Errorf("variants of libFoo expected:\n")
3055		for _, v := range expectedVariants {
3056			t.Errorf("%q\n", v)
3057		}
3058		t.Errorf(", but got:\n")
3059		for _, v := range variants {
3060			t.Errorf("%q\n", v)
3061		}
3062	}
3063
3064	libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("ld")
3065	libFlags := libBarLinkRule.Args["libFlags"]
3066	libFoo1StubPath := "libFoo/android_arm64_armv8-a_shared_1/libFoo.so"
3067	if !strings.Contains(libFlags, libFoo1StubPath) {
3068		t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
3069	}
3070
3071	libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("cc")
3072	cFlags := libBarCompileRule.Args["cFlags"]
3073	libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
3074	if !strings.Contains(cFlags, libFoo1VersioningMacro) {
3075		t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
3076	}
3077}
3078
3079func TestVersioningMacro(t *testing.T) {
3080	for _, tc := range []struct{ moduleName, expected string }{
3081		{"libc", "__LIBC_API__"},
3082		{"libfoo", "__LIBFOO_API__"},
3083		{"libfoo@1", "__LIBFOO_1_API__"},
3084		{"libfoo-v1", "__LIBFOO_V1_API__"},
3085		{"libfoo.v1", "__LIBFOO_V1_API__"},
3086	} {
3087		checkEquals(t, tc.moduleName, tc.expected, versioningMacroName(tc.moduleName))
3088	}
3089}
3090
3091func TestStaticExecutable(t *testing.T) {
3092	ctx := testCc(t, `
3093		cc_binary {
3094			name: "static_test",
3095			srcs: ["foo.c", "baz.o"],
3096			static_executable: true,
3097		}`)
3098
3099	variant := "android_arm64_armv8-a"
3100	binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
3101	libFlags := binModuleRule.Args["libFlags"]
3102	systemStaticLibs := []string{"libc.a", "libm.a"}
3103	for _, lib := range systemStaticLibs {
3104		if !strings.Contains(libFlags, lib) {
3105			t.Errorf("Static lib %q was not found in %q", lib, libFlags)
3106		}
3107	}
3108	systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
3109	for _, lib := range systemSharedLibs {
3110		if strings.Contains(libFlags, lib) {
3111			t.Errorf("Shared lib %q was found in %q", lib, libFlags)
3112		}
3113	}
3114}
3115
3116func TestStaticDepsOrderWithStubs(t *testing.T) {
3117	ctx := testCc(t, `
3118		cc_binary {
3119			name: "mybin",
3120			srcs: ["foo.c"],
3121			static_libs: ["libfooB"],
3122			static_executable: true,
3123			stl: "none",
3124		}
3125
3126		cc_library {
3127			name: "libfooB",
3128			srcs: ["foo.c"],
3129			shared_libs: ["libfooC"],
3130			stl: "none",
3131		}
3132
3133		cc_library {
3134			name: "libfooC",
3135			srcs: ["foo.c"],
3136			stl: "none",
3137			stubs: {
3138				versions: ["1"],
3139			},
3140		}`)
3141
3142	mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a").Module().(*Module)
3143	actual := mybin.depsInLinkOrder
3144	expected := getOutputPaths(ctx, "android_arm64_armv8-a_static", []string{"libfooB", "libfooC"})
3145
3146	if !reflect.DeepEqual(actual, expected) {
3147		t.Errorf("staticDeps orderings were not propagated correctly"+
3148			"\nactual:   %v"+
3149			"\nexpected: %v",
3150			actual,
3151			expected,
3152		)
3153	}
3154}
3155
3156func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) {
3157	testCcError(t, `module "libA" .* depends on disabled module "libB"`, `
3158		cc_library {
3159			name: "libA",
3160			srcs: ["foo.c"],
3161			shared_libs: ["libB"],
3162			stl: "none",
3163		}
3164
3165		cc_library {
3166			name: "libB",
3167			srcs: ["foo.c"],
3168			enabled: false,
3169			stl: "none",
3170		}
3171	`)
3172}
3173
3174// Simple smoke test for the cc_fuzz target that ensures the rule compiles
3175// correctly.
3176func TestFuzzTarget(t *testing.T) {
3177	ctx := testCc(t, `
3178		cc_fuzz {
3179			name: "fuzz_smoke_test",
3180			srcs: ["foo.c"],
3181		}`)
3182
3183	variant := "android_arm64_armv8-a_fuzzer"
3184	ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
3185}
3186
3187func TestAidl(t *testing.T) {
3188}
3189
3190func assertString(t *testing.T, got, expected string) {
3191	t.Helper()
3192	if got != expected {
3193		t.Errorf("expected %q got %q", expected, got)
3194	}
3195}
3196
3197func assertArrayString(t *testing.T, got, expected []string) {
3198	t.Helper()
3199	if len(got) != len(expected) {
3200		t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got)
3201		return
3202	}
3203	for i := range got {
3204		if got[i] != expected[i] {
3205			t.Errorf("expected %d-th %q (%q) got %q (%q)",
3206				i, expected[i], expected, got[i], got)
3207			return
3208		}
3209	}
3210}
3211
3212func assertMapKeys(t *testing.T, m map[string]string, expected []string) {
3213	t.Helper()
3214	assertArrayString(t, android.SortedStringKeys(m), expected)
3215}
3216
3217func TestDefaults(t *testing.T) {
3218	ctx := testCc(t, `
3219		cc_defaults {
3220			name: "defaults",
3221			srcs: ["foo.c"],
3222			static: {
3223				srcs: ["bar.c"],
3224			},
3225			shared: {
3226				srcs: ["baz.c"],
3227			},
3228		}
3229
3230		cc_library_static {
3231			name: "libstatic",
3232			defaults: ["defaults"],
3233		}
3234
3235		cc_library_shared {
3236			name: "libshared",
3237			defaults: ["defaults"],
3238		}
3239
3240		cc_library {
3241			name: "libboth",
3242			defaults: ["defaults"],
3243		}
3244
3245		cc_binary {
3246			name: "binary",
3247			defaults: ["defaults"],
3248		}`)
3249
3250	pathsToBase := func(paths android.Paths) []string {
3251		var ret []string
3252		for _, p := range paths {
3253			ret = append(ret, p.Base())
3254		}
3255		return ret
3256	}
3257
3258	shared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Rule("ld")
3259	if g, w := pathsToBase(shared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
3260		t.Errorf("libshared ld rule wanted %q, got %q", w, g)
3261	}
3262	bothShared := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_shared").Rule("ld")
3263	if g, w := pathsToBase(bothShared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
3264		t.Errorf("libboth ld rule wanted %q, got %q", w, g)
3265	}
3266	binary := ctx.ModuleForTests("binary", "android_arm64_armv8-a").Rule("ld")
3267	if g, w := pathsToBase(binary.Inputs), []string{"foo.o"}; !reflect.DeepEqual(w, g) {
3268		t.Errorf("binary ld rule wanted %q, got %q", w, g)
3269	}
3270
3271	static := ctx.ModuleForTests("libstatic", "android_arm64_armv8-a_static").Rule("ar")
3272	if g, w := pathsToBase(static.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
3273		t.Errorf("libstatic ar rule wanted %q, got %q", w, g)
3274	}
3275	bothStatic := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_static").Rule("ar")
3276	if g, w := pathsToBase(bothStatic.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
3277		t.Errorf("libboth ar rule wanted %q, got %q", w, g)
3278	}
3279}
3280
3281func TestProductVariableDefaults(t *testing.T) {
3282	bp := `
3283		cc_defaults {
3284			name: "libfoo_defaults",
3285			srcs: ["foo.c"],
3286			cppflags: ["-DFOO"],
3287			product_variables: {
3288				debuggable: {
3289					cppflags: ["-DBAR"],
3290				},
3291			},
3292		}
3293
3294		cc_library {
3295			name: "libfoo",
3296			defaults: ["libfoo_defaults"],
3297		}
3298	`
3299
3300	config := TestConfig(buildDir, android.Android, nil, bp, nil)
3301	config.TestProductVariables.Debuggable = BoolPtr(true)
3302
3303	ctx := CreateTestContext()
3304	ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
3305		ctx.BottomUp("variable", android.VariableMutator).Parallel()
3306	})
3307	ctx.Register(config)
3308
3309	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
3310	android.FailIfErrored(t, errs)
3311	_, errs = ctx.PrepareBuildActions(config)
3312	android.FailIfErrored(t, errs)
3313
3314	libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Module().(*Module)
3315	if !android.InList("-DBAR", libfoo.flags.Local.CppFlags) {
3316		t.Errorf("expected -DBAR in cppflags, got %q", libfoo.flags.Local.CppFlags)
3317	}
3318}
3319