xref: /aosp_15_r20/build/soong/cc/androidmk.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1// Copyright 2015 Google Inc. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7//     http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package cc
16
17import (
18	"fmt"
19	"io"
20	"path/filepath"
21	"strings"
22
23	"android/soong/android"
24)
25
26var (
27	NativeBridgeSuffix  = ".native_bridge"
28	ProductSuffix       = ".product"
29	VendorSuffix        = ".vendor"
30	RamdiskSuffix       = ".ramdisk"
31	VendorRamdiskSuffix = ".vendor_ramdisk"
32	RecoverySuffix      = ".recovery"
33	sdkSuffix           = ".sdk"
34)
35
36type AndroidMkContext interface {
37	BaseModuleName() string
38	Target() android.Target
39	subAndroidMk(android.Config, *android.AndroidMkInfo, interface{})
40	Arch() android.Arch
41	Os() android.OsType
42	Host() bool
43	UseVndk() bool
44	VndkVersion() string
45	static() bool
46	InRamdisk() bool
47	InVendorRamdisk() bool
48	InRecovery() bool
49	NotInPlatform() bool
50	InVendorOrProduct() bool
51	ArchSpecific() bool
52}
53
54type subAndroidMkProviderInfoProducer interface {
55	prepareAndroidMKProviderInfo(android.Config, AndroidMkContext, *android.AndroidMkInfo)
56}
57
58type subAndroidMkFooterInfoProducer interface {
59	prepareAndroidMKFooterInfo(android.Config, AndroidMkContext, *android.AndroidMkInfo)
60}
61
62func (c *Module) subAndroidMk(config android.Config, entries *android.AndroidMkInfo, obj interface{}) {
63	if c.subAndroidMkOnce == nil {
64		c.subAndroidMkOnce = make(map[subAndroidMkProviderInfoProducer]bool)
65	}
66	if androidmk, ok := obj.(subAndroidMkProviderInfoProducer); ok {
67		if !c.subAndroidMkOnce[androidmk] {
68			c.subAndroidMkOnce[androidmk] = true
69			androidmk.prepareAndroidMKProviderInfo(config, c, entries)
70		}
71	}
72}
73
74var _ android.AndroidMkProviderInfoProducer = (*Module)(nil)
75
76func (c *Module) PrepareAndroidMKProviderInfo(config android.Config) *android.AndroidMkProviderInfo {
77	if c.hideApexVariantFromMake || c.Properties.HideFromMake {
78		return &android.AndroidMkProviderInfo{
79			PrimaryInfo: android.AndroidMkInfo{
80				Disabled: true,
81			},
82		}
83	}
84
85	providerData := android.AndroidMkProviderInfo{
86		PrimaryInfo: android.AndroidMkInfo{
87			OutputFile:   c.outputFile,
88			Required:     c.Properties.AndroidMkRuntimeLibs,
89			OverrideName: c.BaseModuleName(),
90			Include:      "$(BUILD_SYSTEM)/soong_cc_rust_prebuilt.mk",
91			EntryMap:     make(map[string][]string),
92		},
93	}
94
95	entries := &providerData.PrimaryInfo
96	if len(c.Properties.Logtags) > 0 {
97		entries.AddStrings("LOCAL_SOONG_LOGTAGS_FILES", c.logtagsPaths.Strings()...)
98	}
99	// Note: Pass the exact value of AndroidMkSystemSharedLibs to the Make
100	// world, even if it is an empty list. In the Make world,
101	// LOCAL_SYSTEM_SHARED_LIBRARIES defaults to "none", which is expanded
102	// to the default list of system shared libs by the build system.
103	// Soong computes the exact list of system shared libs, so we have to
104	// override the default value when the list of libs is actually empty.
105	entries.SetString("LOCAL_SYSTEM_SHARED_LIBRARIES", strings.Join(c.Properties.AndroidMkSystemSharedLibs, " "))
106	if len(c.Properties.AndroidMkSharedLibs) > 0 {
107		entries.AddStrings("LOCAL_SHARED_LIBRARIES", c.Properties.AndroidMkSharedLibs...)
108	}
109	if len(c.Properties.AndroidMkRuntimeLibs) > 0 {
110		entries.AddStrings("LOCAL_RUNTIME_LIBRARIES", c.Properties.AndroidMkRuntimeLibs...)
111	}
112	entries.SetString("LOCAL_SOONG_LINK_TYPE", c.makeLinkType)
113	if c.InVendor() {
114		entries.SetBool("LOCAL_IN_VENDOR", true)
115	} else if c.InProduct() {
116		entries.SetBool("LOCAL_IN_PRODUCT", true)
117	}
118	if c.Properties.SdkAndPlatformVariantVisibleToMake {
119		// Add the unsuffixed name to SOONG_SDK_VARIANT_MODULES so that Make can rewrite
120		// dependencies to the .sdk suffix when building a module that uses the SDK.
121		entries.SetString("SOONG_SDK_VARIANT_MODULES",
122			"$(SOONG_SDK_VARIANT_MODULES) $(patsubst %.sdk,%,$(LOCAL_MODULE))")
123	}
124	entries.SetBoolIfTrue("LOCAL_UNINSTALLABLE_MODULE", c.IsSkipInstall())
125
126	for _, feature := range c.features {
127		c.subAndroidMk(config, entries, feature)
128	}
129
130	c.subAndroidMk(config, entries, c.compiler)
131	c.subAndroidMk(config, entries, c.linker)
132	if c.sanitize != nil {
133		c.subAndroidMk(config, entries, c.sanitize)
134	}
135	c.subAndroidMk(config, entries, c.installer)
136
137	entries.SubName += c.Properties.SubName
138
139	// The footer info comes at the last step, previously it was achieved by
140	// calling some extra footer function that were added earlier. Because we no
141	// longer use these extra footer functions, we need to put this step at the
142	// last one.
143	if c.Properties.IsSdkVariant && c.Properties.SdkAndPlatformVariantVisibleToMake &&
144		c.CcLibraryInterface() && c.Shared() {
145		// Using the SDK variant as a JNI library needs a copy of the .so that
146		// is not named .sdk.so so that it can be packaged into the APK with
147		// the right name.
148		entries.FooterStrings = []string{
149			fmt.Sprintf("%s %s %s", "$(eval $(call copy-one-file,",
150				"$(LOCAL_BUILT_MODULE),",
151				"$(patsubst %.sdk.so,%.so,$(LOCAL_BUILT_MODULE))))")}
152	}
153
154	for _, obj := range []interface{}{c.compiler, c.linker, c.sanitize, c.installer} {
155		if obj == nil {
156			continue
157		}
158		if p, ok := obj.(subAndroidMkFooterInfoProducer); ok {
159			p.prepareAndroidMKFooterInfo(config, c, entries)
160		}
161	}
162
163	return &providerData
164}
165
166func androidMkWriteExtraTestConfigs(extraTestConfigs android.Paths, entries *android.AndroidMkInfo) {
167	if len(extraTestConfigs) > 0 {
168		entries.AddStrings("LOCAL_EXTRA_FULL_TEST_CONFIGS", extraTestConfigs.Strings()...)
169	}
170}
171
172func makeOverrideModuleNames(ctx AndroidMkContext, overrides []string) []string {
173	if ctx.Target().NativeBridge == android.NativeBridgeEnabled {
174		var result []string
175		for _, override := range overrides {
176			result = append(result, override+NativeBridgeSuffix)
177		}
178		return result
179	}
180
181	return overrides
182}
183
184func (library *libraryDecorator) androidMkWriteExportedFlags(entries *android.AndroidMkInfo) {
185	var exportedFlags []string
186	var includeDirs android.Paths
187	var systemIncludeDirs android.Paths
188	var exportedDeps android.Paths
189
190	if library.flagExporterInfo != nil {
191		exportedFlags = library.flagExporterInfo.Flags
192		includeDirs = library.flagExporterInfo.IncludeDirs
193		systemIncludeDirs = library.flagExporterInfo.SystemIncludeDirs
194		exportedDeps = library.flagExporterInfo.Deps
195	} else {
196		exportedFlags = library.flagExporter.flags
197		includeDirs = library.flagExporter.dirs
198		systemIncludeDirs = library.flagExporter.systemDirs
199		exportedDeps = library.flagExporter.deps
200	}
201	for _, dir := range includeDirs {
202		exportedFlags = append(exportedFlags, "-I"+dir.String())
203	}
204	for _, dir := range systemIncludeDirs {
205		exportedFlags = append(exportedFlags, "-isystem "+dir.String())
206	}
207	if len(exportedFlags) > 0 {
208		entries.AddStrings("LOCAL_EXPORT_CFLAGS", exportedFlags...)
209	}
210	if len(exportedDeps) > 0 {
211		entries.AddStrings("LOCAL_EXPORT_C_INCLUDE_DEPS", exportedDeps.Strings()...)
212	}
213}
214
215func (library *libraryDecorator) androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries *android.AndroidMkInfo) {
216	if !library.static() {
217		entries.AddPaths("LOCAL_ADDITIONAL_DEPENDENCIES", library.sAbiDiff)
218	}
219}
220
221// TODO(ccross): remove this once apex/androidmk.go is converted to AndroidMkEntries
222func (library *libraryDecorator) androidMkWriteAdditionalDependenciesForSourceAbiDiff(w io.Writer) {
223	if !library.static() {
224		fmt.Fprintln(w, "LOCAL_ADDITIONAL_DEPENDENCIES +=", strings.Join(library.sAbiDiff.Strings(), " "))
225	}
226}
227
228func (library *libraryDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
229	if library.static() {
230		entries.Class = "STATIC_LIBRARIES"
231	} else if library.shared() {
232		entries.Class = "SHARED_LIBRARIES"
233		entries.SetString("LOCAL_SOONG_TOC", library.toc().String())
234		if !library.buildStubs() && library.unstrippedOutputFile != nil {
235			entries.SetString("LOCAL_SOONG_UNSTRIPPED_BINARY", library.unstrippedOutputFile.String())
236		}
237		if len(library.Properties.Overrides) > 0 {
238			entries.SetString("LOCAL_OVERRIDES_MODULES", strings.Join(makeOverrideModuleNames(ctx, library.Properties.Overrides), " "))
239		}
240		if len(library.postInstallCmds) > 0 {
241			entries.SetString("LOCAL_POST_INSTALL_CMD", strings.Join(library.postInstallCmds, "&& "))
242		}
243	} else if library.header() {
244		entries.Class = "HEADER_LIBRARIES"
245	}
246
247	if library.distFile != nil {
248		entries.DistFiles = android.MakeDefaultDistFiles(library.distFile)
249	}
250
251	library.androidMkWriteExportedFlags(entries)
252	library.androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries)
253
254	if entries.OutputFile.Valid() {
255		_, _, ext := android.SplitFileExt(entries.OutputFile.Path().Base())
256		entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext)
257	}
258
259	if library.coverageOutputFile.Valid() {
260		entries.SetString("LOCAL_PREBUILT_COVERAGE_ARCHIVE", library.coverageOutputFile.String())
261	}
262
263	if library.shared() && !library.buildStubs() {
264		ctx.subAndroidMk(config, entries, library.baseInstaller)
265	} else {
266		if library.buildStubs() && library.stubsVersion() != "" {
267			entries.SubName = "." + library.stubsVersion()
268		}
269		// library.makeUninstallable() depends on this to bypass HideFromMake() for
270		// static libraries.
271		entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
272		if library.buildStubs() {
273			entries.SetBool("LOCAL_NO_NOTICE_FILE", true)
274		}
275	}
276	// If a library providing a stub is included in an APEX, the private APIs of the library
277	// is accessible only inside the APEX. From outside of the APEX, clients can only use the
278	// public APIs via the stub. To enforce this, the (latest version of the) stub gets the
279	// name of the library. The impl library instead gets the `.bootstrap` suffix to so that
280	// they can be exceptionally used directly when APEXes are not available (e.g. during the
281	// very early stage in the boot process).
282	if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.NotInPlatform() &&
283		!ctx.InRamdisk() && !ctx.InVendorRamdisk() && !ctx.InRecovery() && !ctx.InVendorOrProduct() && !ctx.static() {
284		if library.buildStubs() && library.isLatestStubVersion() {
285			entries.SubName = ""
286		}
287		if !library.buildStubs() {
288			entries.SubName = ".bootstrap"
289		}
290	}
291}
292
293func (object *objectLinker) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
294	entries.Class = "STATIC_LIBRARIES"
295}
296
297func (object *objectLinker) prepareAndroidMKFooterInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
298	out := entries.OutputFile.Path()
299	name := ctx.BaseModuleName()
300	if entries.OverrideName != "" {
301		name = entries.OverrideName
302	}
303
304	prefix := ""
305	if ctx.ArchSpecific() {
306		switch ctx.Os().Class {
307		case android.Host:
308			if ctx.Target().HostCross {
309				prefix = "HOST_CROSS_"
310			} else {
311				prefix = "HOST_"
312			}
313		case android.Device:
314			prefix = "TARGET_"
315
316		}
317
318		if ctx.Arch().ArchType != config.Targets[ctx.Os()][0].Arch.ArchType {
319			prefix = "2ND_" + prefix
320		}
321	}
322
323	varname := fmt.Sprintf("SOONG_%sOBJECT_%s%s", prefix, name, entries.SubName)
324
325	entries.FooterStrings = append(entries.FooterStrings,
326		fmt.Sprintf("\n%s := %s\n.KATI_READONLY: %s", varname, out.String(), varname))
327}
328
329func (test *testDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
330	if len(test.InstallerProperties.Test_suites) > 0 {
331		entries.AddCompatibilityTestSuites(test.InstallerProperties.Test_suites...)
332	}
333}
334
335func (binary *binaryDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
336	ctx.subAndroidMk(config, entries, binary.baseInstaller)
337
338	entries.Class = "EXECUTABLES"
339	entries.DistFiles = binary.distFiles
340	entries.SetString("LOCAL_SOONG_UNSTRIPPED_BINARY", binary.unstrippedOutputFile.String())
341	if len(binary.symlinks) > 0 {
342		entries.AddStrings("LOCAL_MODULE_SYMLINKS", binary.symlinks...)
343	}
344
345	if binary.coverageOutputFile.Valid() {
346		entries.SetString("LOCAL_PREBUILT_COVERAGE_ARCHIVE", binary.coverageOutputFile.String())
347	}
348
349	if len(binary.Properties.Overrides) > 0 {
350		entries.SetString("LOCAL_OVERRIDES_MODULES", strings.Join(makeOverrideModuleNames(ctx, binary.Properties.Overrides), " "))
351	}
352	if len(binary.postInstallCmds) > 0 {
353		entries.SetString("LOCAL_POST_INSTALL_CMD", strings.Join(binary.postInstallCmds, "&& "))
354	}
355}
356
357func (benchmark *benchmarkDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
358	ctx.subAndroidMk(config, entries, benchmark.binaryDecorator)
359	entries.Class = "NATIVE_TESTS"
360	if len(benchmark.Properties.Test_suites) > 0 {
361		entries.AddCompatibilityTestSuites(benchmark.Properties.Test_suites...)
362	}
363	if benchmark.testConfig != nil {
364		entries.SetString("LOCAL_FULL_TEST_CONFIG", benchmark.testConfig.String())
365	}
366	entries.SetBool("LOCAL_NATIVE_BENCHMARK", true)
367	if !BoolDefault(benchmark.Properties.Auto_gen_config, true) {
368		entries.SetBool("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", true)
369	}
370}
371
372func (test *testBinary) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
373	ctx.subAndroidMk(config, entries, test.binaryDecorator)
374	ctx.subAndroidMk(config, entries, test.testDecorator)
375
376	entries.Class = "NATIVE_TESTS"
377	if test.testConfig != nil {
378		entries.SetString("LOCAL_FULL_TEST_CONFIG", test.testConfig.String())
379	}
380	if !BoolDefault(test.Properties.Auto_gen_config, true) {
381		entries.SetBool("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", true)
382	}
383	entries.AddStrings("LOCAL_TEST_MAINLINE_MODULES", test.Properties.Test_mainline_modules...)
384
385	entries.SetBoolIfTrue("LOCAL_COMPATIBILITY_PER_TESTCASE_DIRECTORY", Bool(test.Properties.Per_testcase_directory))
386	if len(test.Properties.Data_bins) > 0 {
387		entries.AddStrings("LOCAL_TEST_DATA_BINS", test.Properties.Data_bins...)
388	}
389
390	test.Properties.Test_options.CommonTestOptions.SetAndroidMkInfoEntries(entries)
391
392	androidMkWriteExtraTestConfigs(test.extraTestConfigs, entries)
393}
394
395func (fuzz *fuzzBinary) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
396	ctx.subAndroidMk(config, entries, fuzz.binaryDecorator)
397
398	entries.SetBool("LOCAL_IS_FUZZ_TARGET", true)
399	if fuzz.installedSharedDeps != nil {
400		// TOOD: move to install dep
401		entries.AddStrings("LOCAL_FUZZ_INSTALLED_SHARED_DEPS", fuzz.installedSharedDeps...)
402	}
403}
404
405func (test *testLibrary) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
406	ctx.subAndroidMk(config, entries, test.libraryDecorator)
407	ctx.subAndroidMk(config, entries, test.testDecorator)
408}
409
410func (installer *baseInstaller) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
411	if installer.path == (android.InstallPath{}) {
412		return
413	}
414
415	path, file := filepath.Split(installer.path.String())
416	stem, suffix, _ := android.SplitFileExt(file)
417	entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
418	entries.SetString("LOCAL_MODULE_PATH", path)
419	entries.SetString("LOCAL_MODULE_STEM", stem)
420}
421
422func (c *stubDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
423	entries.SubName = ndkLibrarySuffix + "." + c.apiLevel.String()
424	entries.Class = "SHARED_LIBRARIES"
425
426	if !c.buildStubs() {
427		entries.Disabled = true
428		return
429	}
430
431	path, file := filepath.Split(c.installPath.String())
432	stem, suffix, _ := android.SplitFileExt(file)
433	entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
434	entries.SetString("LOCAL_MODULE_PATH", path)
435	entries.SetString("LOCAL_MODULE_STEM", stem)
436	entries.SetBool("LOCAL_NO_NOTICE_FILE", true)
437	if c.parsedCoverageXmlPath.String() != "" {
438		entries.SetString("SOONG_NDK_API_XML", "$(SOONG_NDK_API_XML) "+c.parsedCoverageXmlPath.String())
439	}
440	entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true) // Stubs should not be installed
441}
442
443func (c *vndkPrebuiltLibraryDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
444	entries.Class = "SHARED_LIBRARIES"
445
446	entries.SubName = c.androidMkSuffix
447
448	c.libraryDecorator.androidMkWriteExportedFlags(entries)
449
450	// Specifying stem is to pass check_elf_files when vendor modules link against vndk prebuilt.
451	// We can't use install path because VNDKs are not installed. Instead, Srcs is directly used.
452	_, file := filepath.Split(c.properties.Srcs[0])
453	stem, suffix, ext := android.SplitFileExt(file)
454	entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext)
455	entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
456	entries.SetString("LOCAL_MODULE_STEM", stem)
457
458	if c.tocFile.Valid() {
459		entries.SetString("LOCAL_SOONG_TOC", c.tocFile.String())
460	}
461
462	// VNDK libraries available to vendor are not installed because
463	// they are packaged in VNDK APEX and installed by APEX packages (apex/apex.go)
464	entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
465}
466
467func (p *prebuiltLinker) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
468	if p.properties.Check_elf_files != nil {
469		entries.SetBool("LOCAL_CHECK_ELF_FILES", *p.properties.Check_elf_files)
470	} else {
471		// soong_cc_rust_prebuilt.mk does not include check_elf_file.mk by default
472		// because cc_library_shared and cc_binary use soong_cc_rust_prebuilt.mk as well.
473		// In order to turn on prebuilt ABI checker, set `LOCAL_CHECK_ELF_FILES` to
474		// true if `p.properties.Check_elf_files` is not specified.
475		entries.SetBool("LOCAL_CHECK_ELF_FILES", true)
476	}
477}
478
479func (p *prebuiltLibraryLinker) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
480	ctx.subAndroidMk(config, entries, p.libraryDecorator)
481	if p.shared() {
482		ctx.subAndroidMk(config, entries, &p.prebuiltLinker)
483		androidMkWritePrebuiltOptions(p.baseLinker, entries)
484	}
485}
486
487func (p *prebuiltBinaryLinker) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
488	ctx.subAndroidMk(config, entries, p.binaryDecorator)
489	ctx.subAndroidMk(config, entries, &p.prebuiltLinker)
490	androidMkWritePrebuiltOptions(p.baseLinker, entries)
491}
492
493func androidMkWritePrebuiltOptions(linker *baseLinker, entries *android.AndroidMkInfo) {
494	allow := linker.Properties.Allow_undefined_symbols
495	if allow != nil {
496		entries.SetBool("LOCAL_ALLOW_UNDEFINED_SYMBOLS", *allow)
497	}
498	ignore := linker.Properties.Ignore_max_page_size
499	if ignore != nil {
500		entries.SetBool("LOCAL_IGNORE_MAX_PAGE_SIZE", *ignore)
501	}
502}
503