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