platform_build_blueprint/bootstrap.bash
Dan Willemsen 7d0dddd84d Simplify bootstrap
tl;dr: Read if you don't use the wrapper or use SKIP_NINJA

Previously, we were relying on the ninja behavior of restarting the
build when the build.ninja file was updated to switch between different
bootstrap stages. But that means that every step that could produce a
build.ninja must pass in order to switch to a different stage. That
wasn't a big problem when we had a two stage build -- there was very
little that could fail in the second stage before we chose to go back to
the first stage. But when we had a three stage build, it was possible to
get into a state (usually during development) where you were in the
second stage, but the build was failing because the first stage needed
to be run. This was fixed in d79f1af742
by adding a wrapper that always started building at the first stage.

But this kept all of the complexity of using ninja restarts without any
of the benefits, so this change removes that complexity and just runs
each stage sequentially in the wrapper. So the wrapper is now required.

Since we're no longer going through choosestage, we can also skip the
template parsing for the later stages that don't need to be templated --
this can save a couple of seconds for large files.

In addition to all of the above, this also lets Soong reduce the number
of times the main ninja file is loaded. We had been running the wrapper
once (3 stages), then running ninja again after combining the
Soong-generated build.ninja with the Kati-generated build.ninja. This
change lets us removing the intermediate parsing of Soong's build.ninja,
so that we only execute ninja 3 times per build. It also lets us have
dependencies on pools or rules from Kati in the primary builder, since
we're never executing the main build.ninja without the Kati build.ninja.

The wrapper has a new option, NINJA to provide the path to ninja. This
used to be hardcoded to `ninja`, and will still default to that. But
we'll be running the first two bootstrap stages with $NINJA even if
SKIP_NINJA is set.

The wrapper passes "-w dupbuild=err" to ninja now -- this really should
always be turned on if you care about reliable builds.

Change-Id: I6f656b74eb3d064b8b9e69d1d6dac1129d72b747
2016-08-30 17:26:56 -07:00

145 lines
4.8 KiB
Bash
Executable file

