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
This commit is contained in:
@@ -1,61 +1,9 @@
|
|||||||
#!/bin/bash
|
#!/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" "$@"
|
|
||||||
|
@@ -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]))
|
|
@@ -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()
|
|
52
soong.bash
52
soong.bash
@@ -1,48 +1,8 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
set -e
|
echo '==== ERROR: bootstrap.bash & ./soong are obsolete ====' >&2
|
||||||
|
echo 'Use `m --skip-make` with a standalone OUT_DIR instead.' >&2
|
||||||
# Switch to the build directory
|
echo 'Without envsetup.sh, use:' >&2
|
||||||
cd $(dirname "${BASH_SOURCE[0]}")
|
echo ' build/soong/soong_ui.bash --make-mode --skip-make' >&2
|
||||||
|
echo '======================================================' >&2
|
||||||
if [ -z "$NO_DEPRECATION_WARNING" ]; then
|
exit 1
|
||||||
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 "$@"
|
|
||||||
|
@@ -20,6 +20,7 @@ bootstrap_go_package {
|
|||||||
"soong-ui-tracer",
|
"soong-ui-tracer",
|
||||||
"soong-shared",
|
"soong-shared",
|
||||||
"soong-finder",
|
"soong-finder",
|
||||||
|
"blueprint-microfactory",
|
||||||
],
|
],
|
||||||
srcs: [
|
srcs: [
|
||||||
"build.go",
|
"build.go",
|
||||||
|
@@ -156,7 +156,6 @@ func Build(ctx Context, config Config, what int) {
|
|||||||
|
|
||||||
if what&BuildSoong != 0 {
|
if what&BuildSoong != 0 {
|
||||||
// Run Soong
|
// Run Soong
|
||||||
runSoongBootstrap(ctx, config)
|
|
||||||
runSoong(ctx, config)
|
runSoong(ctx, config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -15,37 +15,101 @@
|
|||||||
package build
|
package build
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/blueprint/microfactory"
|
||||||
)
|
)
|
||||||
|
|
||||||
func runSoongBootstrap(ctx Context, config Config) {
|
|
||||||
ctx.BeginTrace("bootstrap soong")
|
|
||||||
defer ctx.EndTrace()
|
|
||||||
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
func runSoong(ctx Context, config Config) {
|
func runSoong(ctx Context, config Config) {
|
||||||
ctx.BeginTrace("soong")
|
ctx.BeginTrace("soong")
|
||||||
defer ctx.EndTrace()
|
defer ctx.EndTrace()
|
||||||
|
|
||||||
cmd := Command(ctx, config, "soong",
|
func() {
|
||||||
filepath.Join(config.SoongOutDir(), "soong"), "-w", "dupbuild=err")
|
ctx.BeginTrace("blueprint bootstrap")
|
||||||
if config.IsVerbose() {
|
defer ctx.EndTrace()
|
||||||
cmd.Args = append(cmd.Args, "-v")
|
|
||||||
|
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")
|
ninja("minibootstrap", ".minibootstrap/build.ninja")
|
||||||
cmd.Sandbox = soongSandbox
|
ninja("bootstrap", ".bootstrap/build.ninja")
|
||||||
cmd.Stdin = ctx.Stdin()
|
|
||||||
cmd.Stdout = ctx.Stdout()
|
|
||||||
cmd.Stderr = ctx.Stderr()
|
|
||||||
cmd.RunOrFatal()
|
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user