Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/build/build/soong/sysprop/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 18 kB image not shown  

Quelle  sysprop_library.go   Sprache: unbekannt

 
Spracherkennung für: .go vermutete Sprache: Unknown {[0] [0] [0]} [Methode: Schwerpunktbildung, einfache Gewichte, sechs Dimensionen]

// Copyright (C) 2019 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// sysprop package defines a module named sysprop_library that can implement sysprop as API
// See https://source.android.com/devices/architecture/sysprops-apis for details
package sysprop

import (
 "fmt"
 "strings"
 "sync"

 "github.com/google/blueprint"
 "github.com/google/blueprint/proptools"

 "android/soong/android"
 "android/soong/cc"
 "android/soong/java"
 "android/soong/rust"
)

//go:generate go run ../../blueprint/gobtools/codegen

type dependencyTag struct {
 blueprint.BaseDependencyTag
 name string
}

type syspropGenProperties struct {
 Srcs  []string `android:"path"`
 Scope string
 Name  *string
}

type syspropJavaGenRule struct {
 android.ModuleBase

 properties syspropGenProperties
}

type syspropRustGenRule struct {
 *rust.BaseSourceProvider

 properties rustLibraryProperties
}

var _ rust.SourceProvider = (*syspropRustGenRule)(nil)

var (
 syspropJava = pctx.AndroidStaticRule("syspropJava",
  blueprint.RuleParams{
   Command: `rm -rf $out.tmp && mkdir -p $out.tmp && ` +
    `$syspropJavaCmd --scope $scope --java-output-dir $out.tmp $in && ` +
    `$soongZipCmd -jar -o $out -C $out.tmp -D $out.tmp && rm -rf $out.tmp`,
   CommandDeps: []string{
    "$syspropJavaCmd",
    "$soongZipCmd",
   },
   SandboxDisabled: true,
  }, "scope")
 syspropRust = pctx.AndroidStaticRule("syspropRust",
  blueprint.RuleParams{
   Command: `rm -rf $out_dir && mkdir -p $out_dir && ` +
    `$syspropRustCmd --scope $scope --rust-output-dir $out_dir $in`,
   CommandDeps: []string{
    "$syspropRustCmd",
   },
   SandboxDisabled: true,
  }, "scope", "out_dir")
)

func init() {
 pctx.HostBinToolVariable("soongZipCmd", "soong_zip")
 pctx.HostBinToolVariable("syspropJavaCmd", "sysprop_java")
 pctx.HostBinToolVariable("syspropRustCmd", "sysprop_rust")
}

var SyspropLibraryInfoProvider = blueprint.NewProvider[SyspropLibraryInfo]()

// @auto-generate: gob
type SyspropLibraryInfo struct {
 CheckApiFileTimeStamp android.WritablePath
 CurrentApiFile        android.OptionalPath
}

// syspropJavaGenRule module generates srcjar containing generated java APIs.
// It also depends on check api rule, so api check has to pass to use sysprop_library.
func (g *syspropJavaGenRule) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 var genSrcjars android.Paths
 for _, syspropFile := range android.PathsForModuleSrc(ctx, g.properties.Srcs) {
  srcJarFile := android.GenPathWithExt(ctx, "sysprop", syspropFile, "srcjar")

  ctx.Build(pctx, android.BuildParams{
   Rule:        syspropJava,
   Description: "sysprop_java " + syspropFile.Rel(),
   Output:      srcJarFile,
   Input:       syspropFile,
   Args: map[string]string{
    "scope": g.properties.Scope,
   },
  })

  genSrcjars = append(genSrcjars, srcJarFile)
 }

 ctx.SetOutputFiles(genSrcjars, "")
}

func (g *syspropJavaGenRule) DepsMutator(ctx android.BottomUpMutatorContext) {
}

func syspropJavaGenFactory() android.Module {
 g := &syspropJavaGenRule{}
 g.AddProperties(&g.properties)
 android.InitAndroidModule(g)
 return g
}

