• 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/bazel/cquery"
21
22	"github.com/google/blueprint"
23	"github.com/google/blueprint/proptools"
24
25	"android/soong/android"
26	"android/soong/bazel"
27)
28
29type BinaryLinkerProperties struct {
30	// compile executable with -static
31	Static_executable *bool `android:"arch_variant"`
32
33	// set the name of the output
34	Stem *string `android:"arch_variant"`
35
36	// append to the name of the output
37	Suffix *string `android:"arch_variant"`
38
39	// if set, add an extra objcopy --prefix-symbols= step
40	Prefix_symbols *string
41
42	// if set, install a symlink to the preferred architecture
43	Symlink_preferred_arch *bool `android:"arch_variant"`
44
45	// install symlinks to the binary.  Symlink names will have the suffix and the binary
46	// extension (if any) appended
47	Symlinks []string `android:"arch_variant"`
48
49	// override the dynamic linker
50	DynamicLinker string `blueprint:"mutated"`
51
52	// Names of modules to be overridden. Listed modules can only be other binaries
53	// (in Make or Soong).
54	// This does not completely prevent installation of the overridden binaries, but if both
55	// binaries would be installed by default (in PRODUCT_PACKAGES) the other binary will be removed
56	// from PRODUCT_PACKAGES.
57	Overrides []string
58
59	// Inject boringssl hash into the shared library.  This is only intended for use by external/boringssl.
60	Inject_bssl_hash *bool `android:"arch_variant"`
61}
62
63func init() {
64	RegisterBinaryBuildComponents(android.InitRegistrationContext)
65}
66
67func RegisterBinaryBuildComponents(ctx android.RegistrationContext) {
68	ctx.RegisterModuleType("cc_binary", BinaryFactory)
69	ctx.RegisterModuleType("cc_binary_host", BinaryHostFactory)
70}
71
72// cc_binary produces a binary that is runnable on a device.
73func BinaryFactory() android.Module {
74	module, _ := newBinary(android.HostAndDeviceSupported, true)
75	module.bazelHandler = &ccBinaryBazelHandler{module: module}
76	return module.Init()
77}
78
79// cc_binary_host produces a binary that is runnable on a host.
80func BinaryHostFactory() android.Module {
81	module, _ := newBinary(android.HostSupported, true)
82	return module.Init()
83}
84
85//
86// Executables
87//
88
89// binaryDecorator is a decorator containing information for C++ binary modules.
90type binaryDecorator struct {
91	*baseLinker
92	*baseInstaller
93	stripper Stripper
94
95	Properties BinaryLinkerProperties
96
97	toolPath android.OptionalPath
98
99	// Location of the linked, unstripped binary
100	unstrippedOutputFile android.Path
101
102	// Names of symlinks to be installed for use in LOCAL_MODULE_SYMLINKS
103	symlinks []string
104
105	// If the module has symlink_preferred_arch set, the name of the symlink to the
106	// binary for the preferred arch.
107	preferredArchSymlink string
108
109	// Output archive of gcno coverage information
110	coverageOutputFile android.OptionalPath
111
112	// Location of the files that should be copied to dist dir when requested
113	distFiles android.TaggedDistFiles
114
115	// Action command lines to run directly after the binary is installed. For example,
116	// may be used to symlink runtime dependencies (such as bionic) alongside installation.
117	postInstallCmds []string
118}
119
120var _ linker = (*binaryDecorator)(nil)
121
122// linkerProps returns the list of individual properties objects relevant
123// for this binary.
124func (binary *binaryDecorator) linkerProps() []interface{} {
125	return append(binary.baseLinker.linkerProps(),
126		&binary.Properties,
127		&binary.stripper.StripProperties)
128
129}
130
131// getStemWithoutSuffix returns the main section of the name to use for the symlink of
132// the main output file of this binary module. This may be derived from the module name
133// or other property overrides.
134// For the full symlink name, the `Suffix` property of a binary module must be appended.
135func (binary *binaryDecorator) getStemWithoutSuffix(ctx BaseModuleContext) string {
136	stem := ctx.baseModuleName()
137	if String(binary.Properties.Stem) != "" {
138		stem = String(binary.Properties.Stem)
139	}
140
141	return stem
142}
143
144// getStem returns the full name to use for the symlink of the main output file of this binary
145// module. This may be derived from the module name and/or other property overrides.
146func (binary *binaryDecorator) getStem(ctx BaseModuleContext) string {
147	return binary.getStemWithoutSuffix(ctx) + String(binary.Properties.Suffix)
148}
149
150// linkerDeps augments and returns the given `deps` to contain dependencies on
151// modules common to most binaries, such as bionic libraries.
152func (binary *binaryDecorator) linkerDeps(ctx DepsContext, deps Deps) Deps {
153	deps = binary.baseLinker.linkerDeps(ctx, deps)
154	if binary.baseLinker.Properties.crt() {
155		if binary.static() {
156			deps.CrtBegin = ctx.toolchain().CrtBeginStaticBinary()
157			deps.CrtEnd = ctx.toolchain().CrtEndStaticBinary()
158		} else {
159			deps.CrtBegin = ctx.toolchain().CrtBeginSharedBinary()
160			deps.CrtEnd = ctx.toolchain().CrtEndSharedBinary()
161		}
162	}
163
164	if binary.static() {
165		deps.StaticLibs = append(deps.StaticLibs, deps.SystemSharedLibs...)
166	}
167
168	if ctx.toolchain().Bionic() {
169		if binary.static() {
170			if ctx.selectedStl() == "libc++_static" {
171				deps.StaticLibs = append(deps.StaticLibs, "libm", "libc")
172			}
173			// static libraries libcompiler_rt, libc and libc_nomalloc need to be linked with
174			// --start-group/--end-group along with libgcc.  If they are in deps.StaticLibs,
175			// move them to the beginning of deps.LateStaticLibs
176			var groupLibs []string
177			deps.StaticLibs, groupLibs = filterList(deps.StaticLibs,
178				[]string{"libc", "libc_nomalloc", "libcompiler_rt"})
179			deps.LateStaticLibs = append(groupLibs, deps.LateStaticLibs...)
180		}
181
182		if ctx.Os() == android.LinuxBionic && !binary.static() {
183			deps.DynamicLinker = "linker"
184		}
185	}
186
187	if !binary.static() && inList("libc", deps.StaticLibs) {
188		ctx.ModuleErrorf("statically linking libc to dynamic executable, please remove libc\n" +
189			"from static libs or set static_executable: true")
190	}
191
192	return deps
193}
194
195// NewBinary builds and returns a new Module corresponding to a C++ binary.
196// Individual module implementations which comprise a C++ binary should call this function,
197// set some fields on the result, and then call the Init function.
198func NewBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) {
199	return newBinary(hod, true)
200}
201
202func newBinary(hod android.HostOrDeviceSupported, bazelable bool) (*Module, *binaryDecorator) {
203	module := newModule(hod, android.MultilibFirst)
204	binary := &binaryDecorator{
205		baseLinker:    NewBaseLinker(module.sanitize),
206		baseInstaller: NewBaseInstaller("bin", "", InstallInSystem),
207	}
208	module.compiler = NewBaseCompiler()
209	module.linker = binary
210	module.installer = binary
211	module.bazelable = bazelable
212
213	// Allow module to be added as member of an sdk/module_exports.
214	module.sdkMemberTypes = []android.SdkMemberType{
215		ccBinarySdkMemberType,
216	}
217	return module, binary
218}
219
220// linkerInit initializes dynamic properties of the linker (such as runpath) based
221// on properties of this binary.
222func (binary *binaryDecorator) linkerInit(ctx BaseModuleContext) {
223	binary.baseLinker.linkerInit(ctx)
224
225	if ctx.Os().Linux() && ctx.Host() {
226		// Unless explicitly specified otherwise, host static binaries are built with -static
227		// if HostStaticBinaries is true for the product configuration.
228		if binary.Properties.Static_executable == nil && ctx.Config().HostStaticBinaries() {
229			binary.Properties.Static_executable = BoolPtr(true)
230		}
231	}
232
233	if ctx.Darwin() || ctx.Windows() {
234		// Static executables are not supported on Darwin or Windows
235		binary.Properties.Static_executable = nil
236	}
237}
238
239func (binary *binaryDecorator) static() bool {
240	return Bool(binary.Properties.Static_executable)
241}
242
243func (binary *binaryDecorator) staticBinary() bool {
244	return binary.static()
245}
246
247func (binary *binaryDecorator) binary() bool {
248	return true
249}
250
251// linkerFlags returns a Flags object containing linker flags that are defined
252// by this binary, or that are implied by attributes of this binary. These flags are
253// combined with the given flags.
254func (binary *binaryDecorator) linkerFlags(ctx ModuleContext, flags Flags) Flags {
255	flags = binary.baseLinker.linkerFlags(ctx, flags)
256
257	// Passing -pie to clang for Windows binaries causes a warning that -pie is unused.
258	if ctx.Host() && !ctx.Windows() && !binary.static() {
259		if !ctx.Config().IsEnvTrue("DISABLE_HOST_PIE") {
260			flags.Global.LdFlags = append(flags.Global.LdFlags, "-pie")
261		}
262	}
263
264	// MinGW spits out warnings about -fPIC even for -fpie?!) being ignored because
265	// all code is position independent, and then those warnings get promoted to
266	// errors.
267	if !ctx.Windows() {
268		flags.Global.CFlags = append(flags.Global.CFlags, "-fPIE")
269	}
270
271	if ctx.toolchain().Bionic() {
272		if binary.static() {
273			// Clang driver needs -static to create static executable.
274			// However, bionic/linker uses -shared to overwrite.
275			// Linker for x86 targets does not allow coexistance of -static and -shared,
276			// so we add -static only if -shared is not used.
277			if !inList("-shared", flags.Local.LdFlags) {
278				flags.Global.LdFlags = append(flags.Global.LdFlags, "-static")
279			}
280
281			flags.Global.LdFlags = append(flags.Global.LdFlags,
282				"-nostdlib",
283				"-Bstatic",
284				"-Wl,--gc-sections",
285			)
286		} else { // not static
287			if flags.DynamicLinker == "" {
288				if binary.Properties.DynamicLinker != "" {
289					flags.DynamicLinker = binary.Properties.DynamicLinker
290				} else {
291					switch ctx.Os() {
292					case android.Android:
293						if ctx.bootstrap() && !ctx.inRecovery() && !ctx.inRamdisk() && !ctx.inVendorRamdisk() {
294							flags.DynamicLinker = "/system/bin/bootstrap/linker"
295						} else {
296							flags.DynamicLinker = "/system/bin/linker"
297						}
298						if flags.Toolchain.Is64Bit() {
299							flags.DynamicLinker += "64"
300						}
301					case android.LinuxBionic:
302						flags.DynamicLinker = ""
303					default:
304						ctx.ModuleErrorf("unknown dynamic linker")
305					}
306				}
307
308				if ctx.Os() == android.LinuxBionic {
309					// Use the dlwrap entry point, but keep _start around so
310					// that it can be used by host_bionic_inject
311					flags.Global.LdFlags = append(flags.Global.LdFlags,
312						"-Wl,--entry=__dlwrap__start",
313						"-Wl,--undefined=_start",
314					)
315				}
316			}
317
318			flags.Global.LdFlags = append(flags.Global.LdFlags,
319				"-pie",
320				"-nostdlib",
321				"-Bdynamic",
322				"-Wl,--gc-sections",
323				"-Wl,-z,nocopyreloc",
324			)
325		}
326	} else { // not bionic
327		if binary.static() {
328			flags.Global.LdFlags = append(flags.Global.LdFlags, "-static")
329		}
330		if ctx.Darwin() {
331			flags.Global.LdFlags = append(flags.Global.LdFlags, "-Wl,-headerpad_max_install_names")
332		}
333	}
334
335	return flags
336}
337
338// link registers actions to link this binary, and sets various fields
339// on this binary to reflect information that should be exported up the build
340// tree (for example, exported flags and include paths).
341func (binary *binaryDecorator) link(ctx ModuleContext,
342	flags Flags, deps PathDeps, objs Objects) android.Path {
343
344	fileName := binary.getStem(ctx) + flags.Toolchain.ExecutableSuffix()
345	outputFile := android.PathForModuleOut(ctx, fileName)
346	ret := outputFile
347
348	var linkerDeps android.Paths
349
350	if flags.DynamicLinker != "" {
351		flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,-dynamic-linker,"+flags.DynamicLinker)
352	} else if (ctx.toolchain().Bionic() || ctx.toolchain().Musl()) && !binary.static() {
353		flags.Local.LdFlags = append(flags.Local.LdFlags, "-Wl,--no-dynamic-linker")
354	}
355
356	if ctx.Darwin() && deps.DarwinSecondArchOutput.Valid() {
357		fatOutputFile := outputFile
358		outputFile = android.PathForModuleOut(ctx, "pre-fat", fileName)
359		transformDarwinUniversalBinary(ctx, fatOutputFile, outputFile, deps.DarwinSecondArchOutput.Path())
360	}
361
362	builderFlags := flagsToBuilderFlags(flags)
363	stripFlags := flagsToStripFlags(flags)
364	if binary.stripper.NeedsStrip(ctx) {
365		if ctx.Darwin() {
366			stripFlags.StripUseGnuStrip = true
367		}
368		strippedOutputFile := outputFile
369		outputFile = android.PathForModuleOut(ctx, "unstripped", fileName)
370		binary.stripper.StripExecutableOrSharedLib(ctx, outputFile, strippedOutputFile, stripFlags)
371	}
372
373	binary.unstrippedOutputFile = outputFile
374
375	if String(binary.Properties.Prefix_symbols) != "" {
376		afterPrefixSymbols := outputFile
377		outputFile = android.PathForModuleOut(ctx, "unprefixed", fileName)
378		transformBinaryPrefixSymbols(ctx, String(binary.Properties.Prefix_symbols), outputFile,
379			builderFlags, afterPrefixSymbols)
380	}
381
382	outputFile = maybeInjectBoringSSLHash(ctx, outputFile, binary.Properties.Inject_bssl_hash, fileName)
383
384	// If use_version_lib is true, make an android::build::GetBuildNumber() function available.
385	if Bool(binary.baseLinker.Properties.Use_version_lib) {
386		if ctx.Host() {
387			versionedOutputFile := outputFile
388			outputFile = android.PathForModuleOut(ctx, "unversioned", fileName)
389			binary.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
390		} else {
391			// When dist'ing a library or binary that has use_version_lib set, always
392			// distribute the stamped version, even for the device.
393			versionedOutputFile := android.PathForModuleOut(ctx, "versioned", fileName)
394			binary.distFiles = android.MakeDefaultDistFiles(versionedOutputFile)
395
396			if binary.stripper.NeedsStrip(ctx) {
397				out := android.PathForModuleOut(ctx, "versioned-stripped", fileName)
398				binary.distFiles = android.MakeDefaultDistFiles(out)
399				binary.stripper.StripExecutableOrSharedLib(ctx, versionedOutputFile, out, stripFlags)
400			}
401
402			binary.injectVersionSymbol(ctx, outputFile, versionedOutputFile)
403		}
404	}
405
406	var validations android.Paths
407
408	// Handle host bionic linker symbols.
409	if ctx.Os() == android.LinuxBionic && !binary.static() {
410		verifyFile := android.PathForModuleOut(ctx, "host_bionic_verify.stamp")
411
412		if !deps.DynamicLinker.Valid() {
413			panic("Non-static host bionic modules must have a dynamic linker")
414		}
415
416		binary.verifyHostBionicLinker(ctx, outputFile, deps.DynamicLinker.Path(), verifyFile)
417		validations = append(validations, verifyFile)
418	}
419
420	var sharedLibs android.Paths
421	// Ignore shared libs for static executables.
422	if !binary.static() {
423		sharedLibs = deps.EarlySharedLibs
424		sharedLibs = append(sharedLibs, deps.SharedLibs...)
425		sharedLibs = append(sharedLibs, deps.LateSharedLibs...)
426		linkerDeps = append(linkerDeps, deps.EarlySharedLibsDeps...)
427		linkerDeps = append(linkerDeps, deps.SharedLibsDeps...)
428		linkerDeps = append(linkerDeps, deps.LateSharedLibsDeps...)
429		linkerDeps = append(linkerDeps, ndkSharedLibDeps(ctx)...)
430	}
431
432	validations = append(validations, objs.tidyDepFiles...)
433	linkerDeps = append(linkerDeps, flags.LdFlagsDeps...)
434
435	// Register link action.
436	transformObjToDynamicBinary(ctx, objs.objFiles, sharedLibs, deps.StaticLibs,
437		deps.LateStaticLibs, deps.WholeStaticLibs, linkerDeps, deps.CrtBegin, deps.CrtEnd, true,
438		builderFlags, outputFile, nil, validations)
439
440	objs.coverageFiles = append(objs.coverageFiles, deps.StaticLibObjs.coverageFiles...)
441	objs.coverageFiles = append(objs.coverageFiles, deps.WholeStaticLibObjs.coverageFiles...)
442	binary.coverageOutputFile = transformCoverageFilesToZip(ctx, objs, binary.getStem(ctx))
443
444	// Need to determine symlinks early since some targets (ie APEX) need this
445	// information but will not call 'install'
446	binary.setSymlinkList(ctx)
447
448	return ret
449}
450
451func (binary *binaryDecorator) unstrippedOutputFilePath() android.Path {
452	return binary.unstrippedOutputFile
453}
454
455func (binary *binaryDecorator) setSymlinkList(ctx ModuleContext) {
456	for _, symlink := range binary.Properties.Symlinks {
457		binary.symlinks = append(binary.symlinks,
458			symlink+String(binary.Properties.Suffix)+ctx.toolchain().ExecutableSuffix())
459	}
460
461	if Bool(binary.Properties.Symlink_preferred_arch) {
462		if String(binary.Properties.Suffix) == "" {
463			ctx.PropertyErrorf("symlink_preferred_arch", "must also specify suffix")
464		}
465		if ctx.TargetPrimary() {
466			// Install a symlink to the preferred architecture
467			symlinkName := binary.getStemWithoutSuffix(ctx)
468			binary.symlinks = append(binary.symlinks, symlinkName)
469			binary.preferredArchSymlink = symlinkName
470		}
471	}
472}
473
474func (binary *binaryDecorator) symlinkList() []string {
475	return binary.symlinks
476}
477
478func (binary *binaryDecorator) nativeCoverage() bool {
479	return true
480}
481
482func (binary *binaryDecorator) coverageOutputFilePath() android.OptionalPath {
483	return binary.coverageOutputFile
484}
485
486// /system/bin/linker -> /apex/com.android.runtime/bin/linker
487func (binary *binaryDecorator) installSymlinkToRuntimeApex(ctx ModuleContext, file android.Path) {
488	dir := binary.baseInstaller.installDir(ctx)
489	dirOnDevice := android.InstallPathToOnDevicePath(ctx, dir)
490	target := "/" + filepath.Join("apex", "com.android.runtime", dir.Base(), file.Base())
491
492	ctx.InstallAbsoluteSymlink(dir, file.Base(), target)
493	binary.postInstallCmds = append(binary.postInstallCmds, makeSymlinkCmd(dirOnDevice, file.Base(), target))
494
495	for _, symlink := range binary.symlinks {
496		ctx.InstallAbsoluteSymlink(dir, symlink, target)
497		binary.postInstallCmds = append(binary.postInstallCmds, makeSymlinkCmd(dirOnDevice, symlink, target))
498	}
499}
500
501func (binary *binaryDecorator) install(ctx ModuleContext, file android.Path) {
502	// Bionic binaries (e.g. linker) is installed to the bootstrap subdirectory.
503	// The original path becomes a symlink to the corresponding file in the
504	// runtime APEX.
505	translatedArch := ctx.Target().NativeBridge == android.NativeBridgeEnabled
506	if InstallToBootstrap(ctx.baseModuleName(), ctx.Config()) && !ctx.Host() && ctx.directlyInAnyApex() &&
507		!translatedArch && ctx.apexVariationName() == "" && !ctx.inRamdisk() && !ctx.inRecovery() &&
508		!ctx.inVendorRamdisk() {
509
510		if ctx.Device() && isBionic(ctx.baseModuleName()) {
511			binary.installSymlinkToRuntimeApex(ctx, file)
512		}
513		binary.baseInstaller.subDir = "bootstrap"
514	}
515	binary.baseInstaller.installExecutable(ctx, file)
516
517	var preferredArchSymlinkPath android.OptionalPath
518	for _, symlink := range binary.symlinks {
519		installedSymlink := ctx.InstallSymlink(binary.baseInstaller.installDir(ctx), symlink,
520			binary.baseInstaller.path)
521		if symlink == binary.preferredArchSymlink {
522			// If this is the preferred arch symlink, save the installed path for use as the
523			// tool path.
524			preferredArchSymlinkPath = android.OptionalPathForPath(installedSymlink)
525		}
526	}
527
528	if ctx.Os().Class == android.Host {
529		// If the binary is multilib with a symlink to the preferred architecture, use the
530		// symlink instead of the binary because that's the more "canonical" name.
531		if preferredArchSymlinkPath.Valid() {
532			binary.toolPath = preferredArchSymlinkPath
533		} else {
534			binary.toolPath = android.OptionalPathForPath(binary.baseInstaller.path)
535		}
536	}
537}
538
539func (binary *binaryDecorator) hostToolPath() android.OptionalPath {
540	return binary.toolPath
541}
542
543func (binary *binaryDecorator) overriddenModules() []string {
544	return binary.Properties.Overrides
545}
546
547var _ overridable = (*binaryDecorator)(nil)
548
549func init() {
550	pctx.HostBinToolVariable("verifyHostBionicCmd", "host_bionic_verify")
551}
552
553var verifyHostBionic = pctx.AndroidStaticRule("verifyHostBionic",
554	blueprint.RuleParams{
555		Command:     "$verifyHostBionicCmd -i $in -l $linker && touch $out",
556		CommandDeps: []string{"$verifyHostBionicCmd"},
557	}, "linker")
558
559func (binary *binaryDecorator) verifyHostBionicLinker(ctx ModuleContext, in, linker android.Path, out android.WritablePath) {
560	ctx.Build(pctx, android.BuildParams{
561		Rule:        verifyHostBionic,
562		Description: "verify host bionic",
563		Input:       in,
564		Implicit:    linker,
565		Output:      out,
566		Args: map[string]string{
567			"linker": linker.String(),
568		},
569	})
570}
571
572type ccBinaryBazelHandler struct {
573	module *Module
574}
575
576var _ BazelHandler = (*ccBinaryBazelHandler)(nil)
577
578func (handler *ccBinaryBazelHandler) QueueBazelCall(ctx android.BaseModuleContext, label string) {
579	bazelCtx := ctx.Config().BazelContext
580	bazelCtx.QueueBazelRequest(label, cquery.GetCcUnstrippedInfo, android.GetConfigKeyApexVariant(ctx, GetApexConfigKey(ctx)))
581}
582
583func (handler *ccBinaryBazelHandler) ProcessBazelQueryResponse(ctx android.ModuleContext, label string) {
584	bazelCtx := ctx.Config().BazelContext
585	info, err := bazelCtx.GetCcUnstrippedInfo(label, android.GetConfigKeyApexVariant(ctx, GetApexConfigKey(ctx)))
586	if err != nil {
587		ctx.ModuleErrorf(err.Error())
588		return
589	}
590
591	var outputFilePath android.Path = android.PathForBazelOut(ctx, info.OutputFile)
592	if len(info.TidyFiles) > 0 {
593		handler.module.tidyFiles = android.PathsForBazelOut(ctx, info.TidyFiles)
594		outputFilePath = android.AttachValidationActions(ctx, outputFilePath, handler.module.tidyFiles)
595	}
596	handler.module.outputFile = android.OptionalPathForPath(outputFilePath)
597	handler.module.linker.(*binaryDecorator).unstrippedOutputFile = android.PathForBazelOut(ctx, info.UnstrippedOutput)
598
599	handler.module.setAndroidMkVariablesFromCquery(info.CcAndroidMkInfo)
600}
601
602func binaryBp2buildAttrs(ctx android.TopDownMutatorContext, m *Module) binaryAttributes {
603	baseAttrs := bp2BuildParseBaseProps(ctx, m)
604	binaryLinkerAttrs := bp2buildBinaryLinkerProps(ctx, m)
605
606	if proptools.BoolDefault(binaryLinkerAttrs.Linkshared, true) {
607		baseAttrs.implementationDynamicDeps.Add(baseAttrs.protoDependency)
608	} else {
609		baseAttrs.implementationDeps.Add(baseAttrs.protoDependency)
610	}
611
612	attrs := binaryAttributes{
613		binaryLinkerAttrs: binaryLinkerAttrs,
614
615		Srcs:    baseAttrs.srcs,
616		Srcs_c:  baseAttrs.cSrcs,
617		Srcs_as: baseAttrs.asSrcs,
618
619		Copts:      baseAttrs.copts,
620		Cppflags:   baseAttrs.cppFlags,
621		Conlyflags: baseAttrs.conlyFlags,
622		Asflags:    baseAttrs.asFlags,
623
624		Deps:               baseAttrs.implementationDeps,
625		Dynamic_deps:       baseAttrs.implementationDynamicDeps,
626		Whole_archive_deps: baseAttrs.wholeArchiveDeps,
627		System_deps:        baseAttrs.systemDynamicDeps,
628		Runtime_deps:       baseAttrs.runtimeDeps,
629
630		Local_includes:    baseAttrs.localIncludes,
631		Absolute_includes: baseAttrs.absoluteIncludes,
632		Linkopts:          baseAttrs.linkopts,
633		Use_version_lib:   baseAttrs.useVersionLib,
634		Rtti:              baseAttrs.rtti,
635		Stl:               baseAttrs.stl,
636		Cpp_std:           baseAttrs.cppStd,
637
638		Additional_linker_inputs: baseAttrs.additionalLinkerInputs,
639
640		Strip: stripAttributes{
641			Keep_symbols:                 baseAttrs.stripKeepSymbols,
642			Keep_symbols_and_debug_frame: baseAttrs.stripKeepSymbolsAndDebugFrame,
643			Keep_symbols_list:            baseAttrs.stripKeepSymbolsList,
644			All:                          baseAttrs.stripAll,
645			None:                         baseAttrs.stripNone,
646		},
647
648		Features: baseAttrs.features,
649
650		sdkAttributes: bp2BuildParseSdkAttributes(m),
651
652		Native_coverage: baseAttrs.Native_coverage,
653	}
654
655	m.convertTidyAttributes(ctx, &attrs.tidyAttributes)
656
657	return attrs
658}
659
660func binaryBp2build(ctx android.TopDownMutatorContext, m *Module) {
661	// shared with cc_test
662	binaryAttrs := binaryBp2buildAttrs(ctx, m)
663
664	tags := android.ApexAvailableTags(m)
665	ctx.CreateBazelTargetModule(bazel.BazelTargetModuleProperties{
666		Rule_class:        "cc_binary",
667		Bzl_load_location: "//build/bazel/rules/cc:cc_binary.bzl",
668	},
669		android.CommonAttributes{Name: m.Name(), Tags: tags},
670		&binaryAttrs)
671}
672
673// binaryAttributes contains Bazel attributes corresponding to a cc binary
674type binaryAttributes struct {
675	binaryLinkerAttrs
676	Srcs    bazel.LabelListAttribute
677	Srcs_c  bazel.LabelListAttribute
678	Srcs_as bazel.LabelListAttribute
679
680	Copts      bazel.StringListAttribute
681	Cppflags   bazel.StringListAttribute
682	Conlyflags bazel.StringListAttribute
683	Asflags    bazel.StringListAttribute
684
685	Deps               bazel.LabelListAttribute
686	Dynamic_deps       bazel.LabelListAttribute
687	Whole_archive_deps bazel.LabelListAttribute
688	System_deps        bazel.LabelListAttribute
689	Runtime_deps       bazel.LabelListAttribute
690
691	Local_includes    bazel.StringListAttribute
692	Absolute_includes bazel.StringListAttribute
693
694	Linkopts                 bazel.StringListAttribute
695	Additional_linker_inputs bazel.LabelListAttribute
696	Use_version_lib          bazel.BoolAttribute
697
698	Rtti    bazel.BoolAttribute
699	Stl     *string
700	Cpp_std *string
701
702	Strip stripAttributes
703
704	Features bazel.StringListAttribute
705
706	sdkAttributes
707
708	tidyAttributes
709
710	Native_coverage *bool
711}
712