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 vendor ramdisk 230 Vendor_ramdisk_available *bool 231 232 // Make this module available when building for recovery 233 Recovery_available *bool 234 235 // Make this module available when building for vendor 236 Vendor_available *bool 237 238 // Make this module available when building for product 239 Product_available *bool 240 241 // list of .sysprop files which defines the properties. 242 Srcs []string `android:"path"` 243 244 // If set to true, build a variant of the module for the host. Defaults to false. 245 Host_supported *bool 246 247 Cpp struct { 248 // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX). 249 // Forwarded to cc_library.min_sdk_version 250 Min_sdk_version *string 251 252 // C compiler flags used to build library 253 Cflags []string 254 255 // Linker flags used to build binary 256 Ldflags []string 257 } 258 259 Java struct { 260 // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX). 261 // Forwarded to java_library.min_sdk_version 262 Min_sdk_version *string 263 } 264 265 Rust struct { 266 // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX). 267 // Forwarded to rust_library.min_sdk_version 268 Min_sdk_version *string 269 } 270} 271 272var ( 273 pctx = android.NewPackageContext("android/soong/sysprop") 274 syspropCcTag = dependencyTag{name: "syspropCc"} 275 276 syspropLibrariesKey = android.NewOnceKey("syspropLibraries") 277 syspropLibrariesLock sync.Mutex 278) 279 280// List of sysprop_library used by property_contexts to perform type check. 281func syspropLibraries(config android.Config) *[]string { 282 return config.Once(syspropLibrariesKey, func() interface{} { 283 return &[]string{} 284 }).(*[]string) 285} 286 287func SyspropLibraries(config android.Config) []string { 288 return append([]string{}, *syspropLibraries(config)...) 289} 290 291func init() { 292 registerSyspropBuildComponents(android.InitRegistrationContext) 293} 294 295func registerSyspropBuildComponents(ctx android.RegistrationContext) { 296 ctx.RegisterModuleType("sysprop_library", syspropLibraryFactory) 297} 298 299func (m *syspropLibrary) Name() string { 300 return m.BaseModuleName() + "_sysprop_library" 301} 302 303func (m *syspropLibrary) Owner() string { 304 return m.properties.Property_owner 305} 306 307func (m *syspropLibrary) CcImplementationModuleName() string { 308 return "lib" + m.BaseModuleName() 309} 310 311func (m *syspropLibrary) javaPublicStubName() string { 312 return m.BaseModuleName() + "_public" 313} 314 315func (m *syspropLibrary) javaGenModuleName() string { 316 return m.BaseModuleName() + "_java_gen" 317} 318 319func (m *syspropLibrary) javaGenPublicStubName() string { 320 return m.BaseModuleName() + "_java_gen_public" 321} 322 323func (m *syspropLibrary) rustGenStubName() string { 324 return "lib" + m.rustCrateName() + "_rust" 325} 326 327func (m *syspropLibrary) rustCrateName() string { 328 moduleName := strings.ToLower(m.BaseModuleName()) 329 moduleName = strings.ReplaceAll(moduleName, "-", "_") 330 moduleName = strings.ReplaceAll(moduleName, ".", "_") 331 return moduleName 332} 333 334func (m *syspropLibrary) BaseModuleName() string { 335 return m.ModuleBase.Name() 336} 337 338func (m *syspropLibrary) CurrentSyspropApiFile() android.OptionalPath { 339 return m.currentApiFile 340} 341 342// GenerateAndroidBuildActions of sysprop_library handles API dump and API check. 343// generated java_library will depend on these API files. 344func (m *syspropLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) { 345 baseModuleName := m.BaseModuleName() 346 srcs := android.PathsForModuleSrc(ctx, m.properties.Srcs) 347 for _, syspropFile := range srcs { 348 if syspropFile.Ext() != ".sysprop" { 349 ctx.PropertyErrorf("srcs", "srcs contains non-sysprop file %q", syspropFile.String()) 350 } 351 } 352 353 if ctx.Failed() { 354 return 355 } 356 357 apiDirectoryPath := path.Join(ctx.ModuleDir(), "api") 358 currentApiFilePath := path.Join(apiDirectoryPath, baseModuleName+"-current.txt") 359 latestApiFilePath := path.Join(apiDirectoryPath, baseModuleName+"-latest.txt") 360 m.currentApiFile = android.ExistentPathForSource(ctx, currentApiFilePath) 361 m.latestApiFile = android.ExistentPathForSource(ctx, latestApiFilePath) 362 363 // dump API rule 364 rule := android.NewRuleBuilder(pctx, ctx) 365 m.dumpedApiFile = android.PathForModuleOut(ctx, "api-dump.txt") 366 rule.Command(). 367 BuiltTool("sysprop_api_dump"). 368 Output(m.dumpedApiFile). 369 Inputs(srcs) 370 rule.Build(baseModuleName+"_api_dump", baseModuleName+" api dump") 371 372 // check API rule 373 rule = android.NewRuleBuilder(pctx, ctx) 374 375 // We allow that the API txt files don't exist, when the sysprop_library only contains internal 376 // properties. But we have to feed current api file and latest api file to the rule builder. 377 // Currently we can't get android.Path representing the null device, so we add any existing API 378 // txt files to implicits, and then directly feed string paths, rather than calling Input(Path) 379 // method. 380 var apiFileList android.Paths 381 currentApiArgument := os.DevNull 382 if m.currentApiFile.Valid() { 383 apiFileList = append(apiFileList, m.currentApiFile.Path()) 384 currentApiArgument = m.currentApiFile.String() 385 } 386 387 latestApiArgument := os.DevNull 388 if m.latestApiFile.Valid() { 389 apiFileList = append(apiFileList, m.latestApiFile.Path()) 390 latestApiArgument = m.latestApiFile.String() 391 } 392 393 // 1. compares current.txt to api-dump.txt 394 // current.txt should be identical to api-dump.txt. 395 msg := fmt.Sprintf(`\n******************************\n`+ 396 `API of sysprop_library %s doesn't match with current.txt\n`+ 397 `Please update current.txt by:\n`+ 398 `m %s-dump-api && mkdir -p %q && rm -rf %q && cp -f %q %q\n`+ 399 `******************************\n`, baseModuleName, baseModuleName, 400 apiDirectoryPath, currentApiFilePath, m.dumpedApiFile.String(), currentApiFilePath) 401 402 rule.Command(). 403 Text("( cmp").Flag("-s"). 404 Input(m.dumpedApiFile). 405 Text(currentApiArgument). 406 Text("|| ( echo").Flag("-e"). 407 Flag(`"` + msg + `"`). 408 Text("; exit 38) )") 409 410 // 2. compares current.txt to latest.txt (frozen API) 411 // current.txt should be compatible with latest.txt 412 msg = fmt.Sprintf(`\n******************************\n`+ 413 `API of sysprop_library %s doesn't match with latest version\n`+ 414 `Please fix the breakage and rebuild.\n`+ 415 `******************************\n`, baseModuleName) 416 417 rule.Command(). 418 Text("( "). 419 BuiltTool("sysprop_api_checker"). 420 Text(latestApiArgument). 421 Text(currentApiArgument). 422 Text(" || ( echo").Flag("-e"). 423 Flag(`"` + msg + `"`). 424 Text("; exit 38) )"). 425 Implicits(apiFileList) 426 427 m.checkApiFileTimeStamp = android.PathForModuleOut(ctx, "check_api.timestamp") 428 429 rule.Command(). 430 Text("touch"). 431 Output(m.checkApiFileTimeStamp) 432 433 rule.Build(baseModuleName+"_check_api", baseModuleName+" check api") 434} 435 436func (m *syspropLibrary) AndroidMk() android.AndroidMkData { 437 return android.AndroidMkData{ 438 Custom: func(w io.Writer, name, prefix, moduleDir string, data android.AndroidMkData) { 439 // sysprop_library module itself is defined as a FAKE module to perform API check. 440 // Actual implementation libraries are created on LoadHookMutator 441 fmt.Fprintln(w, "\ninclude $(CLEAR_VARS)", " # sysprop.syspropLibrary") 442 fmt.Fprintln(w, "LOCAL_MODULE :=", m.Name()) 443 fmt.Fprintf(w, "LOCAL_MODULE_CLASS := FAKE\n") 444 fmt.Fprintf(w, "LOCAL_MODULE_TAGS := optional\n") 445 // AconfigUpdateAndroidMkData may have added elements to Extra. Process them here. 446 for _, extra := range data.Extra { 447 extra(w, nil) 448 } 449 fmt.Fprintf(w, "include $(BUILD_SYSTEM)/base_rules.mk\n\n") 450 fmt.Fprintf(w, "$(LOCAL_BUILT_MODULE): %s\n", m.checkApiFileTimeStamp.String()) 451 fmt.Fprintf(w, "\ttouch $@\n\n") 452 fmt.Fprintf(w, ".PHONY: %s-check-api %s-dump-api\n\n", name, name) 453 454 // dump API rule 455 fmt.Fprintf(w, "%s-dump-api: %s\n\n", name, m.dumpedApiFile.String()) 456 457 // check API rule 458 fmt.Fprintf(w, "%s-check-api: %s\n\n", name, m.checkApiFileTimeStamp.String()) 459 }} 460} 461 462var _ android.ApexModule = (*syspropLibrary)(nil) 463 464// Implements android.ApexModule 465func (m *syspropLibrary) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel { 466 return android.MinApiLevel 467} 468 469// sysprop_library creates schematized APIs from sysprop description files (.sysprop). 470// Both Java and C++ modules can link against sysprop_library, and API stability check 471// against latest APIs (see build/soong/scripts/freeze-sysprop-api-files.sh) 472// is performed. Note that the generated C++ module has its name prefixed with 473// `lib`, and it is this module that should be depended on from other C++ 474// modules; i.e., if the sysprop_library module is named `foo`, C++ modules 475// should depend on `libfoo`. 476func syspropLibraryFactory() android.Module { 477 m := &syspropLibrary{} 478 479 m.AddProperties( 480 &m.properties, 481 ) 482 android.InitAndroidModule(m) 483 android.InitApexModule(m) 484 android.AddLoadHook(m, func(ctx android.LoadHookContext) { syspropLibraryHook(ctx, m) }) 485 return m 486} 487 488type ccLibraryProperties struct { 489 Name *string 490 Srcs []string 491 Soc_specific *bool 492 Device_specific *bool 493 Product_specific *bool 494 Sysprop struct { 495 Platform *bool 496 } 497 Target struct { 498 Android struct { 499 Header_libs []string 500 Shared_libs []string 501 } 502 Host struct { 503 Static_libs []string 504 } 505 } 506 Required []string 507 Recovery *bool 508 Recovery_available *bool 509 Vendor_available *bool 510 Product_available *bool 511 Ramdisk_available *bool 512 Vendor_ramdisk_available *bool 513 Host_supported *bool 514 Apex_available []string 515 Min_sdk_version *string 516 Cflags []string 517 Ldflags []string 518} 519 520type javaLibraryProperties struct { 521 Name *string 522 Srcs []string 523 Soc_specific *bool 524 Device_specific *bool 525 Product_specific *bool 526 Required []string 527 Sdk_version *string 528 Installable *bool 529 Libs []string 530 Stem *string 531 SyspropPublicStub string 532 Apex_available []string 533 Min_sdk_version *string 534} 535 536type rustLibraryProperties struct { 537 Name *string 538 Sysprop_srcs []string `android:"path"` 539 Scope string 540 Check_api *string 541 Srcs []string 542 Installable *bool 543 Crate_name string 544 Rustlibs []string 545 Vendor_available *bool 546 Product_available *bool 547 Apex_available []string 548 Min_sdk_version *string 549} 550 551func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) { 552 if len(m.properties.Srcs) == 0 { 553 ctx.PropertyErrorf("srcs", "sysprop_library must specify srcs") 554 } 555 556 // ctx's Platform or Specific functions represent where this sysprop_library installed. 557 installedInSystem := ctx.Platform() || ctx.SystemExtSpecific() 558 installedInVendorOrOdm := ctx.SocSpecific() || ctx.DeviceSpecific() 559 installedInProduct := ctx.ProductSpecific() 560 isOwnerPlatform := false 561 var javaSyspropStub string 562 563 // javaSyspropStub contains stub libraries used by generated APIs, instead of framework stub. 564 // This is to make sysprop_library link against core_current. 565 if installedInVendorOrOdm { 566 javaSyspropStub = "sysprop-library-stub-vendor" 567 } else if installedInProduct { 568 javaSyspropStub = "sysprop-library-stub-product" 569 } else { 570 javaSyspropStub = "sysprop-library-stub-platform" 571 } 572 573 switch m.Owner() { 574 case "Platform": 575 // Every partition can access platform-defined properties 576 isOwnerPlatform = true 577 case "Vendor": 578 // System can't access vendor's properties 579 if installedInSystem { 580 ctx.ModuleErrorf("None of soc_specific, device_specific, product_specific is true. " + 581 "System can't access sysprop_library owned by Vendor") 582 } 583 case "Odm": 584 // Only vendor can access Odm-defined properties 585 if !installedInVendorOrOdm { 586 ctx.ModuleErrorf("Neither soc_speicifc nor device_specific is true. " + 587 "Odm-defined properties should be accessed only in Vendor or Odm") 588 } 589 default: 590 ctx.PropertyErrorf("property_owner", 591 "Unknown value %s: must be one of Platform, Vendor or Odm", m.Owner()) 592 } 593 594 // Generate a C++ implementation library. 595 // cc_library can receive *.sysprop files as their srcs, generating sources itself. 596 ccProps := ccLibraryProperties{} 597 ccProps.Name = proptools.StringPtr(m.CcImplementationModuleName()) 598 ccProps.Srcs = m.properties.Srcs 599 ccProps.Soc_specific = proptools.BoolPtr(ctx.SocSpecific()) 600 ccProps.Device_specific = proptools.BoolPtr(ctx.DeviceSpecific()) 601 ccProps.Product_specific = proptools.BoolPtr(ctx.ProductSpecific()) 602 ccProps.Sysprop.Platform = proptools.BoolPtr(isOwnerPlatform) 603 ccProps.Target.Android.Header_libs = []string{"libbase_headers"} 604 ccProps.Target.Android.Shared_libs = []string{"liblog"} 605 ccProps.Target.Host.Static_libs = []string{"libbase", "liblog"} 606 ccProps.Recovery_available = m.properties.Recovery_available 607 ccProps.Vendor_available = m.properties.Vendor_available 608 ccProps.Product_available = m.properties.Product_available 609 ccProps.Ramdisk_available = m.properties.Ramdisk_available 610 ccProps.Vendor_ramdisk_available = m.properties.Vendor_ramdisk_available 611 ccProps.Host_supported = m.properties.Host_supported 612 ccProps.Apex_available = m.ApexProperties.Apex_available 613 ccProps.Min_sdk_version = m.properties.Cpp.Min_sdk_version 614 ccProps.Cflags = m.properties.Cpp.Cflags 615 ccProps.Ldflags = m.properties.Cpp.Ldflags 616 ctx.CreateModule(cc.LibraryFactory, &ccProps) 617 618 scope := "internal" 619 620 // We need to only use public version, if the partition where sysprop_library will be installed 621 // is different from owner. 622 if ctx.ProductSpecific() { 623 // Currently product partition can't own any sysprop_library. So product always uses public. 624 scope = "public" 625 } else if isOwnerPlatform && installedInVendorOrOdm { 626 // Vendor or Odm should use public version of Platform's sysprop_library. 627 scope = "public" 628 } 629 630 // Generate a Java implementation library. 631 // Contrast to C++, syspropJavaGenRule module will generate srcjar and the srcjar will be fed 632 // to Java implementation library. 633 ctx.CreateModule(syspropJavaGenFactory, &syspropGenProperties{ 634 Srcs: m.properties.Srcs, 635 Scope: scope, 636 Name: proptools.StringPtr(m.javaGenModuleName()), 637 Check_api: proptools.StringPtr(ctx.ModuleName()), 638 }) 639 640 // if platform sysprop_library is installed in /system or /system-ext, we regard it as an API 641 // and allow any modules (even from different partition) to link against the sysprop_library. 642 // To do that, we create a public stub and expose it to modules with sdk_version: system_*. 643 var publicStub string 644 if isOwnerPlatform && installedInSystem { 645 publicStub = m.javaPublicStubName() 646 } 647 648 ctx.CreateModule(java.LibraryFactory, &javaLibraryProperties{ 649 Name: proptools.StringPtr(m.BaseModuleName()), 650 Srcs: []string{":" + m.javaGenModuleName()}, 651 Soc_specific: proptools.BoolPtr(ctx.SocSpecific()), 652 Device_specific: proptools.BoolPtr(ctx.DeviceSpecific()), 653 Product_specific: proptools.BoolPtr(ctx.ProductSpecific()), 654 Installable: m.properties.Installable, 655 Sdk_version: proptools.StringPtr("core_current"), 656 Libs: []string{javaSyspropStub}, 657 SyspropPublicStub: publicStub, 658 Apex_available: m.ApexProperties.Apex_available, 659 Min_sdk_version: m.properties.Java.Min_sdk_version, 660 }) 661 662 if publicStub != "" { 663 ctx.CreateModule(syspropJavaGenFactory, &syspropGenProperties{ 664 Srcs: m.properties.Srcs, 665 Scope: "public", 666 Name: proptools.StringPtr(m.javaGenPublicStubName()), 667 Check_api: proptools.StringPtr(ctx.ModuleName()), 668 }) 669 670 ctx.CreateModule(java.LibraryFactory, &javaLibraryProperties{ 671 Name: proptools.StringPtr(publicStub), 672 Srcs: []string{":" + m.javaGenPublicStubName()}, 673 Installable: proptools.BoolPtr(false), 674 Sdk_version: proptools.StringPtr("core_current"), 675 Libs: []string{javaSyspropStub}, 676 Stem: proptools.StringPtr(m.BaseModuleName()), 677 }) 678 } 679 680 // Generate a Rust implementation library. 681 rustProps := rustLibraryProperties{ 682 Name: proptools.StringPtr(m.rustGenStubName()), 683 Sysprop_srcs: m.properties.Srcs, 684 Scope: scope, 685 Check_api: proptools.StringPtr(ctx.ModuleName()), 686 Installable: m.properties.Installable, 687 Crate_name: m.rustCrateName(), 688 Rustlibs: []string{ 689 "liblog_rust", 690 "librustutils", 691 }, 692 Vendor_available: m.properties.Vendor_available, 693 Product_available: m.properties.Product_available, 694 Apex_available: m.ApexProperties.Apex_available, 695 Min_sdk_version: proptools.StringPtr("29"), 696 } 697 ctx.CreateModule(syspropRustGenFactory, &rustProps) 698 699 // syspropLibraries will be used by property_contexts to check types. 700 // Record absolute paths of sysprop_library to prevent soong_namespace problem. 701 if m.ExportedToMake() { 702 syspropLibrariesLock.Lock() 703 defer syspropLibrariesLock.Unlock() 704 705 libraries := syspropLibraries(ctx.Config()) 706 *libraries = append(*libraries, "//"+ctx.ModuleDir()+":"+ctx.ModuleName()) 707 } 708} 709