// syspropRustGenRule module generates rust source files containing generated rust APIs.
// It also depends on check api rule, so api check has to pass to use sysprop_library.
func (g *syspropRustGenRule) GenerateSource(ctx rust.ModuleContext, deps rust.PathDeps) android.Path {
 outputDir := android.PathForModuleOut(ctx, "src")
 libFile := outputDir.Join(ctx, "lib.rs")
 g.BaseSourceProvider.OutputFiles = append(g.BaseSourceProvider.OutputFiles, libFile)
 libFileLines := []string{"//! Autogenerated system property accessors."}

 for _, syspropFile := range android.PathsForModuleSrc(ctx, g.properties.Sysprop_srcs) {
  moduleName := syspropPathToRustModule(syspropFile)
  moduleDir := outputDir.Join(ctx, moduleName)
  modulePath := moduleDir.Join(ctx, "mod.rs")

  ctx.Build(pctx, android.BuildParams{
   Rule:        syspropRust,
   Description: "sysprop_rust " + syspropFile.Rel(),
   Output:      modulePath,
   Input:       syspropFile,
   Args: map[string]string{
    "scope":   g.properties.Scope,
    "out_dir": moduleDir.String(),
   },
  })

  g.BaseSourceProvider.OutputFiles = append(g.BaseSourceProvider.OutputFiles, modulePath)
  libFileLines = append(libFileLines, fmt.Sprintf("pub mod %s;", moduleName))
 }

 libFileSource := strings.Join(libFileLines, "\n")
 android.WriteFileRule(ctx, libFile, libFileSource)

 return libFile
}

func (g *syspropRustGenRule) SourceProviderProps() []interface{} {
 return append(g.BaseSourceProvider.SourceProviderProps(), &g.Properties)
}

// syspropPathToRustModule takes a path to a .sysprop file and returns the name to use for the
// corresponding Rust module.
func syspropPathToRustModule(syspropFilename android.Path) string {
 filenameBase := strings.TrimSuffix(syspropFilename.Base(), ".sysprop")
 return strings.ToLower(filenameBase)
}

func (g *syspropRustGenRule) DepsMutator(ctx android.BottomUpMutatorContext) {
}

func syspropRustGenFactory() android.Module {
 g := &syspropRustGenRule{
  BaseSourceProvider: rust.NewSourceProvider(),
 }
 sourceProvider := rust.NewSourceProviderModule(android.DeviceSupported, g, false, false)
 sourceProvider.AddProperties(&g.properties)
 return sourceProvider.Init()
}

type syspropLibrary struct {
 android.ModuleBase
 android.ApexModuleBase

 properties syspropLibraryProperties
}

type syspropLibraryProperties struct {
 // Determine who owns this sysprop library. Possible values are
 // "Platform", "Vendor", or "Odm"
 Property_owner string

 // list of package names that will be documented and publicized as API
 Api_packages []string

 // If set to true, allow this module to be dexed and installed on devices.
 Installable *bool

 // Make this module available when building for ramdisk
 Ramdisk_available *bool

 // Make this module available when building for vendor ramdisk
 Vendor_ramdisk_available *bool

 // Make this module available when building for recovery
 Recovery_available *bool

 // Make this module available when building for vendor
 Vendor_available *bool

 // Make this module available when building for product
 Product_available *bool

 // list of .sysprop files which defines the properties.
 Srcs []string `android:"path"`

 // If set to true, build a variant of the module for the host.  Defaults to false.
 Host_supported *bool

 Cpp struct {
  // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
  // Forwarded to cc_library.min_sdk_version
  Min_sdk_version *string

  // C compiler flags used to build library
  Cflags []string

  // Linker flags used to build binary
  Ldflags []string
 }

 Java struct {
  // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
  // Forwarded to java_library.min_sdk_version
  Min_sdk_version *string
 }

 Rust struct {
  // Minimum sdk version that the artifact should support when it runs as part of mainline modules(APEX).
  // Forwarded to rust_library.min_sdk_version
  Min_sdk_version *string
 }
}

var (
 pctx         = android.NewPackageContext("android/soong/sysprop")
 syspropCcTag = dependencyTag{name: "syspropCc"}

 syspropLibrariesKey  = android.NewOnceKey("syspropLibraries")
 syspropLibrariesLock sync.Mutex
)

