1// Copyright 2017 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 "encoding/json" 19 "errors" 20 "fmt" 21 "path/filepath" 22 "sort" 23 "strings" 24 "sync" 25 26 "android/soong/android" 27 "android/soong/cc/config" 28 "android/soong/etc" 29) 30 31const ( 32 llndkLibrariesTxt = "llndk.libraries.txt" 33 vndkCoreLibrariesTxt = "vndkcore.libraries.txt" 34 vndkSpLibrariesTxt = "vndksp.libraries.txt" 35 vndkPrivateLibrariesTxt = "vndkprivate.libraries.txt" 36 vndkUsingCoreVariantLibrariesTxt = "vndkcorevariant.libraries.txt" 37) 38 39func VndkLibrariesTxtModules(vndkVersion string) []string { 40 if vndkVersion == "current" { 41 return []string{ 42 llndkLibrariesTxt, 43 vndkCoreLibrariesTxt, 44 vndkSpLibrariesTxt, 45 vndkPrivateLibrariesTxt, 46 } 47 } 48 // Snapshot vndks have their own *.libraries.VER.txt files. 49 // Note that snapshots don't have "vndkcorevariant.libraries.VER.txt" 50 return []string{ 51 insertVndkVersion(llndkLibrariesTxt, vndkVersion), 52 insertVndkVersion(vndkCoreLibrariesTxt, vndkVersion), 53 insertVndkVersion(vndkSpLibrariesTxt, vndkVersion), 54 insertVndkVersion(vndkPrivateLibrariesTxt, vndkVersion), 55 } 56} 57 58type VndkProperties struct { 59 Vndk struct { 60 // declared as a VNDK or VNDK-SP module. The vendor variant 61 // will be installed in /system instead of /vendor partition. 62 // 63 // `vendor_available` must be explicitly set to either true or 64 // false together with `vndk: {enabled: true}`. 65 Enabled *bool 66 67 // declared as a VNDK-SP module, which is a subset of VNDK. 68 // 69 // `vndk: { enabled: true }` must set together. 70 // 71 // All these modules are allowed to link to VNDK-SP or LL-NDK 72 // modules only. Other dependency will cause link-type errors. 73 // 74 // If `support_system_process` is not set or set to false, 75 // the module is VNDK-core and can link to other VNDK-core, 76 // VNDK-SP or LL-NDK modules only. 77 Support_system_process *bool 78 79 // Extending another module 80 Extends *string 81 } 82} 83 84type vndkdep struct { 85 Properties VndkProperties 86} 87 88func (vndk *vndkdep) props() []interface{} { 89 return []interface{}{&vndk.Properties} 90} 91 92func (vndk *vndkdep) begin(ctx BaseModuleContext) {} 93 94func (vndk *vndkdep) deps(ctx BaseModuleContext, deps Deps) Deps { 95 return deps 96} 97 98func (vndk *vndkdep) isVndk() bool { 99 return Bool(vndk.Properties.Vndk.Enabled) 100} 101 102func (vndk *vndkdep) isVndkSp() bool { 103 return Bool(vndk.Properties.Vndk.Support_system_process) 104} 105 106func (vndk *vndkdep) isVndkExt() bool { 107 return vndk.Properties.Vndk.Extends != nil 108} 109 110func (vndk *vndkdep) getVndkExtendsModuleName() string { 111 return String(vndk.Properties.Vndk.Extends) 112} 113 114func (vndk *vndkdep) typeName() string { 115 if !vndk.isVndk() { 116 return "native:vendor" 117 } 118 if !vndk.isVndkExt() { 119 if !vndk.isVndkSp() { 120 return "native:vendor:vndk" 121 } 122 return "native:vendor:vndksp" 123 } 124 if !vndk.isVndkSp() { 125 return "native:vendor:vndkext" 126 } 127 return "native:vendor:vndkspext" 128} 129 130func (vndk *vndkdep) vndkCheckLinkType(ctx android.ModuleContext, to *Module, tag DependencyTag) { 131 if to.linker == nil { 132 return 133 } 134 if !vndk.isVndk() { 135 // Non-VNDK modules (those installed to /vendor, /product, or /system/product) can't depend 136 // on modules marked with vendor_available: false. 137 violation := false 138 if lib, ok := to.linker.(*llndkStubDecorator); ok && !Bool(lib.Properties.Vendor_available) { 139 violation = true 140 } else { 141 if _, ok := to.linker.(libraryInterface); ok && to.VendorProperties.Vendor_available != nil && !Bool(to.VendorProperties.Vendor_available) { 142 // Vendor_available == nil && !Bool(Vendor_available) should be okay since 143 // it means a vendor-only, or product-only library which is a valid dependency 144 // for non-VNDK modules. 145 violation = true 146 } 147 } 148 if violation { 149 ctx.ModuleErrorf("Vendor module that is not VNDK should not link to %q which is marked as `vendor_available: false`", to.Name()) 150 } 151 } 152 if lib, ok := to.linker.(*libraryDecorator); !ok || !lib.shared() { 153 // Check only shared libraries. 154 // Other (static and LL-NDK) libraries are allowed to link. 155 return 156 } 157 if !to.UseVndk() { 158 ctx.ModuleErrorf("(%s) should not link to %q which is not a vendor-available library", 159 vndk.typeName(), to.Name()) 160 return 161 } 162 if tag == vndkExtDepTag { 163 // Ensure `extends: "name"` property refers a vndk module that has vendor_available 164 // and has identical vndk properties. 165 if to.vndkdep == nil || !to.vndkdep.isVndk() { 166 ctx.ModuleErrorf("`extends` refers a non-vndk module %q", to.Name()) 167 return 168 } 169 if vndk.isVndkSp() != to.vndkdep.isVndkSp() { 170 ctx.ModuleErrorf( 171 "`extends` refers a module %q with mismatched support_system_process", 172 to.Name()) 173 return 174 } 175 if !Bool(to.VendorProperties.Vendor_available) { 176 ctx.ModuleErrorf( 177 "`extends` refers module %q which does not have `vendor_available: true`", 178 to.Name()) 179 return 180 } 181 } 182 if to.vndkdep == nil { 183 return 184 } 185 186 // Check the dependencies of VNDK shared libraries. 187 if err := vndkIsVndkDepAllowed(vndk, to.vndkdep); err != nil { 188 ctx.ModuleErrorf("(%s) should not link to %q (%s): %v", 189 vndk.typeName(), to.Name(), to.vndkdep.typeName(), err) 190 return 191 } 192} 193 194func vndkIsVndkDepAllowed(from *vndkdep, to *vndkdep) error { 195 // Check the dependencies of VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext and vendor modules. 196 if from.isVndkExt() { 197 if from.isVndkSp() { 198 if to.isVndk() && !to.isVndkSp() { 199 return errors.New("VNDK-SP extensions must not depend on VNDK or VNDK extensions") 200 } 201 return nil 202 } 203 // VNDK-Ext may depend on VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext, or vendor libs. 204 return nil 205 } 206 if from.isVndk() { 207 if to.isVndkExt() { 208 return errors.New("VNDK-core and VNDK-SP must not depend on VNDK extensions") 209 } 210 if from.isVndkSp() { 211 if !to.isVndkSp() { 212 return errors.New("VNDK-SP must only depend on VNDK-SP") 213 } 214 return nil 215 } 216 if !to.isVndk() { 217 return errors.New("VNDK-core must only depend on VNDK-core or VNDK-SP") 218 } 219 return nil 220 } 221 // Vendor modules may depend on VNDK, VNDK-Ext, VNDK-SP, VNDK-SP-Ext, or vendor libs. 222 return nil 223} 224 225var ( 226 vndkCoreLibrariesKey = android.NewOnceKey("vndkCoreLibrarires") 227 vndkSpLibrariesKey = android.NewOnceKey("vndkSpLibrarires") 228 llndkLibrariesKey = android.NewOnceKey("llndkLibrarires") 229 vndkPrivateLibrariesKey = android.NewOnceKey("vndkPrivateLibrarires") 230 vndkUsingCoreVariantLibrariesKey = android.NewOnceKey("vndkUsingCoreVariantLibraries") 231 vndkMustUseVendorVariantListKey = android.NewOnceKey("vndkMustUseVendorVariantListKey") 232 vndkLibrariesLock sync.Mutex 233) 234 235func vndkCoreLibraries(config android.Config) map[string]string { 236 return config.Once(vndkCoreLibrariesKey, func() interface{} { 237 return make(map[string]string) 238 }).(map[string]string) 239} 240 241func vndkSpLibraries(config android.Config) map[string]string { 242 return config.Once(vndkSpLibrariesKey, func() interface{} { 243 return make(map[string]string) 244 }).(map[string]string) 245} 246 247func isLlndkLibrary(baseModuleName string, config android.Config) bool { 248 _, ok := llndkLibraries(config)[baseModuleName] 249 return ok 250} 251 252func llndkLibraries(config android.Config) map[string]string { 253 return config.Once(llndkLibrariesKey, func() interface{} { 254 return make(map[string]string) 255 }).(map[string]string) 256} 257 258func isVndkPrivateLibrary(baseModuleName string, config android.Config) bool { 259 _, ok := vndkPrivateLibraries(config)[baseModuleName] 260 return ok 261} 262 263func vndkPrivateLibraries(config android.Config) map[string]string { 264 return config.Once(vndkPrivateLibrariesKey, func() interface{} { 265 return make(map[string]string) 266 }).(map[string]string) 267} 268 269func vndkUsingCoreVariantLibraries(config android.Config) map[string]string { 270 return config.Once(vndkUsingCoreVariantLibrariesKey, func() interface{} { 271 return make(map[string]string) 272 }).(map[string]string) 273} 274 275func vndkMustUseVendorVariantList(cfg android.Config) []string { 276 return cfg.Once(vndkMustUseVendorVariantListKey, func() interface{} { 277 return config.VndkMustUseVendorVariantList 278 }).([]string) 279} 280 281// test may call this to override global configuration(config.VndkMustUseVendorVariantList) 282// when it is called, it must be before the first call to vndkMustUseVendorVariantList() 283func setVndkMustUseVendorVariantListForTest(config android.Config, mustUseVendorVariantList []string) { 284 config.Once(vndkMustUseVendorVariantListKey, func() interface{} { 285 return mustUseVendorVariantList 286 }) 287} 288 289func processLlndkLibrary(mctx android.BottomUpMutatorContext, m *Module) { 290 lib := m.linker.(*llndkStubDecorator) 291 name := m.BaseModuleName() 292 filename := m.BaseModuleName() + ".so" 293 294 vndkLibrariesLock.Lock() 295 defer vndkLibrariesLock.Unlock() 296 297 llndkLibraries(mctx.Config())[name] = filename 298 if !Bool(lib.Properties.Vendor_available) { 299 vndkPrivateLibraries(mctx.Config())[name] = filename 300 } 301 if mctx.OtherModuleExists(name) { 302 mctx.AddFarVariationDependencies(m.Target().Variations(), llndkImplDep, name) 303 } 304} 305 306func processVndkLibrary(mctx android.BottomUpMutatorContext, m *Module) { 307 name := m.BaseModuleName() 308 filename, err := getVndkFileName(m) 309 if err != nil { 310 panic(err) 311 } 312 313 if m.HasStubsVariants() { 314 mctx.PropertyErrorf("vndk.enabled", "This library provides stubs. Shouldn't be VNDK. Consider making it as LLNDK") 315 } 316 317 vndkLibrariesLock.Lock() 318 defer vndkLibrariesLock.Unlock() 319 320 if inList(name, vndkMustUseVendorVariantList(mctx.Config())) { 321 m.Properties.MustUseVendorVariant = true 322 } 323 if mctx.DeviceConfig().VndkUseCoreVariant() && !m.Properties.MustUseVendorVariant { 324 vndkUsingCoreVariantLibraries(mctx.Config())[name] = filename 325 } 326 327 if m.vndkdep.isVndkSp() { 328 vndkSpLibraries(mctx.Config())[name] = filename 329 } else { 330 vndkCoreLibraries(mctx.Config())[name] = filename 331 } 332 if !Bool(m.VendorProperties.Vendor_available) { 333 vndkPrivateLibraries(mctx.Config())[name] = filename 334 } 335} 336 337// Sanity check for modules that mustn't be VNDK 338func shouldSkipVndkMutator(m *Module) bool { 339 if !m.Enabled() { 340 return true 341 } 342 if !m.Device() { 343 // Skip non-device modules 344 return true 345 } 346 if m.Target().NativeBridge == android.NativeBridgeEnabled { 347 // Skip native_bridge modules 348 return true 349 } 350 return false 351} 352 353func IsForVndkApex(mctx android.BottomUpMutatorContext, m *Module) bool { 354 if shouldSkipVndkMutator(m) { 355 return false 356 } 357 358 // prebuilt vndk modules should match with device 359 // TODO(b/142675459): Use enabled: to select target device in vndk_prebuilt_shared 360 // When b/142675459 is landed, remove following check 361 if p, ok := m.linker.(*vndkPrebuiltLibraryDecorator); ok && !p.matchesWithDevice(mctx.DeviceConfig()) { 362 return false 363 } 364 365 if lib, ok := m.linker.(libraryInterface); ok { 366 // VNDK APEX for VNDK-Lite devices will have VNDK-SP libraries from core variants 367 if mctx.DeviceConfig().VndkVersion() == "" { 368 // b/73296261: filter out libz.so because it is considered as LLNDK for VNDK-lite devices 369 if mctx.ModuleName() == "libz" { 370 return false 371 } 372 return m.ImageVariation().Variation == android.CoreVariation && lib.shared() && m.isVndkSp() 373 } 374 375 useCoreVariant := m.VndkVersion() == mctx.DeviceConfig().PlatformVndkVersion() && 376 mctx.DeviceConfig().VndkUseCoreVariant() && !m.MustUseVendorVariant() 377 return lib.shared() && m.inVendor() && m.IsVndk() && !m.isVndkExt() && !useCoreVariant 378 } 379 return false 380} 381 382// gather list of vndk-core, vndk-sp, and ll-ndk libs 383func VndkMutator(mctx android.BottomUpMutatorContext) { 384 m, ok := mctx.Module().(*Module) 385 if !ok { 386 return 387 } 388 389 if shouldSkipVndkMutator(m) { 390 return 391 } 392 393 if _, ok := m.linker.(*llndkStubDecorator); ok { 394 processLlndkLibrary(mctx, m) 395 return 396 } 397 398 lib, is_lib := m.linker.(*libraryDecorator) 399 prebuilt_lib, is_prebuilt_lib := m.linker.(*prebuiltLibraryLinker) 400 401 if (is_lib && lib.buildShared()) || (is_prebuilt_lib && prebuilt_lib.buildShared()) { 402 if m.vndkdep != nil && m.vndkdep.isVndk() && !m.vndkdep.isVndkExt() { 403 processVndkLibrary(mctx, m) 404 return 405 } 406 } 407} 408 409func init() { 410 android.RegisterModuleType("vndk_libraries_txt", VndkLibrariesTxtFactory) 411 android.RegisterSingletonType("vndk-snapshot", VndkSnapshotSingleton) 412} 413 414type vndkLibrariesTxt struct { 415 android.ModuleBase 416 outputFile android.OutputPath 417} 418 419var _ etc.PrebuiltEtcModule = &vndkLibrariesTxt{} 420var _ android.OutputFileProducer = &vndkLibrariesTxt{} 421 422// vndk_libraries_txt is a special kind of module type in that it name is one of 423// - llndk.libraries.txt 424// - vndkcore.libraries.txt 425// - vndksp.libraries.txt 426// - vndkprivate.libraries.txt 427// - vndkcorevariant.libraries.txt 428// A module behaves like a prebuilt_etc but its content is generated by soong. 429// By being a soong module, these files can be referenced by other soong modules. 430// For example, apex_vndk can depend on these files as prebuilt. 431func VndkLibrariesTxtFactory() android.Module { 432 m := &vndkLibrariesTxt{} 433 android.InitAndroidModule(m) 434 return m 435} 436 437func insertVndkVersion(filename string, vndkVersion string) string { 438 if index := strings.LastIndex(filename, "."); index != -1 { 439 return filename[:index] + "." + vndkVersion + filename[index:] 440 } 441 return filename 442} 443 444func (txt *vndkLibrariesTxt) GenerateAndroidBuildActions(ctx android.ModuleContext) { 445 var list []string 446 switch txt.Name() { 447 case llndkLibrariesTxt: 448 for _, filename := range android.SortedStringMapValues(llndkLibraries(ctx.Config())) { 449 if strings.HasPrefix(filename, "libclang_rt.hwasan-") { 450 continue 451 } 452 list = append(list, filename) 453 } 454 case vndkCoreLibrariesTxt: 455 list = android.SortedStringMapValues(vndkCoreLibraries(ctx.Config())) 456 case vndkSpLibrariesTxt: 457 list = android.SortedStringMapValues(vndkSpLibraries(ctx.Config())) 458 case vndkPrivateLibrariesTxt: 459 list = android.SortedStringMapValues(vndkPrivateLibraries(ctx.Config())) 460 case vndkUsingCoreVariantLibrariesTxt: 461 list = android.SortedStringMapValues(vndkUsingCoreVariantLibraries(ctx.Config())) 462 default: 463 ctx.ModuleErrorf("name(%s) is unknown.", txt.Name()) 464 return 465 } 466 467 var filename string 468 if txt.Name() != vndkUsingCoreVariantLibrariesTxt { 469 filename = insertVndkVersion(txt.Name(), ctx.DeviceConfig().PlatformVndkVersion()) 470 } else { 471 filename = txt.Name() 472 } 473 474 txt.outputFile = android.PathForModuleOut(ctx, filename).OutputPath 475 ctx.Build(pctx, android.BuildParams{ 476 Rule: android.WriteFile, 477 Output: txt.outputFile, 478 Description: "Writing " + txt.outputFile.String(), 479 Args: map[string]string{ 480 "content": strings.Join(list, "\\n"), 481 }, 482 }) 483 484 installPath := android.PathForModuleInstall(ctx, "etc") 485 ctx.InstallFile(installPath, filename, txt.outputFile) 486} 487 488func (txt *vndkLibrariesTxt) AndroidMkEntries() []android.AndroidMkEntries { 489 return []android.AndroidMkEntries{android.AndroidMkEntries{ 490 Class: "ETC", 491 OutputFile: android.OptionalPathForPath(txt.outputFile), 492 ExtraEntries: []android.AndroidMkExtraEntriesFunc{ 493 func(entries *android.AndroidMkEntries) { 494 entries.SetString("LOCAL_MODULE_STEM", txt.outputFile.Base()) 495 }, 496 }, 497 }} 498} 499 500func (txt *vndkLibrariesTxt) OutputFile() android.OutputPath { 501 return txt.outputFile 502} 503 504func (txt *vndkLibrariesTxt) OutputFiles(tag string) (android.Paths, error) { 505 return android.Paths{txt.outputFile}, nil 506} 507 508func (txt *vndkLibrariesTxt) SubDir() string { 509 return "" 510} 511 512func VndkSnapshotSingleton() android.Singleton { 513 return &vndkSnapshotSingleton{} 514} 515 516type vndkSnapshotSingleton struct { 517 vndkLibrariesFile android.OutputPath 518 vndkSnapshotZipFile android.OptionalPath 519} 520 521func isVndkSnapshotLibrary(config android.DeviceConfig, m *Module) (i snapshotLibraryInterface, vndkType string, isVndkSnapshotLib bool) { 522 if m.Target().NativeBridge == android.NativeBridgeEnabled { 523 return nil, "", false 524 } 525 if !m.inVendor() || !m.installable() || m.isSnapshotPrebuilt() { 526 return nil, "", false 527 } 528 l, ok := m.linker.(snapshotLibraryInterface) 529 if !ok || !l.shared() { 530 return nil, "", false 531 } 532 if m.VndkVersion() == config.PlatformVndkVersion() && m.IsVndk() && !m.isVndkExt() { 533 if m.isVndkSp() { 534 return l, "vndk-sp", true 535 } else { 536 return l, "vndk-core", true 537 } 538 } 539 540 return nil, "", false 541} 542 543func (c *vndkSnapshotSingleton) GenerateBuildActions(ctx android.SingletonContext) { 544 // build these files even if PlatformVndkVersion or BoardVndkVersion is not set 545 c.buildVndkLibrariesTxtFiles(ctx) 546 547 // BOARD_VNDK_VERSION must be set to 'current' in order to generate a VNDK snapshot. 548 if ctx.DeviceConfig().VndkVersion() != "current" { 549 return 550 } 551 552 if ctx.DeviceConfig().PlatformVndkVersion() == "" { 553 return 554 } 555 556 if ctx.DeviceConfig().BoardVndkRuntimeDisable() { 557 return 558 } 559 560 var snapshotOutputs android.Paths 561 562 /* 563 VNDK snapshot zipped artifacts directory structure: 564 {SNAPSHOT_ARCH}/ 565 arch-{TARGET_ARCH}-{TARGET_ARCH_VARIANT}/ 566 shared/ 567 vndk-core/ 568 (VNDK-core libraries, e.g. libbinder.so) 569 vndk-sp/ 570 (VNDK-SP libraries, e.g. libc++.so) 571 arch-{TARGET_2ND_ARCH}-{TARGET_2ND_ARCH_VARIANT}/ 572 shared/ 573 vndk-core/ 574 (VNDK-core libraries, e.g. libbinder.so) 575 vndk-sp/ 576 (VNDK-SP libraries, e.g. libc++.so) 577 binder32/ 578 (This directory is newly introduced in v28 (Android P) to hold 579 prebuilts built for 32-bit binder interface.) 580 arch-{TARGET_ARCH}-{TARGE_ARCH_VARIANT}/ 581 ... 582 configs/ 583 (various *.txt configuration files) 584 include/ 585 (header files of same directory structure with source tree) 586 NOTICE_FILES/ 587 (notice files of libraries, e.g. libcutils.so.txt) 588 */ 589 590 snapshotDir := "vndk-snapshot" 591 snapshotArchDir := filepath.Join(snapshotDir, ctx.DeviceConfig().DeviceArch()) 592 593 configsDir := filepath.Join(snapshotArchDir, "configs") 594 noticeDir := filepath.Join(snapshotArchDir, "NOTICE_FILES") 595 includeDir := filepath.Join(snapshotArchDir, "include") 596 597 // set of notice files copied. 598 noticeBuilt := make(map[string]bool) 599 600 // paths of VNDK modules for GPL license checking 601 modulePaths := make(map[string]string) 602 603 // actual module names of .so files 604 // e.g. moduleNames["libprotobuf-cpp-full-3.9.1.so"] = "libprotobuf-cpp-full" 605 moduleNames := make(map[string]string) 606 607 var headers android.Paths 608 609 installVndkSnapshotLib := func(m *Module, l snapshotLibraryInterface, vndkType string) (android.Paths, bool) { 610 var ret android.Paths 611 612 targetArch := "arch-" + m.Target().Arch.ArchType.String() 613 if m.Target().Arch.ArchVariant != "" { 614 targetArch += "-" + m.Target().Arch.ArchVariant 615 } 616 617 libPath := m.outputFile.Path() 618 snapshotLibOut := filepath.Join(snapshotArchDir, targetArch, "shared", vndkType, libPath.Base()) 619 ret = append(ret, copyFile(ctx, libPath, snapshotLibOut)) 620 621 if ctx.Config().VndkSnapshotBuildArtifacts() { 622 prop := struct { 623 ExportedDirs []string `json:",omitempty"` 624 ExportedSystemDirs []string `json:",omitempty"` 625 ExportedFlags []string `json:",omitempty"` 626 RelativeInstallPath string `json:",omitempty"` 627 }{} 628 prop.ExportedFlags = l.exportedFlags() 629 prop.ExportedDirs = l.exportedDirs().Strings() 630 prop.ExportedSystemDirs = l.exportedSystemDirs().Strings() 631 prop.RelativeInstallPath = m.RelativeInstallPath() 632 633 propOut := snapshotLibOut + ".json" 634 635 j, err := json.Marshal(prop) 636 if err != nil { 637 ctx.Errorf("json marshal to %q failed: %#v", propOut, err) 638 return nil, false 639 } 640 ret = append(ret, writeStringToFile(ctx, string(j), propOut)) 641 } 642 return ret, true 643 } 644 645 ctx.VisitAllModules(func(module android.Module) { 646 m, ok := module.(*Module) 647 if !ok || !m.Enabled() { 648 return 649 } 650 651 l, vndkType, ok := isVndkSnapshotLibrary(ctx.DeviceConfig(), m) 652 if !ok { 653 return 654 } 655 656 // install .so files for appropriate modules. 657 // Also install .json files if VNDK_SNAPSHOT_BUILD_ARTIFACTS 658 libs, ok := installVndkSnapshotLib(m, l, vndkType) 659 if !ok { 660 return 661 } 662 snapshotOutputs = append(snapshotOutputs, libs...) 663 664 // These are for generating module_names.txt and module_paths.txt 665 stem := m.outputFile.Path().Base() 666 moduleNames[stem] = ctx.ModuleName(m) 667 modulePaths[stem] = ctx.ModuleDir(m) 668 669 if m.NoticeFile().Valid() { 670 noticeName := stem + ".txt" 671 // skip already copied notice file 672 if _, ok := noticeBuilt[noticeName]; !ok { 673 noticeBuilt[noticeName] = true 674 snapshotOutputs = append(snapshotOutputs, copyFile( 675 ctx, m.NoticeFile().Path(), filepath.Join(noticeDir, noticeName))) 676 } 677 } 678 679 if ctx.Config().VndkSnapshotBuildArtifacts() { 680 headers = append(headers, l.snapshotHeaders()...) 681 } 682 }) 683 684 // install all headers after removing duplicates 685 for _, header := range android.FirstUniquePaths(headers) { 686 snapshotOutputs = append(snapshotOutputs, copyFile( 687 ctx, header, filepath.Join(includeDir, header.String()))) 688 } 689 690 // install *.libraries.txt except vndkcorevariant.libraries.txt 691 ctx.VisitAllModules(func(module android.Module) { 692 m, ok := module.(*vndkLibrariesTxt) 693 if !ok || !m.Enabled() || m.Name() == vndkUsingCoreVariantLibrariesTxt { 694 return 695 } 696 snapshotOutputs = append(snapshotOutputs, copyFile( 697 ctx, m.OutputFile(), filepath.Join(configsDir, m.Name()))) 698 }) 699 700 /* 701 Dump a map to a list file as: 702 703 {key1} {value1} 704 {key2} {value2} 705 ... 706 */ 707 installMapListFile := func(m map[string]string, path string) android.OutputPath { 708 var txtBuilder strings.Builder 709 for idx, k := range android.SortedStringKeys(m) { 710 if idx > 0 { 711 txtBuilder.WriteString("\\n") 712 } 713 txtBuilder.WriteString(k) 714 txtBuilder.WriteString(" ") 715 txtBuilder.WriteString(m[k]) 716 } 717 return writeStringToFile(ctx, txtBuilder.String(), path) 718 } 719 720 /* 721 module_paths.txt contains paths on which VNDK modules are defined. 722 e.g., 723 libbase.so system/core/base 724 libc.so bionic/libc 725 ... 726 */ 727 snapshotOutputs = append(snapshotOutputs, installMapListFile(modulePaths, filepath.Join(configsDir, "module_paths.txt"))) 728 729 /* 730 module_names.txt contains names as which VNDK modules are defined, 731 because output filename and module name can be different with stem and suffix properties. 732 733 e.g., 734 libcutils.so libcutils 735 libprotobuf-cpp-full-3.9.2.so libprotobuf-cpp-full 736 ... 737 */ 738 snapshotOutputs = append(snapshotOutputs, installMapListFile(moduleNames, filepath.Join(configsDir, "module_names.txt"))) 739 740 // All artifacts are ready. Sort them to normalize ninja and then zip. 741 sort.Slice(snapshotOutputs, func(i, j int) bool { 742 return snapshotOutputs[i].String() < snapshotOutputs[j].String() 743 }) 744 745 zipPath := android.PathForOutput(ctx, snapshotDir, "android-vndk-"+ctx.DeviceConfig().DeviceArch()+".zip") 746 zipRule := android.NewRuleBuilder() 747 748 // filenames in rspfile from FlagWithRspFileInputList might be single-quoted. Remove it with xargs 749 snapshotOutputList := android.PathForOutput(ctx, snapshotDir, "android-vndk-"+ctx.DeviceConfig().DeviceArch()+"_list") 750 zipRule.Command(). 751 Text("tr"). 752 FlagWithArg("-d ", "\\'"). 753 FlagWithRspFileInputList("< ", snapshotOutputs). 754 FlagWithOutput("> ", snapshotOutputList) 755 756 zipRule.Temporary(snapshotOutputList) 757 758 zipRule.Command(). 759 BuiltTool(ctx, "soong_zip"). 760 FlagWithOutput("-o ", zipPath). 761 FlagWithArg("-C ", android.PathForOutput(ctx, snapshotDir).String()). 762 FlagWithInput("-l ", snapshotOutputList) 763 764 zipRule.Build(pctx, ctx, zipPath.String(), "vndk snapshot "+zipPath.String()) 765 zipRule.DeleteTemporaryFiles() 766 c.vndkSnapshotZipFile = android.OptionalPathForPath(zipPath) 767} 768 769func getVndkFileName(m *Module) (string, error) { 770 if library, ok := m.linker.(*libraryDecorator); ok { 771 return library.getLibNameHelper(m.BaseModuleName(), true) + ".so", nil 772 } 773 if prebuilt, ok := m.linker.(*prebuiltLibraryLinker); ok { 774 return prebuilt.libraryDecorator.getLibNameHelper(m.BaseModuleName(), true) + ".so", nil 775 } 776 return "", fmt.Errorf("VNDK library should have libraryDecorator or prebuiltLibraryLinker as linker: %T", m.linker) 777} 778 779func (c *vndkSnapshotSingleton) buildVndkLibrariesTxtFiles(ctx android.SingletonContext) { 780 llndk := android.SortedStringMapValues(llndkLibraries(ctx.Config())) 781 vndkcore := android.SortedStringMapValues(vndkCoreLibraries(ctx.Config())) 782 vndksp := android.SortedStringMapValues(vndkSpLibraries(ctx.Config())) 783 vndkprivate := android.SortedStringMapValues(vndkPrivateLibraries(ctx.Config())) 784 785 // Build list of vndk libs as merged & tagged & filter-out(libclang_rt): 786 // Since each target have different set of libclang_rt.* files, 787 // keep the common set of files in vndk.libraries.txt 788 var merged []string 789 filterOutLibClangRt := func(libList []string) (filtered []string) { 790 for _, lib := range libList { 791 if !strings.HasPrefix(lib, "libclang_rt.") { 792 filtered = append(filtered, lib) 793 } 794 } 795 return 796 } 797 merged = append(merged, addPrefix(filterOutLibClangRt(llndk), "LLNDK: ")...) 798 merged = append(merged, addPrefix(vndksp, "VNDK-SP: ")...) 799 merged = append(merged, addPrefix(filterOutLibClangRt(vndkcore), "VNDK-core: ")...) 800 merged = append(merged, addPrefix(vndkprivate, "VNDK-private: ")...) 801 c.vndkLibrariesFile = android.PathForOutput(ctx, "vndk", "vndk.libraries.txt") 802 ctx.Build(pctx, android.BuildParams{ 803 Rule: android.WriteFile, 804 Output: c.vndkLibrariesFile, 805 Description: "Writing " + c.vndkLibrariesFile.String(), 806 Args: map[string]string{ 807 "content": strings.Join(merged, "\\n"), 808 }, 809 }) 810} 811 812func (c *vndkSnapshotSingleton) MakeVars(ctx android.MakeVarsContext) { 813 // Make uses LLNDK_MOVED_TO_APEX_LIBRARIES to avoid installing libraries on /system if 814 // they been moved to an apex. 815 movedToApexLlndkLibraries := []string{} 816 for lib := range llndkLibraries(ctx.Config()) { 817 // Skip bionic libs, they are handled in different manner 818 if android.DirectlyInAnyApex(¬OnHostContext{}, lib) && !isBionic(lib) { 819 movedToApexLlndkLibraries = append(movedToApexLlndkLibraries, lib) 820 } 821 } 822 ctx.Strict("LLNDK_MOVED_TO_APEX_LIBRARIES", strings.Join(movedToApexLlndkLibraries, " ")) 823 824 // Make uses LLNDK_LIBRARIES to determine which libraries to install. 825 // HWASAN is only part of the LL-NDK in builds in which libc depends on HWASAN. 826 // Therefore, by removing the library here, we cause it to only be installed if libc 827 // depends on it. 828 installedLlndkLibraries := []string{} 829 for lib := range llndkLibraries(ctx.Config()) { 830 if strings.HasPrefix(lib, "libclang_rt.hwasan-") { 831 continue 832 } 833 installedLlndkLibraries = append(installedLlndkLibraries, lib) 834 } 835 sort.Strings(installedLlndkLibraries) 836 ctx.Strict("LLNDK_LIBRARIES", strings.Join(installedLlndkLibraries, " ")) 837 838 ctx.Strict("VNDK_CORE_LIBRARIES", strings.Join(android.SortedStringKeys(vndkCoreLibraries(ctx.Config())), " ")) 839 ctx.Strict("VNDK_SAMEPROCESS_LIBRARIES", strings.Join(android.SortedStringKeys(vndkSpLibraries(ctx.Config())), " ")) 840 ctx.Strict("VNDK_PRIVATE_LIBRARIES", strings.Join(android.SortedStringKeys(vndkPrivateLibraries(ctx.Config())), " ")) 841 ctx.Strict("VNDK_USING_CORE_VARIANT_LIBRARIES", strings.Join(android.SortedStringKeys(vndkUsingCoreVariantLibraries(ctx.Config())), " ")) 842 843 ctx.Strict("VNDK_LIBRARIES_FILE", c.vndkLibrariesFile.String()) 844 ctx.Strict("SOONG_VNDK_SNAPSHOT_ZIP", c.vndkSnapshotZipFile.String()) 845} 846