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

Quelle  finder.go   Sprache: unbekannt

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

// Copyright 2017 Google Inc. All rights reserved.
//
// 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 build

import (
 "bytes"
 "io/ioutil"
 "os"
 "path/filepath"
 "strings"

 "android/soong/finder"
 "android/soong/finder/fs"
 "android/soong/ui/logger"

 "android/soong/ui/metrics"
)

// This file provides an interface to the Finder type for soong_ui. Finder is
// used to recursively traverse the source tree to gather paths of files, such
// as Android.bp or Android.mk, and store the lists/database of paths in files
// under `$OUT_DIR/.module_paths`. This directory can also be dist'd.

// NewSourceFinder returns a new Finder configured to search for source files.
// Callers of NewSourceFinder should call <f.Shutdown()> when done
func NewSourceFinder(ctx Context, config Config) (f *finder.Finder) {
 e := ctx.BeginTrace(metrics.RunSetupTool, "NewSourceFinder")
 defer e.End()

 // Set up the working directory for the Finder.
 dir, err := os.Getwd()
 if err != nil {
  ctx.Fatalf("No working directory for module-finder: %v", err.Error())
 }
 filesystem := fs.OsFs

 // .out-dir and .find-ignore are markers for Finder to ignore siblings and
 // subdirectories of the directory Finder finds them in, hence stopping the
 // search recursively down those branches. It's possible that these files
 // are in the root directory, and if they are, then the subsequent error
 // messages are very confusing, so check for that here.
 pruneFiles := []string{".out-dir", ".find-ignore"}
 for _, name := range pruneFiles {
  prunePath := filepath.Join(dir, name)
  _, statErr := filesystem.Lstat(prunePath)
  if statErr == nil {
   ctx.Fatalf("%v must not exist", prunePath)
  }
 }

 // Set up configuration parameters for the Finder cache.
 cacheParams := finder.CacheParams{
  WorkingDirectory: dir,
  RootDirs:         []string{"."},
  FollowSymlinks:   config.environ.IsEnvTrue("ALLOW_BP_UNDER_SYMLINKS"),
  ExcludeDirs:      []string{".git", ".repo"},
  PruneFiles:       pruneFiles,
  IncludeFiles: []string{
   // Kati build definitions.
   "Android.mk",
   // Product configuration files.
   "AndroidProducts.mk",
   // General Soong build definitions, using the Blueprint syntax.
   "Android.bp",
   // Kati clean definitions.
   "CleanSpec.mk",
   // Ownership definition.
   "OWNERS",
   // Test configuration for modules in directories that contain this
   // file.
   "TEST_MAPPING",
   // METADATA file of packages
   "METADATA",
   // Release config contributions.
   "release_config_map.textproto",
   // Release config allowed duplicate flag declarations.
   "duplicate_allowlist.txt",
  },
  IncludeSuffixes: []string{
   // .mk files for product/board configuration.
   ".mk",
   // otatools cert files
   ".pk8",
   ".pem",
   ".prop",
   ".avbpubkey",
  },
 }
 dumpDir := config.FileListDir()
 f, err = finder.New(cacheParams, filesystem, logger.New(ioutil.Discard),
  filepath.Join(dumpDir, "files.db"))
 if err != nil {
  ctx.Fatalf("Could not create module-finder: %v", err)
 }
 return f
}

func findProductAndBoardConfigFiles(entries finder.DirEntries) (dirNames []string, fileNames []string) {
 matches := []string{}
 for _, foundName := range entries.FileNames {
  if foundName != "Android.mk" &&
   foundName != "AndroidProducts.mk" &&
   foundName != "CleanSpec.mk" &&
   strings.HasSuffix(foundName, ".mk") {
   matches = append(matches, foundName)
  }
 }
 return entries.DirNames, matches
}

func findOtaToolsCertFiles(entries finder.DirEntries) (dirNames []string, fileNames []string) {
 matches := []string{}
 for _, foundName := range entries.FileNames {
  if strings.HasSuffix(foundName, ".pk8") ||
   strings.HasSuffix(foundName, ".pem") ||
   strings.HasSuffix(foundName, ".avbpubkey") {
   matches = append(matches, foundName)
  }
 }
 return entries.DirNames, matches
}

