• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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	"path/filepath"
19
20	"android/soong/android"
21	"android/soong/bazel"
22	"android/soong/bazel/cquery"
23)
24
25func init() {
26	RegisterPrebuiltBuildComponents(android.InitRegistrationContext)
27}
28
29func RegisterPrebuiltBuildComponents(ctx android.RegistrationContext) {
30	ctx.RegisterModuleType("cc_prebuilt_library", PrebuiltLibraryFactory)
31	ctx.RegisterModuleType("cc_prebuilt_library_shared", PrebuiltSharedLibraryFactory)
32	ctx.RegisterModuleType("cc_prebuilt_library_static", PrebuiltStaticLibraryFactory)
33	ctx.RegisterModuleType("cc_prebuilt_test_library_shared", PrebuiltSharedTestLibraryFactory)
34	ctx.RegisterModuleType("cc_prebuilt_object", PrebuiltObjectFactory)
35	ctx.RegisterModuleType("cc_prebuilt_binary", PrebuiltBinaryFactory)
36}
37
38type prebuiltLinkerInterface interface {
39	Name(string) string
40	prebuilt() *android.Prebuilt
41}
42
43type prebuiltLinkerProperties struct {
44	// a prebuilt library or binary. Can reference a genrule module that generates an executable file.
45	Srcs []string `android:"path,arch_variant"`
46
47	Sanitized Sanitized `android:"arch_variant"`
48
49	// Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined
50	// symbols, etc), default true.
51	Check_elf_files *bool
52
53	// if set, add an extra objcopy --prefix-symbols= step
54	Prefix_symbols *string
55
56	// Optionally provide an import library if this is a Windows PE DLL prebuilt.
57	// This is needed only if this library is linked by other modules in build time.
58	// Only makes sense for the Windows target.
59	Windows_import_lib *string `android:"path,arch_variant"`
60
61	// MixedBuildsDisabled is true if and only if building this prebuilt is explicitly disabled in mixed builds for either
62	// its static or shared version on the current build variant. This is to prevent Bazel targets for build variants with
63	// which either the static or shared version is incompatible from participating in mixed buiods. Please note that this
64	// is an override and does not fully determine whether Bazel or Soong will be used. For the full determination, see
65	// cc.ProcessBazelQueryResponse, cc.QueueBazelCall, and cc.MixedBuildsDisabled.
66	MixedBuildsDisabled bool `blueprint:"mutated"`
67}
68
69type prebuiltLinker struct {
70	android.Prebuilt
71
72	properties prebuiltLinkerProperties
73}
74
75func (p *prebuiltLinker) prebuilt() *android.Prebuilt {
76	return &p.Prebuilt
77}
78
79func (p *prebuiltLinker) PrebuiltSrcs() []string {
80	return p.properties.Srcs
81}
82
83type prebuiltLibraryInterface interface {
84	libraryInterface
85	prebuiltLinkerInterface
86	disablePrebuilt()
87}
88
89type prebuiltLibraryLinker struct {
90	*libraryDecorator
91	prebuiltLinker
92}
93
94var _ prebuiltLinkerInterface = (*prebuiltLibraryLinker)(nil)
95var _ prebuiltLibraryInterface = (*prebuiltLibraryLinker)(nil)
96
97func (p *prebuiltLibraryLinker) linkerInit(ctx BaseModuleContext) {}
98
99func (p *prebuiltLibraryLinker) linkerDeps(ctx DepsContext, deps Deps) Deps {
100	return p.libraryDecorator.linkerDeps(ctx, deps)
101}
102
103func (p *prebuiltLibraryLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags {
104	return flags
105}
106
107func (p *prebuiltLibraryLinker) linkerProps() []interface{} {
108	return p.libraryDecorator.linkerProps()
109}
110
111func (p *prebuiltLibraryLinker) link(ctx ModuleContext,
112	flags Flags, deps PathDeps, objs Objects) android.Path {
113
114	p.libraryDecorator.flagExporter.exportIncludes(ctx)
115	p.libraryDecorator.flagExporter.reexportDirs(deps.ReexportedDirs...)
116	p.libraryDecorator.flagExporter.reexportSystemDirs(deps.ReexportedSystemDirs...)
117	p.libraryDecorator.flagExporter.reexportFlags(deps.ReexportedFlags...)
118	p.libraryDecorator.flagExporter.reexportDeps(deps.ReexportedDeps...)
119	p.libraryDecorator.flagExporter.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...)
120
121	p.libraryDecorator.flagExporter.setProvider(ctx)
122
123	// TODO(ccross): verify shared library dependencies
124	srcs := p.prebuiltSrcs(ctx)
125	if len(srcs) > 0 {
126		if len(srcs) > 1 {
127			ctx.PropertyErrorf("srcs", "multiple prebuilt source files")
128			return nil
129		}
130
131		p.libraryDecorator.exportVersioningMacroIfNeeded(ctx)
132
133		in := android.PathForModuleSrc(ctx, srcs[0])
134
135		if String(p.prebuiltLinker.properties.Prefix_symbols) != "" {
136			prefixed := android.PathForModuleOut(ctx, "prefixed", srcs[0])
137			transformBinaryPrefixSymbols(ctx, String(p.prebuiltLinker.properties.Prefix_symbols),
138				in, flagsToBuilderFlags(flags), prefixed)
139			in = prefixed
140		}
141
142		if p.static() {
143			depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(in).Build()
144			ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{
145				StaticLibrary: in,
146
147				TransitiveStaticLibrariesForOrdering: depSet,
148			})
149			return in
150		}
151
152		if p.shared() {
153			p.unstrippedOutputFile = in
154			libName := p.libraryDecorator.getLibName(ctx) + flags.Toolchain.ShlibSuffix()
155			outputFile := android.PathForModuleOut(ctx, libName)
156			var implicits android.Paths
157
158			if p.stripper.NeedsStrip(ctx) {
159				stripFlags := flagsToStripFlags(flags)
160				stripped := android.PathForModuleOut(ctx, "stripped", libName)
161				p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, stripFlags)
162				in = stripped
163			}
164
165			// Optimize out relinking against shared libraries whose interface hasn't changed by
166			// depending on a table of contents file instead of the library itself.
167			tocFile := android.PathForModuleOut(ctx, libName+".toc")
168			p.tocFile = android.OptionalPathForPath(tocFile)
169			TransformSharedObjectToToc(ctx, outputFile, tocFile)
170
171			if ctx.Windows() && p.properties.Windows_import_lib != nil {
172				// Consumers of this library actually links to the import library in build
173				// time and dynamically links to the DLL in run time. i.e.
174				// a.exe <-- static link --> foo.lib <-- dynamic link --> foo.dll
175				importLibSrc := android.PathForModuleSrc(ctx, String(p.properties.Windows_import_lib))
176				importLibName := p.libraryDecorator.getLibName(ctx) + ".lib"
177				importLibOutputFile := android.PathForModuleOut(ctx, importLibName)
178				implicits = append(implicits, importLibOutputFile)
179
180				ctx.Build(pctx, android.BuildParams{
181					Rule:        android.Cp,
182					Description: "prebuilt import library",
183					Input:       importLibSrc,
184					Output:      importLibOutputFile,
185					Args: map[string]string{
186						"cpFlags": "-L",
187					},
188				})
189			}
190
191			ctx.Build(pctx, android.BuildParams{
192				Rule:        android.Cp,
193				Description: "prebuilt shared library",
194				Implicits:   implicits,
195				Input:       in,
196				Output:      outputFile,
197				Args: map[string]string{
198					"cpFlags": "-L",
199				},
200			})
201
202			ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{
203				SharedLibrary: outputFile,
204				Target:        ctx.Target(),
205
206				TableOfContents: p.tocFile,
207			})
208
209			// TODO(b/220898484): Mainline module sdk prebuilts of stub libraries use a stub
210			// library as their source and must not be installed, but other prebuilts like
211			// libclang_rt.* libraries set `stubs` property because they are LLNDK libraries,
212			// but use an implementation library as their source and need to be installed.
213			// This discrepancy should be resolved without the prefix hack below.
214			isModuleSdkPrebuilts := android.HasAnyPrefix(ctx.ModuleDir(), []string{
215				"prebuilts/runtime/mainline/", "prebuilts/module_sdk/"})
216			if p.hasStubsVariants() && !p.buildStubs() && !ctx.Host() && isModuleSdkPrebuilts {
217				ctx.Module().MakeUninstallable()
218			}
219
220			return outputFile
221		}
222	}
223
224	if p.header() {
225		ctx.SetProvider(HeaderLibraryInfoProvider, HeaderLibraryInfo{})
226
227		// Need to return an output path so that the AndroidMk logic doesn't skip
228		// the prebuilt header. For compatibility, in case Android.mk files use a
229		// header lib in LOCAL_STATIC_LIBRARIES, create an empty ar file as
230		// placeholder, just like non-prebuilt header modules do in linkStatic().
231		ph := android.PathForModuleOut(ctx, ctx.ModuleName()+staticLibraryExtension)
232		transformObjToStaticLib(ctx, nil, nil, builderFlags{}, ph, nil, nil)
233		return ph
234	}
235
236	return nil
237}
238
239func (p *prebuiltLibraryLinker) prebuiltSrcs(ctx android.BaseModuleContext) []string {
240	sanitize := ctx.Module().(*Module).sanitize
241	srcs := p.properties.Srcs
242	srcs = append(srcs, srcsForSanitizer(sanitize, p.properties.Sanitized)...)
243	if p.static() {
244		srcs = append(srcs, p.libraryDecorator.StaticProperties.Static.Srcs...)
245		srcs = append(srcs, srcsForSanitizer(sanitize, p.libraryDecorator.StaticProperties.Static.Sanitized)...)
246	}
247	if p.shared() {
248		srcs = append(srcs, p.libraryDecorator.SharedProperties.Shared.Srcs...)
249		srcs = append(srcs, srcsForSanitizer(sanitize, p.libraryDecorator.SharedProperties.Shared.Sanitized)...)
250	}
251	return srcs
252}
253
254func (p *prebuiltLibraryLinker) shared() bool {
255	return p.libraryDecorator.shared()
256}
257
258func (p *prebuiltLibraryLinker) nativeCoverage() bool {
259	return false
260}
261
262func (p *prebuiltLibraryLinker) disablePrebuilt() {
263	p.properties.Srcs = nil
264	p.properties.MixedBuildsDisabled = true
265}
266
267// Implements versionedInterface
268func (p *prebuiltLibraryLinker) implementationModuleName(name string) string {
269	return android.RemoveOptionalPrebuiltPrefix(name)
270}
271
272func NewPrebuiltLibrary(hod android.HostOrDeviceSupported, srcsProperty string) (*Module, *libraryDecorator) {
273	module, library := NewLibrary(hod)
274	module.compiler = nil
275	module.bazelable = true
276	module.bazelHandler = &prebuiltLibraryBazelHandler{module: module, library: library}
277
278	prebuilt := &prebuiltLibraryLinker{
279		libraryDecorator: library,
280	}
281	module.linker = prebuilt
282	module.library = prebuilt
283
284	module.AddProperties(&prebuilt.properties)
285
286	if srcsProperty == "" {
287		android.InitPrebuiltModuleWithoutSrcs(module)
288	} else {
289		srcsSupplier := func(ctx android.BaseModuleContext, _ android.Module) []string {
290			return prebuilt.prebuiltSrcs(ctx)
291		}
292
293		android.InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, srcsProperty)
294	}
295
296	return module, library
297}
298
299// cc_prebuilt_library installs a precompiled shared library that are
300// listed in the srcs property in the device's directory.
301func PrebuiltLibraryFactory() android.Module {
302	module, _ := NewPrebuiltLibrary(android.HostAndDeviceSupported, "srcs")
303
304	// Prebuilt shared libraries can be included in APEXes
305	android.InitApexModule(module)
306
307	return module.Init()
308}
309
310// cc_prebuilt_library_shared installs a precompiled shared library that are
311// listed in the srcs property in the device's directory.
312func PrebuiltSharedLibraryFactory() android.Module {
313	module, _ := NewPrebuiltSharedLibrary(android.HostAndDeviceSupported)
314	return module.Init()
315}
316
317// cc_prebuilt_test_library_shared installs a precompiled shared library
318// to be used as a data dependency of a test-related module (such as cc_test, or
319// cc_test_library).
320func PrebuiltSharedTestLibraryFactory() android.Module {
321	module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported, "srcs")
322	library.BuildOnlyShared()
323	library.baseInstaller = NewTestInstaller()
324	return module.Init()
325}
326
327func NewPrebuiltSharedLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
328	module, library := NewPrebuiltLibrary(hod, "srcs")
329	library.BuildOnlyShared()
330
331	// Prebuilt shared libraries can be included in APEXes
332	android.InitApexModule(module)
333
334	return module, library
335}
336
337// cc_prebuilt_library_static installs a precompiled static library that are
338// listed in the srcs property in the device's directory.
339func PrebuiltStaticLibraryFactory() android.Module {
340	module, _ := NewPrebuiltStaticLibrary(android.HostAndDeviceSupported)
341	return module.Init()
342}
343
344func NewPrebuiltStaticLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) {
345	module, library := NewPrebuiltLibrary(hod, "srcs")
346	library.BuildOnlyStatic()
347
348	return module, library
349}
350
351type bazelPrebuiltLibraryStaticAttributes struct {
352	Static_library         bazel.LabelAttribute
353	Export_includes        bazel.StringListAttribute
354	Export_system_includes bazel.StringListAttribute
355	Alwayslink             bazel.BoolAttribute
356}
357
358// TODO(b/228623543): The below is not entirely true until the bug is fixed. For now, both targets are always generated
359// Implements bp2build for cc_prebuilt_library modules. This will generate:
360//   - Only a cc_prebuilt_library_static if the shared.enabled property is set to false across all variants.
361//   - Only a cc_prebuilt_library_shared if the static.enabled property is set to false across all variants
362//   - Both a cc_prebuilt_library_static and cc_prebuilt_library_shared if the aforementioned properties are not false across
363//     all variants
364//
365// In all cases, cc_prebuilt_library_static target names will be appended with "_bp2build_cc_library_static".
366func prebuiltLibraryBp2Build(ctx android.TopDownMutatorContext, module *Module) {
367	prebuiltLibraryStaticBp2Build(ctx, module, true)
368	prebuiltLibrarySharedBp2Build(ctx, module)
369}
370
371func prebuiltLibraryStaticBp2Build(ctx android.TopDownMutatorContext, module *Module, fullBuild bool) {
372	prebuiltAttrs := Bp2BuildParsePrebuiltLibraryProps(ctx, module, true)
373	exportedIncludes := bp2BuildParseExportedIncludes(ctx, module, nil)
374
375	attrs := &bazelPrebuiltLibraryStaticAttributes{
376		Static_library:         prebuiltAttrs.Src,
377		Export_includes:        exportedIncludes.Includes,
378		Export_system_includes: exportedIncludes.SystemIncludes,
379		// TODO: ¿Alwayslink?
380	}
381
382	props := bazel.BazelTargetModuleProperties{
383		Rule_class:        "cc_prebuilt_library_static",
384		Bzl_load_location: "//build/bazel/rules/cc:cc_prebuilt_library_static.bzl",
385	}
386
387	name := android.RemoveOptionalPrebuiltPrefix(module.Name())
388	if fullBuild {
389		name += "_bp2build_cc_library_static"
390	}
391
392	tags := android.ApexAvailableTags(module)
393	ctx.CreateBazelTargetModuleWithRestrictions(props, android.CommonAttributes{Name: name, Tags: tags}, attrs, prebuiltAttrs.Enabled)
394
395	_true := true
396	alwayslinkAttrs := *attrs
397	alwayslinkAttrs.Alwayslink.SetValue(&_true)
398	ctx.CreateBazelTargetModuleWithRestrictions(props, android.CommonAttributes{Name: name + "_alwayslink", Tags: tags}, &alwayslinkAttrs, prebuiltAttrs.Enabled)
399}
400
401type bazelPrebuiltLibrarySharedAttributes struct {
402	Shared_library         bazel.LabelAttribute
403	Export_includes        bazel.StringListAttribute
404	Export_system_includes bazel.StringListAttribute
405}
406
407func prebuiltLibrarySharedBp2Build(ctx android.TopDownMutatorContext, module *Module) {
408	prebuiltAttrs := Bp2BuildParsePrebuiltLibraryProps(ctx, module, false)
409	exportedIncludes := bp2BuildParseExportedIncludes(ctx, module, nil)
410
411	attrs := &bazelPrebuiltLibrarySharedAttributes{
412		Shared_library:         prebuiltAttrs.Src,
413		Export_includes:        exportedIncludes.Includes,
414		Export_system_includes: exportedIncludes.SystemIncludes,
415	}
416
417	props := bazel.BazelTargetModuleProperties{
418		Rule_class:        "cc_prebuilt_library_shared",
419		Bzl_load_location: "//build/bazel/rules/cc:cc_prebuilt_library_shared.bzl",
420	}
421
422	name := android.RemoveOptionalPrebuiltPrefix(module.Name())
423	tags := android.ApexAvailableTags(module)
424	ctx.CreateBazelTargetModuleWithRestrictions(props, android.CommonAttributes{Name: name, Tags: tags}, attrs, prebuiltAttrs.Enabled)
425}
426
427type prebuiltObjectProperties struct {
428	Srcs []string `android:"path,arch_variant"`
429}
430
431type prebuiltObjectLinker struct {
432	android.Prebuilt
433	objectLinker
434
435	properties prebuiltObjectProperties
436}
437
438type prebuiltLibraryBazelHandler struct {
439	module  *Module
440	library *libraryDecorator
441}
442
443var _ BazelHandler = (*prebuiltLibraryBazelHandler)(nil)
444
445func (h *prebuiltLibraryBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
446	if h.module.linker.(*prebuiltLibraryLinker).properties.MixedBuildsDisabled {
447		return
448	}
449	bazelCtx := ctx.Config().BazelContext
450	bazelCtx.QueueBazelRequest(label, cquery.GetCcInfo, android.GetConfigKey(ctx))
451}
452
453func (h *prebuiltLibraryBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
454	if h.module.linker.(*prebuiltLibraryLinker).properties.MixedBuildsDisabled {
455		return
456	}
457	bazelCtx := ctx.Config().BazelContext
458	ccInfo, err := bazelCtx.GetCcInfo(label, android.GetConfigKey(ctx))
459	if err != nil {
460		ctx.ModuleErrorf(err.Error())
461		return
462	}
463
464	if h.module.static() {
465		if ok := h.processStaticBazelQueryResponse(ctx, label, ccInfo); !ok {
466			return
467		}
468	} else if h.module.Shared() {
469		if ok := h.processSharedBazelQueryResponse(ctx, label, ccInfo); !ok {
470			return
471		}
472	} else {
473		return
474	}
475
476	h.module.maybeUnhideFromMake()
477
478	h.module.setAndroidMkVariablesFromCquery(ccInfo.CcAndroidMkInfo)
479}
480
481func (h *prebuiltLibraryBazelHandler) processStaticBazelQueryResponse(ctx android.ModuleContext, label string, ccInfo cquery.CcInfo) bool {
482	staticLibs := ccInfo.CcStaticLibraryFiles
483	if len(staticLibs) > 1 {
484		ctx.ModuleErrorf("expected 1 static library from bazel target %q, got %s", label, staticLibs)
485		return false
486	}
487
488	// TODO(b/184543518): cc_prebuilt_library_static may have properties for re-exporting flags
489
490	// TODO(eakammer):Add stub-related flags if this library is a stub library.
491	// h.library.exportVersioningMacroIfNeeded(ctx)
492
493	// Dependencies on this library will expect collectedSnapshotHeaders to be set, otherwise
494	// validation will fail. For now, set this to an empty list.
495	// TODO(cparsons): More closely mirror the collectHeadersForSnapshot implementation.
496	h.library.collectedSnapshotHeaders = android.Paths{}
497
498	if len(staticLibs) == 0 {
499		h.module.outputFile = android.OptionalPath{}
500		return true
501	}
502
503	var outputPath android.Path = android.PathForBazelOut(ctx, staticLibs[0])
504	if len(ccInfo.TidyFiles) > 0 {
505		h.module.tidyFiles = android.PathsForBazelOut(ctx, ccInfo.TidyFiles)
506		outputPath = android.AttachValidationActions(ctx, outputPath, h.module.tidyFiles)
507	}
508
509	h.module.outputFile = android.OptionalPathForPath(outputPath)
510
511	depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(outputPath).Build()
512	ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{
513		StaticLibrary:                        outputPath,
514		TransitiveStaticLibrariesForOrdering: depSet,
515	})
516
517	return true
518}
519
520func (h *prebuiltLibraryBazelHandler) processSharedBazelQueryResponse(ctx android.ModuleContext, label string, ccInfo cquery.CcInfo) bool {
521	sharedLibs := ccInfo.CcSharedLibraryFiles
522	if len(sharedLibs) > 1 {
523		ctx.ModuleErrorf("expected 1 shared library from bazel target %s, got %q", label, sharedLibs)
524		return false
525	}
526
527	// TODO(b/184543518): cc_prebuilt_library_shared may have properties for re-exporting flags
528
529	// TODO(eakammer):Add stub-related flags if this library is a stub library.
530	// h.library.exportVersioningMacroIfNeeded(ctx)
531
532	if len(sharedLibs) == 0 {
533		h.module.outputFile = android.OptionalPath{}
534		return true
535	}
536
537	var outputPath android.Path = android.PathForBazelOut(ctx, sharedLibs[0])
538	if len(ccInfo.TidyFiles) > 0 {
539		h.module.tidyFiles = android.PathsForBazelOut(ctx, ccInfo.TidyFiles)
540		outputPath = android.AttachValidationActions(ctx, outputPath, h.module.tidyFiles)
541	}
542
543	h.module.outputFile = android.OptionalPathForPath(outputPath)
544
545	// FIXME(b/214600441): We don't yet strip prebuilt shared libraries
546	h.library.unstrippedOutputFile = outputPath
547
548	var toc android.Path
549	if len(ccInfo.TocFile) > 0 {
550		toc = android.PathForBazelOut(ctx, ccInfo.TocFile)
551	} else {
552		toc = outputPath // Just reuse `out` so ninja still gets an input but won't matter
553	}
554
555	info := SharedLibraryInfo{
556		SharedLibrary:   outputPath,
557		TableOfContents: android.OptionalPathForPath(toc),
558		Target:          ctx.Target(),
559	}
560	ctx.SetProvider(SharedLibraryInfoProvider, info)
561
562	h.library.setFlagExporterInfoFromCcInfo(ctx, ccInfo)
563	h.module.maybeUnhideFromMake()
564	return true
565}
566
567func (p *prebuiltObjectLinker) prebuilt() *android.Prebuilt {
568	return &p.Prebuilt
569}
570
571var _ prebuiltLinkerInterface = (*prebuiltObjectLinker)(nil)
572
573func (p *prebuiltObjectLinker) link(ctx ModuleContext,
574	flags Flags, deps PathDeps, objs Objects) android.Path {
575	if len(p.properties.Srcs) > 0 {
576		// Copy objects to a name matching the final installed name
577		in := p.Prebuilt.SingleSourcePath(ctx)
578		outputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".o")
579		ctx.Build(pctx, android.BuildParams{
580			Rule:        android.CpExecutable,
581			Description: "prebuilt",
582			Output:      outputFile,
583			Input:       in,
584		})
585		return outputFile
586	}
587	return nil
588}
589
590func (p *prebuiltObjectLinker) object() bool {
591	return true
592}
593
594func NewPrebuiltObject(hod android.HostOrDeviceSupported) *Module {
595	module := newObject(hod)
596	module.bazelHandler = &prebuiltObjectBazelHandler{module: module}
597	module.bazelable = true
598	prebuilt := &prebuiltObjectLinker{
599		objectLinker: objectLinker{
600			baseLinker: NewBaseLinker(nil),
601		},
602	}
603	module.linker = prebuilt
604	module.AddProperties(&prebuilt.properties)
605	android.InitPrebuiltModule(module, &prebuilt.properties.Srcs)
606	return module
607}
608
609type prebuiltObjectBazelHandler struct {
610	module *Module
611}
612
613var _ BazelHandler = (*prebuiltObjectBazelHandler)(nil)
614
615func (h *prebuiltObjectBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
616	bazelCtx := ctx.Config().BazelContext
617	bazelCtx.QueueBazelRequest(label, cquery.GetOutputFiles, android.GetConfigKey(ctx))
618}
619
620func (h *prebuiltObjectBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
621	bazelCtx := ctx.Config().BazelContext
622	outputs, err := bazelCtx.GetOutputFiles(label, android.GetConfigKey(ctx))
623	if err != nil {
624		ctx.ModuleErrorf(err.Error())
625		return
626	}
627	if len(outputs) != 1 {
628		ctx.ModuleErrorf("Expected a single output for `%s`, but got:\n%v", label, outputs)
629		return
630	}
631	out := android.PathForBazelOut(ctx, outputs[0])
632	h.module.outputFile = android.OptionalPathForPath(out)
633	h.module.maybeUnhideFromMake()
634}
635
636type bazelPrebuiltObjectAttributes struct {
637	Src bazel.LabelAttribute
638}
639
640func prebuiltObjectBp2Build(ctx android.TopDownMutatorContext, module *Module) {
641	prebuiltAttrs := bp2BuildParsePrebuiltObjectProps(ctx, module)
642
643	attrs := &bazelPrebuiltObjectAttributes{
644		Src: prebuiltAttrs.Src,
645	}
646
647	props := bazel.BazelTargetModuleProperties{
648		Rule_class:        "cc_prebuilt_object",
649		Bzl_load_location: "//build/bazel/rules/cc:cc_prebuilt_object.bzl",
650	}
651
652	name := android.RemoveOptionalPrebuiltPrefix(module.Name())
653	tags := android.ApexAvailableTags(module)
654	ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name, Tags: tags}, attrs)
655}
656
657func PrebuiltObjectFactory() android.Module {
658	module := NewPrebuiltObject(android.HostAndDeviceSupported)
659	return module.Init()
660}
661
662type prebuiltBinaryLinker struct {
663	*binaryDecorator
664	prebuiltLinker
665
666	toolPath android.OptionalPath
667}
668
669var _ prebuiltLinkerInterface = (*prebuiltBinaryLinker)(nil)
670
671func (p *prebuiltBinaryLinker) hostToolPath() android.OptionalPath {
672	return p.toolPath
673}
674
675func (p *prebuiltBinaryLinker) link(ctx ModuleContext,
676	flags Flags, deps PathDeps, objs Objects) android.Path {
677	// TODO(ccross): verify shared library dependencies
678	if len(p.properties.Srcs) > 0 {
679		fileName := p.getStem(ctx) + flags.Toolchain.ExecutableSuffix()
680		in := p.Prebuilt.SingleSourcePath(ctx)
681		outputFile := android.PathForModuleOut(ctx, fileName)
682		p.unstrippedOutputFile = in
683
684		if ctx.Host() {
685			// Host binaries are symlinked to their prebuilt source locations. That
686			// way they are executed directly from there so the linker resolves their
687			// shared library dependencies relative to that location (using
688			// $ORIGIN/../lib(64):$ORIGIN/lib(64) as RUNPATH). This way the prebuilt
689			// repository can supply the expected versions of the shared libraries
690			// without interference from what is in the out tree.
691
692			// These shared lib paths may point to copies of the libs in
693			// .intermediates, which isn't where the binary will load them from, but
694			// it's fine for dependency tracking. If a library dependency is updated,
695			// the symlink will get a new timestamp, along with any installed symlinks
696			// handled in make.
697			sharedLibPaths := deps.EarlySharedLibs
698			sharedLibPaths = append(sharedLibPaths, deps.SharedLibs...)
699			sharedLibPaths = append(sharedLibPaths, deps.LateSharedLibs...)
700
701			var fromPath = in.String()
702			if !filepath.IsAbs(fromPath) {
703				fromPath = "$$PWD/" + fromPath
704			}
705
706			ctx.Build(pctx, android.BuildParams{
707				Rule:      android.Symlink,
708				Output:    outputFile,
709				Input:     in,
710				Implicits: sharedLibPaths,
711				Args: map[string]string{
712					"fromPath": fromPath,
713				},
714			})
715
716			p.toolPath = android.OptionalPathForPath(outputFile)
717		} else {
718			if p.stripper.NeedsStrip(ctx) {
719				stripped := android.PathForModuleOut(ctx, "stripped", fileName)
720				p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, flagsToStripFlags(flags))
721				in = stripped
722			}
723
724			// Copy binaries to a name matching the final installed name
725			ctx.Build(pctx, android.BuildParams{
726				Rule:        android.CpExecutable,
727				Description: "prebuilt",
728				Output:      outputFile,
729				Input:       in,
730			})
731		}
732
733		return outputFile
734	}
735
736	return nil
737}
738
739func (p *prebuiltBinaryLinker) binary() bool {
740	return true
741}
742
743// cc_prebuilt_binary installs a precompiled executable in srcs property in the
744// device's directory, for both the host and device
745func PrebuiltBinaryFactory() android.Module {
746	module, _ := NewPrebuiltBinary(android.HostAndDeviceSupported)
747	return module.Init()
748}
749
750type prebuiltBinaryBazelHandler struct {
751	module    *Module
752	decorator *binaryDecorator
753}
754
755func NewPrebuiltBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) {
756	module, binary := newBinary(hod, true)
757	module.compiler = nil
758	module.bazelHandler = &prebuiltBinaryBazelHandler{module, binary}
759
760	prebuilt := &prebuiltBinaryLinker{
761		binaryDecorator: binary,
762	}
763	module.linker = prebuilt
764	module.installer = prebuilt
765
766	module.AddProperties(&prebuilt.properties)
767
768	android.InitPrebuiltModule(module, &prebuilt.properties.Srcs)
769	return module, binary
770}
771
772var _ BazelHandler = (*prebuiltBinaryBazelHandler)(nil)
773
774func (h *prebuiltBinaryBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
775	bazelCtx := ctx.Config().BazelContext
776	bazelCtx.QueueBazelRequest(label, cquery.GetOutputFiles, android.GetConfigKeyApexVariant(ctx, GetApexConfigKey(ctx)))
777}
778
779func (h *prebuiltBinaryBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
780	bazelCtx := ctx.Config().BazelContext
781	outputs, err := bazelCtx.GetOutputFiles(label, android.GetConfigKeyApexVariant(ctx, GetApexConfigKey(ctx)))
782	if err != nil {
783		ctx.ModuleErrorf(err.Error())
784		return
785	}
786	if len(outputs) != 1 {
787		ctx.ModuleErrorf("Expected a single output for `%s`, but got:\n%v", label, outputs)
788		return
789	}
790	out := android.PathForBazelOut(ctx, outputs[0])
791	h.module.outputFile = android.OptionalPathForPath(out)
792	h.module.maybeUnhideFromMake()
793}
794
795type bazelPrebuiltBinaryAttributes struct {
796	Src   bazel.LabelAttribute
797	Strip stripAttributes
798}
799
800func prebuiltBinaryBp2Build(ctx android.TopDownMutatorContext, module *Module) {
801	prebuiltAttrs := bp2BuildParsePrebuiltBinaryProps(ctx, module)
802
803	var la linkerAttributes
804	la.convertStripProps(ctx, module)
805	attrs := &bazelPrebuiltBinaryAttributes{
806		Src:   prebuiltAttrs.Src,
807		Strip: stripAttrsFromLinkerAttrs(&la),
808	}
809
810	props := bazel.BazelTargetModuleProperties{
811		Rule_class:        "cc_prebuilt_binary",
812		Bzl_load_location: "//build/bazel/rules/cc:cc_prebuilt_binary.bzl",
813	}
814
815	name := android.RemoveOptionalPrebuiltPrefix(module.Name())
816	tags := android.ApexAvailableTags(module)
817	ctx.CreateBazelTargetModule(props, android.CommonAttributes{Name: name, Tags: tags}, attrs)
818}
819
820type Sanitized struct {
821	None struct {
822		Srcs []string `android:"path,arch_variant"`
823	} `android:"arch_variant"`
824	Address struct {
825		Srcs []string `android:"path,arch_variant"`
826	} `android:"arch_variant"`
827	Hwaddress struct {
828		Srcs []string `android:"path,arch_variant"`
829	} `android:"arch_variant"`
830}
831
832func srcsForSanitizer(sanitize *sanitize, sanitized Sanitized) []string {
833	if sanitize == nil {
834		return nil
835	}
836	if sanitize.isSanitizerEnabled(Asan) && sanitized.Address.Srcs != nil {
837		return sanitized.Address.Srcs
838	}
839	if sanitize.isSanitizerEnabled(Hwasan) && sanitized.Hwaddress.Srcs != nil {
840		return sanitized.Hwaddress.Srcs
841	}
842	return sanitized.None.Srcs
843}
844