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