Eine aufbereitete Darstellung der Quelle

 
     
 
 
Anforderungen  |   Konzepte  |   Entwurf  |   Entwicklung  |   Qualitätssicherung  |   Lebenszyklus  |   Steuerung
 
 
 
 

Benutzer

Quelle  classpath_fragment.go   Sprache: unbekannt

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

/*
 * Copyright (C) 2021 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.
 */

package java

import (
 "fmt"
 "strings"

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

 "android/soong/android"
)

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

// Build rules and utilities to generate individual packages/modules/common/proto/classpaths.proto
// config files based on build configuration to embed into /system and /apex on a device.
//
// See `derive_classpath` service that reads the configs at runtime and defines *CLASSPATH variables
// on the device.

type classpathType int

const (
 // Matches definition in packages/modules/common/proto/classpaths.proto
 BOOTCLASSPATH classpathType = iota
 DEX2OATBOOTCLASSPATH
 SYSTEMSERVERCLASSPATH
 STANDALONE_SYSTEMSERVER_JARS
)

func (c classpathType) String() string {
 return [...]string{"BOOTCLASSPATH", "DEX2OATBOOTCLASSPATH", "SYSTEMSERVERCLASSPATH", "STANDALONE_SYSTEMSERVER_JARS"}[c]
}

type classpathFragmentProperties struct {
 // Whether to generated classpaths.proto config instance for the fragment. If the config is not
 // generated, then relevant boot jars are added to platform classpath, i.e. platform_bootclasspath
 // or platform_systemserverclasspath. This is useful for non-updatable APEX boot jars, to keep
 // them as part of dexopt on device. Defaults to true.
 Generate_classpaths_proto *bool

 // If not blank, the minimum SDK version that the fragment will be included in. This is mostly
 // relevant when other fragments depend on this one through the `fragments` property, to prune
 // those dependencies in SDKs where this fragment doesn't exist.
 Min_sdk_version proptools.Configurable[string] `android:"replace_instead_of_append"`
}

// classpathFragment interface is implemented by a module that contributes jars to a *CLASSPATH
// variables at runtime.
type classpathFragment interface {
 android.Module

 classpathFragmentBase() *ClasspathFragmentBase

 // MinSdkVersion returns the value of the min_sdk_version property.
 MinSdkVersion(ctx android.MinSdkVersionFromValueContext) android.ApiLevel

 // ConfigurableEvaluator returns the ConfigurableEvaluator for the module.
 ConfigurableEvaluator(ctx android.ConfigurableEvaluatorContext) proptools.ConfigurableEvaluator
}

// ClasspathFragmentBase is meant to be embedded in any module types that implement classpathFragment;
// such modules are expected to call initClasspathFragment().
type ClasspathFragmentBase struct {
 android.ModuleBase

 properties classpathFragmentProperties

 classpathType classpathType

 outputFilepath android.OutputPath
 installDirPath android.InstallPath
}

func (c *ClasspathFragmentBase) classpathFragmentBase() *ClasspathFragmentBase {
 return c
}

func (c *ClasspathFragmentBase) MinSdkVersion(ctx android.MinSdkVersionFromValueContext) android.ApiLevel {
 minSdkVersion := c.properties.Min_sdk_version.Get(c.ConfigurableEvaluator(ctx))
 if minSdkVersion.IsPresent() {
  return android.ApiLevelFrom(ctx, minSdkVersion.Get())
 }
 return android.MinApiLevel
}

func (c *ClasspathFragmentBase) MinSdkVersionSupported(ctx android.BaseModuleContext) android.ApiLevel {
 // Return MinApiLevel since fragments should be allowed to have newer min_sdk_version's than their
 // APEX'es because they may be added to existing modules to add classpath jars on newer platform
 // releases.
 return android.MinApiLevel
}

func (c *ClasspathFragmentBase) checkMinSdkVersionConstraint(ctx android.ModuleContext) {
 apexInfo, _ := android.ModuleProvider(ctx, android.ApexInfoProvider)
 if !apexInfo.IsForPlatform() && !apexInfo.MinSdkVersion.IsCurrent() {
  fragmentMinSdk := c.properties.Min_sdk_version.Get(c.ConfigurableEvaluator(ctx))
  if fragmentMinSdk.IsPresent() {
   apiLevel := android.ApiLevelFrom(ctx, fragmentMinSdk.Get())
   if apiLevel.LessThan(apexInfo.MinSdkVersion) {
    ctx.ModuleErrorf("fragment min_sdk_version %v lower than its APEX (%v)", apiLevel, apexInfo.MinSdkVersion)
   }
  }
 }
}

