• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright (C) 2019 The Android Open Source Project
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	"path/filepath"
19	"testing"
20
21	"android/soong/android"
22	"android/soong/genrule"
23	"android/soong/snapshot"
24)
25
26func RegisterRequiredBuildComponentsForTest(ctx android.RegistrationContext) {
27	RegisterPrebuiltBuildComponents(ctx)
28	RegisterCCBuildComponents(ctx)
29	RegisterBinaryBuildComponents(ctx)
30	RegisterLibraryBuildComponents(ctx)
31	RegisterLibraryHeadersBuildComponents(ctx)
32
33	ctx.RegisterModuleType("cc_benchmark", BenchmarkFactory)
34	ctx.RegisterModuleType("cc_object", ObjectFactory)
35	ctx.RegisterModuleType("cc_genrule", GenRuleFactory)
36	ctx.RegisterModuleType("ndk_prebuilt_shared_stl", NdkPrebuiltSharedStlFactory)
37	ctx.RegisterModuleType("ndk_prebuilt_static_stl", NdkPrebuiltStaticStlFactory)
38	ctx.RegisterModuleType("ndk_prebuilt_object", NdkPrebuiltObjectFactory)
39	ctx.RegisterModuleType("ndk_library", NdkLibraryFactory)
40}
41
42func GatherRequiredDepsForTest(oses ...android.OsType) string {
43	ret := commonDefaultModules()
44
45	supportLinuxBionic := false
46	for _, os := range oses {
47		if os == android.Windows {
48			ret += withWindowsModules()
49		}
50		if os == android.LinuxBionic {
51			supportLinuxBionic = true
52			ret += withLinuxBionic()
53		}
54	}
55
56	if !supportLinuxBionic {
57		ret += withoutLinuxBionic()
58	}
59
60	return ret
61}
62
63func commonDefaultModules() string {
64	return `
65		cc_defaults {
66			name: "toolchain_libs_defaults",
67			vendor_available: true,
68			product_available: true,
69			recovery_available: true,
70			no_libcrt: true,
71			sdk_version: "minimum",
72			nocrt: true,
73			system_shared_libs: [],
74			stl: "none",
75			srcs: [""],
76			check_elf_files: false,
77			sanitize: {
78				never: true,
79			},
80		}
81
82		cc_prebuilt_library_static {
83			name: "libcompiler_rt-extras",
84			defaults: ["toolchain_libs_defaults"],
85			vendor_ramdisk_available: true,
86		}
87
88		cc_prebuilt_library_static {
89			name: "libclang_rt.builtins",
90			defaults: ["toolchain_libs_defaults"],
91			host_supported: true,
92	        vendor_available: true,
93			vendor_ramdisk_available: true,
94			native_bridge_supported: true,
95		}
96
97		cc_prebuilt_library_shared {
98			name: "libclang_rt.hwasan",
99			defaults: ["toolchain_libs_defaults"],
100		}
101
102		cc_prebuilt_library_static {
103			name: "libunwind",
104			defaults: [
105				"linux_bionic_supported",
106				"toolchain_libs_defaults",
107			],
108			vendor_ramdisk_available: true,
109			native_bridge_supported: true,
110		}
111
112		cc_prebuilt_library_static {
113			name: "libclang_rt.fuzzer",
114			defaults: [
115				"linux_bionic_supported",
116				"toolchain_libs_defaults",
117			],
118		}
119
120		// Needed for sanitizer
121		cc_prebuilt_library_shared {
122			name: "libclang_rt.ubsan_standalone",
123			defaults: ["toolchain_libs_defaults"],
124		}
125
126		cc_prebuilt_library_static {
127			name: "libclang_rt.ubsan_minimal",
128			defaults: ["toolchain_libs_defaults"],
129		}
130
131		cc_library {
132			name: "libc",
133			defaults: ["linux_bionic_supported"],
134			no_libcrt: true,
135			nocrt: true,
136			stl: "none",
137			system_shared_libs: [],
138			recovery_available: true,
139			stubs: {
140				versions: ["27", "28", "29"],
141			},
142			llndk: {
143				symbol_file: "libc.map.txt",
144			},
145		}
146		cc_library {
147			name: "libm",
148			defaults: ["linux_bionic_supported"],
149			no_libcrt: true,
150			nocrt: true,
151			stl: "none",
152			system_shared_libs: [],
153			recovery_available: true,
154			stubs: {
155				versions: ["27", "28", "29"],
156			},
157			apex_available: [
158				"//apex_available:platform",
159				"myapex"
160			],
161			llndk: {
162				symbol_file: "libm.map.txt",
163			},
164		}
165
166		// Coverage libraries
167		cc_library {
168			name: "libprofile-extras",
169			vendor_available: true,
170			vendor_ramdisk_available: true,
171			product_available: true,
172			recovery_available: true,
173			native_coverage: false,
174			system_shared_libs: [],
175			stl: "none",
176			notice: "custom_notice",
177		}
178		cc_library {
179			name: "libprofile-clang-extras",
180			vendor_available: true,
181			vendor_ramdisk_available: true,
182			product_available: true,
183			recovery_available: true,
184			native_coverage: false,
185			system_shared_libs: [],
186			stl: "none",
187			notice: "custom_notice",
188		}
189		cc_library {
190			name: "libprofile-extras_ndk",
191			vendor_available: true,
192			product_available: true,
193			native_coverage: false,
194			system_shared_libs: [],
195			stl: "none",
196			notice: "custom_notice",
197			sdk_version: "current",
198		}
199		cc_library {
200			name: "libprofile-clang-extras_ndk",
201			vendor_available: true,
202			product_available: true,
203			native_coverage: false,
204			system_shared_libs: [],
205			stl: "none",
206			notice: "custom_notice",
207			sdk_version: "current",
208		}
209
210		cc_library {
211			name: "libdl",
212			defaults: ["linux_bionic_supported"],
213			no_libcrt: true,
214			nocrt: true,
215			stl: "none",
216			system_shared_libs: [],
217			recovery_available: true,
218			stubs: {
219				versions: ["27", "28", "29"],
220			},
221			apex_available: [
222				"//apex_available:platform",
223				"myapex"
224			],
225			llndk: {
226				symbol_file: "libdl.map.txt",
227			},
228		}
229		cc_library {
230			name: "libft2",
231			no_libcrt: true,
232			nocrt: true,
233			system_shared_libs: [],
234			recovery_available: true,
235			llndk: {
236				symbol_file: "libft2.map.txt",
237				private: true,
238			}
239		}
240		cc_library {
241			name: "libc++_static",
242			no_libcrt: true,
243			nocrt: true,
244			system_shared_libs: [],
245			stl: "none",
246			vendor_available: true,
247			vendor_ramdisk_available: true,
248			product_available: true,
249			recovery_available: true,
250			host_supported: true,
251			min_sdk_version: "29",
252			apex_available: [
253				"//apex_available:platform",
254				"//apex_available:anyapex",
255			],
256		}
257		cc_library {
258			name: "libc++",
259			no_libcrt: true,
260			nocrt: true,
261			system_shared_libs: [],
262			stl: "none",
263			vendor_available: true,
264			product_available: true,
265			recovery_available: true,
266			host_supported: true,
267			min_sdk_version: "29",
268			vndk: {
269				enabled: true,
270				support_system_process: true,
271			},
272			apex_available: [
273				"//apex_available:platform",
274				"//apex_available:anyapex",
275			],
276		}
277		cc_library {
278			name: "libc++demangle",
279			no_libcrt: true,
280			nocrt: true,
281			system_shared_libs: [],
282			stl: "none",
283			host_supported: false,
284			vendor_available: true,
285			vendor_ramdisk_available: true,
286			product_available: true,
287			recovery_available: true,
288			min_sdk_version: "29",
289			apex_available: [
290				"//apex_available:platform",
291				"//apex_available:anyapex",
292			],
293		}
294
295		cc_defaults {
296			name: "crt_defaults",
297			defaults: ["linux_bionic_supported"],
298			recovery_available: true,
299			vendor_available: true,
300			vendor_ramdisk_available: true,
301			product_available: true,
302			native_bridge_supported: true,
303			stl: "none",
304			min_sdk_version: "16",
305			crt: true,
306			system_shared_libs: [],
307			apex_available: [
308				"//apex_available:platform",
309				"//apex_available:anyapex",
310			],
311		}
312
313		cc_object {
314			name: "crtbegin_so",
315			defaults: ["crt_defaults"],
316			srcs: ["crtbegin_so.c"],
317			objs: ["crtbrand"],
318		}
319
320		cc_object {
321			name: "crtbegin_dynamic",
322			defaults: ["crt_defaults"],
323			srcs: ["crtbegin.c"],
324			objs: ["crtbrand"],
325		}
326
327		cc_object {
328			name: "crtbegin_static",
329			defaults: ["crt_defaults"],
330			srcs: ["crtbegin.c"],
331			objs: ["crtbrand"],
332		}
333
334		cc_object {
335			name: "crtend_so",
336			defaults: ["crt_defaults"],
337			srcs: ["crtend_so.c"],
338			objs: ["crtbrand"],
339		}
340
341		cc_object {
342			name: "crtend_android",
343			defaults: ["crt_defaults"],
344			srcs: ["crtend.c"],
345			objs: ["crtbrand"],
346		}
347
348		cc_object {
349			name: "crtbrand",
350			defaults: ["crt_defaults"],
351			srcs: ["crtbrand.c"],
352		}
353
354		cc_library {
355			name: "libprotobuf-cpp-lite",
356		}
357
358		cc_library {
359			name: "ndk_libunwind",
360			sdk_version: "minimum",
361			stl: "none",
362			system_shared_libs: [],
363		}
364
365		ndk_library {
366			name: "libc",
367			first_version: "minimum",
368			symbol_file: "libc.map.txt",
369		}
370
371		ndk_library {
372			name: "libm",
373			first_version: "minimum",
374			symbol_file: "libm.map.txt",
375		}
376
377		ndk_library {
378			name: "libdl",
379			first_version: "minimum",
380			symbol_file: "libdl.map.txt",
381		}
382
383		ndk_prebuilt_shared_stl {
384			name: "ndk_libc++_shared",
385			export_include_dirs: ["ndk_libc++_shared"],
386		}
387
388		ndk_prebuilt_static_stl {
389			name: "ndk_libandroid_support",
390			export_include_dirs: ["ndk_libandroid_support"],
391		}
392
393		cc_library_static {
394			name: "libgoogle-benchmark",
395			sdk_version: "current",
396			stl: "none",
397			system_shared_libs: [],
398		}
399
400		cc_library_static {
401			name: "note_memtag_heap_async",
402		}
403
404		cc_library_static {
405			name: "note_memtag_heap_sync",
406		}
407
408		cc_library {
409			name: "libc_musl",
410			host_supported: true,
411			no_libcrt: true,
412			nocrt: true,
413			system_shared_libs: [],
414			stl: "none",
415		}
416	`
417}
418
419func withWindowsModules() string {
420	return `
421		cc_prebuilt_library_static {
422			name: "libwinpthread",
423			host_supported: true,
424			enabled: false,
425			target: {
426				windows: {
427					enabled: true,
428				},
429			},
430			stl: "none",
431			srcs:[""],
432		}
433		`
434}
435
436func withLinuxBionic() string {
437	return `
438				cc_binary {
439					name: "linker",
440					defaults: ["linux_bionic_supported"],
441					recovery_available: true,
442					stl: "none",
443					nocrt: true,
444					static_executable: true,
445					native_coverage: false,
446					system_shared_libs: [],
447				}
448
449				cc_genrule {
450					name: "host_bionic_linker_script",
451					host_supported: true,
452					device_supported: false,
453					target: {
454						host: {
455							enabled: false,
456						},
457						linux_bionic: {
458							enabled: true,
459						},
460					},
461					out: ["linker.script"],
462				}
463
464				cc_defaults {
465					name: "linux_bionic_supported",
466					host_supported: true,
467					target: {
468						host: {
469							enabled: false,
470						},
471						linux_bionic: {
472							enabled: true,
473						},
474					},
475				}
476			`
477}
478
479func withoutLinuxBionic() string {
480	return `
481			cc_defaults {
482				name: "linux_bionic_supported",
483			}
484		`
485}
486
487func GatherRequiredFilesForTest(fs map[string][]byte) {
488}
489
490// The directory in which cc linux bionic default modules will be defined.
491//
492// Placing them here ensures that their location does not conflict with default test modules
493// defined by other packages.
494const linuxBionicDefaultsPath = "defaults/cc/linux-bionic/Android.bp"
495
496// The directory in which the default cc common test modules will be defined.
497//
498// Placing them here ensures that their location does not conflict with default test modules
499// defined by other packages.
500const DefaultCcCommonTestModulesDir = "defaults/cc/common/"
501
502// Test fixture preparer that will register most cc build components.
503//
504// Singletons and mutators should only be added here if they are needed for a majority of cc
505// module types, otherwise they should be added under a separate preparer to allow them to be
506// selected only when needed to reduce test execution time.
507//
508// Module types do not have much of an overhead unless they are used so this should include as many
509// module types as possible. The exceptions are those module types that require mutators and/or
510// singletons in order to function in which case they should be kept together in a separate
511// preparer.
512var PrepareForTestWithCcBuildComponents = android.GroupFixturePreparers(
513	android.PrepareForTestWithAndroidBuildComponents,
514	android.FixtureRegisterWithContext(RegisterRequiredBuildComponentsForTest),
515	android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
516		ctx.RegisterModuleType("cc_fuzz", FuzzFactory)
517		ctx.RegisterModuleType("cc_test", TestFactory)
518		ctx.RegisterModuleType("cc_test_library", TestLibraryFactory)
519		ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
520
521		RegisterVndkLibraryTxtTypes(ctx)
522	}),
523
524	// Additional files needed in tests that disallow non-existent source files.
525	// This includes files that are needed by all, or at least most, instances of a cc module type.
526	android.MockFS{
527		// Needed for ndk_prebuilt_(shared|static)_stl.
528		"prebuilts/ndk/current/sources/cxx-stl/llvm-libc++/libs": nil,
529	}.AddToFixture(),
530)
531
532// Preparer that will define default cc modules, e.g. standard prebuilt modules.
533var PrepareForTestWithCcDefaultModules = android.GroupFixturePreparers(
534	PrepareForTestWithCcBuildComponents,
535
536	// Additional files needed in tests that disallow non-existent source.
537	android.MockFS{
538		"defaults/cc/common/libc.map.txt":           nil,
539		"defaults/cc/common/libdl.map.txt":          nil,
540		"defaults/cc/common/libm.map.txt":           nil,
541		"defaults/cc/common/ndk_libandroid_support": nil,
542		"defaults/cc/common/ndk_libc++_shared":      nil,
543		"defaults/cc/common/crtbegin_so.c":          nil,
544		"defaults/cc/common/crtbegin.c":             nil,
545		"defaults/cc/common/crtend_so.c":            nil,
546		"defaults/cc/common/crtend.c":               nil,
547		"defaults/cc/common/crtbrand.c":             nil,
548	}.AddToFixture(),
549
550	// Place the default cc test modules that are common to all platforms in a location that will not
551	// conflict with default test modules defined by other packages.
552	android.FixtureAddTextFile(DefaultCcCommonTestModulesDir+"Android.bp", commonDefaultModules()),
553	// Disable linux bionic by default.
554	android.FixtureAddTextFile(linuxBionicDefaultsPath, withoutLinuxBionic()),
555)
556
557// Prepare a fixture to use all cc module types, mutators and singletons fully.
558//
559// This should only be used by tests that want to run with as much of the build enabled as possible.
560var PrepareForIntegrationTestWithCc = android.GroupFixturePreparers(
561	android.PrepareForIntegrationTestWithAndroid,
562	genrule.PrepareForIntegrationTestWithGenrule,
563	PrepareForTestWithCcDefaultModules,
564)
565
566// The preparer to include if running a cc related test for windows.
567var PrepareForTestOnWindows = android.GroupFixturePreparers(
568	// Place the default cc test modules for windows platforms in a location that will not conflict
569	// with default test modules defined by other packages.
570	android.FixtureAddTextFile("defaults/cc/windows/Android.bp", withWindowsModules()),
571)
572
573// The preparer to include if running a cc related test for linux bionic.
574var PrepareForTestOnLinuxBionic = android.GroupFixturePreparers(
575	// Enable linux bionic
576	//
577	// Can be used after PrepareForTestWithCcDefaultModules to override its default behavior of
578	// disabling linux bionic, hence why this uses FixtureOverrideTextFile.
579	android.FixtureOverrideTextFile(linuxBionicDefaultsPath, withLinuxBionic()),
580)
581
582// This adds some additional modules and singletons which might negatively impact the performance
583// of tests so they are not included in the PrepareForIntegrationTestWithCc.
584var PrepareForTestWithCcIncludeVndk = android.GroupFixturePreparers(
585	PrepareForIntegrationTestWithCc,
586	android.FixtureRegisterWithContext(func(ctx android.RegistrationContext) {
587		snapshot.VendorSnapshotImageSingleton.Init(ctx)
588		snapshot.RecoverySnapshotImageSingleton.Init(ctx)
589		RegisterVendorSnapshotModules(ctx)
590		RegisterRecoverySnapshotModules(ctx)
591		ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
592	}),
593)
594
595// TestConfig is the legacy way of creating a test Config for testing cc modules.
596//
597// See testCc for an explanation as to how to stop using this deprecated method.
598//
599// deprecated
600func TestConfig(buildDir string, os android.OsType, env map[string]string,
601	bp string, fs map[string][]byte) android.Config {
602
603	// add some modules that are required by the compiler and/or linker
604	bp = bp + GatherRequiredDepsForTest(os)
605
606	mockFS := map[string][]byte{}
607
608	GatherRequiredFilesForTest(mockFS)
609
610	for k, v := range fs {
611		mockFS[k] = v
612	}
613
614	return android.TestArchConfig(buildDir, env, bp, mockFS)
615}
616
617// CreateTestContext is the legacy way of creating a TestContext for testing cc modules.
618//
619// See testCc for an explanation as to how to stop using this deprecated method.
620//
621// deprecated
622func CreateTestContext(config android.Config) *android.TestContext {
623	ctx := android.NewTestArchContext(config)
624	genrule.RegisterGenruleBuildComponents(ctx)
625	ctx.RegisterModuleType("cc_fuzz", FuzzFactory)
626	ctx.RegisterModuleType("cc_test", TestFactory)
627	ctx.RegisterModuleType("cc_test_library", TestLibraryFactory)
628	ctx.RegisterModuleType("filegroup", android.FileGroupFactory)
629	ctx.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
630
631	snapshot.VendorSnapshotImageSingleton.Init(ctx)
632	snapshot.RecoverySnapshotImageSingleton.Init(ctx)
633	RegisterVendorSnapshotModules(ctx)
634	RegisterRecoverySnapshotModules(ctx)
635	ctx.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton)
636	RegisterVndkLibraryTxtTypes(ctx)
637
638	ctx.PreArchMutators(android.RegisterDefaultsPreArchMutators)
639	android.RegisterPrebuiltMutators(ctx)
640	RegisterRequiredBuildComponentsForTest(ctx)
641
642	return ctx
643}
644
645func checkSnapshotIncludeExclude(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string, include bool, fake bool) {
646	t.Helper()
647	mod := ctx.ModuleForTests(moduleName, variant)
648	outputFiles := mod.OutputFiles(t, "")
649	if len(outputFiles) != 1 {
650		t.Errorf("%q must have single output\n", moduleName)
651		return
652	}
653	snapshotPath := filepath.Join(subDir, snapshotFilename)
654
655	if include {
656		out := singleton.Output(snapshotPath)
657		if fake {
658			if out.Rule == nil {
659				t.Errorf("Missing rule for module %q output file %q", moduleName, outputFiles[0])
660			}
661		} else {
662			if out.Input.String() != outputFiles[0].String() {
663				t.Errorf("The input of snapshot %q must be %q, but %q", moduleName, out.Input.String(), outputFiles[0])
664			}
665		}
666	} else {
667		out := singleton.MaybeOutput(snapshotPath)
668		if out.Rule != nil {
669			t.Errorf("There must be no rule for module %q output file %q", moduleName, outputFiles[0])
670		}
671	}
672}
673
674func CheckSnapshot(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string) {
675	t.Helper()
676	checkSnapshotIncludeExclude(t, ctx, singleton, moduleName, snapshotFilename, subDir, variant, true, false)
677}
678
679func CheckSnapshotExclude(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string) {
680	t.Helper()
681	checkSnapshotIncludeExclude(t, ctx, singleton, moduleName, snapshotFilename, subDir, variant, false, false)
682}
683
684func CheckSnapshotRule(t *testing.T, ctx *android.TestContext, singleton android.TestingSingleton, moduleName, snapshotFilename, subDir, variant string) {
685	t.Helper()
686	checkSnapshotIncludeExclude(t, ctx, singleton, moduleName, snapshotFilename, subDir, variant, true, true)
687}
688
689func AssertExcludeFromVendorSnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool, variant string) {
690	t.Helper()
691	m := ctx.ModuleForTests(name, variant).Module().(LinkableInterface)
692	if m.ExcludeFromVendorSnapshot() != expected {
693		t.Errorf("expected %q ExcludeFromVendorSnapshot to be %t", m.String(), expected)
694	}
695}
696
697func GetOutputPaths(ctx *android.TestContext, variant string, moduleNames []string) (paths android.Paths) {
698	for _, moduleName := range moduleNames {
699		module := ctx.ModuleForTests(moduleName, variant).Module().(*Module)
700		output := module.outputFile.Path().RelativeToTop()
701		paths = append(paths, output)
702	}
703	return paths
704}
705
706func AssertExcludeFromRecoverySnapshotIs(t *testing.T, ctx *android.TestContext, name string, expected bool, variant string) {
707	t.Helper()
708	m := ctx.ModuleForTests(name, variant).Module().(LinkableInterface)
709	if m.ExcludeFromRecoverySnapshot() != expected {
710		t.Errorf("expected %q ExcludeFromRecoverySnapshot to be %t", m.String(), expected)
711	}
712}
713