// List of sysprop_library used by property_contexts to perform type check.
func syspropLibraries(config android.Config) *[]string {
 return config.Once(syspropLibrariesKey, func() interface{} {
  return &[]string{}
 }).(*[]string)
}

func SyspropLibraries(config android.Config) []string {
 return append([]string{}, *syspropLibraries(config)...)
}

func init() {
 registerSyspropBuildComponents(android.InitRegistrationContext)
}

func registerSyspropBuildComponents(ctx android.RegistrationContext) {
 ctx.RegisterModuleType("sysprop_library", syspropLibraryFactory)
}

func (m *syspropLibrary) Name() string {
 return m.BaseModuleName() + "_sysprop_library"
}

func (m *syspropLibrary) Owner() string {
 return m.properties.Property_owner
}

func (m *syspropLibrary) CcImplementationModuleName() string {
 return "lib" + m.BaseModuleName()
}

func (m *syspropLibrary) javaPublicStubName() string {
 return m.BaseModuleName() + "_public"
}

func (m *syspropLibrary) javaGenModuleName() string {
 return m.BaseModuleName() + "_java_gen"
}

func (m *syspropLibrary) javaGenPublicStubName() string {
 return m.BaseModuleName() + "_java_gen_public"
}

func (m *syspropLibrary) rustGenStubName() string {
 return "lib" + m.rustCrateName() + "_rust"
}

func (m *syspropLibrary) rustCrateName() string {
 moduleName := strings.ToLower(m.BaseModuleName())
 moduleName = strings.ReplaceAll(moduleName, "-", "_")
 moduleName = strings.ReplaceAll(moduleName, ".", "_")
 return moduleName
}

func (m *syspropLibrary) BaseModuleName() string {
 return m.ModuleBase.Name()
}

// GenerateAndroidBuildActions of sysprop_library handles API dump and API check.
// generated java_library will depend on these API files.
func (m *syspropLibrary) GenerateAndroidBuildActions(ctx android.ModuleContext) {
 srcs := android.PathsForModuleSrc(ctx, m.properties.Srcs)
 for _, syspropFile := range srcs {
  if syspropFile.Ext() != ".sysprop" {
   ctx.PropertyErrorf("srcs", "srcs contains non-sysprop file %q", syspropFile.String())
  }
 }

 if ctx.Failed() {
  return
 }
}

var _ android.ApexModule = (*syspropLibrary)(nil)

// Implements android.ApexModule
func (m *syspropLibrary) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
 return android.MinApiLevel
}

// sysprop_library creates schematized APIs from sysprop description files (.sysprop).
// Both Java and C++ modules can link against sysprop_library. Note that the generated
// C++ module has its name prefixed with `lib`, and it is this module that should be
// depended on from other C++ modules; i.e., if the sysprop_library module is named
// `foo`, C++ modules should depend on `libfoo`.
func syspropLibraryFactory() android.Module {
 m := &syspropLibrary{}

 m.AddProperties(
  &m.properties,
 )
 android.InitAndroidModule(m)
 android.InitApexModule(m)
 android.AddLoadHook(m, func(ctx android.LoadHookContext) { syspropLibraryHook(ctx, m) })
 return m
}

type ccLibraryProperties struct {
 Name             *string
 Srcs             []string
 Soc_specific     *bool
 Device_specific  *bool
 Product_specific *bool
 Sysprop          struct {
  Platform *bool
 }
 Target struct {
  Android struct {
   Header_libs []string
   Shared_libs []string
  }
  Host struct {
   Static_libs []string
  }
 }
 Required                 []string
 Recovery                 *bool
 Recovery_available       *bool
 Vendor_available         *bool
 Product_available        *bool
 Ramdisk_available        *bool
 Vendor_ramdisk_available *bool
 Host_supported           *bool
 Apex_available           []string
 Min_sdk_version          *string
 Cflags                   []string
 Ldflags                  []string
 Split_all_variants       *bool
}

type javaLibraryProperties struct {
 Name               *string
 Srcs               []string
 Soc_specific       *bool
 Device_specific    *bool
 Product_specific   *bool
 Required           []string
 Sdk_version        *string
 Installable        *bool
 Libs               []string
 Stem               *string
 SyspropPublicStub  string
 Apex_available     []string
 Min_sdk_version    *string
 Split_all_variants *bool
}

