aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLaMont Jones <lamontjones@google.com>2022-08-04 16:44:22 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2022-08-04 16:44:22 +0000
commitef1d2f06c6b7c793df1894e648dbc3d8d237b183 (patch)
tree5abc33b8dbae465007e409a2d7a52fdaba6ae6f3
parentffa1f0fff0ba22dcfa301e87416e002e96e5d65d (diff)
parentc39e50277490184ed290e092964a1bf515f66ee2 (diff)
downloadbuild-ef1d2f06c6b7c793df1894e648dbc3d8d237b183.tar.gz
Merge "orchestrator: inner-tree path can be a list."
-rw-r--r--envsetup.sh21
-rw-r--r--orchestrator/core/inner_tree.py65
-rwxr-xr-xorchestrator/core/lunch.py5
-rwxr-xr-xorchestrator/core/orchestrator.py8
-rw-r--r--orchestrator/core/utils.py2
-rw-r--r--orchestrator/multitree_combos/aosp_cf_arm64_phone.mcombo6
-rw-r--r--orchestrator/multitree_combos/test.mcombo6
7 files changed, 73 insertions, 40 deletions
diff --git a/envsetup.sh b/envsetup.sh
index 8856212004..ea28c2ea42 100644
--- a/envsetup.sh
+++ b/envsetup.sh
@@ -455,10 +455,19 @@ function multitree_lunch()
{
local code
local results
+ # Lunch must be run in the topdir, but this way we get a clear error
+ # message, instead of FileNotFound.
+ local T=$(multitree_gettop)
+ if [ -n "$T" ]; then
+ "$T/build/build/make/orchestrator/core/orchestrator.py" "$@"
+ else
+ _multitree_lunch_error
+ return 1
+ fi
if $(echo "$1" | grep -q '^-') ; then
# Calls starting with a -- argument are passed directly and the function
# returns with the lunch.py exit code.
- build/build/make/orchestrator/core/lunch.py "$@"
+ "${T}/build/build/make/orchestrator/core/lunch.py" "$@"
code=$?
if [[ $code -eq 2 ]] ; then
echo 1>&2
@@ -469,7 +478,7 @@ function multitree_lunch()
fi
else
# All other calls go through the --lunch variant of lunch.py
- results=($(build/build/make/orchestrator/core/lunch.py --lunch "$@"))
+ results=($(${T}/build/build/make/orchestrator/core/lunch.py --lunch "$@"))
code=$?
if [[ $code -eq 2 ]] ; then
echo 1>&2
@@ -1813,7 +1822,8 @@ function _wrap_build()
function _trigger_build()
(
local -r bc="$1"; shift
- if T="$(gettop)"; then
+ local T=$(gettop)
+ if [ -n "$T" ]; then
_wrap_build "$T/build/soong/soong_ui.bash" --build-mode --${bc} --dir="$(pwd)" "$@"
else
>&2 echo "Couldn't locate the top of the tree. Try setting TOP."
@@ -1873,8 +1883,9 @@ function _multitree_lunch_error()
function multitree_build()
{
- if T="$(multitree_gettop)"; then
- "$T/build/build/orchestrator/core/orchestrator.py" "$@"
+ local T=$(multitree_gettop)
+ if [ -n "$T" ]; then
+ "$T/build/build/make/orchestrator/core/orchestrator.py" "$@"
else
_multitree_lunch_error
return 1
diff --git a/orchestrator/core/inner_tree.py b/orchestrator/core/inner_tree.py
index d348ee7f98..dcfb3eb4af 100644
--- a/orchestrator/core/inner_tree.py
+++ b/orchestrator/core/inner_tree.py
@@ -14,11 +14,13 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import json
import os
import subprocess
import sys
import textwrap
+
class InnerTreeKey(object):
"""Trees are identified uniquely by their root and the TARGET_PRODUCT they will use to build.
If a single tree uses two different prdoucts, then we won't make assumptions about
@@ -26,21 +28,33 @@ class InnerTreeKey(object):
TODO: This is true for soong. It's more likely that bazel could do analysis for two
products at the same time in a single tree, so there's an optimization there to do
eventually."""
+
def __init__(self, root, product):
+ if isinstance(root, list):
+ self.melds = root[1:]
+ root = root[0]
+ else:
+ self.melds = []
self.root = root
self.product = product
def __str__(self):
- return "TreeKey(root=%s product=%s)" % (enquote(self.root), enquote(self.product))
+ return (f"TreeKey(root={enquote(self.root)} "
+ f"product={enquote(self.product)}")
def __hash__(self):
return hash((self.root, self.product))
def _cmp(self, other):
+ assert isinstance(other, InnerTreeKey)
if self.root < other.root:
return -1
if self.root > other.root:
return 1
+ if self.melds < other.melds:
+ return -1
+ if self.melds > other.melds:
+ return 1
if self.product == other.product:
return 0
if self.product is None:
@@ -71,13 +85,16 @@ class InnerTreeKey(object):
class InnerTree(object):
- def __init__(self, context, root, product):
+ def __init__(self, context, paths, product):
"""Initialize with the inner tree root (relative to the workspace root)"""
- self.root = root
+ if not isinstance(paths, list):
+ paths = [paths]
+ self.root = paths[0]
+ self.meld_dirs = paths[1:]
self.product = product
self.domains = {}
# TODO: Base directory on OUT_DIR
- out_root = context.out.inner_tree_dir(root)
+ out_root = context.out.inner_tree_dir(self.root)
if product:
out_root += "_" + product
else:
@@ -85,9 +102,10 @@ class InnerTree(object):
self.out = OutDirLayout(out_root)
def __str__(self):
- return "InnerTree(root=%s product=%s domains=[%s])" % (enquote(self.root),
- enquote(self.product),
- " ".join([enquote(d) for d in sorted(self.domains.keys())]))
+ return (f"InnerTree(root={enquote(self.root)} "
+ f"product={enquote(self.product)} "
+ f"domains={enquote(list(self.domains.keys()))} "
+ f"meld={enquote(self.meld_dirs)})")
def invoke(self, args):
"""Call the inner tree command for this inner tree. Exits on failure."""
@@ -97,8 +115,9 @@ class InnerTree(object):
# so we can print a good error message
inner_build_tool = os.path.join(self.root, ".inner_build")
if not os.access(inner_build_tool, os.X_OK):
- sys.stderr.write(("Unable to execute %s. Is there an inner tree or lunch combo"
- + " misconfiguration?\n") % inner_build_tool)
+ sys.stderr.write(
+ f"Unable to execute {inner_build_tool}. Is there an inner tree "
+ "or lunch combo misconfiguration?\n")
sys.exit(1)
# TODO: This is where we should set up the shared trees
@@ -115,8 +134,9 @@ class InnerTree(object):
# TODO: Probably want better handling of inner tree failures
if process.returncode:
- sys.stderr.write("Build error in inner tree: %s\nstopping multitree build.\n"
- % self.root)
+ sys.stderr.write(
+ f"Build error in inner tree: {self.root}\nstopping "
+ "multitree build.\n")
sys.exit(1)
@@ -127,19 +147,19 @@ class InnerTrees(object):
def __str__(self):
"Return a debugging dump of this object"
- return textwrap.dedent("""\
- InnerTrees {
+
+ def _vals(values):
+ return ("\n" + " " * 16).join(sorted([str(t) for t in values]))
+
+ return textwrap.dedent(f"""\
+ InnerTrees {{
trees: [
- %(trees)s
+ {_vals(self.trees.values())}
]
domains: [
- %(domains)s
+ {_vals(self.domains.values())}
]
- }""" % {
- "trees": "\n ".join(sorted([str(t) for t in self.trees.values()])),
- "domains": "\n ".join(sorted([str(d) for d in self.domains.values()])),
- })
-
+ }}""")
def for_each_tree(self, func, cookie=None):
"""Call func for each of the inner trees once for each product that will be built in it.
@@ -153,7 +173,6 @@ class InnerTrees(object):
result[key] = func(key, self.trees[key], cookie)
return result
-
def get(self, tree_key):
"""Get an inner tree for tree_key"""
return self.trees.get(tree_key)
@@ -188,6 +207,4 @@ class OutDirLayout(object):
def enquote(s):
- return "None" if s is None else "\"%s\"" % s
-
-
+ return json.dumps(s)
diff --git a/orchestrator/core/lunch.py b/orchestrator/core/lunch.py
index 70a2d1d411..71ae45bb27 100755
--- a/orchestrator/core/lunch.py
+++ b/orchestrator/core/lunch.py
@@ -240,9 +240,12 @@ def make_config_header(config_file, config, variant):
trees = [("Component", "Path", "Product"),
("---------", "----", "-------")]
entry = config.get("system", None)
+
def add_config_tuple(trees, entry, name):
if entry:
- trees.append((name, entry.get("tree"), entry.get("product", "")))
+ trees.append(
+ (name, entry.get("inner-tree"), entry.get("product", "")))
+
add_config_tuple(trees, config.get("system"), "system")
add_config_tuple(trees, config.get("vendor"), "vendor")
for k, v in config.get("modules", {}).items():
diff --git a/orchestrator/core/orchestrator.py b/orchestrator/core/orchestrator.py
index 508f73aabb..256850fd8d 100755
--- a/orchestrator/core/orchestrator.py
+++ b/orchestrator/core/orchestrator.py
@@ -55,14 +55,16 @@ def process_config(context, lunch_config):
system_entry = lunch_config.get("system")
if system_entry:
- add(API_DOMAIN_SYSTEM, system_entry["tree"], system_entry["product"])
+ add(API_DOMAIN_SYSTEM, system_entry["inner-tree"],
+ system_entry["product"])
vendor_entry = lunch_config.get("vendor")
if vendor_entry:
- add(API_DOMAIN_VENDOR, vendor_entry["tree"], vendor_entry["product"])
+ add(API_DOMAIN_VENDOR, vendor_entry["inner-tree"],
+ vendor_entry["product"])
for module_name, module_entry in lunch_config.get("modules", []).items():
- add(module_name, module_entry["tree"], None)
+ add(module_name, module_entry["inner-tree"], None)
return inner_tree.InnerTrees(trees, domains)
diff --git a/orchestrator/core/utils.py b/orchestrator/core/utils.py
index 41310e0156..2ce40a6789 100644
--- a/orchestrator/core/utils.py
+++ b/orchestrator/core/utils.py
@@ -28,7 +28,7 @@ class TestContext(Context):
"Context for testing. The real Context is manually constructed in orchestrator.py."
def __init__(self, test_work_dir, test_name):
- super(MockContext, self).__init__(os.path.join(test_work_dir, test_name),
+ super(TestContext, self).__init__(os.path.join(test_work_dir, test_name),
Errors(None))
diff --git a/orchestrator/multitree_combos/aosp_cf_arm64_phone.mcombo b/orchestrator/multitree_combos/aosp_cf_arm64_phone.mcombo
index 079022611d..62fe778172 100644
--- a/orchestrator/multitree_combos/aosp_cf_arm64_phone.mcombo
+++ b/orchestrator/multitree_combos/aosp_cf_arm64_phone.mcombo
@@ -1,16 +1,16 @@
{
"lunchable": true,
"system": {
- "tree": "master",
+ "inner-tree": "aosp-master-with-phones",
"product": "aosp_cf_arm64_phone"
},
"vendor": {
- "tree": "master",
+ "inner-tree": "aosp-master-with-phones",
"product": "aosp_cf_arm64_phone"
},
"modules": {
"com.android.bionic": {
- "tree": "sc-mainline-prod"
+ "inner-tree": "aosp-master-with-phones"
}
}
}
diff --git a/orchestrator/multitree_combos/test.mcombo b/orchestrator/multitree_combos/test.mcombo
index 3ad0717577..d601b7d2ca 100644
--- a/orchestrator/multitree_combos/test.mcombo
+++ b/orchestrator/multitree_combos/test.mcombo
@@ -1,16 +1,16 @@
{
"lunchable": true,
"system": {
- "tree": "inner_tree_system",
+ "inner-tree": "inner_tree_system",
"product": "system_lunch_product"
},
"vendor": {
- "tree": "inner_tree_vendor",
+ "inner-tree": "inner_tree_vendor",
"product": "vendor_lunch_product"
},
"modules": {
"com.android.something": {
- "tree": "inner_tree_module"
+ "inner-tree": ["inner_tree_module", "sc-common"]
}
}
}