소스 검색

Obsolete bootstrap.bash and ./soong wrappers

We can call directly into the blueprint bootstrap.bash using values that
soong_ui has already calculated.

Instead of calling into blueprint.bash, build minibp with microfactory,
and directly run ninja. This allows us to get individual tracing data
from each component.

Test: m -j blueprint_tools
Test: m clean; m -j blueprint_tools
Change-Id: I2239943c9a8a3ad6e1a40fa0dc914421f4b5202c
Dan Willemsen 6 년 전
부모
커밋
99a75cd2a5
7개의 변경된 파일102개의 추가작업 그리고 217개의 파일을 삭제
  1. 6 58
      bootstrap.bash
  2. 0 40
      scripts/reverse_path.py
  3. 0 47
      scripts/reverse_path_test.py
  4. 6 46
      soong.bash
  5. 1 0
      ui/build/Android.bp
  6. 0 1
      ui/build/build.go
  7. 89 25
      ui/build/soong.go

+ 6 - 58
bootstrap.bash

@@ -1,61 +1,9 @@
 #!/bin/bash
 
-set -e
+echo '==== ERROR: bootstrap.bash & ./soong are obsolete ====' >&2
+echo 'Use `m --skip-make` with a standalone OUT_DIR instead.' >&2
+echo 'Without envsetup.sh, use:' >&2
+echo '  build/soong/soong_ui.bash --make-mode --skip-make' >&2
+echo '======================================================' >&2
+exit 1
 