// Initializes ClasspathFragmentBase struct. Must be called by all modules that include ClasspathFragmentBase.
func initClasspathFragment(c classpathFragment, classpathType classpathType) {
 base := c.classpathFragmentBase()
 base.classpathType = classpathType
 c.AddProperties(&base.properties)
}

// Matches definition of Jar in packages/modules/SdkExtensions/proto/classpaths.proto
type classpathJar struct {
 path          string
 classpath     classpathType
 minSdkVersion string
 maxSdkVersion string
}

// gatherPossibleApexModuleNamesAndStems returns a set of module and stem names from the
// supplied contents that may be in the apex boot jars.
//
// The module names are included because sometimes the stem is set to just change the name of
// the installed file and it expects the configuration to still use the actual module name.
//
// The stem names are included because sometimes the stem is set to change the effective name of the
// module that is used in the configuration as well,e .g. when a test library is overriding an
// actual boot jar
func gatherPossibleApexModuleNamesAndStems(ctx android.ModuleContext, contents []string, tag blueprint.DependencyTag) []string {
 set := map[string]struct{}{}
 for _, name := range contents {
  dep := ctx.GetDirectDepProxyWithTag(name, tag)
  if dep.IsNil() && ctx.Config().AllowMissingDependencies() {
   // Ignore apex boot jars from dexpreopt if it does not exist, and missing deps are allowed.
   continue
  }
  info := android.OtherModuleProviderOrDefault(ctx, dep, JavaInfoProvider)
  set[ModuleStemForDeapexing(ctx, dep)] = struct{}{}
  set[info.Stem] = struct{}{}
 }
 return android.SortedKeys(set)
}

// Converts android.ConfiguredJarList into a list of classpathJars for each given classpathType.
func configuredJarListToClasspathJars(ctx android.ModuleContext, configuredJars android.ConfiguredJarList, classpaths ...classpathType) []classpathJar {
 paths := configuredJars.DevicePaths(ctx.Config(), android.Android)
 jars := make([]classpathJar, 0, len(paths)*len(classpaths))
 for i := 0; i < len(paths); i++ {
  for _, classpathType := range classpaths {
   jar := classpathJar{
    classpath: classpathType,
    path:      paths[i],
   }
   ctx.VisitDirectDepsProxy(func(m android.ModuleProxy) {
    if m.Name() != configuredJars.Jar(i) {
     return
    }
    if _, ok := android.OtherModuleProvider(ctx, m, SdkLibraryInfoProvider); ok {
     info := android.OtherModuleProviderOrDefault(ctx, m, JavaInfoProvider)
     commonInfo := android.OtherModulePointerProviderOrDefault(ctx, m, android.CommonModuleInfoProvider)
     minSdkVersion := *commonInfo.MinSdkVersion.ApiLevel
     maxSdkVersion := info.MaxSdkVersion
     // TODO(208456999): instead of mapping "current" to latest, min_sdk_version should never be set to "current"
     if minSdkVersion.Specified() {
      if minSdkVersion.IsCurrent() {
       jar.minSdkVersion = ctx.Config().DefaultAppTargetSdk(ctx).String()
      } else {
       jar.minSdkVersion = minSdkVersion.String()
      }
     }
     if maxSdkVersion.Specified() {
      if maxSdkVersion.IsCurrent() {
       jar.maxSdkVersion = ctx.Config().DefaultAppTargetSdk(ctx).String()
      } else {
       jar.maxSdkVersion = maxSdkVersion.String()
      }
     }
    }
   })
   jars = append(jars, jar)
  }
 }
 return jars
}

func (c *ClasspathFragmentBase) outputFilename() string {
 return strings.ToLower(c.classpathType.String()) + ".pb"
}

