• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2017 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cc
16
17import (
18	"fmt"
19	"os"
20	"path/filepath"
21	"reflect"
22	"regexp"
23	"runtime"
24	"strings"
25	"testing"
26
27	"android/soong/android"
28	"android/soong/bazel/cquery"
29)
30
31func init() {
32	registerTestMutators(android.InitRegistrationContext)
33}
34
35func TestMain(m *testing.M) {
36	os.Exit(m.Run())
37}
38
39var prepareForCcTest = android.GroupFixturePreparers(
40	PrepareForTestWithCcIncludeVndk,
41	android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
42		variables.DeviceVndkVersion = StringPtr("current")
43		variables.ProductVndkVersion = StringPtr("current")
44		variables.Platform_vndk_version = StringPtr("29")
45	}),
46)
47
48var ccLibInApex = "cc_lib_in_apex"
49var apexVariationName = "apex28"
50var apexVersion = "28"
51
52func registerTestMutators(ctx android.RegistrationContext) {
53	ctx.PostDepsMutators(func(ctx android.RegisterMutatorsContext) {
54		ctx.BottomUp("apex", testApexMutator).Parallel()
55		ctx.BottomUp("mixed_builds_prep", mixedBuildsPrepareMutator).Parallel()
56	})
57}
58
59func mixedBuildsPrepareMutator(ctx android.BottomUpMutatorContext) {
60	if m := ctx.Module(); m.Enabled() {
61		if mixedBuildMod, ok := m.(android.MixedBuildBuildable); ok {
62			if mixedBuildMod.IsMixedBuildSupported(ctx) && android.MixedBuildsEnabled(ctx) {
63				mixedBuildMod.QueueBazelCall(ctx)
64			}
65		}
66	}
67}
68
69func testApexMutator(mctx android.BottomUpMutatorContext) {
70	modules := mctx.CreateVariations(apexVariationName)
71	apexInfo := android.ApexInfo{
72		ApexVariationName: apexVariationName,
73		MinSdkVersion:     android.ApiLevelForTest(apexVersion),
74	}
75	mctx.SetVariationProvider(modules[0], android.ApexInfoProvider, apexInfo)
76}
77
78// testCcWithConfig runs tests using the prepareForCcTest
79//
80// See testCc for an explanation as to how to stop using this deprecated method.
81//
82// deprecated
83func testCcWithConfig(t *testing.T, config android.Config) *android.TestContext {
84	t.Helper()
85	result := prepareForCcTest.RunTestWithConfig(t, config)
86	return result.TestContext
87}
88
89// testCc runs tests using the prepareForCcTest
90//
91// Do not add any new usages of this, instead use the prepareForCcTest directly as it makes it much
92// easier to customize the test behavior.
93//
94// If it is necessary to customize the behavior of an existing test that uses this then please first
95// convert the test to using prepareForCcTest first and then in a following change add the
96// appropriate fixture preparers. Keeping the conversion change separate makes it easy to verify
97// that it did not change the test behavior unexpectedly.
98//
99// deprecated
100func testCc(t *testing.T, bp string) *android.TestContext {
101	t.Helper()
102	result := prepareForCcTest.RunTestWithBp(t, bp)
103	return result.TestContext
104}
105
106// testCcNoVndk runs tests using the prepareForCcTest
107//
108// See testCc for an explanation as to how to stop using this deprecated method.
109//
110// deprecated
111func testCcNoVndk(t *testing.T, bp string) *android.TestContext {
112	t.Helper()
113	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
114	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
115
116	return testCcWithConfig(t, config)
117}
118
119// testCcNoProductVndk runs tests using the prepareForCcTest
120//
121// See testCc for an explanation as to how to stop using this deprecated method.
122//
123// deprecated
124func testCcNoProductVndk(t *testing.T, bp string) *android.TestContext {
125	t.Helper()
126	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
127	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
128	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
129
130	return testCcWithConfig(t, config)
131}
132
133// testCcErrorWithConfig runs tests using the prepareForCcTest
134//
135// See testCc for an explanation as to how to stop using this deprecated method.
136//
137// deprecated
138func testCcErrorWithConfig(t *testing.T, pattern string, config android.Config) {
139	t.Helper()
140
141	prepareForCcTest.
142		ExtendWithErrorHandler(android.FixtureExpectsAtLeastOneErrorMatchingPattern(pattern)).
143		RunTestWithConfig(t, config)
144}
145
146// testCcError runs tests using the prepareForCcTest
147//
148// See testCc for an explanation as to how to stop using this deprecated method.
149//
150// deprecated
151func testCcError(t *testing.T, pattern string, bp string) {
152	t.Helper()
153	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
154	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
155	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
156	testCcErrorWithConfig(t, pattern, config)
157	return
158}
159
160// testCcErrorProductVndk runs tests using the prepareForCcTest
161//
162// See testCc for an explanation as to how to stop using this deprecated method.
163//
164// deprecated
165func testCcErrorProductVndk(t *testing.T, pattern string, bp string) {
166	t.Helper()
167	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
168	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
169	config.TestProductVariables.ProductVndkVersion = StringPtr("current")
170	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
171	testCcErrorWithConfig(t, pattern, config)
172	return
173}
174
175const (
176	coreVariant     = "android_arm64_armv8-a_shared"
177	vendorVariant   = "android_vendor.29_arm64_armv8-a_shared"
178	productVariant  = "android_product.29_arm64_armv8-a_shared"
179	recoveryVariant = "android_recovery_arm64_armv8-a_shared"
180)
181
182// Test that the PrepareForTestWithCcDefaultModules provides all the files that it uses by
183// running it in a fixture that requires all source files to exist.
184func TestPrepareForTestWithCcDefaultModules(t *testing.T) {
185	android.GroupFixturePreparers(
186		PrepareForTestWithCcDefaultModules,
187		android.PrepareForTestDisallowNonExistentPaths,
188	).RunTest(t)
189}
190
191func TestVendorSrc(t *testing.T) {
192	t.Parallel()
193	ctx := testCc(t, `
194		cc_library {
195			name: "libTest",
196			srcs: ["foo.c"],
197			no_libcrt: true,
198			nocrt: true,
199			system_shared_libs: [],
200			vendor_available: true,
201			target: {
202				vendor: {
203					srcs: ["bar.c"],
204				},
205			},
206		}
207	`)
208
209	ld := ctx.ModuleForTests("libTest", vendorVariant).Rule("ld")
210	var objs []string
211	for _, o := range ld.Inputs {
212		objs = append(objs, o.Base())
213	}
214	if len(objs) != 2 || objs[0] != "foo.o" || objs[1] != "bar.o" {
215		t.Errorf("inputs of libTest must be []string{\"foo.o\", \"bar.o\"}, but was %#v.", objs)
216	}
217}
218
219func checkInstallPartition(t *testing.T, ctx *android.TestContext, name, variant, expected string) {
220	mod := ctx.ModuleForTests(name, variant).Module().(*Module)
221	partitionDefined := false
222	checkPartition := func(specific bool, partition string) {
223		if specific {
224			if expected != partition && !partitionDefined {
225				// The variant is installed to the 'partition'
226				t.Errorf("%s variant of %q must not be installed to %s partition", variant, name, partition)
227			}
228			partitionDefined = true
229		} else {
230			// The variant is not installed to the 'partition'
231			if expected == partition {
232				t.Errorf("%s variant of %q must be installed to %s partition", variant, name, partition)
233			}
234		}
235	}
236	socSpecific := func(m *Module) bool {
237		return m.SocSpecific() || m.socSpecificModuleContext()
238	}
239	deviceSpecific := func(m *Module) bool {
240		return m.DeviceSpecific() || m.deviceSpecificModuleContext()
241	}
242	productSpecific := func(m *Module) bool {
243		return m.ProductSpecific() || m.productSpecificModuleContext()
244	}
245	systemExtSpecific := func(m *Module) bool {
246		return m.SystemExtSpecific()
247	}
248	checkPartition(socSpecific(mod), "vendor")
249	checkPartition(deviceSpecific(mod), "odm")
250	checkPartition(productSpecific(mod), "product")
251	checkPartition(systemExtSpecific(mod), "system_ext")
252	if !partitionDefined && expected != "system" {
253		t.Errorf("%s variant of %q is expected to be installed to %s partition,"+
254			" but installed to system partition", variant, name, expected)
255	}
256}
257
258func TestInstallPartition(t *testing.T) {
259	t.Parallel()
260	t.Helper()
261	ctx := prepareForCcTest.RunTestWithBp(t, `
262		cc_library {
263			name: "libsystem",
264		}
265		cc_library {
266			name: "libsystem_ext",
267			system_ext_specific: true,
268		}
269		cc_library {
270			name: "libproduct",
271			product_specific: true,
272		}
273		cc_library {
274			name: "libvendor",
275			vendor: true,
276		}
277		cc_library {
278			name: "libodm",
279			device_specific: true,
280		}
281		cc_library {
282			name: "liball_available",
283			vendor_available: true,
284			product_available: true,
285		}
286		cc_library {
287			name: "libsystem_ext_all_available",
288			system_ext_specific: true,
289			vendor_available: true,
290			product_available: true,
291		}
292		cc_library {
293			name: "liball_available_odm",
294			odm_available: true,
295			product_available: true,
296		}
297		cc_library {
298			name: "libproduct_vendoravailable",
299			product_specific: true,
300			vendor_available: true,
301		}
302		cc_library {
303			name: "libproduct_odmavailable",
304			product_specific: true,
305			odm_available: true,
306		}
307	`).TestContext
308
309	checkInstallPartition(t, ctx, "libsystem", coreVariant, "system")
310	checkInstallPartition(t, ctx, "libsystem_ext", coreVariant, "system_ext")
311	checkInstallPartition(t, ctx, "libproduct", productVariant, "product")
312	checkInstallPartition(t, ctx, "libvendor", vendorVariant, "vendor")
313	checkInstallPartition(t, ctx, "libodm", vendorVariant, "odm")
314
315	checkInstallPartition(t, ctx, "liball_available", coreVariant, "system")
316	checkInstallPartition(t, ctx, "liball_available", productVariant, "product")
317	checkInstallPartition(t, ctx, "liball_available", vendorVariant, "vendor")
318
319	checkInstallPartition(t, ctx, "libsystem_ext_all_available", coreVariant, "system_ext")
320	checkInstallPartition(t, ctx, "libsystem_ext_all_available", productVariant, "product")
321	checkInstallPartition(t, ctx, "libsystem_ext_all_available", vendorVariant, "vendor")
322
323	checkInstallPartition(t, ctx, "liball_available_odm", coreVariant, "system")
324	checkInstallPartition(t, ctx, "liball_available_odm", productVariant, "product")
325	checkInstallPartition(t, ctx, "liball_available_odm", vendorVariant, "odm")
326
327	checkInstallPartition(t, ctx, "libproduct_vendoravailable", productVariant, "product")
328	checkInstallPartition(t, ctx, "libproduct_vendoravailable", vendorVariant, "vendor")
329
330	checkInstallPartition(t, ctx, "libproduct_odmavailable", productVariant, "product")
331	checkInstallPartition(t, ctx, "libproduct_odmavailable", vendorVariant, "odm")
332}
333
334func checkVndkModule(t *testing.T, ctx *android.TestContext, name, subDir string,
335	isVndkSp bool, extends string, variant string) {
336
337	t.Helper()
338
339	mod := ctx.ModuleForTests(name, variant).Module().(*Module)
340
341	// Check library properties.
342	lib, ok := mod.compiler.(*libraryDecorator)
343	if !ok {
344		t.Errorf("%q must have libraryDecorator", name)
345	} else if lib.baseInstaller.subDir != subDir {
346		t.Errorf("%q must use %q as subdir but it is using %q", name, subDir,
347			lib.baseInstaller.subDir)
348	}
349
350	// Check VNDK properties.
351	if mod.vndkdep == nil {
352		t.Fatalf("%q must have `vndkdep`", name)
353	}
354	if !mod.IsVndk() {
355		t.Errorf("%q IsVndk() must equal to true", name)
356	}
357	if mod.IsVndkSp() != isVndkSp {
358		t.Errorf("%q IsVndkSp() must equal to %t", name, isVndkSp)
359	}
360
361	// Check VNDK extension properties.
362	isVndkExt := extends != ""
363	if mod.IsVndkExt() != isVndkExt {
364		t.Errorf("%q IsVndkExt() must equal to %t", name, isVndkExt)
365	}
366
367	if actualExtends := mod.getVndkExtendsModuleName(); actualExtends != extends {
368		t.Errorf("%q must extend from %q but get %q", name, extends, actualExtends)
369	}
370}
371
372func checkWriteFileOutput(t *testing.T, params android.TestingBuildParams, expected []string) {
373	t.Helper()
374	content := android.ContentFromFileRuleForTests(t, params)
375	actual := strings.FieldsFunc(content, func(r rune) bool { return r == '\n' })
376	assertArrayString(t, actual, expected)
377}
378
379func checkVndkOutput(t *testing.T, ctx *android.TestContext, output string, expected []string) {
380	t.Helper()
381	vndkSnapshot := ctx.SingletonForTests("vndk-snapshot")
382	checkWriteFileOutput(t, vndkSnapshot.Output(output), expected)
383}
384
385func checkVndkLibrariesOutput(t *testing.T, ctx *android.TestContext, module string, expected []string) {
386	t.Helper()
387	got := ctx.ModuleForTests(module, "android_common").Module().(*vndkLibrariesTxt).fileNames
388	assertArrayString(t, got, expected)
389}
390
391func TestVndk(t *testing.T) {
392	t.Parallel()
393	bp := `
394		cc_library {
395			name: "libvndk",
396			vendor_available: true,
397			vndk: {
398				enabled: true,
399			},
400			nocrt: true,
401		}
402
403		cc_library {
404			name: "libvndk_private",
405			vendor_available: true,
406			vndk: {
407				enabled: true,
408				private: true,
409			},
410			nocrt: true,
411			stem: "libvndk-private",
412		}
413
414		cc_library {
415			name: "libvndk_product",
416			vendor_available: true,
417			product_available: true,
418			vndk: {
419				enabled: true,
420			},
421			nocrt: true,
422			target: {
423				vendor: {
424					cflags: ["-DTEST"],
425				},
426				product: {
427					cflags: ["-DTEST"],
428				},
429			},
430		}
431
432		cc_library {
433			name: "libvndk_sp",
434			vendor_available: true,
435			vndk: {
436				enabled: true,
437				support_system_process: true,
438			},
439			nocrt: true,
440			suffix: "-x",
441		}
442
443		cc_library {
444			name: "libvndk_sp_private",
445			vendor_available: true,
446			vndk: {
447				enabled: true,
448				support_system_process: true,
449				private: true,
450			},
451			nocrt: true,
452			target: {
453				vendor: {
454					suffix: "-x",
455				},
456			},
457		}
458
459		cc_library {
460			name: "libvndk_sp_product_private",
461			vendor_available: true,
462			product_available: true,
463			vndk: {
464				enabled: true,
465				support_system_process: true,
466				private: true,
467			},
468			nocrt: true,
469			target: {
470				vendor: {
471					suffix: "-x",
472				},
473				product: {
474					suffix: "-x",
475				},
476			},
477		}
478
479		cc_library {
480			name: "libllndk",
481			llndk: {
482				symbol_file: "libllndk.map.txt",
483				export_llndk_headers: ["libllndk_headers"],
484			}
485		}
486
487		cc_library {
488			name: "libclang_rt.hwasan-llndk",
489			llndk: {
490				symbol_file: "libclang_rt.hwasan.map.txt",
491			}
492		}
493
494		cc_library_headers {
495			name: "libllndk_headers",
496			llndk: {
497				llndk_headers: true,
498			},
499			export_include_dirs: ["include"],
500		}
501
502		llndk_libraries_txt {
503			name: "llndk.libraries.txt",
504		}
505		vndkcore_libraries_txt {
506			name: "vndkcore.libraries.txt",
507		}
508		vndksp_libraries_txt {
509			name: "vndksp.libraries.txt",
510		}
511		vndkprivate_libraries_txt {
512			name: "vndkprivate.libraries.txt",
513		}
514		vndkproduct_libraries_txt {
515			name: "vndkproduct.libraries.txt",
516		}
517		vndkcorevariant_libraries_txt {
518			name: "vndkcorevariant.libraries.txt",
519			insert_vndk_version: false,
520		}
521	`
522
523	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
524	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
525	config.TestProductVariables.ProductVndkVersion = StringPtr("current")
526	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
527
528	ctx := testCcWithConfig(t, config)
529
530	// subdir == "" because VNDK libs are not supposed to be installed separately.
531	// They are installed as part of VNDK APEX instead.
532	checkVndkModule(t, ctx, "libvndk", "", false, "", vendorVariant)
533	checkVndkModule(t, ctx, "libvndk_private", "", false, "", vendorVariant)
534	checkVndkModule(t, ctx, "libvndk_product", "", false, "", vendorVariant)
535	checkVndkModule(t, ctx, "libvndk_sp", "", true, "", vendorVariant)
536	checkVndkModule(t, ctx, "libvndk_sp_private", "", true, "", vendorVariant)
537	checkVndkModule(t, ctx, "libvndk_sp_product_private", "", true, "", vendorVariant)
538
539	checkVndkModule(t, ctx, "libvndk_product", "", false, "", productVariant)
540	checkVndkModule(t, ctx, "libvndk_sp_product_private", "", true, "", productVariant)
541
542	// Check VNDK snapshot output.
543	snapshotDir := "vndk-snapshot"
544	snapshotVariantPath := filepath.Join("out/soong", snapshotDir, "arm64")
545
546	vndkLibPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
547		"arm64", "armv8-a"))
548	vndkLib2ndPath := filepath.Join(snapshotVariantPath, fmt.Sprintf("arch-%s-%s",
549		"arm", "armv7-a-neon"))
550
551	vndkCoreLibPath := filepath.Join(vndkLibPath, "shared", "vndk-core")
552	vndkSpLibPath := filepath.Join(vndkLibPath, "shared", "vndk-sp")
553	llndkLibPath := filepath.Join(vndkLibPath, "shared", "llndk-stub")
554
555	vndkCoreLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-core")
556	vndkSpLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "vndk-sp")
557	llndkLib2ndPath := filepath.Join(vndkLib2ndPath, "shared", "llndk-stub")
558
559	variant := "android_vendor.29_arm64_armv8-a_shared"
560	variant2nd := "android_vendor.29_arm_armv7-a-neon_shared"
561
562	snapshotSingleton := ctx.SingletonForTests("vndk-snapshot")
563
564	CheckSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", vndkCoreLibPath, variant)
565	CheckSnapshot(t, ctx, snapshotSingleton, "libvndk", "libvndk.so", vndkCoreLib2ndPath, variant2nd)
566	CheckSnapshot(t, ctx, snapshotSingleton, "libvndk_product", "libvndk_product.so", vndkCoreLibPath, variant)
567	CheckSnapshot(t, ctx, snapshotSingleton, "libvndk_product", "libvndk_product.so", vndkCoreLib2ndPath, variant2nd)
568	CheckSnapshot(t, ctx, snapshotSingleton, "libvndk_sp", "libvndk_sp-x.so", vndkSpLibPath, variant)
569	CheckSnapshot(t, ctx, snapshotSingleton, "libvndk_sp", "libvndk_sp-x.so", vndkSpLib2ndPath, variant2nd)
570	CheckSnapshot(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", llndkLibPath, variant)
571	CheckSnapshot(t, ctx, snapshotSingleton, "libllndk", "libllndk.so", llndkLib2ndPath, variant2nd)
572
573	snapshotConfigsPath := filepath.Join(snapshotVariantPath, "configs")
574	CheckSnapshot(t, ctx, snapshotSingleton, "llndk.libraries.txt", "llndk.libraries.txt", snapshotConfigsPath, "android_common")
575	CheckSnapshot(t, ctx, snapshotSingleton, "vndkcore.libraries.txt", "vndkcore.libraries.txt", snapshotConfigsPath, "android_common")
576	CheckSnapshot(t, ctx, snapshotSingleton, "vndksp.libraries.txt", "vndksp.libraries.txt", snapshotConfigsPath, "android_common")
577	CheckSnapshot(t, ctx, snapshotSingleton, "vndkprivate.libraries.txt", "vndkprivate.libraries.txt", snapshotConfigsPath, "android_common")
578	CheckSnapshot(t, ctx, snapshotSingleton, "vndkproduct.libraries.txt", "vndkproduct.libraries.txt", snapshotConfigsPath, "android_common")
579
580	checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{
581		"LLNDK: libc.so",
582		"LLNDK: libdl.so",
583		"LLNDK: libft2.so",
584		"LLNDK: libllndk.so",
585		"LLNDK: libm.so",
586		"VNDK-SP: libc++.so",
587		"VNDK-SP: libvndk_sp-x.so",
588		"VNDK-SP: libvndk_sp_private-x.so",
589		"VNDK-SP: libvndk_sp_product_private-x.so",
590		"VNDK-core: libvndk-private.so",
591		"VNDK-core: libvndk.so",
592		"VNDK-core: libvndk_product.so",
593		"VNDK-private: libft2.so",
594		"VNDK-private: libvndk-private.so",
595		"VNDK-private: libvndk_sp_private-x.so",
596		"VNDK-private: libvndk_sp_product_private-x.so",
597		"VNDK-product: libc++.so",
598		"VNDK-product: libvndk_product.so",
599		"VNDK-product: libvndk_sp_product_private-x.so",
600	})
601	checkVndkLibrariesOutput(t, ctx, "llndk.libraries.txt", []string{"libc.so", "libclang_rt.hwasan-llndk.so", "libdl.so", "libft2.so", "libllndk.so", "libm.so"})
602	checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt", []string{"libvndk-private.so", "libvndk.so", "libvndk_product.so"})
603	checkVndkLibrariesOutput(t, ctx, "vndksp.libraries.txt", []string{"libc++.so", "libvndk_sp-x.so", "libvndk_sp_private-x.so", "libvndk_sp_product_private-x.so"})
604	checkVndkLibrariesOutput(t, ctx, "vndkprivate.libraries.txt", []string{"libft2.so", "libvndk-private.so", "libvndk_sp_private-x.so", "libvndk_sp_product_private-x.so"})
605	checkVndkLibrariesOutput(t, ctx, "vndkproduct.libraries.txt", []string{"libc++.so", "libvndk_product.so", "libvndk_sp_product_private-x.so"})
606	checkVndkLibrariesOutput(t, ctx, "vndkcorevariant.libraries.txt", nil)
607}
608
609func TestVndkWithHostSupported(t *testing.T) {
610	t.Parallel()
611	ctx := testCc(t, `
612		cc_library {
613			name: "libvndk_host_supported",
614			vendor_available: true,
615			product_available: true,
616			vndk: {
617				enabled: true,
618			},
619			host_supported: true,
620		}
621
622		cc_library {
623			name: "libvndk_host_supported_but_disabled_on_device",
624			vendor_available: true,
625			product_available: true,
626			vndk: {
627				enabled: true,
628			},
629			host_supported: true,
630			enabled: false,
631			target: {
632				host: {
633					enabled: true,
634				}
635			}
636		}
637
638		vndkcore_libraries_txt {
639			name: "vndkcore.libraries.txt",
640		}
641	`)
642
643	checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt", []string{"libvndk_host_supported.so"})
644}
645
646func TestVndkLibrariesTxtAndroidMk(t *testing.T) {
647	t.Parallel()
648	bp := `
649		llndk_libraries_txt {
650			name: "llndk.libraries.txt",
651			insert_vndk_version: true,
652		}`
653	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
654	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
655	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
656	ctx := testCcWithConfig(t, config)
657
658	module := ctx.ModuleForTests("llndk.libraries.txt", "android_common")
659	entries := android.AndroidMkEntriesForTest(t, ctx, module.Module())[0]
660	assertArrayString(t, entries.EntryMap["LOCAL_MODULE_STEM"], []string{"llndk.libraries.29.txt"})
661}
662
663func TestVndkUsingCoreVariant(t *testing.T) {
664	t.Parallel()
665	bp := `
666		cc_library {
667			name: "libvndk",
668			vendor_available: true,
669			product_available: true,
670			vndk: {
671				enabled: true,
672			},
673			nocrt: true,
674		}
675
676		cc_library {
677			name: "libvndk_sp",
678			vendor_available: true,
679			product_available: true,
680			vndk: {
681				enabled: true,
682				support_system_process: true,
683			},
684			nocrt: true,
685		}
686
687		cc_library {
688			name: "libvndk2",
689			vendor_available: true,
690			product_available: true,
691			vndk: {
692				enabled: true,
693				private: true,
694			},
695			nocrt: true,
696		}
697
698		vndkcorevariant_libraries_txt {
699			name: "vndkcorevariant.libraries.txt",
700			insert_vndk_version: false,
701		}
702	`
703
704	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
705	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
706	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
707	config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
708
709	setVndkMustUseVendorVariantListForTest(config, []string{"libvndk"})
710
711	ctx := testCcWithConfig(t, config)
712
713	checkVndkLibrariesOutput(t, ctx, "vndkcorevariant.libraries.txt", []string{"libc++.so", "libvndk2.so", "libvndk_sp.so"})
714}
715
716func TestDataLibs(t *testing.T) {
717	t.Parallel()
718	bp := `
719		cc_test_library {
720			name: "test_lib",
721			srcs: ["test_lib.cpp"],
722			gtest: false,
723		}
724
725		cc_test {
726			name: "main_test",
727			data_libs: ["test_lib"],
728			gtest: false,
729		}
730 `
731
732	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
733	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
734	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
735	config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
736
737	ctx := testCcWithConfig(t, config)
738	module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
739	testBinary := module.(*Module).linker.(*testBinary)
740	outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
741	if err != nil {
742		t.Errorf("Expected cc_test to produce output files, error: %s", err)
743		return
744	}
745	if len(outputFiles) != 1 {
746		t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
747		return
748	}
749	if len(testBinary.dataPaths()) != 1 {
750		t.Errorf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths())
751		return
752	}
753
754	outputPath := outputFiles[0].String()
755	testBinaryPath := testBinary.dataPaths()[0].SrcPath.String()
756
757	if !strings.HasSuffix(outputPath, "/main_test") {
758		t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
759		return
760	}
761	if !strings.HasSuffix(testBinaryPath, "/test_lib.so") {
762		t.Errorf("expected test data file to be 'test_lib.so', but was '%s'", testBinaryPath)
763		return
764	}
765}
766
767func TestDataLibsRelativeInstallPath(t *testing.T) {
768	t.Parallel()
769	bp := `
770		cc_test_library {
771			name: "test_lib",
772			srcs: ["test_lib.cpp"],
773			relative_install_path: "foo/bar/baz",
774			gtest: false,
775		}
776
777		cc_binary {
778			name: "test_bin",
779			relative_install_path: "foo/bar/baz",
780			compile_multilib: "both",
781		}
782
783		cc_test {
784			name: "main_test",
785			data_libs: ["test_lib"],
786			data_bins: ["test_bin"],
787			gtest: false,
788		}
789 `
790
791	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
792	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
793	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
794	config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
795
796	ctx := testCcWithConfig(t, config)
797	module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
798	testBinary := module.(*Module).linker.(*testBinary)
799	outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
800	if err != nil {
801		t.Fatalf("Expected cc_test to produce output files, error: %s", err)
802	}
803	if len(outputFiles) != 1 {
804		t.Fatalf("expected exactly one output file. output files: [%s]", outputFiles)
805	}
806	if len(testBinary.dataPaths()) != 2 {
807		t.Fatalf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths())
808	}
809
810	outputPath := outputFiles[0].String()
811
812	if !strings.HasSuffix(outputPath, "/main_test") {
813		t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
814	}
815	entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
816	if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
817		t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
818			" but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
819	}
820	if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][1], ":test_bin:foo/bar/baz") {
821		t.Errorf("expected LOCAL_TEST_DATA to end with `:test_bin:foo/bar/baz`,"+
822			" but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][1])
823	}
824}
825
826func TestTestBinaryTestSuites(t *testing.T) {
827	t.Parallel()
828	bp := `
829		cc_test {
830			name: "main_test",
831			srcs: ["main_test.cpp"],
832			test_suites: [
833				"suite_1",
834				"suite_2",
835			],
836			gtest: false,
837		}
838	`
839
840	ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
841	module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
842
843	entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
844	compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"]
845	if len(compatEntries) != 2 {
846		t.Errorf("expected two elements in LOCAL_COMPATIBILITY_SUITE. got %d", len(compatEntries))
847	}
848	if compatEntries[0] != "suite_1" {
849		t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_1`,"+
850			" but was '%s'", compatEntries[0])
851	}
852	if compatEntries[1] != "suite_2" {
853		t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_2`,"+
854			" but was '%s'", compatEntries[1])
855	}
856}
857
858func TestTestLibraryTestSuites(t *testing.T) {
859	t.Parallel()
860	bp := `
861		cc_test_library {
862			name: "main_test_lib",
863			srcs: ["main_test_lib.cpp"],
864			test_suites: [
865				"suite_1",
866				"suite_2",
867			],
868			gtest: false,
869		}
870	`
871
872	ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
873	module := ctx.ModuleForTests("main_test_lib", "android_arm_armv7-a-neon_shared").Module()
874
875	entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
876	compatEntries := entries.EntryMap["LOCAL_COMPATIBILITY_SUITE"]
877	if len(compatEntries) != 2 {
878		t.Errorf("expected two elements in LOCAL_COMPATIBILITY_SUITE. got %d", len(compatEntries))
879	}
880	if compatEntries[0] != "suite_1" {
881		t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_1`,"+
882			" but was '%s'", compatEntries[0])
883	}
884	if compatEntries[1] != "suite_2" {
885		t.Errorf("expected LOCAL_COMPATIBILITY_SUITE to be`suite_2`,"+
886			" but was '%s'", compatEntries[1])
887	}
888}
889
890func TestVndkWhenVndkVersionIsNotSet(t *testing.T) {
891	t.Parallel()
892	ctx := testCcNoVndk(t, `
893		cc_library {
894			name: "libvndk",
895			vendor_available: true,
896			product_available: true,
897			vndk: {
898				enabled: true,
899			},
900			nocrt: true,
901		}
902		cc_library {
903			name: "libvndk-private",
904			vendor_available: true,
905			product_available: true,
906			vndk: {
907				enabled: true,
908				private: true,
909			},
910			nocrt: true,
911		}
912
913		cc_library {
914			name: "libllndk",
915			llndk: {
916				symbol_file: "libllndk.map.txt",
917				export_llndk_headers: ["libllndk_headers"],
918			}
919		}
920
921		cc_library_headers {
922			name: "libllndk_headers",
923			llndk: {
924				symbol_file: "libllndk.map.txt",
925			},
926			export_include_dirs: ["include"],
927		}
928	`)
929
930	checkVndkOutput(t, ctx, "vndk/vndk.libraries.txt", []string{
931		"LLNDK: libc.so",
932		"LLNDK: libdl.so",
933		"LLNDK: libft2.so",
934		"LLNDK: libllndk.so",
935		"LLNDK: libm.so",
936		"VNDK-SP: libc++.so",
937		"VNDK-core: libvndk-private.so",
938		"VNDK-core: libvndk.so",
939		"VNDK-private: libft2.so",
940		"VNDK-private: libvndk-private.so",
941		"VNDK-product: libc++.so",
942		"VNDK-product: libvndk-private.so",
943		"VNDK-product: libvndk.so",
944	})
945}
946
947func TestVndkModuleError(t *testing.T) {
948	t.Parallel()
949	// Check the error message for vendor_available and product_available properties.
950	testCcErrorProductVndk(t, "vndk: vendor_available must be set to true when `vndk: {enabled: true}`", `
951		cc_library {
952			name: "libvndk",
953			vndk: {
954				enabled: true,
955			},
956			nocrt: true,
957		}
958	`)
959
960	testCcErrorProductVndk(t, "vndk: vendor_available must be set to true when `vndk: {enabled: true}`", `
961		cc_library {
962			name: "libvndk",
963			product_available: true,
964			vndk: {
965				enabled: true,
966			},
967			nocrt: true,
968		}
969	`)
970
971	testCcErrorProductVndk(t, "product properties must have the same values with the vendor properties for VNDK modules", `
972		cc_library {
973			name: "libvndkprop",
974			vendor_available: true,
975			product_available: true,
976			vndk: {
977				enabled: true,
978			},
979			nocrt: true,
980			target: {
981				vendor: {
982					cflags: ["-DTEST",],
983				},
984			},
985		}
986	`)
987}
988
989func TestVndkDepError(t *testing.T) {
990	t.Parallel()
991	// Check whether an error is emitted when a VNDK lib depends on a system lib.
992	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
993		cc_library {
994			name: "libvndk",
995			vendor_available: true,
996			product_available: true,
997			vndk: {
998				enabled: true,
999			},
1000			shared_libs: ["libfwk"],  // Cause error
1001			nocrt: true,
1002		}
1003
1004		cc_library {
1005			name: "libfwk",
1006			nocrt: true,
1007		}
1008	`)
1009
1010	// Check whether an error is emitted when a VNDK lib depends on a vendor lib.
1011	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1012		cc_library {
1013			name: "libvndk",
1014			vendor_available: true,
1015			product_available: true,
1016			vndk: {
1017				enabled: true,
1018			},
1019			shared_libs: ["libvendor"],  // Cause error
1020			nocrt: true,
1021		}
1022
1023		cc_library {
1024			name: "libvendor",
1025			vendor: true,
1026			nocrt: true,
1027		}
1028	`)
1029
1030	// Check whether an error is emitted when a VNDK-SP lib depends on a system lib.
1031	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1032		cc_library {
1033			name: "libvndk_sp",
1034			vendor_available: true,
1035			product_available: true,
1036			vndk: {
1037				enabled: true,
1038				support_system_process: true,
1039			},
1040			shared_libs: ["libfwk"],  // Cause error
1041			nocrt: true,
1042		}
1043
1044		cc_library {
1045			name: "libfwk",
1046			nocrt: true,
1047		}
1048	`)
1049
1050	// Check whether an error is emitted when a VNDK-SP lib depends on a vendor lib.
1051	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
1052		cc_library {
1053			name: "libvndk_sp",
1054			vendor_available: true,
1055			product_available: true,
1056			vndk: {
1057				enabled: true,
1058				support_system_process: true,
1059			},
1060			shared_libs: ["libvendor"],  // Cause error
1061			nocrt: true,
1062		}
1063
1064		cc_library {
1065			name: "libvendor",
1066			vendor: true,
1067			nocrt: true,
1068		}
1069	`)
1070
1071	// Check whether an error is emitted when a VNDK-SP lib depends on a VNDK lib.
1072	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1073		cc_library {
1074			name: "libvndk_sp",
1075			vendor_available: true,
1076			product_available: true,
1077			vndk: {
1078				enabled: true,
1079				support_system_process: true,
1080			},
1081			shared_libs: ["libvndk"],  // Cause error
1082			nocrt: true,
1083		}
1084
1085		cc_library {
1086			name: "libvndk",
1087			vendor_available: true,
1088			product_available: true,
1089			vndk: {
1090				enabled: true,
1091			},
1092			nocrt: true,
1093		}
1094	`)
1095
1096	// Check whether an error is emitted when a VNDK lib depends on a non-VNDK lib.
1097	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1098		cc_library {
1099			name: "libvndk",
1100			vendor_available: true,
1101			product_available: true,
1102			vndk: {
1103				enabled: true,
1104			},
1105			shared_libs: ["libnonvndk"],
1106			nocrt: true,
1107		}
1108
1109		cc_library {
1110			name: "libnonvndk",
1111			vendor_available: true,
1112			nocrt: true,
1113		}
1114	`)
1115
1116	// Check whether an error is emitted when a VNDK-private lib depends on a non-VNDK lib.
1117	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1118		cc_library {
1119			name: "libvndkprivate",
1120			vendor_available: true,
1121			product_available: true,
1122			vndk: {
1123				enabled: true,
1124				private: true,
1125			},
1126			shared_libs: ["libnonvndk"],
1127			nocrt: true,
1128		}
1129
1130		cc_library {
1131			name: "libnonvndk",
1132			vendor_available: true,
1133			nocrt: true,
1134		}
1135	`)
1136
1137	// Check whether an error is emitted when a VNDK-sp lib depends on a non-VNDK lib.
1138	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1139		cc_library {
1140			name: "libvndksp",
1141			vendor_available: true,
1142			product_available: true,
1143			vndk: {
1144				enabled: true,
1145				support_system_process: true,
1146			},
1147			shared_libs: ["libnonvndk"],
1148			nocrt: true,
1149		}
1150
1151		cc_library {
1152			name: "libnonvndk",
1153			vendor_available: true,
1154			nocrt: true,
1155		}
1156	`)
1157
1158	// Check whether an error is emitted when a VNDK-sp-private lib depends on a non-VNDK lib.
1159	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1160		cc_library {
1161			name: "libvndkspprivate",
1162			vendor_available: true,
1163			product_available: true,
1164			vndk: {
1165				enabled: true,
1166				support_system_process: true,
1167				private: true,
1168			},
1169			shared_libs: ["libnonvndk"],
1170			nocrt: true,
1171		}
1172
1173		cc_library {
1174			name: "libnonvndk",
1175			vendor_available: true,
1176			nocrt: true,
1177		}
1178	`)
1179}
1180
1181func TestDoubleLoadbleDep(t *testing.T) {
1182	t.Parallel()
1183	// okay to link : LLNDK -> double_loadable VNDK
1184	testCc(t, `
1185		cc_library {
1186			name: "libllndk",
1187			shared_libs: ["libdoubleloadable"],
1188			llndk: {
1189				symbol_file: "libllndk.map.txt",
1190			}
1191		}
1192
1193		cc_library {
1194			name: "libdoubleloadable",
1195			vendor_available: true,
1196			product_available: true,
1197			vndk: {
1198				enabled: true,
1199			},
1200			double_loadable: true,
1201		}
1202	`)
1203	// okay to link : LLNDK -> VNDK-SP
1204	testCc(t, `
1205		cc_library {
1206			name: "libllndk",
1207			shared_libs: ["libvndksp"],
1208			llndk: {
1209				symbol_file: "libllndk.map.txt",
1210			}
1211		}
1212
1213		cc_library {
1214			name: "libvndksp",
1215			vendor_available: true,
1216			product_available: true,
1217			vndk: {
1218				enabled: true,
1219				support_system_process: true,
1220			},
1221		}
1222	`)
1223	// okay to link : double_loadable -> double_loadable
1224	testCc(t, `
1225		cc_library {
1226			name: "libdoubleloadable1",
1227			shared_libs: ["libdoubleloadable2"],
1228			vendor_available: true,
1229			double_loadable: true,
1230		}
1231
1232		cc_library {
1233			name: "libdoubleloadable2",
1234			vendor_available: true,
1235			double_loadable: true,
1236		}
1237	`)
1238	// okay to link : double_loadable VNDK -> double_loadable VNDK private
1239	testCc(t, `
1240		cc_library {
1241			name: "libdoubleloadable",
1242			vendor_available: true,
1243			product_available: true,
1244			vndk: {
1245				enabled: true,
1246			},
1247			double_loadable: true,
1248			shared_libs: ["libnondoubleloadable"],
1249		}
1250
1251		cc_library {
1252			name: "libnondoubleloadable",
1253			vendor_available: true,
1254			product_available: true,
1255			vndk: {
1256				enabled: true,
1257				private: true,
1258			},
1259			double_loadable: true,
1260		}
1261	`)
1262	// okay to link : LLNDK -> core-only -> vendor_available & double_loadable
1263	testCc(t, `
1264		cc_library {
1265			name: "libllndk",
1266			shared_libs: ["libcoreonly"],
1267			llndk: {
1268				symbol_file: "libllndk.map.txt",
1269			}
1270		}
1271
1272		cc_library {
1273			name: "libcoreonly",
1274			shared_libs: ["libvendoravailable"],
1275		}
1276
1277		// indirect dependency of LLNDK
1278		cc_library {
1279			name: "libvendoravailable",
1280			vendor_available: true,
1281			double_loadable: true,
1282		}
1283	`)
1284}
1285
1286func TestDoubleLoadableDepError(t *testing.T) {
1287	t.Parallel()
1288	// Check whether an error is emitted when a LLNDK depends on a non-double_loadable VNDK lib.
1289	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
1290		cc_library {
1291			name: "libllndk",
1292			shared_libs: ["libnondoubleloadable"],
1293			llndk: {
1294				symbol_file: "libllndk.map.txt",
1295			}
1296		}
1297
1298		cc_library {
1299			name: "libnondoubleloadable",
1300			vendor_available: true,
1301			product_available: true,
1302			vndk: {
1303				enabled: true,
1304			},
1305		}
1306	`)
1307
1308	// Check whether an error is emitted when a LLNDK depends on a non-double_loadable vendor_available lib.
1309	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
1310		cc_library {
1311			name: "libllndk",
1312			no_libcrt: true,
1313			shared_libs: ["libnondoubleloadable"],
1314			llndk: {
1315				symbol_file: "libllndk.map.txt",
1316			}
1317		}
1318
1319		cc_library {
1320			name: "libnondoubleloadable",
1321			vendor_available: true,
1322		}
1323	`)
1324
1325	// Check whether an error is emitted when a LLNDK depends on a non-double_loadable indirectly.
1326	testCcError(t, "module \".*\" variant \".*\": link.* \".*\" which is not LL-NDK, VNDK-SP, .*double_loadable", `
1327		cc_library {
1328			name: "libllndk",
1329			shared_libs: ["libcoreonly"],
1330			llndk: {
1331				symbol_file: "libllndk.map.txt",
1332			}
1333		}
1334
1335		cc_library {
1336			name: "libcoreonly",
1337			shared_libs: ["libvendoravailable"],
1338		}
1339
1340		// indirect dependency of LLNDK
1341		cc_library {
1342			name: "libvendoravailable",
1343			vendor_available: true,
1344		}
1345	`)
1346
1347	// The error is not from 'client' but from 'libllndk'
1348	testCcError(t, "module \"libllndk\".* links a library \"libnondoubleloadable\".*double_loadable", `
1349		cc_library {
1350			name: "client",
1351			vendor_available: true,
1352			double_loadable: true,
1353			shared_libs: ["libllndk"],
1354		}
1355		cc_library {
1356			name: "libllndk",
1357			shared_libs: ["libnondoubleloadable"],
1358			llndk: {
1359				symbol_file: "libllndk.map.txt",
1360			}
1361		}
1362		cc_library {
1363			name: "libnondoubleloadable",
1364			vendor_available: true,
1365		}
1366	`)
1367}
1368
1369func TestCheckVndkMembershipBeforeDoubleLoadable(t *testing.T) {
1370	t.Parallel()
1371	testCcError(t, "module \"libvndksp\" variant .*: .*: VNDK-SP must only depend on VNDK-SP", `
1372		cc_library {
1373			name: "libvndksp",
1374			shared_libs: ["libanothervndksp"],
1375			vendor_available: true,
1376			product_available: true,
1377			vndk: {
1378				enabled: true,
1379				support_system_process: true,
1380			}
1381		}
1382
1383		cc_library {
1384			name: "libllndk",
1385			shared_libs: ["libanothervndksp"],
1386		}
1387
1388		cc_library {
1389			name: "libanothervndksp",
1390			vendor_available: true,
1391		}
1392	`)
1393}
1394
1395func TestVndkExt(t *testing.T) {
1396	t.Parallel()
1397	// This test checks the VNDK-Ext properties.
1398	bp := `
1399		cc_library {
1400			name: "libvndk",
1401			vendor_available: true,
1402			product_available: true,
1403			vndk: {
1404				enabled: true,
1405			},
1406			nocrt: true,
1407		}
1408		cc_library {
1409			name: "libvndk2",
1410			vendor_available: true,
1411			product_available: true,
1412			vndk: {
1413				enabled: true,
1414			},
1415			target: {
1416				vendor: {
1417					suffix: "-suffix",
1418				},
1419				product: {
1420					suffix: "-suffix",
1421				},
1422			},
1423			nocrt: true,
1424		}
1425
1426		cc_library {
1427			name: "libvndk_ext",
1428			vendor: true,
1429			vndk: {
1430				enabled: true,
1431				extends: "libvndk",
1432			},
1433			nocrt: true,
1434		}
1435
1436		cc_library {
1437			name: "libvndk2_ext",
1438			vendor: true,
1439			vndk: {
1440				enabled: true,
1441				extends: "libvndk2",
1442			},
1443			nocrt: true,
1444		}
1445
1446		cc_library {
1447			name: "libvndk_ext_product",
1448			product_specific: true,
1449			vndk: {
1450				enabled: true,
1451				extends: "libvndk",
1452			},
1453			nocrt: true,
1454		}
1455
1456		cc_library {
1457			name: "libvndk2_ext_product",
1458			product_specific: true,
1459			vndk: {
1460				enabled: true,
1461				extends: "libvndk2",
1462			},
1463			nocrt: true,
1464		}
1465	`
1466	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
1467	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
1468	config.TestProductVariables.ProductVndkVersion = StringPtr("current")
1469	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
1470
1471	ctx := testCcWithConfig(t, config)
1472
1473	checkVndkModule(t, ctx, "libvndk_ext", "vndk", false, "libvndk", vendorVariant)
1474	checkVndkModule(t, ctx, "libvndk_ext_product", "vndk", false, "libvndk", productVariant)
1475
1476	mod_vendor := ctx.ModuleForTests("libvndk2_ext", vendorVariant).Module().(*Module)
1477	assertString(t, mod_vendor.outputFile.Path().Base(), "libvndk2-suffix.so")
1478
1479	mod_product := ctx.ModuleForTests("libvndk2_ext_product", productVariant).Module().(*Module)
1480	assertString(t, mod_product.outputFile.Path().Base(), "libvndk2-suffix.so")
1481}
1482
1483func TestVndkExtWithoutBoardVndkVersion(t *testing.T) {
1484	t.Parallel()
1485	// This test checks the VNDK-Ext properties when BOARD_VNDK_VERSION is not set.
1486	ctx := testCcNoVndk(t, `
1487		cc_library {
1488			name: "libvndk",
1489			vendor_available: true,
1490			product_available: true,
1491			vndk: {
1492				enabled: true,
1493			},
1494			nocrt: true,
1495		}
1496
1497		cc_library {
1498			name: "libvndk_ext",
1499			vendor: true,
1500			vndk: {
1501				enabled: true,
1502				extends: "libvndk",
1503			},
1504			nocrt: true,
1505		}
1506	`)
1507
1508	// Ensures that the core variant of "libvndk_ext" can be found.
1509	mod := ctx.ModuleForTests("libvndk_ext", coreVariant).Module().(*Module)
1510	if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
1511		t.Errorf("\"libvndk_ext\" must extend from \"libvndk\" but get %q", extends)
1512	}
1513}
1514
1515func TestVndkExtWithoutProductVndkVersion(t *testing.T) {
1516	t.Parallel()
1517	// This test checks the VNDK-Ext properties when PRODUCT_PRODUCT_VNDK_VERSION is not set.
1518	ctx := testCcNoProductVndk(t, `
1519		cc_library {
1520			name: "libvndk",
1521			vendor_available: true,
1522			product_available: true,
1523			vndk: {
1524				enabled: true,
1525			},
1526			nocrt: true,
1527		}
1528
1529		cc_library {
1530			name: "libvndk_ext_product",
1531			product_specific: true,
1532			vndk: {
1533				enabled: true,
1534				extends: "libvndk",
1535			},
1536			nocrt: true,
1537		}
1538	`)
1539
1540	// Ensures that the core variant of "libvndk_ext_product" can be found.
1541	mod := ctx.ModuleForTests("libvndk_ext_product", coreVariant).Module().(*Module)
1542	if extends := mod.getVndkExtendsModuleName(); extends != "libvndk" {
1543		t.Errorf("\"libvndk_ext_product\" must extend from \"libvndk\" but get %q", extends)
1544	}
1545}
1546
1547func TestVndkExtError(t *testing.T) {
1548	t.Parallel()
1549	// This test ensures an error is emitted in ill-formed vndk-ext definition.
1550	testCcError(t, "must set `vendor: true` or `product_specific: true` to set `extends: \".*\"`", `
1551		cc_library {
1552			name: "libvndk",
1553			vendor_available: true,
1554			product_available: true,
1555			vndk: {
1556				enabled: true,
1557			},
1558			nocrt: true,
1559		}
1560
1561		cc_library {
1562			name: "libvndk_ext",
1563			vndk: {
1564				enabled: true,
1565				extends: "libvndk",
1566			},
1567			nocrt: true,
1568		}
1569	`)
1570
1571	testCcError(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
1572		cc_library {
1573			name: "libvndk",
1574			vendor_available: true,
1575			product_available: true,
1576			vndk: {
1577				enabled: true,
1578			},
1579			nocrt: true,
1580		}
1581
1582		cc_library {
1583			name: "libvndk_ext",
1584			vendor: true,
1585			vndk: {
1586				enabled: true,
1587			},
1588			nocrt: true,
1589		}
1590	`)
1591
1592	testCcErrorProductVndk(t, "must set `extends: \"\\.\\.\\.\"` to vndk extension", `
1593		cc_library {
1594			name: "libvndk",
1595			vendor_available: true,
1596			product_available: true,
1597			vndk: {
1598				enabled: true,
1599			},
1600			nocrt: true,
1601		}
1602
1603		cc_library {
1604			name: "libvndk_ext_product",
1605			product_specific: true,
1606			vndk: {
1607				enabled: true,
1608			},
1609			nocrt: true,
1610		}
1611	`)
1612
1613	testCcErrorProductVndk(t, "must not set at the same time as `vndk: {extends: \"\\.\\.\\.\"}`", `
1614		cc_library {
1615			name: "libvndk",
1616			vendor_available: true,
1617			product_available: true,
1618			vndk: {
1619				enabled: true,
1620			},
1621			nocrt: true,
1622		}
1623
1624		cc_library {
1625			name: "libvndk_ext_product",
1626			product_specific: true,
1627			vendor_available: true,
1628			product_available: true,
1629			vndk: {
1630				enabled: true,
1631				extends: "libvndk",
1632			},
1633			nocrt: true,
1634		}
1635	`)
1636}
1637
1638func TestVndkExtInconsistentSupportSystemProcessError(t *testing.T) {
1639	t.Parallel()
1640	// This test ensures an error is emitted for inconsistent support_system_process.
1641	testCcError(t, "module \".*\" with mismatched support_system_process", `
1642		cc_library {
1643			name: "libvndk",
1644			vendor_available: true,
1645			product_available: true,
1646			vndk: {
1647				enabled: true,
1648			},
1649			nocrt: true,
1650		}
1651
1652		cc_library {
1653			name: "libvndk_sp_ext",
1654			vendor: true,
1655			vndk: {
1656				enabled: true,
1657				extends: "libvndk",
1658				support_system_process: true,
1659			},
1660			nocrt: true,
1661		}
1662	`)
1663
1664	testCcError(t, "module \".*\" with mismatched support_system_process", `
1665		cc_library {
1666			name: "libvndk_sp",
1667			vendor_available: true,
1668			product_available: true,
1669			vndk: {
1670				enabled: true,
1671				support_system_process: true,
1672			},
1673			nocrt: true,
1674		}
1675
1676		cc_library {
1677			name: "libvndk_ext",
1678			vendor: true,
1679			vndk: {
1680				enabled: true,
1681				extends: "libvndk_sp",
1682			},
1683			nocrt: true,
1684		}
1685	`)
1686}
1687
1688func TestVndkExtVendorAvailableFalseError(t *testing.T) {
1689	t.Parallel()
1690	// This test ensures an error is emitted when a VNDK-Ext library extends a VNDK library
1691	// with `private: true`.
1692	testCcError(t, "`extends` refers module \".*\" which has `private: true`", `
1693		cc_library {
1694			name: "libvndk",
1695			vendor_available: true,
1696			product_available: true,
1697			vndk: {
1698				enabled: true,
1699				private: true,
1700			},
1701			nocrt: true,
1702		}
1703
1704		cc_library {
1705			name: "libvndk_ext",
1706			vendor: true,
1707			vndk: {
1708				enabled: true,
1709				extends: "libvndk",
1710			},
1711			nocrt: true,
1712		}
1713	`)
1714
1715	testCcErrorProductVndk(t, "`extends` refers module \".*\" which has `private: true`", `
1716		cc_library {
1717			name: "libvndk",
1718			vendor_available: true,
1719			product_available: true,
1720			vndk: {
1721				enabled: true,
1722				private: true,
1723			},
1724			nocrt: true,
1725		}
1726
1727		cc_library {
1728			name: "libvndk_ext_product",
1729			product_specific: true,
1730			vndk: {
1731				enabled: true,
1732				extends: "libvndk",
1733			},
1734			nocrt: true,
1735		}
1736	`)
1737}
1738
1739func TestVendorModuleUseVndkExt(t *testing.T) {
1740	t.Parallel()
1741	// This test ensures a vendor module can depend on a VNDK-Ext library.
1742	testCc(t, `
1743		cc_library {
1744			name: "libvndk",
1745			vendor_available: true,
1746			product_available: true,
1747			vndk: {
1748				enabled: true,
1749			},
1750			nocrt: true,
1751		}
1752
1753		cc_library {
1754			name: "libvndk_ext",
1755			vendor: true,
1756			vndk: {
1757				enabled: true,
1758				extends: "libvndk",
1759			},
1760			nocrt: true,
1761		}
1762
1763		cc_library {
1764			name: "libvndk_sp",
1765			vendor_available: true,
1766			product_available: true,
1767			vndk: {
1768				enabled: true,
1769				support_system_process: true,
1770			},
1771			nocrt: true,
1772		}
1773
1774		cc_library {
1775			name: "libvndk_sp_ext",
1776			vendor: true,
1777			vndk: {
1778				enabled: true,
1779				extends: "libvndk_sp",
1780				support_system_process: true,
1781			},
1782			nocrt: true,
1783		}
1784
1785		cc_library {
1786			name: "libvendor",
1787			vendor: true,
1788			shared_libs: ["libvndk_ext", "libvndk_sp_ext"],
1789			nocrt: true,
1790		}
1791	`)
1792}
1793
1794func TestVndkExtUseVendorLib(t *testing.T) {
1795	t.Parallel()
1796	// This test ensures a VNDK-Ext library can depend on a vendor library.
1797	testCc(t, `
1798		cc_library {
1799			name: "libvndk",
1800			vendor_available: true,
1801			product_available: true,
1802			vndk: {
1803				enabled: true,
1804			},
1805			nocrt: true,
1806		}
1807
1808		cc_library {
1809			name: "libvndk_ext",
1810			vendor: true,
1811			vndk: {
1812				enabled: true,
1813				extends: "libvndk",
1814			},
1815			shared_libs: ["libvendor"],
1816			nocrt: true,
1817		}
1818
1819		cc_library {
1820			name: "libvendor",
1821			vendor: true,
1822			nocrt: true,
1823		}
1824	`)
1825
1826	// This test ensures a VNDK-SP-Ext library can depend on a vendor library.
1827	testCc(t, `
1828		cc_library {
1829			name: "libvndk_sp",
1830			vendor_available: true,
1831			product_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			shared_libs: ["libvendor"],  // Cause an error
1848			nocrt: true,
1849		}
1850
1851		cc_library {
1852			name: "libvendor",
1853			vendor: true,
1854			nocrt: true,
1855		}
1856	`)
1857}
1858
1859func TestProductVndkExtDependency(t *testing.T) {
1860	t.Parallel()
1861	bp := `
1862		cc_library {
1863			name: "libvndk",
1864			vendor_available: true,
1865			product_available: true,
1866			vndk: {
1867				enabled: true,
1868			},
1869			nocrt: true,
1870		}
1871
1872		cc_library {
1873			name: "libvndk_ext_product",
1874			product_specific: true,
1875			vndk: {
1876				enabled: true,
1877				extends: "libvndk",
1878			},
1879			shared_libs: ["libproduct_for_vndklibs"],
1880			nocrt: true,
1881		}
1882
1883		cc_library {
1884			name: "libvndk_sp",
1885			vendor_available: true,
1886			product_available: true,
1887			vndk: {
1888				enabled: true,
1889				support_system_process: true,
1890			},
1891			nocrt: true,
1892		}
1893
1894		cc_library {
1895			name: "libvndk_sp_ext_product",
1896			product_specific: true,
1897			vndk: {
1898				enabled: true,
1899				extends: "libvndk_sp",
1900				support_system_process: true,
1901			},
1902			shared_libs: ["libproduct_for_vndklibs"],
1903			nocrt: true,
1904		}
1905
1906		cc_library {
1907			name: "libproduct",
1908			product_specific: true,
1909			shared_libs: ["libvndk_ext_product", "libvndk_sp_ext_product"],
1910			nocrt: true,
1911		}
1912
1913		cc_library {
1914			name: "libproduct_for_vndklibs",
1915			product_specific: true,
1916			nocrt: true,
1917		}
1918	`
1919	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
1920	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
1921	config.TestProductVariables.ProductVndkVersion = StringPtr("current")
1922	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
1923
1924	testCcWithConfig(t, config)
1925}
1926
1927func TestVndkSpExtUseVndkError(t *testing.T) {
1928	t.Parallel()
1929	// This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK
1930	// library.
1931	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1932		cc_library {
1933			name: "libvndk",
1934			vendor_available: true,
1935			product_available: true,
1936			vndk: {
1937				enabled: true,
1938			},
1939			nocrt: true,
1940		}
1941
1942		cc_library {
1943			name: "libvndk_sp",
1944			vendor_available: true,
1945			product_available: true,
1946			vndk: {
1947				enabled: true,
1948				support_system_process: true,
1949			},
1950			nocrt: true,
1951		}
1952
1953		cc_library {
1954			name: "libvndk_sp_ext",
1955			vendor: true,
1956			vndk: {
1957				enabled: true,
1958				extends: "libvndk_sp",
1959				support_system_process: true,
1960			},
1961			shared_libs: ["libvndk"],  // Cause an error
1962			nocrt: true,
1963		}
1964	`)
1965
1966	// This test ensures an error is emitted if a VNDK-SP-Ext library depends on a VNDK-Ext
1967	// library.
1968	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
1969		cc_library {
1970			name: "libvndk",
1971			vendor_available: true,
1972			product_available: true,
1973			vndk: {
1974				enabled: true,
1975			},
1976			nocrt: true,
1977		}
1978
1979		cc_library {
1980			name: "libvndk_ext",
1981			vendor: true,
1982			vndk: {
1983				enabled: true,
1984				extends: "libvndk",
1985			},
1986			nocrt: true,
1987		}
1988
1989		cc_library {
1990			name: "libvndk_sp",
1991			vendor_available: true,
1992			product_available: true,
1993			vndk: {
1994				enabled: true,
1995				support_system_process: true,
1996			},
1997			nocrt: true,
1998		}
1999
2000		cc_library {
2001			name: "libvndk_sp_ext",
2002			vendor: true,
2003			vndk: {
2004				enabled: true,
2005				extends: "libvndk_sp",
2006				support_system_process: true,
2007			},
2008			shared_libs: ["libvndk_ext"],  // Cause an error
2009			nocrt: true,
2010		}
2011	`)
2012}
2013
2014func TestVndkUseVndkExtError(t *testing.T) {
2015	t.Parallel()
2016	// This test ensures an error is emitted if a VNDK/VNDK-SP library depends on a
2017	// VNDK-Ext/VNDK-SP-Ext library.
2018	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
2019		cc_library {
2020			name: "libvndk",
2021			vendor_available: true,
2022			product_available: true,
2023			vndk: {
2024				enabled: true,
2025			},
2026			nocrt: true,
2027		}
2028
2029		cc_library {
2030			name: "libvndk_ext",
2031			vendor: true,
2032			vndk: {
2033				enabled: true,
2034				extends: "libvndk",
2035			},
2036			nocrt: true,
2037		}
2038
2039		cc_library {
2040			name: "libvndk2",
2041			vendor_available: true,
2042			product_available: true,
2043			vndk: {
2044				enabled: true,
2045			},
2046			shared_libs: ["libvndk_ext"],
2047			nocrt: true,
2048		}
2049	`)
2050
2051	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
2052		cc_library {
2053			name: "libvndk",
2054			vendor_available: true,
2055			product_available: true,
2056			vndk: {
2057				enabled: true,
2058			},
2059			nocrt: true,
2060		}
2061
2062		cc_library {
2063			name: "libvndk_ext",
2064			vendor: true,
2065			vndk: {
2066				enabled: true,
2067				extends: "libvndk",
2068			},
2069			nocrt: true,
2070		}
2071
2072		cc_library {
2073			name: "libvndk2",
2074			vendor_available: true,
2075			vndk: {
2076				enabled: true,
2077			},
2078			target: {
2079				vendor: {
2080					shared_libs: ["libvndk_ext"],
2081				},
2082			},
2083			nocrt: true,
2084		}
2085	`)
2086
2087	testCcError(t, "dependency \".*\" of \".*\" missing variant", `
2088		cc_library {
2089			name: "libvndk_sp",
2090			vendor_available: true,
2091			product_available: true,
2092			vndk: {
2093				enabled: true,
2094				support_system_process: true,
2095			},
2096			nocrt: true,
2097		}
2098
2099		cc_library {
2100			name: "libvndk_sp_ext",
2101			vendor: true,
2102			vndk: {
2103				enabled: true,
2104				extends: "libvndk_sp",
2105				support_system_process: true,
2106			},
2107			nocrt: true,
2108		}
2109
2110		cc_library {
2111			name: "libvndk_sp_2",
2112			vendor_available: true,
2113			product_available: true,
2114			vndk: {
2115				enabled: true,
2116				support_system_process: true,
2117			},
2118			shared_libs: ["libvndk_sp_ext"],
2119			nocrt: true,
2120		}
2121	`)
2122
2123	testCcError(t, "module \".*\" variant \".*\": \\(.*\\) should not link to \".*\"", `
2124		cc_library {
2125			name: "libvndk_sp",
2126			vendor_available: true,
2127			product_available: true,
2128			vndk: {
2129				enabled: true,
2130			},
2131			nocrt: true,
2132		}
2133
2134		cc_library {
2135			name: "libvndk_sp_ext",
2136			vendor: true,
2137			vndk: {
2138				enabled: true,
2139				extends: "libvndk_sp",
2140			},
2141			nocrt: true,
2142		}
2143
2144		cc_library {
2145			name: "libvndk_sp2",
2146			vendor_available: true,
2147			vndk: {
2148				enabled: true,
2149			},
2150			target: {
2151				vendor: {
2152					shared_libs: ["libvndk_sp_ext"],
2153				},
2154			},
2155			nocrt: true,
2156		}
2157	`)
2158}
2159
2160func TestEnforceProductVndkVersion(t *testing.T) {
2161	t.Parallel()
2162	bp := `
2163		cc_library {
2164			name: "libllndk",
2165			llndk: {
2166				symbol_file: "libllndk.map.txt",
2167			}
2168		}
2169		cc_library {
2170			name: "libvndk",
2171			vendor_available: true,
2172			product_available: true,
2173			vndk: {
2174				enabled: true,
2175			},
2176			nocrt: true,
2177		}
2178		cc_library {
2179			name: "libvndk_sp",
2180			vendor_available: true,
2181			product_available: true,
2182			vndk: {
2183				enabled: true,
2184				support_system_process: true,
2185			},
2186			nocrt: true,
2187		}
2188		cc_library {
2189			name: "libva",
2190			vendor_available: true,
2191			nocrt: true,
2192		}
2193		cc_library {
2194			name: "libpa",
2195			product_available: true,
2196			nocrt: true,
2197		}
2198		cc_library {
2199			name: "libboth_available",
2200			vendor_available: true,
2201			product_available: true,
2202			nocrt: true,
2203			srcs: ["foo.c"],
2204			target: {
2205				vendor: {
2206					suffix: "-vendor",
2207				},
2208				product: {
2209					suffix: "-product",
2210				},
2211			}
2212		}
2213		cc_library {
2214			name: "libproduct_va",
2215			product_specific: true,
2216			vendor_available: true,
2217			nocrt: true,
2218		}
2219		cc_library {
2220			name: "libprod",
2221			product_specific: true,
2222			shared_libs: [
2223				"libllndk",
2224				"libvndk",
2225				"libvndk_sp",
2226				"libpa",
2227				"libboth_available",
2228				"libproduct_va",
2229			],
2230			nocrt: true,
2231		}
2232		cc_library {
2233			name: "libvendor",
2234			vendor: true,
2235			shared_libs: [
2236				"libllndk",
2237				"libvndk",
2238				"libvndk_sp",
2239				"libva",
2240				"libboth_available",
2241				"libproduct_va",
2242			],
2243			nocrt: true,
2244		}
2245	`
2246
2247	ctx := prepareForCcTest.RunTestWithBp(t, bp).TestContext
2248
2249	checkVndkModule(t, ctx, "libvndk", "", false, "", productVariant)
2250	checkVndkModule(t, ctx, "libvndk_sp", "", true, "", productVariant)
2251
2252	mod_vendor := ctx.ModuleForTests("libboth_available", vendorVariant).Module().(*Module)
2253	assertString(t, mod_vendor.outputFile.Path().Base(), "libboth_available-vendor.so")
2254
2255	mod_product := ctx.ModuleForTests("libboth_available", productVariant).Module().(*Module)
2256	assertString(t, mod_product.outputFile.Path().Base(), "libboth_available-product.so")
2257
2258	ensureStringContains := func(t *testing.T, str string, substr string) {
2259		t.Helper()
2260		if !strings.Contains(str, substr) {
2261			t.Errorf("%q is not found in %v", substr, str)
2262		}
2263	}
2264	ensureStringNotContains := func(t *testing.T, str string, substr string) {
2265		t.Helper()
2266		if strings.Contains(str, substr) {
2267			t.Errorf("%q is found in %v", substr, str)
2268		}
2269	}
2270
2271	// _static variant is used since _shared reuses *.o from the static variant
2272	vendor_static := ctx.ModuleForTests("libboth_available", strings.Replace(vendorVariant, "_shared", "_static", 1))
2273	product_static := ctx.ModuleForTests("libboth_available", strings.Replace(productVariant, "_shared", "_static", 1))
2274
2275	vendor_cflags := vendor_static.Rule("cc").Args["cFlags"]
2276	ensureStringContains(t, vendor_cflags, "-D__ANDROID_VNDK__")
2277	ensureStringContains(t, vendor_cflags, "-D__ANDROID_VENDOR__")
2278	ensureStringNotContains(t, vendor_cflags, "-D__ANDROID_PRODUCT__")
2279
2280	product_cflags := product_static.Rule("cc").Args["cFlags"]
2281	ensureStringContains(t, product_cflags, "-D__ANDROID_VNDK__")
2282	ensureStringContains(t, product_cflags, "-D__ANDROID_PRODUCT__")
2283	ensureStringNotContains(t, product_cflags, "-D__ANDROID_VENDOR__")
2284}
2285
2286func TestEnforceProductVndkVersionErrors(t *testing.T) {
2287	t.Parallel()
2288	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.29", `
2289		cc_library {
2290			name: "libprod",
2291			product_specific: true,
2292			shared_libs: [
2293				"libvendor",
2294			],
2295			nocrt: true,
2296		}
2297		cc_library {
2298			name: "libvendor",
2299			vendor: true,
2300			nocrt: true,
2301		}
2302	`)
2303	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.29", `
2304		cc_library {
2305			name: "libprod",
2306			product_specific: true,
2307			shared_libs: [
2308				"libsystem",
2309			],
2310			nocrt: true,
2311		}
2312		cc_library {
2313			name: "libsystem",
2314			nocrt: true,
2315		}
2316	`)
2317	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.29", `
2318		cc_library {
2319			name: "libprod",
2320			product_specific: true,
2321			shared_libs: [
2322				"libva",
2323			],
2324			nocrt: true,
2325		}
2326		cc_library {
2327			name: "libva",
2328			vendor_available: true,
2329			nocrt: true,
2330		}
2331	`)
2332	testCcErrorProductVndk(t, "non-VNDK module should not link to \".*\" which has `private: true`", `
2333		cc_library {
2334			name: "libprod",
2335			product_specific: true,
2336			shared_libs: [
2337				"libvndk_private",
2338			],
2339			nocrt: true,
2340		}
2341		cc_library {
2342			name: "libvndk_private",
2343			vendor_available: true,
2344			product_available: true,
2345			vndk: {
2346				enabled: true,
2347				private: true,
2348			},
2349			nocrt: true,
2350		}
2351	`)
2352	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:product.29", `
2353		cc_library {
2354			name: "libprod",
2355			product_specific: true,
2356			shared_libs: [
2357				"libsystem_ext",
2358			],
2359			nocrt: true,
2360		}
2361		cc_library {
2362			name: "libsystem_ext",
2363			system_ext_specific: true,
2364			nocrt: true,
2365		}
2366	`)
2367	testCcErrorProductVndk(t, "dependency \".*\" of \".*\" missing variant:\n.*image:", `
2368		cc_library {
2369			name: "libsystem",
2370			shared_libs: [
2371				"libproduct_va",
2372			],
2373			nocrt: true,
2374		}
2375		cc_library {
2376			name: "libproduct_va",
2377			product_specific: true,
2378			vendor_available: true,
2379			nocrt: true,
2380		}
2381	`)
2382}
2383
2384func TestMakeLinkType(t *testing.T) {
2385	t.Parallel()
2386	bp := `
2387		cc_library {
2388			name: "libvndk",
2389			vendor_available: true,
2390			product_available: true,
2391			vndk: {
2392				enabled: true,
2393			},
2394		}
2395		cc_library {
2396			name: "libvndksp",
2397			vendor_available: true,
2398			product_available: true,
2399			vndk: {
2400				enabled: true,
2401				support_system_process: true,
2402			},
2403		}
2404		cc_library {
2405			name: "libvndkprivate",
2406			vendor_available: true,
2407			product_available: true,
2408			vndk: {
2409				enabled: true,
2410				private: true,
2411			},
2412		}
2413		cc_library {
2414			name: "libvendor",
2415			vendor: true,
2416		}
2417		cc_library {
2418			name: "libvndkext",
2419			vendor: true,
2420			vndk: {
2421				enabled: true,
2422				extends: "libvndk",
2423			},
2424		}
2425		vndk_prebuilt_shared {
2426			name: "prevndk",
2427			version: "27",
2428			target_arch: "arm",
2429			binder32bit: true,
2430			vendor_available: true,
2431			product_available: true,
2432			vndk: {
2433				enabled: true,
2434			},
2435			arch: {
2436				arm: {
2437					srcs: ["liba.so"],
2438				},
2439			},
2440		}
2441		cc_library {
2442			name: "libllndk",
2443			llndk: {
2444				symbol_file: "libllndk.map.txt",
2445			}
2446		}
2447		cc_library {
2448			name: "libllndkprivate",
2449			llndk: {
2450				symbol_file: "libllndkprivate.map.txt",
2451				private: true,
2452			}
2453		}
2454
2455		llndk_libraries_txt {
2456			name: "llndk.libraries.txt",
2457		}
2458		vndkcore_libraries_txt {
2459			name: "vndkcore.libraries.txt",
2460		}
2461		vndksp_libraries_txt {
2462			name: "vndksp.libraries.txt",
2463		}
2464		vndkprivate_libraries_txt {
2465			name: "vndkprivate.libraries.txt",
2466		}
2467		vndkcorevariant_libraries_txt {
2468			name: "vndkcorevariant.libraries.txt",
2469			insert_vndk_version: false,
2470		}
2471	`
2472
2473	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
2474	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
2475	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
2476	// native:vndk
2477	ctx := testCcWithConfig(t, config)
2478
2479	checkVndkLibrariesOutput(t, ctx, "vndkcore.libraries.txt",
2480		[]string{"libvndk.so", "libvndkprivate.so"})
2481	checkVndkLibrariesOutput(t, ctx, "vndksp.libraries.txt",
2482		[]string{"libc++.so", "libvndksp.so"})
2483	checkVndkLibrariesOutput(t, ctx, "llndk.libraries.txt",
2484		[]string{"libc.so", "libdl.so", "libft2.so", "libllndk.so", "libllndkprivate.so", "libm.so"})
2485	checkVndkLibrariesOutput(t, ctx, "vndkprivate.libraries.txt",
2486		[]string{"libft2.so", "libllndkprivate.so", "libvndkprivate.so"})
2487
2488	vendorVariant27 := "android_vendor.27_arm64_armv8-a_shared"
2489
2490	tests := []struct {
2491		variant  string
2492		name     string
2493		expected string
2494	}{
2495		{vendorVariant, "libvndk", "native:vndk"},
2496		{vendorVariant, "libvndksp", "native:vndk"},
2497		{vendorVariant, "libvndkprivate", "native:vndk_private"},
2498		{vendorVariant, "libvendor", "native:vendor"},
2499		{vendorVariant, "libvndkext", "native:vendor"},
2500		{vendorVariant, "libllndk", "native:vndk"},
2501		{vendorVariant27, "prevndk.vndk.27.arm.binder32", "native:vndk"},
2502		{coreVariant, "libvndk", "native:platform"},
2503		{coreVariant, "libvndkprivate", "native:platform"},
2504		{coreVariant, "libllndk", "native:platform"},
2505	}
2506	for _, test := range tests {
2507		t.Run(test.name, func(t *testing.T) {
2508			module := ctx.ModuleForTests(test.name, test.variant).Module().(*Module)
2509			assertString(t, module.makeLinkType, test.expected)
2510		})
2511	}
2512}
2513
2514var staticLinkDepOrderTestCases = []struct {
2515	// This is a string representation of a map[moduleName][]moduleDependency .
2516	// It models the dependencies declared in an Android.bp file.
2517	inStatic string
2518
2519	// This is a string representation of a map[moduleName][]moduleDependency .
2520	// It models the dependencies declared in an Android.bp file.
2521	inShared string
2522
2523	// allOrdered is a string representation of a map[moduleName][]moduleDependency .
2524	// The keys of allOrdered specify which modules we would like to check.
2525	// The values of allOrdered specify the expected result (of the transitive closure of all
2526	// dependencies) for each module to test
2527	allOrdered string
2528
2529	// outOrdered is a string representation of a map[moduleName][]moduleDependency .
2530	// The keys of outOrdered specify which modules we would like to check.
2531	// The values of outOrdered specify the expected result (of the ordered linker command line)
2532	// for each module to test.
2533	outOrdered string
2534}{
2535	// Simple tests
2536	{
2537		inStatic:   "",
2538		outOrdered: "",
2539	},
2540	{
2541		inStatic:   "a:",
2542		outOrdered: "a:",
2543	},
2544	{
2545		inStatic:   "a:b; b:",
2546		outOrdered: "a:b; b:",
2547	},
2548	// Tests of reordering
2549	{
2550		// diamond example
2551		inStatic:   "a:d,b,c; b:d; c:d; d:",
2552		outOrdered: "a:b,c,d; b:d; c:d; d:",
2553	},
2554	{
2555		// somewhat real example
2556		inStatic:   "bsdiff_unittest:b,c,d,e,f,g,h,i; e:b",
2557		outOrdered: "bsdiff_unittest:c,d,e,b,f,g,h,i; e:b",
2558	},
2559	{
2560		// multiple reorderings
2561		inStatic:   "a:b,c,d,e; d:b; e:c",
2562		outOrdered: "a:d,b,e,c; d:b; e:c",
2563	},
2564	{
2565		// should reorder without adding new transitive dependencies
2566		inStatic:   "bin:lib2,lib1;             lib1:lib2,liboptional",
2567		allOrdered: "bin:lib1,lib2,liboptional; lib1:lib2,liboptional",
2568		outOrdered: "bin:lib1,lib2;             lib1:lib2,liboptional",
2569	},
2570	{
2571		// multiple levels of dependencies
2572		inStatic:   "a:b,c,d,e,f,g,h; f:b,c,d; b:c,d; c:d",
2573		allOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
2574		outOrdered: "a:e,f,b,c,d,g,h; f:b,c,d; b:c,d; c:d",
2575	},
2576	// shared dependencies
2577	{
2578		// Note that this test doesn't recurse, to minimize the amount of logic it tests.
2579		// So, we don't actually have to check that a shared dependency of c will change the order
2580		// of a library that depends statically on b and on c.  We only need to check that if c has
2581		// a shared dependency on b, that that shows up in allOrdered.
2582		inShared:   "c:b",
2583		allOrdered: "c:b",
2584		outOrdered: "c:",
2585	},
2586	{
2587		// This test doesn't actually include any shared dependencies but it's a reminder of what
2588		// the second phase of the above test would look like
2589		inStatic:   "a:b,c; c:b",
2590		allOrdered: "a:c,b; c:b",
2591		outOrdered: "a:c,b; c:b",
2592	},
2593	// tiebreakers for when two modules specifying different orderings and there is no dependency
2594	// to dictate an order
2595	{
2596		// if the tie is between two modules at the end of a's deps, then a's order wins
2597		inStatic:   "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
2598		outOrdered: "a1:b,c,d,e; a2:b,c,e,d; b:d,e; c:e,d",
2599	},
2600	{
2601		// if the tie is between two modules at the start of a's deps, then c's order is used
2602		inStatic:   "a1:d,e,b1,c1; b1:d,e; c1:e,d;   a2:d,e,b2,c2; b2:d,e; c2:d,e",
2603		outOrdered: "a1:b1,c1,e,d; b1:d,e; c1:e,d;   a2:b2,c2,d,e; b2:d,e; c2:d,e",
2604	},
2605	// Tests involving duplicate dependencies
2606	{
2607		// simple duplicate
2608		inStatic:   "a:b,c,c,b",
2609		outOrdered: "a:c,b",
2610	},
2611	{
2612		// duplicates with reordering
2613		inStatic:   "a:b,c,d,c; c:b",
2614		outOrdered: "a:d,c,b",
2615	},
2616	// Tests to confirm the nonexistence of infinite loops.
2617	// These cases should never happen, so as long as the test terminates and the
2618	// result is deterministic then that should be fine.
2619	{
2620		inStatic:   "a:a",
2621		outOrdered: "a:a",
2622	},
2623	{
2624		inStatic:   "a:b;   b:c;   c:a",
2625		allOrdered: "a:b,c; b:c,a; c:a,b",
2626		outOrdered: "a:b;   b:c;   c:a",
2627	},
2628	{
2629		inStatic:   "a:b,c;   b:c,a;   c:a,b",
2630		allOrdered: "a:c,a,b; b:a,b,c; c:b,c,a",
2631		outOrdered: "a:c,b;   b:a,c;   c:b,a",
2632	},
2633}
2634
2635// converts from a string like "a:b,c; d:e" to (["a","b"], {"a":["b","c"], "d":["e"]}, [{"a", "a.o"}, {"b", "b.o"}])
2636func parseModuleDeps(text string) (modulesInOrder []android.Path, allDeps map[android.Path][]android.Path) {
2637	// convert from "a:b,c; d:e" to "a:b,c;d:e"
2638	strippedText := strings.Replace(text, " ", "", -1)
2639	if len(strippedText) < 1 {
2640		return []android.Path{}, make(map[android.Path][]android.Path, 0)
2641	}
2642	allDeps = make(map[android.Path][]android.Path, 0)
2643
2644	// convert from "a:b,c;d:e" to ["a:b,c", "d:e"]
2645	moduleTexts := strings.Split(strippedText, ";")
2646
2647	outputForModuleName := func(moduleName string) android.Path {
2648		return android.PathForTesting(moduleName)
2649	}
2650
2651	for _, moduleText := range moduleTexts {
2652		// convert from "a:b,c" to ["a", "b,c"]
2653		components := strings.Split(moduleText, ":")
2654		if len(components) != 2 {
2655			panic(fmt.Sprintf("illegal module dep string %q from larger string %q; must contain one ':', not %v", moduleText, text, len(components)-1))
2656		}
2657		moduleName := components[0]
2658		moduleOutput := outputForModuleName(moduleName)
2659		modulesInOrder = append(modulesInOrder, moduleOutput)
2660
2661		depString := components[1]
2662		// convert from "b,c" to ["b", "c"]
2663		depNames := strings.Split(depString, ",")
2664		if len(depString) < 1 {
2665			depNames = []string{}
2666		}
2667		var deps []android.Path
2668		for _, depName := range depNames {
2669			deps = append(deps, outputForModuleName(depName))
2670		}
2671		allDeps[moduleOutput] = deps
2672	}
2673	return modulesInOrder, allDeps
2674}
2675
2676func TestStaticLibDepReordering(t *testing.T) {
2677	t.Parallel()
2678	ctx := testCc(t, `
2679	cc_library {
2680		name: "a",
2681		static_libs: ["b", "c", "d"],
2682		stl: "none",
2683	}
2684	cc_library {
2685		name: "b",
2686		stl: "none",
2687	}
2688	cc_library {
2689		name: "c",
2690		static_libs: ["b"],
2691		stl: "none",
2692	}
2693	cc_library {
2694		name: "d",
2695		stl: "none",
2696	}
2697
2698	`)
2699
2700	variant := "android_arm64_armv8-a_static"
2701	moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
2702	actual := ctx.ModuleProvider(moduleA, StaticLibraryInfoProvider).(StaticLibraryInfo).
2703		TransitiveStaticLibrariesForOrdering.ToList().RelativeToTop()
2704	expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b", "d"})
2705
2706	if !reflect.DeepEqual(actual, expected) {
2707		t.Errorf("staticDeps orderings were not propagated correctly"+
2708			"\nactual:   %v"+
2709			"\nexpected: %v",
2710			actual,
2711			expected,
2712		)
2713	}
2714}
2715
2716func TestStaticLibDepReorderingWithShared(t *testing.T) {
2717	t.Parallel()
2718	ctx := testCc(t, `
2719	cc_library {
2720		name: "a",
2721		static_libs: ["b", "c"],
2722		stl: "none",
2723	}
2724	cc_library {
2725		name: "b",
2726		stl: "none",
2727	}
2728	cc_library {
2729		name: "c",
2730		shared_libs: ["b"],
2731		stl: "none",
2732	}
2733
2734	`)
2735
2736	variant := "android_arm64_armv8-a_static"
2737	moduleA := ctx.ModuleForTests("a", variant).Module().(*Module)
2738	actual := ctx.ModuleProvider(moduleA, StaticLibraryInfoProvider).(StaticLibraryInfo).
2739		TransitiveStaticLibrariesForOrdering.ToList().RelativeToTop()
2740	expected := GetOutputPaths(ctx, variant, []string{"a", "c", "b"})
2741
2742	if !reflect.DeepEqual(actual, expected) {
2743		t.Errorf("staticDeps orderings did not account for shared libs"+
2744			"\nactual:   %v"+
2745			"\nexpected: %v",
2746			actual,
2747			expected,
2748		)
2749	}
2750}
2751
2752func checkEquals(t *testing.T, message string, expected, actual interface{}) {
2753	t.Helper()
2754	if !reflect.DeepEqual(actual, expected) {
2755		t.Errorf(message+
2756			"\nactual:   %v"+
2757			"\nexpected: %v",
2758			actual,
2759			expected,
2760		)
2761	}
2762}
2763
2764func TestLlndkLibrary(t *testing.T) {
2765	t.Parallel()
2766	result := prepareForCcTest.RunTestWithBp(t, `
2767	cc_library {
2768		name: "libllndk",
2769		stubs: { versions: ["1", "2"] },
2770		llndk: {
2771			symbol_file: "libllndk.map.txt",
2772		},
2773		export_include_dirs: ["include"],
2774	}
2775
2776	cc_prebuilt_library_shared {
2777		name: "libllndkprebuilt",
2778		stubs: { versions: ["1", "2"] },
2779		llndk: {
2780			symbol_file: "libllndkprebuilt.map.txt",
2781		},
2782	}
2783
2784	cc_library {
2785		name: "libllndk_with_external_headers",
2786		stubs: { versions: ["1", "2"] },
2787		llndk: {
2788			symbol_file: "libllndk.map.txt",
2789			export_llndk_headers: ["libexternal_llndk_headers"],
2790		},
2791		header_libs: ["libexternal_headers"],
2792		export_header_lib_headers: ["libexternal_headers"],
2793	}
2794	cc_library_headers {
2795		name: "libexternal_headers",
2796		export_include_dirs: ["include"],
2797		vendor_available: true,
2798	}
2799	cc_library_headers {
2800		name: "libexternal_llndk_headers",
2801		export_include_dirs: ["include_llndk"],
2802		llndk: {
2803			symbol_file: "libllndk.map.txt",
2804		},
2805		vendor_available: true,
2806	}
2807
2808	cc_library {
2809		name: "libllndk_with_override_headers",
2810		stubs: { versions: ["1", "2"] },
2811		llndk: {
2812			symbol_file: "libllndk.map.txt",
2813			override_export_include_dirs: ["include_llndk"],
2814		},
2815		export_include_dirs: ["include"],
2816	}
2817	`)
2818	actual := result.ModuleVariantsForTests("libllndk")
2819	for i := 0; i < len(actual); i++ {
2820		if !strings.HasPrefix(actual[i], "android_vendor.29_") {
2821			actual = append(actual[:i], actual[i+1:]...)
2822			i--
2823		}
2824	}
2825	expected := []string{
2826		"android_vendor.29_arm64_armv8-a_shared_current",
2827		"android_vendor.29_arm64_armv8-a_shared",
2828		"android_vendor.29_arm_armv7-a-neon_shared_current",
2829		"android_vendor.29_arm_armv7-a-neon_shared",
2830	}
2831	android.AssertArrayString(t, "variants for llndk stubs", expected, actual)
2832
2833	params := result.ModuleForTests("libllndk", "android_vendor.29_arm_armv7-a-neon_shared").Description("generate stub")
2834	android.AssertSame(t, "use VNDK version for default stubs", "current", params.Args["apiLevel"])
2835
2836	checkExportedIncludeDirs := func(module, variant string, expectedDirs ...string) {
2837		t.Helper()
2838		m := result.ModuleForTests(module, variant).Module()
2839		f := result.ModuleProvider(m, FlagExporterInfoProvider).(FlagExporterInfo)
2840		android.AssertPathsRelativeToTopEquals(t, "exported include dirs for "+module+"["+variant+"]",
2841			expectedDirs, f.IncludeDirs)
2842	}
2843
2844	checkExportedIncludeDirs("libllndk", "android_arm64_armv8-a_shared", "include")
2845	checkExportedIncludeDirs("libllndk", "android_vendor.29_arm64_armv8-a_shared", "include")
2846	checkExportedIncludeDirs("libllndk_with_external_headers", "android_arm64_armv8-a_shared", "include")
2847	checkExportedIncludeDirs("libllndk_with_external_headers", "android_vendor.29_arm64_armv8-a_shared", "include_llndk")
2848	checkExportedIncludeDirs("libllndk_with_override_headers", "android_arm64_armv8-a_shared", "include")
2849	checkExportedIncludeDirs("libllndk_with_override_headers", "android_vendor.29_arm64_armv8-a_shared", "include_llndk")
2850}
2851
2852func TestLlndkHeaders(t *testing.T) {
2853	t.Parallel()
2854	ctx := testCc(t, `
2855	cc_library_headers {
2856		name: "libllndk_headers",
2857		export_include_dirs: ["my_include"],
2858		llndk: {
2859			llndk_headers: true,
2860		},
2861	}
2862	cc_library {
2863		name: "libllndk",
2864		llndk: {
2865			symbol_file: "libllndk.map.txt",
2866			export_llndk_headers: ["libllndk_headers"],
2867		}
2868	}
2869
2870	cc_library {
2871		name: "libvendor",
2872		shared_libs: ["libllndk"],
2873		vendor: true,
2874		srcs: ["foo.c"],
2875		no_libcrt: true,
2876		nocrt: true,
2877	}
2878	`)
2879
2880	// _static variant is used since _shared reuses *.o from the static variant
2881	cc := ctx.ModuleForTests("libvendor", "android_vendor.29_arm_armv7-a-neon_static").Rule("cc")
2882	cflags := cc.Args["cFlags"]
2883	if !strings.Contains(cflags, "-Imy_include") {
2884		t.Errorf("cflags for libvendor must contain -Imy_include, but was %#v.", cflags)
2885	}
2886}
2887
2888func checkRuntimeLibs(t *testing.T, expected []string, module *Module) {
2889	actual := module.Properties.AndroidMkRuntimeLibs
2890	if !reflect.DeepEqual(actual, expected) {
2891		t.Errorf("incorrect runtime_libs for shared libs"+
2892			"\nactual:   %v"+
2893			"\nexpected: %v",
2894			actual,
2895			expected,
2896		)
2897	}
2898}
2899
2900const runtimeLibAndroidBp = `
2901	cc_library {
2902		name: "liball_available",
2903		vendor_available: true,
2904		product_available: true,
2905		no_libcrt : true,
2906		nocrt : true,
2907		system_shared_libs : [],
2908	}
2909	cc_library {
2910		name: "libvendor_available1",
2911		vendor_available: true,
2912		runtime_libs: ["liball_available"],
2913		no_libcrt : true,
2914		nocrt : true,
2915		system_shared_libs : [],
2916	}
2917	cc_library {
2918		name: "libvendor_available2",
2919		vendor_available: true,
2920		runtime_libs: ["liball_available"],
2921		target: {
2922			vendor: {
2923				exclude_runtime_libs: ["liball_available"],
2924			}
2925		},
2926		no_libcrt : true,
2927		nocrt : true,
2928		system_shared_libs : [],
2929	}
2930	cc_library {
2931		name: "libproduct_vendor",
2932		product_specific: true,
2933		vendor_available: true,
2934		no_libcrt : true,
2935		nocrt : true,
2936		system_shared_libs : [],
2937	}
2938	cc_library {
2939		name: "libcore",
2940		runtime_libs: ["liball_available"],
2941		no_libcrt : true,
2942		nocrt : true,
2943		system_shared_libs : [],
2944	}
2945	cc_library {
2946		name: "libvendor1",
2947		vendor: true,
2948		no_libcrt : true,
2949		nocrt : true,
2950		system_shared_libs : [],
2951	}
2952	cc_library {
2953		name: "libvendor2",
2954		vendor: true,
2955		runtime_libs: ["liball_available", "libvendor1", "libproduct_vendor"],
2956		no_libcrt : true,
2957		nocrt : true,
2958		system_shared_libs : [],
2959	}
2960	cc_library {
2961		name: "libproduct_available1",
2962		product_available: true,
2963		runtime_libs: ["liball_available"],
2964		no_libcrt : true,
2965		nocrt : true,
2966		system_shared_libs : [],
2967	}
2968	cc_library {
2969		name: "libproduct1",
2970		product_specific: true,
2971		no_libcrt : true,
2972		nocrt : true,
2973		system_shared_libs : [],
2974	}
2975	cc_library {
2976		name: "libproduct2",
2977		product_specific: true,
2978		runtime_libs: ["liball_available", "libproduct1", "libproduct_vendor"],
2979		no_libcrt : true,
2980		nocrt : true,
2981		system_shared_libs : [],
2982	}
2983`
2984
2985func TestRuntimeLibs(t *testing.T) {
2986	t.Parallel()
2987	ctx := testCc(t, runtimeLibAndroidBp)
2988
2989	// runtime_libs for core variants use the module names without suffixes.
2990	variant := "android_arm64_armv8-a_shared"
2991
2992	module := ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
2993	checkRuntimeLibs(t, []string{"liball_available"}, module)
2994
2995	module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
2996	checkRuntimeLibs(t, []string{"liball_available"}, module)
2997
2998	module = ctx.ModuleForTests("libcore", variant).Module().(*Module)
2999	checkRuntimeLibs(t, []string{"liball_available"}, module)
3000
3001	// runtime_libs for vendor variants have '.vendor' suffixes if the modules have both core
3002	// and vendor variants.
3003	variant = "android_vendor.29_arm64_armv8-a_shared"
3004
3005	module = ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
3006	checkRuntimeLibs(t, []string{"liball_available.vendor"}, module)
3007
3008	module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
3009	checkRuntimeLibs(t, []string{"liball_available.vendor", "libvendor1", "libproduct_vendor.vendor"}, module)
3010
3011	// runtime_libs for product variants have '.product' suffixes if the modules have both core
3012	// and product variants.
3013	variant = "android_product.29_arm64_armv8-a_shared"
3014
3015	module = ctx.ModuleForTests("libproduct_available1", variant).Module().(*Module)
3016	checkRuntimeLibs(t, []string{"liball_available.product"}, module)
3017
3018	module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module)
3019	checkRuntimeLibs(t, []string{"liball_available.product", "libproduct1", "libproduct_vendor"}, module)
3020}
3021
3022func TestExcludeRuntimeLibs(t *testing.T) {
3023	t.Parallel()
3024	ctx := testCc(t, runtimeLibAndroidBp)
3025
3026	variant := "android_arm64_armv8-a_shared"
3027	module := ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
3028	checkRuntimeLibs(t, []string{"liball_available"}, module)
3029
3030	variant = "android_vendor.29_arm64_armv8-a_shared"
3031	module = ctx.ModuleForTests("libvendor_available2", variant).Module().(*Module)
3032	checkRuntimeLibs(t, nil, module)
3033}
3034
3035func TestRuntimeLibsNoVndk(t *testing.T) {
3036	t.Parallel()
3037	ctx := testCcNoVndk(t, runtimeLibAndroidBp)
3038
3039	// If DeviceVndkVersion is not defined, then runtime_libs are copied as-is.
3040
3041	variant := "android_arm64_armv8-a_shared"
3042
3043	module := ctx.ModuleForTests("libvendor_available1", variant).Module().(*Module)
3044	checkRuntimeLibs(t, []string{"liball_available"}, module)
3045
3046	module = ctx.ModuleForTests("libvendor2", variant).Module().(*Module)
3047	checkRuntimeLibs(t, []string{"liball_available", "libvendor1", "libproduct_vendor"}, module)
3048
3049	module = ctx.ModuleForTests("libproduct2", variant).Module().(*Module)
3050	checkRuntimeLibs(t, []string{"liball_available", "libproduct1", "libproduct_vendor"}, module)
3051}
3052
3053func checkStaticLibs(t *testing.T, expected []string, module *Module) {
3054	t.Helper()
3055	actual := module.Properties.AndroidMkStaticLibs
3056	if !reflect.DeepEqual(actual, expected) {
3057		t.Errorf("incorrect static_libs"+
3058			"\nactual:   %v"+
3059			"\nexpected: %v",
3060			actual,
3061			expected,
3062		)
3063	}
3064}
3065
3066const staticLibAndroidBp = `
3067	cc_library {
3068		name: "lib1",
3069	}
3070	cc_library {
3071		name: "lib2",
3072		static_libs: ["lib1"],
3073	}
3074`
3075
3076func TestStaticLibDepExport(t *testing.T) {
3077	t.Parallel()
3078	ctx := testCc(t, staticLibAndroidBp)
3079
3080	// Check the shared version of lib2.
3081	variant := "android_arm64_armv8-a_shared"
3082	module := ctx.ModuleForTests("lib2", variant).Module().(*Module)
3083	checkStaticLibs(t, []string{"lib1", "libc++demangle", "libclang_rt.builtins"}, module)
3084
3085	// Check the static version of lib2.
3086	variant = "android_arm64_armv8-a_static"
3087	module = ctx.ModuleForTests("lib2", variant).Module().(*Module)
3088	// libc++_static is linked additionally.
3089	checkStaticLibs(t, []string{"lib1", "libc++_static", "libc++demangle", "libclang_rt.builtins"}, module)
3090}
3091
3092func TestLibDepAndroidMkExportInMixedBuilds(t *testing.T) {
3093	bp := `
3094		cc_library {
3095			name: "static_dep",
3096		}
3097		cc_library {
3098			name: "whole_static_dep",
3099		}
3100		cc_library {
3101			name: "shared_dep",
3102		}
3103		cc_library {
3104			name: "lib",
3105			bazel_module: { label: "//:lib" },
3106			static_libs: ["static_dep"],
3107			whole_static_libs: ["whole_static_dep"],
3108			shared_libs: ["shared_dep"],
3109		}
3110		cc_test {
3111			name: "test",
3112			bazel_module: { label: "//:test" },
3113			static_libs: ["static_dep"],
3114			whole_static_libs: ["whole_static_dep"],
3115			shared_libs: ["shared_dep"],
3116			gtest: false,
3117		}
3118		cc_binary {
3119			name: "binary",
3120			bazel_module: { label: "//:binary" },
3121			static_libs: ["static_dep"],
3122			whole_static_libs: ["whole_static_dep"],
3123			shared_libs: ["shared_dep"],
3124		}
3125		cc_library_headers {
3126			name: "lib_headers",
3127			bazel_module: { label: "//:lib_headers" },
3128			static_libs: ["static_dep"],
3129			whole_static_libs: ["whole_static_dep"],
3130			shared_libs: ["shared_dep"],
3131		}
3132		cc_prebuilt_library {
3133			name: "lib_prebuilt",
3134			bazel_module: { label: "//:lib_prebuilt" },
3135			static_libs: ["static_dep"],
3136			whole_static_libs: ["whole_static_dep"],
3137			shared_libs: ["shared_dep"],
3138		}
3139	`
3140
3141	testCases := []struct {
3142		name          string
3143		moduleName    string
3144		variant       string
3145		androidMkInfo cquery.CcAndroidMkInfo
3146	}{
3147		{
3148			name:       "shared lib",
3149			moduleName: "lib",
3150			variant:    "android_arm64_armv8-a_shared",
3151			androidMkInfo: cquery.CcAndroidMkInfo{
3152				LocalStaticLibs:      []string{"static_dep"},
3153				LocalWholeStaticLibs: []string{"whole_static_dep"},
3154				LocalSharedLibs:      []string{"shared_dep"},
3155			},
3156		},
3157		{
3158			name:       "static lib",
3159			moduleName: "lib",
3160			variant:    "android_arm64_armv8-a_static",
3161			androidMkInfo: cquery.CcAndroidMkInfo{
3162				LocalStaticLibs:      []string{"static_dep"},
3163				LocalWholeStaticLibs: []string{"whole_static_dep"},
3164				LocalSharedLibs:      []string{"shared_dep"},
3165			},
3166		},
3167		{
3168			name:       "cc_test arm64",
3169			moduleName: "test",
3170			variant:    "android_arm64_armv8-a",
3171			androidMkInfo: cquery.CcAndroidMkInfo{
3172				LocalStaticLibs:      []string{"static_dep"},
3173				LocalWholeStaticLibs: []string{"whole_static_dep"},
3174				LocalSharedLibs:      []string{"shared_dep"},
3175			},
3176		},
3177		{
3178			name:       "cc_test arm",
3179			moduleName: "test",
3180			variant:    "android_arm_armv7-a-neon",
3181			androidMkInfo: cquery.CcAndroidMkInfo{
3182				LocalStaticLibs:      []string{"static_dep"},
3183				LocalWholeStaticLibs: []string{"whole_static_dep"},
3184				LocalSharedLibs:      []string{"shared_dep"},
3185			},
3186		},
3187		{
3188			name:       "cc_binary",
3189			moduleName: "binary",
3190			variant:    "android_arm64_armv8-a",
3191			androidMkInfo: cquery.CcAndroidMkInfo{
3192				LocalStaticLibs:      []string{"static_dep"},
3193				LocalWholeStaticLibs: []string{"whole_static_dep"},
3194				LocalSharedLibs:      []string{"shared_dep"},
3195			},
3196		},
3197		{
3198			name:       "cc_library_headers",
3199			moduleName: "lib_headers",
3200			variant:    "android_arm64_armv8-a",
3201			androidMkInfo: cquery.CcAndroidMkInfo{
3202				LocalStaticLibs:      []string{"static_dep"},
3203				LocalWholeStaticLibs: []string{"whole_static_dep"},
3204				LocalSharedLibs:      []string{"shared_dep"},
3205			},
3206		},
3207		{
3208			name:       "prebuilt lib static",
3209			moduleName: "lib_prebuilt",
3210			variant:    "android_arm64_armv8-a_static",
3211			androidMkInfo: cquery.CcAndroidMkInfo{
3212				LocalStaticLibs:      []string{"static_dep"},
3213				LocalWholeStaticLibs: []string{"whole_static_dep"},
3214				LocalSharedLibs:      []string{"shared_dep"},
3215			},
3216		},
3217		{
3218			name:       "prebuilt lib shared",
3219			moduleName: "lib_prebuilt",
3220			variant:    "android_arm64_armv8-a_shared",
3221			androidMkInfo: cquery.CcAndroidMkInfo{
3222				LocalStaticLibs:      []string{"static_dep"},
3223				LocalWholeStaticLibs: []string{"whole_static_dep"},
3224				LocalSharedLibs:      []string{"shared_dep"},
3225			},
3226		},
3227	}
3228
3229	outputBaseDir := "out/bazel"
3230	for _, tc := range testCases {
3231		t.Run(tc.name, func(t *testing.T) {
3232			result := android.GroupFixturePreparers(
3233				prepareForCcTest,
3234				android.FixtureModifyConfig(func(config android.Config) {
3235					config.BazelContext = android.MockBazelContext{
3236						OutputBaseDir: outputBaseDir,
3237						LabelToCcInfo: map[string]cquery.CcInfo{
3238							"//:lib": cquery.CcInfo{
3239								CcAndroidMkInfo:      tc.androidMkInfo,
3240								RootDynamicLibraries: []string{""},
3241							},
3242							"//:lib_bp2build_cc_library_static": cquery.CcInfo{
3243								CcAndroidMkInfo:    tc.androidMkInfo,
3244								RootStaticArchives: []string{""},
3245							},
3246							"//:lib_headers": cquery.CcInfo{
3247								CcAndroidMkInfo: tc.androidMkInfo,
3248								OutputFiles:     []string{""},
3249							},
3250							"//:lib_prebuilt": cquery.CcInfo{
3251								CcAndroidMkInfo: tc.androidMkInfo,
3252							},
3253							"//:lib_prebuilt_bp2build_cc_library_static": cquery.CcInfo{
3254								CcAndroidMkInfo: tc.androidMkInfo,
3255							},
3256						},
3257						LabelToCcBinary: map[string]cquery.CcUnstrippedInfo{
3258							"//:test": cquery.CcUnstrippedInfo{
3259								CcAndroidMkInfo: tc.androidMkInfo,
3260							},
3261							"//:binary": cquery.CcUnstrippedInfo{
3262								CcAndroidMkInfo: tc.androidMkInfo,
3263							},
3264						},
3265					}
3266				}),
3267			).RunTestWithBp(t, bp)
3268			ctx := result.TestContext
3269
3270			module := ctx.ModuleForTests(tc.moduleName, tc.variant).Module().(*Module)
3271			entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
3272			if !reflect.DeepEqual(module.Properties.AndroidMkStaticLibs, tc.androidMkInfo.LocalStaticLibs) {
3273				t.Errorf("incorrect static_libs"+
3274					"\nactual:   %v"+
3275					"\nexpected: %v",
3276					module.Properties.AndroidMkStaticLibs,
3277					tc.androidMkInfo.LocalStaticLibs,
3278				)
3279			}
3280			staticDepsDiffer, missingStaticDeps, additionalStaticDeps := android.ListSetDifference(
3281				entries.EntryMap["LOCAL_STATIC_LIBRARIES"],
3282				tc.androidMkInfo.LocalStaticLibs,
3283			)
3284			if staticDepsDiffer {
3285				t.Errorf(
3286					"expected LOCAL_STATIC_LIBRARIES to be %q but was %q; missing: %q; extra %q",
3287					tc.androidMkInfo.LocalStaticLibs,
3288					entries.EntryMap["LOCAL_STATIC_LIBRARIES"],
3289					missingStaticDeps,
3290					additionalStaticDeps,
3291				)
3292			}
3293
3294			if !reflect.DeepEqual(module.Properties.AndroidMkWholeStaticLibs, tc.androidMkInfo.LocalWholeStaticLibs) {
3295				t.Errorf("expected module.Properties.AndroidMkWholeStaticLibs to be %q, but was %q",
3296					tc.androidMkInfo.LocalWholeStaticLibs,
3297					module.Properties.AndroidMkWholeStaticLibs,
3298				)
3299			}
3300			wholeStaticDepsDiffer, missingWholeStaticDeps, additionalWholeStaticDeps := android.ListSetDifference(
3301				entries.EntryMap["LOCAL_WHOLE_STATIC_LIBRARIES"],
3302				tc.androidMkInfo.LocalWholeStaticLibs,
3303			)
3304			if wholeStaticDepsDiffer {
3305				t.Errorf(
3306					"expected LOCAL_WHOLE_STATIC_LIBRARIES to be %q but was %q; missing: %q; extra %q",
3307					tc.androidMkInfo.LocalWholeStaticLibs,
3308					entries.EntryMap["LOCAL_WHOLE_STATIC_LIBRARIES"],
3309					missingWholeStaticDeps,
3310					additionalWholeStaticDeps,
3311				)
3312			}
3313
3314			if !reflect.DeepEqual(module.Properties.AndroidMkSharedLibs, tc.androidMkInfo.LocalSharedLibs) {
3315				t.Errorf("incorrect shared_libs"+
3316					"\nactual:   %v"+
3317					"\nexpected: %v",
3318					module.Properties.AndroidMkSharedLibs,
3319					tc.androidMkInfo.LocalSharedLibs,
3320				)
3321			}
3322			sharedDepsDiffer, missingSharedDeps, additionalSharedDeps := android.ListSetDifference(
3323				entries.EntryMap["LOCAL_SHARED_LIBRARIES"],
3324				tc.androidMkInfo.LocalSharedLibs,
3325			)
3326			if sharedDepsDiffer {
3327				t.Errorf(
3328					"expected LOCAL_SHARED_LIBRARIES to be %q but was %q; missing %q; extra %q",
3329					tc.androidMkInfo.LocalSharedLibs,
3330					entries.EntryMap["LOCAL_SHARED_LIBRARIES"],
3331					missingSharedDeps,
3332					additionalSharedDeps,
3333				)
3334			}
3335		})
3336	}
3337}
3338
3339var compilerFlagsTestCases = []struct {
3340	in  string
3341	out bool
3342}{
3343	{
3344		in:  "a",
3345		out: false,
3346	},
3347	{
3348		in:  "-a",
3349		out: true,
3350	},
3351	{
3352		in:  "-Ipath/to/something",
3353		out: false,
3354	},
3355	{
3356		in:  "-isystempath/to/something",
3357		out: false,
3358	},
3359	{
3360		in:  "--coverage",
3361		out: false,
3362	},
3363	{
3364		in:  "-include a/b",
3365		out: true,
3366	},
3367	{
3368		in:  "-include a/b c/d",
3369		out: false,
3370	},
3371	{
3372		in:  "-DMACRO",
3373		out: true,
3374	},
3375	{
3376		in:  "-DMAC RO",
3377		out: false,
3378	},
3379	{
3380		in:  "-a -b",
3381		out: false,
3382	},
3383	{
3384		in:  "-DMACRO=definition",
3385		out: true,
3386	},
3387	{
3388		in:  "-DMACRO=defi nition",
3389		out: true, // TODO(jiyong): this should be false
3390	},
3391	{
3392		in:  "-DMACRO(x)=x + 1",
3393		out: true,
3394	},
3395	{
3396		in:  "-DMACRO=\"defi nition\"",
3397		out: true,
3398	},
3399}
3400
3401type mockContext struct {
3402	BaseModuleContext
3403	result bool
3404}
3405
3406func (ctx *mockContext) PropertyErrorf(property, format string, args ...interface{}) {
3407	// CheckBadCompilerFlags calls this function when the flag should be rejected
3408	ctx.result = false
3409}
3410
3411func TestCompilerFlags(t *testing.T) {
3412	t.Parallel()
3413	for _, testCase := range compilerFlagsTestCases {
3414		ctx := &mockContext{result: true}
3415		CheckBadCompilerFlags(ctx, "", []string{testCase.in})
3416		if ctx.result != testCase.out {
3417			t.Errorf("incorrect output:")
3418			t.Errorf("     input: %#v", testCase.in)
3419			t.Errorf("  expected: %#v", testCase.out)
3420			t.Errorf("       got: %#v", ctx.result)
3421		}
3422	}
3423}
3424
3425func TestRecovery(t *testing.T) {
3426	t.Parallel()
3427	ctx := testCc(t, `
3428		cc_library_shared {
3429			name: "librecovery",
3430			recovery: true,
3431		}
3432		cc_library_shared {
3433			name: "librecovery32",
3434			recovery: true,
3435			compile_multilib:"32",
3436		}
3437		cc_library_shared {
3438			name: "libHalInRecovery",
3439			recovery_available: true,
3440			vendor: true,
3441		}
3442	`)
3443
3444	variants := ctx.ModuleVariantsForTests("librecovery")
3445	const arm64 = "android_recovery_arm64_armv8-a_shared"
3446	if len(variants) != 1 || !android.InList(arm64, variants) {
3447		t.Errorf("variants of librecovery must be \"%s\" only, but was %#v", arm64, variants)
3448	}
3449
3450	variants = ctx.ModuleVariantsForTests("librecovery32")
3451	if android.InList(arm64, variants) {
3452		t.Errorf("multilib was set to 32 for librecovery32, but its variants has %s.", arm64)
3453	}
3454
3455	recoveryModule := ctx.ModuleForTests("libHalInRecovery", recoveryVariant).Module().(*Module)
3456	if !recoveryModule.Platform() {
3457		t.Errorf("recovery variant of libHalInRecovery must not specific to device, soc, or product")
3458	}
3459}
3460
3461func TestDataLibsPrebuiltSharedTestLibrary(t *testing.T) {
3462	t.Parallel()
3463	bp := `
3464		cc_prebuilt_test_library_shared {
3465			name: "test_lib",
3466			relative_install_path: "foo/bar/baz",
3467			srcs: ["srcpath/dontusethispath/baz.so"],
3468		}
3469
3470		cc_test {
3471			name: "main_test",
3472			data_libs: ["test_lib"],
3473			gtest: false,
3474		}
3475 `
3476
3477	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
3478	config.TestProductVariables.DeviceVndkVersion = StringPtr("current")
3479	config.TestProductVariables.Platform_vndk_version = StringPtr("29")
3480	config.TestProductVariables.VndkUseCoreVariant = BoolPtr(true)
3481
3482	ctx := testCcWithConfig(t, config)
3483	module := ctx.ModuleForTests("main_test", "android_arm_armv7-a-neon").Module()
3484	testBinary := module.(*Module).linker.(*testBinary)
3485	outputFiles, err := module.(android.OutputFileProducer).OutputFiles("")
3486	if err != nil {
3487		t.Fatalf("Expected cc_test to produce output files, error: %s", err)
3488	}
3489	if len(outputFiles) != 1 {
3490		t.Errorf("expected exactly one output file. output files: [%s]", outputFiles)
3491	}
3492	if len(testBinary.dataPaths()) != 1 {
3493		t.Errorf("expected exactly one test data file. test data files: [%s]", testBinary.dataPaths())
3494	}
3495
3496	outputPath := outputFiles[0].String()
3497
3498	if !strings.HasSuffix(outputPath, "/main_test") {
3499		t.Errorf("expected test output file to be 'main_test', but was '%s'", outputPath)
3500	}
3501	entries := android.AndroidMkEntriesForTest(t, ctx, module)[0]
3502	if !strings.HasSuffix(entries.EntryMap["LOCAL_TEST_DATA"][0], ":test_lib.so:foo/bar/baz") {
3503		t.Errorf("expected LOCAL_TEST_DATA to end with `:test_lib.so:foo/bar/baz`,"+
3504			" but was '%s'", entries.EntryMap["LOCAL_TEST_DATA"][0])
3505	}
3506}
3507
3508func TestVersionedStubs(t *testing.T) {
3509	t.Parallel()
3510	ctx := testCc(t, `
3511		cc_library_shared {
3512			name: "libFoo",
3513			srcs: ["foo.c"],
3514			stubs: {
3515				symbol_file: "foo.map.txt",
3516				versions: ["1", "2", "3"],
3517			},
3518		}
3519
3520		cc_library_shared {
3521			name: "libBar",
3522			srcs: ["bar.c"],
3523			shared_libs: ["libFoo#1"],
3524		}`)
3525
3526	variants := ctx.ModuleVariantsForTests("libFoo")
3527	expectedVariants := []string{
3528		"android_arm64_armv8-a_shared",
3529		"android_arm64_armv8-a_shared_1",
3530		"android_arm64_armv8-a_shared_2",
3531		"android_arm64_armv8-a_shared_3",
3532		"android_arm64_armv8-a_shared_current",
3533		"android_arm_armv7-a-neon_shared",
3534		"android_arm_armv7-a-neon_shared_1",
3535		"android_arm_armv7-a-neon_shared_2",
3536		"android_arm_armv7-a-neon_shared_3",
3537		"android_arm_armv7-a-neon_shared_current",
3538	}
3539	variantsMismatch := false
3540	if len(variants) != len(expectedVariants) {
3541		variantsMismatch = true
3542	} else {
3543		for _, v := range expectedVariants {
3544			if !inList(v, variants) {
3545				variantsMismatch = false
3546			}
3547		}
3548	}
3549	if variantsMismatch {
3550		t.Errorf("variants of libFoo expected:\n")
3551		for _, v := range expectedVariants {
3552			t.Errorf("%q\n", v)
3553		}
3554		t.Errorf(", but got:\n")
3555		for _, v := range variants {
3556			t.Errorf("%q\n", v)
3557		}
3558	}
3559
3560	libBarLinkRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("ld")
3561	libFlags := libBarLinkRule.Args["libFlags"]
3562	libFoo1StubPath := "libFoo/android_arm64_armv8-a_shared_1/libFoo.so"
3563	if !strings.Contains(libFlags, libFoo1StubPath) {
3564		t.Errorf("%q is not found in %q", libFoo1StubPath, libFlags)
3565	}
3566
3567	libBarCompileRule := ctx.ModuleForTests("libBar", "android_arm64_armv8-a_shared").Rule("cc")
3568	cFlags := libBarCompileRule.Args["cFlags"]
3569	libFoo1VersioningMacro := "-D__LIBFOO_API__=1"
3570	if !strings.Contains(cFlags, libFoo1VersioningMacro) {
3571		t.Errorf("%q is not found in %q", libFoo1VersioningMacro, cFlags)
3572	}
3573}
3574
3575func TestStubsForLibraryInMultipleApexes(t *testing.T) {
3576	// TODO(b/275313114): Test exposes non-determinism which should be corrected and the test
3577	// reenabled.
3578	t.Skip()
3579	t.Parallel()
3580	ctx := testCc(t, `
3581		cc_library_shared {
3582			name: "libFoo",
3583			srcs: ["foo.c"],
3584			stubs: {
3585				symbol_file: "foo.map.txt",
3586				versions: ["current"],
3587			},
3588			apex_available: ["bar", "a1"],
3589		}
3590
3591		cc_library_shared {
3592			name: "libBar",
3593			srcs: ["bar.c"],
3594			shared_libs: ["libFoo"],
3595			apex_available: ["a1"],
3596		}
3597
3598		cc_library_shared {
3599			name: "libA1",
3600			srcs: ["a1.c"],
3601			shared_libs: ["libFoo"],
3602			apex_available: ["a1"],
3603		}
3604
3605		cc_library_shared {
3606			name: "libBarA1",
3607			srcs: ["bara1.c"],
3608			shared_libs: ["libFoo"],
3609			apex_available: ["bar", "a1"],
3610		}
3611
3612		cc_library_shared {
3613			name: "libAnyApex",
3614			srcs: ["anyApex.c"],
3615			shared_libs: ["libFoo"],
3616			apex_available: ["//apex_available:anyapex"],
3617		}
3618
3619		cc_library_shared {
3620			name: "libBaz",
3621			srcs: ["baz.c"],
3622			shared_libs: ["libFoo"],
3623			apex_available: ["baz"],
3624		}
3625
3626		cc_library_shared {
3627			name: "libQux",
3628			srcs: ["qux.c"],
3629			shared_libs: ["libFoo"],
3630			apex_available: ["qux", "bar"],
3631		}`)
3632
3633	variants := ctx.ModuleVariantsForTests("libFoo")
3634	expectedVariants := []string{
3635		"android_arm64_armv8-a_shared",
3636		"android_arm64_armv8-a_shared_current",
3637		"android_arm_armv7-a-neon_shared",
3638		"android_arm_armv7-a-neon_shared_current",
3639	}
3640	variantsMismatch := false
3641	if len(variants) != len(expectedVariants) {
3642		variantsMismatch = true
3643	} else {
3644		for _, v := range expectedVariants {
3645			if !inList(v, variants) {
3646				variantsMismatch = false
3647			}
3648		}
3649	}
3650	if variantsMismatch {
3651		t.Errorf("variants of libFoo expected:\n")
3652		for _, v := range expectedVariants {
3653			t.Errorf("%q\n", v)
3654		}
3655		t.Errorf(", but got:\n")
3656		for _, v := range variants {
3657			t.Errorf("%q\n", v)
3658		}
3659	}
3660
3661	linkAgainstFoo := []string{"libBarA1"}
3662	linkAgainstFooStubs := []string{"libBar", "libA1", "libBaz", "libQux", "libAnyApex"}
3663
3664	libFooPath := "libFoo/android_arm64_armv8-a_shared/libFoo.so"
3665	for _, lib := range linkAgainstFoo {
3666		libLinkRule := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld")
3667		libFlags := libLinkRule.Args["libFlags"]
3668		if !strings.Contains(libFlags, libFooPath) {
3669			t.Errorf("%q: %q is not found in %q", lib, libFooPath, libFlags)
3670		}
3671	}
3672
3673	libFooStubPath := "libFoo/android_arm64_armv8-a_shared_current/libFoo.so"
3674	for _, lib := range linkAgainstFooStubs {
3675		libLinkRule := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld")
3676		libFlags := libLinkRule.Args["libFlags"]
3677		if !strings.Contains(libFlags, libFooStubPath) {
3678			t.Errorf("%q: %q is not found in %q", lib, libFooStubPath, libFlags)
3679		}
3680	}
3681}
3682
3683func TestMixedBuildUsesStubs(t *testing.T) {
3684	// TODO(b/275313114): Test exposes non-determinism which should be corrected and the test
3685	// reenabled.
3686	t.Skip()
3687	t.Parallel()
3688	bp := `
3689		cc_library_shared {
3690			name: "libFoo",
3691			bazel_module: { label: "//:libFoo" },
3692			srcs: ["foo.c"],
3693			stubs: {
3694				symbol_file: "foo.map.txt",
3695				versions: ["current"],
3696			},
3697			apex_available: ["bar", "a1"],
3698		}
3699
3700		cc_library_shared {
3701			name: "libBar",
3702			srcs: ["bar.c"],
3703			shared_libs: ["libFoo"],
3704			apex_available: ["a1"],
3705		}
3706
3707		cc_library_shared {
3708			name: "libA1",
3709			srcs: ["a1.c"],
3710			shared_libs: ["libFoo"],
3711			apex_available: ["a1"],
3712		}
3713
3714		cc_library_shared {
3715			name: "libBarA1",
3716			srcs: ["bara1.c"],
3717			shared_libs: ["libFoo"],
3718			apex_available: ["bar", "a1"],
3719		}
3720
3721		cc_library_shared {
3722			name: "libAnyApex",
3723			srcs: ["anyApex.c"],
3724			shared_libs: ["libFoo"],
3725			apex_available: ["//apex_available:anyapex"],
3726		}
3727
3728		cc_library_shared {
3729			name: "libBaz",
3730			srcs: ["baz.c"],
3731			shared_libs: ["libFoo"],
3732			apex_available: ["baz"],
3733		}
3734
3735		cc_library_shared {
3736			name: "libQux",
3737			srcs: ["qux.c"],
3738			shared_libs: ["libFoo"],
3739			apex_available: ["qux", "bar"],
3740		}`
3741
3742	result := android.GroupFixturePreparers(
3743		prepareForCcTest,
3744		android.FixtureModifyConfig(func(config android.Config) {
3745			config.BazelContext = android.MockBazelContext{
3746				OutputBaseDir: "out/bazel",
3747				LabelToCcInfo: map[string]cquery.CcInfo{
3748					"//:libFoo": {
3749						RootDynamicLibraries: []string{"libFoo.so"},
3750					},
3751					"//:libFoo_stub_libs-current": {
3752						RootDynamicLibraries: []string{"libFoo_stub_libs-current.so"},
3753					},
3754				},
3755			}
3756		}),
3757	).RunTestWithBp(t, bp)
3758	ctx := result.TestContext
3759
3760	variants := ctx.ModuleVariantsForTests("libFoo")
3761	expectedVariants := []string{
3762		"android_arm64_armv8-a_shared",
3763		"android_arm64_armv8-a_shared_current",
3764		"android_arm_armv7-a-neon_shared",
3765		"android_arm_armv7-a-neon_shared_current",
3766	}
3767	variantsMismatch := false
3768	if len(variants) != len(expectedVariants) {
3769		variantsMismatch = true
3770	} else {
3771		for _, v := range expectedVariants {
3772			if !inList(v, variants) {
3773				variantsMismatch = false
3774			}
3775		}
3776	}
3777	if variantsMismatch {
3778		t.Errorf("variants of libFoo expected:\n")
3779		for _, v := range expectedVariants {
3780			t.Errorf("%q\n", v)
3781		}
3782		t.Errorf(", but got:\n")
3783		for _, v := range variants {
3784			t.Errorf("%q\n", v)
3785		}
3786	}
3787
3788	linkAgainstFoo := []string{"libBarA1"}
3789	linkAgainstFooStubs := []string{"libBar", "libA1", "libBaz", "libQux", "libAnyApex"}
3790
3791	libFooPath := "out/bazel/execroot/__main__/libFoo.so"
3792	for _, lib := range linkAgainstFoo {
3793		libLinkRule := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld")
3794		libFlags := libLinkRule.Args["libFlags"]
3795		if !strings.Contains(libFlags, libFooPath) {
3796			t.Errorf("%q: %q is not found in %q", lib, libFooPath, libFlags)
3797		}
3798	}
3799
3800	libFooStubPath := "out/bazel/execroot/__main__/libFoo_stub_libs-current.so"
3801	for _, lib := range linkAgainstFooStubs {
3802		libLinkRule := ctx.ModuleForTests(lib, "android_arm64_armv8-a_shared").Rule("ld")
3803		libFlags := libLinkRule.Args["libFlags"]
3804		if !strings.Contains(libFlags, libFooStubPath) {
3805			t.Errorf("%q: %q is not found in %q", lib, libFooStubPath, libFlags)
3806		}
3807	}
3808}
3809
3810func TestVersioningMacro(t *testing.T) {
3811	t.Parallel()
3812	for _, tc := range []struct{ moduleName, expected string }{
3813		{"libc", "__LIBC_API__"},
3814		{"libfoo", "__LIBFOO_API__"},
3815		{"libfoo@1", "__LIBFOO_1_API__"},
3816		{"libfoo-v1", "__LIBFOO_V1_API__"},
3817		{"libfoo.v1", "__LIBFOO_V1_API__"},
3818	} {
3819		checkEquals(t, tc.moduleName, tc.expected, versioningMacroName(tc.moduleName))
3820	}
3821}
3822
3823func pathsToBase(paths android.Paths) []string {
3824	var ret []string
3825	for _, p := range paths {
3826		ret = append(ret, p.Base())
3827	}
3828	return ret
3829}
3830
3831func TestStaticLibArchiveArgs(t *testing.T) {
3832	t.Parallel()
3833	ctx := testCc(t, `
3834		cc_library_static {
3835			name: "foo",
3836			srcs: ["foo.c"],
3837		}
3838
3839		cc_library_static {
3840			name: "bar",
3841			srcs: ["bar.c"],
3842		}
3843
3844		cc_library_shared {
3845			name: "qux",
3846			srcs: ["qux.c"],
3847		}
3848
3849		cc_library_static {
3850			name: "baz",
3851			srcs: ["baz.c"],
3852			static_libs: ["foo"],
3853			shared_libs: ["qux"],
3854			whole_static_libs: ["bar"],
3855		}`)
3856
3857	variant := "android_arm64_armv8-a_static"
3858	arRule := ctx.ModuleForTests("baz", variant).Rule("ar")
3859
3860	// For static libraries, the object files of a whole static dep are included in the archive
3861	// directly
3862	if g, w := pathsToBase(arRule.Inputs), []string{"bar.o", "baz.o"}; !reflect.DeepEqual(w, g) {
3863		t.Errorf("Expected input objects %q, got %q", w, g)
3864	}
3865
3866	// non whole static dependencies are not linked into the archive
3867	if len(arRule.Implicits) > 0 {
3868		t.Errorf("Expected 0 additional deps, got %q", arRule.Implicits)
3869	}
3870}
3871
3872func TestSharedLibLinkingArgs(t *testing.T) {
3873	t.Parallel()
3874	ctx := testCc(t, `
3875		cc_library_static {
3876			name: "foo",
3877			srcs: ["foo.c"],
3878		}
3879
3880		cc_library_static {
3881			name: "bar",
3882			srcs: ["bar.c"],
3883		}
3884
3885		cc_library_shared {
3886			name: "qux",
3887			srcs: ["qux.c"],
3888		}
3889
3890		cc_library_shared {
3891			name: "baz",
3892			srcs: ["baz.c"],
3893			static_libs: ["foo"],
3894			shared_libs: ["qux"],
3895			whole_static_libs: ["bar"],
3896		}`)
3897
3898	variant := "android_arm64_armv8-a_shared"
3899	linkRule := ctx.ModuleForTests("baz", variant).Rule("ld")
3900	libFlags := linkRule.Args["libFlags"]
3901	// When dynamically linking, we expect static dependencies to be found on the command line
3902	if expected := "foo.a"; !strings.Contains(libFlags, expected) {
3903		t.Errorf("Static lib %q was not found in %q", expected, libFlags)
3904	}
3905	// When dynamically linking, we expect whole static dependencies to be found on the command line
3906	if expected := "bar.a"; !strings.Contains(libFlags, expected) {
3907		t.Errorf("Static lib %q was not found in %q", expected, libFlags)
3908	}
3909
3910	// When dynamically linking, we expect shared dependencies to be found on the command line
3911	if expected := "qux.so"; !strings.Contains(libFlags, expected) {
3912		t.Errorf("Shared lib %q was not found in %q", expected, libFlags)
3913	}
3914
3915	// We should only have the objects from the shared library srcs, not the whole static dependencies
3916	if g, w := pathsToBase(linkRule.Inputs), []string{"baz.o"}; !reflect.DeepEqual(w, g) {
3917		t.Errorf("Expected input objects %q, got %q", w, g)
3918	}
3919}
3920
3921func TestStaticExecutable(t *testing.T) {
3922	t.Parallel()
3923	ctx := testCc(t, `
3924		cc_binary {
3925			name: "static_test",
3926			srcs: ["foo.c", "baz.o"],
3927			static_executable: true,
3928		}`)
3929
3930	variant := "android_arm64_armv8-a"
3931	binModuleRule := ctx.ModuleForTests("static_test", variant).Rule("ld")
3932	libFlags := binModuleRule.Args["libFlags"]
3933	systemStaticLibs := []string{"libc.a", "libm.a"}
3934	for _, lib := range systemStaticLibs {
3935		if !strings.Contains(libFlags, lib) {
3936			t.Errorf("Static lib %q was not found in %q", lib, libFlags)
3937		}
3938	}
3939	systemSharedLibs := []string{"libc.so", "libm.so", "libdl.so"}
3940	for _, lib := range systemSharedLibs {
3941		if strings.Contains(libFlags, lib) {
3942			t.Errorf("Shared lib %q was found in %q", lib, libFlags)
3943		}
3944	}
3945}
3946
3947func TestStaticDepsOrderWithStubs(t *testing.T) {
3948	t.Parallel()
3949	ctx := testCc(t, `
3950		cc_binary {
3951			name: "mybin",
3952			srcs: ["foo.c"],
3953			static_libs: ["libfooC", "libfooB"],
3954			static_executable: true,
3955			stl: "none",
3956		}
3957
3958		cc_library {
3959			name: "libfooB",
3960			srcs: ["foo.c"],
3961			shared_libs: ["libfooC"],
3962			stl: "none",
3963		}
3964
3965		cc_library {
3966			name: "libfooC",
3967			srcs: ["foo.c"],
3968			stl: "none",
3969			stubs: {
3970				versions: ["1"],
3971			},
3972		}`)
3973
3974	mybin := ctx.ModuleForTests("mybin", "android_arm64_armv8-a").Rule("ld")
3975	actual := mybin.Implicits[:2]
3976	expected := GetOutputPaths(ctx, "android_arm64_armv8-a_static", []string{"libfooB", "libfooC"})
3977
3978	if !reflect.DeepEqual(actual, expected) {
3979		t.Errorf("staticDeps orderings were not propagated correctly"+
3980			"\nactual:   %v"+
3981			"\nexpected: %v",
3982			actual,
3983			expected,
3984		)
3985	}
3986}
3987
3988func TestErrorsIfAModuleDependsOnDisabled(t *testing.T) {
3989	t.Parallel()
3990	testCcError(t, `module "libA" .* depends on disabled module "libB"`, `
3991		cc_library {
3992			name: "libA",
3993			srcs: ["foo.c"],
3994			shared_libs: ["libB"],
3995			stl: "none",
3996		}
3997
3998		cc_library {
3999			name: "libB",
4000			srcs: ["foo.c"],
4001			enabled: false,
4002			stl: "none",
4003		}
4004	`)
4005}
4006
4007func VerifyAFLFuzzTargetVariant(t *testing.T, variant string) {
4008	bp := `
4009		cc_fuzz {
4010			name: "test_afl_fuzz_target",
4011			srcs: ["foo.c"],
4012			host_supported: true,
4013			static_libs: [
4014				"afl_fuzz_static_lib",
4015			],
4016			shared_libs: [
4017				"afl_fuzz_shared_lib",
4018			],
4019			fuzzing_frameworks: {
4020				afl: true,
4021				libfuzzer: false,
4022			},
4023		}
4024		cc_library {
4025			name: "afl_fuzz_static_lib",
4026			host_supported: true,
4027			srcs: ["static_file.c"],
4028		}
4029		cc_library {
4030			name: "libfuzzer_only_static_lib",
4031			host_supported: true,
4032			srcs: ["static_file.c"],
4033		}
4034		cc_library {
4035			name: "afl_fuzz_shared_lib",
4036			host_supported: true,
4037			srcs: ["shared_file.c"],
4038			static_libs: [
4039				"second_static_lib",
4040			],
4041		}
4042		cc_library_headers {
4043			name: "libafl_headers",
4044			vendor_available: true,
4045			host_supported: true,
4046			export_include_dirs: [
4047				"include",
4048				"instrumentation",
4049			],
4050		}
4051		cc_object {
4052			name: "afl-compiler-rt",
4053			vendor_available: true,
4054			host_supported: true,
4055			cflags: [
4056				"-fPIC",
4057			],
4058			srcs: [
4059				"instrumentation/afl-compiler-rt.o.c",
4060			],
4061		}
4062		cc_library {
4063			name: "second_static_lib",
4064			host_supported: true,
4065			srcs: ["second_file.c"],
4066		}
4067		cc_object {
4068			name: "aflpp_driver",
4069			host_supported: true,
4070			srcs: [
4071				"aflpp_driver.c",
4072			],
4073		}`
4074
4075	testEnv := map[string]string{
4076		"FUZZ_FRAMEWORK": "AFL",
4077	}
4078
4079	ctx := android.GroupFixturePreparers(prepareForCcTest, android.FixtureMergeEnv(testEnv)).RunTestWithBp(t, bp)
4080
4081	checkPcGuardFlag := func(
4082		modName string, variantName string, shouldHave bool) {
4083		cc := ctx.ModuleForTests(modName, variantName).Rule("cc")
4084
4085		cFlags, ok := cc.Args["cFlags"]
4086		if !ok {
4087			t.Errorf("Could not find cFlags for module %s and variant %s",
4088				modName, variantName)
4089		}
4090
4091		if strings.Contains(
4092			cFlags, "-fsanitize-coverage=trace-pc-guard") != shouldHave {
4093			t.Errorf("Flag was found: %t. Expected to find flag:  %t. "+
4094				"Test failed for module %s and variant %s",
4095				!shouldHave, shouldHave, modName, variantName)
4096		}
4097	}
4098
4099	moduleName := "test_afl_fuzz_target"
4100	checkPcGuardFlag(moduleName, variant+"_fuzzer", true)
4101
4102	moduleName = "afl_fuzz_static_lib"
4103	checkPcGuardFlag(moduleName, variant+"_static", false)
4104	checkPcGuardFlag(moduleName, variant+"_static_fuzzer", true)
4105
4106	moduleName = "second_static_lib"
4107	checkPcGuardFlag(moduleName, variant+"_static", false)
4108	checkPcGuardFlag(moduleName, variant+"_static_fuzzer", true)
4109
4110	ctx.ModuleForTests("afl_fuzz_shared_lib",
4111		"android_arm64_armv8-a_shared").Rule("cc")
4112	ctx.ModuleForTests("afl_fuzz_shared_lib",
4113		"android_arm64_armv8-a_shared_fuzzer").Rule("cc")
4114}
4115
4116func TestAFLFuzzTargetForDevice(t *testing.T) {
4117	t.Parallel()
4118	VerifyAFLFuzzTargetVariant(t, "android_arm64_armv8-a")
4119}
4120
4121func TestAFLFuzzTargetForLinuxHost(t *testing.T) {
4122	t.Parallel()
4123	if runtime.GOOS != "linux" {
4124		t.Skip("requires linux")
4125	}
4126
4127	VerifyAFLFuzzTargetVariant(t, "linux_glibc_x86_64")
4128}
4129
4130// Simple smoke test for the cc_fuzz target that ensures the rule compiles
4131// correctly.
4132func TestFuzzTarget(t *testing.T) {
4133	t.Parallel()
4134	ctx := testCc(t, `
4135		cc_fuzz {
4136			name: "fuzz_smoke_test",
4137			srcs: ["foo.c"],
4138		}`)
4139
4140	variant := "android_arm64_armv8-a_fuzzer"
4141	ctx.ModuleForTests("fuzz_smoke_test", variant).Rule("cc")
4142}
4143
4144func assertString(t *testing.T, got, expected string) {
4145	t.Helper()
4146	if got != expected {
4147		t.Errorf("expected %q got %q", expected, got)
4148	}
4149}
4150
4151func assertArrayString(t *testing.T, got, expected []string) {
4152	t.Helper()
4153	if len(got) != len(expected) {
4154		t.Errorf("expected %d (%q) got (%d) %q", len(expected), expected, len(got), got)
4155		return
4156	}
4157	for i := range got {
4158		if got[i] != expected[i] {
4159			t.Errorf("expected %d-th %q (%q) got %q (%q)",
4160				i, expected[i], expected, got[i], got)
4161			return
4162		}
4163	}
4164}
4165
4166func assertMapKeys(t *testing.T, m map[string]string, expected []string) {
4167	t.Helper()
4168	assertArrayString(t, android.SortedKeys(m), expected)
4169}
4170
4171func TestDefaults(t *testing.T) {
4172	t.Parallel()
4173	ctx := testCc(t, `
4174		cc_defaults {
4175			name: "defaults",
4176			srcs: ["foo.c"],
4177			static: {
4178				srcs: ["bar.c"],
4179			},
4180			shared: {
4181				srcs: ["baz.c"],
4182			},
4183			bazel_module: {
4184				bp2build_available: true,
4185			},
4186		}
4187
4188		cc_library_static {
4189			name: "libstatic",
4190			defaults: ["defaults"],
4191		}
4192
4193		cc_library_shared {
4194			name: "libshared",
4195			defaults: ["defaults"],
4196		}
4197
4198		cc_library {
4199			name: "libboth",
4200			defaults: ["defaults"],
4201		}
4202
4203		cc_binary {
4204			name: "binary",
4205			defaults: ["defaults"],
4206		}`)
4207
4208	shared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Rule("ld")
4209	if g, w := pathsToBase(shared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
4210		t.Errorf("libshared ld rule wanted %q, got %q", w, g)
4211	}
4212	bothShared := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_shared").Rule("ld")
4213	if g, w := pathsToBase(bothShared.Inputs), []string{"foo.o", "baz.o"}; !reflect.DeepEqual(w, g) {
4214		t.Errorf("libboth ld rule wanted %q, got %q", w, g)
4215	}
4216	binary := ctx.ModuleForTests("binary", "android_arm64_armv8-a").Rule("ld")
4217	if g, w := pathsToBase(binary.Inputs), []string{"foo.o"}; !reflect.DeepEqual(w, g) {
4218		t.Errorf("binary ld rule wanted %q, got %q", w, g)
4219	}
4220
4221	static := ctx.ModuleForTests("libstatic", "android_arm64_armv8-a_static").Rule("ar")
4222	if g, w := pathsToBase(static.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
4223		t.Errorf("libstatic ar rule wanted %q, got %q", w, g)
4224	}
4225	bothStatic := ctx.ModuleForTests("libboth", "android_arm64_armv8-a_static").Rule("ar")
4226	if g, w := pathsToBase(bothStatic.Inputs), []string{"foo.o", "bar.o"}; !reflect.DeepEqual(w, g) {
4227		t.Errorf("libboth ar rule wanted %q, got %q", w, g)
4228	}
4229}
4230
4231func TestProductVariableDefaults(t *testing.T) {
4232	t.Parallel()
4233	bp := `
4234		cc_defaults {
4235			name: "libfoo_defaults",
4236			srcs: ["foo.c"],
4237			cppflags: ["-DFOO"],
4238			product_variables: {
4239				debuggable: {
4240					cppflags: ["-DBAR"],
4241				},
4242			},
4243		}
4244
4245		cc_library {
4246			name: "libfoo",
4247			defaults: ["libfoo_defaults"],
4248		}
4249	`
4250
4251	result := android.GroupFixturePreparers(
4252		prepareForCcTest,
4253		android.PrepareForTestWithVariables,
4254
4255		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
4256			variables.Debuggable = BoolPtr(true)
4257		}),
4258	).RunTestWithBp(t, bp)
4259
4260	libfoo := result.Module("libfoo", "android_arm64_armv8-a_static").(*Module)
4261	android.AssertStringListContains(t, "cppflags", libfoo.flags.Local.CppFlags, "-DBAR")
4262}
4263
4264func TestEmptyWholeStaticLibsAllowMissingDependencies(t *testing.T) {
4265	t.Parallel()
4266	bp := `
4267		cc_library_static {
4268			name: "libfoo",
4269			srcs: ["foo.c"],
4270			whole_static_libs: ["libbar"],
4271		}
4272
4273		cc_library_static {
4274			name: "libbar",
4275			whole_static_libs: ["libmissing"],
4276		}
4277	`
4278
4279	result := android.GroupFixturePreparers(
4280		prepareForCcTest,
4281		android.PrepareForTestWithAllowMissingDependencies,
4282	).RunTestWithBp(t, bp)
4283
4284	libbar := result.ModuleForTests("libbar", "android_arm64_armv8-a_static").Output("libbar.a")
4285	android.AssertDeepEquals(t, "libbar rule", android.ErrorRule, libbar.Rule)
4286
4287	android.AssertStringDoesContain(t, "libbar error", libbar.Args["error"], "missing dependencies: libmissing")
4288
4289	libfoo := result.ModuleForTests("libfoo", "android_arm64_armv8-a_static").Output("libfoo.a")
4290	android.AssertStringListContains(t, "libfoo.a dependencies", libfoo.Inputs.Strings(), libbar.Output.String())
4291}
4292
4293func TestInstallSharedLibs(t *testing.T) {
4294	t.Parallel()
4295	bp := `
4296		cc_binary {
4297			name: "bin",
4298			host_supported: true,
4299			shared_libs: ["libshared"],
4300			runtime_libs: ["libruntime"],
4301			srcs: [":gen"],
4302		}
4303
4304		cc_library_shared {
4305			name: "libshared",
4306			host_supported: true,
4307			shared_libs: ["libtransitive"],
4308		}
4309
4310		cc_library_shared {
4311			name: "libtransitive",
4312			host_supported: true,
4313		}
4314
4315		cc_library_shared {
4316			name: "libruntime",
4317			host_supported: true,
4318		}
4319
4320		cc_binary_host {
4321			name: "tool",
4322			srcs: ["foo.cpp"],
4323		}
4324
4325		genrule {
4326			name: "gen",
4327			tools: ["tool"],
4328			out: ["gen.cpp"],
4329			cmd: "$(location tool) $(out)",
4330		}
4331	`
4332
4333	config := TestConfig(t.TempDir(), android.Android, nil, bp, nil)
4334	ctx := testCcWithConfig(t, config)
4335
4336	hostBin := ctx.ModuleForTests("bin", config.BuildOSTarget.String()).Description("install")
4337	hostShared := ctx.ModuleForTests("libshared", config.BuildOSTarget.String()+"_shared").Description("install")
4338	hostRuntime := ctx.ModuleForTests("libruntime", config.BuildOSTarget.String()+"_shared").Description("install")
4339	hostTransitive := ctx.ModuleForTests("libtransitive", config.BuildOSTarget.String()+"_shared").Description("install")
4340	hostTool := ctx.ModuleForTests("tool", config.BuildOSTarget.String()).Description("install")
4341
4342	if g, w := hostBin.Implicits.Strings(), hostShared.Output.String(); !android.InList(w, g) {
4343		t.Errorf("expected host bin dependency %q, got %q", w, g)
4344	}
4345
4346	if g, w := hostBin.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
4347		t.Errorf("expected host bin dependency %q, got %q", w, g)
4348	}
4349
4350	if g, w := hostShared.Implicits.Strings(), hostTransitive.Output.String(); !android.InList(w, g) {
4351		t.Errorf("expected host bin dependency %q, got %q", w, g)
4352	}
4353
4354	if g, w := hostBin.Implicits.Strings(), hostRuntime.Output.String(); !android.InList(w, g) {
4355		t.Errorf("expected host bin dependency %q, got %q", w, g)
4356	}
4357
4358	if g, w := hostBin.Implicits.Strings(), hostTool.Output.String(); android.InList(w, g) {
4359		t.Errorf("expected no host bin dependency %q, got %q", w, g)
4360	}
4361
4362	deviceBin := ctx.ModuleForTests("bin", "android_arm64_armv8-a").Description("install")
4363	deviceShared := ctx.ModuleForTests("libshared", "android_arm64_armv8-a_shared").Description("install")
4364	deviceTransitive := ctx.ModuleForTests("libtransitive", "android_arm64_armv8-a_shared").Description("install")
4365	deviceRuntime := ctx.ModuleForTests("libruntime", "android_arm64_armv8-a_shared").Description("install")
4366
4367	if g, w := deviceBin.OrderOnly.Strings(), deviceShared.Output.String(); !android.InList(w, g) {
4368		t.Errorf("expected device bin dependency %q, got %q", w, g)
4369	}
4370
4371	if g, w := deviceBin.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
4372		t.Errorf("expected device bin dependency %q, got %q", w, g)
4373	}
4374
4375	if g, w := deviceShared.OrderOnly.Strings(), deviceTransitive.Output.String(); !android.InList(w, g) {
4376		t.Errorf("expected device bin dependency %q, got %q", w, g)
4377	}
4378
4379	if g, w := deviceBin.OrderOnly.Strings(), deviceRuntime.Output.String(); !android.InList(w, g) {
4380		t.Errorf("expected device bin dependency %q, got %q", w, g)
4381	}
4382
4383	if g, w := deviceBin.OrderOnly.Strings(), hostTool.Output.String(); android.InList(w, g) {
4384		t.Errorf("expected no device bin dependency %q, got %q", w, g)
4385	}
4386
4387}
4388
4389func TestStubsLibReexportsHeaders(t *testing.T) {
4390	t.Parallel()
4391	ctx := testCc(t, `
4392		cc_library_shared {
4393			name: "libclient",
4394			srcs: ["foo.c"],
4395			shared_libs: ["libfoo#1"],
4396		}
4397
4398		cc_library_shared {
4399			name: "libfoo",
4400			srcs: ["foo.c"],
4401			shared_libs: ["libbar"],
4402			export_shared_lib_headers: ["libbar"],
4403			stubs: {
4404				symbol_file: "foo.map.txt",
4405				versions: ["1", "2", "3"],
4406			},
4407		}
4408
4409		cc_library_shared {
4410			name: "libbar",
4411			export_include_dirs: ["include/libbar"],
4412			srcs: ["foo.c"],
4413		}`)
4414
4415	cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
4416
4417	if !strings.Contains(cFlags, "-Iinclude/libbar") {
4418		t.Errorf("expected %q in cflags, got %q", "-Iinclude/libbar", cFlags)
4419	}
4420}
4421
4422func TestAidlFlagsPassedToTheAidlCompiler(t *testing.T) {
4423	t.Parallel()
4424	ctx := testCc(t, `
4425		cc_library {
4426			name: "libfoo",
4427			srcs: ["a/Foo.aidl"],
4428			aidl: { flags: ["-Werror"], },
4429		}
4430	`)
4431
4432	libfoo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_static")
4433	manifest := android.RuleBuilderSboxProtoForTests(t, libfoo.Output("aidl.sbox.textproto"))
4434	aidlCommand := manifest.Commands[0].GetCommand()
4435	expectedAidlFlag := "-Werror"
4436	if !strings.Contains(aidlCommand, expectedAidlFlag) {
4437		t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
4438	}
4439}
4440
4441func TestAidlFlagsWithMinSdkVersion(t *testing.T) {
4442	t.Parallel()
4443	for _, tc := range []struct {
4444		name       string
4445		sdkVersion string
4446		variant    string
4447		expected   string
4448	}{
4449		{
4450			name:       "default is current",
4451			sdkVersion: "",
4452			variant:    "android_arm64_armv8-a_static",
4453			expected:   "platform_apis",
4454		},
4455		{
4456			name:       "use sdk_version",
4457			sdkVersion: `sdk_version: "29"`,
4458			variant:    "android_arm64_armv8-a_static",
4459			expected:   "platform_apis",
4460		},
4461		{
4462			name:       "use sdk_version(sdk variant)",
4463			sdkVersion: `sdk_version: "29"`,
4464			variant:    "android_arm64_armv8-a_sdk_static",
4465			expected:   "29",
4466		},
4467		{
4468			name:       "use min_sdk_version",
4469			sdkVersion: `min_sdk_version: "29"`,
4470			variant:    "android_arm64_armv8-a_static",
4471			expected:   "29",
4472		},
4473	} {
4474		t.Run(tc.name, func(t *testing.T) {
4475			ctx := testCc(t, `
4476				cc_library {
4477					name: "libfoo",
4478					stl: "none",
4479					srcs: ["a/Foo.aidl"],
4480					`+tc.sdkVersion+`
4481				}
4482			`)
4483			libfoo := ctx.ModuleForTests("libfoo", tc.variant)
4484			manifest := android.RuleBuilderSboxProtoForTests(t, libfoo.Output("aidl.sbox.textproto"))
4485			aidlCommand := manifest.Commands[0].GetCommand()
4486			expectedAidlFlag := "--min_sdk_version=" + tc.expected
4487			if !strings.Contains(aidlCommand, expectedAidlFlag) {
4488				t.Errorf("aidl command %q does not contain %q", aidlCommand, expectedAidlFlag)
4489			}
4490		})
4491	}
4492}
4493
4494func TestMinSdkVersionInClangTriple(t *testing.T) {
4495	t.Parallel()
4496	ctx := testCc(t, `
4497		cc_library_shared {
4498			name: "libfoo",
4499			srcs: ["foo.c"],
4500			min_sdk_version: "29",
4501		}`)
4502
4503	cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
4504	android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android29")
4505}
4506
4507func TestNonDigitMinSdkVersionInClangTriple(t *testing.T) {
4508	t.Parallel()
4509	bp := `
4510		cc_library_shared {
4511			name: "libfoo",
4512			srcs: ["foo.c"],
4513			min_sdk_version: "S",
4514		}
4515	`
4516	result := android.GroupFixturePreparers(
4517		prepareForCcTest,
4518		android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
4519			variables.Platform_version_active_codenames = []string{"UpsideDownCake", "Tiramisu"}
4520		}),
4521	).RunTestWithBp(t, bp)
4522	ctx := result.TestContext
4523	cFlags := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
4524	android.AssertStringDoesContain(t, "min sdk version", cFlags, "-target aarch64-linux-android31")
4525}
4526
4527func TestIncludeDirsExporting(t *testing.T) {
4528	t.Parallel()
4529
4530	// Trim spaces from the beginning, end and immediately after any newline characters. Leaves
4531	// embedded newline characters alone.
4532	trimIndentingSpaces := func(s string) string {
4533		return strings.TrimSpace(regexp.MustCompile("(^|\n)\\s+").ReplaceAllString(s, "$1"))
4534	}
4535
4536	checkPaths := func(t *testing.T, message string, expected string, paths android.Paths) {
4537		t.Helper()
4538		expected = trimIndentingSpaces(expected)
4539		actual := trimIndentingSpaces(strings.Join(android.FirstUniqueStrings(android.NormalizePathsForTesting(paths)), "\n"))
4540		if expected != actual {
4541			t.Errorf("%s: expected:\n%s\n actual:\n%s\n", message, expected, actual)
4542		}
4543	}
4544
4545	type exportedChecker func(t *testing.T, name string, exported FlagExporterInfo)
4546
4547	checkIncludeDirs := func(t *testing.T, ctx *android.TestContext, module android.Module, checkers ...exportedChecker) {
4548		t.Helper()
4549		exported := ctx.ModuleProvider(module, FlagExporterInfoProvider).(FlagExporterInfo)
4550		name := module.Name()
4551
4552		for _, checker := range checkers {
4553			checker(t, name, exported)
4554		}
4555	}
4556
4557	expectedIncludeDirs := func(expectedPaths string) exportedChecker {
4558		return func(t *testing.T, name string, exported FlagExporterInfo) {
4559			t.Helper()
4560			checkPaths(t, fmt.Sprintf("%s: include dirs", name), expectedPaths, exported.IncludeDirs)
4561		}
4562	}
4563
4564	expectedSystemIncludeDirs := func(expectedPaths string) exportedChecker {
4565		return func(t *testing.T, name string, exported FlagExporterInfo) {
4566			t.Helper()
4567			checkPaths(t, fmt.Sprintf("%s: system include dirs", name), expectedPaths, exported.SystemIncludeDirs)
4568		}
4569	}
4570
4571	expectedGeneratedHeaders := func(expectedPaths string) exportedChecker {
4572		return func(t *testing.T, name string, exported FlagExporterInfo) {
4573			t.Helper()
4574			checkPaths(t, fmt.Sprintf("%s: generated headers", name), expectedPaths, exported.GeneratedHeaders)
4575		}
4576	}
4577
4578	expectedOrderOnlyDeps := func(expectedPaths string) exportedChecker {
4579		return func(t *testing.T, name string, exported FlagExporterInfo) {
4580			t.Helper()
4581			checkPaths(t, fmt.Sprintf("%s: order only deps", name), expectedPaths, exported.Deps)
4582		}
4583	}
4584
4585	genRuleModules := `
4586		genrule {
4587			name: "genrule_foo",
4588			cmd: "generate-foo",
4589			out: [
4590				"generated_headers/foo/generated_header.h",
4591			],
4592			export_include_dirs: [
4593				"generated_headers",
4594			],
4595		}
4596
4597		genrule {
4598			name: "genrule_bar",
4599			cmd: "generate-bar",
4600			out: [
4601				"generated_headers/bar/generated_header.h",
4602			],
4603			export_include_dirs: [
4604				"generated_headers",
4605			],
4606		}
4607	`
4608
4609	t.Run("ensure exported include dirs are not automatically re-exported from shared_libs", func(t *testing.T) {
4610		ctx := testCc(t, genRuleModules+`
4611		cc_library {
4612			name: "libfoo",
4613			srcs: ["foo.c"],
4614			export_include_dirs: ["foo/standard"],
4615			export_system_include_dirs: ["foo/system"],
4616			generated_headers: ["genrule_foo"],
4617			export_generated_headers: ["genrule_foo"],
4618		}
4619
4620		cc_library {
4621			name: "libbar",
4622			srcs: ["bar.c"],
4623			shared_libs: ["libfoo"],
4624			export_include_dirs: ["bar/standard"],
4625			export_system_include_dirs: ["bar/system"],
4626			generated_headers: ["genrule_bar"],
4627			export_generated_headers: ["genrule_bar"],
4628		}
4629		`)
4630		foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
4631		checkIncludeDirs(t, ctx, foo,
4632			expectedIncludeDirs(`
4633				foo/standard
4634				.intermediates/genrule_foo/gen/generated_headers
4635			`),
4636			expectedSystemIncludeDirs(`foo/system`),
4637			expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
4638			expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
4639		)
4640
4641		bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
4642		checkIncludeDirs(t, ctx, bar,
4643			expectedIncludeDirs(`
4644				bar/standard
4645				.intermediates/genrule_bar/gen/generated_headers
4646			`),
4647			expectedSystemIncludeDirs(`bar/system`),
4648			expectedGeneratedHeaders(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
4649			expectedOrderOnlyDeps(`.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h`),
4650		)
4651	})
4652
4653	t.Run("ensure exported include dirs are automatically re-exported from whole_static_libs", func(t *testing.T) {
4654		ctx := testCc(t, genRuleModules+`
4655		cc_library {
4656			name: "libfoo",
4657			srcs: ["foo.c"],
4658			export_include_dirs: ["foo/standard"],
4659			export_system_include_dirs: ["foo/system"],
4660			generated_headers: ["genrule_foo"],
4661			export_generated_headers: ["genrule_foo"],
4662		}
4663
4664		cc_library {
4665			name: "libbar",
4666			srcs: ["bar.c"],
4667			whole_static_libs: ["libfoo"],
4668			export_include_dirs: ["bar/standard"],
4669			export_system_include_dirs: ["bar/system"],
4670			generated_headers: ["genrule_bar"],
4671			export_generated_headers: ["genrule_bar"],
4672		}
4673		`)
4674		foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
4675		checkIncludeDirs(t, ctx, foo,
4676			expectedIncludeDirs(`
4677				foo/standard
4678				.intermediates/genrule_foo/gen/generated_headers
4679			`),
4680			expectedSystemIncludeDirs(`foo/system`),
4681			expectedGeneratedHeaders(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
4682			expectedOrderOnlyDeps(`.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h`),
4683		)
4684
4685		bar := ctx.ModuleForTests("libbar", "android_arm64_armv8-a_shared").Module()
4686		checkIncludeDirs(t, ctx, bar,
4687			expectedIncludeDirs(`
4688				bar/standard
4689				foo/standard
4690				.intermediates/genrule_foo/gen/generated_headers
4691				.intermediates/genrule_bar/gen/generated_headers
4692			`),
4693			expectedSystemIncludeDirs(`
4694				bar/system
4695				foo/system
4696			`),
4697			expectedGeneratedHeaders(`
4698				.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
4699				.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
4700			`),
4701			expectedOrderOnlyDeps(`
4702				.intermediates/genrule_foo/gen/generated_headers/foo/generated_header.h
4703				.intermediates/genrule_bar/gen/generated_headers/bar/generated_header.h
4704			`),
4705		)
4706	})
4707
4708	t.Run("ensure only aidl headers are exported", func(t *testing.T) {
4709		ctx := testCc(t, genRuleModules+`
4710		cc_library_shared {
4711			name: "libfoo",
4712			srcs: [
4713				"foo.c",
4714				"b.aidl",
4715				"a.proto",
4716			],
4717			aidl: {
4718				export_aidl_headers: true,
4719			}
4720		}
4721		`)
4722		foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
4723		checkIncludeDirs(t, ctx, foo,
4724			expectedIncludeDirs(`
4725				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl
4726			`),
4727			expectedSystemIncludeDirs(``),
4728			expectedGeneratedHeaders(`
4729				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
4730				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
4731				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
4732			`),
4733			expectedOrderOnlyDeps(`
4734				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/b.h
4735				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bnb.h
4736				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/aidl/Bpb.h
4737			`),
4738		)
4739	})
4740
4741	t.Run("ensure only proto headers are exported", func(t *testing.T) {
4742		ctx := testCc(t, genRuleModules+`
4743		cc_library_shared {
4744			name: "libfoo",
4745			srcs: [
4746				"foo.c",
4747				"b.aidl",
4748				"a.proto",
4749			],
4750			proto: {
4751				export_proto_headers: true,
4752			}
4753		}
4754		`)
4755		foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
4756		checkIncludeDirs(t, ctx, foo,
4757			expectedIncludeDirs(`
4758				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto
4759			`),
4760			expectedSystemIncludeDirs(``),
4761			expectedGeneratedHeaders(`
4762				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
4763			`),
4764			expectedOrderOnlyDeps(`
4765				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/proto/a.pb.h
4766			`),
4767		)
4768	})
4769
4770	t.Run("ensure only sysprop headers are exported", func(t *testing.T) {
4771		ctx := testCc(t, genRuleModules+`
4772		cc_library_shared {
4773			name: "libfoo",
4774			srcs: [
4775				"foo.c",
4776				"path/to/a.sysprop",
4777				"b.aidl",
4778				"a.proto",
4779			],
4780		}
4781		`)
4782		foo := ctx.ModuleForTests("libfoo", "android_arm64_armv8-a_shared").Module()
4783		checkIncludeDirs(t, ctx, foo,
4784			expectedIncludeDirs(`
4785				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include
4786			`),
4787			expectedSystemIncludeDirs(``),
4788			expectedGeneratedHeaders(`
4789				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h
4790			`),
4791			expectedOrderOnlyDeps(`
4792				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/include/path/to/a.sysprop.h
4793				.intermediates/libfoo/android_arm64_armv8-a_shared/gen/sysprop/public/include/path/to/a.sysprop.h
4794			`),
4795		)
4796	})
4797}
4798
4799func TestIncludeDirectoryOrdering(t *testing.T) {
4800	t.Parallel()
4801	baseExpectedFlags := []string{
4802		"${config.ArmThumbCflags}",
4803		"${config.ArmCflags}",
4804		"${config.CommonGlobalCflags}",
4805		"${config.DeviceGlobalCflags}",
4806		"${config.ExternalCflags}",
4807		"${config.ArmToolchainCflags}",
4808		"${config.ArmArmv7ANeonCflags}",
4809		"${config.ArmGenericCflags}",
4810		"-target",
4811		"armv7a-linux-androideabi21",
4812	}
4813
4814	expectedIncludes := []string{
4815		"external/foo/android_arm_export_include_dirs",
4816		"external/foo/lib32_export_include_dirs",
4817		"external/foo/arm_export_include_dirs",
4818		"external/foo/android_export_include_dirs",
4819		"external/foo/linux_export_include_dirs",
4820		"external/foo/export_include_dirs",
4821		"external/foo/android_arm_local_include_dirs",
4822		"external/foo/lib32_local_include_dirs",
4823		"external/foo/arm_local_include_dirs",
4824		"external/foo/android_local_include_dirs",
4825		"external/foo/linux_local_include_dirs",
4826		"external/foo/local_include_dirs",
4827		"external/foo",
4828		"external/foo/libheader1",
4829		"external/foo/libheader2",
4830		"external/foo/libwhole1",
4831		"external/foo/libwhole2",
4832		"external/foo/libstatic1",
4833		"external/foo/libstatic2",
4834		"external/foo/libshared1",
4835		"external/foo/libshared2",
4836		"external/foo/liblinux",
4837		"external/foo/libandroid",
4838		"external/foo/libarm",
4839		"external/foo/lib32",
4840		"external/foo/libandroid_arm",
4841		"defaults/cc/common/ndk_libc++_shared",
4842	}
4843
4844	conly := []string{"-fPIC", "${config.CommonGlobalConlyflags}"}
4845	cppOnly := []string{"-fPIC", "${config.CommonGlobalCppflags}", "${config.DeviceGlobalCppflags}", "${config.ArmCppflags}"}
4846
4847	cflags := []string{"-Werror", "-std=candcpp"}
4848	cstd := []string{"-std=gnu11", "-std=conly"}
4849	cppstd := []string{"-std=gnu++17", "-std=cpp", "-fno-rtti"}
4850
4851	lastIncludes := []string{
4852		"out/soong/ndk/sysroot/usr/include",
4853		"out/soong/ndk/sysroot/usr/include/arm-linux-androideabi",
4854	}
4855
4856	combineSlices := func(slices ...[]string) []string {
4857		var ret []string
4858		for _, s := range slices {
4859			ret = append(ret, s...)
4860		}
4861		return ret
4862	}
4863
4864	testCases := []struct {
4865		name     string
4866		src      string
4867		expected []string
4868	}{
4869		{
4870			name:     "c",
4871			src:      "foo.c",
4872			expected: combineSlices(baseExpectedFlags, conly, expectedIncludes, cflags, cstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}),
4873		},
4874		{
4875			name:     "cc",
4876			src:      "foo.cc",
4877			expected: combineSlices(baseExpectedFlags, cppOnly, expectedIncludes, cflags, cppstd, lastIncludes, []string{"${config.NoOverrideGlobalCflags}", "${config.NoOverrideExternalGlobalCflags}"}),
4878		},
4879		{
4880			name:     "assemble",
4881			src:      "foo.s",
4882			expected: combineSlices(baseExpectedFlags, []string{"${config.CommonGlobalAsflags}"}, expectedIncludes, lastIncludes),
4883		},
4884	}
4885
4886	for _, tc := range testCases {
4887		t.Run(tc.name, func(t *testing.T) {
4888			bp := fmt.Sprintf(`
4889		cc_library {
4890			name: "libfoo",
4891			srcs: ["%s"],
4892			cflags: ["-std=candcpp"],
4893			conlyflags: ["-std=conly"],
4894			cppflags: ["-std=cpp"],
4895			local_include_dirs: ["local_include_dirs"],
4896			export_include_dirs: ["export_include_dirs"],
4897			export_system_include_dirs: ["export_system_include_dirs"],
4898			static_libs: ["libstatic1", "libstatic2"],
4899			whole_static_libs: ["libwhole1", "libwhole2"],
4900			shared_libs: ["libshared1", "libshared2"],
4901			header_libs: ["libheader1", "libheader2"],
4902			target: {
4903				android: {
4904					shared_libs: ["libandroid"],
4905					local_include_dirs: ["android_local_include_dirs"],
4906					export_include_dirs: ["android_export_include_dirs"],
4907				},
4908				android_arm: {
4909					shared_libs: ["libandroid_arm"],
4910					local_include_dirs: ["android_arm_local_include_dirs"],
4911					export_include_dirs: ["android_arm_export_include_dirs"],
4912				},
4913				linux: {
4914					shared_libs: ["liblinux"],
4915					local_include_dirs: ["linux_local_include_dirs"],
4916					export_include_dirs: ["linux_export_include_dirs"],
4917				},
4918			},
4919			multilib: {
4920				lib32: {
4921					shared_libs: ["lib32"],
4922					local_include_dirs: ["lib32_local_include_dirs"],
4923					export_include_dirs: ["lib32_export_include_dirs"],
4924				},
4925			},
4926			arch: {
4927				arm: {
4928					shared_libs: ["libarm"],
4929					local_include_dirs: ["arm_local_include_dirs"],
4930					export_include_dirs: ["arm_export_include_dirs"],
4931				},
4932			},
4933			stl: "libc++",
4934			sdk_version: "minimum",
4935		}
4936
4937		cc_library_headers {
4938			name: "libheader1",
4939			export_include_dirs: ["libheader1"],
4940			sdk_version: "minimum",
4941			stl: "none",
4942		}
4943
4944		cc_library_headers {
4945			name: "libheader2",
4946			export_include_dirs: ["libheader2"],
4947			sdk_version: "minimum",
4948			stl: "none",
4949		}
4950	`, tc.src)
4951
4952			libs := []string{
4953				"libstatic1",
4954				"libstatic2",
4955				"libwhole1",
4956				"libwhole2",
4957				"libshared1",
4958				"libshared2",
4959				"libandroid",
4960				"libandroid_arm",
4961				"liblinux",
4962				"lib32",
4963				"libarm",
4964			}
4965
4966			for _, lib := range libs {
4967				bp += fmt.Sprintf(`
4968			cc_library {
4969				name: "%s",
4970				export_include_dirs: ["%s"],
4971				sdk_version: "minimum",
4972				stl: "none",
4973			}
4974		`, lib, lib)
4975			}
4976
4977			ctx := android.GroupFixturePreparers(
4978				PrepareForIntegrationTestWithCc,
4979				android.FixtureAddTextFile("external/foo/Android.bp", bp),
4980			).RunTest(t)
4981			// Use the arm variant instead of the arm64 variant so that it gets headers from
4982			// ndk_libandroid_support to test LateStaticLibs.
4983			cflags := ctx.ModuleForTests("libfoo", "android_arm_armv7-a-neon_sdk_static").Output("obj/external/foo/foo.o").Args["cFlags"]
4984
4985			var includes []string
4986			flags := strings.Split(cflags, " ")
4987			for _, flag := range flags {
4988				if strings.HasPrefix(flag, "-I") {
4989					includes = append(includes, strings.TrimPrefix(flag, "-I"))
4990				} else if flag == "-isystem" {
4991					// skip isystem, include next
4992				} else if len(flag) > 0 {
4993					includes = append(includes, flag)
4994				}
4995			}
4996
4997			android.AssertArrayString(t, "includes", tc.expected, includes)
4998		})
4999	}
5000
5001}
5002
5003func TestAddnoOverride64GlobalCflags(t *testing.T) {
5004	t.Parallel()
5005	ctx := testCc(t, `
5006		cc_library_shared {
5007			name: "libclient",
5008			srcs: ["foo.c"],
5009			shared_libs: ["libfoo#1"],
5010		}
5011
5012		cc_library_shared {
5013			name: "libfoo",
5014			srcs: ["foo.c"],
5015			shared_libs: ["libbar"],
5016			export_shared_lib_headers: ["libbar"],
5017			stubs: {
5018				symbol_file: "foo.map.txt",
5019				versions: ["1", "2", "3"],
5020			},
5021		}
5022
5023		cc_library_shared {
5024			name: "libbar",
5025			export_include_dirs: ["include/libbar"],
5026			srcs: ["foo.c"],
5027		}`)
5028
5029	cFlags := ctx.ModuleForTests("libclient", "android_arm64_armv8-a_shared").Rule("cc").Args["cFlags"]
5030
5031	if !strings.Contains(cFlags, "${config.NoOverride64GlobalCflags}") {
5032		t.Errorf("expected %q in cflags, got %q", "${config.NoOverride64GlobalCflags}", cFlags)
5033	}
5034}
5035
5036func TestCcBuildBrokenClangProperty(t *testing.T) {
5037	t.Parallel()
5038	tests := []struct {
5039		name                     string
5040		clang                    bool
5041		BuildBrokenClangProperty bool
5042		err                      string
5043	}{
5044		{
5045			name:  "error when clang is set to false",
5046			clang: false,
5047			err:   "is no longer supported",
5048		},
5049		{
5050			name:  "error when clang is set to true",
5051			clang: true,
5052			err:   "property is deprecated, see Changes.md",
5053		},
5054		{
5055			name:                     "no error when BuildBrokenClangProperty is explicitly set to true",
5056			clang:                    true,
5057			BuildBrokenClangProperty: true,
5058		},
5059	}
5060
5061	for _, test := range tests {
5062		t.Run(test.name, func(t *testing.T) {
5063			bp := fmt.Sprintf(`
5064			cc_library {
5065			   name: "foo",
5066			   clang: %t,
5067			}`, test.clang)
5068
5069			if test.err == "" {
5070				android.GroupFixturePreparers(
5071					prepareForCcTest,
5072					android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
5073						if test.BuildBrokenClangProperty {
5074							variables.BuildBrokenClangProperty = test.BuildBrokenClangProperty
5075						}
5076					}),
5077				).RunTestWithBp(t, bp)
5078			} else {
5079				prepareForCcTest.
5080					ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
5081					RunTestWithBp(t, bp)
5082			}
5083		})
5084	}
5085}
5086
5087func TestCcBuildBrokenClangAsFlags(t *testing.T) {
5088	t.Parallel()
5089	tests := []struct {
5090		name                    string
5091		clangAsFlags            []string
5092		BuildBrokenClangAsFlags bool
5093		err                     string
5094	}{
5095		{
5096			name:         "error when clang_asflags is set",
5097			clangAsFlags: []string{"-a", "-b"},
5098			err:          "clang_asflags: property is deprecated",
5099		},
5100		{
5101			name:                    "no error when BuildBrokenClangAsFlags is explicitly set to true",
5102			clangAsFlags:            []string{"-a", "-b"},
5103			BuildBrokenClangAsFlags: true,
5104		},
5105	}
5106
5107	for _, test := range tests {
5108		t.Run(test.name, func(t *testing.T) {
5109			bp := fmt.Sprintf(`
5110			cc_library {
5111			   name: "foo",
5112			   clang_asflags: %s,
5113			}`, `["`+strings.Join(test.clangAsFlags, `","`)+`"]`)
5114
5115			if test.err == "" {
5116				android.GroupFixturePreparers(
5117					prepareForCcTest,
5118					android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
5119						if test.BuildBrokenClangAsFlags {
5120							variables.BuildBrokenClangAsFlags = test.BuildBrokenClangAsFlags
5121						}
5122					}),
5123				).RunTestWithBp(t, bp)
5124			} else {
5125				prepareForCcTest.
5126					ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
5127					RunTestWithBp(t, bp)
5128			}
5129		})
5130	}
5131}
5132
5133func TestCcBuildBrokenClangCFlags(t *testing.T) {
5134	t.Parallel()
5135	tests := []struct {
5136		name                   string
5137		clangCFlags            []string
5138		BuildBrokenClangCFlags bool
5139		err                    string
5140	}{
5141		{
5142			name:        "error when clang_cflags is set",
5143			clangCFlags: []string{"-a", "-b"},
5144			err:         "clang_cflags: property is deprecated",
5145		},
5146		{
5147			name:                   "no error when BuildBrokenClangCFlags is explicitly set to true",
5148			clangCFlags:            []string{"-a", "-b"},
5149			BuildBrokenClangCFlags: true,
5150		},
5151	}
5152
5153	for _, test := range tests {
5154		t.Run(test.name, func(t *testing.T) {
5155			bp := fmt.Sprintf(`
5156			cc_library {
5157			   name: "foo",
5158			   clang_cflags: %s,
5159			}`, `["`+strings.Join(test.clangCFlags, `","`)+`"]`)
5160
5161			if test.err == "" {
5162				android.GroupFixturePreparers(
5163					prepareForCcTest,
5164					android.FixtureModifyProductVariables(func(variables android.FixtureProductVariables) {
5165						if test.BuildBrokenClangCFlags {
5166							variables.BuildBrokenClangCFlags = test.BuildBrokenClangCFlags
5167						}
5168					}),
5169				).RunTestWithBp(t, bp)
5170			} else {
5171				prepareForCcTest.
5172					ExtendWithErrorHandler(android.FixtureExpectsOneErrorPattern(test.err)).
5173					RunTestWithBp(t, bp)
5174			}
5175		})
5176	}
5177}
5178
5179func TestDclaLibraryInApex(t *testing.T) {
5180	t.Parallel()
5181	bp := `
5182	cc_library_shared {
5183		name: "cc_lib_in_apex",
5184		srcs: ["foo.cc"],
5185    apex_available: ["myapex"],
5186		bazel_module: { label: "//foo/bar:bar" },
5187	}`
5188	label := "//foo/bar:bar"
5189	arch64 := "arm64_armv8-a"
5190	arch32 := "arm_armv7-a-neon"
5191	apexCfgKey := android.ApexConfigKey{
5192		WithinApex:     true,
5193		ApexSdkVersion: "28",
5194	}
5195
5196	result := android.GroupFixturePreparers(
5197		prepareForCcTest,
5198		android.FixtureRegisterWithContext(registerTestMutators),
5199		android.FixtureModifyConfig(func(config android.Config) {
5200			config.BazelContext = android.MockBazelContext{
5201				OutputBaseDir: "outputbase",
5202				LabelToCcInfo: map[string]cquery.CcInfo{
5203					android.BuildMockBazelContextResultKey(label, arch32, android.Android, apexCfgKey): cquery.CcInfo{
5204						RootDynamicLibraries: []string{"foo.so"},
5205					},
5206					android.BuildMockBazelContextResultKey(label, arch64, android.Android, apexCfgKey): cquery.CcInfo{
5207						RootDynamicLibraries: []string{"foo.so"},
5208					},
5209				},
5210				BazelRequests: make(map[string]bool),
5211			}
5212		}),
5213	).RunTestWithBp(t, bp)
5214	ctx := result.TestContext
5215
5216	// Test if the bazel request is queued correctly
5217	key := android.BuildMockBazelContextRequestKey(label, cquery.GetCcInfo, arch32, android.Android, apexCfgKey)
5218	if !ctx.Config().BazelContext.(android.MockBazelContext).BazelRequests[key] {
5219		t.Errorf("Bazel request was not queued: %s", key)
5220	}
5221
5222	sharedFoo := ctx.ModuleForTests(ccLibInApex, "android_arm_armv7-a-neon_shared_"+apexVariationName).Module()
5223	producer := sharedFoo.(android.OutputFileProducer)
5224	outputFiles, err := producer.OutputFiles("")
5225	if err != nil {
5226		t.Errorf("Unexpected error getting cc_object outputfiles %s", err)
5227	}
5228	expectedOutputFiles := []string{"outputbase/execroot/__main__/foo.so"}
5229	android.AssertDeepEquals(t, "output files", expectedOutputFiles, outputFiles.Strings())
5230}
5231