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

Quelle  bootstrap_test.sh

  Sprache: Shell
 

#!/bin/bash -eu

set -o pipefail

# This test exercises the bootstrapping process of the build system
# in a source tree that only contains enough files for Bazel and Soong to work.

source "$(dirname "$0")/lib.sh"

readonly GENERATED_BUILD_FILE_NAME="BUILD.bazel"

readonly target_product=test_arm64

function test_smoke {
  setup
  run_soong
}

function test_null_build() {
  setup
  run_soong
  local -r bootstrap_mtime1=$(stat -c "%y" out/soong/bootstrap.ninja)
  local -r output_mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)
  run_soong
  local -r bootstrap_mtime2=$(stat -c "%y" out/soong/bootstrap.ninja)
  local -r output_mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)

  if [[ "$bootstrap_mtime1" == "$bootstrap_mtime2" ]]; then
    # Bootstrapping is always done. It doesn't take a measurable amount of time.
    fail "Bootstrap Ninja file did not change on null build"
  fi

  if [[ "$output_mtime1" != "$output_mtime2" ]]; then
    fail "Output Ninja file changed on null build"
  fi
}

function test_soong_build_rebuilt_if_blueprint_changes() {
  setup
  run_soong
  local -r mtime1=$(stat -c "%y" out/soong/bootstrap.ninja)

  sed -i 's/pluginGenSrcCmd/pluginGenSrcCmd2/g' build/blueprint/bootstrap/bootstrap.go

  run_soong
  local -r mtime2=$(stat -c "%y" out/soong/bootstrap.ninja)

  if [[ "$mtime1" == "$mtime2" ]]; then
    fail "Bootstrap Ninja file did not change"
  fi
}

function test_change_android_bp() {
  setup
  mkdir -p a
  cat > a/Android.bp <<'EOF'
python_binary_host {
  name: "my_little_binary_host",
  srcs: ["my_little_binary_host.py"]
}
EOF
  touch a/my_little_binary_host.py
  run_soong

  grep -q "^# Module:.*my_little_binary_host" out/soong/build."${target_product}".*ninja || fail "module not found"

  cat > a/Android.bp <<'EOF'
python_binary_host {
  name: "my_great_binary_host",
  srcs: ["my_great_binary_host.py"]
}
EOF
  touch a/my_great_binary_host.py
  run_soong

  grep -q "^# Module:.*my_little_binary_host" out/soong/build."${target_product}".*ninja && fail "old module found"
  grep -q "^# Module:.*my_great_binary_host" out/soong/build."${target_product}".*ninja || fail "new module not found"
}

function test_add_android_bp() {
  setup
  run_soong
  local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)

  mkdir -p a
  cat > a/Android.bp <<'EOF'
python_binary_host {
  name: "my_little_binary_host",
  srcs: ["my_little_binary_host.py"]
}
EOF
  touch a/my_little_binary_host.py
  run_soong

  local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
  if [[ "$mtime1" == "$mtime2" ]]; then
    fail "Output Ninja file did not change"
  fi

  grep -q "^# Module:.*my_little_binary_host$" out/soong/build."${target_product}".*ninja || fail "New module not in output"

  run_soong
}

function test_delete_android_bp() {
  setup
  mkdir -p a
  cat > a/Android.bp <<'EOF'
python_binary_host {
  name: "my_little_binary_host",
  srcs: ["my_little_binary_host.py"]
}
EOF
  touch a/my_little_binary_host.py
  run_soong

  grep -q "^# Module:.*my_little_binary_host$" out/soong/build."${target_product}".*ninja || fail "Module not in output"

  rm a/Android.bp
  run_soong

  if grep -q "^# Module:.*my_little_binary_host$" out/soong/build."${target_product}".*ninja; then
    fail "Old module in output"
  fi
}

