• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cc
16
17import (
18	"fmt"
19	"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 TestVndkWhenVndkVersionIsNotSet(t *testing.T) {
530	ctx := testCcNoVndk(t, `
531		cc_library {
532			name: "libvndk",
533			vendor_available: true,
534			vndk: {
535				enabled: true,
536			},
537			nocrt: true,
538		}
539	`)
540
541	checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{
542		"LLNDK: libc.so",
543		"LLNDK: libdl.so",
544		"LLNDK: libft2.so",
545		"LLNDK: libm.so",
546		"VNDK-SP: libc++.so",
547		"VNDK-core: libvndk.so",
548		"VNDK-private: libft2.so",
549	})
550}
551
552func TestVndkDepError(t *testing.T) {
553	// Check whether an error is emitted when a VNDK lib depends on a system lib.
554	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
555		cc_library {
556			name: "libvndk",
557			vendor_available: true,
558			vndk: {
559				enabled: true,
560			},
561			shared_libs: ["libfwk"],  // Cause error
562			nocrt: true,
563		}
564
565		cc_library {
566			name: "libfwk",
567			nocrt: true,
568		}
569	`)
570
571	// Check whether an error is emitted when a VNDK lib depends on a vendor lib.
572	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
573		cc_library {
574			name: "libvndk",
575			vendor_available: true,
576			vndk: {
577				enabled: true,
578			},
579			shared_libs: ["libvendor"],  // Cause error
580			nocrt: true,
581		}
582
583		cc_library {
584			name: "libvendor",
585			vendor: true,
586			nocrt: true,
587		}
588	`)
589
590	// Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
591	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
592		cc_library {
593			name: "libvndk_sp",
594			vendor_available: true,
595			vndk: {
596				enabled: true,
597				support_system_process: true,
598			},
599			shared_libs: ["libfwk"],  // Cause error
600			nocrt: true,
601		}
602
603		cc_library {
604			name: "libfwk",
605			nocrt: true,
606		}
607	`)
608
609	// Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
610	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
611		cc_library {
612			name: "libvndk_sp",
613			vendor_available: true,
614			vndk: {
615				enabled: true,
616				support_system_process: true,
617			},
618			shared_libs: ["libvendor"],  // Cause error
619			nocrt: true,
620		}
621
622		cc_library {
623			name: "libvendor",
624			vendor: true,
625			nocrt: true,
626		}
627	`)
628
629	// Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
630	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
631		cc_library {
632			name: "libvndk_sp",
633			vendor_available: true,
634			vndk: {
635				enabled: true,
636				support_system_process: true,
637			},
638			shared_libs: ["libvndk"],  // Cause error
639			nocrt: true,
640		}
641
642		cc_library {
643			name: "libvndk",
644			vendor_available: true,
645			vndk: {
646				enabled: true,
647			},
648			nocrt: true,
649		}
650	`)
651
652	// Check whether an error is emitted when a VNDK lib depends on a non-VNDK lib.
653	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
654		cc_library {
655			name: "libvndk",
656			vendor_available: true,
657			vndk: {
658				enabled: true,
659			},
660			shared_libs: ["libnonvndk"],
661			nocrt: true,
662		}
663
664		cc_library {
665			name: "libnonvndk",
666			vendor_available: true,
667			nocrt: true,
668		}
669	`)
670
671	// Check whether an error is emitted when a VNDK-private lib depends on a non-VNDK lib.
672	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
673		cc_library {
674			name: "libvndkprivate",
675			vendor_available: false,
676			vndk: {
677				enabled: true,
678			},
679			shared_libs: ["libnonvndk"],
680			nocrt: true,
681		}
682
683		cc_library {
684			name: "libnonvndk",
685			vendor_available: true,
686			nocrt: true,
687		}
688	`)
689
690	// Check whether an error is emitted when a VNDK-sp lib depends on a non-VNDK lib.
691	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
692		cc_library {
693			name: "libvndksp",
694			vendor_available: true,
695			vndk: {
696				enabled: true,
697				support_system_process: true,
698			},
699			shared_libs: ["libnonvndk"],
700			nocrt: true,
701		}
702
703		cc_library {
704			name: "libnonvndk",
705			vendor_available: true,
706			nocrt: true,
707		}
708	`)
709
710	// Check whether an error is emitted when a VNDK-sp-private lib depends on a non-VNDK lib.
711	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
712		cc_library {
713			name: "libvndkspprivate",
714			vendor_available: false,
715			vndk: {
716				enabled: true,
717				support_system_process: true,
718			},
719			shared_libs: ["libnonvndk"],
720			nocrt: true,
721		}
722
723		cc_library {
724			name: "libnonvndk",
725			vendor_available: true,
726			nocrt: true,
727		}
728	`)
729}
730
731func TestDoubleLoadbleDep(t *testing.T) {
732	// okay to link : LLNDK -> double_loadable VNDK
733	testCc(t, `
734		cc_library {
735			name: "libllndk",
736			shared_libs: ["libdoubleloadable"],
737		}
738
739		llndk_library {
740			name: "libllndk",
741			symbol_file: "",
742		}
743
744		cc_library {
745			name: "libdoubleloadable",
746			vendor_available: true,
747			vndk: {
748				enabled: true,
749			},
750			double_loadable: true,
751		}
752	`)
753	// okay to link : LLNDK -> VNDK-SP
754	testCc(t, `
755		cc_library {
756			name: "libllndk",
757			shared_libs: ["libvndksp"],
758		}
759
760		llndk_library {
761			name: "libllndk",
762			symbol_file: "",
763		}
764
765		cc_library {
766			name: "libvndksp",
767			vendor_available: true,
768			vndk: {
769				enabled: true,
770				support_system_process: true,
771			},
772		}
773	`)
774	// okay to link : double_loadable -> double_loadable
775	testCc(t, `
776		cc_library {
777			name: "libdoubleloadable1",
778			shared_libs: ["libdoubleloadable2"],
779			vendor_available: true,
780			double_loadable: true,
781		}
782
783		cc_library {
784			name: "libdoubleloadable2",
785			vendor_available: true,
786			double_loadable: true,
787		}
788	`)
789	// okay to link : double_loadable VNDK -> double_loadable VNDK private
790	testCc(t, `
791		cc_library {
792			name: "libdoubleloadable",
793			vendor_available: true,
794			vndk: {
795				enabled: true,
796			},
797			double_loadable: true,
798			shared_libs: ["libnondoubleloadable"],
799		}
800
801		cc_library {
802			name: "libnondoubleloadable",
803			vendor_available: false,
804			vndk: {
805				enabled: true,
806			},
807			double_loadable: true,
808		}
809	`)
810	// okay to link : LLNDK -> core-only -> vendor_available & double_loadable
811	testCc(t, `
812		cc_library {
813			name: "libllndk",
814			shared_libs: ["libcoreonly"],
815		}
816
817		llndk_library {
818			name: "libllndk",
819			symbol_file: "",
820		}
821
822		cc_library {
823			name: "libcoreonly",
824			shared_libs: ["libvendoravailable"],
825		}
826
827		// indirect dependency of LLNDK
828		cc_library {
829			name: "libvendoravailable",
830			vendor_available: true,
831			double_loadable: true,
832		}
833	`)
834}
835
836func TestVendorSnapshot(t *testing.T) {
837	bp := `
838	cc_library {
839		name: "libvndk",
840		vendor_available: true,
841		vndk: {
842			enabled: true,
843		},
844		nocrt: true,
845	}
846
847	cc_library {
848		name: "libvendor",
849		vendor: true,
850		nocrt: true,
851	}
852
853	cc_library {
854		name: "libvendor_available",
855		vendor_available: true,
856		nocrt: true,
857	}
858
859	cc_library_headers {
860		name: "libvendor_headers",
861		vendor_available: true,
862		nocrt: true,
863	}
864
865	cc_binary {
866		name: "vendor_bin",
867		vendor: true,
868		nocrt: true,
869	}
870
871	cc_binary {
872		name: "vendor_available_bin",
873		vendor_available: true,
874		nocrt: true,
875	}
876
877	toolchain_library {
878		name: "libb",
879		vendor_available: true,
880		src: "libb.a",
881	}
882
883	cc_object {
884		name: "obj",
885		vendor_available: true,
886	}
887`
888	config := TestConfig(buildDir, android.Android, nil, bp, nil)
889	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
890	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
891	ctx := testCcWithConfig(t, config)
892
893	// Check Vendor snapshot output.
894
895	snapshotDir := "vendor-snapshot"
896	snapshotVariantPath := filepath.Join(buildDir, snapshotDir, "arm64")
897	snapshotSingleton := ctx.SingletonForTests("vendor-snapshot")
898
899	var jsonFiles []string
900
901	for _, arch := range [][]string{
902		[]string{"arm64", "armv8-a"},
903		[]string{"arm", "armv7-a-neon"},
904	} {
905		archType := arch[0]
906		archVariant := arch[1]
907		archDir := fmt.Sprintf("arch-%s-%s", archType, archVariant)
908
909		// For shared libraries, only non-VNDK vendor_available modules are captured
910		sharedVariant := fmt.Sprintf("android_vendor.VER_%s_%s_shared", archType, archVariant)
911		sharedDir := filepath.Join(snapshotVariantPath, archDir, "shared")
912		checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.so", sharedDir, sharedVariant)
913		checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.so", sharedDir, sharedVariant)
914		jsonFiles = append(jsonFiles,
915			filepath.Join(sharedDir, "libvendor.so.json"),
916			filepath.Join(sharedDir, "libvendor_available.so.json"))
917
918		// For static libraries, all vendor:true and vendor_available modules (including VNDK) are captured.
919		staticVariant := fmt.Sprintf("android_vendor.VER_%s_%s_static", archType, archVariant)
920		staticDir := filepath.Join(snapshotVariantPath, archDir, "static")
921		checkSnapshot(t, ctx, snapshotSingleton, "libb", "libb.a", staticDir, staticVariant)
922		checkSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.a", staticDir, staticVariant)
923		checkSnapshot(t, ctx, snapshotSingleton, "libvendor", "libvendor.a", staticDir, staticVariant)
924		checkSnapshot(t, ctx, snapshotSingleton, "libvendor_available", "libvendor_available.a", staticDir, staticVariant)
925		jsonFiles = append(jsonFiles,
926			filepath.Join(staticDir, "libb.a.json"),
927			filepath.Join(staticDir, "libvndk.a.json"),
928			filepath.Join(staticDir, "libvendor.a.json"),
929			filepath.Join(staticDir, "libvendor_available.a.json"))
930
931		// For binary executables, all vendor:true and vendor_available modules are captured.
932		if archType == "arm64" {
933			binaryVariant := fmt.Sprintf("android_vendor.VER_%s_%s", archType, archVariant)
934			binaryDir := filepath.Join(snapshotVariantPath, archDir, "binary")
935			checkSnapshot(t, ctx, snapshotSingleton, "vendor_bin", "vendor_bin", binaryDir, binaryVariant)
936			checkSnapshot(t, ctx, snapshotSingleton, "vendor_available_bin", "vendor_available_bin", binaryDir, binaryVariant)
937			jsonFiles = append(jsonFiles,
938				filepath.Join(binaryDir, "vendor_bin.json"),
939				filepath.Join(binaryDir, "vendor_available_bin.json"))
940		}
941
942		// For header libraries, all vendor:true and vendor_available modules are captured.
943		headerDir := filepath.Join(snapshotVariantPath, archDir, "header")
944		jsonFiles = append(jsonFiles, filepath.Join(headerDir, "libvendor_headers.json"))
945
946		// For object modules, all vendor:true and vendor_available modules are captured.
947		objectVariant := fmt.Sprintf("android_vendor.VER_%s_%s", archType, archVariant)
948		objectDir := filepath.Join(snapshotVariantPath, archDir, "object")
949		checkSnapshot(t, ctx, snapshotSingleton, "obj", "obj.o", objectDir, objectVariant)
950		jsonFiles = append(jsonFiles, filepath.Join(objectDir, "obj.o.json"))
951	}
952
953	for _, jsonFile := range jsonFiles {
954		// verify all json files exist
955		if snapshotSingleton.MaybeOutput(jsonFile).Rule == nil {
956			t.Errorf("%q expected but not found", jsonFile)
957		}
958	}
959}
960
961func TestDoubleLoadableDepError(t *testing.T) {
962	// Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib.
963	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
964		cc_library {
965			name: "libllndk",
966			shared_libs: ["libnondoubleloadable"],
967		}
968
969		llndk_library {
970			name: "libllndk",
971			symbol_file: "",
972		}
973
974		cc_library {
975			name: "libnondoubleloadable",
976			vendor_available: true,
977			vndk: {
978				enabled: true,
979			},
980		}
981	`)
982
983	// Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib.
984	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
985		cc_library {
986			name: "libllndk",
987			no_libcrt: true,
988			shared_libs: ["libnondoubleloadable"],
989		}
990
991		llndk_library {
992			name: "libllndk",
993			symbol_file: "",
994		}
995
996		cc_library {
997			name: "libnondoubleloadable",
998			vendor_available: true,
999		}
1000	`)
1001
1002	// Check whether an error is emitted when a double_loadable lib depends on a non-double_loadable vendor_available lib.
1003	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
1004		cc_library {
1005			name: "libdoubleloadable",
1006			vendor_available: true,
1007			double_loadable: true,
1008			shared_libs: ["libnondoubleloadable"],
1009		}
1010
1011		cc_library {
1012			name: "libnondoubleloadable",
1013			vendor_available: true,
1014		}
1015	`)
1016
1017	// Check whether an error is emitted when a double_loadable lib depends on a non-double_loadable VNDK lib.
1018	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
1019		cc_library {
1020			name: "libdoubleloadable",
1021			vendor_available: true,
1022			double_loadable: true,
1023			shared_libs: ["libnondoubleloadable"],
1024		}
1025
1026		cc_library {
1027			name: "libnondoubleloadable",
1028			vendor_available: true,
1029			vndk: {
1030				enabled: true,
1031			},
1032		}
1033	`)
1034
1035	// Check whether an error is emitted when a double_loadable VNDK depends on a non-double_loadable VNDK private lib.
1036	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
1037		cc_library {
1038			name: "libdoubleloadable",
1039			vendor_available: true,
1040			vndk: {
1041				enabled: true,
1042			},
1043			double_loadable: true,
1044			shared_libs: ["libnondoubleloadable"],
1045		}
1046
1047		cc_library {
1048			name: "libnondoubleloadable",
1049			vendor_available: false,
1050			vndk: {
1051				enabled: true,
1052			},
1053		}
1054	`)
1055
1056	// Check whether an error is emitted when a LLNDK depends on a non-double_loadable indirectly.
1057	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
1058		cc_library {
1059			name: "libllndk",
1060			shared_libs: ["libcoreonly"],
1061		}
1062
1063		llndk_library {
1064			name: "libllndk",
1065			symbol_file: "",
1066		}
1067
1068		cc_library {
1069			name: "libcoreonly",
1070			shared_libs: ["libvendoravailable"],
1071		}
1072
1073		// indirect dependency of LLNDK
1074		cc_library {
1075			name: "libvendoravailable",
1076			vendor_available: true,
1077		}
1078	`)
1079}
1080
1081func TestVndkExt(t *testing.T) {
1082	// This test checks the VNDK-Ext properties.
1083	bp := `
1084		cc_library {
1085			name: "libvndk",
1086			vendor_available: true,
1087			vndk: {
1088				enabled: true,
1089			},
1090			nocrt: true,
1091		}
1092		cc_library {
1093			name: "libvndk2",
1094			vendor_available: true,
1095			vndk: {
1096				enabled: true,
1097			},
1098			target: {
1099				vendor: {
1100					suffix: "-suffix",
1101				},
1102			},
1103			nocrt: true,
1104		}
1105
1106		cc_library {
1107			name: "libvndk_ext",
1108			vendor: true,
1109			vndk: {
1110				enabled: true,
1111				extends: "libvndk",
1112			},
1113			nocrt: true,
1114		}
1115
1116		cc_library {
1117			name: "libvndk2_ext",
1118			vendor: true,
1119			vndk: {
1120				enabled: true,
1121				extends: "libvndk2",
1122			},
1123			nocrt: true,
1124		}
1125
1126		cc_library {
1127			name: "libvndk_ext_product",
1128			product_specific: true,
1129			vndk: {
1130				enabled: true,
1131				extends: "libvndk",
1132			},
1133			nocrt: true,
1134		}
1135
1136		cc_library {
1137			name: "libvndk2_ext_product",
1138			product_specific: true,
1139			vndk: {
1140				enabled: true,
1141				extends: "libvndk2",
1142			},
1143			nocrt: true,
1144		}
1145	`
1146	config := TestConfig(buildDir, android.Android, nil, bp, nil)
1147	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
1148	config.TestProductVariables.ProductVndkVersion = StringPtr("current")
1149	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
1150
1151	ctx := testCcWithConfig(t, config)
1152
1153	checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk", vendorVariant)
1154	checkVndkModule(t, ctx, "libvndk_ext_product", "vndk", false, "libvndk", productVariant)
1155
1156	mod_vendor := ctx.ModuleForTests("libvndk2_ext", vendorVariant).Module().(*Module)
1157	assertString(t, mod_vendor.outputFile.Path().Base(), "libvndk2-suffix.so")
1158
1159	mod_product := ctx.ModuleForTests("libvndk2_ext_product", productVariant).Module().(*Module)
1160	assertString(t, mod_product.outputFile.Path().Base(), "libvndk2-suffix.so")
1161}
1162
1163func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
1164	// This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
1165	ctx := testCcNoVndk(t, `
1166		cc_library {
1167			name: "libvndk",
1168			vendor_available: true,
1169			vndk: {
1170				enabled: true,
1171			},
1172			nocrt: true,
1173		}
1174
1175		cc_library {
1176			name: "libvndk_ext",
1177			vendor: true,
1178			vndk: {
1179				enabled: true,
1180				extends: "libvndk",
1181			},
1182			nocrt: true,
1183		}
1184	`)
1185
1186	// Ensures that the core variant of "libvndk_ext" can be found.
1187	mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
1188	if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
1189		t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
1190	}
1191}
1192
1193func TestVndkExtWithoutProductVndkVersion(t *testing.T) {
1194	// This test checks the VNDK-Ext properties when PRODUCT_PRODUCT_VNDK_VERSION is not set.
1195	ctx := testCc(t, `
1196		cc_library {
1197			name: "libvndk",
1198			vendor_available: true,
1199			vndk: {
1200				enabled: true,
1201			},
1202			nocrt: true,
1203		}
1204
1205		cc_library {
1206			name: "libvndk_ext_product",
1207			product_specific: true,
1208			vndk: {
1209				enabled: true,
1210				extends: "libvndk",
1211			},
1212			nocrt: true,
1213		}
1214	`)
1215
1216	// Ensures that the core variant of "libvndk_ext_product" can be found.
1217	mod := ctx.ModuleForTests("libvndk_ext_product", coreVariant).Module().(*Module)
1218	if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
1219		t.Errorf("\"libvndk_ext_product\" must extend from \"libvndk\" but get %q", extends)
1220	}
1221}
1222
1223func TestVndkExtError(t *testing.T) {
1224	// This test ensures an error is emitted in ill-formed vndk-ext definition.
1225	testCcError(t, "must set `vendor: true` or `product_specific: true` to set `extends: \".*\"`", `
1226		cc_library {
1227			name: "libvndk",
1228			vendor_available: true,
1229			vndk: {
1230				enabled: true,
1231			},
1232			nocrt: true,
1233		}
1234
1235		cc_library {
1236			name: "libvndk_ext",
1237			vndk: {
1238				enabled: true,
1239				extends: "libvndk",
1240			},
1241			nocrt: true,
1242		}
1243	`)
1244
1245	testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
1246		cc_library {
1247			name: "libvndk",
1248			vendor_available: true,
1249			vndk: {
1250				enabled: true,
1251			},
1252			nocrt: true,
1253		}
1254
1255		cc_library {
1256			name: "libvndk_ext",
1257			vendor: true,
1258			vndk: {
1259				enabled: true,
1260			},
1261			nocrt: true,
1262		}
1263	`)
1264
1265	testCcErrorProductVndk(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
1266		cc_library {
1267			name: "libvndk",
1268			vendor_available: true,
1269			vndk: {
1270				enabled: true,
1271			},
1272			nocrt: true,
1273		}
1274
1275		cc_library {
1276			name: "libvndk_ext_product",
1277			product_specific: true,
1278			vndk: {
1279				enabled: true,
1280			},
1281			nocrt: true,
1282		}
1283	`)
1284
1285	testCcErrorProductVndk(t, "must not set at the same time as `vndk: {extends: \"\\.\\.\\.\"}`", `
1286		cc_library {
1287			name: "libvndk",
1288			vendor_available: true,
1289			vndk: {
1290				enabled: true,
1291			},
1292			nocrt: true,
1293		}
1294
1295		cc_library {
1296			name: "libvndk_ext_product",
1297			product_specific: true,
1298			vendor_available: true,
1299			vndk: {
1300				enabled: true,
1301				extends: "libvndk",
1302			},
1303			nocrt: true,
1304		}
1305	`)
1306}
1307
1308func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
1309	// This test ensures an error is emitted for inconsistent support_system_process.
1310	testCcError(t, "module \".*\" with mismatched support_system_process", `
1311		cc_library {
1312			name: "libvndk",
1313			vendor_available: true,
1314			vndk: {
1315				enabled: true,
1316			},
1317			nocrt: true,
1318		}
1319
1320		cc_library {
1321			name: "libvndk_sp_ext",
1322			vendor: true,
1323			vndk: {
1324				enabled: true,
1325				extends: "libvndk",
1326				support_system_process: true,
1327			},
1328			nocrt: true,
1329		}
1330	`)
1331
1332	testCcError(t, "module \".*\" with mismatched support_system_process", `
1333		cc_library {
1334			name: "libvndk_sp",
1335			vendor_available: true,
1336			vndk: {
1337				enabled: true,
1338				support_system_process: true,
1339			},
1340			nocrt: true,
1341		}
1342
1343		cc_library {
1344			name: "libvndk_ext",
1345			vendor: true,
1346			vndk: {
1347				enabled: true,
1348				extends: "libvndk_sp",
1349			},
1350			nocrt: true,
1351		}
1352	`)
1353}
1354
1355func TestVndkExtVendorAvailableFalseError(t *testing.T) {
1356	// This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
1357	// with `vendor_available: false`.
1358	testCcError(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
1359		cc_library {
1360			name: "libvndk",
1361			vendor_available: false,
1362			vndk: {
1363				enabled: true,
1364			},
1365			nocrt: true,
1366		}
1367
1368		cc_library {
1369			name: "libvndk_ext",
1370			vendor: true,
1371			vndk: {
1372				enabled: true,
1373				extends: "libvndk",
1374			},
1375			nocrt: true,
1376		}
1377	`)
1378
1379	testCcErrorProductVndk(t, "`extends` refers module \".*\" which does not have `vendor_available: true`", `
1380		cc_library {
1381			name: "libvndk",
1382			vendor_available: false,
1383			vndk: {
1384				enabled: true,
1385			},
1386			nocrt: true,
1387		}
1388
1389		cc_library {
1390			name: "libvndk_ext_product",
1391			product_specific: true,
1392			vndk: {
1393				enabled: true,
1394				extends: "libvndk",
1395			},
1396			nocrt: true,
1397		}
1398	`)
1399}
1400
1401func TestVendorModuleUseVndkExt(t *testing.T) {
1402	// This test ensures a vendor module can depend on a VNDK-Ext library.
1403	testCc(t, `
1404		cc_library {
1405			name: "libvndk",
1406			vendor_available: true,
1407			vndk: {
1408				enabled: true,
1409			},
1410			nocrt: true,
1411		}
1412
1413		cc_library {
1414			name: "libvndk_ext",
1415			vendor: true,
1416			vndk: {
1417				enabled: true,
1418				extends: "libvndk",
1419			},
1420			nocrt: true,
1421		}
1422
1423		cc_library {
1424			name: "libvndk_sp",
1425			vendor_available: true,
1426			vndk: {
1427				enabled: true,
1428				support_system_process: true,
1429			},
1430			nocrt: true,
1431		}
1432
1433		cc_library {
1434			name: "libvndk_sp_ext",
1435			vendor: true,
1436			vndk: {
1437				enabled: true,
1438				extends: "libvndk_sp",
1439				support_system_process: true,
1440			},
1441			nocrt: true,
1442		}
1443
1444		cc_library {
1445			name: "libvendor",
1446			vendor: true,
1447			shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
1448			nocrt: true,
1449		}
1450	`)
1451}
1452
1453func TestVndkExtUseVendorLib(t *testing.T) {
1454	// This test ensures a VNDK-Ext library can depend on a vendor library.
1455	testCc(t, `
1456		cc_library {
1457			name: "libvndk",
1458			vendor_available: true,
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			shared_libs: ["libvendor"],
1473			nocrt: true,
1474		}
1475
1476		cc_library {
1477			name: "libvendor",
1478			vendor: true,
1479			nocrt: true,
1480		}
1481	`)
1482
1483	// This test ensures a VNDK-SP-Ext library can depend on a vendor library.
1484	testCc(t, `
1485		cc_library {
1486			name: "libvndk_sp",
1487			vendor_available: true,
1488			vndk: {
1489				enabled: true,
1490				support_system_process: true,
1491			},
1492			nocrt: true,
1493		}
1494
1495		cc_library {
1496			name: "libvndk_sp_ext",
1497			vendor: true,
1498			vndk: {
1499				enabled: true,
1500				extends: "libvndk_sp",
1501				support_system_process: true,
1502			},
1503			shared_libs: ["libvendor"],  // Cause an error
1504			nocrt: true,
1505		}
1506
1507		cc_library {
1508			name: "libvendor",
1509			vendor: true,
1510			nocrt: true,
1511		}
1512	`)
1513}
1514
1515func TestProductVndkExtDependency(t *testing.T) {
1516	bp := `
1517		cc_library {
1518			name: "libvndk",
1519			vendor_available: true,
1520			vndk: {
1521				enabled: true,
1522			},
1523			nocrt: true,
1524		}
1525
1526		cc_library {
1527			name: "libvndk_ext_product",
1528			product_specific: true,
1529			vndk: {
1530				enabled: true,
1531				extends: "libvndk",
1532			},
1533			shared_libs: ["libproduct_for_vndklibs"],
1534			nocrt: true,
1535		}
1536
1537		cc_library {
1538			name: "libvndk_sp",
1539			vendor_available: true,
1540			vndk: {
1541				enabled: true,
1542				support_system_process: true,
1543			},
1544			nocrt: true,
1545		}
1546
1547		cc_library {
1548			name: "libvndk_sp_ext_product",
1549			product_specific: true,
1550			vndk: {
1551				enabled: true,
1552				extends: "libvndk_sp",
1553				support_system_process: true,
1554			},
1555			shared_libs: ["libproduct_for_vndklibs"],
1556			nocrt: true,
1557		}
1558
1559		cc_library {
1560			name: "libproduct",
1561			product_specific: true,
1562			shared_libs: ["libvndk_ext_product", "libvndk_sp_ext_product"],
1563			nocrt: true,
1564		}
1565
1566		cc_library {
1567			name: "libproduct_for_vndklibs",
1568			product_specific: true,
1569			nocrt: true,
1570		}
1571	`
1572	config := TestConfig(buildDir, android.Android, nil, bp, nil)
1573	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
1574	config.TestProductVariables.ProductVndkVersion = StringPtr("current")
1575	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
1576
1577	testCcWithConfig(t, config)
1578}
1579
1580func TestVndkSpExtUseVndkError(t *testing.T) {
1581	// This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
1582	// library.
1583	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1584		cc_library {
1585			name: "libvndk",
1586			vendor_available: true,
1587			vndk: {
1588				enabled: true,
1589			},
1590			nocrt: true,
1591		}
1592
1593		cc_library {
1594			name: "libvndk_sp",
1595			vendor_available: true,
1596			vndk: {
1597				enabled: true,
1598				support_system_process: true,
1599			},
1600			nocrt: true,
1601		}
1602
1603		cc_library {
1604			name: "libvndk_sp_ext",
1605			vendor: true,
1606			vndk: {
1607				enabled: true,
1608				extends: "libvndk_sp",
1609				support_system_process: true,
1610			},
1611			shared_libs: ["libvndk"],  // Cause an error
1612			nocrt: true,
1613		}
1614	`)
1615
1616	// This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
1617	// library.
1618	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1619		cc_library {
1620			name: "libvndk",
1621			vendor_available: true,
1622			vndk: {
1623				enabled: true,
1624			},
1625			nocrt: true,
1626		}
1627
1628		cc_library {
1629			name: "libvndk_ext",
1630			vendor: true,
1631			vndk: {
1632				enabled: true,
1633				extends: "libvndk",
1634			},
1635			nocrt: true,
1636		}
1637
1638		cc_library {
1639			name: "libvndk_sp",
1640			vendor_available: true,
1641			vndk: {
1642				enabled: true,
1643				support_system_process: true,
1644			},
1645			nocrt: true,
1646		}
1647
1648		cc_library {
1649			name: "libvndk_sp_ext",
1650			vendor: true,
1651			vndk: {
1652				enabled: true,
1653				extends: "libvndk_sp",
1654				support_system_process: true,
1655			},
1656			shared_libs: ["libvndk_ext"],  // Cause an error
1657			nocrt: true,
1658		}
1659	`)
1660}
1661
1662func TestVndkUseVndkExtError(t *testing.T) {
1663	// This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
1664	// VNDK-Ext/VNDK-SP-Ext library.
1665	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1666		cc_library {
1667			name: "libvndk",
1668			vendor_available: true,
1669			vndk: {
1670				enabled: true,
1671			},
1672			nocrt: true,
1673		}
1674
1675		cc_library {
1676			name: "libvndk_ext",
1677			vendor: true,
1678			vndk: {
1679				enabled: true,
1680				extends: "libvndk",
1681			},
1682			nocrt: true,
1683		}
1684
1685		cc_library {
1686			name: "libvndk2",
1687			vendor_available: true,
1688			vndk: {
1689				enabled: true,
1690			},
1691			shared_libs: ["libvndk_ext"],
1692			nocrt: true,
1693		}
1694	`)
1695
1696	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1697		cc_library {
1698			name: "libvndk",
1699			vendor_available: true,
1700			vndk: {
1701				enabled: true,
1702			},
1703			nocrt: true,
1704		}
1705
1706		cc_library {
1707			name: "libvndk_ext",
1708			vendor: true,
1709			vndk: {
1710				enabled: true,
1711				extends: "libvndk",
1712			},
1713			nocrt: true,
1714		}
1715
1716		cc_library {
1717			name: "libvndk2",
1718			vendor_available: true,
1719			vndk: {
1720				enabled: true,
1721			},
1722			target: {
1723				vendor: {
1724					shared_libs: ["libvndk_ext"],
1725				},
1726			},
1727			nocrt: true,
1728		}
1729	`)
1730
1731	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1732		cc_library {
1733			name: "libvndk_sp",
1734			vendor_available: true,
1735			vndk: {
1736				enabled: true,
1737				support_system_process: true,
1738			},
1739			nocrt: true,
1740		}
1741
1742		cc_library {
1743			name: "libvndk_sp_ext",
1744			vendor: true,
1745			vndk: {
1746				enabled: true,
1747				extends: "libvndk_sp",
1748				support_system_process: true,
1749			},
1750			nocrt: true,
1751		}
1752
1753		cc_library {
1754			name: "libvndk_sp_2",
1755			vendor_available: true,
1756			vndk: {
1757				enabled: true,
1758				support_system_process: true,
1759			},
1760			shared_libs: ["libvndk_sp_ext"],
1761			nocrt: true,
1762		}
1763	`)
1764
1765	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1766		cc_library {
1767			name: "libvndk_sp",
1768			vendor_available: true,
1769			vndk: {
1770				enabled: true,
1771			},
1772			nocrt: true,
1773		}
1774
1775		cc_library {
1776			name: "libvndk_sp_ext",
1777			vendor: true,
1778			vndk: {
1779				enabled: true,
1780				extends: "libvndk_sp",
1781			},
1782			nocrt: true,
1783		}
1784
1785		cc_library {
1786			name: "libvndk_sp2",
1787			vendor_available: true,
1788			vndk: {
1789				enabled: true,
1790			},
1791			target: {
1792				vendor: {
1793					shared_libs: ["libvndk_sp_ext"],
1794				},
1795			},
1796			nocrt: true,
1797		}
1798	`)
1799}
1800
1801func TestEnforceProductVndkVersion(t *testing.T) {
1802	bp := `
1803		cc_library {
1804			name: "libllndk",
1805		}
1806		llndk_library {
1807			name: "libllndk",
1808			symbol_file: "",
1809		}
1810		cc_library {
1811			name: "libvndk",
1812			vendor_available: true,
1813			vndk: {
1814				enabled: true,
1815			},
1816			nocrt: true,
1817		}
1818		cc_library {
1819			name: "libvndk_sp",
1820			vendor_available: true,
1821			vndk: {
1822				enabled: true,
1823				support_system_process: true,
1824			},
1825			nocrt: true,
1826		}
1827		cc_library {
1828			name: "libva",
1829			vendor_available: true,
1830			nocrt: true,
1831		}
1832		cc_library {
1833			name: "libproduct_va",
1834			product_specific: true,
1835			vendor_available: true,
1836			nocrt: true,
1837		}
1838		cc_library {
1839			name: "libprod",
1840			product_specific: true,
1841			shared_libs: [
1842				"libllndk",
1843				"libvndk",
1844				"libvndk_sp",
1845				"libva",
1846				"libproduct_va",
1847			],
1848			nocrt: true,
1849		}
1850		cc_library {
1851			name: "libvendor",
1852			vendor: true,
1853			shared_libs: [
1854				"libllndk",
1855				"libvndk",
1856				"libvndk_sp",
1857				"libva",
1858				"libproduct_va",
1859			],
1860			nocrt: true,
1861		}
1862	`
1863
1864	config := TestConfig(buildDir, android.Android, nil, bp, nil)
1865	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
1866	config.TestProductVariables.ProductVndkVersion = StringPtr("current")
1867	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
1868
1869	ctx := testCcWithConfig(t, config)
1870
1871	checkVndkModule(t, ctx, "libvndk", "vndk-VER", false, "", productVariant)
1872	checkVndkModule(t, ctx, "libvndk_sp", "vndk-sp-VER", true, "", productVariant)
1873}
1874
1875func TestEnforceProductVndkVersionErrors(t *testing.T) {
1876	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.VER", `
1877		cc_library {
1878			name: "libprod",
1879			product_specific: true,
1880			shared_libs: [
1881				"libvendor",
1882			],
1883			nocrt: true,
1884		}
1885		cc_library {
1886			name: "libvendor",
1887			vendor: true,
1888			nocrt: true,
1889		}
1890	`)
1891	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.VER", `
1892		cc_library {
1893			name: "libprod",
1894			product_specific: true,
1895			shared_libs: [
1896				"libsystem",
1897			],
1898			nocrt: true,
1899		}
1900		cc_library {
1901			name: "libsystem",
1902			nocrt: true,
1903		}
1904	`)
1905	testCcErrorProductVndk(t, "Vendor module that is not VNDK should not link to \".*\" which is marked as `vendor_available: false`", `
1906		cc_library {
1907			name: "libprod",
1908			product_specific: true,
1909			shared_libs: [
1910				"libvndk_private",
1911			],
1912			nocrt: true,
1913		}
1914		cc_library {
1915			name: "libvndk_private",
1916			vendor_available: false,
1917			vndk: {
1918				enabled: true,
1919			},
1920			nocrt: true,
1921		}
1922	`)
1923	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.VER", `
1924		cc_library {
1925			name: "libprod",
1926			product_specific: true,
1927			shared_libs: [
1928				"libsystem_ext",
1929			],
1930			nocrt: true,
1931		}
1932		cc_library {
1933			name: "libsystem_ext",
1934			system_ext_specific: true,
1935			nocrt: true,
1936		}
1937	`)
1938	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:", `
1939		cc_library {
1940			name: "libsystem",
1941			shared_libs: [
1942				"libproduct_va",
1943			],
1944			nocrt: true,
1945		}
1946		cc_library {
1947			name: "libproduct_va",
1948			product_specific: true,
1949			vendor_available: true,
1950			nocrt: true,
1951		}
1952	`)
1953}
1954
1955func TestMakeLinkType(t *testing.T) {
1956	bp := `
1957		cc_library {
1958			name: "libvndk",
1959			vendor_available: true,
1960			vndk: {
1961				enabled: true,
1962			},
1963		}
1964		cc_library {
1965			name: "libvndksp",
1966			vendor_available: true,
1967			vndk: {
1968				enabled: true,
1969				support_system_process: true,
1970			},
1971		}
1972		cc_library {
1973			name: "libvndkprivate",
1974			vendor_available: false,
1975			vndk: {
1976				enabled: true,
1977			},
1978		}
1979		cc_library {
1980			name: "libvendor",
1981			vendor: true,
1982		}
1983		cc_library {
1984			name: "libvndkext",
1985			vendor: true,
1986			vndk: {
1987				enabled: true,
1988				extends: "libvndk",
1989			},
1990		}
1991		vndk_prebuilt_shared {
1992			name: "prevndk",
1993			version: "27",
1994			target_arch: "arm",
1995			binder32bit: true,
1996			vendor_available: true,
1997			vndk: {
1998				enabled: true,
1999			},
2000			arch: {
2001				arm: {
2002					srcs: ["liba.so"],
2003				},
2004			},
2005		}
2006		cc_library {
2007			name: "libllndk",
2008		}
2009		llndk_library {
2010			name: "libllndk",
2011			symbol_file: "",
2012		}
2013		cc_library {
2014			name: "libllndkprivate",
2015		}
2016		llndk_library {
2017			name: "libllndkprivate",
2018			vendor_available: false,
2019			symbol_file: "",
2020		}`
2021
2022	config := TestConfig(buildDir, android.Android, nil, bp, nil)
2023	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
2024	config.TestProductVariables.Platform_vndk_version = StringPtr("VER")
2025	// native:vndk
2026	ctx := testCcWithConfig(t, config)
2027
2028	assertMapKeys(t, vndkCoreLibraries(config),
2029		[]string{"libvndk", "libvndkprivate"})
2030	assertMapKeys(t, vndkSpLibraries(config),
2031		[]string{"libc++", "libvndksp"})
2032	assertMapKeys(t, llndkLibraries(config),
2033		[]string{"libc", "libdl", "libft2", "libllndk", "libllndkprivate", "libm"})
2034	assertMapKeys(t, vndkPrivateLibraries(config),
2035		[]string{"libft2", "libllndkprivate", "libvndkprivate"})
2036
2037	vendorVariant27 := "android_vendor.27_arm64_armv8-a_shared"
2038
2039	tests := []struct {
2040		variant  string
2041		name     string
2042		expected string
2043	}{
2044		{vendorVariant, "libvndk", "native:vndk"},
2045		{vendorVariant, "libvndksp", "native:vndk"},
2046		{vendorVariant, "libvndkprivate", "native:vndk_private"},
2047		{vendorVariant, "libvendor", "native:vendor"},
2048		{vendorVariant, "libvndkext", "native:vendor"},
2049		{vendorVariant, "libllndk.llndk", "native:vndk"},
2050		{vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vndk"},
2051		{coreVariant, "libvndk", "native:platform"},
2052		{coreVariant, "libvndkprivate", "native:platform"},
2053		{coreVariant, "libllndk", "native:platform"},
2054	}
2055	for _, test := range tests {
2056		t.Run(test.name, func(t *testing.T) {
2057			module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module)
2058			assertString(t, module.makeLinkType, test.expected)
2059		})
2060	}
2061}
2062
2063var (
2064	str11 = "01234567891"
2065	str10 = str11[:10]
2066	str9  = str11[:9]
2067	str5  = str11[:5]
2068	str4  = str11[:4]
2069)
2070
2071var splitListForSizeTestCases = []struct {
2072	in   []string
2073	out  [][]string
2074	size int
2075}{
2076	{
2077		in:   []string{str10},
2078		out:  [][]string{{str10}},
2079		size: 10,
2080	},
2081	{
2082		in:   []string{str9},
2083		out:  [][]string{{str9}},
2084		size: 10,
2085	},
2086	{
2087		in:   []string{str5},
2088		out:  [][]string{{str5}},
2089		size: 10,
2090	},
2091	{
2092		in:   []string{str11},
2093		out:  nil,
2094		size: 10,
2095	},
2096	{
2097		in:   []string{str10, str10},
2098		out:  [][]string{{str10}, {str10}},
2099		size: 10,
2100	},
2101	{
2102		in:   []string{str9, str10},
2103		out:  [][]string{{str9}, {str10}},
2104		size: 10,
2105	},
2106	{
2107		in:   []string{str10, str9},
2108		out:  [][]string{{str10}, {str9}},
2109		size: 10,
2110	},
2111	{
2112		in:   []string{str5, str4},
2113		out:  [][]string{{str5, str4}},
2114		size: 10,
2115	},
2116	{
2117		in:   []string{str5, str4, str5},
2118		out:  [][]string{{str5, str4}, {str5}},
2119		size: 10,
2120	},
2121	{
2122		in:   []string{str5, str4, str5, str4},
2123		out:  [][]string{{str5, str4}, {str5, str4}},
2124		size: 10,
2125	},
2126	{
2127		in:   []string{str5, str4, str5, str5},
2128		out:  [][]string{{str5, str4}, {str5}, {str5}},
2129		size: 10,
2130	},
2131	{
2132		in:   []string{str5, str5, str5, str4},
2133		out:  [][]string{{str5}, {str5}, {str5, str4}},
2134		size: 10,
2135	},
2136	{
2137		in:   []string{str9, str11},
2138		out:  nil,
2139		size: 10,
2140	},
2141	{
2142		in:   []string{str11, str9},
2143		out:  nil,
2144		size: 10,
2145	},
2146}
2147
2148func TestSplitListForSize(t *testing.T) {
2149	for _, testCase := range splitListForSizeTestCases {
2150		out, _ := splitListForSize(android.PathsForTesting(testCase.in...), testCase.size)
2151
2152		var outStrings [][]string
2153
2154		if len(out) > 0 {
2155			outStrings = make([][]string, len(out))
2156			for i, o := range out {
2157				outStrings[i] = o.Strings()
2158			}
2159		}
2160
2161		if !reflect.DeepEqual(outStrings, testCase.out) {
2162			t.Errorf("incorrect output:")
2163			t.Errorf("     input: %#v", testCase.in)
2164			t.Errorf("      size: %d", testCase.size)
2165			t.Errorf("  expected: %#v", testCase.out)
2166			t.Errorf("       got: %#v", outStrings)
2167		}
2168	}
2169}
2170
2171var staticLinkDepOrderTestCases = []struct {
2172	// This is a string representation of a map[moduleName][]moduleDependency .
2173	// It models the dependencies declared in an Android.bp file.
2174	inStatic string
2175
2176	// This is a string representation of a map[moduleName][]moduleDependency .
2177	// It models the dependencies declared in an Android.bp file.
2178	inShared string
2179
2180	// allOrdered is a string representation of a map[moduleName][]moduleDependency .
2181	// The keys of allOrdered specify which modules we would like to check.
2182	// The values of allOrdered specify the expected result (of the transitive closure of all
2183	// dependencies) for each module to test
2184	allOrdered string
2185
2186	// outOrdered is a string representation of a map[moduleName][]moduleDependency .
2187	// The keys of outOrdered specify which modules we would like to check.
2188	// The values of outOrdered specify the expected result (of the ordered linker command line)
2189	// for each module to test.
2190	outOrdered string
2191}{
2192	// Simple tests
2193	{
2194		inStatic:   "",
2195		outOrdered: "",
2196	},
2197	{
2198		inStatic:   "a:",
2199		outOrdered: "a:",
2200	},
2201	{
2202		inStatic:   "a:b; b:",
2203		outOrdered: "a:b; b:",
2204	},
2205	// Tests of reordering
2206	{
2207		// diamond example
2208		inStatic:   "a:d,b,c; b:d; c:d; d:",
2209		outOrdered: "a:b,c,d; b:d; c:d; d:",
2210	},
2211	{
2212		// somewhat real example
2213		inStatic:   "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
2214		outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
2215	},
2216	{
2217		// multiple reorderings
2218		inStatic:   "a:b,c,d,e; d:b; e:c",
2219		outOrdered: "a:d,b,e,c; d:b; e:c",
2220	},
2221	{
2222		// should reorder without adding new transitive dependencies
2223		inStatic:   "bin:lib2,lib1;             lib1:lib2,liboptional",
2224		allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
2225		outOrdered: "bin:lib1,lib2;             lib1:lib2,liboptional",
2226	},
2227	{
2228		// multiple levels of dependencies
2229		inStatic:   "a:b,c,d,e,f,g,h; f:b,c,d; b:c,d; c:d",
2230		allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
2231		outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
2232	},
2233	// shared dependencies
2234	{
2235		// Note that this test doesn't recurse, to minimize the amount of logic it tests.
2236		// So, we don't actually have to check that a shared dependency of c will change the order
2237		// of a library that depends statically on b and on c.  We only need to check that if c has
2238		// a shared dependency on b, that that shows up in allOrdered.
2239		inShared:   "c:b",
2240		allOrdered: "c:b",
2241		outOrdered: "c:",
2242	},
2243	{
2244		// This test doesn't actually include any shared dependencies but it's a reminder of what
2245		// the second phase of the above test would look like
2246		inStatic:   "a:b,c; c:b",
2247		allOrdered: "a:c,b; c:b",
2248		outOrdered: "a:c,b; c:b",
2249	},
2250	// tiebreakers for when two modules specifying different orderings and there is no dependency
2251	// to dictate an order
2252	{
2253		// if the tie is between two modules at the end of a's deps, then a's order wins
2254		inStatic:   "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
2255		outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
2256	},
2257	{
2258		// if the tie is between two modules at the start of a's deps, then c's order is used
2259		inStatic:   "a1:d,e,b1,c1; b1:d,e; c1:e,d;   a2:d,e,b2,c2; b2:d,e; c2:d,e",
2260		outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d;   a2:b2,c2,d,e; b2:d,e; c2:d,e",
2261	},
2262	// Tests involving duplicate dependencies
2263	{
2264		// simple duplicate
2265		inStatic:   "a:b,c,c,b",
2266		outOrdered: "a:c,b",
2267	},
2268	{
2269		// duplicates with reordering
2270		inStatic:   "a:b,c,d,c; c:b",
2271		outOrdered: "a:d,c,b",
2272	},
2273	// Tests to confirm the nonexistence of infinite loops.
2274	// These cases should never happen, so as long as the test terminates and the
2275	// result is deterministic then that should be fine.
2276	{
2277		inStatic:   "a:a",
2278		outOrdered: "a:a",
2279	},
2280	{
2281		inStatic:   "a:b;   b:c;   c:a",
2282		allOrdered: "a:b,c; b:c,a; c:a,b",
2283		outOrdered: "a:b;   b:c;   c:a",
2284	},
2285	{
2286		inStatic:   "a:b,c;   b:c,a;   c:a,b",
2287		allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
2288		outOrdered: "a:c,b;   b:a,c;   c:b,a",
2289	},
2290}
2291
2292// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
2293func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
2294	// convert from "a:b,c; d:e" to "a:b,c;d:e"
2295	strippedText := strings.Replace(text, " ", "", -1)
2296	if len(strippedText) < 1 {
2297		return []android.Path{}, make(map[android.Path][]android.Path, 0)
2298	}
2299	allDeps = make(map[android.Path][]android.Path, 0)
2300
2301	// convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
2302	moduleTexts := strings.Split(strippedText, ";")
2303
2304	outputForModuleName := func(moduleName string) android.Path {
2305		return android.PathForTesting(moduleName)
2306	}
2307
2308	for _, moduleText := range moduleTexts {
2309		// convert from "a:b,c" to ["a", "b,c"]
2310		components := strings.Split(moduleText, ":")
2311		if len(components) != 2 {
2312			panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
2313		}
2314		moduleName := components[0]
2315		moduleOutput := outputForModuleName(moduleName)
2316		modulesInOrder = append(modulesInOrder, moduleOutput)
2317
2318		depString := components[1]
2319		// convert from "b,c" to ["b", "c"]
2320		depNames := strings.Split(depString, ",")
2321		if len(depString) < 1 {
2322			depNames = []string{}
2323		}
2324		var deps []android.Path
2325		for _, depName := range depNames {
2326			deps = append(deps, outputForModuleName(depName))
2327		}
2328		allDeps[moduleOutput] = deps
2329	}
2330	return modulesInOrder, allDeps
2331}
2332
2333func TestLinkReordering(t *testing.T) {
2334	for _, testCase := range staticLinkDepOrderTestCases {
2335		errs := []string{}
2336
2337		// parse testcase
2338		_, givenTransitiveDeps := parseModuleDeps(testCase.inStatic)
2339		expectedModuleNames, expectedTransitiveDeps := parseModuleDeps(testCase.outOrdered)
2340		if testCase.allOrdered == "" {
2341			// allow the test case to skip specifying allOrdered
2342			testCase.allOrdered = testCase.outOrdered
2343		}
2344		_, expectedAllDeps := parseModuleDeps(testCase.allOrdered)
2345		_, givenAllSharedDeps := parseModuleDeps(testCase.inShared)
2346
2347		// For each module whose post-reordered dependencies were specified, validate that
2348		// reordering the inputs produces the expected outputs.
2349		for _, moduleName := range expectedModuleNames {
2350			moduleDeps := givenTransitiveDeps[moduleName]
2351			givenSharedDeps := givenAllSharedDeps[moduleName]
2352			orderedAllDeps, orderedDeclaredDeps := orderDeps(moduleDeps, givenSharedDeps, givenTransitiveDeps)
2353
2354			correctAllOrdered := expectedAllDeps[moduleName]
2355			if !reflect.DeepEqual(orderedAllDeps, correctAllOrdered) {
2356				errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedAllDeps."+
2357					"\nin static:%q"+
2358					"\nin shared:%q"+
2359					"\nmodule:   %v"+
2360					"\nexpected: %s"+
2361					"\nactual:   %s",
2362					testCase.inStatic, testCase.inShared, moduleName, correctAllOrdered, orderedAllDeps))
2363			}
2364
2365			correctOutputDeps := expectedTransitiveDeps[moduleName]
2366			if !reflect.DeepEqual(correctOutputDeps, orderedDeclaredDeps) {
2367				errs = append(errs, fmt.Sprintf("orderDeps returned incorrect orderedDeclaredDeps."+
2368					"\nin static:%q"+
2369					"\nin shared:%q"+
2370					"\nmodule:   %v"+
2371					"\nexpected: %s"+
2372					"\nactual:   %s",
2373					testCase.inStatic, testCase.inShared, moduleName, correctOutputDeps, orderedDeclaredDeps))
2374			}
2375		}
2376
2377		if len(errs) > 0 {
2378			sort.Strings(errs)
2379			for _, err := range errs {
2380				t.Error(err)
2381			}
2382		}
2383	}
2384}
2385
2386func getOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
2387	for _, moduleName := range moduleNames {
2388		module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
2389		output := module.outputFile.Path()
2390		paths = append(paths, output)
2391	}
2392	return paths
2393}
2394
2395func TestStaticLibDepReordering(t *testing.T) {
2396	ctx := testCc(t, `
2397	cc_library {
2398		name: "a",
2399		static_libs: ["b", "c", "d"],
2400		stl: "none",
2401	}
2402	cc_library {
2403		name: "b",
2404		stl: "none",
2405	}
2406	cc_library {
2407		name: "c",
2408		static_libs: ["b"],
2409		stl: "none",
2410	}
2411	cc_library {
2412		name: "d",
2413		stl: "none",
2414	}
2415
2416	`)
2417
2418	variant := "android_arm64_armv8-a_static"
2419	moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
2420	actual := moduleA.depsInLinkOrder
2421	expected := getOutputPaths(ctx, variant, []string{"c", "b", "d"})
2422
2423	if !reflect.DeepEqual(actual, expected) {
2424		t.Errorf("staticDeps orderings were not propagated correctly"+
2425			"\nactual:   %v"+
2426			"\nexpected: %v",
2427			actual,
2428			expected,
2429		)
2430	}
2431}
2432
2433func TestStaticLibDepReorderingWithShared(t *testing.T) {
2434	ctx := testCc(t, `
2435	cc_library {
2436		name: "a",
2437		static_libs: ["b", "c"],
2438		stl: "none",
2439	}
2440	cc_library {
2441		name: "b",
2442		stl: "none",
2443	}
2444	cc_library {
2445		name: "c",
2446		shared_libs: ["b"],
2447		stl: "none",
2448	}
2449
2450	`)
2451
2452	variant := "android_arm64_armv8-a_static"
2453	moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
2454	actual := moduleA.depsInLinkOrder
2455	expected := getOutputPaths(ctx, variant, []string{"c", "b"})
2456
2457	if !reflect.DeepEqual(actual, expected) {
2458		t.Errorf("staticDeps orderings did not account for shared libs"+
2459			"\nactual:   %v"+
2460			"\nexpected: %v",
2461			actual,
2462			expected,
2463		)
2464	}
2465}
2466
2467func checkEquals(t *testing.T, message string, expected, actual interface{}) {
2468	if !reflect.DeepEqual(actual, expected) {
2469		t.Errorf(message+
2470			"\nactual:   %v"+
2471			"\nexpected: %v",
2472			actual,
2473			expected,
2474		)
2475	}
2476}
2477
2478func TestLlndkLibrary(t *testing.T) {
2479	ctx := testCc(t, `
2480	cc_library {
2481		name: "libllndk",
2482		stubs: { versions: ["1", "2"] },
2483	}
2484	llndk_library {
2485		name: "libllndk",
2486	}
2487	`)
2488	actual := ctx.ModuleVariantsForTests("libllndk.llndk")
2489	expected := []string{
2490		"android_vendor.VER_arm64_armv8-a_shared",
2491		"android_vendor.VER_arm64_armv8-a_shared_1",
2492		"android_vendor.VER_arm64_armv8-a_shared_2",
2493		"android_vendor.VER_arm_armv7-a-neon_shared",
2494		"android_vendor.VER_arm_armv7-a-neon_shared_1",
2495		"android_vendor.VER_arm_armv7-a-neon_shared_2",
2496	}
2497	checkEquals(t, "variants for llndk stubs", expected, actual)
2498
2499	params := ctx.ModuleForTests("libllndk.llndk", "android_vendor.VER_arm_armv7-a-neon_shared").Description("generate stub")
2500	checkEquals(t, "use VNDK version for default stubs", "current", params.Args["apiLevel"])
2501
2502	params = ctx.ModuleForTests("libllndk.llndk", "android_vendor.VER_arm_armv7-a-neon_shared_1").Description("generate stub")
2503	checkEquals(t, "override apiLevel for versioned stubs", "1", params.Args["apiLevel"])
2504}
2505
2506func TestLlndkHeaders(t *testing.T) {
2507	ctx := testCc(t, `
2508	llndk_headers {
2509		name: "libllndk_headers",
2510		export_include_dirs: ["my_include"],
2511	}
2512	llndk_library {
2513		name: "libllndk",
2514		export_llndk_headers: ["libllndk_headers"],
2515	}
2516	cc_library {
2517		name: "libvendor",
2518		shared_libs: ["libllndk"],
2519		vendor: true,
2520		srcs: ["foo.c"],
2521		no_libcrt: true,
2522		nocrt: true,
2523	}
2524	`)
2525
2526	// _static variant is used since _shared reuses *.o from the static variant
2527	cc := ctx.ModuleForTests("libvendor", "android_vendor.VER_arm_armv7-a-neon_static").Rule("cc")
2528	cflags := cc.Args["cFlags"]
2529	if !strings.Contains(cflags, "-Imy_include") {
2530		t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
2531	}
2532}
2533
2534func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
2535	actual := module.Properties.AndroidMkRuntimeLibs
2536	if !reflect.DeepEqual(actual, expected) {
2537		t.Errorf("incorrect runtime_libs for shared libs"+
2538			"\nactual:   %v"+
2539			"\nexpected: %v",
2540			actual,
2541			expected,
2542		)
2543	}
2544}
2545
2546const runtimeLibAndroidBp = `
2547	cc_library {
2548		name: "libvendor_available1",
2549		vendor_available: true,
2550		no_libcrt : true,
2551		nocrt : true,
2552		system_shared_libs : [],
2553	}
2554	cc_library {
2555		name: "libvendor_available2",
2556		vendor_available: true,
2557		runtime_libs: ["libvendor_available1"],
2558		no_libcrt : true,
2559		nocrt : true,
2560		system_shared_libs : [],
2561	}
2562	cc_library {
2563		name: "libvendor_available3",
2564		vendor_available: true,
2565		runtime_libs: ["libvendor_available1"],
2566		target: {
2567			vendor: {
2568				exclude_runtime_libs: ["libvendor_available1"],
2569			}
2570		},
2571		no_libcrt : true,
2572		nocrt : true,
2573		system_shared_libs : [],
2574	}
2575	cc_library {
2576		name: "libcore",
2577		runtime_libs: ["libvendor_available1"],
2578		no_libcrt : true,
2579		nocrt : true,
2580		system_shared_libs : [],
2581	}
2582	cc_library {
2583		name: "libvendor1",
2584		vendor: true,
2585		no_libcrt : true,
2586		nocrt : true,
2587		system_shared_libs : [],
2588	}
2589	cc_library {
2590		name: "libvendor2",
2591		vendor: true,
2592		runtime_libs: ["libvendor_available1", "libvendor1"],
2593		no_libcrt : true,
2594		nocrt : true,
2595		system_shared_libs : [],
2596	}
2597`
2598
2599func TestRuntimeLibs(t *testing.T) {
2600	ctx := testCc(t, runtimeLibAndroidBp)
2601
2602	// runtime_libs for core variants use the module names without suffixes.
2603	variant := "android_arm64_armv8-a_shared"
2604
2605	module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
2606	checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
2607
2608	module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
2609	checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
2610
2611	// runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
2612	// and vendor variants.
2613	variant = "android_vendor.VER_arm64_armv8-a_shared"
2614
2615	module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
2616	checkRuntimeLibs(t, []string{"libvendor_available1.vendor"}, module)
2617
2618	module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
2619	checkRuntimeLibs(t, []string{"libvendor_available1.vendor", "libvendor1"}, module)
2620}
2621
2622func TestExcludeRuntimeLibs(t *testing.T) {
2623	ctx := testCc(t, runtimeLibAndroidBp)
2624
2625	variant := "android_arm64_armv8-a_shared"
2626	module := ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
2627	checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
2628
2629	variant = "android_vendor.VER_arm64_armv8-a_shared"
2630	module = ctx.ModuleForTests("libvendor_available3", variant).Module().(*Module)
2631	checkRuntimeLibs(t, nil, module)
2632}
2633
2634func TestRuntimeLibsNoVndk(t *testing.T) {
2635	ctx := testCcNoVndk(t, runtimeLibAndroidBp)
2636
2637	// If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
2638
2639	variant := "android_arm64_armv8-a_shared"
2640
2641	module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
2642	checkRuntimeLibs(t, []string{"libvendor_available1"}, module)
2643
2644	module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
2645	checkRuntimeLibs(t, []string{"libvendor_available1", "libvendor1"}, module)
2646}
2647
2648func checkStaticLibs(t *testing.T, expected []string, module *Module) {
2649	t.Helper()
2650	actual := module.Properties.AndroidMkStaticLibs
2651	if !reflect.DeepEqual(actual, expected) {
2652		t.Errorf("incorrect static_libs"+
2653			"\nactual:   %v"+
2654			"\nexpected: %v",
2655			actual,
2656			expected,
2657		)
2658	}
2659}
2660
2661const staticLibAndroidBp = `
2662	cc_library {
2663		name: "lib1",
2664	}
2665	cc_library {
2666		name: "lib2",
2667		static_libs: ["lib1"],
2668	}
2669`
2670
2671func TestStaticLibDepExport(t *testing.T) {
2672	ctx := testCc(t, staticLibAndroidBp)
2673
2674	// Check the shared version of lib2.
2675	variant := "android_arm64_armv8-a_shared"
2676	module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
2677	checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic"}, module)
2678
2679	// Check the static version of lib2.
2680	variant = "android_arm64_armv8-a_static"
2681	module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
2682	// libc++_static is linked additionally.
2683	checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins-aarch64-android", "libatomic"}, module)
2684}
2685
2686var compilerFlagsTestCases = []struct {
2687	in  string
2688	out bool
2689}{
2690	{
2691		in:  "a",
2692		out: false,
2693	},
2694	{
2695		in:  "-a",
2696		out: true,
2697	},
2698	{
2699		in:  "-Ipath/to/something",
2700		out: false,
2701	},
2702	{
2703		in:  "-isystempath/to/something",
2704		out: false,
2705	},
2706	{
2707		in:  "--coverage",
2708		out: false,
2709	},
2710	{
2711		in:  "-include a/b",
2712		out: true,
2713	},
2714	{
2715		in:  "-include a/b c/d",
2716		out: false,
2717	},
2718	{
2719		in:  "-DMACRO",
2720		out: true,
2721	},
2722	{
2723		in:  "-DMAC RO",
2724		out: false,
2725	},
2726	{
2727		in:  "-a -b",
2728		out: false,
2729	},
2730	{
2731		in:  "-DMACRO=definition",
2732		out: true,
2733	},
2734	{
2735		in:  "-DMACRO=defi nition",
2736		out: true, // TODO(jiyong): this should be false
2737	},
2738	{
2739		in:  "-DMACRO(x)=x + 1",
2740		out: true,
2741	},
2742	{
2743		in:  "-DMACRO=\"defi nition\"",
2744		out: true,
2745	},
2746}
2747
2748type mockContext struct {
2749	BaseModuleContext
2750	result bool
2751}
2752
2753func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
2754	// CheckBadCompilerFlags calls this function when the flag should be rejected
2755	ctx.result = false
2756}
2757
2758func TestCompilerFlags(t *testing.T) {
2759	for _, testCase := range compilerFlagsTestCases {
2760		ctx := &mockContext{result: true}
2761		CheckBadCompilerFlags(ctx, "", []string{testCase.in})
2762		if ctx.result != testCase.out {
2763			t.Errorf("incorrect output:")
2764			t.Errorf("     input: %#v", testCase.in)
2765			t.Errorf("  expected: %#v", testCase.out)
2766			t.Errorf("       got: %#v", ctx.result)
2767		}
2768	}
2769}
2770
2771func TestVendorPublicLibraries(t *testing.T) {
2772	ctx := testCc(t, `
2773	cc_library_headers {
2774		name: "libvendorpublic_headers",
2775		export_include_dirs: ["my_include"],
2776	}
2777	vendor_public_library {
2778		name: "libvendorpublic",
2779		symbol_file: "",
2780		export_public_headers: ["libvendorpublic_headers"],
2781	}
2782	cc_library {
2783		name: "libvendorpublic",
2784		srcs: ["foo.c"],
2785		vendor: true,
2786		no_libcrt: true,
2787		nocrt: true,
2788	}
2789
2790	cc_library {
2791		name: "libsystem",
2792		shared_libs: ["libvendorpublic"],
2793		vendor: false,
2794		srcs: ["foo.c"],
2795		no_libcrt: true,
2796		nocrt: true,
2797	}
2798	cc_library {
2799		name: "libvendor",
2800		shared_libs: ["libvendorpublic"],
2801		vendor: true,
2802		srcs: ["foo.c"],
2803		no_libcrt: true,
2804		nocrt: true,
2805	}
2806	`)
2807
2808	coreVariant := "android_arm64_armv8-a_shared"
2809	vendorVariant := "android_vendor.VER_arm64_armv8-a_shared"
2810
2811	// test if header search paths are correctly added
2812	// _static variant is used since _shared reuses *.o from the static variant
2813	cc := ctx.ModuleForTests("libsystem", strings.Replace(coreVariant, "_shared", "_static", 1)).Rule("cc")
2814	cflags := cc.Args["cFlags"]
2815	if !strings.Contains(cflags, "-Imy_include") {
2816		t.Errorf("cflags for libsystem must contain -Imy_include, but was %#v.", cflags)
2817	}
2818
2819	// test if libsystem is linked to the stub
2820	ld := ctx.ModuleForTests("libsystem", coreVariant).Rule("ld")
2821	libflags := ld.Args["libFlags"]
2822	stubPaths := getOutputPaths(ctx, coreVariant, []string{"libvendorpublic" + vendorPublicLibrarySuffix})
2823	if !strings.Contains(libflags, stubPaths[0].String()) {
2824		t.Errorf("libflags for libsystem must contain %#v, but was %#v", stubPaths[0], libflags)
2825	}
2826
2827	// test if libvendor is linked to the real shared lib
2828	ld = ctx.ModuleForTests("libvendor", vendorVariant).Rule("ld")
2829	libflags = ld.Args["libFlags"]
2830	stubPaths = getOutputPaths(ctx, vendorVariant, []string{"libvendorpublic"})
2831	if !strings.Contains(libflags, stubPaths[0].String()) {
2832		t.Errorf("libflags for libvendor must contain %#v, but was %#v", stubPaths[0], libflags)
2833	}
2834
2835}
2836
2837func TestRecovery(t *testing.T) {
2838	ctx := testCc(t, `
2839		cc_library_shared {
2840			name: "librecovery",
2841			recovery: true,
2842		}
2843		cc_library_shared {
2844			name: "librecovery32",
2845			recovery: true,
2846			compile_multilib:"32",
2847		}
2848		cc_library_shared {
2849			name: "libHalInRecovery",
2850			recovery_available: true,
2851			vendor: true,
2852		}
2853	`)
2854
2855	variants := ctx.ModuleVariantsForTests("librecovery")
2856	const arm64 = "android_recovery_arm64_armv8-a_shared"
2857	if len(variants) != 1 || !android.InList(arm64, variants) {
2858		t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
2859	}
2860
2861	variants = ctx.ModuleVariantsForTests("librecovery32")
2862	if android.InList(arm64, variants) {
2863		t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
2864	}
2865
2866	recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
2867	if !recoveryModule.Platform() {
2868		t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
2869	}
2870}
2871
2872func TestVersionedStubs(t *testing.T) {
2873	ctx := testCc(t, `
2874		cc_library_shared {
2875			name: "libFoo",
2876			srcs: ["foo.c"],
2877			stubs: {
2878				symbol_file: "foo.map.txt",
2879				versions: ["1", "2", "3"],
2880			},
2881		}
2882
2883		cc_library_shared {
2884			name: "libBar",
2885			srcs: ["bar.c"],
2886			shared_libs: ["libFoo#1"],
2887		}`)
2888
2889	variants := ctx.ModuleVariantsForTests("libFoo")
2890	expectedVariants := []string{
2891		"android_arm64_armv8-a_shared",
2892		"android_arm64_armv8-a_shared_1",
2893		"android_arm64_armv8-a_shared_2",
2894		"android_arm64_armv8-a_shared_3",
2895		"android_arm_armv7-a-neon_shared",
2896		"android_arm_armv7-a-neon_shared_1",
2897		"android_arm_armv7-a-neon_shared_2",
2898		"android_arm_armv7-a-neon_shared_3",
2899	}
2900	variantsMismatch := false
2901	if len(variants) != len(expectedVariants) {
2902		variantsMismatch = true
2903	} else {
2904		for _, v := range expectedVariants {
2905			if !inList(v, variants) {
2906				variantsMismatch = false
2907			}
2908		}
2909	}
2910	if variantsMismatch {
2911		t.Errorf("variants of libFoo expected:\n")
2912		for _, v := range expectedVariants {
2913			t.Errorf("%q\n", v)
2914		}
2915		t.Errorf(", but got:\n")
2916		for _, v := range variants {
2917			t.Errorf("%q\n", v)
2918		}
2919	}
2920
2921	libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("ld")
2922	libFlags := libBarLinkRule.Args["libFlags"]
2923	libFoo1StubPath := "libFoo/android_arm64_armv8-a_shared_1/libFoo.so"
2924	if !strings.Contains(libFlags, libFoo1StubPath) {
2925		t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
2926	}
2927
2928	libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("cc")
2929	cFlags := libBarCompileRule.Args["cFlags"]
2930	libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
2931	if !strings.Contains(cFlags, libFoo1VersioningMacro) {
2932		t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
2933	}
2934}
2935
2936func TestVersioningMacro(t *testing.T) {
2937	for _, tc := range []struct{ moduleName, expected string }{
2938		{"libc", "__LIBC_API__"},
2939		{"libfoo", "__LIBFOO_API__"},
2940		{"libfoo@1", "__LIBFOO_1_API__"},
2941		{"libfoo-v1", "__LIBFOO_V1_API__"},
2942		{"libfoo.v1", "__LIBFOO_V1_API__"},
2943	} {
2944		checkEquals(t, tc.moduleName, tc.expected, versioningMacroName(tc.moduleName))
2945	}
2946}
2947
2948func TestStaticExecutable(t *testing.T) {
2949	ctx := testCc(t, `
2950		cc_binary {
2951			name: "static_test",
2952			srcs: ["foo.c", "baz.o"],
2953			static_executable: true,
2954		}`)
2955
2956	variant := "android_arm64_armv8-a"
2957	binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
2958	libFlags := binModuleRule.Args["libFlags"]
2959	systemStaticLibs := []string{"libc.a", "libm.a"}
2960	for _, lib := range systemStaticLibs {
2961		if !strings.Contains(libFlags, lib) {
2962			t.Errorf("Static lib %q was not found in %q", lib, libFlags)
2963		}
2964	}
2965	systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
2966	for _, lib := range systemSharedLibs {
2967		if strings.Contains(libFlags, lib) {
2968			t.Errorf("Shared lib %q was found in %q", lib, libFlags)
2969		}
2970	}
2971}
2972
2973func TestStaticDepsOrderWithStubs(t *testing.T) {
2974	ctx := testCc(t, `
2975		cc_binary {
2976			name: "mybin",
2977			srcs: ["foo.c"],
2978			static_libs: ["libfooB"],
2979			static_executable: true,
2980			stl: "none",
2981		}
2982
2983		cc_library {
2984			name: "libfooB",
2985			srcs: ["foo.c"],
2986			shared_libs: ["libfooC"],
2987			stl: "none",
2988		}
2989
2990		cc_library {
2991			name: "libfooC",
2992			srcs: ["foo.c"],
2993			stl: "none",
2994			stubs: {
2995				versions: ["1"],
2996			},
2997		}`)
2998
2999	mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a").Module().(*Module)
3000	actual := mybin.depsInLinkOrder
3001	expected := getOutputPaths(ctx, "android_arm64_armv8-a_static", []string{"libfooB", "libfooC"})
3002
3003	if !reflect.DeepEqual(actual, expected) {
3004		t.Errorf("staticDeps orderings were not propagated correctly"+
3005			"\nactual:   %v"+
3006			"\nexpected: %v",
3007			actual,
3008			expected,
3009		)
3010	}
3011}
3012
3013func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) {
3014	testCcError(t, `module "libA" .* depends on disabled module "libB"`, `
3015		cc_library {
3016			name: "libA",
3017			srcs: ["foo.c"],
3018			shared_libs: ["libB"],
3019			stl: "none",
3020		}
3021
3022		cc_library {
3023			name: "libB",
3024			srcs: ["foo.c"],
3025			enabled: false,
3026			stl: "none",
3027		}
3028	`)
3029}
3030
3031// Simple smoke test for the cc_fuzz target that ensures the rule compiles
3032// correctly.
3033func TestFuzzTarget(t *testing.T) {
3034	ctx := testCc(t, `
3035		cc_fuzz {
3036			name: "fuzz_smoke_test",
3037			srcs: ["foo.c"],
3038		}`)
3039
3040	variant := "android_arm64_armv8-a_fuzzer"
3041	ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
3042}
3043
3044func TestAidl(t *testing.T) {
3045}
3046
3047func assertString(t *testing.T, got, expected string) {
3048	t.Helper()
3049	if got != expected {
3050		t.Errorf("expected %q got %q", expected, got)
3051	}
3052}
3053
3054func assertArrayString(t *testing.T, got, expected []string) {
3055	t.Helper()
3056	if len(got) != len(expected) {
3057		t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got)
3058		return
3059	}
3060	for i := range got {
3061		if got[i] != expected[i] {
3062			t.Errorf("expected %d-th %q (%q) got %q (%q)",
3063				i, expected[i], expected, got[i], got)
3064			return
3065		}
3066	}
3067}
3068
3069func assertMapKeys(t *testing.T, m map[string]string, expected []string) {
3070	t.Helper()
3071	assertArrayString(t, android.SortedStringKeys(m), expected)
3072}
3073
3074func TestDefaults(t *testing.T) {
3075	ctx := testCc(t, `
3076		cc_defaults {
3077			name: "defaults",
3078			srcs: ["foo.c"],
3079			static: {
3080				srcs: ["bar.c"],
3081			},
3082			shared: {
3083				srcs: ["baz.c"],
3084			},
3085		}
3086
3087		cc_library_static {
3088			name: "libstatic",
3089			defaults: ["defaults"],
3090		}
3091
3092		cc_library_shared {
3093			name: "libshared",
3094			defaults: ["defaults"],
3095		}
3096
3097		cc_library {
3098			name: "libboth",
3099			defaults: ["defaults"],
3100		}
3101
3102		cc_binary {
3103			name: "binary",
3104			defaults: ["defaults"],
3105		}`)
3106
3107	pathsToBase := func(paths android.Paths) []string {
3108		var ret []string
3109		for _, p := range paths {
3110			ret = append(ret, p.Base())
3111		}
3112		return ret
3113	}
3114
3115	shared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Rule("ld")
3116	if g, w := pathsToBase(shared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
3117		t.Errorf("libshared ld rule wanted %q, got %q", w, g)
3118	}
3119	bothShared := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_shared").Rule("ld")
3120	if g, w := pathsToBase(bothShared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
3121		t.Errorf("libboth ld rule wanted %q, got %q", w, g)
3122	}
3123	binary := ctx.ModuleForTests("binary", "android_arm64_armv8-a").Rule("ld")
3124	if g, w := pathsToBase(binary.Inputs), []string{"foo.o"}; !reflect.DeepEqual(w, g) {
3125		t.Errorf("binary ld rule wanted %q, got %q", w, g)
3126	}
3127
3128	static := ctx.ModuleForTests("libstatic", "android_arm64_armv8-a_static").Rule("ar")
3129	if g, w := pathsToBase(static.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
3130		t.Errorf("libstatic ar rule wanted %q, got %q", w, g)
3131	}
3132	bothStatic := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_static").Rule("ar")
3133	if g, w := pathsToBase(bothStatic.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
3134		t.Errorf("libboth ar rule wanted %q, got %q", w, g)
3135	}
3136}
3137
3138func TestProductVariableDefaults(t *testing.T) {
3139	bp := `
3140		cc_defaults {
3141			name: "libfoo_defaults",
3142			srcs: ["foo.c"],
3143			cppflags: ["-DFOO"],
3144			product_variables: {
3145				debuggable: {
3146					cppflags: ["-DBAR"],
3147				},
3148			},
3149		}
3150
3151		cc_library {
3152			name: "libfoo",
3153			defaults: ["libfoo_defaults"],
3154		}
3155	`
3156
3157	config := TestConfig(buildDir, android.Android, nil, bp, nil)
3158	config.TestProductVariables.Debuggable = BoolPtr(true)
3159
3160	ctx := CreateTestContext()
3161	ctx.PreDepsMutators(func(ctx android.RegisterMutatorsContext) {
3162		ctx.BottomUp("variable", android.VariableMutator).Parallel()
3163	})
3164	ctx.Register(config)
3165
3166	_, errs := ctx.ParseFileList(".", []string{"Android.bp"})
3167	android.FailIfErrored(t, errs)
3168	_, errs = ctx.PrepareBuildActions(config)
3169	android.FailIfErrored(t, errs)
3170
3171	libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Module().(*Module)
3172	if !android.InList("-DBAR", libfoo.flags.Local.CppFlags) {
3173		t.Errorf("expected -DBAR in cppflags, got %q", libfoo.flags.Local.CppFlags)
3174	}
3175}
3176