#!/bin/bash
# This script serves two purposes. First, it can bootstrap the standalone
# Blueprint to generate the minibp binary. To do this simply run the script
# with no arguments from the desired build directory.
#
# It can also be invoked from another script to bootstrap a custom Blueprint-
# based build system. To do this, the invoking script must first set some or
# all of the following environment variables, which are documented below where
# their default values are set:
#
# BOOTSTRAP
# WRAPPER
# SRCDIR
# BUILDDIR
# BOOTSTRAP_MANIFEST
# GOROOT
# GOOS
# GOARCH
# GOCHAR
#
# The invoking script should then run this script, passing along all of its
# command line arguments.
set -e
EXTRA_ARGS=""
# BOOTSTRAP should be set to the path of the bootstrap script. It can be
# either an absolute path or one relative to the build directory (which of
# these is used should probably match what's used for SRCDIR).
if [ -z "$BOOTSTRAP" ]; then
BOOTSTRAP="${BASH_SOURCE[0]}"
# WRAPPER should only be set if you want a ninja wrapper script to be
# installed into the builddir. It is set to blueprint's blueprint.bash
# only if BOOTSTRAP and WRAPPER are unset.
[ -z "$WRAPPER" ] && WRAPPER="`dirname "${BOOTSTRAP}"`/blueprint.bash"
fi
# SRCDIR should be set to the path of the root source directory. It can be
# either an absolute path or a path relative to the build directory. Whether
# its an absolute or relative path determines whether the build directory can
# be moved relative to or along with the source directory without re-running
# the bootstrap script.
[ -z "$SRCDIR" ] && SRCDIR=`dirname "${BOOTSTRAP}"`
# BUILDDIR should be set to the path to store build results. By default, this
# is the current directory, but it may be set to an absolute or relative path.
[ -z "$BUILDDIR" ] && BUILDDIR=.
# TOPNAME should be set to the name of the top-level Blueprints file
[ -z "$TOPNAME" ] && TOPNAME="Blueprints"
# BOOTSTRAP_MANIFEST is the path to the bootstrap Ninja file that is part of
# the source tree. It is used to bootstrap a build output directory from when
# the script is run manually by a user.
[ -z "$BOOTSTRAP_MANIFEST" ] && BOOTSTRAP_MANIFEST="${SRCDIR}/build.ninja.in"
# These variables should be set by auto-detecting or knowing a priori the host
# Go toolchain properties.
[ -z "$GOROOT" ] && GOROOT=`go env GOROOT`
[ -z "$GOOS" ] && GOOS=`go env GOHOSTOS`
[ -z "$GOARCH" ] && GOARCH=`go env GOHOSTARCH`
[ -z "$GOCHAR" ] && GOCHAR=`go env GOCHAR`
# If RUN_TESTS is set, behave like -t was passed in as an option.
[ ! -z "$RUN_TESTS" ] && EXTRA_ARGS="$EXTRA_ARGS -t"
GOTOOLDIR="$GOROOT/pkg/tool/${GOOS}_$GOARCH"
GOCOMPILE="$GOTOOLDIR/${GOCHAR}g"
GOLINK="$GOTOOLDIR/${GOCHAR}l"
if [ ! -f $GOCOMPILE ]; then
GOCOMPILE="$GOTOOLDIR/compile"
fi
if [ ! -f $GOLINK ]; then
GOLINK="$GOTOOLDIR/link"
fi
if [[ ! -f $GOCOMPILE || ! -f $GOLINK ]]; then
echo "Cannot find go tools under $GOROOT"
exit 1
fi
usage() {
echo "Usage of ${BOOTSTRAP}:"
echo " -h: print a help message and exit"
echo " -r: regenerate ${BOOTSTRAP_MANIFEST}"
echo " -t: include tests when regenerating manifest"
}
# Parse the command line flags.
IN="$BOOTSTRAP_MANIFEST"
REGEN_BOOTSTRAP_MANIFEST=false
while getopts ":b:hi:rt" opt; do
case $opt in
b) BUILDDIR="$OPTARG";;
h)
usage
exit 1
;;
i) IN="$OPTARG";;
r) REGEN_BOOTSTRAP_MANIFEST=true;;
t) EXTRA_ARGS="$EXTRA_ARGS -t";;
\?)
echo "Invalid option: -$OPTARG" >&2
usage
exit 1
;;
:)
echo "Option -$OPTARG requires an argument." >&2
exit 1
;;
esac
done
if [ $REGEN_BOOTSTRAP_MANIFEST = true ]; then
# This assumes that the script is being run from a build output directory
# that has been built in the past.
if [ -x $BUILDDIR/.bootstrap/bin/minibp ]; then
echo "Regenerating $BOOTSTRAP_MANIFEST"
$BUILDDIR/.bootstrap/bin/minibp $EXTRA_ARGS -o $BOOTSTRAP_MANIFEST $SRCDIR/$TOPNAME
else
echo "Executable minibp not found at $BUILDDIR/.bootstrap/bin/minibp" >&2
exit 1
fi
fi
mkdir -p $BUILDDIR/.minibootstrap
sed -e "s|@@SrcDir@@|$SRCDIR|g" \
-e "s|@@BuildDir@@|$BUILDDIR|g" \
-e "s|@@GoRoot@@|$GOROOT|g" \
-e "s|@@GoCompile@@|$GOCOMPILE|g" \
-e "s|@@GoLink@@|$GOLINK|g" \
-e "s|@@Bootstrap@@|$BOOTSTRAP|g" \
-e "s|@@BootstrapManifest@@|$BOOTSTRAP_MANIFEST|g" \
$IN > $BUILDDIR/.minibootstrap/build.ninja
echo "BOOTSTRAP=\"${BOOTSTRAP}\"" > $BUILDDIR/.blueprint.bootstrap
echo "BOOTSTRAP_MANIFEST=\"${BOOTSTRAP_MANIFEST}\"" >> $BUILDDIR/.blueprint.bootstrap
if [ ! -z "$WRAPPER" ]; then
cp $WRAPPER $BUILDDIR/
fi