# Test that an incremental build with a glob doesn't rerun soong_build, and
# only regenerates the globs on the first but not the second incremental build.
function test_glob_noop_incremental() {
  setup

  # This test needs to start from a clean build, but setup creates an
  # initialized tree that has already been built once.  Clear the out
  # directory to start from scratch (see b/185591972)
  rm -rf out

  mkdir -p a
  cat > a/Android.bp <<'EOF'
python_binary_host {
  name: "my_little_binary_host",
  srcs: ["*.py"],
}
EOF
  touch a/my_little_binary_host.py
  run_soong
  local -r ninja_mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)

  run_soong
  local -r ninja_mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)

  if [[ "$ninja_mtime1" != "$ninja_mtime2" ]]; then
    fail "Ninja file rewritten on null incremental build"
  fi

  run_soong
  local -r ninja_mtime3=$(stat -c "%y" out/soong/build."${target_product}".ninja)

  if [[ "$ninja_mtime2" != "$ninja_mtime3" ]]; then
    fail "Ninja file rewritten on null incremental build"
  fi
}

function test_add_file_to_glob() {
  setup

  mkdir -p a
  cat > a/Android.bp <<'EOF'
python_binary_host {
  name: "my_little_binary_host",
  srcs: ["*.py"],
}
EOF
  touch a/my_little_binary_host.py
  run_soong
  local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)

  touch a/my_little_library.py
  run_soong

  local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
  if [[ "$mtime1" == "$mtime2" ]]; then
    fail "Output Ninja file did not change"
  fi

  grep -q my_little_library.py out/soong/build."${target_product}".*ninja || fail "new file is not in output"
}

function test_soong_build_rerun_iff_environment_changes() {
  setup

  mkdir -p build/soong/cherry
  cat > build/soong/cherry/Android.bp <<'EOF'
bootstrap_go_package {
  name: "cherry",
  pkgPath: "android/soong/cherry",
  deps: [
    "blueprint",
    "soong",
    "soong-android",
  ],
  srcs: [
    "cherry.go",
  ],
  pluginFor: ["soong_build"],
}
EOF

  cat > build/soong/cherry/cherry.go <<'EOF'
package cherry

import (
  "android/soong/android"
  "github.com/google/blueprint"
)

var (
  pctx = android.NewPackageContext("cherry")
)

func init() {
  android.RegisterSingletonType("cherry", CherrySingleton)
}

func CherrySingleton() android.Singleton {
  return &cherrySingleton{}
}

type cherrySingleton struct{}

func (p *cherrySingleton) GenerateBuildActions(ctx android.SingletonContext) {
  cherryRule := ctx.Rule(pctx, "cherry",
    blueprint.RuleParams{
      Command: "echo CHERRY IS " + ctx.Config().Getenv("CHERRY") + " > ${out}",
      CommandDeps: []string{},
      Description: "Cherry",
    })

  outputFile := android.PathForOutput(ctx, "cherry""cherry.txt")
  var deps android.Paths

  ctx.Build(pctx, android.BuildParams{
    Rule: cherryRule,
    Output: outputFile,
    Inputs: deps,
  })
}
EOF

  export CHERRY=TASTY
  run_soong
  grep -q "CHERRY IS TASTY" out/soong/build."${target_product}".ninja \
    || fail "first value of environment variable is not used"

  export CHERRY=RED
  run_soong
  grep -q "CHERRY IS RED" out/soong/build."${target_product}".ninja \
    || fail "second value of environment variable not used"
  local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)

  run_soong
  local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
  if [[ "$mtime1" != "$mtime2" ]]; then
    fail "Output Ninja file changed when environment variable did not"
  fi

}

function test_create_global_include_directory() {
  setup
  run_soong
  local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)

  # Soong needs to know if top level directories like hardware/ exist for use
  # as global include directories.  Make sure that doesn't cause regens for
  # unrelated changes to the top level directory.
  mkdir -p system/core

  run_soong
  local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
  if [[ "$mtime1" != "$mtime2" ]]; then
    fail "Output Ninja file changed when top level directory changed"
  fi

  # Make sure it does regen if a missing directory in the path of a global
  # include directory is added.
  mkdir -p system/core/include

  run_soong
  local -r mtime3=$(stat -c "%y" out/soong/build."${target_product}".ninja)
  if [[ "$mtime2" = "$mtime3" ]]; then
    # TODO(b/422558779): test fails
    # fail "Output Ninja file did not change when global include directory created"
    true
  fi

}