func (c *ClasspathFragmentBase) generateClasspathProtoBuildActions(ctx android.ModuleContext, configuredJars android.ConfiguredJarList, jars []classpathJar) android.OutputPath {
 generateProto := proptools.BoolDefault(c.properties.Generate_classpaths_proto, true)
 if generateProto {
  outputFilename := c.outputFilename()
  c.outputFilepath = android.PathForModuleOut(ctx, outputFilename).OutputPath
  c.installDirPath = android.PathForModuleInstall(ctx, "etc", "classpaths")

  generatedTextproto := android.PathForModuleOut(ctx, outputFilename+".textproto")
  writeClasspathsTextproto(ctx, generatedTextproto, jars)

  rule := android.NewRuleBuilder(pctx, ctx).SandboxDisabled()
  rule.Command().
   BuiltTool("conv_classpaths_proto").
   Flag("encode").
   Flag("--format=textproto").
   FlagWithInput("--input=", generatedTextproto).
   FlagWithOutput("--output=", c.outputFilepath)

  rule.Build("classpath_fragment", "Compiling "+c.outputFilepath.String())
 }

 classpathProtoInfo := ClasspathFragmentProtoContentInfo{
  ClasspathFragmentProtoGenerated:  generateProto,
  ClasspathFragmentProtoContents:   configuredJars,
  ClasspathFragmentProtoInstallDir: c.installDirPath,
  ClasspathFragmentProtoOutput:     c.outputFilepath,
 }
 android.SetProvider(ctx, ClasspathFragmentProtoContentInfoProvider, classpathProtoInfo)
 return c.outputFilepath
}

func (c *ClasspathFragmentBase) installClasspathProto(ctx android.ModuleContext) android.InstallPath {
 return ctx.InstallFile(c.installDirPath, c.outputFilename(), c.outputFilepath)
}

func writeClasspathsTextproto(ctx android.ModuleContext, output android.WritablePath, jars []classpathJar) {
 var content strings.Builder

 for _, jar := range jars {
  fmt.Fprintf(&content, "jars {\n")
  fmt.Fprintf(&content, "path: \"%s\"\n", jar.path)
  fmt.Fprintf(&content, "classpath: %s\n", jar.classpath)
  fmt.Fprintf(&content, "min_sdk_version: \"%s\"\n", jar.minSdkVersion)
  fmt.Fprintf(&content, "max_sdk_version: \"%s\"\n", jar.maxSdkVersion)
  fmt.Fprintf(&content, "}\n")
 }

 android.WriteFileRule(ctx, output, content.String())
}

// Returns AndroidMkInfo objects to install generated classpath.proto.
// Do not use this to install into APEXes as the injection of the generated files happen separately for APEXes.
func (c *ClasspathFragmentBase) androidMkInfo() android.AndroidMkInfo {
 info := android.AndroidMkInfo{
  Class:      "ETC",
  OutputFile: android.OptionalPathForPath(c.outputFilepath),
 }
 info.SetString("LOCAL_MODULE_PATH", c.installDirPath.String())
 info.SetString("LOCAL_INSTALLED_MODULE_STEM", c.outputFilepath.Base())
 return info
}

var ClasspathFragmentProtoContentInfoProvider = blueprint.NewProvider[ClasspathFragmentProtoContentInfo]()

// @auto-generate: gob
type ClasspathFragmentProtoContentInfo struct {
 // Whether the classpaths.proto config is generated for the fragment.
 ClasspathFragmentProtoGenerated bool

 // ClasspathFragmentProtoContents contains a list of jars that are part of this classpath fragment.
 ClasspathFragmentProtoContents android.ConfiguredJarList

 // ClasspathFragmentProtoOutput is an output path for the generated classpaths.proto config of this module.
 //
 // The file should be copied to a relevant place on device, see ClasspathFragmentProtoInstallDir
 // for more details.
 ClasspathFragmentProtoOutput android.OutputPath

 // ClasspathFragmentProtoInstallDir contains information about on device location for the generated classpaths.proto file.
 //
 // The path encodes expected sub-location within partitions, i.e. etc/classpaths/<proto-file>,
 // for ClasspathFragmentProtoOutput. To get sub-location, instead of the full output / make path
 // use android.InstallPath#Rel().
 //
 // This is only relevant for APEX modules as they perform their own installation; while regular
 // system files are installed via ClasspathFragmentBase#androidMkInfo().
 ClasspathFragmentProtoInstallDir android.InstallPath
}

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

                                                                                                                                                                                                                                                                                                                                                                                                     


Neuigkeiten

     Aktuelles
     Motto des Tages

Software

     Quellcodebibliothek
     Eigene Quellcodes
     Fremde Quellcodes
     Suchen

Aktivitäten

     Artikel über Sicherheit
     Anleitung zur Aktivierung von SSL

Muße

     Gedichte
     Musik
     Bilder

Jenseits des Üblichen ....
    

Besucherstatistik

Besucherstatistik