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 "github.com/google/blueprint/proptools" 21 22 "android/soong/android" 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 sourceModuleName() string 42} 43 44type prebuiltLinkerProperties struct { 45 // Name of the source soong module that gets shadowed by this prebuilt 46 // If unspecified, follows the naming convention that the source module of 47 // the prebuilt is Name() without "prebuilt_" prefix 48 Source_module_name *string 49 50 // a prebuilt library or binary. Can reference a genrule module that generates an executable file. 51 Srcs []string `android:"path,arch_variant"` 52 53 Sanitized Sanitized `android:"arch_variant"` 54 55 // Check the prebuilt ELF files (e.g. DT_SONAME, DT_NEEDED, resolution of undefined 56 // symbols, etc), default true. 57 Check_elf_files *bool 58 59 // if set, add an extra objcopy --prefix-symbols= step 60 Prefix_symbols *string 61 62 // Optionally provide an import library if this is a Windows PE DLL prebuilt. 63 // This is needed only if this library is linked by other modules in build time. 64 // Only makes sense for the Windows target. 65 Windows_import_lib *string `android:"path,arch_variant"` 66} 67 68type prebuiltLinker struct { 69 android.Prebuilt 70 71 properties prebuiltLinkerProperties 72} 73 74func (p *prebuiltLinker) prebuilt() *android.Prebuilt { 75 return &p.Prebuilt 76} 77 78func (p *prebuiltLinker) PrebuiltSrcs() []string { 79 return p.properties.Srcs 80} 81 82type prebuiltLibraryInterface interface { 83 libraryInterface 84 prebuiltLinkerInterface 85 disablePrebuilt() 86} 87 88type prebuiltLibraryLinker struct { 89 *libraryDecorator 90 prebuiltLinker 91} 92 93var _ prebuiltLinkerInterface = (*prebuiltLibraryLinker)(nil) 94var _ prebuiltLibraryInterface = (*prebuiltLibraryLinker)(nil) 95 96func (p *prebuiltLibraryLinker) linkerInit(ctx BaseModuleContext) {} 97 98func (p *prebuiltLibraryLinker) linkerDeps(ctx DepsContext, deps Deps) Deps { 99 return p.libraryDecorator.linkerDeps(ctx, deps) 100} 101 102func (p *prebuiltLibraryLinker) linkerFlags(ctx ModuleContext, flags Flags) Flags { 103 return flags 104} 105 106func (p *prebuiltLibraryLinker) linkerProps() []interface{} { 107 return p.libraryDecorator.linkerProps() 108} 109 110func (p *prebuiltLibraryLinker) link(ctx ModuleContext, 111 flags Flags, deps PathDeps, objs Objects) android.Path { 112 113 p.libraryDecorator.flagExporter.exportIncludes(ctx) 114 p.libraryDecorator.flagExporter.reexportDirs(deps.ReexportedDirs...) 115 p.libraryDecorator.flagExporter.reexportSystemDirs(deps.ReexportedSystemDirs...) 116 p.libraryDecorator.flagExporter.reexportFlags(deps.ReexportedFlags...) 117 p.libraryDecorator.flagExporter.reexportDeps(deps.ReexportedDeps...) 118 p.libraryDecorator.flagExporter.addExportedGeneratedHeaders(deps.ReexportedGeneratedHeaders...) 119 120 p.libraryDecorator.flagExporter.setProvider(ctx) 121 122 // TODO(ccross): verify shared library dependencies 123 srcs := p.prebuiltSrcs(ctx) 124 if len(srcs) > 0 { 125 if len(srcs) > 1 { 126 ctx.PropertyErrorf("srcs", "multiple prebuilt source files") 127 return nil 128 } 129 130 p.libraryDecorator.exportVersioningMacroIfNeeded(ctx) 131 132 in := android.PathForModuleSrc(ctx, srcs[0]) 133 134 if String(p.prebuiltLinker.properties.Prefix_symbols) != "" { 135 prefixed := android.PathForModuleOut(ctx, "prefixed", srcs[0]) 136 transformBinaryPrefixSymbols(ctx, String(p.prebuiltLinker.properties.Prefix_symbols), 137 in, flagsToBuilderFlags(flags), prefixed) 138 in = prefixed 139 } 140 141 if p.static() { 142 depSet := android.NewDepSetBuilder[android.Path](android.TOPOLOGICAL).Direct(in).Build() 143 android.SetProvider(ctx, StaticLibraryInfoProvider, StaticLibraryInfo{ 144 StaticLibrary: in, 145 146 TransitiveStaticLibrariesForOrdering: depSet, 147 }) 148 return in 149 } 150 151 if p.shared() { 152 p.unstrippedOutputFile = in 153 libName := p.libraryDecorator.getLibName(ctx) + flags.Toolchain.ShlibSuffix() 154 outputFile := android.PathForModuleOut(ctx, libName) 155 var implicits android.Paths 156 157 if p.stripper.NeedsStrip(ctx) { 158 stripFlags := flagsToStripFlags(flags) 159 stripped := android.PathForModuleOut(ctx, "stripped", libName) 160 p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, stripFlags) 161 in = stripped 162 } 163 164 // Optimize out relinking against shared libraries whose interface hasn't changed by 165 // depending on a table of contents file instead of the library itself. 166 tocFile := android.PathForModuleOut(ctx, libName+".toc") 167 p.tocFile = android.OptionalPathForPath(tocFile) 168 TransformSharedObjectToToc(ctx, outputFile, tocFile) 169 170 if ctx.Windows() && p.properties.Windows_import_lib != nil { 171 // Consumers of this library actually links to the import library in build 172 // time and dynamically links to the DLL in run time. i.e. 173 // a.exe <-- static link --> foo.lib <-- dynamic link --> foo.dll 174 importLibSrc := android.PathForModuleSrc(ctx, String(p.properties.Windows_import_lib)) 175 importLibName := p.libraryDecorator.getLibName(ctx) + ".lib" 176 importLibOutputFile := android.PathForModuleOut(ctx, importLibName) 177 implicits = append(implicits, importLibOutputFile) 178 179 ctx.Build(pctx, android.BuildParams{ 180 Rule: android.CpExecutable, 181 Description: "prebuilt import library", 182 Input: importLibSrc, 183 Output: importLibOutputFile, 184 Args: map[string]string{ 185 "cpFlags": "-L", 186 }, 187 }) 188 } 189 190 ctx.Build(pctx, android.BuildParams{ 191 Rule: android.CpExecutable, 192 Description: "prebuilt shared library", 193 Implicits: implicits, 194 Input: in, 195 Output: outputFile, 196 Args: map[string]string{ 197 "cpFlags": "-L", 198 }, 199 }) 200 201 android.SetProvider(ctx, SharedLibraryInfoProvider, SharedLibraryInfo{ 202 SharedLibrary: outputFile, 203 Target: ctx.Target(), 204 205 TableOfContents: p.tocFile, 206 }) 207 208 // TODO(b/220898484): Mainline module sdk prebuilts of stub libraries use a stub 209 // library as their source and must not be installed, but other prebuilts like 210 // libclang_rt.* libraries set `stubs` property because they are LLNDK libraries, 211 // but use an implementation library as their source and need to be installed. 212 // This discrepancy should be resolved without the prefix hack below. 213 isModuleSdkPrebuilts := android.HasAnyPrefix(ctx.ModuleDir(), []string{ 214 "prebuilts/runtime/mainline/", "prebuilts/module_sdk/"}) 215 if p.hasStubsVariants() && !p.buildStubs() && !ctx.Host() && isModuleSdkPrebuilts { 216 ctx.Module().MakeUninstallable() 217 } 218 219 return outputFile 220 } 221 } 222 223 if p.header() { 224 android.SetProvider(ctx, HeaderLibraryInfoProvider, HeaderLibraryInfo{}) 225 226 // Need to return an output path so that the AndroidMk logic doesn't skip 227 // the prebuilt header. For compatibility, in case Android.mk files use a 228 // header lib in LOCAL_STATIC_LIBRARIES, create an empty ar file as 229 // placeholder, just like non-prebuilt header modules do in linkStatic(). 230 ph := android.PathForModuleOut(ctx, ctx.ModuleName()+staticLibraryExtension) 231 transformObjToStaticLib(ctx, nil, nil, builderFlags{}, ph, nil, nil) 232 return ph 233 } 234 235 return nil 236} 237 238func (p *prebuiltLibraryLinker) prebuiltSrcs(ctx android.BaseModuleContext) []string { 239 sanitize := ctx.Module().(*Module).sanitize 240 srcs := p.properties.Srcs 241 srcs = append(srcs, srcsForSanitizer(sanitize, p.properties.Sanitized)...) 242 if p.static() { 243 srcs = append(srcs, p.libraryDecorator.StaticProperties.Static.Srcs...) 244 srcs = append(srcs, srcsForSanitizer(sanitize, p.libraryDecorator.StaticProperties.Static.Sanitized)...) 245 } 246 if p.shared() { 247 srcs = append(srcs, p.libraryDecorator.SharedProperties.Shared.Srcs...) 248 srcs = append(srcs, srcsForSanitizer(sanitize, p.libraryDecorator.SharedProperties.Shared.Sanitized)...) 249 } 250 return srcs 251} 252 253func (p *prebuiltLibraryLinker) shared() bool { 254 return p.libraryDecorator.shared() 255} 256 257func (p *prebuiltLibraryLinker) nativeCoverage() bool { 258 return false 259} 260 261func (p *prebuiltLibraryLinker) disablePrebuilt() { 262 p.properties.Srcs = nil 263 p.properties.Sanitized.None.Srcs = nil 264 p.properties.Sanitized.Address.Srcs = nil 265 p.properties.Sanitized.Hwaddress.Srcs = nil 266} 267 268// Implements versionedInterface 269func (p *prebuiltLibraryLinker) implementationModuleName(name string) string { 270 return android.RemoveOptionalPrebuiltPrefix(name) 271} 272 273func NewPrebuiltLibrary(hod android.HostOrDeviceSupported, srcsProperty string) (*Module, *libraryDecorator) { 274 module, library := NewLibrary(hod) 275 module.compiler = nil 276 277 prebuilt := &prebuiltLibraryLinker{ 278 libraryDecorator: library, 279 } 280 module.linker = prebuilt 281 module.library = prebuilt 282 283 module.AddProperties(&prebuilt.properties) 284 285 if srcsProperty == "" { 286 android.InitPrebuiltModuleWithoutSrcs(module) 287 } else { 288 srcsSupplier := func(ctx android.BaseModuleContext, _ android.Module) []string { 289 return prebuilt.prebuiltSrcs(ctx) 290 } 291 292 android.InitPrebuiltModuleWithSrcSupplier(module, srcsSupplier, srcsProperty) 293 } 294 295 return module, library 296} 297 298// cc_prebuilt_library installs a precompiled shared library that are 299// listed in the srcs property in the device's directory. 300func PrebuiltLibraryFactory() android.Module { 301 module, _ := NewPrebuiltLibrary(android.HostAndDeviceSupported, "srcs") 302 303 // Prebuilt shared libraries can be included in APEXes 304 android.InitApexModule(module) 305 306 return module.Init() 307} 308 309// cc_prebuilt_library_shared installs a precompiled shared library that are 310// listed in the srcs property in the device's directory. 311func PrebuiltSharedLibraryFactory() android.Module { 312 module, _ := NewPrebuiltSharedLibrary(android.HostAndDeviceSupported) 313 return module.Init() 314} 315 316// cc_prebuilt_test_library_shared installs a precompiled shared library 317// to be used as a data dependency of a test-related module (such as cc_test, or 318// cc_test_library). 319func PrebuiltSharedTestLibraryFactory() android.Module { 320 module, library := NewPrebuiltLibrary(android.HostAndDeviceSupported, "srcs") 321 library.BuildOnlyShared() 322 library.baseInstaller = NewTestInstaller() 323 return module.Init() 324} 325 326func NewPrebuiltSharedLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { 327 module, library := NewPrebuiltLibrary(hod, "srcs") 328 library.BuildOnlyShared() 329 330 // Prebuilt shared libraries can be included in APEXes 331 android.InitApexModule(module) 332 333 return module, library 334} 335 336// cc_prebuilt_library_static installs a precompiled static library that are 337// listed in the srcs property in the device's directory. 338func PrebuiltStaticLibraryFactory() android.Module { 339 module, _ := NewPrebuiltStaticLibrary(android.HostAndDeviceSupported) 340 return module.Init() 341} 342 343func NewPrebuiltStaticLibrary(hod android.HostOrDeviceSupported) (*Module, *libraryDecorator) { 344 module, library := NewPrebuiltLibrary(hod, "srcs") 345 library.BuildOnlyStatic() 346 347 return module, library 348} 349 350type prebuiltObjectProperties struct { 351 // Name of the source soong module that gets shadowed by this prebuilt 352 // If unspecified, follows the naming convention that the source module of 353 // the prebuilt is Name() without "prebuilt_" prefix 354 Source_module_name *string 355 Srcs []string `android:"path,arch_variant"` 356} 357 358type prebuiltObjectLinker struct { 359 android.Prebuilt 360 objectLinker 361 362 properties prebuiltObjectProperties 363} 364 365func (p *prebuiltObjectLinker) prebuilt() *android.Prebuilt { 366 return &p.Prebuilt 367} 368 369func (p *prebuiltObjectLinker) sourceModuleName() string { 370 return proptools.String(p.properties.Source_module_name) 371} 372 373var _ prebuiltLinkerInterface = (*prebuiltObjectLinker)(nil) 374 375func (p *prebuiltObjectLinker) link(ctx ModuleContext, 376 flags Flags, deps PathDeps, objs Objects) android.Path { 377 if len(p.properties.Srcs) > 0 { 378 // Copy objects to a name matching the final installed name 379 in := p.Prebuilt.SingleSourcePath(ctx) 380 outputFile := android.PathForModuleOut(ctx, ctx.ModuleName()+".o") 381 ctx.Build(pctx, android.BuildParams{ 382 Rule: android.CpExecutable, 383 Description: "prebuilt", 384 Output: outputFile, 385 Input: in, 386 }) 387 return outputFile 388 } 389 return nil 390} 391 392func (p *prebuiltObjectLinker) object() bool { 393 return true 394} 395 396func NewPrebuiltObject(hod android.HostOrDeviceSupported) *Module { 397 module := newObject(hod) 398 prebuilt := &prebuiltObjectLinker{ 399 objectLinker: objectLinker{ 400 baseLinker: NewBaseLinker(nil), 401 }, 402 } 403 module.linker = prebuilt 404 module.AddProperties(&prebuilt.properties) 405 android.InitPrebuiltModule(module, &prebuilt.properties.Srcs) 406 return module 407} 408 409func PrebuiltObjectFactory() android.Module { 410 module := NewPrebuiltObject(android.HostAndDeviceSupported) 411 return module.Init() 412} 413 414type prebuiltBinaryLinker struct { 415 *binaryDecorator 416 prebuiltLinker 417 418 toolPath android.OptionalPath 419} 420 421var _ prebuiltLinkerInterface = (*prebuiltBinaryLinker)(nil) 422 423func (p *prebuiltBinaryLinker) hostToolPath() android.OptionalPath { 424 return p.toolPath 425} 426 427func (p *prebuiltBinaryLinker) link(ctx ModuleContext, 428 flags Flags, deps PathDeps, objs Objects) android.Path { 429 // TODO(ccross): verify shared library dependencies 430 if len(p.properties.Srcs) > 0 { 431 fileName := p.getStem(ctx) + flags.Toolchain.ExecutableSuffix() 432 in := p.Prebuilt.SingleSourcePath(ctx) 433 outputFile := android.PathForModuleOut(ctx, fileName) 434 p.unstrippedOutputFile = in 435 436 if ctx.Host() { 437 // Host binaries are symlinked to their prebuilt source locations. That 438 // way they are executed directly from there so the linker resolves their 439 // shared library dependencies relative to that location (using 440 // $ORIGIN/../lib(64):$ORIGIN/lib(64) as RUNPATH). This way the prebuilt 441 // repository can supply the expected versions of the shared libraries 442 // without interference from what is in the out tree. 443 444 // These shared lib paths may point to copies of the libs in 445 // .intermediates, which isn't where the binary will load them from, but 446 // it's fine for dependency tracking. If a library dependency is updated, 447 // the symlink will get a new timestamp, along with any installed symlinks 448 // handled in make. 449 sharedLibPaths := deps.EarlySharedLibs 450 sharedLibPaths = append(sharedLibPaths, deps.SharedLibs...) 451 sharedLibPaths = append(sharedLibPaths, deps.LateSharedLibs...) 452 453 var fromPath = in.String() 454 if !filepath.IsAbs(fromPath) { 455 fromPath = "$$PWD/" + fromPath 456 } 457 458 ctx.Build(pctx, android.BuildParams{ 459 Rule: android.Symlink, 460 Output: outputFile, 461 Input: in, 462 Implicits: sharedLibPaths, 463 Args: map[string]string{ 464 "fromPath": fromPath, 465 }, 466 }) 467 468 p.toolPath = android.OptionalPathForPath(outputFile) 469 } else { 470 if p.stripper.NeedsStrip(ctx) { 471 stripped := android.PathForModuleOut(ctx, "stripped", fileName) 472 p.stripper.StripExecutableOrSharedLib(ctx, in, stripped, flagsToStripFlags(flags)) 473 in = stripped 474 } 475 476 // Copy binaries to a name matching the final installed name 477 ctx.Build(pctx, android.BuildParams{ 478 Rule: android.CpExecutable, 479 Description: "prebuilt", 480 Output: outputFile, 481 Input: in, 482 }) 483 } 484 485 return outputFile 486 } 487 488 return nil 489} 490 491func (p *prebuiltBinaryLinker) binary() bool { 492 return true 493} 494 495// cc_prebuilt_binary installs a precompiled executable in srcs property in the 496// device's directory, for both the host and device 497func PrebuiltBinaryFactory() android.Module { 498 module, _ := NewPrebuiltBinary(android.HostAndDeviceSupported) 499 return module.Init() 500} 501 502func NewPrebuiltBinary(hod android.HostOrDeviceSupported) (*Module, *binaryDecorator) { 503 module, binary := newBinary(hod) 504 module.compiler = nil 505 506 prebuilt := &prebuiltBinaryLinker{ 507 binaryDecorator: binary, 508 } 509 module.linker = prebuilt 510 module.installer = prebuilt 511 512 module.AddProperties(&prebuilt.properties) 513 514 android.InitPrebuiltModule(module, &prebuilt.properties.Srcs) 515 return module, binary 516} 517 518type Sanitized struct { 519 None struct { 520 Srcs []string `android:"path,arch_variant"` 521 } `android:"arch_variant"` 522 Address struct { 523 Srcs []string `android:"path,arch_variant"` 524 } `android:"arch_variant"` 525 Hwaddress struct { 526 Srcs []string `android:"path,arch_variant"` 527 } `android:"arch_variant"` 528} 529 530func srcsForSanitizer(sanitize *sanitize, sanitized Sanitized) []string { 531 if sanitize == nil { 532 return nil 533 } 534 if sanitize.isSanitizerEnabled(Asan) && sanitized.Address.Srcs != nil { 535 return sanitized.Address.Srcs 536 } 537 if sanitize.isSanitizerEnabled(Hwasan) && sanitized.Hwaddress.Srcs != nil { 538 return sanitized.Hwaddress.Srcs 539 } 540 return sanitized.None.Srcs 541} 542 543func (p *prebuiltLinker) sourceModuleName() string { 544 return proptools.String(p.properties.Source_module_name) 545} 546