aboutsummaryrefslogtreecommitdiffstats
path: root/soong_ui.bash
diff options
context:
space:
mode:
authorDan Willemsen <dwillemsen@google.com>2016-09-18 20:27:41 -0700
committerDan Willemsen <dwillemsen@google.com>2017-02-06 14:05:07 -0800
commit0043c0e767499838f27e19f2b3872b49e6b54b8c (patch)
tree05e878074a195464f479c0028f19198621b14ea9 /soong_ui.bash
parent1e704462510e225716fbb8c5758fdd698bf7edb6 (diff)
downloadbuild_soong-0043c0e767499838f27e19f2b3872b49e6b54b8c.tar.gz
build_soong-0043c0e767499838f27e19f2b3872b49e6b54b8c.tar.bz2
build_soong-0043c0e767499838f27e19f2b3872b49e6b54b8c.zip
Add microfactory to bootstrap a go program with minimal overhead
microfactory is a tool to incrementally compile a go program. It's similar to `go install`, but doesn't require a GOPATH. A package->path mapping can be specified as command line options. All input files are hashed, and if any change, the necessary packages will be rebuilt. microfactory can (re)build itself as necessary, so combined with a shell script that runs `go run microfactory.go` the first time, it can bootstrap a go program entirely from sources with just a working goroot. Time to build soong_ui only using source & GOROOT: first time no-change incremental microfactory 1400ms 15ms go install 670ms 130ms While microfactory takes longer the first time, almost half of that time is from `go run` and building microfactory for use later. If microfactory only has to build soong_ui, it's about 580ms. Test: USE_SOONG_UI=true m -j blueprint_tools Test: go test -bench . build/soong/cmd/microfactory/microfactory_test.go Change-Id: I4d2b9825788144fa10042bbd804482e44f459a54
Diffstat (limited to 'soong_ui.bash')
-rwxr-xr-xsoong_ui.bash101
1 files changed, 101 insertions, 0 deletions
diff --git a/soong_ui.bash b/soong_ui.bash
new file mode 100755
index 00000000..724d9c54
--- /dev/null
+++ b/soong_ui.bash
@@ -0,0 +1,101 @@
+#!/bin/bash -eu
+#
+# 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.
+
+# To track how long we took to startup. %N isn't supported on Darwin, but
+# that's detected in the Go code, and skip calculating the startup time.
+export TRACE_BEGIN_SOONG=$(date +%s%N)
+
+# Function to find top of the source tree (if $TOP isn't set) by walking up the
+# tree.
+function gettop
+{
+ local TOPFILE=build/soong/root.bp
+ if [ -z "${TOP-}" -a -f "${TOP-}/${TOPFILE}" ] ; then
+ # The following circumlocution ensures we remove symlinks from TOP.
+ (cd $TOP; PWD= /bin/pwd)
+ else
+ if [ -f $TOPFILE ] ; then
+ # The following circumlocution (repeated below as well) ensures
+ # that we record the true directory name and not one that is
+ # faked up with symlink names.
+ PWD= /bin/pwd
+ else
+ local HERE=$PWD
+ T=
+ while [ \( ! \( -f $TOPFILE \) \) -a \( $PWD != "/" \) ]; do
+ \cd ..
+ T=`PWD= /bin/pwd -P`
+ done
+ \cd $HERE
+ if [ -f "$T/$TOPFILE" ]; then
+ echo $T
+ fi
+ fi
+ fi
+}
+
+# Bootstrap microfactory from source if necessary and use it to build the
+# soong_ui binary, then run soong_ui.
+function run_go
+{
+ # Increment when microfactory changes enough that it cannot rebuild itself.
+ # For example, if we use a new command line argument that doesn't work on older versions.
+ local mf_version=1
+
+ local mf_src="${TOP}/build/soong/cmd/microfactory"
+
+ local out_dir="${OUT_DIR:-${TOP}/out}"
+ local mf_bin="${out_dir}/microfactory_$(uname)"
+ local mf_version_file="${out_dir}/.microfactory_$(uname)_version"
+ local soong_ui_bin="${out_dir}/soong_ui"
+ local from_src=1
+
+ if [ -f "${mf_bin}" ] && [ -f "${mf_version_file}" ]; then
+ if [ "${mf_version}" -eq "$(cat "${mf_version_file}")" ]; then
+ from_src=0
+ fi
+ fi
+
+ local mf_cmd
+ if [ $from_src -eq 1 ]; then
+ mf_cmd="${GOROOT}/bin/go run ${mf_src}/microfactory.go"
+ else
+ mf_cmd="${mf_bin}"
+ fi
+
+ ${mf_cmd} -s "${mf_src}" -b "${mf_bin}" \
+ -pkg-path "android/soong=${TOP}/build/soong" -trimpath "${TOP}/build/soong" \
+ -o "${soong_ui_bin}" android/soong/cmd/soong_ui
+
+ if [ $from_src -eq 1 ]; then
+ echo "${mf_version}" >"${mf_version_file}"
+ fi
+
+ exec "${out_dir}/soong_ui" "$@"
+}
+
+export TOP=$(gettop)
+case $(uname) in
+ Linux)
+ export GOROOT="${TOP}/prebuilts/go/linux-x86/"
+ ;;
+ Darwin)
+ export GOROOT="${TOP}/prebuilts/go/darwin-x86/"
+ ;;
+ *) echo "unknown OS:" $(uname) >&2 && exit 1;;
+esac
+
+run_go "$@"