type rustLibraryProperties struct {
 Name               *string
 Sysprop_srcs       []string `android:"path"`
 Scope              string
 Srcs               proptools.Configurable[[]string]
 Installable        *bool
 Crate_name         string
 Rustlibs           proptools.Configurable[[]string]
 Vendor_available   *bool
 Product_available  *bool
 Apex_available     []string
 Min_sdk_version    *string
 Split_all_variants *bool
}

func syspropLibraryHook(ctx android.LoadHookContext, m *syspropLibrary) {
 if len(m.properties.Srcs) == 0 {
  ctx.PropertyErrorf("srcs", "sysprop_library must specify srcs")
 }

 // ctx's Platform or Specific functions represent where this sysprop_library installed.
 installedInSystem := ctx.Platform() || ctx.SystemExtSpecific()
 installedInVendorOrOdm := ctx.SocSpecific() || ctx.DeviceSpecific()
 installedInProduct := ctx.ProductSpecific()
 isOwnerPlatform := false
 var javaSyspropStub string

 // javaSyspropStub contains stub libraries used by generated APIs, instead of framework stub.
 // This is to make sysprop_library link against core_current.
 if installedInVendorOrOdm {
  javaSyspropStub = "sysprop-library-stub-vendor"
 } else if installedInProduct {
  javaSyspropStub = "sysprop-library-stub-product"
 } else {
  javaSyspropStub = "sysprop-library-stub-platform"
 }

 switch m.Owner() {
 case "Platform":
  // Every partition can access platform-defined properties
  isOwnerPlatform = true
 case "Vendor":
  // System can't access vendor's properties
  if installedInSystem {
   ctx.ModuleErrorf("None of soc_specific, device_specific, product_specific is true. " +
    "System can't access sysprop_library owned by Vendor")
  }
 case "Odm":
  // Only vendor can access Odm-defined properties
  if !installedInVendorOrOdm {
   ctx.ModuleErrorf("Neither soc_speicifc nor device_specific is true. " +
    "Odm-defined properties should be accessed only in Vendor or Odm")
  }
 default:
  ctx.PropertyErrorf("property_owner",
   "Unknown value %s: must be one of Platform, Vendor or Odm", m.Owner())
 }

 // Generate a C++ implementation library.
 // cc_library can receive *.sysprop files as their srcs, generating sources itself.
 ccProps := ccLibraryProperties{}
 ccProps.Name = proptools.StringPtr(m.CcImplementationModuleName())
 ccProps.Srcs = m.properties.Srcs
 ccProps.Soc_specific = proptools.BoolPtr(ctx.SocSpecific())
 ccProps.Device_specific = proptools.BoolPtr(ctx.DeviceSpecific())
 ccProps.Product_specific = proptools.BoolPtr(ctx.ProductSpecific())
 ccProps.Sysprop.Platform = proptools.BoolPtr(isOwnerPlatform)
 ccProps.Target.Android.Header_libs = []string{"libbase_headers"}
 ccProps.Target.Android.Shared_libs = []string{"liblog"}
 ccProps.Target.Host.Static_libs = []string{"libbase", "liblog"}
 ccProps.Recovery_available = m.properties.Recovery_available
 ccProps.Vendor_available = m.properties.Vendor_available
 ccProps.Product_available = m.properties.Product_available
 ccProps.Ramdisk_available = m.properties.Ramdisk_available
 ccProps.Vendor_ramdisk_available = m.properties.Vendor_ramdisk_available
 ccProps.Host_supported = m.properties.Host_supported
 ccProps.Apex_available = m.ApexProperties.Apex_available
 ccProps.Min_sdk_version = m.properties.Cpp.Min_sdk_version
 ccProps.Cflags = m.properties.Cpp.Cflags
 ccProps.Ldflags = m.properties.Cpp.Ldflags
 ccProps.Split_all_variants = proptools.BoolPtr(m.SplitAllVariants())
 ctx.CreateModule(cc.LibraryFactory, &ccProps)

 scope := "internal"

 // We need to only use public version, if the partition where sysprop_library will be installed
 // is different from owner.
 if ctx.ProductSpecific() {
  // Currently product partition can't own any sysprop_library. So product always uses public.
  scope = "public"
 } else if isOwnerPlatform && installedInVendorOrOdm {
  // Vendor or Odm should use public version of Platform's sysprop_library.
  scope = "public"
 }

 // Generate a Java implementation library.
 // Contrast to C++, syspropJavaGenRule module will generate srcjar and the srcjar will be fed
 // to Java implementation library.
 ctx.CreateModule(syspropJavaGenFactory, &syspropGenProperties{
  Srcs:  m.properties.Srcs,
  Scope: scope,
  Name:  proptools.StringPtr(m.javaGenModuleName()),
 })

 // if platform sysprop_library is installed in /system or /system-ext, we regard it as an API
 // and allow any modules (even from different partition) to link against the sysprop_library.
 // To do that, we create a public stub and expose it to modules with sdk_version: system_*.
 var publicStub string
 if isOwnerPlatform && installedInSystem {
  publicStub = m.javaPublicStubName()
 }

 ctx.CreateModule(java.LibraryFactory, &javaLibraryProperties{
  Name:               proptools.StringPtr(m.BaseModuleName()),
  Srcs:               []string{":" + m.javaGenModuleName()},
  Soc_specific:       proptools.BoolPtr(ctx.SocSpecific()),
  Device_specific:    proptools.BoolPtr(ctx.DeviceSpecific()),
  Product_specific:   proptools.BoolPtr(ctx.ProductSpecific()),
  Installable:        m.properties.Installable,
  Sdk_version:        proptools.StringPtr("core_current"),
  Libs:               []string{javaSyspropStub},
  SyspropPublicStub:  publicStub,
  Apex_available:     m.ApexProperties.Apex_available,
  Min_sdk_version:    m.properties.Java.Min_sdk_version,
  Split_all_variants: proptools.BoolPtr(m.SplitAllVariants()),
 })

 if publicStub != "" {
  ctx.CreateModule(syspropJavaGenFactory, &syspropGenProperties{
   Srcs:  m.properties.Srcs,
   Scope: "public",
   Name:  proptools.StringPtr(m.javaGenPublicStubName()),
  })

  ctx.CreateModule(java.LibraryFactory, &javaLibraryProperties{
   Name:               proptools.StringPtr(publicStub),
   Srcs:               []string{":" + m.javaGenPublicStubName()},
   Installable:        proptools.BoolPtr(false),
   Sdk_version:        proptools.StringPtr("core_current"),
   Libs:               []string{javaSyspropStub},
   Stem:               proptools.StringPtr(m.BaseModuleName()),
   Split_all_variants: proptools.BoolPtr(m.SplitAllVariants()),
  })
 }

 // Generate a Rust implementation library.
 rustProps := rustLibraryProperties{
  Name:         proptools.StringPtr(m.rustGenStubName()),
  Sysprop_srcs: m.properties.Srcs,
  Scope:        scope,
  Installable:  m.properties.Installable,
  Crate_name:   m.rustCrateName(),
  Rustlibs: proptools.NewSimpleConfigurable([]string{
   "liblog_rust",
   "librustutils",
  }),
  Vendor_available:   m.properties.Vendor_available,
  Product_available:  m.properties.Product_available,
  Apex_available:     m.ApexProperties.Apex_available,
  Min_sdk_version:    proptools.StringPtr("29"),
  Split_all_variants: proptools.BoolPtr(m.SplitAllVariants()),
 }
 ctx.CreateModule(syspropRustGenFactory, &rustProps)

 // syspropLibraries will be used by property_contexts to check types.
 // Record absolute paths of sysprop_library to prevent soong_namespace problem.
 if m.ExportedToMake() {
  syspropLibrariesLock.Lock()
  defer syspropLibrariesLock.Unlock()

  libraries := syspropLibraries(ctx.Config())
  *libraries = append(*libraries, "//"+ctx.ModuleDir()+":"+ctx.ModuleName())
 }
}

[Dauer der Verarbeitung: 0.19 Sekunden, vorverarbeitet 2026-06-28]