• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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	library.androidMkWriteExportedFlags(entries)
248	library.androidMkEntriesWriteAdditionalDependenciesForSourceAbiDiff(entries)
249
250	if entries.OutputFile.Valid() {
251		_, _, ext := android.SplitFileExt(entries.OutputFile.Path().Base())
252		entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext)
253	}
254
255	if library.coverageOutputFile.Valid() {
256		entries.SetString("LOCAL_PREBUILT_COVERAGE_ARCHIVE", library.coverageOutputFile.String())
257	}
258
259	if library.shared() && !library.BuildStubs() {
260		ctx.subAndroidMk(config, entries, library.baseInstaller)
261	} else {
262		if library.BuildStubs() && library.StubsVersion() != "" {
263			entries.SubName = "." + library.StubsVersion()
264		}
265		// library.makeUninstallable() depends on this to bypass HideFromMake() for
266		// static libraries.
267		entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
268		if library.BuildStubs() {
269			entries.SetBool("LOCAL_NO_NOTICE_FILE", true)
270		}
271	}
272	// If a library providing a stub is included in an APEX, the private APIs of the library
273	// is accessible only inside the APEX. From outside of the APEX, clients can only use the
274	// public APIs via the stub. To enforce this, the (latest version of the) stub gets the
275	// name of the library. The impl library instead gets the `.bootstrap` suffix to so that
276	// they can be exceptionally used directly when APEXes are not available (e.g. during the
277	// very early stage in the boot process).
278	if len(library.Properties.Stubs.Versions) > 0 && !ctx.Host() && ctx.NotInPlatform() &&
279		!ctx.InRamdisk() && !ctx.InVendorRamdisk() && !ctx.InRecovery() && !ctx.InVendorOrProduct() && !ctx.static() {
280		if library.BuildStubs() && library.isLatestStubVersion() {
281			entries.SubName = ""
282		}
283		if !library.BuildStubs() {
284			entries.SubName = ".bootstrap"
285		}
286	}
287}
288
289func (object *objectLinker) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
290	entries.Class = "STATIC_LIBRARIES"
291}
292
293func (object *objectLinker) prepareAndroidMKFooterInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
294	out := entries.OutputFile.Path()
295	name := ctx.BaseModuleName()
296	if entries.OverrideName != "" {
297		name = entries.OverrideName
298	}
299
300	prefix := ""
301	if ctx.ArchSpecific() {
302		switch ctx.Os().Class {
303		case android.Host:
304			if ctx.Target().HostCross {
305				prefix = "HOST_CROSS_"
306			} else {
307				prefix = "HOST_"
308			}
309		case android.Device:
310			prefix = "TARGET_"
311
312		}
313
314		if ctx.Arch().ArchType != config.Targets[ctx.Os()][0].Arch.ArchType {
315			prefix = "2ND_" + prefix
316		}
317	}
318
319	varname := fmt.Sprintf("SOONG_%sOBJECT_%s%s", prefix, name, entries.SubName)
320
321	entries.FooterStrings = append(entries.FooterStrings,
322		fmt.Sprintf("\n%s := %s\n.KATI_READONLY: %s", varname, out.String(), varname))
323}
324
325func (test *testDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
326	if len(test.InstallerProperties.Test_suites) > 0 {
327		entries.AddCompatibilityTestSuites(test.InstallerProperties.Test_suites...)
328	}
329}
330
331func (binary *binaryDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
332	ctx.subAndroidMk(config, entries, binary.baseInstaller)
333
334	entries.Class = "EXECUTABLES"
335	entries.SetString("LOCAL_SOONG_UNSTRIPPED_BINARY", binary.unstrippedOutputFile.String())
336	if len(binary.symlinks) > 0 {
337		entries.AddStrings("LOCAL_MODULE_SYMLINKS", binary.symlinks...)
338	}
339
340	if binary.coverageOutputFile.Valid() {
341		entries.SetString("LOCAL_PREBUILT_COVERAGE_ARCHIVE", binary.coverageOutputFile.String())
342	}
343
344	if len(binary.Properties.Overrides) > 0 {
345		entries.SetString("LOCAL_OVERRIDES_MODULES", strings.Join(makeOverrideModuleNames(ctx, binary.Properties.Overrides), " "))
346	}
347	if len(binary.postInstallCmds) > 0 {
348		entries.SetString("LOCAL_POST_INSTALL_CMD", strings.Join(binary.postInstallCmds, "&& "))
349	}
350}
351
352func (benchmark *benchmarkDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
353	ctx.subAndroidMk(config, entries, benchmark.binaryDecorator)
354	entries.Class = "NATIVE_TESTS"
355	if len(benchmark.Properties.Test_suites) > 0 {
356		entries.AddCompatibilityTestSuites(benchmark.Properties.Test_suites...)
357	}
358	if benchmark.testConfig != nil {
359		entries.SetString("LOCAL_FULL_TEST_CONFIG", benchmark.testConfig.String())
360	}
361	entries.SetBool("LOCAL_NATIVE_BENCHMARK", true)
362	if !BoolDefault(benchmark.Properties.Auto_gen_config, true) {
363		entries.SetBool("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", true)
364	}
365}
366
367func (test *testBinary) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
368	ctx.subAndroidMk(config, entries, test.binaryDecorator)
369	ctx.subAndroidMk(config, entries, test.testDecorator)
370
371	entries.Class = "NATIVE_TESTS"
372	if test.testConfig != nil {
373		entries.SetString("LOCAL_FULL_TEST_CONFIG", test.testConfig.String())
374	}
375	if !BoolDefault(test.Properties.Auto_gen_config, true) {
376		entries.SetBool("LOCAL_DISABLE_AUTO_GENERATE_TEST_CONFIG", true)
377	}
378	entries.AddStrings("LOCAL_TEST_MAINLINE_MODULES", test.Properties.Test_mainline_modules...)
379
380	entries.SetBoolIfTrue("LOCAL_COMPATIBILITY_PER_TESTCASE_DIRECTORY", Bool(test.Properties.Per_testcase_directory))
381	if len(test.Properties.Data_bins) > 0 {
382		entries.AddStrings("LOCAL_TEST_DATA_BINS", test.Properties.Data_bins...)
383	}
384
385	test.Properties.Test_options.CommonTestOptions.SetAndroidMkInfoEntries(entries)
386
387	androidMkWriteExtraTestConfigs(test.extraTestConfigs, entries)
388}
389
390func (fuzz *fuzzBinary) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
391	ctx.subAndroidMk(config, entries, fuzz.binaryDecorator)
392
393	entries.SetBool("LOCAL_IS_FUZZ_TARGET", true)
394	if fuzz.installedSharedDeps != nil {
395		// TOOD: move to install dep
396		entries.AddStrings("LOCAL_FUZZ_INSTALLED_SHARED_DEPS", fuzz.installedSharedDeps...)
397	}
398}
399
400func (test *testLibrary) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
401	ctx.subAndroidMk(config, entries, test.libraryDecorator)
402	ctx.subAndroidMk(config, entries, test.testDecorator)
403}
404
405func (installer *baseInstaller) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
406	if installer.path == (android.InstallPath{}) {
407		return
408	}
409
410	path, file := filepath.Split(installer.path.String())
411	stem, suffix, _ := android.SplitFileExt(file)
412	entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
413	entries.SetString("LOCAL_MODULE_PATH", path)
414	entries.SetString("LOCAL_MODULE_STEM", stem)
415}
416
417func (c *stubDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
418	entries.SubName = ndkLibrarySuffix + "." + c.apiLevel.String()
419	entries.Class = "SHARED_LIBRARIES"
420
421	if !c.BuildStubs() {
422		entries.Disabled = true
423		return
424	}
425
426	path, file := filepath.Split(c.installPath.String())
427	stem, suffix, _ := android.SplitFileExt(file)
428	entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
429	entries.SetString("LOCAL_MODULE_PATH", path)
430	entries.SetString("LOCAL_MODULE_STEM", stem)
431	entries.SetBool("LOCAL_NO_NOTICE_FILE", true)
432	if c.parsedCoverageXmlPath.String() != "" {
433		entries.SetString("SOONG_NDK_API_XML", "$(SOONG_NDK_API_XML) "+c.parsedCoverageXmlPath.String())
434	}
435	entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true) // Stubs should not be installed
436}
437
438func (c *vndkPrebuiltLibraryDecorator) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
439	entries.Class = "SHARED_LIBRARIES"
440
441	entries.SubName = c.androidMkSuffix
442
443	c.libraryDecorator.androidMkWriteExportedFlags(entries)
444
445	// Specifying stem is to pass check_elf_files when vendor modules link against vndk prebuilt.
446	// We can't use install path because VNDKs are not installed. Instead, Srcs is directly used.
447	_, file := filepath.Split(c.properties.Srcs[0])
448	stem, suffix, ext := android.SplitFileExt(file)
449	entries.SetString("LOCAL_BUILT_MODULE_STEM", "$(LOCAL_MODULE)"+ext)
450	entries.SetString("LOCAL_MODULE_SUFFIX", suffix)
451	entries.SetString("LOCAL_MODULE_STEM", stem)
452
453	if c.tocFile.Valid() {
454		entries.SetString("LOCAL_SOONG_TOC", c.tocFile.String())
455	}
456
457	// VNDK libraries available to vendor are not installed because
458	// they are packaged in VNDK APEX and installed by APEX packages (apex/apex.go)
459	entries.SetBool("LOCAL_UNINSTALLABLE_MODULE", true)
460}
461
462func (p *prebuiltLinker) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
463	if p.properties.Check_elf_files != nil {
464		entries.SetBool("LOCAL_CHECK_ELF_FILES", *p.properties.Check_elf_files)
465	} else {
466		// soong_cc_rust_prebuilt.mk does not include check_elf_file.mk by default
467		// because cc_library_shared and cc_binary use soong_cc_rust_prebuilt.mk as well.
468		// In order to turn on prebuilt ABI checker, set `LOCAL_CHECK_ELF_FILES` to
469		// true if `p.properties.Check_elf_files` is not specified.
470		entries.SetBool("LOCAL_CHECK_ELF_FILES", true)
471	}
472}
473
474func (p *prebuiltLibraryLinker) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
475	ctx.subAndroidMk(config, entries, p.libraryDecorator)
476	if p.shared() {
477		ctx.subAndroidMk(config, entries, &p.prebuiltLinker)
478		androidMkWritePrebuiltOptions(p.baseLinker, entries)
479	}
480}
481
482func (p *prebuiltBinaryLinker) prepareAndroidMKProviderInfo(config android.Config, ctx AndroidMkContext, entries *android.AndroidMkInfo) {
483	ctx.subAndroidMk(config, entries, p.binaryDecorator)
484	ctx.subAndroidMk(config, entries, &p.prebuiltLinker)
485	androidMkWritePrebuiltOptions(p.baseLinker, entries)
486}
487
488func androidMkWritePrebuiltOptions(linker *baseLinker, entries *android.AndroidMkInfo) {
489	allow := linker.Properties.Allow_undefined_symbols
490	if allow != nil {
491		entries.SetBool("LOCAL_ALLOW_UNDEFINED_SYMBOLS", *allow)
492	}
493	ignore := linker.Properties.Ignore_max_page_size
494	if ignore != nil {
495		entries.SetBool("LOCAL_IGNORE_MAX_PAGE_SIZE", *ignore)
496	}
497}
498