1// Copyright 2016 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	"android/soong/android"
19)
20
21func init() {
22	RegisterPrebuiltBuildComponents(android.InitRegistrationContext)
23}
24
25func RegisterPrebuiltBuildComponents(ctx android.RegistrationContext) {
26	ctx.RegisterModuleType("cc_prebuilt_library", PrebuiltLibraryFactory)
27	ctx.RegisterModuleType("cc_prebuilt_library_shared", PrebuiltSharedLibraryFactory)
28	ctx.RegisterModuleType("cc_prebuilt_library_static", PrebuiltStaticLibraryFactory)
29	ctx.RegisterModuleType("cc_prebuilt_test_library_shared", PrebuiltSharedTestLibraryFactory)
30	ctx.RegisterModuleType("cc_prebuilt_object", prebuiltObjectFactory)
31	ctx.RegisterModuleType("cc_prebuilt_binary", prebuiltBinaryFactory)
32}
33
34type prebuiltLinkerInterface interface {
35	Name(string) string
36	prebuilt() *android.Prebuilt
37}
38
39type prebuiltLinkerProperties struct {
40
41	// a prebuilt library or binary. Can reference a genrule module that generates an executable file.
42	Srcs []string `android:"path,arch_variant"`
43
44	// Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined
45	// symbols, etc), default true.
46	Check_elf_files *bool
47
48	// Optionally provide an import library if this is a Windows PE DLL prebuilt.
49	// This is needed only if this library is linked by other modules in build time.
50	// Only makes sense for the Windows target.
51	Windows_import_lib *string `android:"path,arch_variant"`
52}
53
54type prebuiltLinker struct {
55	android.Prebuilt
56
57	properties prebuiltLinkerProperties
58}
59
60func (p *prebuiltLinker) prebuilt() *android.Prebuilt {
61	return &p.Prebuilt
62}
63
64func (p *prebuiltLinker) PrebuiltSrcs() []string {
65	return p.properties.Srcs
66}
67
68type prebuiltLibraryInterface interface {
69	libraryInterface
70	prebuiltLinkerInterface
71	disablePrebuilt()
72}
73
74type prebuiltLibraryLinker struct {
75	*libraryDecorator
76	prebuiltLinker
77}
78
79var _ prebuiltLinkerInterface = (*prebuiltLibraryLinker)(nil)
80var _ prebuiltLibraryInterface = (*prebuiltLibraryLinker)(nil)
81
82func (p *prebuiltLibraryLinker) linkerInit(ctx BaseModuleContext) {}
83
84func (p *prebuiltLibraryLinker) linkerDeps(ctx DepsContext, deps Deps) Deps {
85	return p.libraryDecorator.linkerDeps(ctx, deps)
86}
87
88func (p *prebuiltLibraryLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
89	return flags
90}
91
92func (p *prebuiltLibraryLinker) linkerProps() []interface{} {
93	return p.libraryDecorator.linkerProps()
94}
95
96func (p *prebuiltLibraryLinker) link(ctx ModuleContext,
97	flags Flags, deps PathDeps, objs Objects) android.Path {
98
99	p.libraryDecorator.exportIncludes(ctx)
100	p.libraryDecorator.reexportDirs(deps.ReexportedDirs...)
101	p.libraryDecorator.reexportSystemDirs(deps.ReexportedSystemDirs...)
102	p.libraryDecorator.reexportFlags(deps.ReexportedFlags...)
103	p.libraryDecorator.reexportDeps(deps.ReexportedDeps...)
104	p.libraryDecorator.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
105
106	// TODO(ccross): verify shared library dependencies
107	srcs := p.prebuiltSrcs()
108	if len(srcs) > 0 {
109		builderFlags := flagsToBuilderFlags(flags)
110
111		if len(srcs) > 1 {
112			ctx.PropertyErrorf("srcs", "multiple prebuilt source files")
113			return nil
114		}
115
116		in := android.PathForModuleSrc(ctx, srcs[0])
117
118		if p.static() {
119			return in
120		}
121
122		if p.shared() {
123			p.unstrippedOutputFile = in
124			libName := p.libraryDecorator.getLibName(ctx) + flags.Toolchain.ShlibSuffix()
125			outputFile := android.PathForModuleOut(ctx, libName)
126			var implicits android.Paths
127
128			if p.needsStrip(ctx) {
129				stripped := android.PathForModuleOut(ctx, "stripped", libName)
130				p.stripExecutableOrSharedLib(ctx, in, stripped, builderFlags)
131				in = stripped
132			}
133
134			// Optimize out relinking against shared libraries whose interface hasn't changed by
135			// depending on a table of contents file instead of the library itself.
136			tocFile := android.PathForModuleOut(ctx, libName+".toc")
137			p.tocFile = android.OptionalPathForPath(tocFile)
138			TransformSharedObjectToToc(ctx, outputFile, tocFile, builderFlags)
139
140			if ctx.Windows() && p.properties.Windows_import_lib != nil {
141				// Consumers of this library actually links to the import library in build
142				// time and dynamically links to the DLL in run time. i.e.
143				// a.exe <-- static link --> foo.lib <-- dynamic link --> foo.dll
144				importLibSrc := android.PathForModuleSrc(ctx, String(p.properties.Windows_import_lib))
145				importLibName := p.libraryDecorator.getLibName(ctx) + ".lib"
146				importLibOutputFile := android.PathForModuleOut(ctx, importLibName)
147				implicits = append(implicits, importLibOutputFile)
148
149				ctx.Build(pctx, android.BuildParams{
150					Rule:        android.Cp,
151					Description: "prebuilt import library",
152					Input:       importLibSrc,
153					Output:      importLibOutputFile,
154					Args: map[string]string{
155						"cpFlags": "-L",
156					},
157				})
158			}
159
160			ctx.Build(pctx, android.BuildParams{
161				Rule:        android.Cp,
162				Description: "prebuilt shared library",
163				Implicits:   implicits,
164				Input:       in,
165				Output:      outputFile,
166				Args: map[string]string{
167					"cpFlags": "-L",
168				},
169			})
170
171			return outputFile
172		}
173	}
174
175	return nil
176}
177
178func (p *prebuiltLibraryLinker) prebuiltSrcs() []string {
179	srcs := p.properties.Srcs
180	if p.static() {
181		srcs = append(srcs, p.libraryDecorator.StaticProperties.Static.Srcs...)
182	}
183	if p.shared() {
184		srcs = append(srcs, p.libraryDecorator.SharedProperties.Shared.Srcs...)
185	}
186
187	return srcs
188}
189
190func (p *prebuiltLibraryLinker) shared() bool {
191	return p.libraryDecorator.shared()
192}
193
194func (p *prebuiltLibraryLinker) nativeCoverage() bool {
195	return false
196}
197
198func (p *prebuiltLibraryLinker) disablePrebuilt() {
199	p.properties.Srcs = nil
200}
201
202func (p *prebuiltLibraryLinker) skipInstall(mod *Module) {
203	mod.ModuleBase.SkipInstall()
204}
205
206func NewPrebuiltLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
207	module, library := NewLibrary(hod)
208	module.compiler = nil
209
210	prebuilt := &prebuiltLibraryLinker{
211		libraryDecorator: library,
212	}
213	module.linker = prebuilt
214	module.installer = prebuilt
215
216	module.AddProperties(&prebuilt.properties)
217
218	srcsSupplier := func() []string {
219		return prebuilt.prebuiltSrcs()
220	}
221
222	android.InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, "srcs")
223
224	// Prebuilt libraries can be used in SDKs.
225	android.InitSdkAwareModule(module)
226	return module, library
227}
228
229// cc_prebuilt_library installs a precompiled shared library that are
230// listed in the srcs property in the device's directory.
231func PrebuiltLibraryFactory() android.Module {
232	module, _ := NewPrebuiltLibrary(android.HostAndDeviceSupported)
233
234	// Prebuilt shared libraries can be included in APEXes
235	android.InitApexModule(module)
236
237	return module.Init()
238}
239
240// cc_prebuilt_library_shared installs a precompiled shared library that are
241// listed in the srcs property in the device's directory.
242func PrebuiltSharedLibraryFactory() android.Module {
243	module, _ := NewPrebuiltSharedLibrary(android.HostAndDeviceSupported)
244	return module.Init()
245}
246
247// cc_prebuilt_test_library_shared installs a precompiled shared library
248// to be used as a data dependency of a test-related module (such as cc_test, or
249// cc_test_library).
250func PrebuiltSharedTestLibraryFactory() android.Module {
251	module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported)
252	library.BuildOnlyShared()
253	library.baseInstaller = NewTestInstaller()
254	return module.Init()
255}
256
257func NewPrebuiltSharedLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
258	module, library := NewPrebuiltLibrary(hod)
259	library.BuildOnlyShared()
260
261	// Prebuilt shared libraries can be included in APEXes
262	android.InitApexModule(module)
263
264	return module, library
265}
266
267// cc_prebuilt_library_static installs a precompiled static library that are
268// listed in the srcs property in the device's directory.
269func PrebuiltStaticLibraryFactory() android.Module {
270	module, _ := NewPrebuiltStaticLibrary(android.HostAndDeviceSupported)
271	return module.Init()
272}
273
274func NewPrebuiltStaticLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
275	module, library := NewPrebuiltLibrary(hod)
276	library.BuildOnlyStatic()
277	return module, library
278}
279
280type prebuiltObjectProperties struct {
281	Srcs []string `android:"path,arch_variant"`
282}
283
284type prebuiltObjectLinker struct {
285	android.Prebuilt
286	objectLinker
287
288	properties prebuiltObjectProperties
289}
290
291func (p *prebuiltObjectLinker) prebuilt() *android.Prebuilt {
292	return &p.Prebuilt
293}
294
295var _ prebuiltLinkerInterface = (*prebuiltObjectLinker)(nil)
296
297func (p *prebuiltObjectLinker) link(ctx ModuleContext,
298	flags Flags, deps PathDeps, objs Objects) android.Path {
299	if len(p.properties.Srcs) > 0 {
300		return p.Prebuilt.SingleSourcePath(ctx)
301	}
302	return nil
303}
304
305func (p *prebuiltObjectLinker) object() bool {
306	return true
307}
308
309func newPrebuiltObject() *Module {
310	module := newObject()
311	prebuilt := &prebuiltObjectLinker{
312		objectLinker: objectLinker{
313			baseLinker: NewBaseLinker(nil),
314		},
315	}
316	module.linker = prebuilt
317	module.AddProperties(&prebuilt.properties)
318	android.InitPrebuiltModule(module, &prebuilt.properties.Srcs)
319	android.InitSdkAwareModule(module)
320	return module
321}
322
323func prebuiltObjectFactory() android.Module {
324	module := newPrebuiltObject()
325	return module.Init()
326}
327
328type prebuiltBinaryLinker struct {
329	*binaryDecorator
330	prebuiltLinker
331}
332
333var _ prebuiltLinkerInterface = (*prebuiltBinaryLinker)(nil)
334
335func (p *prebuiltBinaryLinker) link(ctx ModuleContext,
336	flags Flags, deps PathDeps, objs Objects) android.Path {
337	// TODO(ccross): verify shared library dependencies
338	if len(p.properties.Srcs) > 0 {
339		builderFlags := flagsToBuilderFlags(flags)
340
341		fileName := p.getStem(ctx) + flags.Toolchain.ExecutableSuffix()
342		in := p.Prebuilt.SingleSourcePath(ctx)
343
344		p.unstrippedOutputFile = in
345
346		if p.needsStrip(ctx) {
347			stripped := android.PathForModuleOut(ctx, "stripped", fileName)
348			p.stripExecutableOrSharedLib(ctx, in, stripped, builderFlags)
349			in = stripped
350		}
351
352		// Copy binaries to a name matching the final installed name
353		outputFile := android.PathForModuleOut(ctx, fileName)
354		ctx.Build(pctx, android.BuildParams{
355			Rule:        android.CpExecutable,
356			Description: "prebuilt",
357			Output:      outputFile,
358			Input:       in,
359		})
360
361		return outputFile
362	}
363
364	return nil
365}
366
367func (p *prebuiltBinaryLinker) binary() bool {
368	return true
369}
370
371// cc_prebuilt_binary installs a precompiled executable in srcs property in the
372// device's directory.
373func prebuiltBinaryFactory() android.Module {
374	module, _ := NewPrebuiltBinary(android.HostAndDeviceSupported)
375	return module.Init()
376}
377
378func NewPrebuiltBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) {
379	module, binary := NewBinary(hod)
380	module.compiler = nil
381
382	prebuilt := &prebuiltBinaryLinker{
383		binaryDecorator: binary,
384	}
385	module.linker = prebuilt
386
387	module.AddProperties(&prebuilt.properties)
388
389	android.InitPrebuiltModule(module, &prebuilt.properties.Srcs)
390	return module, binary
391}
392