func findOtaToolsOemPropFiles(entries finder.DirEntries) (dirNames []string, fileNames []string) {
 matches := []string{}
 for _, foundName := range entries.FileNames {
  if strings.HasPrefix(foundName, "oem") &&
   strings.HasSuffix(foundName, ".prop") {
   matches = append(matches, foundName)
  }
 }
 return entries.DirNames, matches
}

// FindSources searches for source files known to <f> and writes them to the filesystem for
// use later.
func FindSources(ctx Context, config Config, f *finder.Finder) {
 // note that dumpDir in FindSources may be different than dumpDir in NewSourceFinder
 // if a caller such as multiproduct_kati wants to share one Finder among several builds
 dumpDir := config.FileListDir()
 os.MkdirAll(dumpDir, 0777)

 // Stop searching a subdirectory recursively after finding an Android.mk.
 androidMks := f.FindFirstNamedAt(".", "Android.mk")
 androidMks = ignoreSomeAndroidMks(androidMks)
 blockAndroidMks(ctx, androidMks)
 err := dumpListToFile(ctx, config, androidMks, filepath.Join(dumpDir, "Android.mk.list"))
 if err != nil {
  ctx.Fatalf("Could not export module list: %v", err)
 }

 // Gate collecting/reporting mk metrics on builds that specifically request
 // it, as identifying the total number of mk files adds 4-5ms onto null
 // builds.
 if config.reportMkMetrics {
  androidMksTotal := f.FindNamedAt(".", "Android.mk")

  ctx.Metrics.SetToplevelMakefiles(len(androidMks))
  ctx.Metrics.SetTotalMakefiles(len(androidMksTotal))
  ctx.Metrics.DumpMkMetrics(config.MkMetrics())
 }

 // Stop searching a subdirectory recursively after finding a CleanSpec.mk.
 cleanSpecs := f.FindFirstNamedAt(".", "CleanSpec.mk")
 err = dumpListToFile(ctx, config, cleanSpecs, filepath.Join(dumpDir, "CleanSpec.mk.list"))
 if err != nil {
  ctx.Fatalf("Could not export module list: %v", err)
 }

 // Only consider AndroidProducts.mk in device/, vendor/ and product/, recursively in these directories.
 androidProductsMks := f.FindNamedAt("device", "AndroidProducts.mk")
 androidProductsMks = append(androidProductsMks, f.FindNamedAt("vendor", "AndroidProducts.mk")...)
 androidProductsMks = append(androidProductsMks, f.FindNamedAt("product", "AndroidProducts.mk")...)
 err = dumpListToFile(ctx, config, androidProductsMks, filepath.Join(dumpDir, "AndroidProducts.mk.list"))
 if err != nil {
  ctx.Fatalf("Could not export product list: %v", err)
 }

 // Recursively look for all OWNERS files.
 owners := f.FindNamedAt(".", "OWNERS")
 err = dumpListToFile(ctx, config, owners, filepath.Join(dumpDir, "OWNERS.list"))
 if err != nil {
  ctx.Fatalf("Could not find OWNERS: %v", err)
 }

 // Recursively look for all METADATA files.
 metadataFiles := f.FindNamedAt(".", "METADATA")
 metadataFiles = ignoreNonAndroidMetadataFiles(metadataFiles)
 err = dumpListToFile(ctx, config, metadataFiles, filepath.Join(dumpDir, "METADATA.list"))
 if err != nil {
  ctx.Fatalf("Could not find METADATA: %v", err)
 }

 // Recursively look for all release_config_map.textproto files.
 releaseConfigMaps := f.FindNamedAt(".", "release_config_map.textproto")
 err = dumpListToFile(ctx, config, releaseConfigMaps, filepath.Join(dumpDir, "release_config_map.list"))
 if err != nil {
  ctx.Fatalf("Could not find release_config_map.textproto: %v", err)
 }

 // Recursively look for all duplicate_allowlist.txt files where we found release_config_map.textproto.
 var duplicateAllowlists []string
 for _, mapPath := range releaseConfigMaps {
  // The only `duplicate_allowlist.txt` files we care about are in the same directory
  // as `release_config_map.textproto`.
  duplicateAllowlists = append(duplicateAllowlists, f.FindNamedAt(filepath.Dir(mapPath), "duplicate_allowlist.txt")...)
 }
 err = dumpListToFile(ctx, config, duplicateAllowlists, filepath.Join(dumpDir, "duplicate_allowlist.list"))
 if err != nil {
  ctx.Fatalf("Could not find duplicate_allowlist.txt: %v", err)
 }

 // Recursively look for all TEST_MAPPING files.
 testMappings := f.FindNamedAt(".", "TEST_MAPPING")
 err = dumpListToFile(ctx, config, testMappings, filepath.Join(dumpDir, "TEST_MAPPING.list"))
 if err != nil {
  ctx.Fatalf("Could not find TEST_MAPPING: %v", err)
 }

 // Recursively look for all otatools cert files.
 otatools_cert_files := f.FindMatching("build/make/target/product/security", findOtaToolsCertFiles)
 otatools_cert_files = append(otatools_cert_files, f.FindMatching("device", findOtaToolsCertFiles)...)
 otatools_cert_files = append(otatools_cert_files, f.FindMatching("external/avb/test/data", findOtaToolsCertFiles)...)
 otatools_cert_files = append(otatools_cert_files, f.FindMatching("packages/modules", findOtaToolsCertFiles)...)
 otatools_cert_files = append(otatools_cert_files, f.FindMatching("vendor", findOtaToolsCertFiles)...)
 otatools_cert_files = append(otatools_cert_files, f.FindMatching("device", findOtaToolsOemPropFiles)...)
 otatools_cert_files = append(otatools_cert_files, f.FindMatching("vendor", findOtaToolsOemPropFiles)...)
 err = dumpListToFile(ctx, config, otatools_cert_files, filepath.Join(dumpDir, "OtaToolsCertFiles.list"))
 if err != nil {
  ctx.Fatalf("Could not find otatools cert files: %v", err)
 }

 // Recursively look for all Android.bp files
 androidBps := f.FindNamedAt(".", "Android.bp")
 if len(androidBps) == 0 {
  ctx.Fatalf("No Android.bp found")
 }
 err = dumpListToFile(ctx, config, androidBps, filepath.Join(dumpDir, "Android.bp.list"))
 if err != nil {
  ctx.Fatalf("Could not find modules: %v", err)
 }

 // Recursively look for all product/board config files.
 configurationFiles := f.FindMatching(".", findProductAndBoardConfigFiles)
 err = dumpListToFile(ctx, config, configurationFiles, filepath.Join(dumpDir, "configuration.list"))
 if err != nil {
  ctx.Fatalf("Could not export product/board configuration list: %v", err)
 }

 if config.Dist() {
  f.WaitForDbDump()
  // Dist the files.db plain text database.
  distFile(ctx, config, f.DbPath, "soong_ui/module_paths")
 }
}

// Write the .list files to disk.
func dumpListToFile(ctx Context, config Config, list []string, filePath string) (err error) {
 desiredText := strings.Join(list, "\n")
 desiredBytes := []byte(desiredText)
 actualBytes, readErr := ioutil.ReadFile(filePath)
 if readErr != nil || !bytes.Equal(desiredBytes, actualBytes) {
  err = ioutil.WriteFile(filePath, desiredBytes, 0777)
  if err != nil {
   return err
  }
 }

 distFile(ctx, config, filePath, "soong_ui/module_paths")

 return nil
}

func ignoreNonAndroidMetadataFiles(metadataFiles []string) []string {
 result := make([]string, 0, len(metadataFiles))
 for _, file := range metadataFiles {
  // Ignore files like prebuilts/clang/host/linux-x86/clang-r536225/python3/lib/python3.11/site-packages/pip-23.1.2.dist-info/METADATA
  // these METADATA files are from upstream and are not the METADATA files used in Android codebase.
  if strings.Contains(file, "prebuilts/clang/host/") && strings.Contains(file, "/site-packages/") {
   continue
  }
  result = append(result, file)
 }
 return result
}

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