xref: /aosp_15_r20/build/soong/cc/vndk_prebuilt.go (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
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	"strings"
19
20	"android/soong/android"
21)
22
23var (
24	vndkSuffix     = ".vndk."
25	binder32Suffix = ".binder32"
26)
27
28// Creates vndk prebuilts that include the VNDK version.
29//
30// Example:
31//
32//	vndk_prebuilt_shared {
33//	    name: "libfoo",
34//	    version: "27",
35//	    target_arch: "arm64",
36//	    vendor_available: true,
37//	    product_available: true,
38//	    vndk: {
39//	        enabled: true,
40//	    },
41//	    export_include_dirs: ["include/external/libfoo/vndk_include"],
42//	    arch: {
43//	        arm64: {
44//	            srcs: ["arm/lib64/libfoo.so"],
45//	        },
46//	        arm: {
47//	            srcs: ["arm/lib/libfoo.so"],
48//	        },
49//	    },
50//	}
51type vndkPrebuiltProperties struct {
52	VndkProperties
53
54	// VNDK snapshot version.
55	Version *string
56
57	// Target arch name of the snapshot (e.g. 'arm64' for variant 'aosp_arm64')
58	Target_arch *string
59
60	// If the prebuilt snapshot lib is built with 32 bit binder, this must be set to true.
61	// The lib with 64 bit binder does not need to set this property.
62	Binder32bit *bool
63
64	// Prebuilt files for each arch.
65	Srcs []string `android:"arch_variant"`
66
67	// list of flags that will be used for any module that links against this module.
68	Export_flags []string `android:"arch_variant"`
69
70	// Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined symbols,
71	// etc).
72	Check_elf_files *bool
73}
74
75type vndkPrebuiltLibraryDecorator struct {
76	*libraryDecorator
77	properties      vndkPrebuiltProperties
78	androidMkSuffix string
79}
80
81func (p *vndkPrebuiltLibraryDecorator) Name(name string) string {
82	return name + p.NameSuffix()
83}
84
85func (p *vndkPrebuiltLibraryDecorator) NameSuffix() string {
86	suffix := p.Version()
87	if p.arch() != "" {
88		suffix += "." + p.arch()
89	}
90	if Bool(p.properties.Binder32bit) {
91		suffix += binder32Suffix
92	}
93	return vndkSuffix + suffix
94}
95
96func (p *vndkPrebuiltLibraryDecorator) Version() string {
97	return String(p.properties.Version)
98}
99
100func (p *vndkPrebuiltLibraryDecorator) arch() string {
101	return String(p.properties.Target_arch)
102}
103
104func (p *vndkPrebuiltLibraryDecorator) binderBit() string {
105	if Bool(p.properties.Binder32bit) {
106		return "32"
107	}
108	return "64"
109}
110
111func (p *vndkPrebuiltLibraryDecorator) SnapshotAndroidMkSuffix() string {
112	return ".vendor"
113}
114
115func (p *vndkPrebuiltLibraryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
116	p.libraryDecorator.libName = strings.TrimSuffix(ctx.ModuleName(), p.NameSuffix())
117	return p.libraryDecorator.linkerFlags(ctx, flags)
118}
119
120func (p *vndkPrebuiltLibraryDecorator) singleSourcePath(ctx ModuleContext) android.Path {
121	if len(p.properties.Srcs) == 0 {
122		ctx.PropertyErrorf("srcs", "missing prebuilt source file")
123		return nil
124	}
125
126	if len(p.properties.Srcs) > 1 {
127		ctx.PropertyErrorf("srcs", "multiple prebuilt source files")
128		return nil
129	}
130
131	return android.PathForModuleSrc(ctx, p.properties.Srcs[0])
132}
133
134func (p *vndkPrebuiltLibraryDecorator) link(ctx ModuleContext,
135	flags Flags, deps PathDeps, objs Objects) android.Path {
136	if !p.MatchesWithDevice(ctx.DeviceConfig()) {
137		ctx.Module().HideFromMake()
138		return nil
139	}
140
141	if len(p.properties.Srcs) > 0 && p.shared() {
142		p.libraryDecorator.exportIncludes(ctx)
143		p.libraryDecorator.reexportFlags(p.properties.Export_flags...)
144		// current VNDK prebuilts are only shared libs.
145
146		in := p.singleSourcePath(ctx)
147		p.unstrippedOutputFile = in
148		libName := in.Base()
149		if p.stripper.NeedsStrip(ctx) {
150			stripFlags := flagsToStripFlags(flags)
151			stripped := android.PathForModuleOut(ctx, "stripped", libName)
152			p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, stripFlags)
153			in = stripped
154		}
155
156		// Optimize out relinking against shared libraries whose interface hasn't changed by
157		// depending on a table of contents file instead of the library itself.
158		tocFile := android.PathForModuleOut(ctx, libName+".toc")
159		p.tocFile = android.OptionalPathForPath(tocFile)
160		TransformSharedObjectToToc(ctx, in, tocFile)
161
162		p.androidMkSuffix = p.NameSuffix()
163
164		android.SetProvider(ctx, SharedLibraryInfoProvider, SharedLibraryInfo{
165			SharedLibrary: in,
166			Target:        ctx.Target(),
167
168			TableOfContents: p.tocFile,
169			IsStubs:         false,
170		})
171
172		p.libraryDecorator.flagExporter.setProvider(ctx)
173
174		return in
175	}
176
177	ctx.Module().HideFromMake()
178	return nil
179}
180
181func (p *vndkPrebuiltLibraryDecorator) moduleInfoJSON(ctx ModuleContext, moduleInfoJSON *android.ModuleInfoJSON) {
182	p.libraryDecorator.moduleInfoJSON(ctx, moduleInfoJSON)
183	moduleInfoJSON.SubName += p.androidMkSuffix
184}
185
186func (p *vndkPrebuiltLibraryDecorator) MatchesWithDevice(config android.DeviceConfig) bool {
187	arches := config.Arches()
188	if len(arches) == 0 || arches[0].ArchType.String() != p.arch() {
189		return false
190	}
191	if config.BinderBitness() != p.binderBit() {
192		return false
193	}
194	if len(p.properties.Srcs) == 0 {
195		return false
196	}
197	return true
198}
199
200func (p *vndkPrebuiltLibraryDecorator) nativeCoverage() bool {
201	return false
202}
203
204func (p *vndkPrebuiltLibraryDecorator) IsSnapshotPrebuilt() bool {
205	return true
206}
207
208func (p *vndkPrebuiltLibraryDecorator) install(ctx ModuleContext, file android.Path) {
209	// do not install vndk libs
210}
211
212func vndkPrebuiltSharedLibrary() *Module {
213	module, library := NewLibrary(android.DeviceSupported)
214	library.BuildOnlyShared()
215	module.stl = nil
216	module.sanitize = nil
217	library.disableStripping()
218
219	prebuilt := &vndkPrebuiltLibraryDecorator{
220		libraryDecorator: library,
221	}
222
223	prebuilt.properties.Check_elf_files = BoolPtr(false)
224	prebuilt.baseLinker.Properties.No_libcrt = BoolPtr(true)
225	prebuilt.baseLinker.Properties.Nocrt = BoolPtr(true)
226	prebuilt.baseLinker.Properties.No_crt_pad_segment = BoolPtr(true)
227
228	// Prevent default system libs (libc, libm, and libdl) from being linked
229	if prebuilt.baseLinker.Properties.System_shared_libs == nil {
230		prebuilt.baseLinker.Properties.System_shared_libs = []string{}
231	}
232
233	module.compiler = nil
234	module.linker = prebuilt
235	module.installer = prebuilt
236
237	module.AddProperties(
238		&prebuilt.properties,
239	)
240
241	return module
242}
243
244// vndk_prebuilt_shared installs Vendor Native Development kit (VNDK) snapshot
245// shared libraries for system build. Example:
246//
247//	vndk_prebuilt_shared {
248//	    name: "libfoo",
249//	    version: "27",
250//	    target_arch: "arm64",
251//	    vendor_available: true,
252//	    product_available: true,
253//	    vndk: {
254//	        enabled: true,
255//	    },
256//	    export_include_dirs: ["include/external/libfoo/vndk_include"],
257//	    arch: {
258//	        arm64: {
259//	            srcs: ["arm/lib64/libfoo.so"],
260//	        },
261//	        arm: {
262//	            srcs: ["arm/lib/libfoo.so"],
263//	        },
264//	    },
265//	}
266func VndkPrebuiltSharedFactory() android.Module {
267	module := vndkPrebuiltSharedLibrary()
268	return module.Init()
269}
270
271func init() {
272	android.RegisterModuleType("vndk_prebuilt_shared", VndkPrebuiltSharedFactory)
273}
274
275func IsForVndkApex(mctx android.BottomUpMutatorContext, m *Module) bool {
276	if !m.Enabled(mctx) {
277		return true
278	}
279
280	if p, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok {
281		return p.MatchesWithDevice(mctx.DeviceConfig()) && Bool(p.properties.Vndk.Enabled)
282	}
283	return false
284}
285