function test_add_file_to_soong_build() {
  setup
  run_soong
  local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)

  mkdir -p vendor/foo/picard
  cat > vendor/foo/picard/Android.bp <<'EOF'
bootstrap_go_package {
  name: "picard-soong-rules",
  pkgPath: "android/soong/picard",
  deps: [
    "blueprint",
    "soong",
    "soong-android",
  ],
  srcs: [
    "picard.go",
  ],
  pluginFor: ["soong_build"],
}
EOF

  cat > vendor/foo/picard/picard.go <<'EOF'
package picard

import (
  "android/soong/android"
  "github.com/google/blueprint"
)

var (
  pctx = android.NewPackageContext("picard")
)

func init() {
  android.RegisterSingletonType("picard", PicardSingleton)
}

func PicardSingleton() android.Singleton {
  return &picardSingleton{}
}

type picardSingleton struct{}

func (p *picardSingleton) GenerateBuildActions(ctx android.SingletonContext) {
  picardRule := ctx.Rule(pctx, "picard",
    blueprint.RuleParams{
      Command: "echo Make it so. > ${out}",
      CommandDeps: []string{},
      Description: "Something quotable",
    })

  outputFile := android.PathForOutput(ctx, "picard""picard.txt")
  var deps android.Paths

  ctx.Build(pctx, android.BuildParams{
    Rule: picardRule,
    Output: outputFile,
    Inputs: deps,
  })
}

EOF

  run_soong
  local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
  if [[ "$mtime1" == "$mtime2" ]]; then
    fail "Output Ninja file did not change"
  fi

  grep -q "Make it so" out/soong/build."${target_product}".*ninja || fail "New action not present"
}

# Tests a glob in a build= statement in an Android.bp file, which is interpreted
# during bootstrapping.
function test_glob_during_bootstrapping() {
  setup

  mkdir -p build/soong/picard
  cat > build/soong/picard/Android.bp <<'EOF'
build=["foo*.bp"]
EOF
  cat > build/soong/picard/fooa.bp <<'EOF'
bootstrap_go_package {
  name: "picard-soong-rules",
  pkgPath: "android/soong/picard",
  deps: [
    "blueprint",
    "soong",
    "soong-android",
  ],
  srcs: [
    "picard.go",
  ],
  pluginFor: ["soong_build"],
}
EOF

  cat > build/soong/picard/picard.go <<'EOF'
package picard

import (
  "android/soong/android"
  "github.com/google/blueprint"
)

var (
  pctx = android.NewPackageContext("picard")
)

func init() {
  android.RegisterSingletonType("picard", PicardSingleton)
}

func PicardSingleton() android.Singleton {
  return &picardSingleton{}
}

type picardSingleton struct{}

var Message = "Make it so."

func (p *picardSingleton) GenerateBuildActions(ctx android.SingletonContext) {
  picardRule := ctx.Rule(pctx, "picard",
    blueprint.RuleParams{
      Command: "echo " + Message + " > ${out}",
      CommandDeps: []string{},
      Description: "Something quotable",
    })

  outputFile := android.PathForOutput(ctx, "picard""picard.txt")
  var deps android.Paths

  ctx.Build(pctx, android.BuildParams{
    Rule: picardRule,
    Output: outputFile,
    Inputs: deps,
  })
}

EOF

  run_soong
  local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)

  grep -q "Make it so" out/soong/build."${target_product}".ninja || fail "Original action not present"

  cat > build/soong/picard/foob.bp <<'EOF'
bootstrap_go_package {
  name: "worf-soong-rules",
  pkgPath: "android/soong/worf",
  deps: [
    "blueprint",
    "soong",
    "soong-android",
    "picard-soong-rules",
  ],
  srcs: [
    "worf.go",
  ],
  pluginFor: ["soong_build"],
}
EOF

  cat > build/soong/picard/worf.go <<'EOF'
package worf

import "android/soong/picard"

func init() {
   picard.Message = "Engage."
}
EOF

  run_soong
  local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)
  if [[ "$mtime1" == "$mtime2" ]]; then
    fail "Output Ninja file did not change"
  fi

  grep -q "Engage" out/soong/build."${target_product}".*ninja || fail "New action not present"

  if grep -q "Make it so" out/soong/build."${target_product}".*ninja; then
    fail "Original action still present"
  fi
}

