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