aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bazel.WORKSPACE2
-rw-r--r--common.bazelrc1
-rw-r--r--platforms/platform_mappings3
-rw-r--r--rules/android/aar_import.bzl2
-rw-r--r--rules/android/aar_import_aosp_internal/BUILD.bazel (renamed from rules/java/rules_java/BUILD)0
-rw-r--r--rules/android/aar_import_aosp_internal/attrs.bzl40
-rw-r--r--rules/android/aar_import_aosp_internal/rule.bzl33
-rw-r--r--rules/apex/apex.bzl78
-rw-r--r--rules/apex/apex_test.bzl49
-rw-r--r--rules/apex/cc.bzl1
-rw-r--r--rules/cc/cc_library_common.bzl19
-rw-r--r--rules/cc/cc_prebuilt_library_shared.bzl45
-rw-r--r--rules/cc/cc_prebuilt_library_shared_test.bzl83
-rw-r--r--rules/cc/cc_prebuilt_library_static.bzl49
-rw-r--r--rules/cc/cc_prebuilt_library_static_test.bzl150
-rw-r--r--rules/java/rules_java/WORKSPACE0
-rw-r--r--rules/java/rules_java/java/BUILD7
-rw-r--r--rules/java/rules_java/java/defs.bzl29
-rwxr-xr-xscripts/incremental_build/canonical_perf.sh4
-rw-r--r--scripts/incremental_build/cuj_catalog.py210
-rw-r--r--scripts/incremental_build/incremental_build.py10
-rw-r--r--scripts/incremental_build/perf_metrics.py11
-rw-r--r--scripts/incremental_build/perf_metrics_test.py5
-rw-r--r--scripts/incremental_build/util_test.py4
24 files changed, 585 insertions, 250 deletions
diff --git a/bazel.WORKSPACE b/bazel.WORKSPACE
index d0fe5d7b..dc96892f 100644
--- a/bazel.WORKSPACE
+++ b/bazel.WORKSPACE
@@ -131,7 +131,7 @@ local_repository(
# it can be properly vendored.
local_repository(
name = "rules_java",
- path = "build/bazel/rules/java/rules_java",
+ path = "build/bazel_common_rules/rules/java/rules_java",
)
register_toolchains(
diff --git a/common.bazelrc b/common.bazelrc
index 70371f5b..cef887af 100644
--- a/common.bazelrc
+++ b/common.bazelrc
@@ -3,7 +3,6 @@
# thrashing the output directory when switching between top level target
# --platforms values.
build --experimental_platform_in_output_dir
-build --platform_mappings=build/bazel/platforms/platform_mappings
# Use toolchain resolution to find the cc toolchain.
build --incompatible_enable_cc_toolchain_resolution
diff --git a/platforms/platform_mappings b/platforms/platform_mappings
deleted file mode 100644
index 4db0aeb2..00000000
--- a/platforms/platform_mappings
+++ /dev/null
@@ -1,3 +0,0 @@
-flags:
- --cpu=k8
- @soong_injection//product_config_platforms:current_android_platform
diff --git a/rules/android/aar_import.bzl b/rules/android/aar_import.bzl
index e93a821f..76abef03 100644
--- a/rules/android/aar_import.bzl
+++ b/rules/android/aar_import.bzl
@@ -14,7 +14,7 @@
"""Macro wrapping the aar_import for bp2build. """
-load("@rules_android//rules:rules.bzl", _aar_import = "aar_import")
+load("//build/bazel/rules/android/aar_import_aosp_internal:rule.bzl", _aar_import = "aar_import")
load("//build/bazel/rules/java:sdk_transition.bzl", "sdk_transition", "sdk_transition_attrs")
# TODO(b/277801336): document these attributes.
diff --git a/rules/java/rules_java/BUILD b/rules/android/aar_import_aosp_internal/BUILD.bazel
index e69de29b..e69de29b 100644
--- a/rules/java/rules_java/BUILD
+++ b/rules/android/aar_import_aosp_internal/BUILD.bazel
diff --git a/rules/android/aar_import_aosp_internal/attrs.bzl b/rules/android/aar_import_aosp_internal/attrs.bzl
new file mode 100644
index 00000000..1b685b3f
--- /dev/null
+++ b/rules/android/aar_import_aosp_internal/attrs.bzl
@@ -0,0 +1,40 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# 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.
+
+load(
+ "@rules_android//rules:attrs.bzl",
+ _attrs = "attrs",
+)
+load(
+ "@rules_android//rules/aar_import:attrs.bzl",
+ _BASE_ATTRS = "ATTRS",
+)
+
+ATTRS = _attrs.replace(
+ _BASE_ATTRS,
+ exports = attr.label_list(
+ allow_files = False,
+ allow_rules = [
+ "aar_import",
+ "java_import",
+ "kt_jvm_import",
+ "aar_import_sdk_transition",
+ "java_import_sdk_transition",
+ "kt_jvm_import_sdk_transition",
+ ],
+ doc = "The closure of all rules reached via `exports` attributes are considered " +
+ "direct dependencies of any rule that directly depends on the target with " +
+ "`exports`. The `exports` are not direct deps of the rule they belong to.",
+ ),
+)
diff --git a/rules/android/aar_import_aosp_internal/rule.bzl b/rules/android/aar_import_aosp_internal/rule.bzl
new file mode 100644
index 00000000..79580f2a
--- /dev/null
+++ b/rules/android/aar_import_aosp_internal/rule.bzl
@@ -0,0 +1,33 @@
+# Copyright (C) 2023 The Android Open Source Project
+#
+# 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.
+
+"""aar_import rule."""
+
+load(":attrs.bzl", _ATTRS = "ATTRS")
+load("@rules_android//rules/aar_import:impl.bzl", _impl = "impl")
+load("@rules_android//rules/aar_import:rule.bzl", "RULE_DOC")
+
+aar_import = rule(
+ attrs = _ATTRS,
+ fragments = ["android"],
+ implementation = _impl,
+ doc = RULE_DOC,
+ provides = [
+ AndroidIdeInfo,
+ AndroidLibraryResourceClassJarProvider,
+ AndroidNativeLibsInfo,
+ JavaInfo,
+ ],
+ toolchains = ["@rules_android//toolchains/android:toolchain_type"],
+)
diff --git a/rules/apex/apex.bzl b/rules/apex/apex.bzl
index cc679cea..c31b6404 100644
--- a/rules/apex/apex.bzl
+++ b/rules/apex/apex.bzl
@@ -423,51 +423,52 @@ def _run_apexer(ctx, apex_toolchain):
apexer_files = apex_toolchain.apexer[DefaultInfo].files_to_run
# Arguments
- args = ctx.actions.args()
- args.add(file_mapping_file.path)
+ command = [ctx.executable._staging_dir_builder.path, file_mapping_file.path]
# NOTE: When used as inputs to another sandboxed action, this directory
# artifact's inner files will be made up of symlinks. Ensure that the
# aforementioned action handles symlinks correctly (e.g. following
# symlinks).
staging_dir = ctx.actions.declare_directory(ctx.attr.name + "_staging_dir")
- args.add(staging_dir.path)
+
+ command.append(staging_dir.path)
# start of apexer cmd
- args.add(apexer_files.executable.path)
+ command.append(apexer_files.executable.path)
if ctx.attr._apexer_verbose[BuildSettingInfo].value:
- args.add("--verbose")
- args.add("--force")
- args.add("--include_build_info")
- args.add_all(["--canned_fs_config", canned_fs_config.path])
- args.add_all(["--manifest", apex_manifest_pb.path])
- args.add_all(["--file_contexts", file_contexts.path])
- args.add_all(["--key", privkey.path])
- args.add_all(["--pubkey", pubkey.path])
- args.add_all(["--payload_type", "image"])
- args.add_all(["--payload_fs_type", "ext4"])
- args.add_all(["--assets_dir", notices_file.dirname])
+ command.append("--verbose")
+
+ command.append("--force")
+ command.append("--include_build_info")
+ command.extend(["--canned_fs_config", canned_fs_config.path])
+ command.extend(["--manifest", apex_manifest_pb.path])
+ command.extend(["--file_contexts", file_contexts.path])
+ command.extend(["--key", privkey.path])
+ command.extend(["--pubkey", pubkey.path])
+ command.extend(["--payload_type", "image"])
+ command.extend(["--payload_fs_type", "ext4"])
+ command.extend(["--assets_dir", notices_file.dirname])
# Override the package name, if it's expicitly specified
if ctx.attr.package_name:
- args.add_all(["--override_apk_package_name", ctx.attr.package_name])
+ command.extend(["--override_apk_package_name", ctx.attr.package_name])
else:
override_package_name = _override_manifest_package_name(ctx)
if override_package_name:
- args.add_all(["--override_apk_package_name", override_package_name])
+ command.extend(["--override_apk_package_name", override_package_name])
if ctx.attr.logging_parent:
- args.add_all(["--logging_parent", ctx.attr.logging_parent])
+ command.extend(["--logging_parent", ctx.attr.logging_parent])
use_api_fingerprint = _use_api_fingerprint(ctx)
- target_sdk_version = api.final_or_future(api.default_app_target_sdk())
+ target_sdk_version = str(api.final_or_future(api.default_app_target_sdk()))
if use_api_fingerprint:
api_fingerprint_file = ctx.file._api_fingerprint_txt
- sdk_version_suffix = ".$$(cat {})".format(api_fingerprint_file.path)
+ sdk_version_suffix = ".$(cat {})".format(api_fingerprint_file.path)
target_sdk_version = ctx.attr._platform_sdk_codename[BuildSettingInfo].value + sdk_version_suffix
- args.add(api_fingerprint_file.path)
- args.add_all(["--target_sdk_version", target_sdk_version])
+
+ command.extend(["--target_sdk_version", target_sdk_version])
# TODO(b/215339575): This is a super rudimentary way to convert "current" to a numerical number.
# Generalize this to API level handling logic in a separate Starlark utility, preferably using
@@ -477,12 +478,12 @@ def _run_apexer(ctx, apex_toolchain):
min_sdk_version = "10000"
override_min_sdk_version = ctx.attr._apex_global_min_sdk_version_override[BuildSettingInfo].value
- min_sdk_version = maybe_override_min_sdk_version(min_sdk_version, override_min_sdk_version)
+ min_sdk_version = str(maybe_override_min_sdk_version(min_sdk_version, override_min_sdk_version))
if min_sdk_version == "10000" and use_api_fingerprint:
min_sdk_version = ctx.attr._platform_sdk_codename[BuildSettingInfo].value + sdk_version_suffix
- args.add(api_fingerprint_file.path)
- args.add_all(["--min_sdk_version", min_sdk_version])
+ command.append(api_fingerprint_file.path)
+ command.extend(["--min_sdk_version", min_sdk_version])
# apexer needs the list of directories containing all auxilliary tools invoked during
# the creation of an apex
@@ -491,6 +492,7 @@ def _run_apexer(ctx, apex_toolchain):
mke2fs_files = apex_toolchain.mke2fs[DefaultInfo].files_to_run
resize2fs_files = apex_toolchain.resize2fs[DefaultInfo].files_to_run
sefcontext_compile_files = apex_toolchain.sefcontext_compile[DefaultInfo].files_to_run
+ staging_dir_builder_files = ctx.attr._staging_dir_builder[DefaultInfo].files_to_run
apexer_tool_paths = [
apex_toolchain.aapt2.dirname,
apexer_files.executable.dirname,
@@ -501,20 +503,21 @@ def _run_apexer(ctx, apex_toolchain):
sefcontext_compile_files.executable.dirname,
]
- args.add_all(["--apexer_tool_path", ":".join(apexer_tool_paths)])
+ command.extend(["--apexer_tool_path", ":".join(apexer_tool_paths)])
android_manifest = ctx.file.android_manifest
if android_manifest != None:
if ctx.attr.testonly:
android_manifest = _mark_manifest_as_test_only(ctx, apex_toolchain)
- args.add_all(["--android_manifest", android_manifest.path])
+ command.extend(["--android_manifest", android_manifest.path])
elif ctx.attr.testonly:
- args.add("--test_only")
+ command.append("--test_only")
- args.add(staging_dir.path)
- args.add(apex_output_file)
+ command.append(staging_dir.path)
+ command.append(apex_output_file.path)
inputs = [
+ ctx.executable._staging_dir_builder,
file_mapping_file,
canned_fs_config,
apex_manifest_pb,
@@ -538,17 +541,22 @@ def _run_apexer(ctx, apex_toolchain):
resize2fs_files,
sefcontext_compile_files,
apex_toolchain.aapt2,
+ staging_dir_builder_files,
]
- ctx.actions.run(
+ # This is run_shell instead of run because --target_sdk_version may
+ # use the API fingerprinting file contents using bash expansion,
+ # and only run_shell can support that by executing the whole command with
+ # /bin/bash -c. Regular run would quote the --target_sdk_version value with
+ # single quotes ('--target_sdk_version=ABC.$(cat version.txt)'), preventing
+ # bash expansion.
+ ctx.actions.run_shell(
inputs = inputs,
tools = tools,
outputs = [apex_output_file, staging_dir],
- executable = ctx.executable._staging_dir_builder,
- arguments = [args],
+ command = " ".join(command),
mnemonic = "Apexer",
)
-
return struct(
unsigned_apex = apex_output_file,
requires_native_libs = requires_native_libs,
@@ -871,7 +879,7 @@ file mode, and cap is hexadecimal value for the capability.""",
doc = """The minimum SDK version that this APEX must support at minimum. This is usually set to
the SDK version that the APEX was first introduced.
-When not set, defaults to 10000 (or "current").""",
+When not set, defaults to "10000" (or "current").""",
),
"updatable": attr.bool(default = True, doc = """Whether this APEX is considered updatable or not.
diff --git a/rules/apex/apex_test.bzl b/rules/apex/apex_test.bzl
index f714a599..51ba3d07 100644
--- a/rules/apex/apex_test.bzl
+++ b/rules/apex/apex_test.bzl
@@ -455,8 +455,9 @@ def _apex_manifest_test(ctx):
conv_apex_manifest_action = [a for a in actions if a.mnemonic == "ConvApexManifest"][0]
apexer_action = [a for a in actions if a.mnemonic == "Apexer"][0]
- manifest_index = apexer_action.argv.index("--manifest")
- manifest_path = apexer_action.argv[manifest_index + 1]
+ argv = apexer_action.argv[:-1] + apexer_action.argv[-1].split(" ")
+ manifest_index = argv.index("--manifest")
+ manifest_path = argv[manifest_index + 1]
asserts.equals(
env,
@@ -471,8 +472,8 @@ def _apex_manifest_test(ctx):
)
if ctx.attr.expected_min_sdk_version != "":
- flag_index = apexer_action.argv.index("--min_sdk_version")
- min_sdk_version_argv = apexer_action.argv[flag_index + 1]
+ flag_index = argv.index("--min_sdk_version")
+ min_sdk_version_argv = argv[flag_index + 1]
asserts.equals(
env,
ctx.attr.expected_min_sdk_version,
@@ -492,9 +493,17 @@ apex_manifest_test = analysistest.make(
**apex_manifest_test_attr
)
+apex_manifest_global_min_sdk_current_test = analysistest.make(
+ config_settings = {
+ "@//build/bazel/rules/apex:unbundled_build_target_sdk_with_api_fingerprint": False,
+ },
+ **apex_manifest_test_attr
+)
+
apex_manifest_global_min_sdk_override_tiramisu_test = analysistest.make(
config_settings = {
"@//build/bazel/rules/apex:apex_global_min_sdk_version_override": "Tiramisu",
+ "@//build/bazel/rules/apex:unbundled_build_target_sdk_with_api_fingerprint": False,
},
**apex_manifest_test_attr
)
@@ -538,7 +547,8 @@ def _test_apex_manifest_min_sdk_version_current():
min_sdk_version = "current",
)
- apex_manifest_test(
+ # this test verifies min_sdk_version without use_api_fingerprint
+ apex_manifest_global_min_sdk_current_test(
name = test_name,
target_under_test = name,
expected_min_sdk_version = "10000",
@@ -555,6 +565,7 @@ def _test_apex_manifest_min_sdk_version_override():
min_sdk_version = "30",
)
+ # this test verifies min_sdk_version without use_api_fingerprint
apex_manifest_global_min_sdk_override_tiramisu_test(
name = test_name,
target_under_test = name,
@@ -999,13 +1010,14 @@ def _action_args_test(ctx):
actions = analysistest.target_actions(env)
action = [a for a in actions if a.mnemonic == ctx.attr.action_mnemonic][0]
- flag_idx = action.argv.index(ctx.attr.expected_args[0])
+ argv = action.argv[:-1] + action.argv[-1].split(" ")
+ flag_idx = argv.index(ctx.attr.expected_args[0])
for i, expected_arg in enumerate(ctx.attr.expected_args):
asserts.equals(
env,
expected_arg,
- action.argv[flag_idx + i],
+ argv[flag_idx + i],
)
return analysistest.end(env)
@@ -1630,7 +1642,7 @@ def _apex_testonly_without_manifest_test_impl(ctx):
len(actions) == 1,
"No apexer action found: %s" % actions,
)
- argv = actions[0].argv
+ argv = actions[0].argv[:-1] + actions[0].argv[-1].split(" ")
asserts.true(
env,
@@ -2572,8 +2584,11 @@ def _min_target_sdk_version_api_fingerprint_test(ctx):
for action in actions:
if action.argv == None:
continue
- if "--min_sdk_version" in action.argv:
- apexer_action = action
+ for a in action.argv:
+ if "--min_sdk_version" in a:
+ apexer_action = action
+ break
+ if apexer_action != None:
break
asserts.true(
@@ -2582,7 +2597,7 @@ def _min_target_sdk_version_api_fingerprint_test(ctx):
"There is no apexer action in all the actions",
)
- argv = apexer_action.argv
+ argv = apexer_action.argv[:-1] + apexer_action.argv[-1].split(" ")
api_fingerprint_in_input = False
api_fingerprint_path = None
for f in apexer_action.inputs.to_list():
@@ -2597,21 +2612,25 @@ def _min_target_sdk_version_api_fingerprint_test(ctx):
"api_fingerprint.txt is not in the input files",
)
- expected_target_sdk_version = "123" + ".$$(cat {})".format(api_fingerprint_path)
+ expected_target_sdk_version = "123" + ".$(cat {})".format(api_fingerprint_path)
+ target_sdk_version_index = argv.index("--target_sdk_version")
asserts.equals(
env,
expected = expected_target_sdk_version,
- actual = argv[argv.index("--target_sdk_version") + 1],
+ actual = argv[target_sdk_version_index + 1] + " " + argv[target_sdk_version_index + 2],
)
+ min_sdk_version_index = argv.index("--min_sdk_version")
if ctx.attr.min_sdk_version in ["current", "10000"]:
- expected_min_sdk_version = "123" + ".$$(cat {})".format(api_fingerprint_path)
+ expected_min_sdk_version = "123" + ".$(cat {})".format(api_fingerprint_path)
+ actual_min_sdk_version = argv[min_sdk_version_index + 1] + " " + argv[min_sdk_version_index + 2]
else:
expected_min_sdk_version = ctx.attr.min_sdk_version
+ actual_min_sdk_version = argv[min_sdk_version_index + 1]
asserts.equals(
env,
expected = expected_min_sdk_version,
- actual = argv[argv.index("--min_sdk_version") + 1],
+ actual = actual_min_sdk_version,
)
return analysistest.end(env)
diff --git a/rules/apex/cc.bzl b/rules/apex/cc.bzl
index 98f9b7b5..1bb14871 100644
--- a/rules/apex/cc.bzl
+++ b/rules/apex/cc.bzl
@@ -54,6 +54,7 @@ def _installed_to_bootstrap(label):
# bionic libs
if label in [
"@//bionic/libc:libc",
+ "@//bionic/libc:libc_hwasan", # For completeness, but no one should be depending on this.
"@//bionic/libm:libm",
"@//bionic/libdl:libdl",
"@//bionic/libdl_android:libdl_android",
diff --git a/rules/cc/cc_library_common.bzl b/rules/cc/cc_library_common.bzl
index bd861c50..afd5d978 100644
--- a/rules/cc/cc_library_common.bzl
+++ b/rules/cc/cc_library_common.bzl
@@ -402,3 +402,22 @@ def create_cc_androidmk_provider(*, static_deps, whole_archive_deps, dynamic_dep
local_whole_static_libs = local_whole_static_libs,
local_shared_libs = local_shared_libs,
)
+
+def create_cc_prebuilt_library_info(ctx, lib_to_link):
+ "Create the CcInfo for a prebuilt_library_{shared,static}"
+
+ compilation_context = cc_common.create_compilation_context(
+ includes = depset(get_includes_paths(ctx, ctx.attr.export_includes)),
+ system_includes = depset(get_includes_paths(ctx, ctx.attr.export_system_includes)),
+ )
+ linker_input = cc_common.create_linker_input(
+ owner = ctx.label,
+ libraries = depset(direct = [lib_to_link] if lib_to_link != None else []),
+ )
+ linking_context = cc_common.create_linking_context(
+ linker_inputs = depset(direct = [linker_input]),
+ )
+ return CcInfo(
+ compilation_context = compilation_context,
+ linking_context = linking_context,
+ )
diff --git a/rules/cc/cc_prebuilt_library_shared.bzl b/rules/cc/cc_prebuilt_library_shared.bzl
index d713a928..25144f86 100644
--- a/rules/cc/cc_prebuilt_library_shared.bzl
+++ b/rules/cc/cc_prebuilt_library_shared.bzl
@@ -12,16 +12,39 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-def cc_prebuilt_library_shared(
- name,
- shared_library,
- alwayslink = None,
- **kwargs):
- "Bazel macro to correspond with the *_cc_prebuilt_library_shared Soong module types"
+load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
+load(":cc_library_common.bzl", "create_cc_prebuilt_library_info")
- native.cc_import(
- name = name,
- shared_library = shared_library,
- alwayslink = alwayslink,
- **kwargs
+def _cc_prebuilt_library_shared_impl(ctx):
+ lib = ctx.file.shared_library
+ files = ctx.attr.shared_library.files if lib != None else None
+ cc_toolchain = find_cpp_toolchain(ctx)
+ feature_configuration = cc_common.configure_features(
+ ctx = ctx,
+ cc_toolchain = cc_toolchain,
)
+ cc_info = create_cc_prebuilt_library_info(
+ ctx,
+ cc_common.create_library_to_link(
+ actions = ctx.actions,
+ dynamic_library = lib,
+ feature_configuration = feature_configuration,
+ cc_toolchain = cc_toolchain,
+ ) if lib != None else None,
+ )
+ return [DefaultInfo(files = files), cc_info]
+
+cc_prebuilt_library_shared = rule(
+ implementation = _cc_prebuilt_library_shared_impl,
+ attrs = dict(
+ shared_library = attr.label(
+ providers = [CcInfo],
+ allow_single_file = True,
+ ),
+ export_includes = attr.string_list(),
+ export_system_includes = attr.string_list(),
+ ),
+ toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
+ fragments = ["cpp"],
+ provides = [CcInfo],
+)
diff --git a/rules/cc/cc_prebuilt_library_shared_test.bzl b/rules/cc/cc_prebuilt_library_shared_test.bzl
index 79084a0a..8fe63f85 100644
--- a/rules/cc/cc_prebuilt_library_shared_test.bzl
+++ b/rules/cc/cc_prebuilt_library_shared_test.bzl
@@ -16,30 +16,56 @@ limitations under the License.
load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
load("//build/bazel/rules/cc:cc_prebuilt_library_shared.bzl", "cc_prebuilt_library_shared")
+load("//build/bazel/rules/test_common:paths.bzl", "get_output_and_package_dir_based_path")
+
+_fake_expected_lib = "{[()]}"
def _cc_prebuilt_library_shared_test_impl(ctx):
env = analysistest.begin(ctx)
target = analysistest.target_under_test(env)
expected_lib = ctx.attr.expected_lib
-
cc_info = target[CcInfo]
+ compilation_context = cc_info.compilation_context
linker_inputs = cc_info.linking_context.linker_inputs.to_list()
libs_to_link = []
for lib in linker_inputs:
libs_to_link += lib.libraries
- asserts.true(
- env,
- expected_lib in [lib.dynamic_library.basename for lib in libs_to_link],
- "\nExpected the target to include the shared library %s; but instead got:\n\t%s\n" % (expected_lib, libs_to_link),
- )
+ if expected_lib == _fake_expected_lib:
+ asserts.true(
+ env,
+ len(libs_to_link) == 0,
+ "\nExpected the shared library to be empty, but instead got:\n\t%s\n" % str(libs_to_link),
+ )
+ else:
+ asserts.true(
+ env,
+ expected_lib in [lib.dynamic_library.basename for lib in libs_to_link],
+ "\nExpected the target to include the shared library %s; but instead got:\n\t%s\n" % (expected_lib, libs_to_link),
+ )
+
+ # Checking for the expected {,system_}includes
+ assert_template = "\nExpected the %s for " + expected_lib + " to be:\n\t%s\n, but instead got:\n\t%s\n"
+ expand_paths = lambda paths: [get_output_and_package_dir_based_path(env, p) for p in paths]
+ expected_includes = expand_paths(ctx.attr.expected_includes)
+ expected_system_includes = expand_paths(ctx.attr.expected_system_includes)
+
+ includes = compilation_context.includes.to_list()
+ for include in expected_includes:
+ asserts.true(env, include in includes, assert_template % ("includes", expected_includes, includes))
+
+ system_includes = compilation_context.system_includes.to_list()
+ for include in expected_system_includes:
+ asserts.true(env, include in system_includes, assert_template % ("system_includes", expected_system_includes, system_includes))
return analysistest.end(env)
_cc_prebuilt_library_shared_test = analysistest.make(
_cc_prebuilt_library_shared_test_impl,
attrs = dict(
- expected_lib = attr.string(mandatory = True),
+ expected_lib = attr.string(default = _fake_expected_lib),
+ expected_includes = attr.string_list(),
+ expected_system_includes = attr.string_list(),
),
)
@@ -53,11 +79,52 @@ def _cc_prebuilt_library_shared_simple():
shared_library = lib,
tags = ["manual"],
)
+ _cc_prebuilt_library_shared_test(
+ name = test_name,
+ target_under_test = name,
+ expected_lib = lib,
+ )
+ return test_name
+
+def _cc_prebuilt_library_shared_default_library_field():
+ name = "_cc_prebuilt_library_shared_default_library_field"
+ test_name = name + "_test"
+ lib = None
+
+ cc_prebuilt_library_shared(
+ name = name,
+ shared_library = lib,
+ tags = ["manual"],
+ )
+ _cc_prebuilt_library_shared_test(
+ name = test_name,
+ target_under_test = name,
+ expected_lib = lib, # We expect the default of _fake_expected_lib
+ )
+
+ return test_name
+
+def _cc_prebuilt_library_shared_has_all_includes():
+ name = "_cc_prebuilt_library_shared_has_all_includes"
+ test_name = name + "_test"
+ lib = "libfoo.so"
+ includes = ["includes"]
+ system_includes = ["system_includes"]
+
+ cc_prebuilt_library_shared(
+ name = name,
+ shared_library = lib,
+ export_includes = includes,
+ export_system_includes = system_includes,
+ tags = ["manual"],
+ )
_cc_prebuilt_library_shared_test(
name = test_name,
target_under_test = name,
expected_lib = lib,
+ expected_includes = includes,
+ expected_system_includes = system_includes,
)
return test_name
@@ -67,5 +134,7 @@ def cc_prebuilt_library_shared_test_suite(name):
name = name,
tests = [
_cc_prebuilt_library_shared_simple(),
+ _cc_prebuilt_library_shared_default_library_field(),
+ _cc_prebuilt_library_shared_has_all_includes(),
],
)
diff --git a/rules/cc/cc_prebuilt_library_static.bzl b/rules/cc/cc_prebuilt_library_static.bzl
index 1981fbf7..1d84adac 100644
--- a/rules/cc/cc_prebuilt_library_static.bzl
+++ b/rules/cc/cc_prebuilt_library_static.bzl
@@ -12,18 +12,41 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-def cc_prebuilt_library_static(
- name,
- static_library,
- export_includes = [], # @unused
- export_system_includes = [], # @unused
- **kwargs):
- "Bazel macro to correspond with the *_cc_prebuilt_library_static Soong module types"
+load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
+load(":cc_library_common.bzl", "create_cc_prebuilt_library_info")
- # TODO: Handle includes similarly to cc_library_static
- # e.g. includes = ["clang-r416183b/prebuilt_include/llvm/lib/Fuzzer"],
- native.cc_import(
- name = name,
- static_library = static_library,
- **kwargs
+def _cc_prebuilt_library_static_impl(ctx):
+ lib = ctx.file.static_library
+ files = ctx.attr.static_library.files if lib != None else None
+ cc_toolchain = find_cpp_toolchain(ctx)
+ feature_configuration = cc_common.configure_features(
+ ctx = ctx,
+ cc_toolchain = cc_toolchain,
)
+ cc_info = create_cc_prebuilt_library_info(
+ ctx,
+ cc_common.create_library_to_link(
+ actions = ctx.actions,
+ static_library = lib,
+ alwayslink = ctx.attr.alwayslink,
+ feature_configuration = feature_configuration,
+ cc_toolchain = cc_toolchain,
+ ) if lib != None else None,
+ )
+ return [DefaultInfo(files = files), cc_info]
+
+cc_prebuilt_library_static = rule(
+ implementation = _cc_prebuilt_library_static_impl,
+ attrs = dict(
+ static_library = attr.label(
+ providers = [CcInfo],
+ allow_single_file = True,
+ ),
+ alwayslink = attr.bool(default = False),
+ export_includes = attr.string_list(),
+ export_system_includes = attr.string_list(),
+ ),
+ toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
+ fragments = ["cpp"],
+ provides = [CcInfo],
+)
diff --git a/rules/cc/cc_prebuilt_library_static_test.bzl b/rules/cc/cc_prebuilt_library_static_test.bzl
index 5a386e4c..326e1953 100644
--- a/rules/cc/cc_prebuilt_library_static_test.bzl
+++ b/rules/cc/cc_prebuilt_library_static_test.bzl
@@ -1,5 +1,5 @@
"""
-Copyright (C) 2022 The Android Open Source Project
+Copyright (C) 2023 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -16,59 +16,193 @@ limitations under the License.
load("@bazel_skylib//lib:unittest.bzl", "analysistest", "asserts")
load("//build/bazel/rules/cc:cc_prebuilt_library_static.bzl", "cc_prebuilt_library_static")
+load("//build/bazel/rules/test_common:paths.bzl", "get_output_and_package_dir_based_path")
+
+_fake_expected_lib = "{[()]}"
def _cc_prebuilt_library_static_alwayslink_test_impl(ctx):
env = analysistest.begin(ctx)
target = analysistest.target_under_test(env)
expected_lib = ctx.attr.expected_lib
+ alwayslink = ctx.attr.alwayslink
cc_info = target[CcInfo]
linker_inputs = cc_info.linking_context.linker_inputs.to_list()
libs_to_link = []
for l in linker_inputs:
libs_to_link += l.libraries
+ has_lib = False
has_alwayslink = False
libs = {}
for lib_to_link in libs_to_link:
lib = lib_to_link.static_library.basename
libs[lib_to_link.static_library] = lib_to_link.alwayslink
if lib == expected_lib:
+ has_lib = True
has_alwayslink = lib_to_link.alwayslink
if has_alwayslink:
break
- asserts.true(env, has_alwayslink, "\nExpected to find the static library `%s` unconditionally in the linker_input, with alwayslink set:\n\t%s" % (expected_lib, str(libs)))
+ asserts.true(
+ env,
+ has_lib,
+ "\nExpected to find the static library `%s` in the linker_input:\n\t%s" % (expected_lib, str(libs)),
+ )
+ asserts.equals(
+ env,
+ has_alwayslink,
+ alwayslink,
+ "\nExpected to find the static library `%s` unconditionally in the linker_input, with alwayslink set to %s:\n\t%s" % (expected_lib, alwayslink, str(libs)),
+ )
return analysistest.end(env)
_cc_prebuilt_library_static_alwayslink_test = analysistest.make(
_cc_prebuilt_library_static_alwayslink_test_impl,
- attrs = {"expected_lib": attr.string()},
+ attrs = {
+ "expected_lib": attr.string(),
+ "alwayslink": attr.bool(),
+ },
)
-def _cc_prebuilt_library_static_given_alwayslink_lib():
- name = "_cc_prebuilt_library_static_given_alwayslink_lib"
+def _cc_prebuilt_library_static_alwayslink_lib(alwayslink):
+ name = "_cc_prebuilt_library_static_alwayslink_lib_" + str(alwayslink)
test_name = name + "_test"
lib = "libfoo.a"
cc_prebuilt_library_static(
name = name,
static_library = lib,
- alwayslink = True,
+ alwayslink = alwayslink,
tags = ["manual"],
)
-
_cc_prebuilt_library_static_alwayslink_test(
name = test_name,
target_under_test = name,
expected_lib = lib,
+ alwayslink = alwayslink,
)
return test_name
+def _cc_prebuilt_library_static_test_impl(ctx):
+ env = analysistest.begin(ctx)
+ target = analysistest.target_under_test(env)
+ expected_lib = ctx.attr.expected_lib
+ cc_info = target[CcInfo]
+ compilation_context = cc_info.compilation_context
+ linker_inputs = cc_info.linking_context.linker_inputs.to_list()
+ libs_to_link = []
+ for lib in linker_inputs:
+ libs_to_link += lib.libraries
+
+ if expected_lib == _fake_expected_lib:
+ asserts.true(
+ env,
+ len(libs_to_link) == 0,
+ "\nExpected the static library to be empty, but instead got:\n\t%s\n" % str(libs_to_link),
+ )
+ else:
+ asserts.true(
+ env,
+ expected_lib in [lib.static_library.basename for lib in libs_to_link],
+ "\nExpected the target to include the static library %s; but instead got:\n\t%s\n" % (expected_lib, libs_to_link),
+ )
+
+ # Checking for the expected {,system_}includes
+ assert_template = "\nExpected the %s for " + expected_lib + " to be:\n\t%s\n, but instead got:\n\t%s\n"
+ expand_paths = lambda paths: [get_output_and_package_dir_based_path(env, p) for p in paths]
+ expected_includes = expand_paths(ctx.attr.expected_includes)
+ expected_system_includes = expand_paths(ctx.attr.expected_system_includes)
+
+ includes = compilation_context.includes.to_list()
+ for include in expected_includes:
+ asserts.true(env, include in includes, assert_template % ("includes", expected_includes, includes))
+
+ system_includes = compilation_context.system_includes.to_list()
+ for include in expected_system_includes:
+ asserts.true(env, include in system_includes, assert_template % ("system_includes", expected_system_includes, system_includes))
+
+ return analysistest.end(env)
+
+_cc_prebuilt_library_static_test = analysistest.make(
+ _cc_prebuilt_library_static_test_impl,
+ attrs = dict(
+ expected_lib = attr.string(default = _fake_expected_lib),
+ expected_includes = attr.string_list(),
+ expected_system_includes = attr.string_list(),
+ ),
+)
+
+def _cc_prebuilt_library_static_simple():
+ name = "_cc_prebuilt_library_static_simple"
+ test_name = name + "_test"
+ lib = "libfoo.a"
+
+ cc_prebuilt_library_static(
+ name = name,
+ static_library = lib,
+ tags = ["manual"],
+ )
+ _cc_prebuilt_library_static_test(
+ name = test_name,
+ target_under_test = name,
+ expected_lib = lib,
+ )
+
+ return test_name
+
+def _cc_prebuilt_library_static_None():
+ name = "_cc_prebuilt_library_static_None"
+ test_name = name + "_test"
+ lib = None
+
+ cc_prebuilt_library_static(
+ name = name,
+ static_library = lib,
+ tags = ["manual"],
+ )
+ _cc_prebuilt_library_static_test(
+ name = test_name,
+ target_under_test = name,
+ expected_lib = lib, # We expect the default of _fake_expected_lib
+ )
+
+ return test_name
+
+def _cc_prebuilt_library_static_has_all_includes():
+ name = "_cc_prebuilt_library_static_has_all_includes"
+ test_name = name + "_test"
+ lib = "libfoo.a"
+ includes = ["includes"]
+ system_includes = ["system_includes"]
+
+ cc_prebuilt_library_static(
+ name = name,
+ static_library = lib,
+ export_includes = includes,
+ export_system_includes = system_includes,
+ tags = ["manual"],
+ )
+ _cc_prebuilt_library_static_test(
+ name = test_name,
+ target_under_test = name,
+ expected_lib = lib,
+ expected_includes = includes,
+ expected_system_includes = system_includes,
+ )
+
+ return test_name
+
+# TODO: Test that is alwayslink = alse
+
def cc_prebuilt_library_static_test_suite(name):
native.test_suite(
name = name,
tests = [
- _cc_prebuilt_library_static_given_alwayslink_lib(),
+ _cc_prebuilt_library_static_simple(),
+ _cc_prebuilt_library_static_None(),
+ _cc_prebuilt_library_static_alwayslink_lib(True),
+ _cc_prebuilt_library_static_alwayslink_lib(False),
+ _cc_prebuilt_library_static_has_all_includes(),
],
)
diff --git a/rules/java/rules_java/WORKSPACE b/rules/java/rules_java/WORKSPACE
deleted file mode 100644
index e69de29b..00000000
--- a/rules/java/rules_java/WORKSPACE
+++ /dev/null
diff --git a/rules/java/rules_java/java/BUILD b/rules/java/rules_java/java/BUILD
deleted file mode 100644
index ee5ee6b2..00000000
--- a/rules/java/rules_java/java/BUILD
+++ /dev/null
@@ -1,7 +0,0 @@
-load("@bazel_skylib//:bzl_library.bzl", "bzl_library")
-
-bzl_library(
- name = "rules",
- srcs = ["defs.bzl"],
- visibility = ["//visibility:public"],
-)
diff --git a/rules/java/rules_java/java/defs.bzl b/rules/java/rules_java/java/defs.bzl
deleted file mode 100644
index 5c9ec57d..00000000
--- a/rules/java/rules_java/java/defs.bzl
+++ /dev/null
@@ -1,29 +0,0 @@
-def java_binary(**attrs):
- native.java_binary(**attrs)
-
-def java_import(**attrs):
- native.java_import(**attrs)
-
-def java_library(**attrs):
- native.java_library(**attrs)
-
-def java_lite_proto_library(**attrs):
- native.java_lite_proto_library(**attrs)
-
-def java_proto_library(**attrs):
- native.java_proto_library(**attrs)
-
-def java_test(**attrs):
- native.java_test(**attrs)
-
-def java_package_configuration(**attrs):
- native.java_package_configuration(**attrs)
-
-def java_plugin(**attrs):
- native.java_plugin(**attrs)
-
-def java_runtime(**attrs):
- native.java_runtime(**attrs)
-
-def java_toolchain(**attrs):
- native.java_toolchain(**attrs)
diff --git a/scripts/incremental_build/canonical_perf.sh b/scripts/incremental_build/canonical_perf.sh
index dc2a750a..97e47d43 100755
--- a/scripts/incremental_build/canonical_perf.sh
+++ b/scripts/incremental_build/canonical_perf.sh
@@ -40,11 +40,13 @@ done
shift $((OPTIND - 1))
readonly -a build_types=("$@")
+log_dir=${log_dir:-"$TOP/../timing-$(date +%b%d-%H%M)"}
+
function build() {
date
set -x
if ! "$TOP/build/bazel/scripts/incremental_build/incremental_build.sh" \
- --ignore-repo-diff ${log_dir:+--log-dir "$log_dir"} \
+ --ignore-repo-diff --log-dir "$log_dir" \
${build_types:+--build-types "${build_types[@]}"} \
"$@"; then
echo "See logs for errors"
diff --git a/scripts/incremental_build/cuj_catalog.py b/scripts/incremental_build/cuj_catalog.py
index e2d4868e..7d2de238 100644
--- a/scripts/incremental_build/cuj_catalog.py
+++ b/scripts/incremental_build/cuj_catalog.py
@@ -25,6 +25,7 @@ import uuid
from enum import Enum
from pathlib import Path
from typing import Callable, Optional
+from typing import Final
from typing import TypeAlias
import util
@@ -63,20 +64,15 @@ def verify_symlink_forest_has_only_symlink_leaves():
files except for merged BUILD.bazel files"""
top_in_ws = InWorkspace.ws_counterpart(util.get_top_dir())
- def helper(d: Path):
- for child in os.scandir(d):
- child_path: Path = Path(child.path)
- if child_path.name == 'symlink_forest_version' and d == top_in_ws:
- continue
- if child_path.is_symlink():
+
+ for root, dirs, files in os.walk(top_in_ws, topdown=True, followlinks=False):
+ for file in files:
+ if file == 'symlink_forest_version' and top_in_ws.samefile(root):
continue
- if child_path.is_file() and child.name != 'BUILD.bazel':
- # only "merged" BUILD.bazel files expected
- raise AssertionError(f'{child_path} is an unexpected file')
- if child_path.is_dir():
- helper(child_path)
+ f = Path(root).joinpath(file)
+ if file != 'BUILD.bazel' and not f.is_symlink():
+ raise AssertionError(f'{f} unexpected')
- helper(top_in_ws)
logging.info('VERIFIED Symlink Forest has no real files except BUILD.bazel')
@@ -106,8 +102,12 @@ class CujGroup:
if len(self.steps) < 2:
return f'{self.steps[0].verb} {self.description}'.strip()
return ' '.join(
- [f'({chr(ord("a") + i)}) {step.verb} {self.description}'.strip() for
- i, step in enumerate(self.steps)])
+ [f'({chr(ord("a") + i)}) {step.verb} {self.description}'.strip() for
+ i, step in enumerate(self.steps)])
+
+
+Warmup: Final[CujGroup] = CujGroup('WARMUP',
+ [CujStep('no change', lambda: None)])
class InWorkspace(Enum):
@@ -122,7 +122,7 @@ class InWorkspace(Enum):
@staticmethod
def ws_counterpart(src_path: Path) -> Path:
return util.get_out_dir().joinpath('soong/workspace').joinpath(
- de_src(src_path))
+ de_src(src_path))
def verifier(self, src_path: Path) -> Verifier:
@skip_when_soong_only
@@ -146,7 +146,7 @@ class InWorkspace(Enum):
if self != actual:
raise AssertionError(
- f'{ws_path} expected {self.name} but got {actual.name}')
+ f'{ws_path} expected {self.name} but got {actual.name}')
logging.info(f'VERIFIED {de_src(ws_path)} {self.name}')
return f
@@ -181,8 +181,8 @@ def modify_revert(file: Path, text: str = '//BOGUS line\n') -> CujGroup:
f.truncate()
return CujGroup(de_src(file), [
- CujStep('modify', add_line),
- CujStep('revert', revert)
+ CujStep('modify', add_line),
+ CujStep('revert', revert)
])
@@ -202,8 +202,8 @@ def create_delete(file: Path, ws: InWorkspace,
def create():
if file.exists():
raise RuntimeError(
- f'File {file} already exists. Interrupted an earlier run?\n'
- 'TIP: `repo status` and revert changes!!!')
+ f'File {file} already exists. Interrupted an earlier run?\n'
+ 'TIP: `repo status` and revert changes!!!')
file.parent.mkdir(parents=True, exist_ok=True)
file.touch(exist_ok=False)
with open(file, mode="w") as f:
@@ -216,8 +216,8 @@ def create_delete(file: Path, ws: InWorkspace,
file.unlink(missing_ok=False)
return CujGroup(de_src(file), [
- CujStep('create', create, ws.verifier(file)),
- CujStep('delete', delete, InWorkspace.OMISSION.verifier(file)),
+ CujStep('create', create, ws.verifier(file)),
+ CujStep('delete', delete, InWorkspace.OMISSION.verifier(file)),
])
@@ -227,8 +227,8 @@ def create_delete_bp(bp_file: Path) -> CujGroup:
an Android.bp file.
"""
return create_delete(
- bp_file, InWorkspace.SYMLINK,
- 'filegroup { name: "test-bogus-filegroup", srcs: ["**/*.md"] }')
+ bp_file, InWorkspace.SYMLINK,
+ 'filegroup { name: "test-bogus-filegroup", srcs: ["**/*.md"] }')
def delete_restore(original: Path, ws: InWorkspace) -> CujGroup:
@@ -252,12 +252,12 @@ def delete_restore(original: Path, ws: InWorkspace) -> CujGroup:
original.rename(copied)
return CujGroup(de_src(original), [
- CujStep('delete',
- move_to_tempdir_to_mimic_deletion,
- InWorkspace.OMISSION.verifier(original)),
- CujStep('restore',
- lambda: copied.rename(original),
- ws.verifier(original))
+ CujStep('delete',
+ move_to_tempdir_to_mimic_deletion,
+ InWorkspace.OMISSION.verifier(original)),
+ CujStep('restore',
+ lambda: copied.rename(original),
+ ws.verifier(original))
])
@@ -274,7 +274,7 @@ def replace_link_with_dir(p: Path):
create_dir: CujStep
delete_dir: CujStep
create_dir, delete_dir, *tail = create_delete_bp(
- p.joinpath('Android.bp')).steps
+ p.joinpath('Android.bp')).steps
assert len(tail) == 0
def replace_it():
@@ -282,11 +282,11 @@ def replace_link_with_dir(p: Path):
create_dir.apply_change()
return CujGroup(cd.description, [
- create_file,
- CujStep(f'{de_src(p)}/Android.bp instead of',
- replace_it,
- create_dir.verify),
- delete_dir
+ create_file,
+ CujStep(f'{de_src(p)}/Android.bp instead of',
+ replace_it,
+ create_dir.verify),
+ delete_dir
])
@@ -311,14 +311,14 @@ def content_verfiers(
def contains():
if not search():
raise AssertionError(
- f'{de_src(ws_build_file)} expected to contain {content}')
+ f'{de_src(ws_build_file)} expected to contain {content}')
logging.info(f'VERIFIED {de_src(ws_build_file)} contains {content}')
@skip_when_soong_only
def does_not_contain():
if search():
raise AssertionError(
- f'{de_src(ws_build_file)} not expected to contain {content}')
+ f'{de_src(ws_build_file)} not expected to contain {content}')
logging.info(f'VERIFIED {de_src(ws_build_file)} does not contain {content}')
return contains, does_not_contain
@@ -329,22 +329,22 @@ def modify_revert_kept_build_file(build_file: Path) -> CujGroup:
step1, step2, *tail = modify_revert(build_file, content).steps
assert len(tail) == 0
ws_build_file = InWorkspace.ws_counterpart(build_file).with_name(
- 'BUILD.bazel')
+ 'BUILD.bazel')
merge_prover, merge_disprover = content_verfiers(ws_build_file, content)
return CujGroup(de_src(build_file), [
- CujStep(step1.verb,
- step1.apply_change,
- _sequence(step1.verify, merge_prover)),
- CujStep(step2.verb,
- step2.apply_change,
- _sequence(step2.verify, merge_disprover))
+ CujStep(step1.verb,
+ step1.apply_change,
+ _sequence(step1.verify, merge_prover)),
+ CujStep(step2.verb,
+ step2.apply_change,
+ _sequence(step2.verify, merge_disprover))
])
def create_delete_kept_build_file(build_file: Path) -> CujGroup:
content = f'//BOGUS {uuid.uuid4()}\n'
ws_build_file = InWorkspace.ws_counterpart(build_file).with_name(
- 'BUILD.bazel')
+ 'BUILD.bazel')
if build_file.name == 'BUILD.bazel':
ws = InWorkspace.NOT_UNDER_SYMLINK
elif build_file.name == 'BUILD':
@@ -359,32 +359,32 @@ def create_delete_kept_build_file(build_file: Path) -> CujGroup:
step1, step2, *tail = create_delete(build_file, ws, content).steps
assert len(tail) == 0
return CujGroup(de_src(build_file), [
- CujStep(step1.verb,
- step1.apply_change,
- _sequence(step1.verify, merge_prover)),
- CujStep(step2.verb,
- step2.apply_change,
- _sequence(step2.verify, merge_disprover))
+ CujStep(step1.verb,
+ step1.apply_change,
+ _sequence(step1.verify, merge_prover)),
+ CujStep(step2.verb,
+ step2.apply_change,
+ _sequence(step2.verify, merge_disprover))
])
def create_delete_unkept_build_file(build_file) -> CujGroup:
content = f'//BOGUS {uuid.uuid4()}\n'
ws_build_file = InWorkspace.ws_counterpart(build_file).with_name(
- 'BUILD.bazel')
+ 'BUILD.bazel')
step1: CujStep
step2: CujStep
step1, step2, *tail = create_delete(
- build_file, InWorkspace.SYMLINK, content).steps
+ build_file, InWorkspace.SYMLINK, content).steps
assert len(tail) == 0
_, merge_disprover = content_verfiers(ws_build_file, content)
return CujGroup(de_src(build_file), [
- CujStep(step1.verb,
- step1.apply_change,
- _sequence(step1.verify, merge_disprover)),
- CujStep(step2.verb,
- step2.apply_change,
- _sequence(step2.verify, merge_disprover))
+ CujStep(step1.verb,
+ step1.apply_change,
+ _sequence(step1.verify, merge_disprover)),
+ CujStep(step2.verb,
+ step2.apply_change,
+ _sequence(step2.verify, merge_disprover))
])
@@ -407,9 +407,9 @@ def _kept_build_cujs() -> list[CujGroup]:
pkg.joinpath('BUILD.bazel')]
return [
- *[create_delete_kept_build_file(build_file) for build_file in examples],
- create_delete(pkg.joinpath('BUILD/kept-dir'), InWorkspace.SYMLINK),
- modify_revert_kept_build_file(util.any_file_under(kept, 'BUILD'))]
+ *[create_delete_kept_build_file(build_file) for build_file in examples],
+ create_delete(pkg.joinpath('BUILD/kept-dir'), InWorkspace.SYMLINK),
+ modify_revert_kept_build_file(util.any_file_under(kept, 'BUILD'))]
def _unkept_build_cujs() -> list[CujGroup]:
@@ -417,15 +417,15 @@ def _unkept_build_cujs() -> list[CujGroup]:
unkept = src('bionic')
pkg = util.any_dir_under(unkept, *PKG)
return [
- *[create_delete_unkept_build_file(build_file) for build_file in [
- pkg.joinpath('BUILD'),
- pkg.joinpath('BUILD.bazel'),
- ]],
- *[create_delete(build_file, InWorkspace.OMISSION) for build_file in [
- unkept.joinpath('bogus-unkept/BUILD'),
- unkept.joinpath('bogus-unkept/BUILD.bazel'),
- ]],
- create_delete(pkg.joinpath('BUILD/unkept-dir'), InWorkspace.SYMLINK)
+ *[create_delete_unkept_build_file(build_file) for build_file in [
+ pkg.joinpath('BUILD'),
+ pkg.joinpath('BUILD.bazel'),
+ ]],
+ *[create_delete(build_file, InWorkspace.OMISSION) for build_file in [
+ unkept.joinpath('bogus-unkept/BUILD'),
+ unkept.joinpath('bogus-unkept/BUILD.bazel'),
+ ]],
+ create_delete(pkg.joinpath('BUILD/unkept-dir'), InWorkspace.SYMLINK)
]
@@ -447,52 +447,48 @@ def get_cujgroups() -> list[CujGroup]:
'''))
android_bp_cujs = [
- modify_revert(src('Android.bp')),
- *[create_delete_bp(d.joinpath('Android.bp')) for d in
- [ancestor, pkg_free, leaf_pkg_free]]
+ modify_revert(src('Android.bp')),
+ *[create_delete_bp(d.joinpath('Android.bp')) for d in
+ [ancestor, pkg_free, leaf_pkg_free]]
]
mixed_build_launch_cujs = [
- modify_revert(src('bionic/libc/tzcode/asctime.c')),
- modify_revert(src('bionic/libc/stdio/stdio.cpp')),
- modify_revert(src('packages/modules/adb/daemon/main.cpp')),
- modify_revert(src('frameworks/base/core/java/android/view/View.java')),
+ modify_revert(src('bionic/libc/tzcode/asctime.c')),
+ modify_revert(src('bionic/libc/stdio/stdio.cpp')),
+ modify_revert(src('packages/modules/adb/daemon/main.cpp')),
+ modify_revert(src('frameworks/base/core/java/android/view/View.java')),
]
unreferenced_file_cujs = [
- *[create_delete(d.joinpath('unreferenced.txt'), InWorkspace.SYMLINK) for
- d in [ancestor, pkg]],
- *[create_delete(d.joinpath('unreferenced.txt'), InWorkspace.UNDER_SYMLINK)
- for d
- in [pkg_free, leaf_pkg_free]]
+ *[create_delete(d.joinpath('unreferenced.txt'), InWorkspace.SYMLINK) for
+ d in [ancestor, pkg]],
+ *[create_delete(d.joinpath('unreferenced.txt'), InWorkspace.UNDER_SYMLINK)
+ for d
+ in [pkg_free, leaf_pkg_free]]
]
def clean():
if ui.get_user_input().log_dir.is_relative_to(util.get_top_dir()):
raise AssertionError(
- f'specify a different LOG_DIR: {ui.get_user_input().log_dir}')
+ f'specify a different LOG_DIR: {ui.get_user_input().log_dir}')
if util.get_out_dir().exists():
shutil.rmtree(util.get_out_dir())
return [
- CujGroup('', [CujStep('clean', clean)]),
- CujGroup('', [CujStep('no change', lambda: None)]),
-
- create_delete(src('bionic/libc/tzcode/globbed.c'),
- InWorkspace.UNDER_SYMLINK),
-
- # TODO (usta): find targets that should be affected
- *[delete_restore(f, InWorkspace.SYMLINK) for f in [
- util.any_file('version_script.txt'),
- util.any_file('AndroidManifest.xml')]],
-
- *unreferenced_file_cujs,
- *mixed_build_launch_cujs,
- *android_bp_cujs,
- *_unkept_build_cujs(),
- *_kept_build_cujs(),
- replace_link_with_dir(pkg.joinpath('bogus.txt')),
- # TODO(usta): add a dangling symlink
+ CujGroup('', [CujStep('clean', clean)]),
+ Warmup,
+
+ create_delete(src('bionic/libc/tzcode/globbed.c'),
+ InWorkspace.UNDER_SYMLINK),
+
+ # TODO (usta): find targets that should be affected
+ *[delete_restore(f, InWorkspace.SYMLINK) for f in [
+ util.any_file('version_script.txt'),
+ util.any_file('AndroidManifest.xml')]],
+
+ *unreferenced_file_cujs,
+ *mixed_build_launch_cujs,
+ *android_bp_cujs,
+ *_unkept_build_cujs(),
+ *_kept_build_cujs(),
+ replace_link_with_dir(pkg.joinpath('bogus.txt')),
+ # TODO(usta): add a dangling symlink
]
-
-
-def warmup_index() -> int:
- return 1
diff --git a/scripts/incremental_build/incremental_build.py b/scripts/incremental_build/incremental_build.py
index b95d3a84..b43e0fb1 100644
--- a/scripts/incremental_build/incremental_build.py
+++ b/scripts/incremental_build/incremental_build.py
@@ -32,9 +32,9 @@ from typing import Mapping
import cuj_catalog
import perf_metrics
+import pretty
import ui
import util
-import pretty
MAX_RUN_COUNT: int = 5
@@ -213,13 +213,11 @@ def main():
run_dir_gen = util.next_path(user_input.log_dir.joinpath(util.RUN_DIR_PREFIX))
- def run_cuj_group(cuj_group: cuj_catalog.CujGroup, is_warmup: bool):
+ def run_cuj_group(cuj_group: cuj_catalog.CujGroup):
for cujstep in cuj_group.steps:
desc = cujstep.verb
desc = f'{desc} {cuj_group.description}'.strip()
desc = f'{desc} {user_input.description}'.strip()
- if is_warmup:
- desc = f'WARMUP {desc}'
logging.info('START %s %s [%s]', build_type.name,
' '.join(user_input.targets), desc)
cujstep.apply_change()
@@ -234,9 +232,9 @@ def main():
for build_type in user_input.build_types:
# warm-up run reduces variations attributable to OS caches
- run_cuj_group(cuj_catalog.get_cujgroups()[cuj_catalog.warmup_index()], True)
+ run_cuj_group(cuj_catalog.Warmup)
for i in user_input.chosen_cujgroups:
- run_cuj_group(cuj_catalog.get_cujgroups()[i], False)
+ run_cuj_group(cuj_catalog.get_cujgroups()[i])
perf_metrics.tabulate_metrics_csv(user_input.log_dir)
perf_metrics.display_tabulated_metrics(user_input.log_dir)
diff --git a/scripts/incremental_build/perf_metrics.py b/scripts/incremental_build/perf_metrics.py
index 3d074566..64512e73 100644
--- a/scripts/incremental_build/perf_metrics.py
+++ b/scripts/incremental_build/perf_metrics.py
@@ -181,10 +181,12 @@ def _get_column_headers(rows: list[Row], allow_cycles: bool) -> list[str]:
prev_col = all_cols[col]
acc = []
- while len(all_cols) > 0:
- entries = [c for c in all_cols.values()]
- entries.sort(key=lambda c: f'{c.indegree:03d}{c.header}')
- entry = entries[0]
+ entries = [c for c in all_cols.values()]
+ while len(entries) > 0:
+ # sorting alphabetically to break ties for concurrent events
+ entries.sort(key=lambda c: c.header, reverse=True)
+ entries.sort(key=lambda c: c.indegree, reverse=True)
+ entry = entries.pop()
# take only one to maintain alphabetical sort
if entry.indegree != 0:
cycle = '->'.join(entry.dfs(entry.header))
@@ -200,7 +202,6 @@ def _get_column_headers(rows: list[Row], allow_cycles: bool) -> list[str]:
else:
if not allow_cycles:
raise ValueError(f'unexpected error for: {n}')
- all_cols.pop(entry.header)
return acc
diff --git a/scripts/incremental_build/perf_metrics_test.py b/scripts/incremental_build/perf_metrics_test.py
index a25c4405..119bdc10 100644
--- a/scripts/incremental_build/perf_metrics_test.py
+++ b/scripts/incremental_build/perf_metrics_test.py
@@ -40,6 +40,7 @@ class PerfMetricsTest(unittest.TestCase):
Example(['ac', 'bd'], 'abcd'),
Example(['abe', 'cde'], 'abcde'),
Example(['ab', 'ba'], 'ab'),
+ Example(['abcde', 'edcba'], 'abcde'),
Example(['ac', 'abc'], 'abc')
]
for e in examples:
@@ -60,3 +61,7 @@ class PerfMetricsTest(unittest.TestCase):
with self.assertRaisesRegex(ValueError,
f'event ordering has a cycle {cycle}'):
_get_column_headers(rows, allow_cycles=False)
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/scripts/incremental_build/util_test.py b/scripts/incremental_build/util_test.py
index 01b5f9c2..b117bd74 100644
--- a/scripts/incremental_build/util_test.py
+++ b/scripts/incremental_build/util_test.py
@@ -101,3 +101,7 @@ class UtilTest(unittest.TestCase):
for (ts, expected) in examples:
self.subTest(ts=ts, expected=expected)
self.assertEqual(period_to_seconds(ts), expected)
+
+
+if __name__ == '__main__':
+ unittest.main()