-if [ -z "$NO_DEPRECATION_WARNING" ]; then
-    echo '== WARNING: bootstrap.bash & ./soong are deprecated ==' >&2
-    echo 'Use `m --skip-make` with a standalone OUT_DIR instead.' >&2
-    echo 'Without envsetup.sh, use:' >&2
-    echo '  build/soong/soong_ui.bash --make-mode --skip-make' >&2
-    echo '======================================================' >&2
-fi
-
-ORIG_SRCDIR=$(dirname "${BASH_SOURCE[0]}")
-if [[ "$ORIG_SRCDIR" != "." ]]; then
-  if [[ ! -z "$BUILDDIR" ]]; then
-    echo "error: To use BUILDDIR, run from the source directory"
-    exit 1
-  fi
-  export BUILDDIR=$("${ORIG_SRCDIR}/build/soong/scripts/reverse_path.py" "$ORIG_SRCDIR")
-  cd $ORIG_SRCDIR
-fi
-if [[ -z "$BUILDDIR" ]]; then
-  echo "error: Run ${BASH_SOURCE[0]} from the build output directory"
-  exit 1
-fi
-export SRCDIR="."
-export BOOTSTRAP="${SRCDIR}/bootstrap.bash"
-export BLUEPRINTDIR="${SRCDIR}/build/blueprint"
-
-export TOPNAME="Android.bp"
-export RUN_TESTS="-t"
-
-case $(uname) in
-    Linux)
-	export PREBUILTOS="linux-x86"
-	;;
-    Darwin)
-	export PREBUILTOS="darwin-x86"
-	;;
-    *) echo "unknown OS:" $(uname) && exit 1;;
-esac
-export GOROOT="${SRCDIR}/prebuilts/go/$PREBUILTOS"
-
-if [[ $# -eq 0 ]]; then
-    mkdir -p $BUILDDIR
-
-    if [[ $(find $BUILDDIR -maxdepth 1 -name Android.bp) ]]; then
-      echo "FAILED: The build directory must not be a source directory"
-      exit 1
-    fi
-
-    export SRCDIR_FROM_BUILDDIR=$(build/soong/scripts/reverse_path.py "$BUILDDIR")
-
-    sed -e "s|@@BuildDir@@|${BUILDDIR}|" \
-        -e "s|@@SrcDirFromBuildDir@@|${SRCDIR_FROM_BUILDDIR}|" \
-        -e "s|@@PrebuiltOS@@|${PREBUILTOS}|" \
-        "$SRCDIR/build/soong/soong.bootstrap.in" > $BUILDDIR/.soong.bootstrap
-    ln -sf "${SRCDIR_FROM_BUILDDIR}/build/soong/soong.bash" $BUILDDIR/soong
-fi
-
-"$SRCDIR/build/blueprint/bootstrap.bash" "$@"

+ 0 - 40
scripts/reverse_path.py

@@ -1,40 +0,0 @@
-#!/usr/bin/env python
-
-from __future__ import print_function
-
-import os
-import sys
-
-# Find the best reverse path to reference the current directory from another
-# directory. We use this to find relative paths to and from the source and build
-# directories.
-#
-# If the directory is given as an absolute path, return an absolute path to the
-# current directory.
-#
-# If there's a symlink involved, and the same relative path would not work if
-# the symlink was replace with a regular directory, then return an absolute
-# path. This handles paths like out -> /mnt/ssd/out
-#
-# For symlinks that can use the same relative path (out -> out.1), just return
-# the relative path. That way out.1 can be renamed as long as the symlink is
-# updated.
-#
-# For everything else, just return the relative path. That allows the source and
-# output directories to be moved as long as they stay in the same position
-# relative to each other.
-def reverse_path(path):
-    if path.startswith("/"):
-        return os.path.abspath('.')
-
-    realpath = os.path.relpath(os.path.realpath('.'), os.path.realpath(path))
-    relpath = os.path.relpath('.', path)
-
-    if realpath != relpath:
-        return os.path.abspath('.')
-
-    return relpath
-
-
-if __name__ == '__main__':
-    print(reverse_path(sys.argv[1]))

+ 0 - 47
scripts/reverse_path_test.py

@@ -1,47 +0,0 @@
-#!/usr/bin/env python
-
-from __future__ import print_function
-
-import os
-import shutil
-import tempfile
-import unittest
-
-from reverse_path import reverse_path
-
-class TestReversePath(unittest.TestCase):
-    def setUp(self):
-        self.tmpdir = tempfile.mkdtemp()
-        os.chdir(self.tmpdir)
-
-    def tearDown(self):
-        shutil.rmtree(self.tmpdir)
-
-    def test_absolute(self):
-        self.assertEqual(self.tmpdir, reverse_path('/out'))
-
-    def test_relative(self):
-        os.mkdir('a')
-        os.mkdir('b')
-
-        self.assertEqual('..', reverse_path('a'))
-
-        os.chdir('a')
-        self.assertEqual('a', reverse_path('..'))
-        self.assertEqual('.', reverse_path('../a'))
-        self.assertEqual('../a', reverse_path('../b'))
-
-    def test_symlink(self):
-        os.mkdir('b')
-        os.symlink('b', 'a')
-        os.mkdir('b/d')
-        os.symlink('b/d', 'c')
-
-        self.assertEqual('..', reverse_path('a'))
-        self.assertEqual('..', reverse_path('b'))
-        self.assertEqual(self.tmpdir, reverse_path('c'))
-        self.assertEqual('../..', reverse_path('b/d'))
-
-
-if __name__ == '__main__':
-    unittest.main()

+ 6 - 46
soong.bash

@@ -1,48 +1,8 @@
 #!/bin/bash
 
-set -e
-
-# Switch to the build directory
-cd $(dirname "${BASH_SOURCE[0]}")
-
-if [ -z "$NO_DEPRECATION_WARNING" ]; then
-    echo '== WARNING: bootstrap.bash & ./soong are deprecated ==' >&2
-    echo 'Use `m --skip-make` with a standalone OUT_DIR instead.' >&2
-    echo 'Without envsetup.sh, use:' >&2
-    echo '  build/soong/soong_ui.bash --make-mode --skip-make' >&2
-    echo '======================================================' >&2
-fi
-
-# The source directory path and operating system will get written to
-# .soong.bootstrap by the bootstrap script.
-
-BOOTSTRAP=".soong.bootstrap"
-if [ ! -f "${BOOTSTRAP}" ]; then
-    echo "Error: soong script must be located in a directory created by bootstrap.bash"
-    exit 1
-fi
-
-source "${BOOTSTRAP}"
-
-# Now switch to the source directory so that all the relative paths from
-# $BOOTSTRAP are correct
-cd ${SRCDIR_FROM_BUILDDIR}
-
-# Ninja can't depend on environment variables, so do a manual comparison
-# of the relevant environment variables from the last build using the
-# soong_env tool and trigger a build manifest regeneration if necessary
-ENVFILE="${BUILDDIR}/.soong.environment"
-ENVTOOL="${BUILDDIR}/.bootstrap/bin/soong_env"
-if [ -f "${ENVFILE}" ]; then
-    if [ -x "${ENVTOOL}" ]; then
-        if ! "${ENVTOOL}" "${ENVFILE}"; then
-            echo "forcing build manifest regeneration"
-            rm -f "${ENVFILE}"
-        fi
-    else
-        echo "Missing soong_env tool, forcing build manifest regeneration"
-        rm -f "${ENVFILE}"
-    fi
-fi
-
-BUILDDIR="${BUILDDIR}" NINJA="prebuilts/build-tools/${PREBUILTOS}/bin/ninja" build/blueprint/blueprint.bash "$@"
+echo '==== ERROR: bootstrap.bash & ./soong are obsolete ====' >&2
+echo 'Use `m --skip-make` with a standalone OUT_DIR instead.' >&2
+echo 'Without envsetup.sh, use:' >&2
+echo '  build/soong/soong_ui.bash --make-mode --skip-make' >&2
+echo '======================================================' >&2
+exit 1

+ 1 - 0
ui/build/Android.bp

@@ -20,6 +20,7 @@ bootstrap_go_package {
         "soong-ui-tracer",
         "soong-shared",
         "soong-finder",
+        "blueprint-microfactory",
     ],
     srcs: [
         "build.go",

+ 0 - 1
ui/build/build.go

@@ -156,7 +156,6 @@ func Build(ctx Context, config Config, what int) {
 
 	if what&BuildSoong != 0 {
 		// Run Soong
-		runSoongBootstrap(ctx, config)
 		runSoong(ctx, config)
 	}
 

+ 89 - 25
ui/build/soong.go

@@ -15,37 +15,101 @@
 package build
 
 import (
+	"os"
 	"path/filepath"
-)
-
-func runSoongBootstrap(ctx Context, config Config) {
-	ctx.BeginTrace("bootstrap soong")
-	defer ctx.EndTrace()
+	"strconv"
+	"time"
 
-	cmd := Command(ctx, config, "soong bootstrap", "./bootstrap.bash")
-	cmd.Environment.Set("BUILDDIR", config.SoongOutDir())
-	cmd.Environment.Set("NINJA_BUILDDIR", config.OutDir())
-	cmd.Environment.Set("NO_DEPRECATION_WARNING", "true")
-	cmd.Sandbox = soongSandbox
-	cmd.Stdout = ctx.Stdout()
-	cmd.Stderr = ctx.Stderr()
-	cmd.RunOrFatal()
-}
+	"github.com/google/blueprint/microfactory"
+)
 
 func runSoong(ctx Context, config Config) {
 	ctx.BeginTrace("soong")
 	defer ctx.EndTrace()
 
-	cmd := Command(ctx, config, "soong",
-		filepath.Join(config.SoongOutDir(), "soong"), "-w", "dupbuild=err")
-	if config.IsVerbose() {
-		cmd.Args = append(cmd.Args, "-v")
+	func() {
+		ctx.BeginTrace("blueprint bootstrap")
+		defer ctx.EndTrace()
+
+		cmd := Command(ctx, config, "blueprint bootstrap", "build/blueprint/bootstrap.bash", "-t")
+		cmd.Environment.Set("BLUEPRINTDIR", "./build/blueprint")
+		cmd.Environment.Set("BOOTSTRAP", "./build/blueprint/bootstrap.bash")
+		cmd.Environment.Set("BUILDDIR", config.SoongOutDir())
+		cmd.Environment.Set("GOROOT", filepath.Join("./prebuilts/go", config.HostPrebuiltTag()))
+		cmd.Environment.Set("NINJA_BUILDDIR", config.OutDir())
+		cmd.Environment.Set("SRCDIR", ".")
+		cmd.Environment.Set("TOPNAME", "Android.bp")
+		cmd.Sandbox = soongSandbox
+		cmd.Stdout = ctx.Stdout()
+		cmd.Stderr = ctx.Stderr()
+		cmd.RunOrFatal()
+	}()
+
+	func() {
+		ctx.BeginTrace("environment check")
+		defer ctx.EndTrace()
+
+		envFile := filepath.Join(config.SoongOutDir(), ".soong.environment")
+		envTool := filepath.Join(config.SoongOutDir(), ".bootstrap/bin/soong_env")
+		if _, err := os.Stat(envFile); err == nil {
+			if _, err := os.Stat(envTool); err == nil {
+				cmd := Command(ctx, config, "soong_env", envTool, envFile)
+				cmd.Sandbox = soongSandbox
+				cmd.Stdout = ctx.Stdout()
+				cmd.Stderr = ctx.Stderr()
+				if err := cmd.Run(); err != nil {
+					ctx.Verboseln("soong_env failed, forcing manifest regeneration")
+					os.Remove(envFile)
+				}
+			} else {
+				ctx.Verboseln("Missing soong_env tool, forcing manifest regeneration")
+				os.Remove(envFile)
+			}
+		} else if !os.IsNotExist(err) {
+			ctx.Fatalf("Failed to stat %f: %v", envFile, err)
+		}
+	}()
+
+	func() {
+		ctx.BeginTrace("minibp")
+		defer ctx.EndTrace()
+
+		var cfg microfactory.Config
+		cfg.Map("github.com/google/blueprint", "build/blueprint")
+
+		if absPath, err := filepath.Abs("."); err == nil {
+			cfg.TrimPath = absPath
+		}
+
+		minibp := filepath.Join(config.SoongOutDir(), ".minibootstrap/minibp")
+		if _, err := microfactory.Build(&cfg, minibp, "github.com/google/blueprint/bootstrap/minibp"); err != nil {
+			ctx.Fatalln("Failed to build minibp:", err)
+		}
+	}()
+
+	ninja := func(name, file string) {
+		ctx.BeginTrace(name)
+		defer ctx.EndTrace()
+
+		cmd := Command(ctx, config, "soong "+name,
+			config.PrebuiltBuildTool("ninja"),
+			"-d", "keepdepfile",
+			"-w", "dupbuild=err",
+			"-j", strconv.Itoa(config.Parallel()),
+			"-f", filepath.Join(config.SoongOutDir(), file))
+		if config.IsVerbose() {
+			cmd.Args = append(cmd.Args, "-v")
+		}
+		cmd.Environment.Set("GOROOT", filepath.Join("./prebuilts/go", config.HostPrebuiltTag()))
+		cmd.Sandbox = soongSandbox
+		cmd.Stdin = ctx.Stdin()
+		cmd.Stdout = ctx.Stdout()
+		cmd.Stderr = ctx.Stderr()
+
+		defer ctx.ImportNinjaLog(filepath.Join(config.OutDir(), ".ninja_log"), time.Now())
+		cmd.RunOrFatal()
 	}
-	cmd.Environment.Set("SKIP_NINJA", "true")
-	cmd.Environment.Set("NO_DEPRECATION_WARNING", "true")
-	cmd.Sandbox = soongSandbox
-	cmd.Stdin = ctx.Stdin()
-	cmd.Stdout = ctx.Stdout()
-	cmd.Stderr = ctx.Stderr()
-	cmd.RunOrFatal()
+
+	ninja("minibootstrap", ".minibootstrap/build.ninja")
+	ninja("bootstrap", ".bootstrap/build.ninja")
 }