function test_soong_docs_smoke() {
  setup

  run_soong soong_docs

  [[ -e "out/soong/docs/soong_build.html" ]] || fail "Documentation for main page not created"
  [[ -e "out/soong/docs/cc.html" ]] || fail "Documentation for C++ modules not created"
}

function test_null_build_after_soong_docs() {
  setup

  run_soong
  local -r ninja_mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)

  run_soong soong_docs
  local -r docs_mtime1=$(stat -c "%y" out/soong/docs/soong_build.html)

  run_soong soong_docs
  local -r docs_mtime2=$(stat -c "%y" out/soong/docs/soong_build.html)

  if [[ "$docs_mtime1" != "$docs_mtime2" ]]; then
    fail "Output Ninja file changed on null build"
  fi

  run_soong
  local -r ninja_mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)

  if [[ "$ninja_mtime1" != "$ninja_mtime2" ]]; then
    fail "Output Ninja file changed on null build"
  fi
}

function test_write_to_source_tree {
  setup
  mkdir -p a
  cat > a/Android.bp <<EOF
genrule {
  name: "write_to_source_tree",
  out: ["write_to_source_tree"],
  cmd: "touch file_in_source_tree && touch \$(out)",
}
EOF
  readonly EXPECTED_OUT=out/soong/.intermediates/a/write_to_source_tree/gen/write_to_source_tree
  readonly ERROR_LOG=${MOCK_TOP}/out/error.log
  readonly ERROR_MSG="Read-only file system"
  readonly ERROR_HINT_PATTERN="BUILD_BROKEN_SRC_DIR"
  # Test in ReadOnly source tree
  run_ninja BUILD_BROKEN_SRC_DIR_IS_WRITABLE=false ${EXPECTED_OUT} &> /dev/null && \
    # TODO(b/422558875): genrules are sandboxed, so they won't write to the source tree
    # fail "Write to source tree should not work in a ReadOnly source tree"
    true

  if grep -q "${ERROR_MSG}" "${ERROR_LOG}" && grep -q "${ERROR_HINT_PATTERN}" "${ERROR_LOG}" ; then
    echo Error message and error hint found in logs >/dev/null
  else
    # TODO(b/422558875): genrules are sandboxed, so they won't write to the source tree
    # fail "Did not find Read-only error AND error hint in error.log"
    true
  fi

  # Test in ReadWrite source tree
  run_ninja BUILD_BROKEN_SRC_DIR_IS_WRITABLE=true ${EXPECTED_OUT} &> /dev/null || \
    fail "Write to source tree did not succeed in a ReadWrite source tree"

  if  grep -q "${ERROR_MSG}\|${ERROR_HINT_PATTERN}" "${ERROR_LOG}" ; then
    fail "Found read-only error OR error hint in error.log"
  fi
}

# This test verifies that adding a new glob to a blueprint file only
# causes build."${target_product}".ninja to be regenerated on the *next* build, and *not*
# the build after. (This is a regression test for a bug where globs
# resulted in two successive regenerations.)
function test_new_glob_incrementality {
  setup

  run_soong nothing
  local -r mtime1=$(stat -c "%y" out/soong/build."${target_product}".ninja)

  mkdir -p globdefpkg/
  cat > globdefpkg/Android.bp <<'EOF'
filegroup {
  name: "fg_with_glob",
  srcs: ["*.txt"],
}
EOF

  run_soong nothing
  local -r mtime2=$(stat -c "%y" out/soong/build."${target_product}".ninja)

  if [[ "$mtime1" == "$mtime2" ]]; then
    fail "Ninja file was not regenerated, despite a new bp file"
  fi

  run_soong nothing
  local -r mtime3=$(stat -c "%y" out/soong/build."${target_product}".ninja)

  if [[ "$mtime2" != "$mtime3" ]]; then
    fail "Ninja file was regenerated despite no previous bp changes"
  fi
}

scan_and_run_tests "$@"

Messung V0.5 in Prozent
C=95 H=100 G=97

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet am  2026-06-28) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.