1// Copyright (C) 2019 The Android Open Source Project 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 15// sysprop package defines a module named sysprop_library that can implement sysprop as API 16// See https://source.android.com/devices/architecture/sysprops-apis for details 17package sysprop 18 19import ( 20 "fmt" 21 "io" 22 "os" 23 "path" 24 "strings" 25 "sync" 26 27 "github.com/google/blueprint" 28 "github.com/google/blueprint/proptools" 29 30 "android/soong/android" 31 "android/soong/cc" 32 "android/soong/java" 33 "android/soong/rust" 34) 35 36type dependencyTag struct { 37 blueprint.BaseDependencyTag 38 name string 39} 40 41type syspropGenProperties struct { 42 Srcs []string `android:"path"` 43 Scope string 44 Name *string 45 Check_api *string 46} 47 48type syspropJavaGenRule struct { 49 android.ModuleBase 50 51 properties syspropGenProperties 52} 53 54type syspropRustGenRule struct { 55 *rust.BaseSourceProvider 56 57 properties rustLibraryProperties 58} 59 60var _ rust.SourceProvider = (*syspropRustGenRule)(nil) 61 62var ( 63 syspropJava = pctx.AndroidStaticRule("syspropJava", 64 blueprint.RuleParams{ 65 Command: `rm -rf $out.tmp && mkdir -p $out.tmp && ` + 66 `$syspropJavaCmd --scope $scope --java-output-dir $out.tmp $in && ` + 67 `$soongZipCmd -jar -o $out -C $out.tmp -D $out.tmp && rm -rf $out.tmp`, 68 CommandDeps: []string{ 69 "$syspropJavaCmd", 70 "$soongZipCmd", 71 }, 72 }, "scope") 73 syspropRust = pctx.AndroidStaticRule("syspropRust", 74 blueprint.RuleParams{ 75 Command: `rm -rf $out_dir && mkdir -p $out_dir && ` + 76 `$syspropRustCmd --scope $scope --rust-output-dir $out_dir $in`, 77 CommandDeps: []string{ 78 "$syspropRustCmd", 79 }, 80 }, "scope", "out_dir") 81) 82 83func init() { 84 pctx.HostBinToolVariable("soongZipCmd", "soong_zip") 85 pctx.HostBinToolVariable("syspropJavaCmd", "sysprop_java") 86 pctx.HostBinToolVariable("syspropRustCmd", "sysprop_rust") 87} 88 89// syspropJavaGenRule module generates srcjar containing generated java APIs. 90// It also depends on check api rule, so api check has to pass to use sysprop_library. 91func (g *syspropJavaGenRule) GenerateAndroidBuildActions(ctx android.ModuleContext) { 92 var checkApiFileTimeStamp android.WritablePath 93 94 ctx.VisitDirectDeps(func(dep android.Module) { 95 if m, ok := dep.(*syspropLibrary); ok { 96 checkApiFileTimeStamp = m.checkApiFileTimeStamp 97 } 98 }) 99 100 var genSrcjars android.Paths 101 for _, syspropFile := range android.PathsForModuleSrc(ctx, g.properties.Srcs) { 102 srcJarFile := android.GenPathWithExt(ctx, "sysprop", syspropFile, "srcjar") 103 104 ctx.Build(pctx, android.BuildParams{ 105 Rule: syspropJava, 106 Description: "sysprop_java " + syspropFile.Rel(), 107 Output: srcJarFile, 108 Input: syspropFile, 109 Implicit: checkApiFileTimeStamp, 110 Args: map[string]string{ 111 "scope": g.properties.Scope, 112 }, 113 }) 114 115 genSrcjars = append(genSrcjars, srcJarFile) 116 } 117 118 ctx.SetOutputFiles(genSrcjars, "") 119} 120 121func (g *syspropJavaGenRule) DepsMutator(ctx android.BottomUpMutatorContext) { 122 // Add a dependency from the stubs to sysprop library so that the generator rule can depend on 123 // the check API rule of the sysprop library. 124 ctx.AddFarVariationDependencies(nil, nil, proptools.String(g.properties.Check_api)) 125} 126 127func syspropJavaGenFactory() android.Module { 128 g := &syspropJavaGenRule{} 129 g.AddProperties(&g.properties) 130 android.InitAndroidModule(g) 131 return g 132} 133 134// syspropRustGenRule module generates rust source files containing generated rust APIs. 135// It also depends on check api rule, so api check has to pass to use sysprop_library. 136func (g *syspropRustGenRule) GenerateSource(ctx rust.ModuleContext, deps rust.PathDeps) android.Path { 137 var checkApiFileTimeStamp android.WritablePath 138 139 ctx.VisitDirectDeps(func(dep android.Module) { 140 if m, ok := dep.(*syspropLibrary); ok { 141 checkApiFileTimeStamp = m.checkApiFileTimeStamp 142 } 143 }) 144 145 outputDir := android.PathForModuleOut(ctx, "src") 146 libFile := outputDir.Join(ctx, "lib.rs") 147 g.BaseSourceProvider.OutputFiles = append(g.BaseSourceProvider.OutputFiles, libFile) 148 libFileLines := []string{"//! Autogenerated system property accessors."} 149 150 for _, syspropFile := range android.PathsForModuleSrc(ctx, g.properties.Sysprop_srcs) { 151 moduleName := syspropPathToRustModule(syspropFile) 152 moduleDir := outputDir.Join(ctx, moduleName) 153 modulePath := moduleDir.Join(ctx, "mod.rs") 154 155 ctx.Build(pctx, android.BuildParams{ 156 Rule: syspropRust, 157 Description: "sysprop_rust " + syspropFile.Rel(), 158 Output: modulePath, 159 Input: syspropFile, 160 Implicit: checkApiFileTimeStamp, 161 Args: map[string]string{ 162 "scope": g.properties.Scope, 163 "out_dir": moduleDir.String(), 164 }, 165 }) 166 167 g.BaseSourceProvider.OutputFiles = append(g.BaseSourceProvider.OutputFiles, modulePath) 168 libFileLines = append(libFileLines, fmt.Sprintf("pub mod %s;", moduleName)) 169 } 170 171 libFileSource := strings.Join(libFileLines, "\n") 172 android.WriteFileRule(ctx, libFile, libFileSource) 173 174 return libFile 175} 176 177func (g *syspropRustGenRule) SourceProviderProps() []interface{} { 178 return append(g.BaseSourceProvider.SourceProviderProps(), &g.Properties) 179} 180 181// syspropPathToRustModule takes a path to a .sysprop file and returns the name to use for the 182// corresponding Rust module. 183func syspropPathToRustModule(syspropFilename android.Path) string { 184 filenameBase := strings.TrimSuffix(syspropFilename.Base(), ".sysprop") 185 return strings.ToLower(filenameBase) 186} 187 188func (g *syspropRustGenRule) DepsMutator(ctx android.BottomUpMutatorContext) { 189 // Add a dependency from the stubs to sysprop library so that the generator rule can depend on 190 // the check API rule of the sysprop library. 191 ctx.AddFarVariationDependencies(nil, nil, proptools.String(g.properties.Check_api)) 192} 193 194func syspropRustGenFactory() android.Module { 195 g := &syspropRustGenRule{ 196 BaseSourceProvider: rust.NewSourceProvider(), 197 } 198 sourceProvider := rust.NewSourceProviderModule(android.DeviceSupported, g, false, false) 199 sourceProvider.AddProperties(&g.properties) 200 return sourceProvider.Init() 201} 202 203type syspropLibrary struct { 204 android.ModuleBase 205 android.ApexModuleBase 206 207 properties syspropLibraryProperties 208 209 checkApiFileTimeStamp android.WritablePath 210 latestApiFile android.OptionalPath 211 currentApiFile android.OptionalPath 212 dumpedApiFile android.WritablePath 213} 214 215type syspropLibraryProperties struct { 216 // Determine who owns this sysprop library. Possible values are 217 // "Platform", "Vendor", or "Odm" 218 Property_owner string 219 220 // list of package names that will be documented and publicized as API 221 Api_packages []string 222 223 // If set to true, allow this module to be dexed and installed on devices. 224 Installable *bool 225 226 // Make this module available when building for ramdisk 227 Ramdisk_available *bool 228 229 // Make this module available when building for recovery 230 Recovery_available *bool 231 232 // Make this module available when building for vendor 233 Vendor_available *bool 234 235 // Make this module available when building for product 236 Product_available *bool 237 238 // list of .sysprop files which defines the properties. 239 Srcs []string `android:"path"` 240 241 // If set to true, build a variant of the module for the host. Defaults to false. 242 Host_supported *bool 243 244 Cpp struct { 245 // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX). 246 // Forwarded to cc_library.min_sdk_version 247 Min_sdk_version *string 248 249 // C compiler flags used to build library 250 Cflags []string 251 252 // Linker flags used to build binary 253 Ldflags []string 254 } 255 256 Java struct { 257 // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX). 258 // Forwarded to java_library.min_sdk_version 259 Min_sdk_version *string 260 } 261 262 Rust struct { 263 // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX). 264 // Forwarded to rust_library.min_sdk_version 265 Min_sdk_version *string 266 } 267} 268 269var ( 270 pctx = android.NewPackageContext("android/soong/sysprop") 271 syspropCcTag = dependencyTag{name: "syspropCc"} 272 273 syspropLibrariesKey = android.NewOnceKey("syspropLibraries") 274 syspropLibrariesLock sync.Mutex 275) 276 277// List of sysprop_library used by property_contexts to perform type check. 278func syspropLibraries(config android.Config) *[]string { 279 return config.Once(syspropLibrariesKey, func() interface{} { 280 return &[]string{} 281 }).(*[]string) 282} 283 284func SyspropLibraries(config android.Config) []string { 285 return append([]string{}, *syspropLibraries(config)...) 286} 287 288func init() { 289 registerSyspropBuildComponents(android.InitRegistrationContext) 290} 291 292func registerSyspropBuildComponents(ctx android.RegistrationContext) { 293 ctx.RegisterModuleType("sysprop_library", syspropLibraryFactory) 294} 295 296func (m *syspropLibrary) Name() string { 297 return m.BaseModuleName() + "_sysprop_library" 298} 299 300func (m *syspropLibrary) Owner() string { 301 return m.properties.Property_owner 302} 303 304func (m *syspropLibrary) CcImplementationModuleName() string { 305 return "lib" + m.BaseModuleName() 306} 307 308func (m *syspropLibrary) javaPublicStubName() string { 309 return m.BaseModuleName() + "_public" 310} 311 312func (m *syspropLibrary) javaGenModuleName() string { 313 return m.BaseModuleName() + "_java_gen" 314} 315 316func (m *syspropLibrary) javaGenPublicStubName() string { 317 return m.BaseModuleName() + "_java_gen_public" 318} 319 320func (m *syspropLibrary) rustGenStubName() string { 321 return "lib" + m.rustCrateName() + "_rust" 322} 323 324func (m *syspropLibrary) rustCrateName() string { 325 moduleName := strings.ToLower(m.BaseModuleName()) 326 moduleName = strings.ReplaceAll(moduleName, "-", "_") 327 moduleName = strings.ReplaceAll(moduleName, ".", "_") 328 return moduleName 329} 330 331func (m *syspropLibrary) BaseModuleName() string { 332 return m.ModuleBase.Name() 333} 334 335func (m *syspropLibrary) CurrentSyspropApiFile() android.OptionalPath { 336 return m.currentApiFile 337} 338 339// GenerateAndroidBuildActions of sysprop_library handles API dump and API check. 340// generated java_library will depend on these API files. 341func (m *syspropLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 342 baseModuleName := m.BaseModuleName() 343 srcs := android.PathsForModuleSrc(ctx, m.properties.Srcs) 344 for _, syspropFile := range srcs { 345 if syspropFile.Ext() != ".sysprop" { 346 ctx.PropertyErrorf("srcs", "srcs contains non-sysprop file %q", syspropFile.String()) 347 } 348 } 349 android.SetProvider(ctx, blueprint.SrcsFileProviderKey, blueprint.SrcsFileProviderData{SrcPaths: srcs.Strings()}) 350 351 if ctx.Failed() { 352 return 353 } 354 355 apiDirectoryPath := path.Join(ctx.ModuleDir(), "api") 356 currentApiFilePath := path.Join(apiDirectoryPath, baseModuleName+"-current.txt") 357 latestApiFilePath := path.Join(apiDirectoryPath, baseModuleName+"-latest.txt") 358 m.currentApiFile = android.ExistentPathForSource(ctx, currentApiFilePath) 359 m.latestApiFile = android.ExistentPathForSource(ctx, latestApiFilePath) 360 361 // dump API rule 362 rule := android.NewRuleBuilder(pctx, ctx) 363 m.dumpedApiFile = android.PathForModuleOut(ctx, "api-dump.txt") 364 rule.Command(). 365 BuiltTool("sysprop_api_dump"). 366 Output(m.dumpedApiFile). 367 Inputs(srcs) 368 rule.Build(baseModuleName+"_api_dump", baseModuleName+" api dump") 369 370 // check API rule 371 rule = android.NewRuleBuilder(pctx, ctx) 372 373 // We allow that the API txt files don't exist, when the sysprop_library only contains internal 374 // properties. But we have to feed current api file and latest api file to the rule builder. 375 // Currently we can't get android.Path representing the null device, so we add any existing API 376 // txt files to implicits, and then directly feed string paths, rather than calling Input(Path) 377 // method. 378 var apiFileList android.Paths 379 currentApiArgument := os.DevNull 380 if m.currentApiFile.Valid() { 381 apiFileList = append(apiFileList, m.currentApiFile.Path()) 382 currentApiArgument = m.currentApiFile.String() 383 } 384 385 latestApiArgument := os.DevNull 386 if m.latestApiFile.Valid() { 387 apiFileList = append(apiFileList, m.latestApiFile.Path()) 388 latestApiArgument = m.latestApiFile.String() 389 } 390 391 // 1. compares current.txt to api-dump.txt 392 // current.txt should be identical to api-dump.txt. 393 msg := fmt.Sprintf(`\n******************************\n`+ 394 `API of sysprop_library %s doesn't match with current.txt\n`+ 395 `Please update current.txt by:\n`+ 396 `m %s-dump-api && mkdir -p %q && rm -rf %q && cp -f %q %q\n`+ 397 `******************************\n`, baseModuleName, baseModuleName, 398 apiDirectoryPath, currentApiFilePath, m.dumpedApiFile.String(), currentApiFilePath) 399 400 rule.Command(). 401 Text("( cmp").Flag("-s"). 402 Input(m.dumpedApiFile). 403 Text(currentApiArgument). 404 Text("|| ( echo").Flag("-e"). 405 Flag(`"` + msg + `"`). 406 Text("; exit 38) )") 407 408 // 2. compares current.txt to latest.txt (frozen API) 409 // current.txt should be compatible with latest.txt 410 msg = fmt.Sprintf(`\n******************************\n`+ 411 `API of sysprop_library %s doesn't match with latest version\n`+ 412 `Please fix the breakage and rebuild.\n`+ 413 `******************************\n`, baseModuleName) 414 415 rule.Command(). 416 Text("( "). 417 BuiltTool("sysprop_api_checker"). 418 Text(latestApiArgument). 419 Text(currentApiArgument). 420 Text(" || ( echo").Flag("-e"). 421 Flag(`"` + msg + `"`). 422 Text("; exit 38) )"). 423 Implicits(apiFileList) 424 425 m.checkApiFileTimeStamp = android.PathForModuleOut(ctx, "check_api.timestamp") 426 427 rule.Command(). 428 Text("touch"). 429 Output(m.checkApiFileTimeStamp) 430 431 rule.Build(baseModuleName+"_check_api", baseModuleName+" check api") 432} 433 434func (m *syspropLibrary) AndroidMk() android.AndroidMkData { 435 return android.AndroidMkData{ 436 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) { 437 // sysprop_library module itself is defined as a FAKE module to perform API check. 438 // Actual implementation libraries are created on LoadHookMutator 439 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)", " # sysprop.syspropLibrary") 440 fmt.Fprintln(w, "LOCAL_MODULE :=", m.Name()) 441 fmt.Fprintf(w, "LOCAL_MODULE_CLASS := FAKE\n") 442 fmt.Fprintf(w, "LOCAL_MODULE_TAGS := optional\n") 443 // AconfigUpdateAndroidMkData may have added elements to Extra. Process them here. 444 for _, extra := range data.Extra { 445 extra(w, nil) 446 } 447 fmt.Fprintf(w, "include $(BUILD_SYSTEM)/base_rules.mk\n\n") 448 fmt.Fprintf(w, "$(LOCAL_BUILT_MODULE): %s\n", m.checkApiFileTimeStamp.String()) 449 fmt.Fprintf(w, "\ttouch $@\n\n") 450 fmt.Fprintf(w, ".PHONY: %s-check-api %s-dump-api\n\n", name, name) 451 452 // dump API rule 453 fmt.Fprintf(w, "%s-dump-api: %s\n\n", name, m.dumpedApiFile.String()) 454 455 // check API rule 456 fmt.Fprintf(w, "%s-check-api: %s\n\n", name, m.checkApiFileTimeStamp.String()) 457 }} 458} 459 460var _ android.ApexModule = (*syspropLibrary)(nil) 461 462// Implements android.ApexModule 463func (m *syspropLibrary) ShouldSupportSdkVersion(ctx android.BaseModuleContext, 464 sdkVersion android.ApiLevel) error { 465 return fmt.Errorf("sysprop_library is not supposed to be part of apex modules") 466} 467 468// sysprop_library creates schematized APIs from sysprop description files (.sysprop). 469// Both Java and C++ modules can link against sysprop_library, and API stability check 470// against latest APIs (see build/soong/scripts/freeze-sysprop-api-files.sh) 471// is performed. Note that the generated C++ module has its name prefixed with 472// `lib`, and it is this module that should be depended on from other C++ 473// modules; i.e., if the sysprop_library module is named `foo`, C++ modules 474// should depend on `libfoo`. 475func syspropLibraryFactory() android.Module { 476 m := &syspropLibrary{} 477 478 m.AddProperties( 479 &m.properties, 480 ) 481 android.InitAndroidModule(m) 482 android.InitApexModule(m) 483 android.AddLoadHook(m, func(ctx android.LoadHookContext) { syspropLibraryHook(ctx, m) }) 484 return m 485} 486 487type ccLibraryProperties struct { 488 Name *string 489 Srcs []string 490 Soc_specific *bool 491 Device_specific *bool 492 Product_specific *bool 493 Sysprop struct { 494 Platform *bool 495 } 496 Target struct { 497 Android struct { 498 Header_libs []string 499 Shared_libs []string 500 } 501 Host struct { 502 Static_libs []string 503 } 504 } 505 Required []string 506 Recovery *bool 507 Recovery_available *bool 508 Vendor_available *bool 509 Product_available *bool 510 Ramdisk_available *bool 511 Host_supported *bool 512 Apex_available []string 513 Min_sdk_version *string 514 Cflags []string 515 Ldflags []string 516} 517 518type javaLibraryProperties struct { 519 Name *string 520 Srcs []string 521 Soc_specific *bool 522 Device_specific *bool 523 Product_specific *bool 524 Required []string 525 Sdk_version *string 526 Installable *bool 527 Libs []string 528 Stem *string 529 SyspropPublicStub string 530 Apex_available []string 531 Min_sdk_version *string 532} 533 534type rustLibraryProperties struct { 535 Name *string 536 Sysprop_srcs []string `android:"path"` 537 Scope string 538 Check_api *string 539 Srcs []string 540 Installable *bool 541 Crate_name string 542 Rustlibs []string 543 Vendor_available *bool 544 Product_available *bool 545 Apex_available []string 546 Min_sdk_version *string 547} 548 549func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) { 550 if len(m.properties.Srcs) == 0 { 551 ctx.PropertyErrorf("srcs", "sysprop_library must specify srcs") 552 } 553 554 // ctx's Platform or Specific functions represent where this sysprop_library installed. 555 installedInSystem := ctx.Platform() || ctx.SystemExtSpecific() 556 installedInVendorOrOdm := ctx.SocSpecific() || ctx.DeviceSpecific() 557 installedInProduct := ctx.ProductSpecific() 558 isOwnerPlatform := false 559 var javaSyspropStub string 560 561 // javaSyspropStub contains stub libraries used by generated APIs, instead of framework stub. 562 // This is to make sysprop_library link against core_current. 563 if installedInVendorOrOdm { 564 javaSyspropStub = "sysprop-library-stub-vendor" 565 } else if installedInProduct { 566 javaSyspropStub = "sysprop-library-stub-product" 567 } else { 568 javaSyspropStub = "sysprop-library-stub-platform" 569 } 570 571 switch m.Owner() { 572 case "Platform": 573 // Every partition can access platform-defined properties 574 isOwnerPlatform = true 575 case "Vendor": 576 // System can't access vendor's properties 577 if installedInSystem { 578 ctx.ModuleErrorf("None of soc_specific, device_specific, product_specific is true. " + 579 "System can't access sysprop_library owned by Vendor") 580 } 581 case "Odm": 582 // Only vendor can access Odm-defined properties 583 if !installedInVendorOrOdm { 584 ctx.ModuleErrorf("Neither soc_speicifc nor device_specific is true. " + 585 "Odm-defined properties should be accessed only in Vendor or Odm") 586 } 587 default: 588 ctx.PropertyErrorf("property_owner", 589 "Unknown value %s: must be one of Platform, Vendor or Odm", m.Owner()) 590 } 591 592 // Generate a C++ implementation library. 593 // cc_library can receive *.sysprop files as their srcs, generating sources itself. 594 ccProps := ccLibraryProperties{} 595 ccProps.Name = proptools.StringPtr(m.CcImplementationModuleName()) 596 ccProps.Srcs = m.properties.Srcs 597 ccProps.Soc_specific = proptools.BoolPtr(ctx.SocSpecific()) 598 ccProps.Device_specific = proptools.BoolPtr(ctx.DeviceSpecific()) 599 ccProps.Product_specific = proptools.BoolPtr(ctx.ProductSpecific()) 600 ccProps.Sysprop.Platform = proptools.BoolPtr(isOwnerPlatform) 601 ccProps.Target.Android.Header_libs = []string{"libbase_headers"} 602 ccProps.Target.Android.Shared_libs = []string{"liblog"} 603 ccProps.Target.Host.Static_libs = []string{"libbase", "liblog"} 604 ccProps.Recovery_available = m.properties.Recovery_available 605 ccProps.Vendor_available = m.properties.Vendor_available 606 ccProps.Product_available = m.properties.Product_available 607 ccProps.Ramdisk_available = m.properties.Ramdisk_available 608 ccProps.Host_supported = m.properties.Host_supported 609 ccProps.Apex_available = m.ApexProperties.Apex_available 610 ccProps.Min_sdk_version = m.properties.Cpp.Min_sdk_version 611 ccProps.Cflags = m.properties.Cpp.Cflags 612 ccProps.Ldflags = m.properties.Cpp.Ldflags 613 ctx.CreateModule(cc.LibraryFactory, &ccProps) 614 615 scope := "internal" 616 617 // We need to only use public version, if the partition where sysprop_library will be installed 618 // is different from owner. 619 if ctx.ProductSpecific() { 620 // Currently product partition can't own any sysprop_library. So product always uses public. 621 scope = "public" 622 } else if isOwnerPlatform && installedInVendorOrOdm { 623 // Vendor or Odm should use public version of Platform's sysprop_library. 624 scope = "public" 625 } 626 627 // Generate a Java implementation library. 628 // Contrast to C++, syspropJavaGenRule module will generate srcjar and the srcjar will be fed 629 // to Java implementation library. 630 ctx.CreateModule(syspropJavaGenFactory, &syspropGenProperties{ 631 Srcs: m.properties.Srcs, 632 Scope: scope, 633 Name: proptools.StringPtr(m.javaGenModuleName()), 634 Check_api: proptools.StringPtr(ctx.ModuleName()), 635 }) 636 637 // if platform sysprop_library is installed in /system or /system-ext, we regard it as an API 638 // and allow any modules (even from different partition) to link against the sysprop_library. 639 // To do that, we create a public stub and expose it to modules with sdk_version: system_*. 640 var publicStub string 641 if isOwnerPlatform && installedInSystem { 642 publicStub = m.javaPublicStubName() 643 } 644 645 ctx.CreateModule(java.LibraryFactory, &javaLibraryProperties{ 646 Name: proptools.StringPtr(m.BaseModuleName()), 647 Srcs: []string{":" + m.javaGenModuleName()}, 648 Soc_specific: proptools.BoolPtr(ctx.SocSpecific()), 649 Device_specific: proptools.BoolPtr(ctx.DeviceSpecific()), 650 Product_specific: proptools.BoolPtr(ctx.ProductSpecific()), 651 Installable: m.properties.Installable, 652 Sdk_version: proptools.StringPtr("core_current"), 653 Libs: []string{javaSyspropStub}, 654 SyspropPublicStub: publicStub, 655 Apex_available: m.ApexProperties.Apex_available, 656 Min_sdk_version: m.properties.Java.Min_sdk_version, 657 }) 658 659 if publicStub != "" { 660 ctx.CreateModule(syspropJavaGenFactory, &syspropGenProperties{ 661 Srcs: m.properties.Srcs, 662 Scope: "public", 663 Name: proptools.StringPtr(m.javaGenPublicStubName()), 664 Check_api: proptools.StringPtr(ctx.ModuleName()), 665 }) 666 667 ctx.CreateModule(java.LibraryFactory, &javaLibraryProperties{ 668 Name: proptools.StringPtr(publicStub), 669 Srcs: []string{":" + m.javaGenPublicStubName()}, 670 Installable: proptools.BoolPtr(false), 671 Sdk_version: proptools.StringPtr("core_current"), 672 Libs: []string{javaSyspropStub}, 673 Stem: proptools.StringPtr(m.BaseModuleName()), 674 }) 675 } 676 677 // Generate a Rust implementation library. 678 rustProps := rustLibraryProperties{ 679 Name: proptools.StringPtr(m.rustGenStubName()), 680 Sysprop_srcs: m.properties.Srcs, 681 Scope: scope, 682 Check_api: proptools.StringPtr(ctx.ModuleName()), 683 Installable: proptools.BoolPtr(false), 684 Crate_name: m.rustCrateName(), 685 Rustlibs: []string{ 686 "liblog_rust", 687 "librustutils", 688 }, 689 Vendor_available: m.properties.Vendor_available, 690 Product_available: m.properties.Product_available, 691 Apex_available: m.ApexProperties.Apex_available, 692 Min_sdk_version: proptools.StringPtr("29"), 693 } 694 ctx.CreateModule(syspropRustGenFactory, &rustProps) 695 696 // syspropLibraries will be used by property_contexts to check types. 697 // Record absolute paths of sysprop_library to prevent soong_namespace problem. 698 if m.ExportedToMake() { 699 syspropLibrariesLock.Lock() 700 defer syspropLibrariesLock.Unlock() 701 702 libraries := syspropLibraries(ctx.Config()) 703 *libraries = append(*libraries, "//"+ctx.ModuleDir()+":"+ctx.ModuleName()) 704 } 705} 706