1// Copyright 2016 Google Inc. All rights reserved. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15package cc 16 17import ( 18 "android/soong/android" 19 "path/filepath" 20 "strings" 21) 22 23func init() { 24 RegisterPrebuiltBuildComponents(android.InitRegistrationContext) 25} 26 27func RegisterPrebuiltBuildComponents(ctx android.RegistrationContext) { 28 ctx.RegisterModuleType("cc_prebuilt_library", PrebuiltLibraryFactory) 29 ctx.RegisterModuleType("cc_prebuilt_library_shared", PrebuiltSharedLibraryFactory) 30 ctx.RegisterModuleType("cc_prebuilt_library_static", PrebuiltStaticLibraryFactory) 31 ctx.RegisterModuleType("cc_prebuilt_test_library_shared", PrebuiltSharedTestLibraryFactory) 32 ctx.RegisterModuleType("cc_prebuilt_object", prebuiltObjectFactory) 33 ctx.RegisterModuleType("cc_prebuilt_binary", prebuiltBinaryFactory) 34} 35 36type prebuiltLinkerInterface interface { 37 Name(string) string 38 prebuilt() *android.Prebuilt 39} 40 41type prebuiltLinkerProperties struct { 42 // a prebuilt library or binary. Can reference a genrule module that generates an executable file. 43 Srcs []string `android:"path,arch_variant"` 44 45 Sanitized Sanitized `android:"arch_variant"` 46 47 // Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined 48 // symbols, etc), default true. 49 Check_elf_files *bool 50 51 // Optionally provide an import library if this is a Windows PE DLL prebuilt. 52 // This is needed only if this library is linked by other modules in build time. 53 // Only makes sense for the Windows target. 54 Windows_import_lib *string `android:"path,arch_variant"` 55} 56 57type prebuiltLinker struct { 58 android.Prebuilt 59 60 properties prebuiltLinkerProperties 61} 62 63func (p *prebuiltLinker) prebuilt() *android.Prebuilt { 64 return &p.Prebuilt 65} 66 67func (p *prebuiltLinker) PrebuiltSrcs() []string { 68 return p.properties.Srcs 69} 70 71type prebuiltLibraryInterface interface { 72 libraryInterface 73 prebuiltLinkerInterface 74 disablePrebuilt() 75} 76 77type prebuiltLibraryLinker struct { 78 *libraryDecorator 79 prebuiltLinker 80} 81 82var _ prebuiltLinkerInterface = (*prebuiltLibraryLinker)(nil) 83var _ prebuiltLibraryInterface = (*prebuiltLibraryLinker)(nil) 84 85func (p *prebuiltLibraryLinker) linkerInit(ctx BaseModuleContext) {} 86 87func (p *prebuiltLibraryLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { 88 return p.libraryDecorator.linkerDeps(ctx, deps) 89} 90 91func (p *prebuiltLibraryLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { 92 return flags 93} 94 95func (p *prebuiltLibraryLinker) linkerProps() []interface{} { 96 return p.libraryDecorator.linkerProps() 97} 98 99func (p *prebuiltLibraryLinker) link(ctx ModuleContext, 100 flags Flags, deps PathDeps, objs Objects) android.Path { 101 102 p.libraryDecorator.flagExporter.exportIncludes(ctx) 103 p.libraryDecorator.flagExporter.reexportDirs(deps.ReexportedDirs...) 104 p.libraryDecorator.flagExporter.reexportSystemDirs(deps.ReexportedSystemDirs...) 105 p.libraryDecorator.flagExporter.reexportFlags(deps.ReexportedFlags...) 106 p.libraryDecorator.flagExporter.reexportDeps(deps.ReexportedDeps...) 107 p.libraryDecorator.flagExporter.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...) 108 109 p.libraryDecorator.flagExporter.setProvider(ctx) 110 111 // TODO(ccross): verify shared library dependencies 112 srcs := p.prebuiltSrcs(ctx) 113 if len(srcs) > 0 { 114 builderFlags := flagsToBuilderFlags(flags) 115 116 if len(srcs) > 1 { 117 ctx.PropertyErrorf("srcs", "multiple prebuilt source files") 118 return nil 119 } 120 121 p.libraryDecorator.exportVersioningMacroIfNeeded(ctx) 122 123 in := android.PathForModuleSrc(ctx, srcs[0]) 124 125 if p.static() { 126 depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(in).Build() 127 ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{ 128 StaticLibrary: in, 129 130 TransitiveStaticLibrariesForOrdering: depSet, 131 }) 132 return in 133 } 134 135 if p.shared() { 136 p.unstrippedOutputFile = in 137 libName := p.libraryDecorator.getLibName(ctx) + flags.Toolchain.ShlibSuffix() 138 outputFile := android.PathForModuleOut(ctx, libName) 139 var implicits android.Paths 140 141 if p.stripper.NeedsStrip(ctx) { 142 stripFlags := flagsToStripFlags(flags) 143 stripped := android.PathForModuleOut(ctx, "stripped", libName) 144 p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, stripFlags) 145 in = stripped 146 } 147 148 // Optimize out relinking against shared libraries whose interface hasn't changed by 149 // depending on a table of contents file instead of the library itself. 150 tocFile := android.PathForModuleOut(ctx, libName+".toc") 151 p.tocFile = android.OptionalPathForPath(tocFile) 152 transformSharedObjectToToc(ctx, outputFile, tocFile, builderFlags) 153 154 if ctx.Windows() && p.properties.Windows_import_lib != nil { 155 // Consumers of this library actually links to the import library in build 156 // time and dynamically links to the DLL in run time. i.e. 157 // a.exe <-- static link --> foo.lib <-- dynamic link --> foo.dll 158 importLibSrc := android.PathForModuleSrc(ctx, String(p.properties.Windows_import_lib)) 159 importLibName := p.libraryDecorator.getLibName(ctx) + ".lib" 160 importLibOutputFile := android.PathForModuleOut(ctx, importLibName) 161 implicits = append(implicits, importLibOutputFile) 162 163 ctx.Build(pctx, android.BuildParams{ 164 Rule: android.Cp, 165 Description: "prebuilt import library", 166 Input: importLibSrc, 167 Output: importLibOutputFile, 168 Args: map[string]string{ 169 "cpFlags": "-L", 170 }, 171 }) 172 } 173 174 ctx.Build(pctx, android.BuildParams{ 175 Rule: android.Cp, 176 Description: "prebuilt shared library", 177 Implicits: implicits, 178 Input: in, 179 Output: outputFile, 180 Args: map[string]string{ 181 "cpFlags": "-L", 182 }, 183 }) 184 185 ctx.SetProvider(SharedLibraryInfoProvider, SharedLibraryInfo{ 186 SharedLibrary: outputFile, 187 UnstrippedSharedLibrary: p.unstrippedOutputFile, 188 Target: ctx.Target(), 189 190 TableOfContents: p.tocFile, 191 }) 192 193 return outputFile 194 } 195 } 196 197 if p.header() { 198 ctx.SetProvider(HeaderLibraryInfoProvider, HeaderLibraryInfo{}) 199 200 return nil 201 } 202 203 return nil 204} 205 206func (p *prebuiltLibraryLinker) prebuiltSrcs(ctx android.BaseModuleContext) []string { 207 sanitize := ctx.Module().(*Module).sanitize 208 srcs := p.properties.Srcs 209 srcs = append(srcs, srcsForSanitizer(sanitize, p.properties.Sanitized)...) 210 if p.static() { 211 srcs = append(srcs, p.libraryDecorator.StaticProperties.Static.Srcs...) 212 srcs = append(srcs, srcsForSanitizer(sanitize, p.libraryDecorator.StaticProperties.Static.Sanitized)...) 213 } 214 if p.shared() { 215 srcs = append(srcs, p.libraryDecorator.SharedProperties.Shared.Srcs...) 216 srcs = append(srcs, srcsForSanitizer(sanitize, p.libraryDecorator.SharedProperties.Shared.Sanitized)...) 217 } 218 return srcs 219} 220 221func (p *prebuiltLibraryLinker) shared() bool { 222 return p.libraryDecorator.shared() 223} 224 225func (p *prebuiltLibraryLinker) nativeCoverage() bool { 226 return false 227} 228 229func (p *prebuiltLibraryLinker) disablePrebuilt() { 230 p.properties.Srcs = nil 231} 232 233// Implements versionedInterface 234func (p *prebuiltLibraryLinker) implementationModuleName(name string) string { 235 return strings.TrimPrefix(name, "prebuilt_") 236} 237 238func NewPrebuiltLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { 239 module, library := NewLibrary(hod) 240 module.compiler = nil 241 242 prebuilt := &prebuiltLibraryLinker{ 243 libraryDecorator: library, 244 } 245 module.linker = prebuilt 246 module.library = prebuilt 247 248 module.AddProperties(&prebuilt.properties) 249 250 srcsSupplier := func(ctx android.BaseModuleContext, _ android.Module) []string { 251 return prebuilt.prebuiltSrcs(ctx) 252 } 253 254 android.InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, "srcs") 255 256 // Prebuilt libraries can be used in SDKs. 257 android.InitSdkAwareModule(module) 258 return module, library 259} 260 261// cc_prebuilt_library installs a precompiled shared library that are 262// listed in the srcs property in the device's directory. 263func PrebuiltLibraryFactory() android.Module { 264 module, _ := NewPrebuiltLibrary(android.HostAndDeviceSupported) 265 266 // Prebuilt shared libraries can be included in APEXes 267 android.InitApexModule(module) 268 269 return module.Init() 270} 271 272// cc_prebuilt_library_shared installs a precompiled shared library that are 273// listed in the srcs property in the device's directory. 274func PrebuiltSharedLibraryFactory() android.Module { 275 module, _ := NewPrebuiltSharedLibrary(android.HostAndDeviceSupported) 276 return module.Init() 277} 278 279// cc_prebuilt_test_library_shared installs a precompiled shared library 280// to be used as a data dependency of a test-related module (such as cc_test, or 281// cc_test_library). 282func PrebuiltSharedTestLibraryFactory() android.Module { 283 module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported) 284 library.BuildOnlyShared() 285 library.baseInstaller = NewTestInstaller() 286 return module.Init() 287} 288 289func NewPrebuiltSharedLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { 290 module, library := NewPrebuiltLibrary(hod) 291 library.BuildOnlyShared() 292 293 // Prebuilt shared libraries can be included in APEXes 294 android.InitApexModule(module) 295 296 return module, library 297} 298 299// cc_prebuilt_library_static installs a precompiled static library that are 300// listed in the srcs property in the device's directory. 301func PrebuiltStaticLibraryFactory() android.Module { 302 module, _ := NewPrebuiltStaticLibrary(android.HostAndDeviceSupported) 303 return module.Init() 304} 305 306func NewPrebuiltStaticLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { 307 module, library := NewPrebuiltLibrary(hod) 308 library.BuildOnlyStatic() 309 module.bazelHandler = &prebuiltStaticLibraryBazelHandler{module: module, library: library} 310 return module, library 311} 312 313type prebuiltObjectProperties struct { 314 Srcs []string `android:"path,arch_variant"` 315} 316 317type prebuiltObjectLinker struct { 318 android.Prebuilt 319 objectLinker 320 321 properties prebuiltObjectProperties 322} 323 324type prebuiltStaticLibraryBazelHandler struct { 325 bazelHandler 326 327 module *Module 328 library *libraryDecorator 329} 330 331func (h *prebuiltStaticLibraryBazelHandler) generateBazelBuildActions(ctx android.ModuleContext, label string) bool { 332 bazelCtx := ctx.Config().BazelContext 333 ccInfo, ok, err := bazelCtx.GetCcInfo(label, ctx.Arch().ArchType) 334 if err != nil { 335 ctx.ModuleErrorf("Error getting Bazel CcInfo: %s", err) 336 } 337 if !ok { 338 return false 339 } 340 staticLibs := ccInfo.CcStaticLibraryFiles 341 if len(staticLibs) > 1 { 342 ctx.ModuleErrorf("expected 1 static library from bazel target %q, got %s", label, staticLibs) 343 return false 344 } 345 346 // TODO(b/184543518): cc_prebuilt_library_static may have properties for re-exporting flags 347 348 // TODO(eakammer):Add stub-related flags if this library is a stub library. 349 // h.library.exportVersioningMacroIfNeeded(ctx) 350 351 // Dependencies on this library will expect collectedSnapshotHeaders to be set, otherwise 352 // validation will fail. For now, set this to an empty list. 353 // TODO(cparsons): More closely mirror the collectHeadersForSnapshot implementation. 354 h.library.collectedSnapshotHeaders = android.Paths{} 355 356 if len(staticLibs) == 0 { 357 h.module.outputFile = android.OptionalPath{} 358 return true 359 } 360 361 out := android.PathForBazelOut(ctx, staticLibs[0]) 362 h.module.outputFile = android.OptionalPathForPath(out) 363 364 depSet := android.NewDepSetBuilder(android.TOPOLOGICAL).Direct(out).Build() 365 ctx.SetProvider(StaticLibraryInfoProvider, StaticLibraryInfo{ 366 StaticLibrary: out, 367 368 TransitiveStaticLibrariesForOrdering: depSet, 369 }) 370 371 return true 372} 373 374func (p *prebuiltObjectLinker) prebuilt() *android.Prebuilt { 375 return &p.Prebuilt 376} 377 378var _ prebuiltLinkerInterface = (*prebuiltObjectLinker)(nil) 379 380func (p *prebuiltObjectLinker) link(ctx ModuleContext, 381 flags Flags, deps PathDeps, objs Objects) android.Path { 382 if len(p.properties.Srcs) > 0 { 383 return p.Prebuilt.SingleSourcePath(ctx) 384 } 385 return nil 386} 387 388func (p *prebuiltObjectLinker) object() bool { 389 return true 390} 391 392func newPrebuiltObject() *Module { 393 module := newObject() 394 prebuilt := &prebuiltObjectLinker{ 395 objectLinker: objectLinker{ 396 baseLinker: NewBaseLinker(nil), 397 }, 398 } 399 module.linker = prebuilt 400 module.AddProperties(&prebuilt.properties) 401 android.InitPrebuiltModule(module, &prebuilt.properties.Srcs) 402 android.InitSdkAwareModule(module) 403 return module 404} 405 406func prebuiltObjectFactory() android.Module { 407 module := newPrebuiltObject() 408 return module.Init() 409} 410 411type prebuiltBinaryLinker struct { 412 *binaryDecorator 413 prebuiltLinker 414 415 toolPath android.OptionalPath 416} 417 418var _ prebuiltLinkerInterface = (*prebuiltBinaryLinker)(nil) 419 420func (p *prebuiltBinaryLinker) hostToolPath() android.OptionalPath { 421 return p.toolPath 422} 423 424func (p *prebuiltBinaryLinker) link(ctx ModuleContext, 425 flags Flags, deps PathDeps, objs Objects) android.Path { 426 // TODO(ccross): verify shared library dependencies 427 if len(p.properties.Srcs) > 0 { 428 fileName := p.getStem(ctx) + flags.Toolchain.ExecutableSuffix() 429 in := p.Prebuilt.SingleSourcePath(ctx) 430 outputFile := android.PathForModuleOut(ctx, fileName) 431 p.unstrippedOutputFile = in 432 433 if ctx.Host() { 434 // Host binaries are symlinked to their prebuilt source locations. That 435 // way they are executed directly from there so the linker resolves their 436 // shared library dependencies relative to that location (using 437 // $ORIGIN/../lib(64):$ORIGIN/lib(64) as RUNPATH). This way the prebuilt 438 // repository can supply the expected versions of the shared libraries 439 // without interference from what is in the out tree. 440 441 // These shared lib paths may point to copies of the libs in 442 // .intermediates, which isn't where the binary will load them from, but 443 // it's fine for dependency tracking. If a library dependency is updated, 444 // the symlink will get a new timestamp, along with any installed symlinks 445 // handled in make. 446 sharedLibPaths := deps.EarlySharedLibs 447 sharedLibPaths = append(sharedLibPaths, deps.SharedLibs...) 448 sharedLibPaths = append(sharedLibPaths, deps.LateSharedLibs...) 449 450 var fromPath = in.String() 451 if !filepath.IsAbs(fromPath) { 452 fromPath = "$$PWD/" + fromPath 453 } 454 455 ctx.Build(pctx, android.BuildParams{ 456 Rule: android.Symlink, 457 Output: outputFile, 458 Input: in, 459 Implicits: sharedLibPaths, 460 Args: map[string]string{ 461 "fromPath": fromPath, 462 }, 463 }) 464 465 p.toolPath = android.OptionalPathForPath(outputFile) 466 } else { 467 if p.stripper.NeedsStrip(ctx) { 468 stripped := android.PathForModuleOut(ctx, "stripped", fileName) 469 p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, flagsToStripFlags(flags)) 470 in = stripped 471 } 472 473 // Copy binaries to a name matching the final installed name 474 ctx.Build(pctx, android.BuildParams{ 475 Rule: android.CpExecutable, 476 Description: "prebuilt", 477 Output: outputFile, 478 Input: in, 479 }) 480 } 481 482 return outputFile 483 } 484 485 return nil 486} 487 488func (p *prebuiltBinaryLinker) binary() bool { 489 return true 490} 491 492// cc_prebuilt_binary installs a precompiled executable in srcs property in the 493// device's directory. 494func prebuiltBinaryFactory() android.Module { 495 module, _ := NewPrebuiltBinary(android.HostAndDeviceSupported) 496 return module.Init() 497} 498 499func NewPrebuiltBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) { 500 module, binary := NewBinary(hod) 501 module.compiler = nil 502 503 prebuilt := &prebuiltBinaryLinker{ 504 binaryDecorator: binary, 505 } 506 module.linker = prebuilt 507 module.installer = prebuilt 508 509 module.AddProperties(&prebuilt.properties) 510 511 android.InitPrebuiltModule(module, &prebuilt.properties.Srcs) 512 return module, binary 513} 514 515type Sanitized struct { 516 None struct { 517 Srcs []string `android:"path,arch_variant"` 518 } `android:"arch_variant"` 519 Address struct { 520 Srcs []string `android:"path,arch_variant"` 521 } `android:"arch_variant"` 522 Hwaddress struct { 523 Srcs []string `android:"path,arch_variant"` 524 } `android:"arch_variant"` 525} 526 527func srcsForSanitizer(sanitize *sanitize, sanitized Sanitized) []string { 528 if sanitize == nil { 529 return nil 530 } 531 if Bool(sanitize.Properties.Sanitize.Address) && sanitized.Address.Srcs != nil { 532 return sanitized.Address.Srcs 533 } 534 if Bool(sanitize.Properties.Sanitize.Hwaddress) && sanitized.Hwaddress.Srcs != nil { 535 return sanitized.Hwaddress.Srcs 536 } 537 return sanitized.None.Srcs 538} 539