aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-03-04 22:09:09 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2024-03-04 22:09:09 +0000
commite4e9fc469b0edc4a9c00aee93007bb158bd16c93 (patch)
tree1712145996c7c1417f2e15c23c5f9e6de3529460
parent70ae128471ed69464c0fcc335019d1d9d4bca65c (diff)
parent229e46055785e329ca397400bd4bfba35a7ec1db (diff)
downloadtoolchain-utils-simpleperf-release.tar.gz
Snap for 11526323 from 229e46055785e329ca397400bd4bfba35a7ec1db to simpleperf-releasesimpleperf-release
Change-Id: I3f786968fe8de6ceeb4585432b15cae5ad404b77
-rw-r--r--.gitignore7
-rw-r--r--afdo_metadata/kernel_afdo.json9
-rw-r--r--afdo_metadata/kernel_arm_afdo.json2
-rw-r--r--afdo_tools/update_kernel_afdo.cfg2
-rwxr-xr-xcheck_portable_toolchains.py224
-rw-r--r--compiler_wrapper/README.md121
-rw-r--r--compiler_wrapper/android_config_test.go17
-rwxr-xr-xcompiler_wrapper/build.py38
-rw-r--r--compiler_wrapper/bundle.README18
-rwxr-xr-xcompiler_wrapper/bundle.py93
-rw-r--r--compiler_wrapper/ccache_flag.go13
-rw-r--r--compiler_wrapper/ccache_flag_test.go29
-rw-r--r--compiler_wrapper/clang_flags.go12
-rw-r--r--compiler_wrapper/clang_flags_test.go30
-rw-r--r--compiler_wrapper/clang_tidy_flag_test.go4
-rw-r--r--compiler_wrapper/compiler_wrapper.go83
-rw-r--r--compiler_wrapper/compiler_wrapper_test.go46
-rw-r--r--compiler_wrapper/config.go72
-rw-r--r--compiler_wrapper/config_test.go7
-rw-r--r--compiler_wrapper/crash_dump_test.go42
-rw-r--r--compiler_wrapper/cros_hardened_config_test.go4
-rw-r--r--compiler_wrapper/disable_werror_flag.go133
-rw-r--r--compiler_wrapper/disable_werror_flag_test.go206
-rw-r--r--compiler_wrapper/goldenutil_test.go90
-rwxr-xr-xcompiler_wrapper/install_compiler_wrapper.sh4
-rw-r--r--compiler_wrapper/testdata/android_golden/bisect.json82
-rw-r--r--compiler_wrapper/testdata/android_golden/clang_path.json192
-rw-r--r--compiler_wrapper/testdata/android_golden/compile_with_fallback.json82
-rw-r--r--compiler_wrapper/testdata/cros_clang_host_golden/bisect.json118
-rw-r--r--compiler_wrapper/testdata/cros_clang_host_golden/clang_ftrapv_maincc_target_specific.json262
-rw-r--r--compiler_wrapper/testdata/cros_clang_host_golden/clang_host_wrapper.json36
-rw-r--r--compiler_wrapper/testdata/cros_clang_host_golden/clang_maincc_target_specific.json260
-rw-r--r--compiler_wrapper/testdata/cros_clang_host_golden/clang_path.json406
-rw-r--r--compiler_wrapper/testdata/cros_clang_host_golden/clang_sanitizer_args.json250
-rw-r--r--compiler_wrapper/testdata/cros_clang_host_golden/clang_specific_args.json146
-rw-r--r--compiler_wrapper/testdata/cros_clang_host_golden/clangtidy.json239
-rw-r--r--compiler_wrapper/testdata/cros_clang_host_golden/force_disable_werror.json150
-rw-r--r--compiler_wrapper/testdata/cros_gcc_host_golden/gcc_host_wrapper.json24
-rw-r--r--compiler_wrapper/testdata/cros_gcc_host_golden/gcc_maincc_target_specific.json152
-rw-r--r--compiler_wrapper/testdata/cros_gcc_host_golden/gcc_path.json124
-rw-r--r--compiler_wrapper/testdata/cros_gcc_host_golden/gcc_specific_args.json62
-rw-r--r--compiler_wrapper/testdata/cros_hardened_golden/bisect.json118
-rw-r--r--compiler_wrapper/testdata/cros_hardened_golden/clang_ftrapv_maincc_target_specific.json262
-rw-r--r--compiler_wrapper/testdata/cros_hardened_golden/clang_maincc_target_specific.json260
-rw-r--r--compiler_wrapper/testdata/cros_hardened_golden/clang_path.json405
-rw-r--r--compiler_wrapper/testdata/cros_hardened_golden/clang_sanitizer_args.json236
-rw-r--r--compiler_wrapper/testdata/cros_hardened_golden/clang_specific_args.json146
-rw-r--r--compiler_wrapper/testdata/cros_hardened_golden/clang_sysroot_wrapper_common.json212
-rw-r--r--compiler_wrapper/testdata/cros_hardened_golden/clangtidy.json236
-rw-r--r--compiler_wrapper/testdata/cros_hardened_golden/force_disable_werror.json154
-rw-r--r--compiler_wrapper/testdata/cros_hardened_golden/gcc_clang_syntax.json166
-rw-r--r--compiler_wrapper/testdata/cros_hardened_golden/gcc_maincc_target_specific.json170
-rw-r--r--compiler_wrapper/testdata/cros_hardened_golden/gcc_path.json136
-rw-r--r--compiler_wrapper/testdata/cros_hardened_golden/gcc_sanitizer_args.json170
-rw-r--r--compiler_wrapper/testdata/cros_hardened_golden/gcc_specific_args.json68
-rw-r--r--compiler_wrapper/testdata/cros_hardened_golden/gcc_sysroot_wrapper_common.json152
-rw-r--r--compiler_wrapper/testdata/cros_hardened_llvmnext_golden/bisect.json118
-rw-r--r--compiler_wrapper/testdata/cros_hardened_llvmnext_golden/clang_path.json405
-rw-r--r--compiler_wrapper/testdata/cros_hardened_llvmnext_golden/clangtidy.json236
-rw-r--r--compiler_wrapper/testdata/cros_hardened_llvmnext_golden/force_disable_werror.json154
-rw-r--r--compiler_wrapper/testdata/cros_hardened_llvmnext_golden/gcc_clang_syntax.json166
-rw-r--r--compiler_wrapper/testdata/cros_hardened_llvmnext_golden/gcc_path.json136
-rw-r--r--compiler_wrapper/testdata/cros_hardened_noccache_golden/bisect.json118
-rw-r--r--compiler_wrapper/testdata/cros_hardened_noccache_golden/clang_path.json405
-rw-r--r--compiler_wrapper/testdata/cros_hardened_noccache_golden/clangtidy.json236
-rw-r--r--compiler_wrapper/testdata/cros_hardened_noccache_golden/force_disable_werror.json154
-rw-r--r--compiler_wrapper/testdata/cros_hardened_noccache_golden/gcc_clang_syntax.json166
-rw-r--r--compiler_wrapper/testdata/cros_hardened_noccache_golden/gcc_path.json136
-rw-r--r--compiler_wrapper/testdata/cros_nonhardened_golden/bisect.json109
-rw-r--r--compiler_wrapper/testdata/cros_nonhardened_golden/clang_ftrapv_maincc_target_specific.json235
-rw-r--r--compiler_wrapper/testdata/cros_nonhardened_golden/clang_maincc_target_specific.json233
-rw-r--r--compiler_wrapper/testdata/cros_nonhardened_golden/clang_path.json369
-rw-r--r--compiler_wrapper/testdata/cros_nonhardened_golden/clang_sanitizer_args.json226
-rw-r--r--compiler_wrapper/testdata/cros_nonhardened_golden/clang_specific_args.json134
-rw-r--r--compiler_wrapper/testdata/cros_nonhardened_golden/clang_sysroot_wrapper_common.json192
-rw-r--r--compiler_wrapper/testdata/cros_nonhardened_golden/clangtidy.json212
-rw-r--r--compiler_wrapper/testdata/cros_nonhardened_golden/force_disable_werror.json139
-rw-r--r--compiler_wrapper/testdata/cros_nonhardened_golden/gcc_clang_syntax.json148
-rw-r--r--compiler_wrapper/testdata/cros_nonhardened_golden/gcc_maincc_target_specific.json152
-rw-r--r--compiler_wrapper/testdata/cros_nonhardened_golden/gcc_path.json124
-rw-r--r--compiler_wrapper/testdata/cros_nonhardened_golden/gcc_sanitizer_args.json154
-rw-r--r--compiler_wrapper/testdata/cros_nonhardened_golden/gcc_specific_args.json62
-rw-r--r--compiler_wrapper/testdata/cros_nonhardened_golden/gcc_sysroot_wrapper_common.json138
-rw-r--r--compiler_wrapper/testutil_test.go7
-rw-r--r--contrib/README.md5
-rw-r--r--contrib/gbiv/bgtask/Makefile12
-rw-r--r--contrib/gbiv/bgtask/bgtask.cc131
-rwxr-xr-xcros_utils/bugs.py69
-rwxr-xr-xcros_utils/bugs_test.py50
-rwxr-xr-xcros_utils/no_pseudo_terminal_test.py64
-rw-r--r--cros_utils/tiny_render.py5
-rwxr-xr-xfile_lock_machine.py423
-rwxr-xr-xfile_lock_machine_test.py128
-rw-r--r--llvm_tools/README.md41
-rw-r--r--llvm_tools/atomic_write_file.py24
-rwxr-xr-x[-rw-r--r--]llvm_tools/atomic_write_file_unittest.py3
-rwxr-xr-xllvm_tools/auto_llvm_bisection.py12
-rwxr-xr-xllvm_tools/auto_llvm_bisection_unittest.py10
-rwxr-xr-xllvm_tools/check_clang_diags.py34
-rwxr-xr-xllvm_tools/check_clang_diags_test.py28
-rwxr-xr-xllvm_tools/chroot.py44
-rwxr-xr-xllvm_tools/chroot_unittest.py12
-rwxr-xr-xllvm_tools/copy_helpers_to_chromiumos_overlay.py1
-rw-r--r--llvm_tools/cros_cls.py246
-rwxr-xr-xllvm_tools/cros_cls_test.py132
-rwxr-xr-xllvm_tools/custom_script_example.py27
-rw-r--r--llvm_tools/failure_modes.py2
-rwxr-xr-xllvm_tools/fetch_cq_size_diff.py366
-rwxr-xr-xllvm_tools/fetch_cros_sdk_rolls.py3
-rwxr-xr-xllvm_tools/generate_llvm_revert_report.py159
-rwxr-xr-xllvm_tools/get_llvm_hash.py187
-rwxr-xr-xllvm_tools/get_llvm_hash_unittest.py70
-rwxr-xr-xllvm_tools/get_patch.py722
-rwxr-xr-xllvm_tools/get_patch_unittest.py233
-rwxr-xr-xllvm_tools/get_upstream_patch.py123
-rwxr-xr-xllvm_tools/git.py89
-rwxr-xr-xllvm_tools/git_llvm_rev.py248
-rwxr-xr-xllvm_tools/git_llvm_rev_test.py65
-rwxr-xr-xllvm_tools/git_unittest.py16
-rwxr-xr-xllvm_tools/llvm_bisection.py58
-rwxr-xr-xllvm_tools/llvm_bisection_unittest.py35
-rw-r--r--llvm_tools/llvm_project.py4
-rw-r--r--llvm_tools/manifest_utils.py9
-rwxr-xr-x[-rw-r--r--]llvm_tools/manifest_utils_unittest.py16
-rwxr-xr-xllvm_tools/modify_a_tryjob.py83
-rwxr-xr-xllvm_tools/modify_a_tryjob_unittest.py103
-rwxr-xr-xllvm_tools/nightly_revert_checker.py353
-rwxr-xr-xllvm_tools/nightly_revert_checker_test.py145
-rwxr-xr-xllvm_tools/patch_manager.py95
-rwxr-xr-xllvm_tools/patch_manager_unittest.py12
-rw-r--r--llvm_tools/patch_sync/README.md45
-rw-r--r--llvm_tools/patch_sync/src/main.rs9
-rw-r--r--llvm_tools/patch_sync/src/version_control.rs20
-rw-r--r--llvm_tools/patch_utils.py203
-rwxr-xr-xllvm_tools/patch_utils_unittest.py41
-rwxr-xr-xllvm_tools/setup_for_workon.py286
-rw-r--r--llvm_tools/subprocess_helpers.py16
-rw-r--r--llvm_tools/test_helpers.py38
-rwxr-xr-xllvm_tools/update_chromeos_llvm_hash.py348
-rwxr-xr-xllvm_tools/update_chromeos_llvm_hash_unittest.py162
-rwxr-xr-xllvm_tools/update_packages_and_run_tests.py96
-rwxr-xr-xllvm_tools/update_packages_and_run_tests_unittest.py33
-rwxr-xr-xllvm_tools/update_tryjob_status.py68
-rwxr-xr-xllvm_tools/update_tryjob_status_unittest.py198
-rwxr-xr-xllvm_tools/werror_logs.py577
-rwxr-xr-xllvm_tools/werror_logs_test.py425
-rwxr-xr-xorderfile/post_process_orderfile.py99
-rwxr-xr-xorderfile/post_process_orderfile_test.py95
-rw-r--r--pgo_tools/README.md17
-rwxr-xr-xpgo_tools/benchmark_pgo_profiles.py287
-rwxr-xr-xpgo_tools/benchmark_pgo_profiles_test.py51
-rwxr-xr-xpgo_tools/create_chroot_and_generate_pgo_profile.py260
-rwxr-xr-xpgo_tools/create_chroot_and_generate_pgo_profile_test.py81
-rwxr-xr-xpgo_tools/ensure_pgo_is_a_win.py91
-rwxr-xr-xpgo_tools/ensure_pgo_is_a_win_test.py52
-rwxr-xr-xpgo_tools/generate_pgo_profile.py477
-rwxr-xr-xpgo_tools/generate_pgo_profile_test.py112
-rwxr-xr-xpgo_tools/merge_profdata_and_upload.py420
-rwxr-xr-xpgo_tools/monitor_pgo_profiles.py123
-rwxr-xr-xpgo_tools/monitor_pgo_profiles_unittest.py104
-rw-r--r--pgo_tools/pgo_tools.py160
-rwxr-xr-xpgo_tools/pgo_tools_test.py108
-rwxr-xr-xpgo_tools/update_llvm_manifest.py105
-rwxr-xr-xpgo_tools_rust/pgo_rust.py9
-rwxr-xr-xrun_tests_for.py66
-rw-r--r--rust-analyzer-chromiumos-wrapper/Cargo.lock52
-rw-r--r--rust-analyzer-chromiumos-wrapper/Cargo.toml2
-rw-r--r--rust-analyzer-chromiumos-wrapper/README.md56
-rw-r--r--rust-analyzer-chromiumos-wrapper/src/main.rs145
-rwxr-xr-xrust_tools/auto_update_rust_bootstrap.py854
-rwxr-xr-xrust_tools/auto_update_rust_bootstrap_test.py473
-rwxr-xr-xrust_tools/copy_rust_bootstrap.py19
-rwxr-xr-xrust_tools/rust_uprev.py465
-rwxr-xr-xrust_tools/rust_uprev_test.py277
-rwxr-xr-xrust_tools/rust_watch.py35
-rwxr-xr-xtoolchain_utils_githooks/check-presubmit.py385
176 files changed, 14537 insertions, 10051 deletions
diff --git a/.gitignore b/.gitignore
index 92ee4cb9..822882f7 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
-logs
*.pyc
.mypy_cache/
-llvm-project-copy/
-compiler_wrapper/compiler_wrapper
+/contrib/gbiv/bgtask/bgtask
/rust-analyzer-chromiumos-wrapper/target
+compiler_wrapper/compiler_wrapper
+llvm-project-copy/
+logs
diff --git a/afdo_metadata/kernel_afdo.json b/afdo_metadata/kernel_afdo.json
index 0d6cecc2..d752cadd 100644
--- a/afdo_metadata/kernel_afdo.json
+++ b/afdo_metadata/kernel_afdo.json
@@ -1,14 +1,11 @@
{
- "chromeos-kernel-4_14": {
- "name": "R117-15563.0-1691400981"
- },
"chromeos-kernel-5_4": {
- "name": "R117-15563.0-1691401051"
+ "name": "R121-15699.29-1705314853"
},
"chromeos-kernel-5_10": {
- "name": "R117-15563.0-1691400779"
+ "name": "R122-15699.25-1704709934"
},
"chromeos-kernel-5_15": {
- "name": "R117-15563.0-1691400946"
+ "name": "R122-15699.25-1704709973"
}
}
diff --git a/afdo_metadata/kernel_arm_afdo.json b/afdo_metadata/kernel_arm_afdo.json
index c90edba4..cbe71c51 100644
--- a/afdo_metadata/kernel_arm_afdo.json
+++ b/afdo_metadata/kernel_arm_afdo.json
@@ -1,5 +1,5 @@
{
"chromeos-kernel-5_15": {
- "name": "R117-15563.0-1691400899"
+ "name": "R122-15699.25-1704710142"
}
}
diff --git a/afdo_tools/update_kernel_afdo.cfg b/afdo_tools/update_kernel_afdo.cfg
index a196a0af..821c9c1f 100644
--- a/afdo_tools/update_kernel_afdo.cfg
+++ b/afdo_tools/update_kernel_afdo.cfg
@@ -2,7 +2,7 @@
# All changes here won't affect kernel afdo update in branches.
# WARNING: Changes must be submitted to have effect.
-AMD_KVERS="4.14 5.4 5.10 5.15"
+AMD_KVERS="5.4 5.10 5.15"
ARM_KVERS="5.15"
AMD_METADATA_FILE="afdo_metadata/kernel_afdo.json"
ARM_METADATA_FILE="afdo_metadata/kernel_arm_afdo.json"
diff --git a/check_portable_toolchains.py b/check_portable_toolchains.py
new file mode 100755
index 00000000..3e3bce8d
--- /dev/null
+++ b/check_portable_toolchains.py
@@ -0,0 +1,224 @@
+#!/usr/bin/env python3
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Verify that a given portable toolchain SDK version can link and compile.
+
+Used to test that new portable toolchain SDKs work. See go/crostc-mage for
+when to use this script.
+"""
+
+import argparse
+import json
+import logging
+import os
+from pathlib import Path
+import re
+import subprocess
+import sys
+import tempfile
+from typing import List, Optional, Tuple
+
+
+ABIS = (
+ "aarch64-cros-linux-gnu",
+ "armv7a-cros-linux-gnueabihf",
+ "x86_64-cros-linux-gnu",
+)
+
+GS_PREFIX = "gs://staging-chromiumos-sdk"
+
+# Type alias to make clear when a string is a specially
+# formatted timestamp-version string.
+Version = str
+
+HELLO_WORLD = """#include <iostream>
+
+int main() {
+ std::cout << "Hello world!" << std::endl;
+}
+"""
+
+_COLOR_RED = "\033[91m"
+_COLOR_GREEN = "\033[92m"
+_COLOR_RESET = "\033[0m"
+
+
+def main() -> int:
+ logging.basicConfig(
+ format=">> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: "
+ "%(message)s",
+ level=logging.INFO,
+ )
+ args = parse_args()
+
+ version = args.version
+ if not version:
+ version = _autodetect_latest_llvm_next_sdk_version()
+
+ errors: List[Tuple[str, Exception]] = []
+ for abi in ABIS:
+ res = check_abi(args.bucket_prefix, abi, version)
+ if res:
+ errors.append((abi, res))
+ if errors:
+ logging.error(
+ "%sAt least one ABI failed to validate: %s%s",
+ _COLOR_RED,
+ ", ".join(abi for (abi, _) in errors),
+ _COLOR_RESET,
+ )
+ return 1
+ logging.info(
+ "%sAll ABIs successfully validated :)%s",
+ _COLOR_GREEN,
+ _COLOR_RESET,
+ )
+ return 0
+
+
+def check_abi(
+ bucket_prefix: str, abi: str, version: Version
+) -> Optional[Exception]:
+ """Verify that a given ABI target triplet is okay."""
+ year, month, _ = _split_version(version)
+ toolchain_name = f"{abi}-{version}.tar.xz"
+ artifact_path = f"{bucket_prefix}/{year}/{month}/{toolchain_name}"
+ try:
+ with tempfile.TemporaryDirectory() as tmpdir_str:
+ tmpdir = Path(tmpdir_str)
+
+ def run(*args, **kwargs):
+ return subprocess.run(*args, check=True, cwd=tmpdir, **kwargs)
+
+ logging.info(
+ "Downloading the toolchain %s into %s",
+ artifact_path,
+ tmpdir,
+ )
+ run(["gsutil.py", "cp", artifact_path, tmpdir])
+
+ logging.info("Extracting the toolchain %s", toolchain_name)
+ run(["tar", "-axf", tmpdir / toolchain_name])
+
+ logging.info("Checking if can find ld linker")
+ proc = run(
+ [f"bin/{abi}-clang", "-print-prog-name=ld"],
+ stdout=subprocess.PIPE,
+ encoding="utf-8",
+ )
+ linker_path = tmpdir / proc.stdout.strip()
+ logging.info("linker binary path: %s", linker_path)
+ if not linker_path.exists():
+ raise RuntimeError(f"{linker_path} does not exist")
+ if not os.access(linker_path, os.X_OK):
+ raise RuntimeError(f"{linker_path} is not executable")
+
+ logging.info("Building a simple c++ binary")
+ hello_world_file = tmpdir / "hello_world.cc"
+ hello_world_file.write_text(HELLO_WORLD, encoding="utf-8")
+ hello_world_output = tmpdir / "hello_world"
+ cmd = [
+ f"bin/{abi}-clang++",
+ "-o",
+ hello_world_output,
+ hello_world_file,
+ ]
+ run(cmd)
+ if not hello_world_output.exists():
+ raise RuntimeError(f"{hello_world_output} does not exist")
+ proc = run(
+ [f"bin/{abi}-clang++", "--version"],
+ stdout=subprocess.PIPE,
+ encoding="utf-8",
+ )
+ logging.info(
+ "%s-clang++ --version:\n%s",
+ abi,
+ "> " + "\n> ".join(proc.stdout.strip().split("\n")),
+ )
+
+ logging.info(
+ "%s[PASS] %s was validated%s", _COLOR_GREEN, abi, _COLOR_RESET
+ )
+ except Exception as e:
+ logging.exception(
+ "%s[FAIL] %s could not be validated%s",
+ _COLOR_RED,
+ abi,
+ _COLOR_RESET,
+ )
+ return e
+ return None
+
+
+def _autodetect_latest_llvm_next_sdk_version() -> str:
+ output = subprocess.run(
+ [
+ "bb",
+ "ls",
+ "-json",
+ "-n",
+ "1",
+ "-status",
+ "success",
+ "chromeos/infra/build-chromiumos-sdk-llvm-next",
+ ],
+ check=True,
+ stdin=subprocess.DEVNULL,
+ stdout=subprocess.PIPE,
+ ).stdout
+ builder_summary = json.loads(output)["summaryMarkdown"]
+ # Builder summary looks like:
+ # ```
+ # Built SDK version [2023.12.11.140022](https://link-redacted)
+ # Launched SDK uprev build: https://link-redacted
+ # ```
+ matches = re.findall(r"\[(\d+\.\d+\.\d+\.\d+)\]\(", builder_summary)
+ if len(matches) != 1:
+ raise ValueError(
+ f"Expected exactly 1 match of version in {builder_summary!r}."
+ f" Got {matches}. You can pass --version to disable auto-detection."
+ )
+ version = matches[0]
+ logging.info("Found latest llvm-next SDK version: %s", version)
+ return version
+
+
+def _split_version(version: Version) -> Tuple[str, str, str]:
+ y, m, rest = version.split(".", 2)
+ return y, m, rest
+
+
+def _verify_version(version: str) -> Version:
+ _split_version(version) # Raises a ValueError if invalid.
+ return version
+
+
+def parse_args() -> argparse.Namespace:
+ """Parse arguments."""
+ parser = argparse.ArgumentParser(
+ "check_portable_toolchains", description=__doc__
+ )
+ parser.add_argument(
+ "--version",
+ help="""
+ Version/Timestamp formatted as 'YYYY.MM.DD.HHMMSS'. e.g.
+ '2023.09.01.221258'. Generally this comes from a
+ 'build-chromiumos-sdk-llvm-next' run. Will autodetect if none is
+ specified.
+ """,
+ type=_verify_version,
+ )
+ parser.add_argument(
+ "-p",
+ "--bucket-prefix",
+ default=GS_PREFIX,
+ help="Top level gs:// path. (default: %(default)s)",
+ )
+ return parser.parse_args()
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/compiler_wrapper/README.md b/compiler_wrapper/README.md
index e858038e..7a05c818 100644
--- a/compiler_wrapper/README.md
+++ b/compiler_wrapper/README.md
@@ -1,104 +1,17 @@
-# Compiler wrapper
-
-See the comments on the top of main.go.
-Build is split into 2 steps via separate commands:
-- bundle: copies the sources and the `build.py` file into
- a folder.
-- build: builds the actual go binary, assuming it is executed
- from the folder created by `bundle.py`.
-
-This allows to copy the sources to a ChromeOS / Android
-package, including the build script, and then
-build from there without a dependency on toolchain-utils
-itself.
-
-## Testing Inside the Chroot
-
-To test updates to the wrapper locally:
-
-Run `install_compiler_wrapper.sh` to install the new wrapper in the chroot:
-```
-(chroot) ~/chromiumos/src/third_party/toolchain-utils/compiler_wrapper/install_compiler_wrapper.sh
-```
-
-Then perform the tests, e.g. build with the new compiler.
-
-
-## Updating the Wrapper for ChromeOS
-
-To update the wrapper for everyone, the new wrapper configuration must be copied
-into chromiumos-overlay, and new revisions of the gcc and llvm ebuilds must be
-created.
-
-Copy over sources and `build.py` to chromiumos-overlay:
-```
-(chroot) /mnt/host/source/src/third_party/chromiumos-overlay/sys-devel/llvm/files/update_compiler_wrapper.sh
-```
-
-Rename chromiumos-overlay/sys-devel/llvm/llvm-${VERSION}.ebuild to the next
-revision number. For example, if the current version is
-11.0_pre394483_p20200618-r2:
-```
-(chroot) cd ~/chromiumos/src/third_party/chromiumos-overlay
-(chroot) git mv llvm-11.0_pre394483_p20200618-r2.ebuild llvm-11.0_pre394483_p20200618-r3.ebuild
-```
-
-Rename chromiumos-overlay/sys-devel/gcc/gcc-${VERSION}.ebuild to the next
-revision number. For example, if the current version is 10.2.0-r3:
-```
-(chroot) cd ~/chromiumos/src/third_party/chromiumos-overlay
-(chroot) git mv sys-devel/gcc/gcc-10.2.0-r3.ebuild sys-devel/gcc/gcc-10.2.0-r4.ebuild
-```
-
-Commit those changes together with the changes made by
-`update_compiler_wrapper.sh`.
-
-The changes can then be reviewed and submitted through the normal process.
-
-
-## Paths
-
-`build.py` is called by these ebuilds:
-
-- third_party/chromiumos-overlay/sys-devel/llvm/llvm-*.ebuild
-- third_party/chromiumos-overlay/sys-devel/gcc/gcc-*.ebuild
-
-Generated wrappers are stored here:
-
-- Sysroot wrapper with ccache:
- `/usr/x86_64-pc-linux-gnu/<arch>/gcc-bin/10.2.0/sysroot_wrapper.hardened.ccache`
-- Sysroot wrapper without ccache:
- `/usr/x86_64-pc-linux-gnu/<arch>/gcc-bin/10.2.0/sysroot_wrapper.hardened.noccache`
-- Clang host wrapper:
- `/usr/bin/clang_host_wrapper`
-- Gcc host wrapper:
- `/usr/x86_64-pc-linux-gnu/gcc-bin/10.2.0/host_wrapper`
-
-## Using the compiler wrapper to crash arbitrary compilations
-
-When Clang crashes, its output can be extremely useful. Often, it will provide
-the user with a stack trace, and messages like:
-
-```
-clang-15: unable to execute command: Illegal instruction
-clang-15: note: diagnostic msg: /tmp/clang_crash_diagnostics/foo-5420d2.c
-clang-15: note: diagnostic msg: /tmp/clang_crash_diagnostics/foo-5420d2.sh
-```
-
-Where the artifacts at `/tmp/clang_crash_diagnostics/foo-*` are a full,
-self-contained reproducer of the inputs that caused the crash in question.
-Often, such a reproducer is very valuable to have even for cases where a crash
-_doesn't_ happen (e.g., maybe Clang is now emitting an error where it used to
-not do so, and we want to bisect upstream LLVM with that info). Normally,
-collecting and crafting such a reproducer is a multi-step process, and can be
-error-prone; compile commands may rely on env vars, they may be done within
-`chroot`s, they may rely on being executed in a particular directory, they may
-rely on intermediate state, etc.
-
-Because of the usefulness of these crash reports, our wrapper supports crashing
-Clang even on files that ordinarily don't cause Clang to crash. This requires
-rebuilding and redeploying the wrapper (comments on b/236736327 explain why).
-That said, this could be a valuable tool for devs interested in creating a
-self-contained reproducer without having to manually reproduce the environment
-in which a particular build was performed. See <crash_builds.go>
-for instructions for how to use this functionality.
+Copyright 2023 The ChromiumOS Authors
+Use of this source code is governed by a BSD-style license that can be
+found in the LICENSE file.
+
+Toolchain utils compiler wrapper sources.
+
+Build the wrapper:
+./build.py --config=<config name> --use_ccache=<bool> \
+ --use_llvm_next=<bool> --output_file=<file>
+
+Please note that there's a regular syncing operation between
+`chromiumos-overlay/sys-devel/llvm/files/compiler_wrapper` and
+`toolchain-utils/compiler_wrapper`. This sync is one way (from
+chromiumos-overlay to `toolchain-utils`). Syncing in this way helps the Android
+toolchain keep up-to-date with our wrapper easily, as they're a downstream
+consumer of it. For this reason, **please be sure to land all actual changes in
+chromeos-overlay**.
diff --git a/compiler_wrapper/android_config_test.go b/compiler_wrapper/android_config_test.go
index 6c62c35a..57669f8c 100644
--- a/compiler_wrapper/android_config_test.go
+++ b/compiler_wrapper/android_config_test.go
@@ -12,6 +12,23 @@ import (
const androidGoldenDir = "testdata/android_golden"
+func TestAndroidConfigDoesNotSpecifyCrashDir(t *testing.T) {
+ withTestContext(t, func(ctx *testContext) {
+ useLlvmNext := false
+ useCCache := false
+ cfg, err := getConfig("android", useCCache, useLlvmNext, "123")
+ if err != nil {
+ t.Fatal(err)
+ }
+ ctx.updateConfig(cfg)
+
+ cmd := ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(clangX86_64, mainCc)))
+ if err := verifyArgCount(cmd, 0, "-fcrash-diagnostics-dir=.*"); err != nil {
+ t.Error(err)
+ }
+ })
+}
+
func TestAndroidConfig(t *testing.T) {
withTestContext(t, func(ctx *testContext) {
useLlvmNext := false
diff --git a/compiler_wrapper/build.py b/compiler_wrapper/build.py
index 58822880..bea888db 100755
--- a/compiler_wrapper/build.py
+++ b/compiler_wrapper/build.py
@@ -1,12 +1,10 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Build script that builds a binary from a bundle."""
-
import argparse
import os.path
import re
@@ -25,11 +23,6 @@ def parse_args():
"--use_ccache", required=True, choices=["true", "false"]
)
parser.add_argument(
- "--version_suffix",
- help="A string appended to the computed version of the wrapper. This "
- "is appeneded directly without any delimiter.",
- )
- parser.add_argument(
"--use_llvm_next", required=True, choices=["true", "false"]
)
parser.add_argument("--output_file", required=True, type=str)
@@ -39,6 +32,24 @@ def parse_args():
help="If true, produce a static wrapper. Autodetects a good value if "
"unspecified.",
)
+
+ version_args = parser.add_mutually_exclusive_group()
+ version_args.add_argument(
+ "--version",
+ help="""
+ A string to pass to `go` that instructs the compiler wrapper about what
+ version to print. Automatically selects the current git commit SHA if
+ this is left unspecified.
+ """,
+ )
+ parser.add_argument(
+ "--version_suffix",
+ help="""
+ A string appended to the **computed** version of the wrapper. This is
+ appended directly without any delimiter. Incompatible with
+ `--version`.
+ """,
+ )
args = parser.parse_args()
if args.static is None:
@@ -98,7 +109,7 @@ def calc_go_args(args, version, build_dir, output_file):
def read_version(build_dir):
version_path = os.path.join(build_dir, "VERSION")
if os.path.exists(version_path):
- with open(version_path, "r") as r:
+ with open(version_path, "r", encoding="utf-8") as r:
return r.read()
last_commit_msg = subprocess.check_output(
@@ -114,9 +125,14 @@ def read_version(build_dir):
def main():
args = parse_args()
build_dir = os.path.dirname(__file__)
- version = read_version(build_dir)
- if args.version_suffix:
- version += args.version_suffix
+
+ if args.version:
+ version = args.version
+ else:
+ version = read_version(build_dir)
+ if args.version_suffix:
+ version += args.version_suffix
+
# Note: Go does not support using absolute package names.
# So we run go inside the directory of the the build file.
output_file = os.path.abspath(args.output_file)
diff --git a/compiler_wrapper/bundle.README b/compiler_wrapper/bundle.README
deleted file mode 100644
index 1ffaedd7..00000000
--- a/compiler_wrapper/bundle.README
+++ /dev/null
@@ -1,18 +0,0 @@
-Copyright 2019 The ChromiumOS Authors
-Use of this source code is governed by a BSD-style license that can be
-found in the LICENSE file.
-
-Toolchain utils compiler wrapper sources.
-
-Build the wrapper:
-./build --config=<config name> --use_ccache=<bool> \
- --use_llvm_next=<bool> --output_file=<file>
-
-ATTENTION:
-The files in this folder are generated. Do not modify manually!
-
-To update:
-- modify third_party/toolchain_utils/compiler_wrapper
-- run third_party/toolchain_utils/compiler_wrapper/bundle.py --output_dir=...
-
-Source: https://chromium-review.googlesource.com/q/{change_id}
diff --git a/compiler_wrapper/bundle.py b/compiler_wrapper/bundle.py
deleted file mode 100755
index 90386c8f..00000000
--- a/compiler_wrapper/bundle.py
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-# Copyright 2019 The ChromiumOS Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Build script that copies the go sources to a build destination."""
-
-
-import argparse
-import os.path
-import re
-import shutil
-import subprocess
-import sys
-
-
-def parse_args():
- parser = argparse.ArgumentParser()
- default_output_dir = os.path.normpath(
- os.path.join(
- os.path.dirname(os.path.realpath(__file__)),
- "../../chromiumos-overlay/sys-devel/llvm/files/compiler_wrapper",
- )
- )
- parser.add_argument(
- "--output_dir",
- default=default_output_dir,
- help="Output directory to place bundled files (default: %(default)s)",
- )
- parser.add_argument(
- "--create",
- action="store_true",
- help="Create output_dir if it does not already exist",
- )
- return parser.parse_args()
-
-
-def copy_files(input_dir, output_dir):
- for filename in os.listdir(input_dir):
- if (
- filename.endswith(".go") and not filename.endswith("_test.go")
- ) or filename in ("build.py", "go.mod"):
- shutil.copy(
- os.path.join(input_dir, filename),
- os.path.join(output_dir, filename),
- )
-
-
-def read_change_id(input_dir):
- last_commit_msg = subprocess.check_output(
- ["git", "-C", input_dir, "log", "-1", "--pretty=%B"], encoding="utf-8"
- )
- # Use last found change id to support reverts as well.
- change_ids = re.findall(r"Change-Id: (\w+)", last_commit_msg)
- if not change_ids:
- sys.exit("Couldn't find Change-Id in last commit message.")
- return change_ids[-1]
-
-
-def write_readme(input_dir, output_dir, change_id):
- with open(
- os.path.join(input_dir, "bundle.README"), "r", encoding="utf-8"
- ) as r:
- with open(
- os.path.join(output_dir, "README"), "w", encoding="utf-8"
- ) as w:
- content = r.read()
- w.write(content.format(change_id=change_id))
-
-
-def write_version(output_dir, change_id):
- with open(os.path.join(output_dir, "VERSION"), "w", encoding="utf-8") as w:
- w.write(change_id)
-
-
-def main():
- args = parse_args()
- input_dir = os.path.dirname(__file__)
- change_id = read_change_id(input_dir)
- if not args.create:
- assert os.path.exists(
- args.output_dir
- ), f"Specified output directory ({args.output_dir}) does not exist"
- shutil.rmtree(args.output_dir, ignore_errors=True)
- os.makedirs(args.output_dir)
- copy_files(input_dir, args.output_dir)
- write_readme(input_dir, args.output_dir, change_id)
- write_version(args.output_dir, change_id)
-
-
-if __name__ == "__main__":
- main()
diff --git a/compiler_wrapper/ccache_flag.go b/compiler_wrapper/ccache_flag.go
index 0371f10a..ffa74911 100644
--- a/compiler_wrapper/ccache_flag.go
+++ b/compiler_wrapper/ccache_flag.go
@@ -15,7 +15,7 @@ func processCCacheFlag(builder *commandBuilder) {
// that share compiler flags (like x86 boards) to share caches.
const ccacheDir = "/var/cache/distfiles/ccache"
- useCCache := true
+ useCCache := builder.cfg.useCCache
builder.transformArgs(func(arg builderArg) string {
if arg.value == "-noccache" {
useCCache = false
@@ -24,6 +24,15 @@ func processCCacheFlag(builder *commandBuilder) {
return arg.value
})
+ if force, present := builder.env.getenv("COMPILER_WRAPPER_FORCE_CCACHE"); present {
+ switch force {
+ case "0":
+ useCCache = false
+ case "1":
+ useCCache = true
+ }
+ }
+
// Disable ccache during portage's src_configure phase. Using ccache here is generally a
// waste of time, since these files are very small. Experimentally, this speeds up
// configuring by ~13%.
@@ -31,7 +40,7 @@ func processCCacheFlag(builder *commandBuilder) {
useCCache = false
}
- if builder.cfg.useCCache && useCCache {
+ if useCCache {
// Note: we used to also set CCACHE_BASEDIR but don't do it
// anymore for reasons outlined in crrev.com/c/2103170.
if _, present := builder.env.getenv("CCACHE_DISABLE"); present {
diff --git a/compiler_wrapper/ccache_flag_test.go b/compiler_wrapper/ccache_flag_test.go
index 330d1a1c..087d97be 100644
--- a/compiler_wrapper/ccache_flag_test.go
+++ b/compiler_wrapper/ccache_flag_test.go
@@ -32,8 +32,35 @@ func TestNotCallCCacheGivenConfig(t *testing.T) {
})
}
-func TestNotCallCCacheGivenConfigAndNoCCacheArg(t *testing.T) {
+func TestCallCCacheGivenEnviron(t *testing.T) {
withCCacheEnabledTestContext(t, func(ctx *testContext) {
+ ctx.env = append(ctx.env, "COMPILER_WRAPPER_FORCE_CCACHE=1")
+
+ cmd := ctx.must(callCompiler(ctx, ctx.cfg,
+ ctx.newCommand(gccX86_64, mainCc)))
+ if err := verifyPath(cmd, "/usr/bin/ccache"); err != nil {
+ t.Error(err)
+ }
+ if err := verifyArgOrder(cmd, gccX86_64+".real", mainCc); err != nil {
+ t.Error(err)
+ }
+ })
+}
+
+func TestNotCallCCacheGivenEnviron(t *testing.T) {
+ withCCacheEnabledTestContext(t, func(ctx *testContext) {
+ ctx.env = append(ctx.env, "COMPILER_WRAPPER_FORCE_CCACHE=0")
+
+ cmd := ctx.must(callCompiler(ctx, ctx.cfg,
+ ctx.newCommand(gccX86_64, mainCc)))
+ if err := verifyPath(cmd, gccX86_64+".real"); err != nil {
+ t.Error(err)
+ }
+ })
+}
+
+func TestNotCallCCacheGivenConfigAndNoCCacheArg(t *testing.T) {
+ withTestContext(t, func(ctx *testContext) {
cmd := ctx.must(callCompiler(ctx, ctx.cfg,
ctx.newCommand(gccX86_64, "-noccache", mainCc)))
if err := verifyPath(cmd, gccX86_64+".real"); err != nil {
diff --git a/compiler_wrapper/clang_flags.go b/compiler_wrapper/clang_flags.go
index a38e597a..80e5174a 100644
--- a/compiler_wrapper/clang_flags.go
+++ b/compiler_wrapper/clang_flags.go
@@ -36,21 +36,9 @@ func processClangFlags(builder *commandBuilder) error {
clangDir = filepath.Dir(clangDir)
}
- var languageOverriden = false
- for _, arg := range builder.args {
- // Reading stdin with "-" requires either -E (which defaults to C) or -x
- if arg.value == "-x" || arg.value == "-" {
- languageOverriden = true
- }
- }
-
clangBasename := "clang"
if strings.HasSuffix(builder.target.compiler, "++") {
clangBasename = "clang++"
- // If a package wants to specify the language then it can set the standard too.
- if !languageOverriden {
- builder.addPreUserArgs(builder.cfg.cppFlags...)
- }
}
// Unsupported flags to remove from the clang command line.
diff --git a/compiler_wrapper/clang_flags_test.go b/compiler_wrapper/clang_flags_test.go
index 8b3f5a24..cce79be2 100644
--- a/compiler_wrapper/clang_flags_test.go
+++ b/compiler_wrapper/clang_flags_test.go
@@ -33,36 +33,6 @@ func TestClangBasename(t *testing.T) {
})
}
-func TestAppendCppFlags(t *testing.T) {
- withTestContext(t, func(ctx *testContext) {
- ctx.cfg.cppFlags = append(ctx.cfg.cppFlags, "cppOnlyFlag")
- // C++ only flags are disabled on clang.
- clangCmd := ctx.must(callCompiler(ctx, ctx.cfg,
- ctx.newCommand("./x86_64-cros-linux-gnu-clang", mainCc)))
- if err := verifyArgCount(clangCmd, 0, "cppOnlyFlag"); err != nil {
- t.Error(err)
- }
- // C++ only flags are enabled on clang++.
- clangPlusPlusCmd := ctx.must(callCompiler(ctx, ctx.cfg,
- ctx.newCommand("./x86_64-cros-linux-gnu-clang++", mainCc)))
- if err := verifyArgCount(clangPlusPlusCmd, 1, "cppOnlyFlag"); err != nil {
- t.Error(err)
- }
- // C++ only flags are disabled with -x.
- clangPlusPlusWithXCmd := ctx.must(callCompiler(ctx, ctx.cfg,
- ctx.newCommand("./x86_64-cros-linux-gnu-clang++", "-x", "c", mainCc)))
- if err := verifyArgCount(clangPlusPlusWithXCmd, 0, "cppOnlyFlag"); err != nil {
- t.Error(err)
- }
- // C++ only flags are disabled with " - " .
- clangPlusPlusWithStdin := ctx.must(callCompiler(ctx, ctx.cfg,
- ctx.newCommand("./x86_64-cros-linux-gnu-clang++", "-", mainCc)))
- if err := verifyArgCount(clangPlusPlusWithStdin, 0, "cppOnlyFlag"); err != nil {
- t.Error(err)
- }
- })
-}
-
func TestClangPathGivenClangEnv(t *testing.T) {
withTestContext(t, func(ctx *testContext) {
ctx.env = []string{"CLANG=/a/b/clang"}
diff --git a/compiler_wrapper/clang_tidy_flag_test.go b/compiler_wrapper/clang_tidy_flag_test.go
index b32d0d63..00669cf9 100644
--- a/compiler_wrapper/clang_tidy_flag_test.go
+++ b/compiler_wrapper/clang_tidy_flag_test.go
@@ -9,6 +9,7 @@ import (
"fmt"
"io"
"path"
+ "path/filepath"
"strings"
"testing"
)
@@ -388,6 +389,7 @@ func TestClangTidyFlagsAreFilteredFromGccInvocations(t *testing.T) {
func TestTriciumReportsClangTidyCrashesGracefully(t *testing.T) {
withClangTidyTriciumTestContext(t, func(ctx *testContext) {
+ crashArtifactsDir := filepath.Join(ctx.setArbitraryClangArtifactsDir(), clangCrashArtifactsSubdir)
ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
switch ctx.cmdCount {
case 1:
@@ -425,7 +427,7 @@ func TestTriciumReportsClangTidyCrashesGracefully(t *testing.T) {
t.Errorf("got oArg=%q; wanted -o", oArg)
}
- wantPrefix := path.Join(ctx.cfg.crashArtifactsDir, "clang-tidy")
+ wantPrefix := path.Join(crashArtifactsDir, "clang-tidy")
if !strings.HasPrefix(outFileArg, wantPrefix) {
t.Errorf("got out file %q; wanted one starting with %q", outFileArg, wantPrefix)
}
diff --git a/compiler_wrapper/compiler_wrapper.go b/compiler_wrapper/compiler_wrapper.go
index bb144881..22109e3c 100644
--- a/compiler_wrapper/compiler_wrapper.go
+++ b/compiler_wrapper/compiler_wrapper.go
@@ -16,6 +16,11 @@ import (
"time"
)
+const (
+ clangCrashArtifactsSubdir = "toolchain/clang_crash_diagnostics"
+ crosArtifactsEnvVar = "CROS_ARTIFACTS_TMP_DIR"
+)
+
func callCompiler(env env, cfg *config, inputCmd *command) int {
var compilerErr error
@@ -109,8 +114,19 @@ func runAndroidClangTidy(env env, cmd *command) error {
return nil
}
-func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int, err error) {
+func detectCrashArtifactsDir(env env, cfg *config) string {
+ if cfg.isAndroidWrapper {
+ return ""
+ }
+ tmpdir, ok := env.getenv(crosArtifactsEnvVar)
+ if !ok {
+ return ""
+ }
+ return filepath.Join(tmpdir, clangCrashArtifactsSubdir)
+}
+
+func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int, err error) {
if err := checkUnsupportedFlags(inputCmd); err != nil {
return 0, err
}
@@ -122,6 +138,7 @@ func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int
processPrintCmdlineFlag(mainBuilder)
env = mainBuilder.env
var compilerCmd *command
+ disableWerrorConfig := processForceDisableWerrorFlag(env, cfg, mainBuilder)
clangSyntax := processClangSyntaxFlag(mainBuilder)
rusageEnabled := isRusageEnabled(env)
@@ -153,8 +170,9 @@ func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int
} else {
_, tidyFlags, tidyMode := processClangTidyFlags(mainBuilder)
cSrcFile, iwyuFlags, iwyuMode := processIWYUFlags(mainBuilder)
+ crashArtifactsDir := detectCrashArtifactsDir(env, cfg)
if mainBuilder.target.compilerType == clangType {
- err := prepareClangCommand(mainBuilder)
+ err := prepareClangCommand(crashArtifactsDir, mainBuilder)
if err != nil {
return 0, err
}
@@ -170,7 +188,7 @@ func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int
switch tidyMode {
case tidyModeTricium:
- err = runClangTidyForTricium(env, clangCmdWithoutRemoteBuildAndCCache, cSrcFile, tidyFlags, cfg.crashArtifactsDir)
+ err = runClangTidyForTricium(env, clangCmdWithoutRemoteBuildAndCCache, cSrcFile, tidyFlags, crashArtifactsDir)
case tidyModeAll:
err = runClangTidy(env, clangCmdWithoutRemoteBuildAndCCache, cSrcFile, tidyFlags)
default:
@@ -202,7 +220,7 @@ func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int
} else {
if clangSyntax {
allowCCache = false
- _, clangCmd, err := calcClangCommand(allowCCache, mainBuilder.clone())
+ _, clangCmd, err := calcClangCommand(crashArtifactsDir, allowCCache, mainBuilder.clone())
if err != nil {
return 0, err
}
@@ -232,11 +250,11 @@ func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int
compilerCmd = removeRusageFromCommand(compilerCmd)
}
- if shouldForceDisableWerror(env, cfg, mainBuilder.target.compilerType) {
+ if disableWerrorConfig.enabled {
if bisectStage != "" {
return 0, newUserErrorf("BISECT_STAGE is meaningless with FORCE_DISABLE_WERROR")
}
- return doubleBuildWithWNoError(env, cfg, compilerCmd)
+ return doubleBuildWithWNoError(env, cfg, compilerCmd, disableWerrorConfig)
}
if shouldCompileWithFallback(env) {
if rusageEnabled {
@@ -332,37 +350,35 @@ func callCompilerInternal(env env, cfg *config, inputCmd *command) (exitCode int
}
}
-// TODO(b/288411201): Add -D_FORTIFY_SOURCE=2 to args if -D_FORITFY_SOURCE=3 is not present.
-// This makes migrating to -D_FORTIFY_SOURCE=3 _way_ easier, since the wrapper's implicit
-// -D_FORTIFY_SOURCE=2 can be ignored.
-func addPreUserFortifyFlag(builder *commandBuilder) {
- for _, arg := range builder.args {
- if arg.value == "-D_FORTIFY_SOURCE=3" {
- return
+func hasFlag(flag string, flagList ...string) bool {
+ for _, flagVal := range flagList {
+ if strings.Contains(flagVal, flag) {
+ return true
}
}
-
- builder.addPreUserArgs("-D_FORTIFY_SOURCE=2")
+ return false
}
-func prepareClangCommand(builder *commandBuilder) (err error) {
+func prepareClangCommand(crashArtifactsDir string, builder *commandBuilder) (err error) {
if !builder.cfg.isHostWrapper {
processSysrootFlag(builder)
}
- if builder.cfg.isHardened {
- addPreUserFortifyFlag(builder)
- }
builder.addPreUserArgs(builder.cfg.clangFlags...)
- if builder.cfg.crashArtifactsDir != "" {
- builder.addPreUserArgs("-fcrash-diagnostics-dir=" + builder.cfg.crashArtifactsDir)
+
+ var crashDiagFlagName = "-fcrash-diagnostics-dir"
+ if crashArtifactsDir != "" &&
+ !hasFlag(crashDiagFlagName, builder.cfg.clangFlags...) &&
+ !hasFlag(crashDiagFlagName, builder.cfg.clangPostFlags...) {
+ builder.addPreUserArgs(crashDiagFlagName + "=" + crashArtifactsDir)
}
+
builder.addPostUserArgs(builder.cfg.clangPostFlags...)
calcCommonPreUserArgs(builder)
return processClangFlags(builder)
}
-func calcClangCommand(allowCCache bool, builder *commandBuilder) (bool, *command, error) {
- err := prepareClangCommand(builder)
+func calcClangCommand(crashArtifactsDir string, allowCCache bool, builder *commandBuilder) (bool, *command, error) {
+ err := prepareClangCommand(crashArtifactsDir, builder)
if err != nil {
return false, nil, err
}
@@ -377,19 +393,13 @@ func calcGccCommand(enableRusage bool, builder *commandBuilder) (bool, *command,
if !builder.cfg.isHostWrapper {
processSysrootFlag(builder)
}
- if builder.cfg.isHardened {
- addPreUserFortifyFlag(builder)
- }
builder.addPreUserArgs(builder.cfg.gccFlags...)
calcCommonPreUserArgs(builder)
processGccFlags(builder)
- remoteBuildUsed := false
- if !builder.cfg.isHostWrapper {
- var err error
- if remoteBuildUsed, err = processRemoteBuildAndCCacheFlags(!enableRusage, builder); err != nil {
- return remoteBuildUsed, nil, err
- }
+ remoteBuildUsed, err := processRemoteBuildAndCCacheFlags(!enableRusage, builder)
+ if err != nil {
+ return remoteBuildUsed, nil, err
}
return remoteBuildUsed, builder.build(), nil
}
@@ -406,12 +416,9 @@ func calcCommonPreUserArgs(builder *commandBuilder) {
}
func processRemoteBuildAndCCacheFlags(allowCCache bool, builder *commandBuilder) (remoteBuildUsed bool, err error) {
- remoteBuildUsed = false
- if !builder.cfg.isHostWrapper {
- remoteBuildUsed, err = processRemoteBuildFlags(builder)
- if err != nil {
- return remoteBuildUsed, err
- }
+ remoteBuildUsed, err = processRemoteBuildFlags(builder)
+ if err != nil {
+ return remoteBuildUsed, err
}
if !remoteBuildUsed && allowCCache {
processCCacheFlag(builder)
diff --git a/compiler_wrapper/compiler_wrapper_test.go b/compiler_wrapper/compiler_wrapper_test.go
index a560c9ca..2cace6e9 100644
--- a/compiler_wrapper/compiler_wrapper_test.go
+++ b/compiler_wrapper/compiler_wrapper_test.go
@@ -136,7 +136,7 @@ func TestLogRusageAndForceDisableWError(t *testing.T) {
ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
switch ctx.cmdCount {
case 1:
- io.WriteString(stderr, "-Werror originalerror")
+ io.WriteString(stderr, arbitraryWerrorStderr)
return newExitCodeError(1)
case 2:
return nil
@@ -252,3 +252,47 @@ func TestCalculateAndroidWrapperPath(t *testing.T) {
}
}
}
+
+// If "crash-diagnostics-dir" flag is already provided, only use that flag and don't add a dupe
+func TestCrashDiagPreFlag(t *testing.T) {
+ withTestContext(t, func(ctx *testContext) {
+ ctx.cfg.clangFlags = []string{"-fcrash-diagnostics-dir=/build/something/foo"}
+ ctx.env = []string{
+ "CROS_ARTIFACTS_TMP_DIR=/tmp/foo",
+ }
+ cmd := ctx.must(callCompiler(ctx, ctx.cfg,
+ ctx.newCommand(clangX86_64, mainCc)))
+ if err := verifyArgCount(cmd, 1, "-fcrash-diagnostics-dir=/build/something/foo"); err != nil {
+ t.Error(err)
+ }
+ })
+}
+
+// If "crash-diagnostics-dir" flag is already provided, only use that flag and don't add a dupe
+func TestCrashDiagPostFlag(t *testing.T) {
+ withTestContext(t, func(ctx *testContext) {
+ ctx.cfg.clangPostFlags = []string{"-fcrash-diagnostics-dir=/build/something/foo"}
+ ctx.env = []string{
+ "CROS_ARTIFACTS_TMP_DIR=/tmp/foo",
+ }
+ cmd := ctx.must(callCompiler(ctx, ctx.cfg,
+ ctx.newCommand(clangX86_64, mainCc)))
+ if err := verifyArgCount(cmd, 1, "-fcrash-diagnostics-dir=/build/something/foo"); err != nil {
+ t.Error(err)
+ }
+ })
+}
+
+// If "crash-diagnostics-dir" flag is not provided, add one in
+func TestCrashDiagDefault(t *testing.T) {
+ withTestContext(t, func(ctx *testContext) {
+ ctx.env = []string{
+ "CROS_ARTIFACTS_TMP_DIR=/tmp/foo",
+ }
+ cmd := ctx.must(callCompiler(ctx, ctx.cfg,
+ ctx.newCommand(clangX86_64, mainCc)))
+ if err := verifyArgCount(cmd, 1, "-fcrash-diagnostics-dir=/tmp/foo/toolchain/clang_crash_diagnostics"); err != nil {
+ t.Error(err)
+ }
+ })
+}
diff --git a/compiler_wrapper/config.go b/compiler_wrapper/config.go
index bcf73d79..5bfc8009 100644
--- a/compiler_wrapper/config.go
+++ b/compiler_wrapper/config.go
@@ -25,18 +25,13 @@ type config struct {
// Flags to add to clang only, AFTER user flags (cannot be overridden
// by the user).
clangPostFlags []string
- // Flags to be used only for C++ (not used to compile C code)
- cppFlags []string
// Toolchain root path relative to the wrapper binary.
clangRootRelPath string
gccRootRelPath string
// Directory to store errors that were prevented with -Wno-error.
newWarningsDir string
- // Directory to store crash artifacts in.
- crashArtifactsDir string
// Version. Only exposed via -print-config.
- version string
- isHardened bool
+ version string
}
// Version can be set via a linker flag.
@@ -128,33 +123,21 @@ func crosCommonClangFlags() []string {
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
- }
-}
-
-func crosCommonCppFlags() []string {
- return []string{
- "-std=gnu++14",
+ // TODO(b/315504245): Temporarily prevents new mangling rules from taking effect.
+ "-fclang-abi-compat=17",
}
}
func crosCommonClangPostFlags() []string {
- // Temporarily disable Wdeprecated-copy. b/191479033
- // Temporarily disabled Wno-array-parameter. b/262076232
- return []string{
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
- }
+ // Flags added to the _end_ of every build command. If a flag is added here, file a bug at
+ // go/crostc-bug to clean it up. Use of postflags is discouraged, since it prevents users
+ // from determining their own preferences for warnings/etc.
+ return []string{}
}
// Full hardening.
// Temporarily disable function splitting because of chromium:434751.
var crosHardenedConfig = config{
- isHardened: true,
clangRootRelPath: "../..",
gccRootRelPath: "../../../../..",
// Pass "-fcommon" till the packages are fixed to work with new clang/gcc
@@ -162,6 +145,7 @@ var crosHardenedConfig = config{
commonFlags: []string{
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
},
gccFlags: []string{
@@ -178,13 +162,10 @@ var crosHardenedConfig = config{
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
),
- clangPostFlags: crosCommonClangPostFlags(),
- cppFlags: crosCommonCppFlags(),
- newWarningsDir: "fatal_clang_warnings",
- crashArtifactsDir: "/tmp/clang_crash_diagnostics",
+ clangPostFlags: crosCommonClangPostFlags(),
+ newWarningsDir: "fatal_clang_warnings",
}
// Flags to be added to non-hardened toolchain.
@@ -203,10 +184,8 @@ var crosNonHardenedConfig = config{
crosCommonClangFlags(),
"-Wno-section",
),
- clangPostFlags: crosCommonClangPostFlags(),
- cppFlags: crosCommonCppFlags(),
- newWarningsDir: "fatal_clang_warnings",
- crashArtifactsDir: "/tmp/clang_crash_diagnostics",
+ clangPostFlags: crosCommonClangPostFlags(),
+ newWarningsDir: "fatal_clang_warnings",
}
// Flags to be added to host toolchain.
@@ -230,25 +209,20 @@ var crosHostConfig = config{
crosCommonClangFlags(),
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
),
// Temporarily disable Wdeprecated-copy. b/191479033
- clangPostFlags: crosCommonClangPostFlags(),
- cppFlags: crosCommonCppFlags(),
- newWarningsDir: "fatal_clang_warnings",
- crashArtifactsDir: "/tmp/clang_crash_diagnostics",
+ clangPostFlags: crosCommonClangPostFlags(),
+ newWarningsDir: "fatal_clang_warnings",
}
var androidConfig = config{
- isHostWrapper: false,
- isAndroidWrapper: true,
- gccRootRelPath: "./",
- clangRootRelPath: "./",
- commonFlags: []string{},
- gccFlags: []string{},
- clangFlags: []string{},
- clangPostFlags: []string{},
- cppFlags: []string{},
- newWarningsDir: "",
- crashArtifactsDir: "",
+ isHostWrapper: false,
+ isAndroidWrapper: true,
+ gccRootRelPath: "./",
+ clangRootRelPath: "./",
+ commonFlags: []string{},
+ gccFlags: []string{},
+ clangFlags: []string{},
+ clangPostFlags: []string{},
+ newWarningsDir: "",
}
diff --git a/compiler_wrapper/config_test.go b/compiler_wrapper/config_test.go
index 47432856..49487d8e 100644
--- a/compiler_wrapper/config_test.go
+++ b/compiler_wrapper/config_test.go
@@ -118,7 +118,12 @@ func TestRealConfigWithConfigNameFlag(t *testing.T) {
}
func isSysrootHardened(cfg *config) bool {
- return cfg.isHardened
+ for _, arg := range cfg.commonFlags {
+ if arg == "-D_FORTIFY_SOURCE=3" {
+ return true
+ }
+ }
+ return false
}
func resetGlobals() {
diff --git a/compiler_wrapper/crash_dump_test.go b/compiler_wrapper/crash_dump_test.go
new file mode 100644
index 00000000..f6bacb60
--- /dev/null
+++ b/compiler_wrapper/crash_dump_test.go
@@ -0,0 +1,42 @@
+// Copyright 2024 The ChromiumOS Authors
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+package main
+
+import (
+ "path/filepath"
+ "testing"
+)
+
+func TestHardenedConfigDoesNotSpecifyCrashDirWhenNotInEnv(t *testing.T) {
+ withTestContext(t, func(ctx *testContext) {
+ cmd := ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(clangX86_64, mainCc)))
+ if err := verifyArgCount(cmd, 0, "-fcrash-diagnostics-dir=.*"); err != nil {
+ t.Error(err)
+ }
+ })
+}
+
+func TestHardenedConfigSpecifiesCrashDirWhenInEnv(t *testing.T) {
+ withTestContext(t, func(ctx *testContext) {
+ artifactsDir := ctx.setArbitraryClangArtifactsDir()
+ crashDir := filepath.Join(artifactsDir, clangCrashArtifactsSubdir)
+
+ cmd := ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(clangX86_64, mainCc)))
+ if err := verifyArgCount(cmd, 1, "-fcrash-diagnostics-dir="+crashDir); err != nil {
+ t.Error(err)
+ }
+ })
+}
+
+func TestHardenedConfigDoesNotSpecifyCrashDirForGCC(t *testing.T) {
+ withTestContext(t, func(ctx *testContext) {
+ ctx.setArbitraryClangArtifactsDir()
+
+ cmd := ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(gccX86_64, mainCc)))
+ if err := verifyArgCount(cmd, 0, "-fcrash-diagnostics-dir=.*"); err != nil {
+ t.Error(err)
+ }
+ })
+}
diff --git a/compiler_wrapper/cros_hardened_config_test.go b/compiler_wrapper/cros_hardened_config_test.go
index 80a261c8..361ba707 100644
--- a/compiler_wrapper/cros_hardened_config_test.go
+++ b/compiler_wrapper/cros_hardened_config_test.go
@@ -204,7 +204,7 @@ func createForceDisableWErrorGoldenInputs() goldenFile {
Env: []string{"FORCE_DISABLE_WERROR=1"},
Cmds: []commandResult{
{
- Stderr: "-Werror originalerror",
+ Stderr: arbitraryWerrorStderr,
ExitCode: 1,
},
okResult,
@@ -215,7 +215,7 @@ func createForceDisableWErrorGoldenInputs() goldenFile {
Env: []string{"FORCE_DISABLE_WERROR=1"},
Cmds: []commandResult{
{
- Stderr: "-Werror originalerror",
+ Stderr: arbitraryWerrorStderr,
ExitCode: 1,
},
errorResult,
diff --git a/compiler_wrapper/disable_werror_flag.go b/compiler_wrapper/disable_werror_flag.go
index 91bc5845..b6dd844f 100644
--- a/compiler_wrapper/disable_werror_flag.go
+++ b/compiler_wrapper/disable_werror_flag.go
@@ -12,6 +12,7 @@ import (
"io/ioutil"
"os"
"path"
+ "regexp"
"strconv"
"strings"
)
@@ -22,31 +23,81 @@ func getForceDisableWerrorDir(env env, cfg *config) string {
return path.Join(getCompilerArtifactsDir(env), cfg.newWarningsDir)
}
-func shouldForceDisableWerror(env env, cfg *config, ty compilerType) bool {
+type forceDisableWerrorConfig struct {
+ // If reportToStdout is true, we'll write -Werror reports to stdout. Otherwise, they'll be
+ // written to reportDir. If reportDir is empty, it will be determined via
+ // `getForceDisableWerrorDir`.
+ //
+ // Neither of these have specified values if `enabled == false`.
+ reportDir string
+ reportToStdout bool
+
+ // If true, `-Werror` reporting should be used.
+ enabled bool
+}
+
+func processForceDisableWerrorFlag(env env, cfg *config, builder *commandBuilder) forceDisableWerrorConfig {
if cfg.isAndroidWrapper {
- return cfg.useLlvmNext
+ return forceDisableWerrorConfig{
+ reportToStdout: true,
+ enabled: cfg.useLlvmNext,
+ }
}
- // We only want this functionality for clang.
- if ty != clangType {
- return false
+ // CrOS supports two modes for enabling this flag:
+ // 1 (preferred). A CFLAG that specifies the directory to write reports to. e.g.,
+ // `-D_CROSTC_FORCE_DISABLE_WERROR=/path/to/directory`. This flag will be removed from the
+ // command before the compiler is invoked. If multiple of these are passed, the last one
+ // wins, but all are removed from the build command.
+ // 2 (deprecated). An environment variable, FORCE_DISABLE_WERROR, set to any nonempty value.
+ // In this case, the wrapper will write to either somewhere under
+ // ${CROS_ARTIFACTS_TMP_DIR}, or to /tmp.
+ const cflagPrefix = "-D_CROSTC_FORCE_DISABLE_WERROR="
+
+ argDir := ""
+ sawArg := false
+ builder.transformArgs(func(arg builderArg) string {
+ value := arg.value
+ if !strings.HasPrefix(value, cflagPrefix) {
+ return value
+ }
+ argDir = value[len(cflagPrefix):]
+ sawArg = true
+ return ""
+ })
+
+ // CrOS only wants this functionality to apply to clang, though flags should also be removed
+ // for GCC.
+ if builder.target.compilerType != clangType {
+ return forceDisableWerrorConfig{enabled: false}
}
- value, _ := env.getenv("FORCE_DISABLE_WERROR")
- return value != ""
+
+ if sawArg {
+ return forceDisableWerrorConfig{
+ reportDir: argDir,
+ // Skip this when in src_configure: some build systems ignore CFLAGS
+ // modifications after configure, so this flag must be specified before
+ // src_configure, but we only want the flag to apply to actual builds.
+ enabled: !isInConfigureStage(env),
+ }
+ }
+
+ envValue, _ := env.getenv("FORCE_DISABLE_WERROR")
+ return forceDisableWerrorConfig{enabled: envValue != ""}
}
-func disableWerrorFlags(originalArgs []string) []string {
- extraArgs := []string{"-Wno-error"}
+func disableWerrorFlags(originalArgs, extraFlags []string) []string {
+ allExtraFlags := append([]string{}, extraFlags...)
newArgs := make([]string, 0, len(originalArgs)+numWErrorEstimate)
for _, flag := range originalArgs {
if strings.HasPrefix(flag, "-Werror=") {
- extraArgs = append(extraArgs, strings.Replace(flag, "-Werror", "-Wno-error", 1))
+ allExtraFlags = append(allExtraFlags, strings.Replace(flag, "-Werror", "-Wno-error", 1))
}
if !strings.Contains(flag, "-warnings-as-errors") {
newArgs = append(newArgs, flag)
}
}
- return append(newArgs, extraArgs...)
+ return append(newArgs, allExtraFlags...)
}
func isLikelyAConfTest(cfg *config, cmd *command) bool {
@@ -64,7 +115,37 @@ func isLikelyAConfTest(cfg *config, cmd *command) bool {
return false
}
-func doubleBuildWithWNoError(env env, cfg *config, originalCmd *command) (exitCode int, err error) {
+func getWnoErrorFlags(stdout, stderr []byte) []string {
+ needWnoError := false
+ extraFlags := []string{}
+ for _, submatches := range regexp.MustCompile(`error:.* \[(-W[^\]]+)\]`).FindAllSubmatch(stderr, -1) {
+ bracketedMatch := submatches[1]
+
+ // Some warnings are promoted to errors by -Werror. These contain `-Werror` in the
+ // brackets specifying the warning name. A broad, follow-up `-Wno-error` should
+ // disable those.
+ //
+ // _Others_ are implicitly already errors, and will not be disabled by `-Wno-error`.
+ // These do not have `-Wno-error` in their brackets. These need to explicitly have
+ // `-Wno-error=${warning_name}`. See b/325463152 for an example.
+ if bytes.HasPrefix(bracketedMatch, []byte("-Werror,")) || bytes.HasSuffix(bracketedMatch, []byte(",-Werror")) {
+ needWnoError = true
+ } else {
+ // In this case, the entire bracketed match is the warning flag. Trim the
+ // first two chars off to account for the `-W` matched in the regex.
+ warningName := string(bracketedMatch[2:])
+ extraFlags = append(extraFlags, "-Wno-error="+warningName)
+ }
+ }
+ needWnoError = needWnoError || bytes.Contains(stdout, []byte("warnings-as-errors")) || bytes.Contains(stdout, []byte("clang-diagnostic-"))
+
+ if len(extraFlags) == 0 && !needWnoError {
+ return nil
+ }
+ return append(extraFlags, "-Wno-error")
+}
+
+func doubleBuildWithWNoError(env env, cfg *config, originalCmd *command, werrorConfig forceDisableWerrorConfig) (exitCode int, err error) {
originalStdoutBuffer := &bytes.Buffer{}
originalStderrBuffer := &bytes.Buffer{}
// TODO: This is a bug in the old wrapper that it drops the ccache path
@@ -90,13 +171,11 @@ func doubleBuildWithWNoError(env env, cfg *config, originalCmd *command) (exitCo
// The only way we can do anything useful is if it looks like the failure
// was -Werror-related.
- originalStdoutBufferBytes := originalStdoutBuffer.Bytes()
- shouldRetry := originalExitCode != 0 &&
- !isLikelyAConfTest(cfg, originalCmd) &&
- (bytes.Contains(originalStderrBuffer.Bytes(), []byte("-Werror")) ||
- bytes.Contains(originalStdoutBufferBytes, []byte("warnings-as-errors")) ||
- bytes.Contains(originalStdoutBufferBytes, []byte("clang-diagnostic-")))
- if !shouldRetry {
+ retryWithExtraFlags := []string{}
+ if originalExitCode != 0 && !isLikelyAConfTest(cfg, originalCmd) {
+ retryWithExtraFlags = getWnoErrorFlags(originalStdoutBuffer.Bytes(), originalStderrBuffer.Bytes())
+ }
+ if len(retryWithExtraFlags) == 0 {
if err := commitOriginalRusage(originalExitCode); err != nil {
return 0, fmt.Errorf("commiting rusage: %v", err)
}
@@ -109,7 +188,7 @@ func doubleBuildWithWNoError(env env, cfg *config, originalCmd *command) (exitCo
retryStderrBuffer := &bytes.Buffer{}
retryCommand := &command{
Path: originalCmd.Path,
- Args: disableWerrorFlags(originalCmd.Args),
+ Args: disableWerrorFlags(originalCmd.Args, retryWithExtraFlags),
EnvUpdates: originalCmd.EnvUpdates,
}
@@ -163,7 +242,7 @@ func doubleBuildWithWNoError(env env, cfg *config, originalCmd *command) (exitCo
// Write warning report to stdout for Android. On Android,
// double-build can be requested on remote builds as well, where there
// is no canonical place to write the warnings report.
- if cfg.isAndroidWrapper {
+ if werrorConfig.reportToStdout {
stdout := env.stdout()
io.WriteString(stdout, "<LLVM_NEXT_ERROR_REPORT>")
if err := json.NewEncoder(stdout).Encode(jsonData); err != nil {
@@ -182,10 +261,14 @@ func doubleBuildWithWNoError(env env, cfg *config, originalCmd *command) (exitCo
oldMask := env.umask(0)
defer env.umask(oldMask)
- warningsDir := getForceDisableWerrorDir(env, cfg)
+ reportDir := werrorConfig.reportDir
+ if reportDir == "" {
+ reportDir = getForceDisableWerrorDir(env, cfg)
+ }
+
// Allow root and regular users to write to this without issue.
- if err := os.MkdirAll(warningsDir, 0777); err != nil {
- return 0, wrapErrorwithSourceLocf(err, "error creating warnings directory %s", warningsDir)
+ if err := os.MkdirAll(reportDir, 0777); err != nil {
+ return 0, wrapErrorwithSourceLocf(err, "error creating warnings directory %s", reportDir)
}
// Have some tag to show that files aren't fully written. It would be sad if
@@ -196,7 +279,7 @@ func doubleBuildWithWNoError(env env, cfg *config, originalCmd *command) (exitCo
// Coming up with a consistent name for this is difficult (compiler command's
// SHA can clash in the case of identically named files in different
// directories, or similar); let's use a random one.
- tmpFile, err := ioutil.TempFile(warningsDir, "warnings_report*.json"+incompleteSuffix)
+ tmpFile, err := ioutil.TempFile(reportDir, "warnings_report*.json"+incompleteSuffix)
if err != nil {
return 0, wrapErrorwithSourceLocf(err, "error creating warnings file")
}
diff --git a/compiler_wrapper/disable_werror_flag_test.go b/compiler_wrapper/disable_werror_flag_test.go
index 9d3b4aba..639d404a 100644
--- a/compiler_wrapper/disable_werror_flag_test.go
+++ b/compiler_wrapper/disable_werror_flag_test.go
@@ -13,10 +13,14 @@ import (
"os"
"path"
"path/filepath"
+ "reflect"
+ "regexp"
"strings"
"testing"
)
+const arbitraryWerrorStderr = "error: foo [-Werror,-Wfoo]"
+
func TestOmitDoubleBuildForSuccessfulCall(t *testing.T) {
withForceDisableWErrorTestContext(t, func(ctx *testContext) {
ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(clangX86_64, mainCc)))
@@ -52,7 +56,7 @@ func TestDoubleBuildWithWNoErrorFlag(t *testing.T) {
if err := verifyArgCount(cmd, 0, "-Wno-error"); err != nil {
return err
}
- fmt.Fprint(stderr, "-Werror originalerror")
+ fmt.Fprint(stderr, arbitraryWerrorStderr)
return newExitCodeError(1)
case 2:
if err := verifyArgCount(cmd, 1, "-Wno-error"); err != nil {
@@ -71,6 +75,58 @@ func TestDoubleBuildWithWNoErrorFlag(t *testing.T) {
})
}
+func TestDoubleBuildUsesSpecificWnoErrorFlagsForWarningsThatDefaultToErrors(t *testing.T) {
+ withForceDisableWErrorTestContext(t, func(ctx *testContext) {
+ ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
+ switch ctx.cmdCount {
+ case 1:
+ if err := verifyArgCount(cmd, 0, "-Wno-error"); err != nil {
+ return err
+ }
+ fmt.Fprint(stderr, "error: foo [-Wfoo]")
+ return newExitCodeError(1)
+ case 2:
+ if err := verifyArgCount(cmd, 1, "-Wno-error=foo"); err != nil {
+ return err
+ }
+ if err := verifyArgCount(cmd, 1, "-Wno-error"); err != nil {
+ return err
+ }
+ return nil
+ default:
+ t.Fatalf("unexpected command: %#v", cmd)
+ return nil
+ }
+ }
+ ctx.must(callCompiler(ctx, ctx.cfg, ctx.newCommand(clangX86_64, mainCc)))
+ if ctx.cmdCount != 2 {
+ t.Errorf("expected 2 calls. Got: %d", ctx.cmdCount)
+ }
+ })
+}
+
+func TestDoubleBuildDoesntRecompileIfNoObviousWerrorsExist(t *testing.T) {
+ withForceDisableWErrorTestContext(t, func(ctx *testContext) {
+ ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
+ if ctx.cmdCount != 1 {
+ t.Fatalf("unexpected command: %#v", cmd)
+ }
+ if err := verifyArgCount(cmd, 0, "-Wno-error"); err != nil {
+ return err
+ }
+ fmt.Fprint(stderr, "error: foo bar baz\nwarning: foo [-Wfoo]")
+ return newExitCodeError(1)
+ }
+ exitCode := callCompiler(ctx, ctx.cfg, ctx.newCommand(clangX86_64, mainCc))
+ if exitCode != 1 {
+ t.Errorf("got exit code %d; want 1", exitCode)
+ }
+ if ctx.cmdCount != 1 {
+ t.Errorf("expected 1 call. Got: %d", ctx.cmdCount)
+ }
+ })
+}
+
func TestKnownConfigureFileParsing(t *testing.T) {
withTestContext(t, func(ctx *testContext) {
for _, f := range []string{"conftest.c", "conftest.cpp", "/dev/null"} {
@@ -89,7 +145,7 @@ func TestDoubleBuildWithKnownConfigureFile(t *testing.T) {
if err := verifyArgCount(cmd, 0, "-Wno-error"); err != nil {
return err
}
- fmt.Fprint(stderr, "-Werror originalerror")
+ fmt.Fprint(stderr, arbitraryWerrorStderr)
return newExitCodeError(1)
default:
t.Fatalf("unexpected command: %#v", cmd)
@@ -115,7 +171,7 @@ func TestDoubleBuildWithWNoErrorAndCCache(t *testing.T) {
if err := verifyPath(cmd, "ccache"); err != nil {
return err
}
- fmt.Fprint(stderr, "-Werror originalerror")
+ fmt.Fprint(stderr, arbitraryWerrorStderr)
return newExitCodeError(1)
case 2:
if err := verifyPath(cmd, "ccache"); err != nil {
@@ -140,7 +196,7 @@ func TestForwardStdoutAndStderrWhenDoubleBuildSucceeds(t *testing.T) {
switch ctx.cmdCount {
case 1:
fmt.Fprint(stdout, "originalmessage")
- fmt.Fprint(stderr, "-Werror originalerror")
+ fmt.Fprint(stderr, arbitraryWerrorStderr)
return newExitCodeError(1)
case 2:
fmt.Fprint(stdout, "retrymessage")
@@ -167,7 +223,7 @@ func TestForwardStdoutAndStderrWhenDoubleBuildFails(t *testing.T) {
switch ctx.cmdCount {
case 1:
fmt.Fprint(stdout, "originalmessage")
- fmt.Fprint(stderr, "-Werror originalerror")
+ fmt.Fprint(stderr, arbitraryWerrorStderr)
return newExitCodeError(3)
case 2:
fmt.Fprint(stdout, "retrymessage")
@@ -182,7 +238,7 @@ func TestForwardStdoutAndStderrWhenDoubleBuildFails(t *testing.T) {
if exitCode != 3 {
t.Errorf("unexpected exitcode. Got: %d", exitCode)
}
- if err := verifyNonInternalError(ctx.stderrString(), "-Werror originalerror"); err != nil {
+ if err := verifyNonInternalError(ctx.stderrString(), regexp.QuoteMeta(arbitraryWerrorStderr)); err != nil {
t.Error(err)
}
if !strings.Contains(ctx.stdoutString(), "originalmessage") {
@@ -204,7 +260,7 @@ func TestForwardStdinFromDoubleBuild(t *testing.T) {
switch ctx.cmdCount {
case 1:
- fmt.Fprint(stderr, "-Werror originalerror")
+ fmt.Fprint(stderr, arbitraryWerrorStderr)
return newExitCodeError(1)
case 2:
return nil
@@ -223,7 +279,7 @@ func TestForwardGeneralErrorWhenDoubleBuildFails(t *testing.T) {
ctx.cmdMock = func(cmd *command, stdin io.Reader, stdout io.Writer, stderr io.Writer) error {
switch ctx.cmdCount {
case 1:
- fmt.Fprint(stderr, "-Werror originalerror")
+ fmt.Fprint(stderr, arbitraryWerrorStderr)
return newExitCodeError(3)
case 2:
return errors.New("someerror")
@@ -260,7 +316,7 @@ func TestLogWarningsWhenDoubleBuildSucceeds(t *testing.T) {
switch ctx.cmdCount {
case 1:
fmt.Fprint(stdout, "originalmessage")
- fmt.Fprint(stderr, "-Werror originalerror")
+ fmt.Fprint(stderr, arbitraryWerrorStderr)
return newExitCodeError(1)
case 2:
fmt.Fprint(stdout, "retrymessage")
@@ -298,7 +354,7 @@ func TestLogWarningsWhenDoubleBuildFails(t *testing.T) {
switch ctx.cmdCount {
case 1:
fmt.Fprint(stdout, "originalmessage")
- fmt.Fprint(stderr, "-Werror originalerror")
+ fmt.Fprint(stderr, arbitraryWerrorStderr)
return newExitCodeError(1)
case 2:
fmt.Fprint(stdout, "retrymessage")
@@ -361,7 +417,7 @@ func TestDoubleBuildWerrorChmodsThingsAppropriately(t *testing.T) {
if err := verifyArgCount(cmd, 0, "-Wno-error"); err != nil {
return err
}
- fmt.Fprint(stderr, "-Werror originalerror")
+ fmt.Fprint(stderr, arbitraryWerrorStderr)
return newExitCodeError(1)
case 2:
if err := verifyArgCount(cmd, 1, "-Wno-error"); err != nil {
@@ -415,27 +471,39 @@ func TestDoubleBuildWerrorChmodsThingsAppropriately(t *testing.T) {
})
}
+type commandBuilderOpts struct {
+ isGcc bool
+ cflags []string
+}
+
+func newWerrorCommandBuilderOrDie(t *testing.T, ctx *testContext, opts commandBuilderOpts) *commandBuilder {
+ compiler := "clang"
+ if opts.isGcc {
+ compiler = "gcc"
+ }
+ cmd := ctx.newCommand(compiler, opts.cflags...)
+ b, err := newCommandBuilder(ctx, ctx.cfg, cmd)
+ if err != nil {
+ t.Fatalf("Constructing builder unexpectedly failed: %v", err)
+ }
+ return b
+}
+
func TestAndroidDisableWerror(t *testing.T) {
withTestContext(t, func(ctx *testContext) {
ctx.cfg.isAndroidWrapper = true
+ builder := newWerrorCommandBuilderOrDie(t, ctx, commandBuilderOpts{})
+
// Disable werror ON
ctx.cfg.useLlvmNext = true
- if !shouldForceDisableWerror(ctx, ctx.cfg, gccType) {
- t.Errorf("disable Werror not enabled for Android with useLlvmNext")
- }
-
- if !shouldForceDisableWerror(ctx, ctx.cfg, clangType) {
+ if !processForceDisableWerrorFlag(ctx, ctx.cfg, builder).enabled {
t.Errorf("disable Werror not enabled for Android with useLlvmNext")
}
// Disable werror OFF
ctx.cfg.useLlvmNext = false
- if shouldForceDisableWerror(ctx, ctx.cfg, gccType) {
- t.Errorf("disable-Werror enabled for Android without useLlvmNext")
- }
-
- if shouldForceDisableWerror(ctx, ctx.cfg, clangType) {
+ if processForceDisableWerrorFlag(ctx, ctx.cfg, builder).enabled {
t.Errorf("disable-Werror enabled for Android without useLlvmNext")
}
})
@@ -443,11 +511,8 @@ func TestAndroidDisableWerror(t *testing.T) {
func TestChromeOSNoForceDisableWerror(t *testing.T) {
withTestContext(t, func(ctx *testContext) {
- if shouldForceDisableWerror(ctx, ctx.cfg, gccType) {
- t.Errorf("disable Werror enabled for ChromeOS without FORCE_DISABLE_WERROR set")
- }
-
- if shouldForceDisableWerror(ctx, ctx.cfg, clangType) {
+ builder := newWerrorCommandBuilderOrDie(t, ctx, commandBuilderOpts{})
+ if processForceDisableWerrorFlag(ctx, ctx.cfg, builder).enabled {
t.Errorf("disable Werror enabled for ChromeOS without FORCE_DISABLE_WERROR set")
}
})
@@ -455,16 +520,101 @@ func TestChromeOSNoForceDisableWerror(t *testing.T) {
func TestChromeOSForceDisableWerrorOnlyAppliesToClang(t *testing.T) {
withForceDisableWErrorTestContext(t, func(ctx *testContext) {
- if !shouldForceDisableWerror(ctx, ctx.cfg, clangType) {
+ ctx.env = append(ctx.env, "FORCE_DISABLE_WERROR=1")
+ builder := newWerrorCommandBuilderOrDie(t, ctx, commandBuilderOpts{})
+ if !processForceDisableWerrorFlag(ctx, ctx.cfg, builder).enabled {
t.Errorf("Disable -Werror should be enabled for clang.")
}
- if shouldForceDisableWerror(ctx, ctx.cfg, gccType) {
+ builder = newWerrorCommandBuilderOrDie(t, ctx, commandBuilderOpts{isGcc: true})
+ if processForceDisableWerrorFlag(ctx, ctx.cfg, builder).enabled {
t.Errorf("Disable -Werror should be disabled for gcc.")
}
})
}
+func TestChromeOSForceDisableWerrorWorksAsFlag(t *testing.T) {
+ withForceDisableWErrorTestContext(t, func(ctx *testContext) {
+ builder := newWerrorCommandBuilderOrDie(t, ctx, commandBuilderOpts{
+ cflags: []string{"-D_CROSTC_FORCE_DISABLE_WERROR=/foo"},
+ })
+ werrorConfig := processForceDisableWerrorFlag(ctx, ctx.cfg, builder)
+ if !werrorConfig.enabled {
+ t.Fatalf("Disable -Werror should be enabled by flag.")
+ }
+
+ if werrorConfig.reportToStdout {
+ t.Errorf("Stdout reporting should be disabled on ChromeOS")
+ } else if werrorConfig.reportDir != "/foo" {
+ t.Errorf("Got werror report dir %s; want /foo", werrorConfig.reportDir)
+ }
+ })
+}
+
+func TestChromeOSForceDisableWerrorIsSuppressedInSrcConfigure(t *testing.T) {
+ withForceDisableWErrorTestContext(t, func(ctx *testContext) {
+ ctx.env = append(ctx.env, "EBUILD_PHASE=configure")
+ builder := newWerrorCommandBuilderOrDie(t, ctx, commandBuilderOpts{
+ cflags: []string{"-D_CROSTC_FORCE_DISABLE_WERROR=/foo"},
+ })
+ werrorConfig := processForceDisableWerrorFlag(ctx, ctx.cfg, builder)
+ if werrorConfig.enabled {
+ t.Fatalf("Disable -Werror should be disabled during src_configure.")
+ }
+ })
+}
+
+func TestChromeOSForceDisableWerrorRemovesClangFlags(t *testing.T) {
+ withForceDisableWErrorTestContext(t, func(ctx *testContext) {
+ builder := newWerrorCommandBuilderOrDie(t, ctx, commandBuilderOpts{
+ cflags: []string{
+ "-D_CROSTC_FORCE_DISABLE_WERROR=/foo",
+ "-D_CROSTC_FORCE_DISABLE_WERROR=/bar",
+ "-Wfoo",
+ "-D_CROSTC_FORCE_DISABLE_WERROR=/baz",
+ },
+ })
+ werrorConfig := processForceDisableWerrorFlag(ctx, ctx.cfg, builder)
+ if !werrorConfig.enabled {
+ t.Fatalf("Disable -Werror should be enabled by flag.")
+ }
+
+ if werrorConfig.reportToStdout {
+ t.Errorf("Stdout reporting should be disabled on ChromeOS")
+ } else if werrorConfig.reportDir != "/baz" {
+ t.Errorf("Got werror report dir %s; want /baz", werrorConfig.reportDir)
+ }
+
+ args := builder.build().Args
+ if want := []string{"-Wfoo"}; !reflect.DeepEqual(args, want) {
+ t.Errorf("Got builder args %#v; want %#v", args, want)
+ }
+ })
+}
+
+func TestChromeOSForceDisableWerrorRemovesGCCFlagsButDoesNotEnableFeature(t *testing.T) {
+ withForceDisableWErrorTestContext(t, func(ctx *testContext) {
+ builder := newWerrorCommandBuilderOrDie(t, ctx, commandBuilderOpts{
+ cflags: []string{
+ "-D_CROSTC_FORCE_DISABLE_WERROR=/foo",
+ "-D_CROSTC_FORCE_DISABLE_WERROR=/bar",
+ "-Wfoo",
+ "-D_CROSTC_FORCE_DISABLE_WERROR=/baz",
+ },
+ })
+ builder.target.compilerType = gccType
+ werrorConfig := processForceDisableWerrorFlag(ctx, ctx.cfg, builder)
+ if werrorConfig.enabled {
+ t.Fatalf("Disable -Werror should not be enabled for GCC.")
+ }
+
+ args := builder.build().Args
+ if want := []string{"-Wfoo"}; !reflect.DeepEqual(args, want) {
+ t.Errorf("Got builder args %#v; want %#v", args, want)
+ }
+ })
+}
+
func TestClangTidyNoDoubleBuild(t *testing.T) {
withTestContext(t, func(ctx *testContext) {
ctx.cfg.isAndroidWrapper = true
diff --git a/compiler_wrapper/goldenutil_test.go b/compiler_wrapper/goldenutil_test.go
index 16e2b7e7..593266ea 100644
--- a/compiler_wrapper/goldenutil_test.go
+++ b/compiler_wrapper/goldenutil_test.go
@@ -8,6 +8,7 @@ import (
"bytes"
"encoding/json"
"flag"
+ "fmt"
"io"
"io/ioutil"
"log"
@@ -171,30 +172,81 @@ func fillGoldenResults(ctx *testContext, files []goldenFile) []goldenFile {
}
func writeGoldenRecords(ctx *testContext, writer io.Writer, records []goldenRecord) {
- // Replace the temp dir with a stable path so that the goldens stay stable.
- stableTempDir := filepath.Join(filepath.Dir(ctx.tempDir), "stable")
- writer = &replacingWriter{
- Writer: writer,
- old: [][]byte{[]byte(ctx.tempDir)},
- new: [][]byte{[]byte(stableTempDir)},
+ // We need to rewrite /tmp/${test_specific_tmpdir} records as /tmp/stable, so it's
+ // deterministic across reruns. Round-trip this through JSON so there's no need to maintain
+ // logic that hunts through `record`s. A side-benefit of round-tripping through a JSON `map`
+ // is that `encoding/json` sorts JSON map keys, and `cros format` complains if keys aren't
+ // sorted.
+ encoded, err := json.Marshal(records)
+ if err != nil {
+ ctx.t.Fatal(err)
}
- enc := json.NewEncoder(writer)
- enc.SetIndent("", " ")
- if err := enc.Encode(records); err != nil {
+
+ decoded := interface{}(nil)
+ if err := json.Unmarshal(encoded, &decoded); err != nil {
ctx.t.Fatal(err)
}
-}
-type replacingWriter struct {
- io.Writer
- old [][]byte
- new [][]byte
+ stableTempDir := filepath.Join(filepath.Dir(ctx.tempDir), "stable")
+ decoded, err = dfsJSONValues(decoded, func(i interface{}) interface{} {
+ asString, ok := i.(string)
+ if !ok {
+ return i
+ }
+ return strings.ReplaceAll(asString, ctx.tempDir, stableTempDir)
+ })
+
+ encoder := json.NewEncoder(writer)
+ encoder.SetIndent("", " ")
+ if err := encoder.Encode(decoded); err != nil {
+ ctx.t.Fatal(err)
+ }
}
-func (writer *replacingWriter) Write(p []byte) (n int, err error) {
- // TODO: Use bytes.ReplaceAll once cros sdk uses golang >= 1.12
- for i, old := range writer.old {
- p = bytes.Replace(p, old, writer.new[i], -1)
+// Performs a DFS on `decodedJSON`, replacing elements with the result of calling `mapFunc()` on
+// each value. Only returns an error if an element type is unexpected (read: the input JSON should
+// only contain the types listed for unmarshalling as an interface value here
+// https://pkg.go.dev/encoding/json#Unmarshal).
+//
+// Two subtleties:
+// 1. This calls `mapFunc()` on nested values after the transformation of their individual elements.
+// Moreover, given the JSON `[1, 2]` and a mapFunc that just returns nil, the mapFunc will be
+// called as `mapFunc(1)`, then `mapFunc(2)`, then `mapFunc({}interface{nil, nil})`.
+// 2. This is not called directly on keys in maps. If you want to transform keys, you may do so when
+// `mapFunc` is called on a `map[string]interface{}`. This is to make differentiating between
+// keys and values easier.
+func dfsJSONValues(decodedJSON interface{}, mapFunc func(interface{}) interface{}) (interface{}, error) {
+ if decodedJSON == nil {
+ return mapFunc(nil), nil
+ }
+
+ switch d := decodedJSON.(type) {
+ case bool, float64, string:
+ return mapFunc(decodedJSON), nil
+
+ case []interface{}:
+ newSlice := make([]interface{}, len(d))
+ for i, elem := range d {
+ transformed, err := dfsJSONValues(elem, mapFunc)
+ if err != nil {
+ return nil, err
+ }
+ newSlice[i] = transformed
+ }
+ return mapFunc(newSlice), nil
+
+ case map[string]interface{}:
+ newMap := make(map[string]interface{}, len(d))
+ for k, v := range d {
+ transformed, err := dfsJSONValues(v, mapFunc)
+ if err != nil {
+ return nil, err
+ }
+ newMap[k] = transformed
+ }
+ return mapFunc(newMap), nil
+
+ default:
+ return nil, fmt.Errorf("unexpected type in JSON: %T", decodedJSON)
}
- return writer.Writer.Write(p)
}
diff --git a/compiler_wrapper/install_compiler_wrapper.sh b/compiler_wrapper/install_compiler_wrapper.sh
index 81459082..c3c9b714 100755
--- a/compiler_wrapper/install_compiler_wrapper.sh
+++ b/compiler_wrapper/install_compiler_wrapper.sh
@@ -31,7 +31,7 @@ build_py \
--output_file=./clang_host_wrapper
sudo mv ./clang_host_wrapper /usr/bin/clang_host_wrapper
echo "/usr/bin/clang_host_wrapper"
-sudo cp ../binary_search_tool/bisect_driver.py /usr/bin
+sudo cp ../bisect_driver.py /usr/bin
echo "/usr/bin/clang_host_wrapper/bisect_driver.py"
# Update the target wrappers
@@ -66,7 +66,7 @@ for GCC in cross-x86_64-cros-linux-gnu/gcc cross-armv7a-cros-linux-gnueabihf/gcc
grep sysroot_wrapper.hardened.noccache <<< "${FILES}"
sudo cp ./sysroot_wrapper.hardened.ccache "$(grep sysroot_wrapper.hardened.ccache <<< "${FILES}")"
grep sysroot_wrapper.hardened.ccache <<< "${FILES}"
- sudo cp ../binary_search_tool/bisect_driver.py "$(grep bisect_driver.py <<< "${FILES}")"
+ sudo cp ../bisect_driver.py "$(grep bisect_driver.py <<< "${FILES}")"
grep bisect_driver.py <<< "${FILES}"
done
rm -f ./sysroot_wrapper.hardened.noccache ./sysroot_wrapper.hardened.ccache
diff --git a/compiler_wrapper/testdata/android_golden/bisect.json b/compiler_wrapper/testdata/android_golden/bisect.json
index a1ffc50b..1e657030 100644
--- a/compiler_wrapper/testdata/android_golden/bisect.json
+++ b/compiler_wrapper/testdata/android_golden/bisect.json
@@ -1,22 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "env": [
- "BISECT_STAGE=someBisectStage",
- "HOME=/user/home"
- ],
- "wrapper": {
- "cmd": {
- "path": "/tmp/stable/clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/env",
"args": [
"python3",
"-c",
@@ -28,30 +14,29 @@
],
"env_updates": [
"PYTHONPATH=/somepath/test_binary"
- ]
+ ],
+ "path": "/usr/bin/env"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"BISECT_STAGE=someBisectStage",
- "BISECT_DIR=someBisectDir",
"HOME=/user/home"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/env",
"args": [
"python3",
"-c",
@@ -63,33 +48,30 @@
],
"env_updates": [
"PYTHONPATH=/somepath/test_binary"
- ]
+ ],
+ "path": "/usr/bin/env"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"BISECT_STAGE=someBisectStage",
"BISECT_DIR=someBisectDir",
"HOME=/user/home"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "/tmp/stable/clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/env",
"args": [
"python3",
"-c",
@@ -101,12 +83,30 @@
],
"env_updates": [
"PYTHONPATH=/somepath/test_binary"
- ]
+ ],
+ "path": "/usr/bin/env"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "env": [
+ "BISECT_STAGE=someBisectStage",
+ "BISECT_DIR=someBisectDir",
+ "HOME=/user/home"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
}
]
diff --git a/compiler_wrapper/testdata/android_golden/clang_path.json b/compiler_wrapper/testdata/android_golden/clang_path.json
index 5686b381..42d487b8 100644
--- a/compiler_wrapper/testdata/android_golden/clang_path.json
+++ b/compiler_wrapper/testdata/android_golden/clang_path.json
@@ -1,230 +1,230 @@
[
{
+ "cmds": [
+ {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang.real"
+ }
+ }
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang.real",
"args": [
"main.cc"
- ]
- }
+ ],
+ "path": "/tmp/stable/clang.real"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/clang"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
- },
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang.real",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
+ ],
+ "path": "/tmp/stable/clang.real"
+ }
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"WITH_TIDY=1"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang.real",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/clang++.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/clang++",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/clang++"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang++.real",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/clang-tidy.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/clang-tidy",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/clang-tidy"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang-tidy.real",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/clang-tidy.real"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"WITH_TIDY=1"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/clang-tidy",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/clang-tidy"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang-tidy.real",
"args": [
"main.cc"
- ]
+ ],
+ "path": "a/b/c/d/e/f/g/clang.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "a/b/c/d/e/f/g/clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "a/b/c/d/e/f/g/clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "a/b/c/d/e/f/g/clang.real",
"args": [
"main.cc"
- ]
+ ],
+ "path": "symlinked/clang.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "symlinked/clang_other",
"args": [
"main.cc"
- ]
+ ],
+ "path": "symlinked/clang_other"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "symlinked/clang.real",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/pathenv/clang.real"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"PATH=/tmp/stable/pathenv"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/pathenv/clang.real",
"args": [
+ "/tmp/stable/clang.real",
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"main.cc",
"--gomacc-path",
"/tmp/stable/gomacc"
- ]
- }
- },
- "cmds": [
- {
- "cmd": {
- "path": "/tmp/stable/gomacc",
- "args": [
- "/tmp/stable/clang.real",
- "main.cc"
- ]
- }
+ ],
+ "path": "/tmp/stable/clang"
}
- ]
+ }
}
]
diff --git a/compiler_wrapper/testdata/android_golden/compile_with_fallback.json b/compiler_wrapper/testdata/android_golden/compile_with_fallback.json
index 509583ae..b8ef740d 100644
--- a/compiler_wrapper/testdata/android_golden/compile_with_fallback.json
+++ b/compiler_wrapper/testdata/android_golden/compile_with_fallback.json
@@ -1,115 +1,115 @@
[
{
- "wd": "/tmp/stable",
- "env": [
- "ANDROID_LLVM_PREBUILT_COMPILER_PATH=fallback_compiler",
- "ANDROID_LLVM_STDERR_REDIRECT=/tmp/stable/fallback_stderr",
- "ANDROID_LLVM_FALLBACK_DISABLED_WARNINGS=-a -b"
- ],
- "wrapper": {
- "cmd": {
- "path": "/tmp/stable/clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang.real",
"args": [
"main.cc",
"-fno-color-diagnostics",
"-a",
"-b"
- ]
+ ],
+ "path": "/tmp/stable/clang.real"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"ANDROID_LLVM_PREBUILT_COMPILER_PATH=fallback_compiler",
"ANDROID_LLVM_STDERR_REDIRECT=/tmp/stable/fallback_stderr",
"ANDROID_LLVM_FALLBACK_DISABLED_WARNINGS=-a -b"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang.real",
"args": [
"main.cc",
"-fno-color-diagnostics",
"-a",
"-b"
- ]
+ ],
+ "path": "/tmp/stable/clang.real"
},
"exitcode": 1
},
{
"cmd": {
- "path": "fallback_compiler/clang",
"args": [
"main.cc"
],
"env_updates": [
"ANDROID_LLVM_PREBUILT_COMPILER_PATH="
- ]
+ ],
+ "path": "fallback_compiler/clang"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"ANDROID_LLVM_PREBUILT_COMPILER_PATH=fallback_compiler",
"ANDROID_LLVM_STDERR_REDIRECT=/tmp/stable/fallback_stderr",
"ANDROID_LLVM_FALLBACK_DISABLED_WARNINGS=-a -b"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"main.cc"
- ]
- },
- "exitcode": 1
- },
+ ],
+ "path": "/tmp/stable/clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang.real",
"args": [
"main.cc",
"-fno-color-diagnostics",
"-a",
"-b"
- ]
+ ],
+ "path": "/tmp/stable/clang.real"
},
"exitcode": 1
},
{
"cmd": {
- "path": "fallback_compiler/clang",
"args": [
"main.cc"
],
"env_updates": [
"ANDROID_LLVM_PREBUILT_COMPILER_PATH="
- ]
+ ],
+ "path": "fallback_compiler/clang"
},
"exitcode": 1
}
- ]
+ ],
+ "env": [
+ "ANDROID_LLVM_PREBUILT_COMPILER_PATH=fallback_compiler",
+ "ANDROID_LLVM_STDERR_REDIRECT=/tmp/stable/fallback_stderr",
+ "ANDROID_LLVM_FALLBACK_DISABLED_WARNINGS=-a -b"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
+ },
+ "exitcode": 1
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_clang_host_golden/bisect.json b/compiler_wrapper/testdata/cros_clang_host_golden/bisect.json
index 9c9dac03..a8717e09 100644
--- a/compiler_wrapper/testdata/cros_clang_host_golden/bisect.json
+++ b/compiler_wrapper/testdata/cros_clang_host_golden/bisect.json
@@ -1,22 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "env": [
- "BISECT_STAGE=someBisectStage",
- "HOME=/user/home"
- ],
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/env",
"args": [
"python3",
"-c",
@@ -41,46 +27,37 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
+ "main.cc"
],
"env_updates": [
"PYTHONPATH=/somepath/test_binary"
- ]
+ ],
+ "path": "/usr/bin/env"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"BISECT_STAGE=someBisectStage",
- "BISECT_DIR=someBisectDir",
"HOME=/user/home"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/env",
"args": [
"python3",
"-c",
@@ -105,49 +82,38 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
+ "main.cc"
],
"env_updates": [
"PYTHONPATH=/somepath/test_binary"
- ]
+ ],
+ "path": "/usr/bin/env"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"BISECT_STAGE=someBisectStage",
"BISECT_DIR=someBisectDir",
"HOME=/user/home"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/env",
"args": [
"python3",
"-c",
@@ -172,28 +138,38 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
+ "main.cc"
],
"env_updates": [
"PYTHONPATH=/somepath/test_binary"
- ]
+ ],
+ "path": "/usr/bin/env"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "env": [
+ "BISECT_STAGE=someBisectStage",
+ "BISECT_DIR=someBisectDir",
+ "HOME=/user/home"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_clang_host_golden/clang_ftrapv_maincc_target_specific.json b/compiler_wrapper/testdata/cros_clang_host_golden/clang_ftrapv_maincc_target_specific.json
index 281239a5..843ae17c 100644
--- a/compiler_wrapper/testdata/cros_clang_host_golden/clang_ftrapv_maincc_target_specific.json
+++ b/compiler_wrapper/testdata/cros_clang_host_golden/clang_ftrapv_maincc_target_specific.json
@@ -1,19 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "-ftrapv",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -32,39 +21,31 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-eabi-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -83,39 +64,31 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-win-gnu-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-eabi-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -134,39 +107,31 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-linux-gnu-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-win-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -185,39 +150,31 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-eabi-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -236,39 +193,31 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-win-gnu-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-eabi-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -287,39 +236,31 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-linux-gnu-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-win-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -338,39 +279,31 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-eabi-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -389,39 +322,31 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-win-gnu-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-eabi-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -440,22 +365,25 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "-ftrapv",
+ "main.cc"
+ ],
+ "path": "./armv8m-cros-win-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_clang_host_golden/clang_host_wrapper.json b/compiler_wrapper/testdata/cros_clang_host_golden/clang_host_wrapper.json
index 045b6438..383e41c7 100644
--- a/compiler_wrapper/testdata/cros_clang_host_golden/clang_host_wrapper.json
+++ b/compiler_wrapper/testdata/cros_clang_host_golden/clang_host_wrapper.json
@@ -1,18 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -31,22 +21,24 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_clang_host_golden/clang_maincc_target_specific.json b/compiler_wrapper/testdata/cros_clang_host_golden/clang_maincc_target_specific.json
index 7f4b1c9e..ffa53079 100644
--- a/compiler_wrapper/testdata/cros_clang_host_golden/clang_maincc_target_specific.json
+++ b/compiler_wrapper/testdata/cros_clang_host_golden/clang_maincc_target_specific.json
@@ -1,18 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -31,38 +21,30 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-eabi-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -81,38 +63,30 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-win-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-eabi-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -131,38 +105,30 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-win-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -181,38 +147,30 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-eabi-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -231,38 +189,30 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-win-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-eabi-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -281,38 +231,30 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-win-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -331,38 +273,30 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-eabi-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -381,38 +315,30 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-win-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-eabi-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -431,22 +357,24 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./armv8m-cros-win-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_clang_host_golden/clang_path.json b/compiler_wrapper/testdata/cros_clang_host_golden/clang_path.json
index a965ca7f..1993f10f 100644
--- a/compiler_wrapper/testdata/cros_clang_host_golden/clang_path.json
+++ b/compiler_wrapper/testdata/cros_clang_host_golden/clang_path.json
@@ -1,18 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -31,41 +21,30 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -84,41 +63,36 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang++",
"args": [
"main.cc"
- ]
- }
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang++",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -137,42 +111,30 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "-std=gnu++14",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang++"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "CLANG=somepath/clang"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang++"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "somepath/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -191,48 +153,42 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "somepath/clang"
}
}
- ]
- },
- {
+ ],
+ "env": [
+ "CLANG=somepath/clang"
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-Xclang-path=/somedir",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "/tmp/stable/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/somedir/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -251,54 +207,44 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-resource-dir=someResourceDir",
"--gcc-toolchain=/usr",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/somedir/clang"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-Xclang-path=/somedir",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "/tmp/stable/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/somedir/clang",
"args": [
+ "/somedir/clang",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -316,53 +262,45 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-resource-dir=someResourceDir",
"--gcc-toolchain=/usr",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
+ ],
+ "env": [
+ "GOMACC_PATH=/tmp/stable/gomacc"
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-Xclang-path=/somedir",
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "/tmp/stable/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/somedir/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -381,43 +319,39 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-resource-dir=someResourceDir",
"--gcc-toolchain=/usr",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/somedir/clang"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/x86_64-cros-linux-gnu-clang",
"args": [
+ "-Xclang-path=/somedir",
"main.cc"
- ]
- }
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -436,38 +370,30 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/a/b/c/d/e/f/g/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -486,38 +412,30 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/a/b/c/d/e/f/g/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./symlinked/x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/a/b/c/d/e/f/g/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -536,38 +454,30 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/a/b/c/d/e/f/g/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "somedir/x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./symlinked/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/somedir/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -586,41 +496,30 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/somedir/clang"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "PATH=/tmp/stable/pathenv"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "somedir/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/pathenv/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -639,22 +538,27 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/pathenv/clang"
}
}
- ]
+ ],
+ "env": [
+ "PATH=/tmp/stable/pathenv"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "x86_64-cros-linux-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_clang_host_golden/clang_sanitizer_args.json b/compiler_wrapper/testdata/cros_clang_host_golden/clang_sanitizer_args.json
index 76f3f14b..d843aa1d 100644
--- a/compiler_wrapper/testdata/cros_clang_host_golden/clang_sanitizer_args.json
+++ b/compiler_wrapper/testdata/cros_clang_host_golden/clang_sanitizer_args.json
@@ -1,20 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "-fsanitize=kernel-address",
- "-Wl,--no-undefined",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -33,41 +21,33 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fsanitize=kernel-address",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-fsanitize=kernel-address",
- "-Wl,-z,defs",
+ "-Wl,--no-undefined",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -86,41 +66,33 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fsanitize=kernel-address",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-fsanitize=kernel-address",
- "-D_FORTIFY_SOURCE=1",
+ "-Wl,-z,defs",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -139,41 +111,33 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fsanitize=kernel-address",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-fsanitize=kernel-address",
- "-D_FORTIFY_SOURCE=2",
+ "-D_FORTIFY_SOURCE=1",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -192,40 +156,33 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fsanitize=kernel-address",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-fsanitize=fuzzer",
+ "-fsanitize=kernel-address",
+ "-D_FORTIFY_SOURCE=2",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -244,41 +201,32 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fsanitize=fuzzer",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-fsanitize=address",
- "-fprofile-instr-generate",
+ "-fsanitize=fuzzer",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -297,41 +245,34 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fsanitize=address",
"-fprofile-instr-generate",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-fsanitize=address",
+ "-fprofile-instr-generate",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -350,40 +291,32 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fsanitize=address",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-fprofile-instr-generate",
+ "-fsanitize=address",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -402,23 +335,26 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fprofile-instr-generate",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "-fprofile-instr-generate",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_clang_host_golden/clang_specific_args.json b/compiler_wrapper/testdata/cros_clang_host_golden/clang_specific_args.json
index 493a3dc2..d5567230 100644
--- a/compiler_wrapper/testdata/cros_clang_host_golden/clang_specific_args.json
+++ b/compiler_wrapper/testdata/cros_clang_host_golden/clang_specific_args.json
@@ -1,28 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "-mno-movbe",
- "-Wclobbered",
- "-Wno-psabi",
- "-Wlogical-op",
- "-Wmissing-parameter-type",
- "-Wold-style-declaration",
- "-Woverride-init",
- "-Wunsafe-loop-optimizations",
- "-Wstrict-aliasing=abc",
- "-finline-limit=abc",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -41,10 +21,9 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-mno-movbe",
"-Wclobbered",
@@ -54,34 +33,36 @@
"-Wold-style-declaration",
"-Woverride-init",
"-Wunsafe-loop-optimizations",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-Wno-error=cpp",
+ "-mno-movbe",
+ "-Wclobbered",
+ "-Wno-psabi",
+ "-Wlogical-op",
+ "-Wmissing-parameter-type",
+ "-Wold-style-declaration",
+ "-Woverride-init",
+ "-Wunsafe-loop-optimizations",
+ "-Wstrict-aliasing=abc",
+ "-finline-limit=abc",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -100,40 +81,32 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-Wno-#warnings",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-Wno-error=maybe-uninitialized",
+ "-Wno-error=cpp",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -152,40 +125,32 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-Wno-error=uninitialized",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-Xclang-only=-someflag",
+ "-Wno-error=maybe-uninitialized",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -204,23 +169,26 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-someflag",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "-Xclang-only=-someflag",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_clang_host_golden/clangtidy.json b/compiler_wrapper/testdata/cros_clang_host_golden/clangtidy.json
index e425e074..07fd941d 100644
--- a/compiler_wrapper/testdata/cros_clang_host_golden/clangtidy.json
+++ b/compiler_wrapper/testdata/cros_clang_host_golden/clangtidy.json
@@ -1,30 +1,17 @@
[
{
- "wd": "/tmp/stable",
- "env": [
- "WITH_TIDY=1"
- ],
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "/tmp/stable/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/tmp/stable/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
@@ -47,25 +34,17 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang-tidy"
}
},
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -84,51 +63,42 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
- "WITH_TIDY=1",
- "GOMACC_PATH=/tmp/stable/gomacc"
+ "WITH_TIDY=1"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "/tmp/stable/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/tmp/stable/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
@@ -151,26 +121,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang-tidy"
}
},
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
+ "/tmp/stable/clang",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -188,53 +151,43 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"WITH_TIDY=1",
"GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerrorclang-tidy failed"
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "/tmp/stable/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/tmp/stable/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
@@ -257,29 +210,22 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang-tidy"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
},
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
+ "/tmp/stable/clang",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -297,54 +243,45 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"WITH_TIDY=1",
"GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
},
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ "stderr": "someerrorclang-tidy failed",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "/tmp/stable/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/tmp/stable/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
@@ -367,26 +304,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang-tidy"
}
},
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
+ "/tmp/stable/clang",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -404,25 +334,34 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/gomacc"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "env": [
+ "WITH_TIDY=1",
+ "GOMACC_PATH=/tmp/stable/gomacc"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_clang_host_golden/force_disable_werror.json b/compiler_wrapper/testdata/cros_clang_host_golden/force_disable_werror.json
index 0fb8e1f2..40049689 100644
--- a/compiler_wrapper/testdata/cros_clang_host_golden/force_disable_werror.json
+++ b/compiler_wrapper/testdata/cros_clang_host_golden/force_disable_werror.json
@@ -1,21 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "env": [
- "FORCE_DISABLE_WERROR=1"
- ],
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -34,42 +21,33 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"FORCE_DISABLE_WERROR=1"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "$CROS_ARTIFACTS_TMP_DIR is not set, artifacts will be written to /tmp"
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -88,27 +66,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
},
- "stderr": "-Werror originalerror",
- "exitcode": 1
+ "exitcode": 1,
+ "stderr": "error: foo [-Werror,-Wfoo]"
},
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -127,45 +97,36 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-Wno-error",
"-Wno-error=poison-system-directories"
- ]
+ ],
+ "path": "/tmp/stable/clang"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"FORCE_DISABLE_WERROR=1"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
},
- "stderr": "-Werror originalerror",
- "exitcode": 1
- },
+ "stdout": "$CROS_ARTIFACTS_TMP_DIR is not set, artifacts will be written to /tmp"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -184,27 +145,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
- "main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions"
- ]
+ "main.cc"
+ ],
+ "path": "/tmp/stable/clang"
},
- "stderr": "-Werror originalerror",
- "exitcode": 1
+ "exitcode": 1,
+ "stderr": "error: foo [-Werror,-Wfoo]"
},
{
"cmd": {
- "path": "/tmp/stable/clang",
"args": [
"-Qunused-arguments",
"-Werror=poison-system-directories",
@@ -223,27 +176,34 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-unused-local-typedefs",
"-fno-addrsig",
- "-fuse-ld=lld",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"main.cc",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-Wno-error",
"-Wno-error=poison-system-directories"
- ]
+ ],
+ "path": "/tmp/stable/clang"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "env": [
+ "FORCE_DISABLE_WERROR=1"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "error: foo [-Werror,-Wfoo]"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_gcc_host_golden/gcc_host_wrapper.json b/compiler_wrapper/testdata/cros_gcc_host_golden/gcc_host_wrapper.json
index 825e5dd3..85743a50 100644
--- a/compiler_wrapper/testdata/cros_gcc_host_golden/gcc_host_wrapper.json
+++ b/compiler_wrapper/testdata/cros_gcc_host_golden/gcc_host_wrapper.json
@@ -1,27 +1,27 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./gcc",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "./gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
"-Wno-deprecated-declarations",
"-fcommon",
"main.cc"
- ]
+ ],
+ "path": "./gcc.real"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./gcc"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_gcc_host_golden/gcc_maincc_target_specific.json b/compiler_wrapper/testdata/cros_gcc_host_golden/gcc_maincc_target_specific.json
index 97fb19b0..8e5be534 100644
--- a/compiler_wrapper/testdata/cros_gcc_host_golden/gcc_maincc_target_specific.json
+++ b/compiler_wrapper/testdata/cros_gcc_host_golden/gcc_maincc_target_specific.json
@@ -1,227 +1,227 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
"-Wno-deprecated-declarations",
"-fcommon",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-eabi-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "./x86_64-cros-eabi-gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
"-Wno-deprecated-declarations",
"-fcommon",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-eabi-gcc.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-win-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-eabi-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "./x86_64-cros-win-gnu-gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
"-Wno-deprecated-declarations",
"-fcommon",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-win-gnu-gcc.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-win-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "./armv7m-cros-linux-gnu-gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
"-Wno-deprecated-declarations",
"-fcommon",
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-linux-gnu-gcc.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-eabi-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "./armv7m-cros-eabi-gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
"-Wno-deprecated-declarations",
"-fcommon",
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-eabi-gcc.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-win-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-eabi-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "./armv7m-cros-win-gnu-gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
"-Wno-deprecated-declarations",
"-fcommon",
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-win-gnu-gcc.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-win-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "./armv8m-cros-linux-gnu-gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
"-Wno-deprecated-declarations",
"-fcommon",
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-linux-gnu-gcc.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-eabi-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "./armv8m-cros-eabi-gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
"-Wno-deprecated-declarations",
"-fcommon",
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-eabi-gcc.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-win-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-eabi-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "./armv8m-cros-win-gnu-gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
"-Wno-deprecated-declarations",
"-fcommon",
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-win-gnu-gcc.real"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./armv8m-cros-win-gnu-gcc"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_gcc_host_golden/gcc_path.json b/compiler_wrapper/testdata/cros_gcc_host_golden/gcc_path.json
index c71bcd44..b8c82d63 100644
--- a/compiler_wrapper/testdata/cros_gcc_host_golden/gcc_path.json
+++ b/compiler_wrapper/testdata/cros_gcc_host_golden/gcc_path.json
@@ -1,161 +1,161 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
"-Wno-deprecated-declarations",
"-fcommon",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
"-Wno-deprecated-declarations",
"-fcommon",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc.real"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
- }
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/x86_64-cros-linux-gnu-gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
"-Wno-deprecated-declarations",
"-fcommon",
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
"-Wno-deprecated-declarations",
"-fcommon",
"main.cc"
- ]
+ ],
+ "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./symlinked/x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "./symlinked/x86_64-cros-linux-gnu-gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
"-Wno-deprecated-declarations",
"-fcommon",
"main.cc"
- ]
+ ],
+ "path": "./symlinked/x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "PATH=/tmp/stable/pathenv"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./symlinked/x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/pathenv/x86_64-cros-linux-gnu-gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
"-Wno-deprecated-declarations",
"-fcommon",
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/pathenv/x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
+ ],
+ "env": [
+ "PATH=/tmp/stable/pathenv"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "x86_64-cros-linux-gnu-gcc"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_gcc_host_golden/gcc_specific_args.json b/compiler_wrapper/testdata/cros_gcc_host_golden/gcc_specific_args.json
index cd656307..385fe442 100644
--- a/compiler_wrapper/testdata/cros_gcc_host_golden/gcc_specific_args.json
+++ b/compiler_wrapper/testdata/cros_gcc_host_golden/gcc_specific_args.json
@@ -1,19 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "-march=goldmont",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
@@ -21,26 +10,26 @@
"-fcommon",
"-march=goldmont",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
- "-march=goldmont-plus",
+ "-march=goldmont",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
@@ -48,26 +37,26 @@
"-fcommon",
"-march=goldmont-plus",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
- "-march=skylake",
+ "-march=goldmont-plus",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc.real",
"args": [
"-Wno-maybe-uninitialized",
"-Wno-unused-local-typedefs",
@@ -75,9 +64,20 @@
"-fcommon",
"-march=skylake",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "-march=skylake",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_golden/bisect.json b/compiler_wrapper/testdata/cros_hardened_golden/bisect.json
index b4cdd8d2..e13331c2 100644
--- a/compiler_wrapper/testdata/cros_hardened_golden/bisect.json
+++ b/compiler_wrapper/testdata/cros_hardened_golden/bisect.json
@@ -1,22 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "env": [
- "BISECT_STAGE=someBisectStage",
- "HOME=/user/home"
- ],
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/env",
"args": [
"python3",
"-c",
@@ -26,7 +12,6 @@
"/usr/bin/ccache",
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -44,26 +29,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -74,30 +52,29 @@
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes",
"PYTHONPATH=/somepath/test_binary"
- ]
+ ],
+ "path": "/usr/bin/env"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"BISECT_STAGE=someBisectStage",
- "BISECT_DIR=someBisectDir",
"HOME=/user/home"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/env",
"args": [
"python3",
"-c",
@@ -107,7 +84,6 @@
"/usr/bin/ccache",
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -125,26 +101,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -155,33 +124,30 @@
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes",
"PYTHONPATH=/somepath/test_binary"
- ]
+ ],
+ "path": "/usr/bin/env"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"BISECT_STAGE=someBisectStage",
"BISECT_DIR=someBisectDir",
"HOME=/user/home"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/env",
"args": [
"python3",
"-c",
@@ -191,7 +157,6 @@
"/usr/bin/ccache",
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -209,26 +174,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -239,12 +197,30 @@
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes",
"PYTHONPATH=/somepath/test_binary"
- ]
+ ],
+ "path": "/usr/bin/env"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "env": [
+ "BISECT_STAGE=someBisectStage",
+ "BISECT_DIR=someBisectDir",
+ "HOME=/user/home"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_golden/clang_ftrapv_maincc_target_specific.json b/compiler_wrapper/testdata/cros_hardened_golden/clang_ftrapv_maincc_target_specific.json
index 83d7a8df..2e0fcaa5 100644
--- a/compiler_wrapper/testdata/cros_hardened_golden/clang_ftrapv_maincc_target_specific.json
+++ b/compiler_wrapper/testdata/cros_hardened_golden/clang_ftrapv_maincc_target_specific.json
@@ -1,23 +1,11 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "-ftrapv",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -35,27 +23,20 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-ftrapv",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -65,30 +46,29 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-eabi-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-eabi",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -106,27 +86,20 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-eabi-",
"-ftrapv",
"main.cc",
"-L/usr/x86_64-cros-eabi/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -136,30 +109,29 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-win-gnu-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-eabi-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-win-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -177,27 +149,20 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-win-gnu-",
"-ftrapv",
"main.cc",
"-L/usr/x86_64-cros-win-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -207,30 +172,29 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-linux-gnu-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-win-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv7m-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -248,27 +212,20 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-static-libgcc",
"-mthumb",
"--prefix=../../bin/armv7m-cros-linux-gnu-",
"-ftrapv",
"main.cc",
"-L/usr/armv7m-cros-linux-gnu/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv7m-cros-linux-gnu"
@@ -277,30 +234,29 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-eabi-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv7m-cros-eabi",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -318,27 +274,20 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/armv7m-cros-eabi-",
"-ftrapv",
"main.cc",
"-L/usr/armv7m-cros-eabi/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv7m-cros-eabi"
@@ -347,30 +296,29 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-win-gnu-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-eabi-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv7m-cros-win-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -388,27 +336,20 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-static-libgcc",
"-mthumb",
"--prefix=../../bin/armv7m-cros-win-gnu-",
"-ftrapv",
"main.cc",
"-L/usr/armv7m-cros-win-gnu/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv7m-cros-win-gnu"
@@ -417,30 +358,29 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-linux-gnu-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-win-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv8m-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -458,27 +398,20 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-static-libgcc",
"-mthumb",
"--prefix=../../bin/armv8m-cros-linux-gnu-",
"-ftrapv",
"main.cc",
"-L/usr/armv8m-cros-linux-gnu/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv8m-cros-linux-gnu"
@@ -487,30 +420,29 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-eabi-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv8m-cros-eabi",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -528,27 +460,20 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/armv8m-cros-eabi-",
"-ftrapv",
"main.cc",
"-L/usr/armv8m-cros-eabi/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv8m-cros-eabi"
@@ -557,30 +482,29 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-win-gnu-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-eabi-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv8m-cros-win-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -598,27 +522,20 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-static-libgcc",
"-mthumb",
"--prefix=../../bin/armv8m-cros-win-gnu-",
"-ftrapv",
"main.cc",
"-L/usr/armv8m-cros-win-gnu/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv8m-cros-win-gnu"
@@ -627,9 +544,20 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "-ftrapv",
+ "main.cc"
+ ],
+ "path": "./armv8m-cros-win-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_golden/clang_maincc_target_specific.json b/compiler_wrapper/testdata/cros_hardened_golden/clang_maincc_target_specific.json
index d072960a..739fe183 100644
--- a/compiler_wrapper/testdata/cros_hardened_golden/clang_maincc_target_specific.json
+++ b/compiler_wrapper/testdata/cros_hardened_golden/clang_maincc_target_specific.json
@@ -1,22 +1,11 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -34,26 +23,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -63,29 +45,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-eabi-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-eabi",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -103,26 +84,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-eabi-",
"main.cc",
"-L/usr/x86_64-cros-eabi/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -132,29 +106,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-win-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-eabi-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-win-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -172,26 +145,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-win-gnu-",
"main.cc",
"-L/usr/x86_64-cros-win-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -201,29 +167,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-win-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv7m-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -241,26 +206,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-static-libgcc",
"-mthumb",
"--prefix=../../bin/armv7m-cros-linux-gnu-",
"main.cc",
"-L/usr/armv7m-cros-linux-gnu/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv7m-cros-linux-gnu"
@@ -269,29 +227,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-eabi-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv7m-cros-eabi",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -309,26 +266,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/armv7m-cros-eabi-",
"main.cc",
"-L/usr/armv7m-cros-eabi/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv7m-cros-eabi"
@@ -337,29 +287,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-win-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-eabi-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv7m-cros-win-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -377,26 +326,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-static-libgcc",
"-mthumb",
"--prefix=../../bin/armv7m-cros-win-gnu-",
"main.cc",
"-L/usr/armv7m-cros-win-gnu/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv7m-cros-win-gnu"
@@ -405,29 +347,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-win-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv8m-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -445,26 +386,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-static-libgcc",
"-mthumb",
"--prefix=../../bin/armv8m-cros-linux-gnu-",
"main.cc",
"-L/usr/armv8m-cros-linux-gnu/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv8m-cros-linux-gnu"
@@ -473,29 +407,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-eabi-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv8m-cros-eabi",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -513,26 +446,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/armv8m-cros-eabi-",
"main.cc",
"-L/usr/armv8m-cros-eabi/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv8m-cros-eabi"
@@ -541,29 +467,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-win-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-eabi-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv8m-cros-win-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -581,26 +506,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-static-libgcc",
"-mthumb",
"--prefix=../../bin/armv8m-cros-win-gnu-",
"main.cc",
"-L/usr/armv8m-cros-win-gnu/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv8m-cros-win-gnu"
@@ -609,9 +527,19 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./armv8m-cros-win-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_golden/clang_path.json b/compiler_wrapper/testdata/cros_hardened_golden/clang_path.json
index fc120977..fe64e2da 100644
--- a/compiler_wrapper/testdata/cros_hardened_golden/clang_path.json
+++ b/compiler_wrapper/testdata/cros_hardened_golden/clang_path.json
@@ -1,22 +1,11 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -34,26 +23,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -63,32 +45,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -106,26 +84,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -135,32 +106,34 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang++",
"args": [
"main.cc"
- ]
- }
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang++",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -178,27 +151,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
- "-std=gnu++14",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -208,32 +173,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "CLANG=somepath/clang"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang++"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"somepath/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -251,26 +212,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -280,39 +234,40 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
+ "env": [
+ "CLANG=somepath/clang"
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-Xclang-path=/somedir",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"/somedir/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -330,14 +285,14 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
@@ -345,13 +300,6 @@
"--gcc-toolchain=/usr",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -361,42 +309,38 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-Xclang-path=/somedir",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"/somedir/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -414,14 +358,14 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
@@ -429,53 +373,45 @@
"--gcc-toolchain=/usr",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
+ ],
+ "env": [
+ "GOMACC_PATH=/tmp/stable/gomacc"
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-Xclang-path=/somedir",
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"/somedir/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -493,14 +429,14 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
@@ -508,13 +444,6 @@
"--gcc-toolchain=/usr",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -524,32 +453,35 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/x86_64-cros-linux-gnu-clang",
"args": [
+ "-Xclang-path=/somedir",
"main.cc"
- ]
- }
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"/usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -567,26 +499,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -596,29 +521,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"a/b/c/d/e/usr/bin/clang",
"--sysroot=/tmp/stable/a/b/c/d/e/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -636,26 +560,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=a/b/c/d/e/bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/tmp/stable/a/b/c/d/e/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-Ba/b/c/d/e/bin",
"-target",
@@ -665,29 +582,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./symlinked/x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"a/b/c/d/e/usr/bin/clang",
"--sysroot=/tmp/stable/a/b/c/d/e/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -705,26 +621,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=a/b/c/d/e/bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/tmp/stable/a/b/c/d/e/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-Ba/b/c/d/e/bin",
"-target",
@@ -734,29 +643,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "somedir/x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./symlinked/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../usr/bin/clang",
"--sysroot=/tmp/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -774,26 +682,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/tmp/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../bin",
"-target",
@@ -803,32 +704,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "PATH=/tmp/stable/pathenv"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "somedir/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"/tmp/usr/bin/clang",
"--sysroot=/tmp/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -846,26 +743,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/tmp/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../bin",
"-target",
@@ -875,9 +765,22 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "env": [
+ "PATH=/tmp/stable/pathenv"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "x86_64-cros-linux-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_golden/clang_sanitizer_args.json b/compiler_wrapper/testdata/cros_hardened_golden/clang_sanitizer_args.json
index 0c9376cd..25eabd19 100644
--- a/compiler_wrapper/testdata/cros_hardened_golden/clang_sanitizer_args.json
+++ b/compiler_wrapper/testdata/cros_hardened_golden/clang_sanitizer_args.json
@@ -1,20 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "-fsanitize=kernel-address",
- "-Wl,--no-undefined",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -35,12 +23,11 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
"-fno-omit-frame-pointer",
@@ -49,13 +36,6 @@
"-fsanitize=kernel-address",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -65,27 +45,27 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-fsanitize=kernel-address",
- "-Wl,-z,defs",
+ "-Wl,--no-undefined",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -106,12 +86,11 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
"-fno-omit-frame-pointer",
@@ -120,13 +99,6 @@
"-fsanitize=kernel-address",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -136,27 +108,27 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-fsanitize=kernel-address",
- "-D_FORTIFY_SOURCE=1",
+ "-Wl,-z,defs",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -177,12 +149,11 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
"-fno-omit-frame-pointer",
@@ -191,13 +162,6 @@
"-fsanitize=kernel-address",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -207,27 +171,27 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-fsanitize=kernel-address",
- "-D_FORTIFY_SOURCE=2",
+ "-D_FORTIFY_SOURCE=1",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -248,12 +212,11 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
"-fno-omit-frame-pointer",
@@ -262,13 +225,6 @@
"-fsanitize=kernel-address",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -278,26 +234,27 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-fsanitize=fuzzer",
+ "-fsanitize=kernel-address",
+ "-D_FORTIFY_SOURCE=2",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -318,12 +275,11 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
"-fno-omit-frame-pointer",
@@ -332,13 +288,6 @@
"-fsanitize=fuzzer",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -348,27 +297,26 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-fsanitize=address",
- "-fprofile-instr-generate",
+ "-fsanitize=fuzzer",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -389,12 +337,11 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
"-fno-omit-frame-pointer",
@@ -404,13 +351,6 @@
"-fprofile-instr-generate",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -420,26 +360,27 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-fsanitize=address",
+ "-fprofile-instr-generate",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -460,12 +401,11 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
"-fno-omit-frame-pointer",
@@ -474,13 +414,6 @@
"-fsanitize=address",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -490,30 +423,29 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-fprofile-instr-generate",
+ "-fsanitize=address",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -531,27 +463,20 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-fprofile-instr-generate",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -561,9 +486,20 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "-fprofile-instr-generate",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_golden/clang_specific_args.json b/compiler_wrapper/testdata/cros_hardened_golden/clang_specific_args.json
index d7f73998..f5c11299 100644
--- a/compiler_wrapper/testdata/cros_hardened_golden/clang_specific_args.json
+++ b/compiler_wrapper/testdata/cros_hardened_golden/clang_specific_args.json
@@ -1,32 +1,11 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "-mno-movbe",
- "-Wclobbered",
- "-Wno-psabi",
- "-Wlogical-op",
- "-Wmissing-parameter-type",
- "-Wold-style-declaration",
- "-Woverride-init",
- "-Wunsafe-loop-optimizations",
- "-Wstrict-aliasing=abc",
- "-finline-limit=abc",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -44,14 +23,14 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
@@ -65,13 +44,6 @@
"-Wunsafe-loop-optimizations",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -81,30 +53,38 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-Wno-error=cpp",
+ "-mno-movbe",
+ "-Wclobbered",
+ "-Wno-psabi",
+ "-Wlogical-op",
+ "-Wmissing-parameter-type",
+ "-Wold-style-declaration",
+ "-Woverride-init",
+ "-Wunsafe-loop-optimizations",
+ "-Wstrict-aliasing=abc",
+ "-finline-limit=abc",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -122,27 +102,20 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-Wno-#warnings",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -152,30 +125,29 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-Wno-error=maybe-uninitialized",
+ "-Wno-error=cpp",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -193,27 +165,20 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-Wno-error=uninitialized",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -223,30 +188,29 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-Xclang-only=-someflag",
+ "-Wno-error=maybe-uninitialized",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -264,27 +228,20 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-someflag",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -294,9 +251,20 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "-Xclang-only=-someflag",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_golden/clang_sysroot_wrapper_common.json b/compiler_wrapper/testdata/cros_hardened_golden/clang_sysroot_wrapper_common.json
index 537fc89c..7136b3f4 100644
--- a/compiler_wrapper/testdata/cros_hardened_golden/clang_sysroot_wrapper_common.json
+++ b/compiler_wrapper/testdata/cros_hardened_golden/clang_sysroot_wrapper_common.json
@@ -1,58 +1,44 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "-noccache",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc.real",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
"-mno-movbe"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "GOMACC_PATH=someNonExistingPath"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
+ "-noccache",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -70,26 +56,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -99,32 +78,31 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
- "GOMACC_PATH=/tmp/stable/gomacc"
+ "GOMACC_PATH=someNonExistingPath"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -142,54 +120,48 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
+ ],
+ "env": [
+ "GOMACC_PATH=/tmp/stable/gomacc"
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-nopie",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -207,27 +179,20 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-nopie",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -237,30 +202,29 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-D__KERNEL__",
+ "-nopie",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -278,13 +242,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"-fno-stack-protector",
@@ -292,13 +256,6 @@
"-D__KERNEL__",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -308,30 +265,29 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7a-cros-linux-gnueabihf-clang",
"args": [
"-D__KERNEL__",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv7a-cros-linux-gnueabihf",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -349,13 +305,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
+ "-D_FORTIFY_SOURCE=3",
"-static-libgcc",
"-mthumb",
"-fno-stack-protector",
@@ -363,13 +319,6 @@
"-D__KERNEL__",
"main.cc",
"-L/usr/armv7a-cros-linux-gnueabihf/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv7a-cros-linux-gnueabihf"
@@ -378,29 +327,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "--sysroot=xyz",
+ "-D__KERNEL__",
"main.cc"
- ]
+ ],
+ "path": "./armv7a-cros-linux-gnueabihf-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -418,27 +366,20 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"--sysroot=xyz",
"main.cc",
"-Lxyz/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -448,9 +389,20 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "--sysroot=xyz",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_golden/clangtidy.json b/compiler_wrapper/testdata/cros_hardened_golden/clangtidy.json
index 5d88fec8..04ba8442 100644
--- a/compiler_wrapper/testdata/cros_hardened_golden/clangtidy.json
+++ b/compiler_wrapper/testdata/cros_hardened_golden/clangtidy.json
@@ -1,37 +1,23 @@
[
{
- "wd": "/tmp/stable",
- "env": [
- "WITH_TIDY=1"
- ],
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "../../usr/bin/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
"--",
"-resource-dir=someResourceDir",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -49,39 +35,31 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang-tidy"
}
},
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -99,69 +77,60 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
- "WITH_TIDY=1",
- "GOMACC_PATH=/tmp/stable/gomacc"
+ "WITH_TIDY=1"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "../../usr/bin/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
"--",
"-resource-dir=someResourceDir",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -179,40 +148,32 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang-tidy"
}
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -230,71 +191,61 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"WITH_TIDY=1",
"GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerrorclang-tidy failed"
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "../../usr/bin/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
"--",
"-resource-dir=someResourceDir",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -312,43 +263,35 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang-tidy"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -366,72 +309,63 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"WITH_TIDY=1",
"GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
},
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ "stderr": "someerrorclang-tidy failed",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "../../usr/bin/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
"--",
"-resource-dir=someResourceDir",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -449,40 +383,32 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang-tidy"
}
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -500,36 +426,46 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "env": [
+ "WITH_TIDY=1",
+ "GOMACC_PATH=/tmp/stable/gomacc"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_golden/force_disable_werror.json b/compiler_wrapper/testdata/cros_hardened_golden/force_disable_werror.json
index 3d1e305e..ebff9f99 100644
--- a/compiler_wrapper/testdata/cros_hardened_golden/force_disable_werror.json
+++ b/compiler_wrapper/testdata/cros_hardened_golden/force_disable_werror.json
@@ -1,25 +1,11 @@
[
{
- "wd": "/tmp/stable",
- "env": [
- "FORCE_DISABLE_WERROR=1"
- ],
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -37,26 +23,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -66,33 +45,31 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"FORCE_DISABLE_WERROR=1"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "$CROS_ARTIFACTS_TMP_DIR is not set, artifacts will be written to /tmp"
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -110,26 +87,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -139,18 +109,17 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "ccache"
},
- "stderr": "-Werror originalerror",
- "exitcode": 1
+ "exitcode": 1,
+ "stderr": "error: foo [-Werror,-Wfoo]"
},
{
"cmd": {
- "path": "ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -168,26 +137,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -199,34 +161,32 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"FORCE_DISABLE_WERROR=1"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
},
- "stderr": "-Werror originalerror",
- "exitcode": 1
- },
+ "stdout": "$CROS_ARTIFACTS_TMP_DIR is not set, artifacts will be written to /tmp"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -244,26 +204,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -273,18 +226,17 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "ccache"
},
- "stderr": "-Werror originalerror",
- "exitcode": 1
+ "exitcode": 1,
+ "stderr": "error: foo [-Werror,-Wfoo]"
},
{
"cmd": {
- "path": "ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -302,26 +254,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -333,12 +278,27 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "ccache"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "env": [
+ "FORCE_DISABLE_WERROR=1"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "error: foo [-Werror,-Wfoo]"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_golden/gcc_clang_syntax.json b/compiler_wrapper/testdata/cros_hardened_golden/gcc_clang_syntax.json
index 9d17797a..21f154db 100644
--- a/compiler_wrapper/testdata/cros_hardened_golden/gcc_clang_syntax.json
+++ b/compiler_wrapper/testdata/cros_hardened_golden/gcc_clang_syntax.json
@@ -1,22 +1,10 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "-clang-syntax",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -34,47 +22,40 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu",
"-fsyntax-only",
"-stdlib=libstdc++"
- ]
+ ],
+ "path": "../../usr/bin/clang"
}
},
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -84,33 +65,29 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-clang-syntax",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -128,78 +105,70 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu",
"-fsyntax-only",
"-stdlib=libstdc++"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
"-mno-movbe"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
+ ],
+ "env": [
+ "GOMACC_PATH=/tmp/stable/gomacc"
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-clang-syntax",
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -217,61 +186,53 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu",
"-fsyntax-only",
"-stdlib=libstdc++"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-clang-syntax",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
- },
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -289,47 +250,40 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu",
"-fsyntax-only",
"-stdlib=libstdc++"
- ]
+ ],
+ "path": "../../usr/bin/clang"
}
},
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -339,12 +293,26 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "-clang-syntax",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_golden/gcc_maincc_target_specific.json b/compiler_wrapper/testdata/cros_hardened_golden/gcc_maincc_target_specific.json
index 86745dc6..fcf769b8 100644
--- a/compiler_wrapper/testdata/cros_hardened_golden/gcc_maincc_target_specific.json
+++ b/compiler_wrapper/testdata/cros_hardened_golden/gcc_maincc_target_specific.json
@@ -1,27 +1,17 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -31,34 +21,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-eabi-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-eabi-gcc.real",
"--sysroot=/usr/x86_64-cros-eabi",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -68,34 +58,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-win-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-eabi-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-win-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-win-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -105,34 +95,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-win-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./armv7m-cros-linux-gnu-gcc.real",
"--sysroot=/usr/armv7m-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-static-libgcc",
"-mthumb",
"main.cc",
@@ -141,34 +131,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-eabi-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./armv7m-cros-eabi-gcc.real",
"--sysroot=/usr/armv7m-cros-eabi",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -177,34 +167,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-win-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-eabi-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./armv7m-cros-win-gnu-gcc.real",
"--sysroot=/usr/armv7m-cros-win-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-static-libgcc",
"-mthumb",
"main.cc",
@@ -213,34 +203,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-win-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./armv8m-cros-linux-gnu-gcc.real",
"--sysroot=/usr/armv8m-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-static-libgcc",
"-mthumb",
"main.cc",
@@ -249,34 +239,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-eabi-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./armv8m-cros-eabi-gcc.real",
"--sysroot=/usr/armv8m-cros-eabi",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -285,34 +275,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-win-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-eabi-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./armv8m-cros-win-gnu-gcc.real",
"--sysroot=/usr/armv8m-cros-win-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-static-libgcc",
"-mthumb",
"main.cc",
@@ -321,9 +311,19 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./armv8m-cros-win-gnu-gcc"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_golden/gcc_path.json b/compiler_wrapper/testdata/cros_hardened_golden/gcc_path.json
index b6f3d1d9..32bbd8fc 100644
--- a/compiler_wrapper/testdata/cros_hardened_golden/gcc_path.json
+++ b/compiler_wrapper/testdata/cros_hardened_golden/gcc_path.json
@@ -1,27 +1,17 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -31,37 +21,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -71,37 +58,40 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
- }
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"/tmp/stable/x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -111,34 +101,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/tmp/stable/a/b/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -148,34 +138,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./symlinked/x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./symlinked/x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/tmp/stable/a/b/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -185,37 +175,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "PATH=/tmp/stable/pathenv"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./symlinked/x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"/tmp/stable/pathenv/x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -225,9 +212,22 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "env": [
+ "PATH=/tmp/stable/pathenv"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "x86_64-cros-linux-gnu-gcc"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_golden/gcc_sanitizer_args.json b/compiler_wrapper/testdata/cros_hardened_golden/gcc_sanitizer_args.json
index 0552bf7c..7a48c5d6 100644
--- a/compiler_wrapper/testdata/cros_hardened_golden/gcc_sanitizer_args.json
+++ b/compiler_wrapper/testdata/cros_hardened_golden/gcc_sanitizer_args.json
@@ -1,29 +1,17 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "-fsanitize=kernel-address",
- "-Wl,--no-undefined",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"-fsanitize=kernel-address",
@@ -34,36 +22,36 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-fsanitize=kernel-address",
- "-Wl,-z,defs",
+ "-Wl,--no-undefined",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"-fsanitize=kernel-address",
@@ -74,36 +62,36 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-fsanitize=kernel-address",
- "-D_FORTIFY_SOURCE=1",
+ "-Wl,-z,defs",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"-fsanitize=kernel-address",
@@ -114,36 +102,36 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-fsanitize=kernel-address",
- "-D_FORTIFY_SOURCE=2",
+ "-D_FORTIFY_SOURCE=1",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"-fsanitize=kernel-address",
@@ -154,35 +142,36 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
- "-fsanitize=fuzzer",
+ "-fsanitize=kernel-address",
+ "-D_FORTIFY_SOURCE=2",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"-fsanitize=fuzzer",
@@ -193,36 +182,35 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
- "-fsanitize=address",
- "-fprofile-instr-generate",
+ "-fsanitize=fuzzer",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"-fsanitize=address",
@@ -234,35 +222,36 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-fsanitize=address",
+ "-fprofile-instr-generate",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"-fsanitize=address",
@@ -273,35 +262,35 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
- "-fprofile-instr-generate",
+ "-fsanitize=address",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"-fprofile-instr-generate",
@@ -312,9 +301,20 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "-fprofile-instr-generate",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_golden/gcc_specific_args.json b/compiler_wrapper/testdata/cros_hardened_golden/gcc_specific_args.json
index 52c9f2cc..8308caad 100644
--- a/compiler_wrapper/testdata/cros_hardened_golden/gcc_specific_args.json
+++ b/compiler_wrapper/testdata/cros_hardened_golden/gcc_specific_args.json
@@ -1,28 +1,17 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "-march=goldmont",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"-march=goldmont",
@@ -33,35 +22,35 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
- "-march=goldmont-plus",
+ "-march=goldmont",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"-march=goldmont-plus",
@@ -72,35 +61,35 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
- "-march=skylake",
+ "-march=goldmont-plus",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"-march=skylake",
@@ -111,9 +100,20 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "-march=skylake",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_golden/gcc_sysroot_wrapper_common.json b/compiler_wrapper/testdata/cros_hardened_golden/gcc_sysroot_wrapper_common.json
index 8b28e6e2..43bf4658 100644
--- a/compiler_wrapper/testdata/cros_hardened_golden/gcc_sysroot_wrapper_common.json
+++ b/compiler_wrapper/testdata/cros_hardened_golden/gcc_sysroot_wrapper_common.json
@@ -1,63 +1,50 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "-noccache",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc.real",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
"-mno-movbe"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "GOMACC_PATH=someNonExistingPath"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
+ "-noccache",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -67,71 +54,73 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
- "GOMACC_PATH=/tmp/stable/gomacc"
+ "GOMACC_PATH=someNonExistingPath"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
"-mno-movbe"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
+ ],
+ "env": [
+ "GOMACC_PATH=/tmp/stable/gomacc"
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
- "-nopie",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"-nopie",
@@ -142,34 +131,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
- "-D__KERNEL__",
+ "-nopie",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"-fno-stack-protector",
@@ -181,34 +170,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7a-cros-linux-gnueabihf-gcc",
"args": [
"-D__KERNEL__",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./armv7a-cros-linux-gnueabihf-gcc.real",
"--sysroot=/usr/armv7a-cros-linux-gnueabihf",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
+ "-D_FORTIFY_SOURCE=3",
"-static-libgcc",
"-mthumb",
"-fno-stack-protector",
@@ -219,34 +208,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
- "--sysroot=xyz",
+ "-D__KERNEL__",
"main.cc"
- ]
+ ],
+ "path": "./armv7a-cros-linux-gnueabihf-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--sysroot=xyz",
@@ -257,9 +246,20 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "--sysroot=xyz",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/bisect.json b/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/bisect.json
index b4cdd8d2..e13331c2 100644
--- a/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/bisect.json
+++ b/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/bisect.json
@@ -1,22 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "env": [
- "BISECT_STAGE=someBisectStage",
- "HOME=/user/home"
- ],
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/env",
"args": [
"python3",
"-c",
@@ -26,7 +12,6 @@
"/usr/bin/ccache",
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -44,26 +29,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -74,30 +52,29 @@
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes",
"PYTHONPATH=/somepath/test_binary"
- ]
+ ],
+ "path": "/usr/bin/env"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"BISECT_STAGE=someBisectStage",
- "BISECT_DIR=someBisectDir",
"HOME=/user/home"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/env",
"args": [
"python3",
"-c",
@@ -107,7 +84,6 @@
"/usr/bin/ccache",
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -125,26 +101,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -155,33 +124,30 @@
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes",
"PYTHONPATH=/somepath/test_binary"
- ]
+ ],
+ "path": "/usr/bin/env"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"BISECT_STAGE=someBisectStage",
"BISECT_DIR=someBisectDir",
"HOME=/user/home"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/env",
"args": [
"python3",
"-c",
@@ -191,7 +157,6 @@
"/usr/bin/ccache",
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -209,26 +174,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -239,12 +197,30 @@
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes",
"PYTHONPATH=/somepath/test_binary"
- ]
+ ],
+ "path": "/usr/bin/env"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "env": [
+ "BISECT_STAGE=someBisectStage",
+ "BISECT_DIR=someBisectDir",
+ "HOME=/user/home"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/clang_path.json b/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/clang_path.json
index fc120977..fe64e2da 100644
--- a/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/clang_path.json
+++ b/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/clang_path.json
@@ -1,22 +1,11 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -34,26 +23,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -63,32 +45,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -106,26 +84,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -135,32 +106,34 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang++",
"args": [
"main.cc"
- ]
- }
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang++",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -178,27 +151,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
- "-std=gnu++14",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -208,32 +173,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "CLANG=somepath/clang"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang++"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"somepath/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -251,26 +212,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -280,39 +234,40 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
+ "env": [
+ "CLANG=somepath/clang"
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-Xclang-path=/somedir",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"/somedir/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -330,14 +285,14 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
@@ -345,13 +300,6 @@
"--gcc-toolchain=/usr",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -361,42 +309,38 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-Xclang-path=/somedir",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"/somedir/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -414,14 +358,14 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
@@ -429,53 +373,45 @@
"--gcc-toolchain=/usr",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
+ ],
+ "env": [
+ "GOMACC_PATH=/tmp/stable/gomacc"
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-Xclang-path=/somedir",
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"/somedir/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -493,14 +429,14 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
@@ -508,13 +444,6 @@
"--gcc-toolchain=/usr",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -524,32 +453,35 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/x86_64-cros-linux-gnu-clang",
"args": [
+ "-Xclang-path=/somedir",
"main.cc"
- ]
- }
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"/usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -567,26 +499,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -596,29 +521,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"a/b/c/d/e/usr/bin/clang",
"--sysroot=/tmp/stable/a/b/c/d/e/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -636,26 +560,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=a/b/c/d/e/bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/tmp/stable/a/b/c/d/e/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-Ba/b/c/d/e/bin",
"-target",
@@ -665,29 +582,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./symlinked/x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"a/b/c/d/e/usr/bin/clang",
"--sysroot=/tmp/stable/a/b/c/d/e/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -705,26 +621,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=a/b/c/d/e/bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/tmp/stable/a/b/c/d/e/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-Ba/b/c/d/e/bin",
"-target",
@@ -734,29 +643,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "somedir/x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./symlinked/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../usr/bin/clang",
"--sysroot=/tmp/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -774,26 +682,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/tmp/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../bin",
"-target",
@@ -803,32 +704,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "PATH=/tmp/stable/pathenv"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "somedir/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"/tmp/usr/bin/clang",
"--sysroot=/tmp/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -846,26 +743,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/tmp/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../bin",
"-target",
@@ -875,9 +765,22 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "env": [
+ "PATH=/tmp/stable/pathenv"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "x86_64-cros-linux-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/clangtidy.json b/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/clangtidy.json
index 5d88fec8..04ba8442 100644
--- a/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/clangtidy.json
+++ b/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/clangtidy.json
@@ -1,37 +1,23 @@
[
{
- "wd": "/tmp/stable",
- "env": [
- "WITH_TIDY=1"
- ],
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "../../usr/bin/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
"--",
"-resource-dir=someResourceDir",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -49,39 +35,31 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang-tidy"
}
},
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -99,69 +77,60 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
- "WITH_TIDY=1",
- "GOMACC_PATH=/tmp/stable/gomacc"
+ "WITH_TIDY=1"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "../../usr/bin/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
"--",
"-resource-dir=someResourceDir",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -179,40 +148,32 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang-tidy"
}
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -230,71 +191,61 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"WITH_TIDY=1",
"GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerrorclang-tidy failed"
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "../../usr/bin/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
"--",
"-resource-dir=someResourceDir",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -312,43 +263,35 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang-tidy"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -366,72 +309,63 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"WITH_TIDY=1",
"GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
},
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ "stderr": "someerrorclang-tidy failed",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "../../usr/bin/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
"--",
"-resource-dir=someResourceDir",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -449,40 +383,32 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang-tidy"
}
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -500,36 +426,46 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "env": [
+ "WITH_TIDY=1",
+ "GOMACC_PATH=/tmp/stable/gomacc"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/force_disable_werror.json b/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/force_disable_werror.json
index 3d1e305e..ebff9f99 100644
--- a/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/force_disable_werror.json
+++ b/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/force_disable_werror.json
@@ -1,25 +1,11 @@
[
{
- "wd": "/tmp/stable",
- "env": [
- "FORCE_DISABLE_WERROR=1"
- ],
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -37,26 +23,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -66,33 +45,31 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"FORCE_DISABLE_WERROR=1"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "$CROS_ARTIFACTS_TMP_DIR is not set, artifacts will be written to /tmp"
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -110,26 +87,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -139,18 +109,17 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "ccache"
},
- "stderr": "-Werror originalerror",
- "exitcode": 1
+ "exitcode": 1,
+ "stderr": "error: foo [-Werror,-Wfoo]"
},
{
"cmd": {
- "path": "ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -168,26 +137,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -199,34 +161,32 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"FORCE_DISABLE_WERROR=1"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
},
- "stderr": "-Werror originalerror",
- "exitcode": 1
- },
+ "stdout": "$CROS_ARTIFACTS_TMP_DIR is not set, artifacts will be written to /tmp"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -244,26 +204,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -273,18 +226,17 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "ccache"
},
- "stderr": "-Werror originalerror",
- "exitcode": 1
+ "exitcode": 1,
+ "stderr": "error: foo [-Werror,-Wfoo]"
},
{
"cmd": {
- "path": "ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -302,26 +254,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -333,12 +278,27 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "ccache"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "env": [
+ "FORCE_DISABLE_WERROR=1"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "error: foo [-Werror,-Wfoo]"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/gcc_clang_syntax.json b/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/gcc_clang_syntax.json
index 9d17797a..21f154db 100644
--- a/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/gcc_clang_syntax.json
+++ b/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/gcc_clang_syntax.json
@@ -1,22 +1,10 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "-clang-syntax",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -34,47 +22,40 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu",
"-fsyntax-only",
"-stdlib=libstdc++"
- ]
+ ],
+ "path": "../../usr/bin/clang"
}
},
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -84,33 +65,29 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-clang-syntax",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -128,78 +105,70 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu",
"-fsyntax-only",
"-stdlib=libstdc++"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
"-mno-movbe"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
+ ],
+ "env": [
+ "GOMACC_PATH=/tmp/stable/gomacc"
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-clang-syntax",
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -217,61 +186,53 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu",
"-fsyntax-only",
"-stdlib=libstdc++"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-clang-syntax",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
- },
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -289,47 +250,40 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu",
"-fsyntax-only",
"-stdlib=libstdc++"
- ]
+ ],
+ "path": "../../usr/bin/clang"
}
},
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -339,12 +293,26 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "-clang-syntax",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/gcc_path.json b/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/gcc_path.json
index b6f3d1d9..32bbd8fc 100644
--- a/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/gcc_path.json
+++ b/compiler_wrapper/testdata/cros_hardened_llvmnext_golden/gcc_path.json
@@ -1,27 +1,17 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -31,37 +21,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -71,37 +58,40 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
- }
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"/tmp/stable/x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -111,34 +101,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/tmp/stable/a/b/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -148,34 +138,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./symlinked/x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./symlinked/x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/tmp/stable/a/b/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -185,37 +175,34 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "PATH=/tmp/stable/pathenv"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./symlinked/x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"/tmp/stable/pathenv/x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
@@ -225,9 +212,22 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "env": [
+ "PATH=/tmp/stable/pathenv"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "x86_64-cros-linux-gnu-gcc"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_noccache_golden/bisect.json b/compiler_wrapper/testdata/cros_hardened_noccache_golden/bisect.json
index b476031b..b1e3f291 100644
--- a/compiler_wrapper/testdata/cros_hardened_noccache_golden/bisect.json
+++ b/compiler_wrapper/testdata/cros_hardened_noccache_golden/bisect.json
@@ -1,22 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "env": [
- "BISECT_STAGE=someBisectStage",
- "HOME=/user/home"
- ],
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/env",
"args": [
"python3",
"-c",
@@ -25,7 +11,6 @@
"/tmp/sysroot_bisect",
"/usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -43,26 +28,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -70,30 +48,29 @@
],
"env_updates": [
"PYTHONPATH=/somepath/test_binary"
- ]
+ ],
+ "path": "/usr/bin/env"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"BISECT_STAGE=someBisectStage",
- "BISECT_DIR=someBisectDir",
"HOME=/user/home"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/env",
"args": [
"python3",
"-c",
@@ -102,7 +79,6 @@
"someBisectDir",
"/usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -120,26 +96,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -147,33 +116,30 @@
],
"env_updates": [
"PYTHONPATH=/somepath/test_binary"
- ]
+ ],
+ "path": "/usr/bin/env"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"BISECT_STAGE=someBisectStage",
"BISECT_DIR=someBisectDir",
"HOME=/user/home"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/env",
"args": [
"python3",
"-c",
@@ -182,7 +148,6 @@
"someBisectDir",
"/usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -200,26 +165,19 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -227,12 +185,30 @@
],
"env_updates": [
"PYTHONPATH=/somepath/test_binary"
- ]
+ ],
+ "path": "/usr/bin/env"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "env": [
+ "BISECT_STAGE=someBisectStage",
+ "BISECT_DIR=someBisectDir",
+ "HOME=/user/home"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_noccache_golden/clang_path.json b/compiler_wrapper/testdata/cros_hardened_noccache_golden/clang_path.json
index 3849ecf8..c4d2517e 100644
--- a/compiler_wrapper/testdata/cros_hardened_noccache_golden/clang_path.json
+++ b/compiler_wrapper/testdata/cros_hardened_noccache_golden/clang_path.json
@@ -1,21 +1,10 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -33,55 +22,44 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -99,55 +77,50 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang++",
"args": [
"main.cc"
- ]
- }
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang++",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -165,56 +138,44 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
- "-std=gnu++14",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang++"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "CLANG=somepath/clang"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang++"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "somepath/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -232,62 +193,56 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "somepath/clang"
}
}
- ]
- },
- {
+ ],
+ "env": [
+ "CLANG=somepath/clang"
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-Xclang-path=/somedir",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/somedir/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -305,14 +260,14 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
@@ -320,53 +275,42 @@
"--gcc-toolchain=/usr",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/somedir/clang"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-Xclang-path=/somedir",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"/somedir/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -384,14 +328,14 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
@@ -399,52 +343,44 @@
"--gcc-toolchain=/usr",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
+ ],
+ "env": [
+ "GOMACC_PATH=/tmp/stable/gomacc"
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-Xclang-path=/somedir",
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/somedir/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -462,14 +398,14 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
@@ -477,42 +413,38 @@
"--gcc-toolchain=/usr",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/somedir/clang"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/x86_64-cros-linux-gnu-clang",
"args": [
+ "-Xclang-path=/somedir",
"main.cc"
- ]
- }
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -530,52 +462,44 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/usr/bin/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "a/b/c/d/e/usr/bin/clang",
"args": [
"--sysroot=/tmp/stable/a/b/c/d/e/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -593,52 +517,44 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=a/b/c/d/e/bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/tmp/stable/a/b/c/d/e/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-Ba/b/c/d/e/bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "a/b/c/d/e/usr/bin/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./symlinked/x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "a/b/c/d/e/usr/bin/clang",
"args": [
"--sysroot=/tmp/stable/a/b/c/d/e/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -656,52 +572,44 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=a/b/c/d/e/bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/tmp/stable/a/b/c/d/e/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-Ba/b/c/d/e/bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "a/b/c/d/e/usr/bin/clang"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "somedir/x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./symlinked/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../usr/bin/clang",
"args": [
"--sysroot=/tmp/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -719,55 +627,44 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/tmp/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../usr/bin/clang"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "PATH=/tmp/stable/pathenv"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "somedir/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/usr/bin/clang",
"args": [
"--sysroot=/tmp/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -785,33 +682,39 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/tmp/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/usr/bin/clang"
}
}
- ]
+ ],
+ "env": [
+ "PATH=/tmp/stable/pathenv"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "x86_64-cros-linux-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_noccache_golden/clangtidy.json b/compiler_wrapper/testdata/cros_hardened_noccache_golden/clangtidy.json
index 5d88fec8..04ba8442 100644
--- a/compiler_wrapper/testdata/cros_hardened_noccache_golden/clangtidy.json
+++ b/compiler_wrapper/testdata/cros_hardened_noccache_golden/clangtidy.json
@@ -1,37 +1,23 @@
[
{
- "wd": "/tmp/stable",
- "env": [
- "WITH_TIDY=1"
- ],
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "../../usr/bin/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
"--",
"-resource-dir=someResourceDir",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -49,39 +35,31 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang-tidy"
}
},
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -99,69 +77,60 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
- "WITH_TIDY=1",
- "GOMACC_PATH=/tmp/stable/gomacc"
+ "WITH_TIDY=1"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "../../usr/bin/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
"--",
"-resource-dir=someResourceDir",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -179,40 +148,32 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang-tidy"
}
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -230,71 +191,61 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"WITH_TIDY=1",
"GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerrorclang-tidy failed"
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "../../usr/bin/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
"--",
"-resource-dir=someResourceDir",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -312,43 +263,35 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang-tidy"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -366,72 +309,63 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"WITH_TIDY=1",
"GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
},
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ "stderr": "someerrorclang-tidy failed",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "../../usr/bin/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
"--",
"-resource-dir=someResourceDir",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -449,40 +383,32 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang-tidy"
}
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -500,36 +426,46 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "env": [
+ "WITH_TIDY=1",
+ "GOMACC_PATH=/tmp/stable/gomacc"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_noccache_golden/force_disable_werror.json b/compiler_wrapper/testdata/cros_hardened_noccache_golden/force_disable_werror.json
index a4b2d2b4..77485f0f 100644
--- a/compiler_wrapper/testdata/cros_hardened_noccache_golden/force_disable_werror.json
+++ b/compiler_wrapper/testdata/cros_hardened_noccache_golden/force_disable_werror.json
@@ -1,24 +1,10 @@
[
{
- "wd": "/tmp/stable",
- "env": [
- "FORCE_DISABLE_WERROR=1"
- ],
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -36,56 +22,47 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"FORCE_DISABLE_WERROR=1"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "$CROS_ARTIFACTS_TMP_DIR is not set, artifacts will be written to /tmp"
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -103,41 +80,33 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
- "stderr": "-Werror originalerror",
- "exitcode": 1
+ "exitcode": 1,
+ "stderr": "error: foo [-Werror,-Wfoo]"
},
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -155,59 +124,50 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu",
"-Wno-error",
"-Wno-error=poison-system-directories"
- ]
+ ],
+ "path": "../../usr/bin/clang"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"FORCE_DISABLE_WERROR=1"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
},
- "stderr": "-Werror originalerror",
- "exitcode": 1
- },
+ "stdout": "$CROS_ARTIFACTS_TMP_DIR is not set, artifacts will be written to /tmp"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -225,41 +185,33 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
- "stderr": "-Werror originalerror",
- "exitcode": 1
+ "exitcode": 1,
+ "stderr": "error: foo [-Werror,-Wfoo]"
},
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -277,38 +229,46 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu",
"-Wno-error",
"-Wno-error=poison-system-directories"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "env": [
+ "FORCE_DISABLE_WERROR=1"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "error: foo [-Werror,-Wfoo]"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_noccache_golden/gcc_clang_syntax.json b/compiler_wrapper/testdata/cros_hardened_noccache_golden/gcc_clang_syntax.json
index 091e00f5..c3402a44 100644
--- a/compiler_wrapper/testdata/cros_hardened_noccache_golden/gcc_clang_syntax.json
+++ b/compiler_wrapper/testdata/cros_hardened_noccache_golden/gcc_clang_syntax.json
@@ -1,22 +1,10 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "-clang-syntax",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -34,78 +22,67 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu",
"-fsyntax-only",
"-stdlib=libstdc++"
- ]
+ ],
+ "path": "../../usr/bin/clang"
}
},
{
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc.real",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
"-mno-movbe"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-clang-syntax",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -123,78 +100,70 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu",
"-fsyntax-only",
"-stdlib=libstdc++"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
"-mno-movbe"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
+ ],
+ "env": [
+ "GOMACC_PATH=/tmp/stable/gomacc"
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-clang-syntax",
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -212,61 +181,53 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu",
"-fsyntax-only",
"-stdlib=libstdc++"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-clang-syntax",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
- },
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-Qunused-arguments",
"-Werror=poison-system-directories",
"-Wno-compound-token-split-by-macro",
@@ -284,57 +245,64 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"--unwindlib=libunwind",
"-Wno-section",
"-fno-addrsig",
- "-fuse-ld=lld",
"-ftrivial-auto-var-init=zero",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu",
"-fsyntax-only",
"-stdlib=libstdc++"
- ]
+ ],
+ "path": "../../usr/bin/clang"
}
},
{
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc.real",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
"-mno-movbe"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc.real"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "-clang-syntax",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_hardened_noccache_golden/gcc_path.json b/compiler_wrapper/testdata/cros_hardened_noccache_golden/gcc_path.json
index ed60e6d6..6fe017ac 100644
--- a/compiler_wrapper/testdata/cros_hardened_noccache_golden/gcc_path.json
+++ b/compiler_wrapper/testdata/cros_hardened_noccache_golden/gcc_path.json
@@ -1,203 +1,203 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc.real",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
"-mno-movbe"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc.real",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
"-mno-movbe"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc.real"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
- }
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/x86_64-cros-linux-gnu-gcc.real",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
"-mno-movbe"
- ]
+ ],
+ "path": "/tmp/stable/x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-gcc.real",
"args": [
"--sysroot=/tmp/stable/a/b/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
"-L/tmp/stable/a/b/usr/x86_64-cros-linux-gnu/usr/lib64",
"-mno-movbe"
- ]
+ ],
+ "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./symlinked/x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "./symlinked/x86_64-cros-linux-gnu-gcc.real",
"args": [
"--sysroot=/tmp/stable/a/b/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
"-L/tmp/stable/a/b/usr/x86_64-cros-linux-gnu/usr/lib64",
"-mno-movbe"
- ]
+ ],
+ "path": "./symlinked/x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "PATH=/tmp/stable/pathenv"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./symlinked/x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/pathenv/x86_64-cros-linux-gnu-gcc.real",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
- "-D_FORTIFY_SOURCE=2",
"-fno-reorder-blocks-and-partition",
"-Wno-unused-local-typedefs",
"-Wno-maybe-uninitialized",
"-fcommon",
"-fstack-protector-strong",
+ "-D_FORTIFY_SOURCE=3",
"-fno-omit-frame-pointer",
"-static-libgcc",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
"-mno-movbe"
- ]
+ ],
+ "path": "/tmp/stable/pathenv/x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
+ ],
+ "env": [
+ "PATH=/tmp/stable/pathenv"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "x86_64-cros-linux-gnu-gcc"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_nonhardened_golden/bisect.json b/compiler_wrapper/testdata/cros_nonhardened_golden/bisect.json
index 9a71937a..c72cc990 100644
--- a/compiler_wrapper/testdata/cros_nonhardened_golden/bisect.json
+++ b/compiler_wrapper/testdata/cros_nonhardened_golden/bisect.json
@@ -1,22 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "env": [
- "BISECT_STAGE=someBisectStage",
- "HOME=/user/home"
- ],
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/env",
"args": [
"python3",
"-c",
@@ -43,19 +29,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -66,30 +45,29 @@
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes",
"PYTHONPATH=/somepath/test_binary"
- ]
+ ],
+ "path": "/usr/bin/env"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"BISECT_STAGE=someBisectStage",
- "BISECT_DIR=someBisectDir",
"HOME=/user/home"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/env",
"args": [
"python3",
"-c",
@@ -116,19 +94,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -139,33 +110,30 @@
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes",
"PYTHONPATH=/somepath/test_binary"
- ]
+ ],
+ "path": "/usr/bin/env"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"BISECT_STAGE=someBisectStage",
"BISECT_DIR=someBisectDir",
"HOME=/user/home"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/env",
"args": [
"python3",
"-c",
@@ -192,19 +160,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -215,12 +176,30 @@
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes",
"PYTHONPATH=/somepath/test_binary"
- ]
+ ],
+ "path": "/usr/bin/env"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "env": [
+ "BISECT_STAGE=someBisectStage",
+ "BISECT_DIR=someBisectDir",
+ "HOME=/user/home"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_nonhardened_golden/clang_ftrapv_maincc_target_specific.json b/compiler_wrapper/testdata/cros_nonhardened_golden/clang_ftrapv_maincc_target_specific.json
index aa9dfa80..7932c23b 100644
--- a/compiler_wrapper/testdata/cros_nonhardened_golden/clang_ftrapv_maincc_target_specific.json
+++ b/compiler_wrapper/testdata/cros_nonhardened_golden/clang_ftrapv_maincc_target_specific.json
@@ -1,19 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "-ftrapv",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -34,20 +23,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-ftrapv",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -57,26 +39,26 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-eabi-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-eabi",
@@ -97,20 +79,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-eabi-",
"-ftrapv",
"main.cc",
"-L/usr/x86_64-cros-eabi/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -120,26 +95,26 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-win-gnu-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-eabi-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-win-gnu",
@@ -160,20 +135,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-win-gnu-",
"-ftrapv",
"main.cc",
"-L/usr/x86_64-cros-win-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -183,26 +151,26 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-linux-gnu-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-win-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv7m-cros-linux-gnu",
@@ -223,21 +191,14 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"-mthumb",
"--prefix=../../bin/armv7m-cros-linux-gnu-",
"-ftrapv",
"main.cc",
"-L/usr/armv7m-cros-linux-gnu/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv7m-cros-linux-gnu"
@@ -246,26 +207,26 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-eabi-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv7m-cros-eabi",
@@ -286,20 +247,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/armv7m-cros-eabi-",
"-ftrapv",
"main.cc",
"-L/usr/armv7m-cros-eabi/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv7m-cros-eabi"
@@ -308,26 +262,26 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-win-gnu-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-eabi-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv7m-cros-win-gnu",
@@ -348,21 +302,14 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"-mthumb",
"--prefix=../../bin/armv7m-cros-win-gnu-",
"-ftrapv",
"main.cc",
"-L/usr/armv7m-cros-win-gnu/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv7m-cros-win-gnu"
@@ -371,26 +318,26 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-linux-gnu-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-win-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv8m-cros-linux-gnu",
@@ -411,21 +358,14 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"-mthumb",
"--prefix=../../bin/armv8m-cros-linux-gnu-",
"-ftrapv",
"main.cc",
"-L/usr/armv8m-cros-linux-gnu/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv8m-cros-linux-gnu"
@@ -434,26 +374,26 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-eabi-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv8m-cros-eabi",
@@ -474,20 +414,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/armv8m-cros-eabi-",
"-ftrapv",
"main.cc",
"-L/usr/armv8m-cros-eabi/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv8m-cros-eabi"
@@ -496,26 +429,26 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-win-gnu-clang",
"args": [
"-ftrapv",
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-eabi-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv8m-cros-win-gnu",
@@ -536,21 +469,14 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"-mthumb",
"--prefix=../../bin/armv8m-cros-win-gnu-",
"-ftrapv",
"main.cc",
"-L/usr/armv8m-cros-win-gnu/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv8m-cros-win-gnu"
@@ -559,9 +485,20 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "-ftrapv",
+ "main.cc"
+ ],
+ "path": "./armv8m-cros-win-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_nonhardened_golden/clang_maincc_target_specific.json b/compiler_wrapper/testdata/cros_nonhardened_golden/clang_maincc_target_specific.json
index 778e7a0b..534526f1 100644
--- a/compiler_wrapper/testdata/cros_nonhardened_golden/clang_maincc_target_specific.json
+++ b/compiler_wrapper/testdata/cros_nonhardened_golden/clang_maincc_target_specific.json
@@ -1,18 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -33,19 +23,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -55,25 +38,25 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-eabi-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-eabi",
@@ -94,19 +77,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-eabi-",
"main.cc",
"-L/usr/x86_64-cros-eabi/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -116,25 +92,25 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-win-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-eabi-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-win-gnu",
@@ -155,19 +131,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-win-gnu-",
"main.cc",
"-L/usr/x86_64-cros-win-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -177,25 +146,25 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-win-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv7m-cros-linux-gnu",
@@ -216,20 +185,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"-mthumb",
"--prefix=../../bin/armv7m-cros-linux-gnu-",
"main.cc",
"-L/usr/armv7m-cros-linux-gnu/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv7m-cros-linux-gnu"
@@ -238,25 +200,25 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-eabi-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv7m-cros-eabi",
@@ -277,19 +239,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/armv7m-cros-eabi-",
"main.cc",
"-L/usr/armv7m-cros-eabi/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv7m-cros-eabi"
@@ -298,25 +253,25 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-win-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-eabi-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv7m-cros-win-gnu",
@@ -337,20 +292,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"-mthumb",
"--prefix=../../bin/armv7m-cros-win-gnu-",
"main.cc",
"-L/usr/armv7m-cros-win-gnu/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv7m-cros-win-gnu"
@@ -359,25 +307,25 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-win-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv8m-cros-linux-gnu",
@@ -398,20 +346,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"-mthumb",
"--prefix=../../bin/armv8m-cros-linux-gnu-",
"main.cc",
"-L/usr/armv8m-cros-linux-gnu/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv8m-cros-linux-gnu"
@@ -420,25 +361,25 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-eabi-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv8m-cros-eabi",
@@ -459,19 +400,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/armv8m-cros-eabi-",
"main.cc",
"-L/usr/armv8m-cros-eabi/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv8m-cros-eabi"
@@ -480,25 +414,25 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-win-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-eabi-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv8m-cros-win-gnu",
@@ -519,20 +453,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"-mthumb",
"--prefix=../../bin/armv8m-cros-win-gnu-",
"main.cc",
"-L/usr/armv8m-cros-win-gnu/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv8m-cros-win-gnu"
@@ -541,9 +468,19 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./armv8m-cros-win-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_nonhardened_golden/clang_path.json b/compiler_wrapper/testdata/cros_nonhardened_golden/clang_path.json
index b9ff8405..2fb92c6e 100644
--- a/compiler_wrapper/testdata/cros_nonhardened_golden/clang_path.json
+++ b/compiler_wrapper/testdata/cros_nonhardened_golden/clang_path.json
@@ -1,18 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -33,19 +23,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -55,28 +38,25 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -97,19 +77,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -119,28 +92,31 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang++",
"args": [
"main.cc"
- ]
- }
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang++",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -161,20 +137,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
- "-std=gnu++14",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -184,28 +152,25 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "CLANG=somepath/clang"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang++"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"somepath/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -226,19 +191,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -248,35 +206,37 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
+ "env": [
+ "CLANG=somepath/clang"
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-Xclang-path=/somedir",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"/somedir/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -297,21 +257,14 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-resource-dir=someResourceDir",
"--gcc-toolchain=/usr",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -321,38 +274,35 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-Xclang-path=/somedir",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"/somedir/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -373,57 +323,50 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-resource-dir=someResourceDir",
"--gcc-toolchain=/usr",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
+ ],
+ "env": [
+ "GOMACC_PATH=/tmp/stable/gomacc"
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-Xclang-path=/somedir",
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"/somedir/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -444,21 +387,14 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-resource-dir=someResourceDir",
"--gcc-toolchain=/usr",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -468,28 +404,32 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/x86_64-cros-linux-gnu-clang",
"args": [
+ "-Xclang-path=/somedir",
"main.cc"
- ]
- }
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"/usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -510,19 +450,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -532,25 +465,25 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"a/b/c/d/e/usr/bin/clang",
"--sysroot=/tmp/stable/a/b/c/d/e/usr/x86_64-cros-linux-gnu",
@@ -571,19 +504,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=a/b/c/d/e/bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/tmp/stable/a/b/c/d/e/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-Ba/b/c/d/e/bin",
"-target",
@@ -593,25 +519,25 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./symlinked/x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"a/b/c/d/e/usr/bin/clang",
"--sysroot=/tmp/stable/a/b/c/d/e/usr/x86_64-cros-linux-gnu",
@@ -632,19 +558,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=a/b/c/d/e/bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/tmp/stable/a/b/c/d/e/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-Ba/b/c/d/e/bin",
"-target",
@@ -654,25 +573,25 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "somedir/x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./symlinked/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../usr/bin/clang",
"--sysroot=/tmp/usr/x86_64-cros-linux-gnu",
@@ -693,19 +612,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/tmp/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../bin",
"-target",
@@ -715,28 +627,25 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "PATH=/tmp/stable/pathenv"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "somedir/x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"/tmp/usr/bin/clang",
"--sysroot=/tmp/usr/x86_64-cros-linux-gnu",
@@ -757,19 +666,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/tmp/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../bin",
"-target",
@@ -779,9 +681,22 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "env": [
+ "PATH=/tmp/stable/pathenv"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "x86_64-cros-linux-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_nonhardened_golden/clang_sanitizer_args.json b/compiler_wrapper/testdata/cros_nonhardened_golden/clang_sanitizer_args.json
index 27404a12..ed208391 100644
--- a/compiler_wrapper/testdata/cros_nonhardened_golden/clang_sanitizer_args.json
+++ b/compiler_wrapper/testdata/cros_nonhardened_golden/clang_sanitizer_args.json
@@ -1,20 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "-fsanitize=kernel-address",
- "-Wl,--no-undefined",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -35,20 +23,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-fsanitize=kernel-address",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -58,27 +39,27 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-fsanitize=kernel-address",
- "-Wl,-z,defs",
+ "-Wl,--no-undefined",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -99,20 +80,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-fsanitize=kernel-address",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -122,27 +96,27 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-fsanitize=kernel-address",
- "-D_FORTIFY_SOURCE=1",
+ "-Wl,-z,defs",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -163,20 +137,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-fsanitize=kernel-address",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -186,27 +153,27 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-fsanitize=kernel-address",
- "-D_FORTIFY_SOURCE=2",
+ "-D_FORTIFY_SOURCE=1",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -227,20 +194,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-fsanitize=kernel-address",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -250,26 +210,27 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-fsanitize=fuzzer",
+ "-fsanitize=kernel-address",
+ "-D_FORTIFY_SOURCE=2",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -290,20 +251,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-fsanitize=fuzzer",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -313,27 +267,26 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-fsanitize=address",
- "-fprofile-instr-generate",
+ "-fsanitize=fuzzer",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -354,21 +307,14 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-fsanitize=address",
"-fprofile-instr-generate",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -378,26 +324,27 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"-fsanitize=address",
+ "-fprofile-instr-generate",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -418,20 +365,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-fsanitize=address",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -441,26 +381,26 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-fprofile-instr-generate",
+ "-fsanitize=address",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -481,20 +421,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-fprofile-instr-generate",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -504,9 +437,20 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "-fprofile-instr-generate",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_nonhardened_golden/clang_specific_args.json b/compiler_wrapper/testdata/cros_nonhardened_golden/clang_specific_args.json
index 03d90589..1d8d32c1 100644
--- a/compiler_wrapper/testdata/cros_nonhardened_golden/clang_specific_args.json
+++ b/compiler_wrapper/testdata/cros_nonhardened_golden/clang_specific_args.json
@@ -1,28 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "-mno-movbe",
- "-Wclobbered",
- "-Wno-psabi",
- "-Wlogical-op",
- "-Wmissing-parameter-type",
- "-Wold-style-declaration",
- "-Woverride-init",
- "-Wunsafe-loop-optimizations",
- "-Wstrict-aliasing=abc",
- "-finline-limit=abc",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -43,8 +23,8 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-mno-movbe",
@@ -57,13 +37,6 @@
"-Wunsafe-loop-optimizations",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -73,26 +46,35 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-Wno-error=cpp",
+ "-mno-movbe",
+ "-Wclobbered",
+ "-Wno-psabi",
+ "-Wlogical-op",
+ "-Wmissing-parameter-type",
+ "-Wold-style-declaration",
+ "-Woverride-init",
+ "-Wunsafe-loop-optimizations",
+ "-Wstrict-aliasing=abc",
+ "-finline-limit=abc",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -113,20 +95,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-Wno-#warnings",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -136,26 +111,26 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-Wno-error=maybe-uninitialized",
+ "-Wno-error=cpp",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -176,20 +151,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-Wno-error=uninitialized",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -199,26 +167,26 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-Xclang-only=-someflag",
+ "-Wno-error=maybe-uninitialized",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -239,20 +207,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-someflag",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -262,9 +223,20 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "-Xclang-only=-someflag",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_nonhardened_golden/clang_sysroot_wrapper_common.json b/compiler_wrapper/testdata/cros_nonhardened_golden/clang_sysroot_wrapper_common.json
index 3ceaa3f7..00202da3 100644
--- a/compiler_wrapper/testdata/cros_nonhardened_golden/clang_sysroot_wrapper_common.json
+++ b/compiler_wrapper/testdata/cros_nonhardened_golden/clang_sysroot_wrapper_common.json
@@ -1,19 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "-noccache",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc.real",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
"-Wno-maybe-uninitialized",
@@ -24,28 +13,26 @@
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
"-mno-movbe"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "GOMACC_PATH=someNonExistingPath"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
+ "-noccache",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -66,19 +53,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -88,28 +68,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
- "GOMACC_PATH=/tmp/stable/gomacc"
+ "GOMACC_PATH=someNonExistingPath"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -130,43 +110,38 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
+ ],
+ "env": [
+ "GOMACC_PATH=/tmp/stable/gomacc"
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-nopie",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -187,20 +162,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-nopie",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -210,26 +178,26 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "-D__KERNEL__",
+ "-nopie",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -250,21 +218,14 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"-fno-stack-protector",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"-D__KERNEL__",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -274,26 +235,26 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7a-cros-linux-gnueabihf-clang",
"args": [
"-D__KERNEL__",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/armv7a-cros-linux-gnueabihf",
@@ -314,8 +275,8 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"-mthumb",
"-fno-stack-protector",
@@ -323,13 +284,6 @@
"-D__KERNEL__",
"main.cc",
"-L/usr/armv7a-cros-linux-gnueabihf/usr/lib",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-B../../bin",
"-target",
"armv7a-cros-linux-gnueabihf"
@@ -338,26 +292,26 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
- "--sysroot=xyz",
+ "-D__KERNEL__",
"main.cc"
- ]
+ ],
+ "path": "./armv7a-cros-linux-gnueabihf-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"../../usr/bin/clang",
"-Qunused-arguments",
@@ -377,20 +331,13 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"--sysroot=xyz",
"main.cc",
"-Lxyz/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -400,9 +347,20 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "--sysroot=xyz",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_nonhardened_golden/clangtidy.json b/compiler_wrapper/testdata/cros_nonhardened_golden/clangtidy.json
index b8575a09..0111275e 100644
--- a/compiler_wrapper/testdata/cros_nonhardened_golden/clangtidy.json
+++ b/compiler_wrapper/testdata/cros_nonhardened_golden/clangtidy.json
@@ -1,30 +1,17 @@
[
{
- "wd": "/tmp/stable",
- "env": [
- "WITH_TIDY=1"
- ],
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "../../usr/bin/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
@@ -48,29 +35,22 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang-tidy"
}
},
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
"-Qunused-arguments",
@@ -90,55 +70,47 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
- "WITH_TIDY=1",
- "GOMACC_PATH=/tmp/stable/gomacc"
+ "WITH_TIDY=1"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "../../usr/bin/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
@@ -162,29 +134,22 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang-tidy"
}
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -205,57 +170,48 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"WITH_TIDY=1",
"GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerrorclang-tidy failed"
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "../../usr/bin/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
@@ -279,32 +235,25 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang-tidy"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -325,58 +274,50 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"WITH_TIDY=1",
"GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
},
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ "stderr": "someerrorclang-tidy failed",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--print-resource-dir"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
"stdout": "someResourceDir"
},
{
"cmd": {
- "path": "../../usr/bin/clang-tidy",
"args": [
"-checks=*,-bugprone-narrowing-conversions,-cppcoreguidelines-*,-fuchsia-*,-google-readability*,-google-runtime-references,-hicpp-*,-llvm-*,-misc-non-private-member-variables-in-classes,-misc-unused-parameters,-modernize-*,-readability-*",
"main.cc",
@@ -400,29 +341,22 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "../../usr/bin/clang-tidy"
}
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -443,29 +377,39 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "env": [
+ "WITH_TIDY=1",
+ "GOMACC_PATH=/tmp/stable/gomacc"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_nonhardened_golden/force_disable_werror.json b/compiler_wrapper/testdata/cros_nonhardened_golden/force_disable_werror.json
index ff37898f..0bc33451 100644
--- a/compiler_wrapper/testdata/cros_nonhardened_golden/force_disable_werror.json
+++ b/compiler_wrapper/testdata/cros_nonhardened_golden/force_disable_werror.json
@@ -1,21 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "env": [
- "FORCE_DISABLE_WERROR=1"
- ],
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -36,19 +23,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -58,29 +38,28 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"FORCE_DISABLE_WERROR=1"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
- },
- "stdout": "$CROS_ARTIFACTS_TMP_DIR is not set, artifacts will be written to /tmp"
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -101,19 +80,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -123,14 +95,14 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "ccache"
},
- "stderr": "-Werror originalerror",
- "exitcode": 1
+ "exitcode": 1,
+ "stderr": "error: foo [-Werror,-Wfoo]"
},
{
"cmd": {
- "path": "ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -151,19 +123,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -175,30 +140,29 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
"FORCE_DISABLE_WERROR=1"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-clang",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
},
- "stderr": "-Werror originalerror",
- "exitcode": 1
- },
+ "stdout": "$CROS_ARTIFACTS_TMP_DIR is not set, artifacts will be written to /tmp"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -219,19 +183,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -241,14 +198,14 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "ccache"
},
- "stderr": "-Werror originalerror",
- "exitcode": 1
+ "exitcode": 1,
+ "stderr": "error: foo [-Werror,-Wfoo]"
},
{
"cmd": {
- "path": "ccache",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -269,19 +226,12 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
@@ -293,12 +243,27 @@
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002",
"CCACHE_CPP2=yes"
- ]
+ ],
+ "path": "ccache"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "env": [
+ "FORCE_DISABLE_WERROR=1"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-clang"
+ },
+ "exitcode": 1,
+ "stderr": "error: foo [-Werror,-Wfoo]"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_clang_syntax.json b/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_clang_syntax.json
index 771b224a..ef1d1cbe 100644
--- a/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_clang_syntax.json
+++ b/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_clang_syntax.json
@@ -1,19 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "-clang-syntax",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
"-Qunused-arguments",
@@ -33,31 +22,24 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu",
"-fsyntax-only",
"-stdlib=libstdc++"
- ]
+ ],
+ "path": "../../usr/bin/clang"
}
},
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -73,29 +55,26 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "GOMACC_PATH=/tmp/stable/gomacc"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-clang-syntax",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"../../usr/bin/clang",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -116,31 +95,24 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu",
"-fsyntax-only",
"-stdlib=libstdc++"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
},
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -152,29 +124,29 @@
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
"-mno-movbe"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
+ ],
+ "env": [
+ "GOMACC_PATH=/tmp/stable/gomacc"
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-clang-syntax",
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
"-Qunused-arguments",
@@ -194,51 +166,44 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu",
"-fsyntax-only",
"-stdlib=libstdc++"
- ]
+ ],
+ "path": "../../usr/bin/clang"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-clang-syntax",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
- },
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "../../usr/bin/clang",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
"-Qunused-arguments",
@@ -258,31 +223,24 @@
"-Wno-int-conversion",
"-Wno-incompatible-function-pointer-types",
"-D_LIBCPP_ENABLE_CXX17_REMOVED_FEATURES",
+ "-fclang-abi-compat=17",
"-Wno-section",
- "-fcrash-diagnostics-dir=/tmp/stable/clang_crash_diagnostics",
"-static-libgcc",
"--prefix=../../bin/x86_64-cros-linux-gnu-",
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
- "-Wno-array-parameter",
- "-Wno-compound-token-split-by-space",
- "-Wno-deprecated-copy",
- "-Wno-unused-but-set-variable",
- "-Wno-implicit-int-float-conversion",
- "-Wno-string-concatenation",
- "-Wno-gnu-offsetof-extensions",
"-mno-movbe",
"-B../../bin",
"-target",
"x86_64-cros-linux-gnu",
"-fsyntax-only",
"-stdlib=libstdc++"
- ]
+ ],
+ "path": "../../usr/bin/clang"
}
},
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -298,12 +256,26 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "-clang-syntax",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_maincc_target_specific.json b/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_maincc_target_specific.json
index 24f90fbf..1997a6dd 100644
--- a/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_maincc_target_specific.json
+++ b/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_maincc_target_specific.json
@@ -1,18 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -28,25 +18,25 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-eabi-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-eabi-gcc.real",
"--sysroot=/usr/x86_64-cros-eabi",
@@ -62,25 +52,25 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-win-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-eabi-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-win-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-win-gnu",
@@ -96,25 +86,25 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-win-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./armv7m-cros-linux-gnu-gcc.real",
"--sysroot=/usr/armv7m-cros-linux-gnu",
@@ -130,25 +120,25 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-eabi-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./armv7m-cros-eabi-gcc.real",
"--sysroot=/usr/armv7m-cros-eabi",
@@ -163,25 +153,25 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7m-cros-win-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-eabi-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./armv7m-cros-win-gnu-gcc.real",
"--sysroot=/usr/armv7m-cros-win-gnu",
@@ -197,25 +187,25 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv7m-cros-win-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./armv8m-cros-linux-gnu-gcc.real",
"--sysroot=/usr/armv8m-cros-linux-gnu",
@@ -231,25 +221,25 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-eabi-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./armv8m-cros-eabi-gcc.real",
"--sysroot=/usr/armv8m-cros-eabi",
@@ -264,25 +254,25 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv8m-cros-win-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./armv8m-cros-eabi-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./armv8m-cros-win-gnu-gcc.real",
"--sysroot=/usr/armv8m-cros-win-gnu",
@@ -298,9 +288,19 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "./armv8m-cros-win-gnu-gcc"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_path.json b/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_path.json
index b2662930..c8cf7679 100644
--- a/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_path.json
+++ b/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_path.json
@@ -1,18 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -28,28 +18,25 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
- },
- "stdout": "somemessage",
- "stderr": "someerror",
- "exitcode": 1
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ }
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -65,28 +52,31 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
},
- "stdout": "somemessage",
+ "exitcode": 1,
"stderr": "someerror",
- "exitcode": 1
+ "stdout": "somemessage"
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "/tmp/stable/x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
- }
- },
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ },
+ "exitcode": 1,
+ "stderr": "someerror",
+ "stdout": "somemessage"
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"/tmp/stable/x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -102,25 +92,25 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "/tmp/stable/x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/tmp/stable/a/b/usr/x86_64-cros-linux-gnu",
@@ -136,25 +126,25 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./symlinked/x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./a/b/c/d/e/f/g/x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./symlinked/x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/tmp/stable/a/b/usr/x86_64-cros-linux-gnu",
@@ -170,28 +160,25 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "PATH=/tmp/stable/pathenv"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./symlinked/x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"/tmp/stable/pathenv/x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -207,9 +194,22 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "env": [
+ "PATH=/tmp/stable/pathenv"
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "main.cc"
+ ],
+ "path": "x86_64-cros-linux-gnu-gcc"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_sanitizer_args.json b/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_sanitizer_args.json
index 79e02c3d..8603c168 100644
--- a/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_sanitizer_args.json
+++ b/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_sanitizer_args.json
@@ -1,20 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "-fsanitize=kernel-address",
- "-Wl,--no-undefined",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -31,27 +19,27 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-fsanitize=kernel-address",
- "-Wl,-z,defs",
+ "-Wl,--no-undefined",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -68,27 +56,27 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-fsanitize=kernel-address",
- "-D_FORTIFY_SOURCE=1",
+ "-Wl,-z,defs",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -105,27 +93,27 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-fsanitize=kernel-address",
- "-D_FORTIFY_SOURCE=2",
+ "-D_FORTIFY_SOURCE=1",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -142,26 +130,27 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
- "-fsanitize=fuzzer",
+ "-fsanitize=kernel-address",
+ "-D_FORTIFY_SOURCE=2",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -178,27 +167,26 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
- "-fsanitize=address",
- "-fprofile-instr-generate",
+ "-fsanitize=fuzzer",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -216,26 +204,27 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"-fsanitize=address",
+ "-fprofile-instr-generate",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -252,26 +241,26 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
- "-fprofile-instr-generate",
+ "-fsanitize=address",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -288,9 +277,20 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "-fprofile-instr-generate",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_specific_args.json b/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_specific_args.json
index e0fe5515..2e4a1b15 100644
--- a/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_specific_args.json
+++ b/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_specific_args.json
@@ -1,19 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "-march=goldmont",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -30,26 +19,26 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
- "-march=goldmont-plus",
+ "-march=goldmont",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -66,26 +55,26 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
- "-march=skylake",
+ "-march=goldmont-plus",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -102,9 +91,20 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "-march=skylake",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_sysroot_wrapper_common.json b/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_sysroot_wrapper_common.json
index 25411f20..35ead1b4 100644
--- a/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_sysroot_wrapper_common.json
+++ b/compiler_wrapper/testdata/cros_nonhardened_golden/gcc_sysroot_wrapper_common.json
@@ -1,19 +1,8 @@
[
{
- "wd": "/tmp/stable",
- "wrapper": {
- "cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
- "args": [
- "-noccache",
- "main.cc"
- ]
- }
- },
"cmds": [
{
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc.real",
"args": [
"--sysroot=/usr/x86_64-cros-linux-gnu",
"-Wno-maybe-uninitialized",
@@ -24,28 +13,26 @@
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
"-mno-movbe"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc.real"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
- "env": [
- "GOMACC_PATH=someNonExistingPath"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
+ "-noccache",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -61,28 +48,28 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
- "wd": "/tmp/stable",
+ ],
"env": [
- "GOMACC_PATH=/tmp/stable/gomacc"
+ "GOMACC_PATH=someNonExistingPath"
],
+ "wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/tmp/stable/gomacc",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -94,26 +81,28 @@
"main.cc",
"-L/usr/x86_64-cros-linux-gnu/usr/lib64",
"-mno-movbe"
- ]
+ ],
+ "path": "/tmp/stable/gomacc"
}
}
- ]
- },
- {
+ ],
+ "env": [
+ "GOMACC_PATH=/tmp/stable/gomacc"
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
- "-nopie",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -130,26 +119,26 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
- "-D__KERNEL__",
+ "-nopie",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"--sysroot=/usr/x86_64-cros-linux-gnu",
@@ -167,26 +156,26 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./armv7a-cros-linux-gnueabihf-gcc",
"args": [
"-D__KERNEL__",
"main.cc"
- ]
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./armv7a-cros-linux-gnueabihf-gcc.real",
"--sysroot=/usr/armv7a-cros-linux-gnueabihf",
@@ -204,26 +193,26 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
- },
- {
+ ],
"wd": "/tmp/stable",
"wrapper": {
"cmd": {
- "path": "./x86_64-cros-linux-gnu-gcc",
"args": [
- "--sysroot=xyz",
+ "-D__KERNEL__",
"main.cc"
- ]
+ ],
+ "path": "./armv7a-cros-linux-gnueabihf-gcc"
}
- },
+ }
+ },
+ {
"cmds": [
{
"cmd": {
- "path": "/usr/bin/ccache",
"args": [
"./x86_64-cros-linux-gnu-gcc.real",
"-Wno-maybe-uninitialized",
@@ -239,9 +228,20 @@
"env_updates": [
"CCACHE_DIR=/var/cache/distfiles/ccache",
"CCACHE_UMASK=002"
- ]
+ ],
+ "path": "/usr/bin/ccache"
}
}
- ]
+ ],
+ "wd": "/tmp/stable",
+ "wrapper": {
+ "cmd": {
+ "args": [
+ "--sysroot=xyz",
+ "main.cc"
+ ],
+ "path": "./x86_64-cros-linux-gnu-gcc"
+ }
+ }
}
]
diff --git a/compiler_wrapper/testutil_test.go b/compiler_wrapper/testutil_test.go
index 8bac479b..7b50d4bb 100644
--- a/compiler_wrapper/testutil_test.go
+++ b/compiler_wrapper/testutil_test.go
@@ -84,6 +84,12 @@ func (ctx *testContext) umask(mask int) (oldmask int) {
return syscall.Umask(mask)
}
+func (ctx *testContext) setArbitraryClangArtifactsDir() string {
+ d := filepath.Join(ctx.tempDir, "cros-artifacts")
+ ctx.env = append(ctx.env, crosArtifactsEnvVar+"="+d)
+ return d
+}
+
func (ctx *testContext) initUmaskDependency(lockFn func(), unlockFn func()) {
if ctx.umaskRestoreAction != nil {
// Use a panic so we get a backtrace.
@@ -191,7 +197,6 @@ func (ctx *testContext) mustFail(exitCode int) string {
func (ctx *testContext) updateConfig(cfg *config) {
*ctx.cfg = *cfg
ctx.cfg.newWarningsDir = filepath.Join(ctx.tempDir, "fatal_clang_warnings")
- ctx.cfg.crashArtifactsDir = filepath.Join(ctx.tempDir, "clang_crash_diagnostics")
// Ensure this is always empty, so any test that depends on it will see no output unless
// it's properly set up.
diff --git a/contrib/README.md b/contrib/README.md
new file mode 100644
index 00000000..e430b183
--- /dev/null
+++ b/contrib/README.md
@@ -0,0 +1,5 @@
+This directory contains subdirectories of random upstreamable utilities that may
+be relevant to ChromeOS toolchain members.
+
+These utilites should receive less scrutiny at review-time than others, and
+should consequently _generally_ just be used interactively.
diff --git a/contrib/gbiv/bgtask/Makefile b/contrib/gbiv/bgtask/Makefile
new file mode 100644
index 00000000..fadafb34
--- /dev/null
+++ b/contrib/gbiv/bgtask/Makefile
@@ -0,0 +1,12 @@
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+all: bgtask
+
+bgtask: bgtask.cc
+ clang++ -O2 -std=gnu++20 -Wall -Wextra -Werror -g0 -fno-exceptions \
+ bgtask.cc -o bgtask
+
+clean:
+ rm -f bgtask
diff --git a/contrib/gbiv/bgtask/bgtask.cc b/contrib/gbiv/bgtask/bgtask.cc
new file mode 100644
index 00000000..840ad761
--- /dev/null
+++ b/contrib/gbiv/bgtask/bgtask.cc
@@ -0,0 +1,131 @@
+/*
+ * Copyright 2023 The ChromiumOS Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+#include <err.h>
+#include <errno.h>
+#include <linux/ioprio.h>
+#include <sched.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/resource.h>
+#include <sys/syscall.h>
+#include <sys/sysinfo.h>
+#include <unistd.h>
+
+#include <string_view>
+
+static const char description[] = R"(bgtask - `nice -n19` but more.
+
+This program exists to set a few process attributes, and exec another program.
+
+Intended usage is:
+$ bgtask ./my_long_running_build --extra-optimizations --and-more
+
+Specifically, `bgtask`:
+ - sets its own priority so essentially any other task will take priority, then
+ - sets its I/O priority so any regular task will take priority, then
+ - sets its CPU mask so it may only run on 9/10ths of your cores (this step is
+ skipped if you've already got a more restrictive mask), then
+ - execs the command you gave it.
+)";
+
+static void print_help_and_exit(int exit_code) {
+ fputs(description, stderr);
+ exit(exit_code);
+}
+
+static void deprioritize_nice_or_warn() {
+ constexpr int current_process = 0;
+ constexpr int max_nice_priority = 19;
+ if (setpriority(PRIO_PROCESS, current_process, max_nice_priority)) {
+ warn("setting priority failed");
+ }
+}
+
+static void deprioritize_io_or_warn() {
+ // Glibc provides no wrapper here.
+ constexpr int current_process = 0;
+ const int background_io_prio = IOPRIO_PRIO_VALUE(IOPRIO_CLASS_IDLE, 0);
+ if (syscall(SYS_ioprio_set, IOPRIO_WHO_PROCESS, current_process,
+ background_io_prio) == -1) {
+ warn("setting ioprio failed");
+ }
+}
+
+static void restrict_cpu_mask_or_warn() {
+ const int available_cpus = get_nprocs();
+ // Use 9/10ths of CPUs, as requested in the mask.
+ const int cpus_to_use = (available_cpus * 9) / 10;
+ // Erm, single-core systems need not apply.
+ if (cpus_to_use == 0) {
+ return;
+ }
+
+ // Note pid==0 means "the current thread," for sched_*affinity calls.
+ constexpr int current_process = 0;
+ cpu_set_t current_mask;
+ CPU_ZERO(&current_mask);
+ if (sched_getaffinity(current_process, sizeof(current_mask), &current_mask) ==
+ -1) {
+ if (errno == EINVAL) {
+ // This can only happen if a machine has >1K cores. That can be handled,
+ // but is extra complexity that I can't test & isn't expected to
+ // realistically be a problem in the next few years.
+ warnx("statically-allocated cpu affinity mask is too small");
+ } else {
+ warn("sched_getaffinity failed");
+ }
+ return;
+ }
+
+ const int cpus_in_current_mask = CPU_COUNT(&current_mask);
+ int cpus_to_disable = cpus_in_current_mask - cpus_to_use;
+ if (cpus_to_disable <= 0) {
+ // Don't warn; this probably isn't useful informtion to the user.
+ return;
+ }
+
+ for (int i = 0; i < available_cpus; ++i) {
+ if (CPU_ISSET(i, &current_mask)) {
+ CPU_CLR(i, &current_mask);
+ --cpus_to_disable;
+ if (cpus_to_disable == 0) {
+ break;
+ }
+ }
+ }
+
+ if (cpus_to_disable != 0) {
+ warnx("Internal error: iterated through CPU mask but had %d CPUs left to "
+ "disable.",
+ cpus_to_disable);
+ return;
+ }
+
+ if (sched_setaffinity(current_process, sizeof(current_mask), &current_mask) ==
+ -1) {
+ warn("sched_setaffinity failed");
+ }
+}
+
+__attribute__((noreturn)) int main(int argc, char **argv) {
+ if (argc == 1) {
+ print_help_and_exit(/*exit_code=*/1);
+ }
+
+ std::string_view argv1 = argv[1];
+ // Do minimal option parsing, since the user is likely to be passing `-flags`
+ // and `--flags` to the program they're invoking.
+ if (argv1 == "-h" || argv1 == "--help") {
+ print_help_and_exit(/*exit_code=*/0);
+ }
+
+ deprioritize_nice_or_warn();
+ deprioritize_io_or_warn();
+ restrict_cpu_mask_or_warn();
+
+ execvp(argv[1], &argv[1]);
+ err(1, "execvp failed");
+}
diff --git a/cros_utils/bugs.py b/cros_utils/bugs.py
index ac1202ae..423faa8b 100755
--- a/cros_utils/bugs.py
+++ b/cros_utils/bugs.py
@@ -9,11 +9,15 @@ import enum
import json
import os
import threading
-from typing import Any, Dict, List, Optional
+from typing import Any, Dict, List, Optional, Union
X20_PATH = "/google/data/rw/teams/c-compiler-chrome/prod_bugs"
+# List of 'well-known' bug numbers to tag as parents.
+RUST_MAINTENANCE_METABUG = 322195383
+RUST_SECURITY_METABUG = 322195192
+
# These constants are sourced from
# //google3/googleclient/chrome/chromeos_toolchain/bug_manager/bugs.go
@@ -57,10 +61,10 @@ class _FileNameGenerator:
my_entropy = self._entropy
self._entropy += 1
- now = now.isoformat("T", "seconds") + "Z"
+ now_str = now.isoformat("T", "seconds") + "Z"
entropy_str = str(my_entropy).zfill(self._ENTROPY_STR_SIZE)
pid = os.getpid()
- return f"{now}_{entropy_str}_{pid}.json"
+ return f"{now_str}_{entropy_str}_{pid}.json"
_GLOBAL_NAME_GENERATOR = _FileNameGenerator()
@@ -69,7 +73,7 @@ _GLOBAL_NAME_GENERATOR = _FileNameGenerator()
def _WriteBugJSONFile(
object_type: str,
json_object: Dict[str, Any],
- directory: Optional[os.PathLike],
+ directory: Optional[Union[os.PathLike, str]],
):
"""Writes a JSON file to `directory` with the given bug-ish object.
@@ -122,20 +126,23 @@ def CreateNewBug(
assignee: Optional[str] = None,
cc: Optional[List[str]] = None,
directory: Optional[os.PathLike] = None,
+ parent_bug: int = 0,
):
"""Sends a request to create a new bug.
Args:
- component_id: The component ID to add. Anything from WellKnownComponents
- also works.
- title: Title of the bug. Must be nonempty.
- body: Body of the bug. Must be nonempty.
- assignee: Assignee of the bug. Must be either an email address, or a
- "well-known" assignee (detective, mage).
- cc: A list of emails to add to the CC list. Must either be an email
- address, or a "well-known" individual (detective, mage).
- directory: The directory to write the report to. Defaults to our x20 bugs
- directory.
+ component_id: The component ID to add. Anything from WellKnownComponents
+ also works.
+ title: Title of the bug. Must be nonempty.
+ body: Body of the bug. Must be nonempty.
+ assignee: Assignee of the bug. Must be either an email address, or a
+ "well-known" assignee (detective, mage).
+ cc: A list of emails to add to the CC list. Must either be an email
+ address, or a "well-known" individual (detective, mage).
+ directory: The directory to write the report to. Defaults to our x20
+ bugs directory.
+ parent_bug: The parent bug number for this bug. If none should be
+ specified, pass the value 0.
"""
obj = {
"component_id": component_id,
@@ -149,6 +156,9 @@ def CreateNewBug(
if cc:
obj["cc"] = cc
+ if parent_bug:
+ obj["parent_bug"] = parent_bug
+
_WriteBugJSONFile("FileNewBugRequest", obj, directory)
@@ -158,26 +168,35 @@ def SendCronjobLog(
message: str,
turndown_time_hours: int = 0,
directory: Optional[os.PathLike] = None,
+ parent_bug: int = 0,
):
"""Sends the record of a cronjob to our bug infra.
- cronjob_name: The name of the cronjob. Expected to remain consistent over
- time.
- failed: Whether the job failed or not.
- message: Any seemingly relevant context. This is pasted verbatim in a bug, if
- the cronjob infra deems it worthy.
- turndown_time_hours: If nonzero, this cronjob will be considered
- turned down if more than `turndown_time_hours` pass without a report of
- success or failure. If zero, this job will not automatically be turned
- down.
- directory: The directory to write the report to. Defaults to our x20 bugs
- directory.
+ Args:
+ cronjob_name: The name of the cronjob. Expected to remain consistent
+ over time.
+ failed: Whether the job failed or not.
+ message: Any seemingly relevant context. This is pasted verbatim in a
+ bug, if the cronjob infra deems it worthy.
+ turndown_time_hours: If nonzero, this cronjob will be considered turned
+ down if more than `turndown_time_hours` pass without a report of
+ success or failure. If zero, this job will not automatically be
+ turned down.
+ directory: The directory to write the report to. Defaults to our x20
+ bugs directory.
+ parent_bug: The parent bug number for the bug filed for this cronjob,
+ if any. If none should be specified, pass the value 0.
"""
json_object = {
"name": cronjob_name,
"message": message,
"failed": failed,
}
+
if turndown_time_hours:
json_object["cronjob_turndown_time_hours"] = turndown_time_hours
+
+ if parent_bug:
+ json_object["parent_bug"] = parent_bug
+
_WriteBugJSONFile("CronjobUpdate", json_object, directory)
diff --git a/cros_utils/bugs_test.py b/cros_utils/bugs_test.py
index 1ee6bfe4..21ed2154 100755
--- a/cros_utils/bugs_test.py
+++ b/cros_utils/bugs_test.py
@@ -14,8 +14,7 @@ import os
from pathlib import Path
import tempfile
import unittest
-from unittest import mock
-from unittest.mock import patch
+import unittest.mock
from cros_utils import bugs
@@ -65,7 +64,7 @@ class Tests(unittest.TestCase):
},
)
- @patch.object(bugs, "_WriteBugJSONFile")
+ @unittest.mock.patch.object(bugs, "_WriteBugJSONFile")
def testAppendingToBugsSeemsToWork(self, mock_write_json_file):
"""Tests AppendToExistingBug."""
bugs.AppendToExistingBug(1234, "hello, world!")
@@ -78,7 +77,7 @@ class Tests(unittest.TestCase):
None,
)
- @patch.object(bugs, "_WriteBugJSONFile")
+ @unittest.mock.patch.object(bugs, "_WriteBugJSONFile")
def testBugCreationSeemsToWork(self, mock_write_json_file):
"""Tests CreateNewBug."""
test_case_additions = (
@@ -90,6 +89,9 @@ class Tests(unittest.TestCase):
"assignee": "foo@gbiv.com",
"cc": ["bar@baz.com"],
},
+ {
+ "parent_bug": 123,
+ },
)
for additions in test_case_additions:
@@ -108,14 +110,15 @@ class Tests(unittest.TestCase):
"body": test_case["body"],
}
- assignee = test_case.get("assignee")
- if assignee:
+ if assignee := test_case.get("assignee"):
expected_output["assignee"] = assignee
- cc = test_case.get("cc")
- if cc:
+ if cc := test_case.get("cc"):
expected_output["cc"] = cc
+ if parent_bug := test_case.get("parent_bug"):
+ expected_output["parent_bug"] = parent_bug
+
mock_write_json_file.assert_called_once_with(
"FileNewBugRequest",
expected_output,
@@ -123,7 +126,7 @@ class Tests(unittest.TestCase):
)
mock_write_json_file.reset_mock()
- @patch.object(bugs, "_WriteBugJSONFile")
+ @unittest.mock.patch.object(bugs, "_WriteBugJSONFile")
def testCronjobLogSendingSeemsToWork(self, mock_write_json_file):
"""Tests SendCronjobLog."""
bugs.SendCronjobLog("my_name", False, "hello, world!")
@@ -137,7 +140,7 @@ class Tests(unittest.TestCase):
None,
)
- @patch.object(bugs, "_WriteBugJSONFile")
+ @unittest.mock.patch.object(bugs, "_WriteBugJSONFile")
def testCronjobLogSendingSeemsToWorkWithTurndown(
self, mock_write_json_file
):
@@ -156,6 +159,23 @@ class Tests(unittest.TestCase):
None,
)
+ @unittest.mock.patch.object(bugs, "_WriteBugJSONFile")
+ def testCronjobLogSendingSeemsToWorkWithParentBug(
+ self, mock_write_json_file
+ ):
+ """Tests SendCronjobLog."""
+ bugs.SendCronjobLog("my_name", False, "hello, world!", parent_bug=42)
+ mock_write_json_file.assert_called_once_with(
+ "CronjobUpdate",
+ {
+ "name": "my_name",
+ "message": "hello, world!",
+ "failed": False,
+ "parent_bug": 42,
+ },
+ None,
+ )
+
def testFileNameGenerationProducesFileNamesInSortedOrder(self):
"""Tests that _FileNameGenerator gives us sorted file names."""
gen = bugs._FileNameGenerator()
@@ -180,7 +200,7 @@ class Tests(unittest.TestCase):
fourth = gen.generate_json_file_name(_ARBITRARY_DATETIME)
self.assertLess(third, fourth)
- @patch.object(os, "getpid")
+ @unittest.mock.patch.object(os, "getpid")
def testForkingProducesADifferentReport(self, mock_getpid):
"""Tests that _FileNameGenerator gives us sorted file names."""
gen = bugs._FileNameGenerator()
@@ -194,24 +214,24 @@ class Tests(unittest.TestCase):
child_file = gen.generate_json_file_name(_ARBITRARY_DATETIME)
self.assertNotEqual(parent_file, child_file)
- @patch.object(bugs, "_WriteBugJSONFile")
+ @unittest.mock.patch.object(bugs, "_WriteBugJSONFile")
def testCustomDirectoriesArePassedThrough(self, mock_write_json_file):
directory = "/path/to/somewhere/interesting"
bugs.AppendToExistingBug(1, "foo", directory=directory)
mock_write_json_file.assert_called_once_with(
- mock.ANY, mock.ANY, directory
+ unittest.mock.ANY, unittest.mock.ANY, directory
)
mock_write_json_file.reset_mock()
bugs.CreateNewBug(1, "title", "body", directory=directory)
mock_write_json_file.assert_called_once_with(
- mock.ANY, mock.ANY, directory
+ unittest.mock.ANY, unittest.mock.ANY, directory
)
mock_write_json_file.reset_mock()
bugs.SendCronjobLog("cronjob", False, "message", directory=directory)
mock_write_json_file.assert_called_once_with(
- mock.ANY, mock.ANY, directory
+ unittest.mock.ANY, unittest.mock.ANY, directory
)
def testWriteBugJSONFileWritesToGivenDirectory(self):
diff --git a/cros_utils/no_pseudo_terminal_test.py b/cros_utils/no_pseudo_terminal_test.py
deleted file mode 100755
index acc90af4..00000000
--- a/cros_utils/no_pseudo_terminal_test.py
+++ /dev/null
@@ -1,64 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-#
-# Copyright 2019 The ChromiumOS Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Test to ensure we're not touching /dev/ptmx when running commands."""
-
-
-import os
-import subprocess
-import tempfile
-import time
-import unittest
-
-from cros_utils import command_executer
-
-
-class NoPsuedoTerminalTest(unittest.TestCase):
- """Test to ensure we're not touching /dev/ptmx when running commands."""
-
- _strace_process = None
- STRACE_TIMEOUT = 10
-
- def _AttachStraceToSelf(self, output_file):
- """Attaches strace to the current process."""
- args = ["sudo", "strace", "-o", output_file, "-p", str(os.getpid())]
- print(args)
- # pylint: disable=bad-option-value, subprocess-popen-preexec-fn
- self._strace_process = subprocess.Popen(args, preexec_fn=os.setpgrp)
- # Wait until we see some activity.
- start_time = time.time()
- while time.time() - start_time < self.STRACE_TIMEOUT:
- if os.path.isfile(output_file) and open(output_file).read(1):
- return True
- time.sleep(1)
- return False
-
- def _KillStraceProcess(self):
- """Kills strace that was started by _AttachStraceToSelf()."""
- pgid = os.getpgid(self._strace_process.pid)
- args = ["sudo", "kill", str(pgid)]
- if subprocess.call(args) == 0:
- os.waitpid(pgid, 0)
- return True
- return False
-
- def testNoPseudoTerminalWhenRunningCommand(self):
- """Test to make sure we're not touching /dev/ptmx when running commands."""
- temp_file = tempfile.mktemp()
- self.assertTrue(self._AttachStraceToSelf(temp_file))
-
- ce = command_executer.GetCommandExecuter()
- ce.RunCommand("echo")
-
- self.assertTrue(self._KillStraceProcess())
-
- strace_contents = open(temp_file).read()
- self.assertFalse("/dev/ptmx" in strace_contents)
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/cros_utils/tiny_render.py b/cros_utils/tiny_render.py
index 6168a247..72bbb787 100644
--- a/cros_utils/tiny_render.py
+++ b/cros_utils/tiny_render.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
# Copyright 2020 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -127,7 +126,7 @@ def _render_text_pieces(
def render_text_pieces(piece: Piece) -> str:
"""Renders the given Pieces into text."""
- into = []
+ into: t.List[str] = []
_render_text_pieces(piece, 0, into)
return "".join(into)
@@ -177,6 +176,6 @@ def _render_html_pieces(piece: Piece, into: t.List[str]) -> None:
def render_html_pieces(piece: Piece) -> str:
"""Renders the given Pieces into HTML."""
- into = []
+ into: t.List[str] = []
_render_html_pieces(piece, into)
return "".join(into)
diff --git a/file_lock_machine.py b/file_lock_machine.py
deleted file mode 100755
index 5268398c..00000000
--- a/file_lock_machine.py
+++ /dev/null
@@ -1,423 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-# Copyright 2019 The ChromiumOS Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Script to lock/unlock machines."""
-
-
-__author__ = "asharif@google.com (Ahmad Sharif)"
-
-import argparse
-import datetime
-import fcntl
-import getpass
-import glob
-import json
-import os
-import socket
-import sys
-import time
-
-from cros_utils import logger
-
-
-LOCK_SUFFIX = "_check_lock_liveness"
-
-# The locks file directory REQUIRES that 'group' only has read/write
-# privileges and 'world' has no privileges. So the mask must be
-# '0o27': 0o777 - 0o27 = 0o750.
-LOCK_MASK = 0o27
-
-
-def FileCheckName(name):
- return name + LOCK_SUFFIX
-
-
-def OpenLiveCheck(file_name):
- with FileCreationMask(LOCK_MASK):
- fd = open(file_name, "a")
- try:
- fcntl.lockf(fd, fcntl.LOCK_EX | fcntl.LOCK_NB)
- except IOError as e:
- logger.GetLogger().LogError(e)
- raise
- return fd
-
-
-class FileCreationMask(object):
- """Class for the file creation mask."""
-
- def __init__(self, mask):
- self._mask = mask
- self._old_mask = None
-
- def __enter__(self):
- self._old_mask = os.umask(self._mask)
-
- def __exit__(self, typ, value, traceback):
- os.umask(self._old_mask)
-
-
-class LockDescription(object):
- """The description of the lock."""
-
- def __init__(self, desc=None):
- try:
- self.owner = desc["owner"]
- self.exclusive = desc["exclusive"]
- self.counter = desc["counter"]
- self.time = desc["time"]
- self.reason = desc["reason"]
- self.auto = desc["auto"]
- except (KeyError, TypeError):
- self.owner = ""
- self.exclusive = False
- self.counter = 0
- self.time = 0
- self.reason = ""
- self.auto = False
-
- def IsLocked(self):
- return self.counter or self.exclusive
-
- def __str__(self):
- return " ".join(
- [
- "Owner: %s" % self.owner,
- "Exclusive: %s" % self.exclusive,
- "Counter: %s" % self.counter,
- "Time: %s" % self.time,
- "Reason: %s" % self.reason,
- "Auto: %s" % self.auto,
- ]
- )
-
-
-class FileLock(object):
- """File lock operation class."""
-
- FILE_OPS = []
-
- def __init__(self, lock_filename):
- self._filepath = lock_filename
- lock_dir = os.path.dirname(lock_filename)
- assert os.path.isdir(lock_dir), (
- "Locks dir: %s doesn't exist!" % lock_dir
- )
- self._file = None
- self._description = None
-
- self.exclusive = None
- self.auto = None
- self.reason = None
- self.time = None
- self.owner = None
-
- def getDescription(self):
- return self._description
-
- def getFilePath(self):
- return self._filepath
-
- def setDescription(self, desc):
- self._description = desc
-
- @classmethod
- def AsString(cls, file_locks):
- stringify_fmt = "%-30s %-15s %-4s %-4s %-15s %-40s %-4s"
- header = stringify_fmt % (
- "machine",
- "owner",
- "excl",
- "ctr",
- "elapsed",
- "reason",
- "auto",
- )
- lock_strings = []
- for file_lock in file_locks:
-
- elapsed_time = datetime.timedelta(
- seconds=int(time.time() - file_lock.getDescription().time)
- )
- elapsed_time = "%s ago" % elapsed_time
- lock_strings.append(
- stringify_fmt
- % (
- os.path.basename(file_lock.getFilePath),
- file_lock.getDescription().owner,
- file_lock.getDescription().exclusive,
- file_lock.getDescription().counter,
- elapsed_time,
- file_lock.getDescription().reason,
- file_lock.getDescription().auto,
- )
- )
- table = "\n".join(lock_strings)
- return "\n".join([header, table])
-
- @classmethod
- def ListLock(cls, pattern, locks_dir):
- if not locks_dir:
- locks_dir = Machine.LOCKS_DIR
- full_pattern = os.path.join(locks_dir, pattern)
- file_locks = []
- for lock_filename in glob.glob(full_pattern):
- if LOCK_SUFFIX in lock_filename:
- continue
- file_lock = FileLock(lock_filename)
- with file_lock as lock:
- if lock.IsLocked():
- file_locks.append(file_lock)
- logger.GetLogger().LogOutput("\n%s" % cls.AsString(file_locks))
-
- def __enter__(self):
- with FileCreationMask(LOCK_MASK):
- try:
- self._file = open(self._filepath, "a+")
- self._file.seek(0, os.SEEK_SET)
-
- if fcntl.flock(self._file.fileno(), fcntl.LOCK_EX) == -1:
- raise IOError("flock(%s, LOCK_EX) failed!" % self._filepath)
-
- try:
- desc = json.load(self._file)
- except (EOFError, ValueError):
- desc = None
- self._description = LockDescription(desc)
-
- if self._description.exclusive and self._description.auto:
- locked_byself = False
- for fd in self.FILE_OPS:
- if fd.name == FileCheckName(self._filepath):
- locked_byself = True
- break
- if not locked_byself:
- try:
- fp = OpenLiveCheck(FileCheckName(self._filepath))
- except IOError:
- pass
- else:
- self._description = LockDescription()
- fcntl.lockf(fp, fcntl.LOCK_UN)
- fp.close()
- return self._description
- # Check this differently?
- except IOError as ex:
- logger.GetLogger().LogError(ex)
- return None
-
- def __exit__(self, typ, value, traceback):
- self._file.truncate(0)
- self._file.write(json.dumps(self._description.__dict__, skipkeys=True))
- self._file.close()
-
- def __str__(self):
- return self.AsString([self])
-
-
-class Lock(object):
- """Lock class"""
-
- def __init__(self, lock_file, auto=True):
- self._to_lock = os.path.basename(lock_file)
- self._lock_file = lock_file
- self._logger = logger.GetLogger()
- self._auto = auto
-
- def NonBlockingLock(self, exclusive, reason=""):
- with FileLock(self._lock_file) as lock:
- if lock.exclusive:
- self._logger.LogError(
- "Exclusive lock already acquired by %s. Reason: %s"
- % (lock.owner, lock.reason)
- )
- return False
-
- if exclusive:
- if lock.counter:
- self._logger.LogError("Shared lock already acquired")
- return False
- lock_file_check = FileCheckName(self._lock_file)
- fd = OpenLiveCheck(lock_file_check)
- FileLock.FILE_OPS.append(fd)
-
- lock.exclusive = True
- lock.reason = reason
- lock.owner = getpass.getuser()
- lock.time = time.time()
- lock.auto = self._auto
- else:
- lock.counter += 1
- self._logger.LogOutput("Successfully locked: %s" % self._to_lock)
- return True
-
- def Unlock(self, exclusive, force=False):
- with FileLock(self._lock_file) as lock:
- if not lock.IsLocked():
- self._logger.LogWarning("Can't unlock unlocked machine!")
- return True
-
- if lock.exclusive != exclusive:
- self._logger.LogError(
- "shared locks must be unlocked with --shared"
- )
- return False
-
- if lock.exclusive:
- if lock.owner != getpass.getuser() and not force:
- self._logger.LogError(
- "%s can't unlock lock owned by: %s"
- % (getpass.getuser(), lock.owner)
- )
- return False
- if lock.auto != self._auto:
- self._logger.LogError(
- "Can't unlock lock with different -a" " parameter."
- )
- return False
- lock.exclusive = False
- lock.reason = ""
- lock.owner = ""
-
- if self._auto:
- del_list = [
- i
- for i in FileLock.FILE_OPS
- if i.name == FileCheckName(self._lock_file)
- ]
- for i in del_list:
- FileLock.FILE_OPS.remove(i)
- for f in del_list:
- fcntl.lockf(f, fcntl.LOCK_UN)
- f.close()
- del del_list
- os.remove(FileCheckName(self._lock_file))
-
- else:
- lock.counter -= 1
- return True
-
-
-class Machine(object):
- """Machine class"""
-
- LOCKS_DIR = "/google/data/rw/users/mo/mobiletc-prebuild/locks"
-
- def __init__(self, name, locks_dir=LOCKS_DIR, auto=True):
- self._name = name
- self._auto = auto
- try:
- self._full_name = socket.gethostbyaddr(name)[0]
- except socket.error:
- self._full_name = self._name
- self._full_name = os.path.join(locks_dir, self._full_name)
-
- def Lock(self, exclusive=False, reason=""):
- lock = Lock(self._full_name, self._auto)
- return lock.NonBlockingLock(exclusive, reason)
-
- def TryLock(self, timeout=300, exclusive=False, reason=""):
- locked = False
- sleep = timeout / 10
- while True:
- locked = self.Lock(exclusive, reason)
- if locked or timeout < 0:
- break
- print(
- "Lock not acquired for {0}, wait {1} seconds ...".format(
- self._name, sleep
- )
- )
- time.sleep(sleep)
- timeout -= sleep
- return locked
-
- def Unlock(self, exclusive=False, ignore_ownership=False):
- lock = Lock(self._full_name, self._auto)
- return lock.Unlock(exclusive, ignore_ownership)
-
-
-def Main(argv):
- """The main function."""
-
- parser = argparse.ArgumentParser()
- parser.add_argument(
- "-r", "--reason", dest="reason", default="", help="The lock reason."
- )
- parser.add_argument(
- "-u",
- "--unlock",
- dest="unlock",
- action="store_true",
- default=False,
- help="Use this to unlock.",
- )
- parser.add_argument(
- "-l",
- "--list_locks",
- dest="list_locks",
- action="store_true",
- default=False,
- help="Use this to list locks.",
- )
- parser.add_argument(
- "-f",
- "--ignore_ownership",
- dest="ignore_ownership",
- action="store_true",
- default=False,
- help="Use this to force unlock on a lock you don't own.",
- )
- parser.add_argument(
- "-s",
- "--shared",
- dest="shared",
- action="store_true",
- default=False,
- help="Use this for a shared (non-exclusive) lock.",
- )
- parser.add_argument(
- "-d",
- "--dir",
- dest="locks_dir",
- action="store",
- default=Machine.LOCKS_DIR,
- help="Use this to set different locks_dir",
- )
- parser.add_argument("args", nargs="*", help="Machine arg.")
-
- options = parser.parse_args(argv)
-
- options.locks_dir = os.path.abspath(options.locks_dir)
- exclusive = not options.shared
-
- if not options.list_locks and len(options.args) != 2:
- logger.GetLogger().LogError(
- "Either --list_locks or a machine arg is needed."
- )
- return 1
-
- if len(options.args) > 1:
- machine = Machine(options.args[1], options.locks_dir, auto=False)
- else:
- machine = None
-
- if options.list_locks:
- FileLock.ListLock("*", options.locks_dir)
- retval = True
- elif options.unlock:
- retval = machine.Unlock(exclusive, options.ignore_ownership)
- else:
- retval = machine.Lock(exclusive, options.reason)
-
- if retval:
- return 0
- else:
- return 1
-
-
-if __name__ == "__main__":
- sys.exit(Main(sys.argv[1:]))
diff --git a/file_lock_machine_test.py b/file_lock_machine_test.py
deleted file mode 100755
index 467c183d..00000000
--- a/file_lock_machine_test.py
+++ /dev/null
@@ -1,128 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-
-# Copyright 2019 The ChromiumOS Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""lock_machine.py related unit-tests.
-
-MachineManagerTest tests MachineManager.
-"""
-
-
-__author__ = "asharif@google.com (Ahmad Sharif)"
-
-from multiprocessing import Process
-import time
-import unittest
-
-import file_lock_machine
-
-
-def LockAndSleep(machine):
- file_lock_machine.Machine(machine, "/tmp", auto=True).Lock(exclusive=True)
- time.sleep(1)
-
-
-class MachineTest(unittest.TestCase):
- """Class for testing machine locking."""
-
- def setUp(self):
- pass
-
- def testRepeatedUnlock(self):
- mach = file_lock_machine.Machine("qqqraymes.mtv", "/tmp")
- for _ in range(10):
- self.assertTrue(mach.Unlock())
- mach = file_lock_machine.Machine("qqqraymes.mtv", "/tmp", auto=True)
- for _ in range(10):
- self.assertTrue(mach.Unlock())
-
- def testLockUnlock(self):
- mach = file_lock_machine.Machine("otter.mtv", "/tmp")
- for _ in range(10):
- self.assertTrue(mach.Lock(exclusive=True))
- self.assertTrue(mach.Unlock(exclusive=True))
-
- mach = file_lock_machine.Machine("otter.mtv", "/tmp", True)
- for _ in range(10):
- self.assertTrue(mach.Lock(exclusive=True))
- self.assertTrue(mach.Unlock(exclusive=True))
-
- def testSharedLock(self):
- mach = file_lock_machine.Machine("chrotomation.mtv", "/tmp")
- for _ in range(10):
- self.assertTrue(mach.Lock(exclusive=False))
- for _ in range(10):
- self.assertTrue(mach.Unlock(exclusive=False))
- self.assertTrue(mach.Lock(exclusive=True))
- self.assertTrue(mach.Unlock(exclusive=True))
-
- mach = file_lock_machine.Machine("chrotomation.mtv", "/tmp", auto=True)
- for _ in range(10):
- self.assertTrue(mach.Lock(exclusive=False))
- for _ in range(10):
- self.assertTrue(mach.Unlock(exclusive=False))
- self.assertTrue(mach.Lock(exclusive=True))
- self.assertTrue(mach.Unlock(exclusive=True))
-
- def testExclusiveLock(self):
- mach = file_lock_machine.Machine("atree.mtv", "/tmp")
- self.assertTrue(mach.Lock(exclusive=True))
- for _ in range(10):
- self.assertFalse(mach.Lock(exclusive=True))
- self.assertFalse(mach.Lock(exclusive=False))
- self.assertTrue(mach.Unlock(exclusive=True))
-
- mach = file_lock_machine.Machine("atree.mtv", "/tmp", auto=True)
- self.assertTrue(mach.Lock(exclusive=True))
- for _ in range(10):
- self.assertFalse(mach.Lock(exclusive=True))
- self.assertFalse(mach.Lock(exclusive=False))
- self.assertTrue(mach.Unlock(exclusive=True))
-
- def testExclusiveState(self):
- mach = file_lock_machine.Machine("testExclusiveState", "/tmp")
- self.assertTrue(mach.Lock(exclusive=True))
- for _ in range(10):
- self.assertFalse(mach.Lock(exclusive=False))
- self.assertTrue(mach.Unlock(exclusive=True))
-
- mach = file_lock_machine.Machine(
- "testExclusiveState", "/tmp", auto=True
- )
- self.assertTrue(mach.Lock(exclusive=True))
- for _ in range(10):
- self.assertFalse(mach.Lock(exclusive=False))
- self.assertTrue(mach.Unlock(exclusive=True))
-
- def testAutoLockGone(self):
- mach = file_lock_machine.Machine("lockgone", "/tmp", auto=True)
- p = Process(target=LockAndSleep, args=("lockgone",))
- p.start()
- time.sleep(1.1)
- p.join()
- self.assertTrue(mach.Lock(exclusive=True))
-
- def testAutoLockFromOther(self):
- mach = file_lock_machine.Machine("other_lock", "/tmp", auto=True)
- p = Process(target=LockAndSleep, args=("other_lock",))
- p.start()
- time.sleep(0.5)
- self.assertFalse(mach.Lock(exclusive=True))
- p.join()
- time.sleep(0.6)
- self.assertTrue(mach.Lock(exclusive=True))
-
- def testUnlockByOthers(self):
- mach = file_lock_machine.Machine("other_unlock", "/tmp", auto=True)
- p = Process(target=LockAndSleep, args=("other_unlock",))
- p.start()
- time.sleep(0.5)
- self.assertTrue(mach.Unlock(exclusive=True))
- self.assertTrue(mach.Lock(exclusive=True))
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/llvm_tools/README.md b/llvm_tools/README.md
index e2ef34f1..8d0ff58c 100644
--- a/llvm_tools/README.md
+++ b/llvm_tools/README.md
@@ -552,3 +552,44 @@ Note that it's recommended to 'seed' the state file with a most recent upload
date. This can be done by running this tool *once* with a `--last_date` flag.
This flag has the script override whatever's in the state file (if anything) and
start submitting all crashes uploaded starting at the given day.
+
+### `werror_logs.py`
+
+This tool exists to help devs reason about `-Werror` instances that _would_
+break builds, were the `FORCE_DISABLE_WERROR` support in the compiler wrapper
+not enabled.
+
+Usage example:
+
+```
+$ ./werror_logs.py aggregate \
+ --directory=${repo}/out/sdk/tmp/portage/dev-cpp/gtest-1.13.0-r12/cros-artifacts
+```
+
+## `fetch_cq_size_diff.py`
+
+This script should be runnable both inside and outside of the chroot.
+
+This script exists to help users fill in the llvm-next testing matrix. It's
+capable of comparing the sizes of ChromeOS images, and the size of Chrome's
+debuginfo. An example of this is:
+
+```
+$ ./fetch_cq_size_diff.py --image gs \
+ gs://chromeos-image-archive/asurada-release/R122-15712.0.0/image.zip
+ gs://chromeos-image-archive/asurada-cq/R122-15712.0.0-92036-8761629109681962289/image.zip
+```
+
+For convenience, this script can also figure out what to compare from a CL, like
+so:
+
+```
+$ ./fetch_cq_size_diff.py --image cl \
+ https://chromium-review.googlesource.com/c/chromiumos/overlays/board-overlays/+/5126116/3
+```
+
+In the above case, this script will find a completed CQ build associated with
+PatchSet 3 of the given CL, and compare the `image.zip` generated by said build
+with the image.zip generated by a release builder for the same board. CQ
+attempts don't have to be entirely green for this; as long as there're a few
+green boards to pick from, this script should be able to make a comparison.
diff --git a/llvm_tools/atomic_write_file.py b/llvm_tools/atomic_write_file.py
index aa6f112e..fc10446f 100644
--- a/llvm_tools/atomic_write_file.py
+++ b/llvm_tools/atomic_write_file.py
@@ -13,11 +13,15 @@ import logging
import os
from pathlib import Path
import tempfile
-from typing import Union
+from typing import Iterator, Literal, Optional, Union
@contextlib.contextmanager
-def atomic_write(fp: Union[Path, str], mode="w", *args, **kwargs):
+def atomic_write(
+ fp: Union[Path, str],
+ mode: Literal["w", "wb"] = "w",
+ encoding: Optional[str] = None,
+) -> Iterator:
"""Write to a filepath atomically.
This works by a temp file swap, created with a .tmp suffix in
@@ -34,13 +38,12 @@ def atomic_write(fp: Union[Path, str], mode="w", *args, **kwargs):
>>> # "f" is closed here, and my_file.txt is written to.
Args:
- fp: Filepath to open.
- mode: File mode; can be 'w', 'wb'. Default 'w'.
- *args: Passed to Path.open as nargs.
- **kwargs: Passed to Path.open as kwargs.
+ fp: Filepath to open.
+ mode: File mode; can be 'w', 'wb'. Default 'w'.
+ encoding: the encoding to use (defaults to None).
Raises:
- ValueError when the mode is invalid.
+ ValueError when the mode is invalid.
"""
if isinstance(fp, str):
fp = Path(fp)
@@ -49,14 +52,15 @@ def atomic_write(fp: Union[Path, str], mode="w", *args, **kwargs):
# We use mkstemp here because we want to handle the closing and
# replacement ourselves.
- (fd, tmp_path) = tempfile.mkstemp(
+ result = tempfile.mkstemp(
prefix=fp.name,
suffix=".tmp",
dir=fp.parent,
)
- tmp_path = Path(tmp_path)
+ fd, tmp_path = (result[0], Path(result[1]))
+
try:
- with os.fdopen(fd, mode=mode, *args, **kwargs) as f:
+ with os.fdopen(fd, mode=mode, encoding=encoding) as f:
yield f
except:
try:
diff --git a/llvm_tools/atomic_write_file_unittest.py b/llvm_tools/atomic_write_file_unittest.py
index 78115569..cc0bb5e4 100644..100755
--- a/llvm_tools/atomic_write_file_unittest.py
+++ b/llvm_tools/atomic_write_file_unittest.py
@@ -1,7 +1,10 @@
+#!/usr/bin/env python3
# Copyright 2023 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+"""Tests for atomic_write_file.py."""
+
from pathlib import Path
import tempfile
import unittest
diff --git a/llvm_tools/auto_llvm_bisection.py b/llvm_tools/auto_llvm_bisection.py
index 9b4b8559..d94b6f0b 100755
--- a/llvm_tools/auto_llvm_bisection.py
+++ b/llvm_tools/auto_llvm_bisection.py
@@ -5,7 +5,6 @@
"""Performs bisection on LLVM based off a .JSON file."""
-
import enum
import json
import os
@@ -16,7 +15,6 @@ import traceback
import chroot
import llvm_bisection
-from llvm_bisection import BisectionExitStatus
import update_tryjob_status
@@ -76,7 +74,7 @@ def GetBuildResult(chroot_path, buildbucket_id):
],
cwd=chroot_path,
stderr=subprocess.STDOUT,
- encoding="UTF-8",
+ encoding="utf-8",
)
except subprocess.CalledProcessError as err:
if "No build found. Perhaps not started" not in err.output:
@@ -169,6 +167,9 @@ def main():
os.rename(temp_filename, args_output.last_tested)
# Launch more tryjobs.
+ bisection_complete = (
+ llvm_bisection.BisectionExitStatus.BISECTION_COMPLETE.value
+ )
for cur_try in range(1, BISECTION_ATTEMPTS + 1):
try:
print("\nAttempting to launch more tryjobs if possible:")
@@ -179,10 +180,7 @@ def main():
print("-" * 40)
# Stop if the bisection has completed.
- if (
- bisection_ret
- == BisectionExitStatus.BISECTION_COMPLETE.value
- ):
+ if bisection_ret == bisection_complete:
sys.exit(0)
# Successfully launched more tryjobs.
diff --git a/llvm_tools/auto_llvm_bisection_unittest.py b/llvm_tools/auto_llvm_bisection_unittest.py
index 30e7dfb3..57837ddf 100755
--- a/llvm_tools/auto_llvm_bisection_unittest.py
+++ b/llvm_tools/auto_llvm_bisection_unittest.py
@@ -5,7 +5,6 @@
"""Tests for auto bisection of LLVM."""
-
import json
import os
import subprocess
@@ -55,7 +54,6 @@ class AutoLLVMBisectionTest(unittest.TestCase):
mock_outside_chroot,
mock_chromeos_root,
):
-
mock_isfile.side_effect = [False, False, True, True]
mock_llvm_bisection.side_effect = [
0,
@@ -112,7 +110,6 @@ class AutoLLVMBisectionTest(unittest.TestCase):
mock_outside_chroot,
mock_chromeos_root,
):
-
mock_isfile.return_value = False
mock_llvm_bisection.side_effect = ValueError(
"Failed to launch more tryjobs."
@@ -160,7 +157,6 @@ class AutoLLVMBisectionTest(unittest.TestCase):
mock_outside_chroot,
mock_chromeos_root,
):
-
# Simulate behavior of `time.time()` for time passed.
@test_helpers.CallCountsToMockFunctions
def MockTimePassed(call_count):
@@ -225,7 +221,7 @@ class AutoLLVMBisectionTest(unittest.TestCase):
],
cwd="/some/path/to/chroot",
stderr=subprocess.STDOUT,
- encoding="UTF-8",
+ encoding="utf-8",
)
@mock.patch.object(subprocess, "check_output")
@@ -247,7 +243,7 @@ class AutoLLVMBisectionTest(unittest.TestCase):
],
cwd=chroot_path,
stderr=subprocess.STDOUT,
- encoding="UTF-8",
+ encoding="utf-8",
)
@mock.patch.object(subprocess, "check_output")
@@ -282,7 +278,7 @@ class AutoLLVMBisectionTest(unittest.TestCase):
],
cwd=chroot_path,
stderr=subprocess.STDOUT,
- encoding="UTF-8",
+ encoding="utf-8",
)
diff --git a/llvm_tools/check_clang_diags.py b/llvm_tools/check_clang_diags.py
index 7beb958f..a33a1274 100755
--- a/llvm_tools/check_clang_diags.py
+++ b/llvm_tools/check_clang_diags.py
@@ -18,6 +18,7 @@ import os
import shutil
import subprocess
import sys
+import textwrap
from typing import Dict, List, Tuple
from cros_utils import bugs
@@ -29,7 +30,7 @@ _DEFAULT_CCS = ["cjdb@google.com"]
# FIXME: clang would be cool to check, too? Doesn't seem to have a super stable
# way of listing all warnings, unfortunately.
-def _build_llvm(llvm_dir: str, build_dir: str):
+def _build_llvm(llvm_dir: str, build_dir: str) -> None:
"""Builds everything that _collect_available_diagnostics depends on."""
targets = ["clang-tidy"]
# use `-C $llvm_dir` so the failure is easier to handle if llvm_dir DNE.
@@ -87,11 +88,11 @@ def _collect_available_diagnostics(
assert (
clang_tidy_checks_stdout[0] == "Enabled checks:"
), clang_tidy_checks_stdout
- clang_tidy_checks = clang_tidy_checks_stdout[1:]
+ available_checks = clang_tidy_checks_stdout[1:]
assert not any(
- check.isspace() for check in clang_tidy_checks
+ check.isspace() for check in available_checks
), clang_tidy_checks
- return {"clang-tidy": clang_tidy_checks}
+ return {"clang-tidy": available_checks}
def _process_new_diagnostics(
@@ -120,9 +121,9 @@ def _process_new_diagnostics(
newly_added_diags = [x for x in diags if x not in old_diags]
if newly_added_diags:
new_diagnostics[tool] = newly_added_diags
- # This specifically tries to make diags sticky: if one is landed, then
- # reverted, then relanded, we ignore the reland. This might not be
- # desirable? I don't know.
+ # This specifically tries to make diags sticky: if one is landed,
+ # then reverted, then relanded, we ignore the reland. This might
+ # not be desirable? I don't know.
new_state_file[tool] = old[tool] + newly_added_diags
# Sort things so we have more predictable output.
@@ -138,19 +139,20 @@ def _file_bugs_for_new_diags(new_diags: Dict[str, List[str]]):
bugs.CreateNewBug(
component_id=bugs.WellKnownComponents.CrOSToolchainPublic,
title=f"Investigate {tool} check `{diag}`",
- body="\n".join(
- (
- f"It seems that the `{diag}` check was recently added to {tool}.",
- "It's probably good to TAL at whether this check would be good",
- "for us to enable in e.g., platform2, or across ChromeOS.",
- )
+ body=textwrap.dedent(
+ f"""\
+ It seems that the `{diag}` check was recently added
+ to {tool}. It's probably good to TAL at whether this
+ check would be good for us to enable in e.g., platform2, or
+ across ChromeOS.
+ """
),
assignee=_DEFAULT_ASSIGNEE,
cc=_DEFAULT_CCS,
)
-def main(argv: List[str]):
+def main(argv: List[str]) -> None:
logging.basicConfig(
format=">> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: "
"%(message)s",
@@ -191,8 +193,8 @@ def main(argv: List[str]):
with open(state_file, encoding="utf-8") as f:
prior_diagnostics = json.load(f)
except FileNotFoundError:
- # If the state file didn't exist, just create it without complaining this
- # time.
+ # If the state file didn't exist, just create it without complaining
+ # this time.
prior_diagnostics = {}
available_diagnostics = _collect_available_diagnostics(llvm_dir, build_dir)
diff --git a/llvm_tools/check_clang_diags_test.py b/llvm_tools/check_clang_diags_test.py
index a7889038..e254f204 100755
--- a/llvm_tools/check_clang_diags_test.py
+++ b/llvm_tools/check_clang_diags_test.py
@@ -5,6 +5,7 @@
"""Tests for check_clang_diags."""
+import textwrap
import unittest
from unittest import mock
@@ -68,12 +69,13 @@ class Test(unittest.TestCase):
mock.call(
component_id=bugs.WellKnownComponents.CrOSToolchainPublic,
title="Investigate clang check `-Wone`",
- body="\n".join(
- (
- "It seems that the `-Wone` check was recently added to clang.",
- "It's probably good to TAL at whether this check would be good",
- "for us to enable in e.g., platform2, or across ChromeOS.",
- )
+ body=textwrap.dedent(
+ """\
+ It seems that the `-Wone` check was recently added
+ to clang. It's probably good to TAL at whether this
+ check would be good for us to enable in e.g., platform2, or
+ across ChromeOS.
+ """
),
assignee=check_clang_diags._DEFAULT_ASSIGNEE,
cc=check_clang_diags._DEFAULT_CCS,
@@ -81,13 +83,13 @@ class Test(unittest.TestCase):
mock.call(
component_id=bugs.WellKnownComponents.CrOSToolchainPublic,
title="Investigate clang-tidy check `bugprone-foo`",
- body="\n".join(
- (
- "It seems that the `bugprone-foo` check was recently added to "
- "clang-tidy.",
- "It's probably good to TAL at whether this check would be good",
- "for us to enable in e.g., platform2, or across ChromeOS.",
- )
+ body=textwrap.dedent(
+ """\
+ It seems that the `bugprone-foo` check was recently added
+ to clang-tidy. It's probably good to TAL at whether this
+ check would be good for us to enable in e.g., platform2, or
+ across ChromeOS.
+ """
),
assignee=check_clang_diags._DEFAULT_ASSIGNEE,
cc=check_clang_diags._DEFAULT_CCS,
diff --git a/llvm_tools/chroot.py b/llvm_tools/chroot.py
index cb0ebc87..5edcbf47 100755
--- a/llvm_tools/chroot.py
+++ b/llvm_tools/chroot.py
@@ -1,42 +1,36 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2020 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Chroot helper functions."""
-
-import collections
import os
from pathlib import Path
import subprocess
-from typing import List
-
+from typing import Iterable, List, Union
-CommitContents = collections.namedtuple("CommitContents", ["url", "cl_number"])
-
-def InChroot():
+def InChroot() -> bool:
"""Returns True if currently in the chroot."""
return "CROS_WORKON_SRCROOT" in os.environ
-def VerifyOutsideChroot():
+def VerifyOutsideChroot() -> None:
"""Checks whether the script invoked was executed in the chroot.
Raises:
- AssertionError: The script was run inside the chroot.
+ AssertionError: The script was run inside the chroot.
"""
assert not InChroot(), "Script should be run outside the chroot."
-def VerifyChromeOSRoot(chromeos_root):
+def VerifyChromeOSRoot(chromeos_root: Union[Path, str]) -> None:
"""Checks whether the path actually points to ChromiumOS checkout root.
Raises:
- AssertionError: The path is not ChromiumOS checkout root.
+ AssertionError: The path is not ChromiumOS checkout root.
"""
subdir = "src/third_party/chromiumos-overlay"
@@ -45,20 +39,22 @@ def VerifyChromeOSRoot(chromeos_root):
assert path.is_dir(), msg
-def GetChrootEbuildPaths(chromeos_root, packages):
+def GetChrootEbuildPaths(
+ chromeos_root: Union[Path, str], packages: Iterable[str]
+) -> List[str]:
"""Gets the chroot path(s) of the package(s).
Args:
- chromeos_root: The absolute path to the chroot to
- use for executing chroot commands.
- packages: A list of a package/packages to
- be used to find their chroot path.
+ chromeos_root: The absolute path to the chroot to
+ use for executing chroot commands.
+ packages: A list of a package/packages to
+ be used to find their chroot path.
Returns:
- A list of chroot paths of the packages' ebuild files.
+ A list of chroot paths of the packages' ebuild files.
Raises:
- ValueError: Failed to get the chroot path of a package.
+ ValueError: Failed to get the chroot path of a package.
"""
chroot_paths = []
@@ -82,15 +78,15 @@ def ConvertChrootPathsToAbsolutePaths(
"""Converts the chroot path(s) to absolute symlink path(s).
Args:
- chromeos_root: The absolute path to the chroot.
- chroot_paths: A list of chroot paths to convert to absolute paths.
+ chromeos_root: The absolute path to the chroot.
+ chroot_paths: A list of chroot paths to convert to absolute paths.
Returns:
- A list of absolute path(s).
+ A list of absolute path(s).
Raises:
- ValueError: Invalid prefix for the chroot path or
- invalid chroot paths were provided.
+ ValueError: Invalid prefix for the chroot path or
+ invalid chroot paths were provided.
"""
abs_paths = []
diff --git a/llvm_tools/chroot_unittest.py b/llvm_tools/chroot_unittest.py
index f1a6a626..ff416b9f 100755
--- a/llvm_tools/chroot_unittest.py
+++ b/llvm_tools/chroot_unittest.py
@@ -1,15 +1,13 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2020 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unit tests for chroot helper functions."""
-
import subprocess
import unittest
-import unittest.mock as mock
+from unittest import mock
import chroot
@@ -25,8 +23,8 @@ class HelperFunctionsTest(unittest.TestCase):
def testSucceedsToGetChrootEbuildPathForPackage(self, mock_chroot_command):
package_chroot_path = "/chroot/path/to/package.ebuild"
- # Emulate ChrootRunCommandWOutput behavior when a chroot path is found for
- # a valid package.
+ # Emulate ChrootRunCommandWOutput behavior when a chroot path is found
+ # for a valid package.
mock_chroot_command.return_value = package_chroot_path
chroot_path = "/test/chroot/path"
@@ -43,8 +41,8 @@ class HelperFunctionsTest(unittest.TestCase):
chroot_path = "/path/to/chroot"
chroot_file_path = "/src/package.ebuild"
- # Verify the exception is raised when a chroot path does not have the prefix
- # '/mnt/host/source/'.
+ # Verify the exception is raised when a chroot path does not have the
+ # prefix '/mnt/host/source/'.
with self.assertRaises(ValueError) as err:
chroot.ConvertChrootPathsToAbsolutePaths(
chroot_path, [chroot_file_path]
diff --git a/llvm_tools/copy_helpers_to_chromiumos_overlay.py b/llvm_tools/copy_helpers_to_chromiumos_overlay.py
index 84716aad..18510a43 100755
--- a/llvm_tools/copy_helpers_to_chromiumos_overlay.py
+++ b/llvm_tools/copy_helpers_to_chromiumos_overlay.py
@@ -1,5 +1,4 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
diff --git a/llvm_tools/cros_cls.py b/llvm_tools/cros_cls.py
new file mode 100644
index 00000000..d0524b6d
--- /dev/null
+++ b/llvm_tools/cros_cls.py
@@ -0,0 +1,246 @@
+# Copyright 2024 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Tools for interacting with CrOS CLs, and the CQ in particular."""
+
+import dataclasses
+import json
+import logging
+import re
+import subprocess
+from typing import Any, Dict, Iterable, List, Optional
+
+
+BuildID = int
+
+
+def _run_bb_decoding_output(command: List[str], multiline: bool = False) -> Any:
+ """Runs `bb` with the `json` flag, and decodes the command's output.
+
+ Args:
+ command: Command to run
+ multiline: If True, this function will parse each line of bb's output
+ as a separate JSON object, and a return a list of all parsed
+ objects.
+ """
+ # `bb` always parses argv[1] as a command, so put `-json` after the first
+ # arg to `bb`.
+ run_command = ["bb", command[0], "-json"] + command[1:]
+ stdout = subprocess.run(
+ run_command,
+ check=True,
+ stdin=subprocess.DEVNULL,
+ stdout=subprocess.PIPE,
+ encoding="utf-8",
+ ).stdout
+
+ def parse_or_log(text: str) -> Any:
+ try:
+ return json.loads(text)
+ except json.JSONDecodeError:
+ logging.error(
+ "Error parsing JSON from command %r; bubbling up. Tried to "
+ "parse: %r",
+ run_command,
+ text,
+ )
+ raise
+
+ if multiline:
+ return [
+ parse_or_log(line)
+ for line in stdout.splitlines()
+ if line and not line.isspace()
+ ]
+ return parse_or_log(stdout)
+
+
+@dataclasses.dataclass(frozen=True, eq=True)
+class ChangeListURL:
+ """A consistent representation of a CL URL.
+
+ The __str__s always converts to a crrev.com URL.
+ """
+
+ cl_id: int
+ patch_set: Optional[int] = None
+
+ @classmethod
+ def parse(cls, url: str) -> "ChangeListURL":
+ url_re = re.compile(
+ # Match an optional https:// header.
+ r"(?:https?://)?"
+ # Match either chromium-review or crrev, leaving the CL number and
+ # patch set as the next parts. These can be parsed in unison.
+ r"(?:chromium-review\.googlesource\.com.*/\+/"
+ r"|crrev\.com/c/)"
+ # Match the CL number...
+ r"(\d+)"
+ # and (optionally) the patch-set, as well as consuming any of the
+ # path after the patch-set.
+ r"(?:/(\d+)?(?:/.*)?)?"
+ # Validate any sort of GET params for completeness.
+ r"(?:$|[?&].*)"
+ )
+
+ m = url_re.fullmatch(url)
+ if not m:
+ raise ValueError(
+ f"URL {url!r} was not recognized. Supported URL formats are "
+ "crrev.com/c/${cl_number}/${patch_set_number}, and "
+ "chromium-review.googlesource.com/c/project/path/+/"
+ "${cl_number}/${patch_set_number}. The patch-set number is "
+ "optional, and there may be a preceding http:// or https://."
+ )
+ cl_id, maybe_patch_set = m.groups()
+ if maybe_patch_set is not None:
+ maybe_patch_set = int(maybe_patch_set)
+ return cls(int(cl_id), maybe_patch_set)
+
+ @classmethod
+ def parse_with_patch_set(cls, url: str) -> "ChangeListURL":
+ """parse(), but raises a ValueError if no patchset is specified."""
+ result = cls.parse(url)
+ if result.patch_set is None:
+ raise ValueError("A patchset number must be specified.")
+ return result
+
+ def __str__(self):
+ result = f"https://crrev.com/c/{self.cl_id}"
+ if self.patch_set is not None:
+ result += f"/{self.patch_set}"
+ return result
+
+
+def builder_url(build_id: BuildID) -> str:
+ """Returns a builder URL given a build ID."""
+ return f"https://ci.chromium.org/b/{build_id}"
+
+
+def fetch_cq_orchestrator_ids(
+ cl: ChangeListURL,
+) -> List[BuildID]:
+ """Returns the BuildID of completed cq-orchestrator runs on a CL.
+
+ Newer runs are sorted later in the list.
+ """
+ results: List[Dict[str, Any]] = _run_bb_decoding_output(
+ [
+ "ls",
+ "-cl",
+ str(cl),
+ "chromeos/cq/cq-orchestrator",
+ ],
+ multiline=True,
+ )
+
+ # We can theoretically filter on a status flag, but it seems to only accept
+ # at most one value. Filter here instead; parsing one or two extra JSON
+ # objects is cheap.
+ finished_results = [
+ x for x in results if x["status"] not in ("scheduled", "started")
+ ]
+
+ # Sort by createTime. Fall back to build ID if a tie needs to be broken.
+ # While `createTime` is a string, it's formatted so it can be sorted
+ # correctly without parsing.
+ finished_results.sort(key=lambda x: (x["createTime"], x["id"]))
+ return [int(x["id"]) for x in finished_results]
+
+
+@dataclasses.dataclass(frozen=True)
+class CQOrchestratorOutput:
+ """A class representing the output of a cq-orchestrator builder."""
+
+ # The status of the CQ builder.
+ status: str
+ # A dict of builders that this CQ builder spawned.
+ child_builders: Dict[str, BuildID]
+
+ @classmethod
+ def fetch(cls, bot_id: BuildID) -> "CQOrchestratorOutput":
+ decoded: Dict[str, Any] = _run_bb_decoding_output(
+ ["get", "-steps", str(bot_id)]
+ )
+ results = {}
+
+ # cq-orchestrator spawns builders in a series of steps. Each step has a
+ # markdownified link to the builder in the summaryMarkdown for each
+ # step. This loop parses those out.
+ build_url_re = re.compile(
+ re.escape("https://cr-buildbucket.appspot.com/build/") + r"(\d+)"
+ )
+ # Example step name containing a build URL:
+ # "run builds|schedule new builds|${builder_name}". `builder_name`
+ # contains no spaces, though follow-up steps with the same prefix might
+ # include spaces.
+ step_name_re = re.compile(
+ re.escape("run builds|schedule new builds|") + "([^ ]+)"
+ )
+ for step in decoded["steps"]:
+ step_name = step["name"]
+ m = step_name_re.fullmatch(step_name)
+ if not m:
+ continue
+
+ builder = m.group(1)
+ summary = step["summaryMarkdown"]
+ ids = build_url_re.findall(summary)
+ if len(ids) != 1:
+ raise ValueError(
+ f"Parsing summary of builder {builder} failed: wanted one "
+ f"match for {build_url_re}; got {ids}. Full summary: "
+ f"{summary!r}"
+ )
+ if builder in results:
+ raise ValueError(f"Builder {builder} spawned multiple times?")
+ results[builder] = int(ids[0])
+ return cls(child_builders=results, status=decoded["status"])
+
+
+@dataclasses.dataclass(frozen=True)
+class CQBoardBuilderOutput:
+ """A class representing the output of a *-cq builder (e.g., brya-cq)."""
+
+ # The status of the CQ builder.
+ status: str
+ # Link to artifacts produced by this builder. Not available if the builder
+ # isn't yet finished, and not available if the builder failed in a weird
+ # way (e.g., INFRA_ERROR)
+ artifacts_link: Optional[str]
+
+ @classmethod
+ def fetch_many(
+ cls, bot_ids: Iterable[BuildID]
+ ) -> List["CQBoardBuilderOutput"]:
+ """Fetches CQBoardBuilderOutput for the given bots."""
+ bb_output = _run_bb_decoding_output(
+ ["get", "-p"] + [str(x) for x in bot_ids], multiline=True
+ )
+ results = []
+ for result in bb_output:
+ status = result["status"]
+ output = result.get("output")
+ if output is None:
+ artifacts_link = None
+ else:
+ artifacts_link = output["properties"].get("artifact_link")
+ results.append(cls(status=status, artifacts_link=artifacts_link))
+ return results
+
+
+def parse_release_from_builder_artifacts_link(artifacts_link: str) -> str:
+ """Parses the release version from a builder artifacts link.
+
+ >>> parse_release_from_builder_artifacts_link(
+ "gs://chromeos-image-archive/amd64-generic-asan-cq/"
+ "R122-15711.0.0-59730-8761718482083052481")
+ "R122-15711.0.0"
+ """
+ results = re.findall(r"/(R\d+-\d+\.\d+\.\d+)-", artifacts_link)
+ if len(results) != 1:
+ raise ValueError(
+ f"Expected one release version in {artifacts_link}; got: {results}"
+ )
+ return results[0]
diff --git a/llvm_tools/cros_cls_test.py b/llvm_tools/cros_cls_test.py
new file mode 100755
index 00000000..fd4ed3ef
--- /dev/null
+++ b/llvm_tools/cros_cls_test.py
@@ -0,0 +1,132 @@
+#!/usr/bin/env python3
+# Copyright 2024 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Tests for cros_cls."""
+
+import unittest
+
+import cros_cls
+
+
+class TestChangeListURL(unittest.TestCase):
+ """ChangeListURL tests."""
+
+ def test_parsing_long_form_url(self):
+ self.assertEqual(
+ cros_cls.ChangeListURL.parse(
+ "chromium-review.googlesource.com/c/chromiumos/overlays/"
+ "chromiumos-overlay/+/123456",
+ ),
+ cros_cls.ChangeListURL(cl_id=123456, patch_set=None),
+ )
+
+ def test_parsing_discards_http(self):
+ self.assertEqual(
+ cros_cls.ChangeListURL.parse("http://crrev.com/c/123456"),
+ cros_cls.ChangeListURL(cl_id=123456, patch_set=None),
+ )
+
+ def test_parsing_discards_https(self):
+ self.assertEqual(
+ cros_cls.ChangeListURL.parse("https://crrev.com/c/123456"),
+ cros_cls.ChangeListURL(cl_id=123456, patch_set=None),
+ )
+
+ def test_parsing_detects_patch_sets(self):
+ self.assertEqual(
+ cros_cls.ChangeListURL.parse("crrev.com/c/123456/14"),
+ cros_cls.ChangeListURL(cl_id=123456, patch_set=14),
+ )
+
+ def test_parsing_is_okay_with_trailing_slash(self):
+ self.assertEqual(
+ cros_cls.ChangeListURL.parse("crrev.com/c/123456/"),
+ cros_cls.ChangeListURL(cl_id=123456, patch_set=None),
+ )
+ self.assertEqual(
+ cros_cls.ChangeListURL.parse("crrev.com/c/123456/14/"),
+ cros_cls.ChangeListURL(cl_id=123456, patch_set=14),
+ )
+
+ def test_parsing_is_okay_with_valid_trailing_junk(self):
+ self.assertEqual(
+ cros_cls.ChangeListURL.parse("crrev.com/c/123456?foo=bar"),
+ cros_cls.ChangeListURL(cl_id=123456, patch_set=None),
+ )
+ self.assertEqual(
+ cros_cls.ChangeListURL.parse("crrev.com/c/123456/?foo=bar"),
+ cros_cls.ChangeListURL(cl_id=123456, patch_set=None),
+ )
+ self.assertEqual(
+ cros_cls.ChangeListURL.parse("crrev.com/c/123456/14/foo=bar"),
+ cros_cls.ChangeListURL(cl_id=123456, patch_set=14),
+ )
+ self.assertEqual(
+ cros_cls.ChangeListURL.parse("crrev.com/c/123456/14?foo=bar"),
+ cros_cls.ChangeListURL(cl_id=123456, patch_set=14),
+ )
+
+ # While these aren't well-formed, Gerrit handles them without issue.
+ self.assertEqual(
+ cros_cls.ChangeListURL.parse("crrev.com/c/123456&foo=bar"),
+ cros_cls.ChangeListURL(cl_id=123456, patch_set=None),
+ )
+ self.assertEqual(
+ cros_cls.ChangeListURL.parse("crrev.com/c/123456/14&foo=bar"),
+ cros_cls.ChangeListURL(cl_id=123456, patch_set=14),
+ )
+
+ def test_parsing_raises_on_invalid_trailing_jumk(self):
+ with self.assertRaises(ValueError):
+ cros_cls.ChangeListURL.parse("crrev.com/c/123456foo=bar")
+
+ with self.assertRaises(ValueError):
+ cros_cls.ChangeListURL.parse("crrev.com/c/123456/14foo=bar")
+
+ def test_str_functions_properly(self):
+ self.assertEqual(
+ str(
+ cros_cls.ChangeListURL(
+ cl_id=1234,
+ patch_set=2,
+ )
+ ),
+ "https://crrev.com/c/1234/2",
+ )
+
+ self.assertEqual(
+ str(
+ cros_cls.ChangeListURL(
+ cl_id=1234,
+ patch_set=None,
+ )
+ ),
+ "https://crrev.com/c/1234",
+ )
+
+
+class Test(unittest.TestCase):
+ """General tests for cros_cls."""
+
+ def test_release_builder_parsing_works(self):
+ self.assertEqual(
+ cros_cls.parse_release_from_builder_artifacts_link(
+ "gs://chromeos-image-archive/amd64-generic-asan-cq/"
+ "R122-15711.0.0-59730-8761718482083052481"
+ ),
+ "R122-15711.0.0",
+ )
+ self.assertEqual(
+ cros_cls.parse_release_from_builder_artifacts_link(
+ "gs://chromeos-image-archive/amd64-generic-asan-cq/"
+ "R122-15711.0.0-59730-8761718482083052481/some/trailing/"
+ "stuff.zip"
+ ),
+ "R122-15711.0.0",
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/llvm_tools/custom_script_example.py b/llvm_tools/custom_script_example.py
index 5a320b41..a2d6a66a 100755
--- a/llvm_tools/custom_script_example.py
+++ b/llvm_tools/custom_script_example.py
@@ -1,16 +1,14 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""A custom script example that utilizes the .JSON contents of the tryjob."""
-
import json
import sys
-from update_tryjob_status import TryjobStatus
+import update_tryjob_status
def main():
@@ -32,7 +30,7 @@ def main():
# }
abs_path_json_file = sys.argv[1]
- with open(abs_path_json_file) as f:
+ with open(abs_path_json_file, encoding="utf-8") as f:
tryjob_contents = json.load(f)
CUTOFF_PENDING_REVISION = 369416
@@ -40,7 +38,10 @@ def main():
SKIP_REVISION_CUTOFF_START = 369420
SKIP_REVISION_CUTOFF_END = 369428
- if tryjob_contents["status"] == TryjobStatus.PENDING.value:
+ if (
+ tryjob_contents["status"]
+ == update_tryjob_status.TryjobStatus.PENDING.value
+ ):
if tryjob_contents["rev"] <= CUTOFF_PENDING_REVISION:
# Exit code 0 means to set the tryjob 'status' as 'good'.
sys.exit(0)
@@ -48,15 +49,19 @@ def main():
# Exit code 124 means to set the tryjob 'status' as 'bad'.
sys.exit(124)
- if tryjob_contents["status"] == TryjobStatus.BAD.value:
- # Need to take a closer look at the contents of the tryjob to then decide
- # what that tryjob's 'status' value should be.
+ if tryjob_contents["status"] == update_tryjob_status.TryjobStatus.BAD.value:
+ # Need to take a closer look at the contents of the tryjob to then
+ # decide what that tryjob's 'status' value should be.
#
- # Since the exit code is not in the mapping, an exception will occur which
- # will save the file in the directory of this custom script example.
+ # Since the exit code is not in the mapping, an exception will occur
+ # which will save the file in the directory of this custom script
+ # example.
sys.exit(1)
- if tryjob_contents["status"] == TryjobStatus.SKIP.value:
+ if (
+ tryjob_contents["status"]
+ == update_tryjob_status.TryjobStatus.SKIP.value
+ ):
# Validate that the 'skip value is really set between the cutoffs.
if (
SKIP_REVISION_CUTOFF_START
diff --git a/llvm_tools/failure_modes.py b/llvm_tools/failure_modes.py
index fc4e1fc2..b9355b7e 100644
--- a/llvm_tools/failure_modes.py
+++ b/llvm_tools/failure_modes.py
@@ -1,11 +1,9 @@
-# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Failure mode constants avaiable to the patch manager."""
-
import enum
diff --git a/llvm_tools/fetch_cq_size_diff.py b/llvm_tools/fetch_cq_size_diff.py
new file mode 100755
index 00000000..a20f7396
--- /dev/null
+++ b/llvm_tools/fetch_cq_size_diff.py
@@ -0,0 +1,366 @@
+#!/usr/bin/env python3
+# Copyright 2024 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Fetches the size diff between two images on gs://.
+
+If given a CL, this will autodetect a passing CQ builder on that CL and find
+a corresponding release build for said CQ builder. The sizes of these images
+will be compared.
+
+**Please note** that there's often version skew between release builds and CQ
+builds. While this skew shouldn't result in _huge_ binary size differences,
+it can still account for a few MB of diff in an average case.
+"""
+
+import abc
+import argparse
+import dataclasses
+import json
+import logging
+import os
+from pathlib import Path
+import subprocess
+import sys
+import tempfile
+from typing import List, Optional, Tuple
+
+import cros_cls
+
+
+@dataclasses.dataclass(frozen=True)
+class SizeDiffInfo:
+ """Holds information about a size difference."""
+
+ baseline_size_bytes: int
+ new_size_bytes: int
+
+
+class ComparableArtifact(abc.ABC):
+ """Artifacts from CQ runs that can be compared."""
+
+ @property
+ @abc.abstractmethod
+ def artifact_name(self) -> str:
+ """Returns the name of the artifact in gs:// e.g., "image.zip"."""
+
+ @abc.abstractmethod
+ def _measure_artifact_size(self, file: Path) -> int:
+ """Given a path to the artifact, extract the relevant size info.
+
+ The directory that `file` is in may be mutated by this function. No
+ guarantees are made about the state of said directory after execution
+ finishes, except that `file` should remain unmodified.
+ """
+
+ def _download_and_measure_size(self, gs_url: str) -> int:
+ with tempfile.TemporaryDirectory(
+ prefix="fetch_size_diff_"
+ ) as tempdir_str:
+ into = Path(tempdir_str)
+ local_file = into / os.path.basename(gs_url)
+ subprocess.run(
+ ["gsutil", "cp", gs_url, local_file],
+ check=True,
+ stdin=subprocess.DEVNULL,
+ )
+ return self._measure_artifact_size(local_file)
+
+ def compare_size_from_gs(self, baseline: str, new: str) -> SizeDiffInfo:
+ return SizeDiffInfo(
+ baseline_size_bytes=self._download_and_measure_size(baseline),
+ new_size_bytes=self._download_and_measure_size(new),
+ )
+
+
+class DebugInfoArtifact(ComparableArtifact):
+ """ComparableArtifact instance for debuginfo."""
+
+ @property
+ def artifact_name(self) -> str:
+ return "debug.tgz"
+
+ def _measure_artifact_size(self, file: Path) -> int:
+ chrome_debug = "./opt/google/chrome/chrome.debug"
+ logging.info("Unpacking debuginfo...")
+ subprocess.run(
+ ["tar", "xaf", file, chrome_debug],
+ check=True,
+ cwd=file.parent,
+ stdin=subprocess.DEVNULL,
+ )
+ return os.path.getsize(file.parent / chrome_debug)
+
+
+class ImageSizeArtifact(ComparableArtifact):
+ """ComparableArtifact instance for image files."""
+
+ @property
+ def artifact_name(self) -> str:
+ return "image.zip"
+
+ def _measure_artifact_size(self, file: Path) -> int:
+ binpkg_sizes_name = "chromiumos_base_image.bin-package-sizes.json"
+ subprocess.run(
+ [
+ "unzip",
+ file.name,
+ binpkg_sizes_name,
+ ],
+ check=True,
+ cwd=file.parent,
+ stdin=subprocess.DEVNULL,
+ )
+ with (file.parent / binpkg_sizes_name).open(encoding="utf-8") as f:
+ loaded = json.load(f)
+ try:
+ size = loaded["total_size"]
+ except KeyError:
+ raise ValueError(f"Missing total_size in {loaded.keys()}")
+
+ if not isinstance(size, int):
+ raise ValueError(
+ f"total_size was unexpectedly {type(size)}: {size}"
+ )
+ return size
+
+
+def is_probably_non_production_builder(builder_name: str) -> bool:
+ """Quickly determine if a builder doesn't represent a board in production.
+
+ Note that this is a heuristic; results should be taken as mostly accurate.
+ """
+ return any(
+ x in builder_name
+ for x in (
+ "-asan-",
+ "-buildtest-",
+ "-fuzzer-",
+ "-kernelnext-",
+ "-ubsan-",
+ "-vmtest-",
+ )
+ )
+
+
+def guess_release_artifact_path(artifact_link: str) -> Optional[str]:
+ """Guesses a close-enough release path for a CQ artifact.
+
+ Returns:
+ A path to the release artifact. Returns None if the given image_zip
+ wasn't generated by a CQ builder.
+
+ >>> guess_release_artifact_path("gs://chromeos-image-archive/brya-cq/"
+ "R121-15677.0.0-90523-8764532770258575633/image.zip")
+ "gs://chromeos-image-archive/brya-release/R121-15677.0.0/image.zip"
+ """
+ artifacts_link = os.path.dirname(artifact_link)
+ release_version = cros_cls.parse_release_from_builder_artifacts_link(
+ artifacts_link
+ )
+ # Scrape the board name from a level above the artifacts directory.
+ builder = os.path.basename(os.path.dirname(artifacts_link))
+ if not builder.endswith("-cq"):
+ return None
+ board = builder[:-3]
+ return (
+ f"gs://chromeos-image-archive/{board}-release/{release_version}/"
+ f"{os.path.basename(artifact_link)}"
+ )
+
+
+def try_gsutil_ls(paths: List[str]) -> List[str]:
+ """Returns all of the paths `gsutil` matches from `paths`.
+
+ Ignores errors from gsutil about paths not existing.
+ """
+ result = subprocess.run(
+ ["gsutil", "-m", "ls"] + paths,
+ # If any URI doesn't exist, gsutil will fail. Ignore the failure.
+ check=False,
+ encoding="utf-8",
+ stdin=subprocess.DEVNULL,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.PIPE,
+ )
+ if result.returncode:
+ # Ensure the error message is what's expected, rather than e.g.,
+ # invalid credentials.
+ err_msg = "CommandException: One or more URLs matched no objects"
+ if err_msg not in result.stderr:
+ logging.error(
+ "gsutil had unexpected output; stderr: %r", result.stderr
+ )
+ result.check_returncode()
+ return [x.strip() for x in result.stdout.splitlines()]
+
+
+def find_size_diffable_cq_artifacts(
+ cq_build_ids: List[cros_cls.BuildID],
+ artifact_name: str,
+) -> Optional[Tuple[str, str]]:
+ """Searches the cq-orchestrator builds for candidates for size comparison.
+
+ Returns:
+ None if no candidates are found. Otherwise, returns a two-tuple: index
+ 0 is the baseline (release) artifact, index 1 is the corresponding
+ artifact generated by the CQ.
+ """
+ for cq_build_id in cq_build_ids:
+ logging.info("Inspecting CQ build %d...", cq_build_id)
+ orch_output = cros_cls.CQOrchestratorOutput.fetch(cq_build_id)
+ child_builder_values = cros_cls.CQBoardBuilderOutput.fetch_many(
+ [
+ val
+ for name, val in orch_output.child_builders.items()
+ if not is_probably_non_production_builder(name)
+ ]
+ )
+ artifacts_links = [
+ x.artifacts_link
+ for x in child_builder_values
+ if x.artifacts_link is not None
+ ]
+ if not artifacts_links:
+ logging.info("No children of CQ run %d had artifacts", cq_build_id)
+ continue
+
+ potential_artifacts = try_gsutil_ls(
+ [os.path.join(x, artifact_name) for x in artifacts_links]
+ )
+ if not potential_artifacts:
+ logging.info(
+ "No children of CQ run %d produced a(n) %s",
+ cq_build_id,
+ artifact_name,
+ )
+ continue
+
+ logging.debug(
+ "Found candidate %s files: %s", artifact_name, potential_artifacts
+ )
+ guessed_paths = [
+ (x, guess_release_artifact_path(x)) for x in potential_artifacts
+ ]
+ logging.debug("Guessed corresponding artifact files: %s", guessed_paths)
+ release_artifacts = try_gsutil_ls([x for _, x in guessed_paths if x])
+ if not release_artifacts:
+ logging.info(
+ "No release %s artifacts could be found for CQ builder %d.",
+ artifact_name,
+ cq_build_id,
+ )
+ continue
+
+ # `try_gsutil_ls` makes no ordering guarantees; always pick the min()
+ # artifact here for consistency across reruns.
+ selected_release_artifact = min(release_artifacts)
+ logging.info("Selected release artifact: %s", selected_release_artifact)
+ cq_artifact = next(
+ cq_path
+ for cq_path, guessed_path in guessed_paths
+ if guessed_path == selected_release_artifact
+ )
+ return selected_release_artifact, cq_artifact
+ return None
+
+
+def inspect_gs_impl(
+ baseline_gs_url: str, new_gs_url: str, artifact: ComparableArtifact
+) -> None:
+ """Compares the `image.zip`s at the given URLs, logging the results."""
+ size_diff = artifact.compare_size_from_gs(baseline_gs_url, new_gs_url)
+ # `%d` doesn't support `,` as a modifier, and commas make these numbers
+ # much easier to read. Prefer to keep strings interpreted as format strings
+ # constant.
+ logging.info("Baseline size: %s", f"{size_diff.baseline_size_bytes:,}")
+ logging.info("New size: %s", f"{size_diff.new_size_bytes:,}")
+
+ diff_pct = abs(size_diff.new_size_bytes / size_diff.baseline_size_bytes) - 1
+ logging.info("Diff: %.2f%%", diff_pct * 100)
+
+
+def inspect_cl(opts: argparse.Namespace, artifact: ComparableArtifact) -> None:
+ """Implements the `cl` subcommand of this script."""
+ cq_build_ids = cros_cls.fetch_cq_orchestrator_ids(opts.cl)
+ if not cq_build_ids:
+ sys.exit(f"No completed cq-orchestrators found for {opts.cl}")
+
+ # Reverse cq_build_ids so we try the newest first.
+ diffable_artifacts = find_size_diffable_cq_artifacts(
+ cq_build_ids, artifact.artifact_name
+ )
+ if not diffable_artifacts:
+ sys.exit("No diffable artifacts were found")
+
+ baseline, new = diffable_artifacts
+ logging.info("Comparing %s (baseline) to %s (new)", baseline, new)
+ inspect_gs_impl(baseline, new, artifact)
+ logging.warning(
+ "Friendly reminder: CL inspection diffs between your CL and a "
+ "corresponding release build. Size differences up to a few megabytes "
+ "are expected and do not necessarily indicate a size difference "
+ "attributable to your CL."
+ )
+
+
+def inspect_gs(opts: argparse.Namespace, artifact: ComparableArtifact) -> None:
+ """Implements the `gs` subcommand of this script."""
+ inspect_gs_impl(opts.baseline, opts.new, artifact)
+
+
+def main(argv: List[str]) -> None:
+ parser = argparse.ArgumentParser(
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+ what_to_compare = parser.add_mutually_exclusive_group(required=True)
+ what_to_compare.add_argument(
+ "--image", action="store_true", help="Compare image.zip sizes."
+ )
+ what_to_compare.add_argument(
+ "--debuginfo", action="store_true", help="Compare debuginfo sizes."
+ )
+
+ parser.add_argument(
+ "--debug", action="store_true", help="Enable debug logging"
+ )
+ subparsers = parser.add_subparsers(required=True)
+
+ cl_parser = subparsers.add_parser(
+ "cl", help="Inspect a CL's CQ runs to find artifacts to compare."
+ )
+ cl_parser.set_defaults(func=inspect_cl)
+ cl_parser.add_argument(
+ "cl",
+ type=cros_cls.ChangeListURL.parse_with_patch_set,
+ help="CL to inspect CQ runs of. This must contain a patchset number.",
+ )
+
+ gs_parser = subparsers.add_parser(
+ "gs", help="Directly compare two zip files from gs://."
+ )
+ gs_parser.add_argument("baseline", help="Baseline file to compare.")
+ gs_parser.add_argument("new", help="New file to compare.")
+ gs_parser.set_defaults(func=inspect_gs)
+ opts = parser.parse_args(argv)
+
+ logging.basicConfig(
+ format=">> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: "
+ "%(message)s",
+ level=logging.DEBUG if opts.debug else logging.INFO,
+ )
+
+ assert getattr(opts, "func", None), "Unknown subcommand?"
+ if opts.image:
+ artifact: ComparableArtifact = ImageSizeArtifact()
+ else:
+ assert opts.debuginfo
+ artifact = DebugInfoArtifact()
+
+ opts.func(opts, artifact)
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/llvm_tools/fetch_cros_sdk_rolls.py b/llvm_tools/fetch_cros_sdk_rolls.py
index dc678e10..b426f147 100755
--- a/llvm_tools/fetch_cros_sdk_rolls.py
+++ b/llvm_tools/fetch_cros_sdk_rolls.py
@@ -79,7 +79,8 @@ def main():
"--number",
type=int,
default=20,
- help="Number of recent manifests to fetch info about. 0 means unlimited.",
+ help="Number of recent manifests to fetch info about. 0 means "
+ "unlimited.",
)
args = parser.parse_args()
diff --git a/llvm_tools/generate_llvm_revert_report.py b/llvm_tools/generate_llvm_revert_report.py
new file mode 100755
index 00000000..f6a11128
--- /dev/null
+++ b/llvm_tools/generate_llvm_revert_report.py
@@ -0,0 +1,159 @@
+#!/usr/bin/env python3
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Reports on all reverts applied and not applied to sys-devel/llvm.
+
+Note that this is primarily intended to produce output that can be easily
+pasted into a spreadsheet (read: the ChromeOS Mage's test matrix), so output is
+in CSV format.
+"""
+
+import argparse
+import csv
+import dataclasses
+import json
+import logging
+from pathlib import Path
+import re
+import subprocess
+import sys
+from typing import List, Set, TextIO
+
+import get_upstream_patch
+import revert_checker
+
+
+@dataclasses.dataclass(frozen=True)
+class RevertInfo:
+ """Information to write about a revert."""
+
+ revert: revert_checker.Revert
+ has_in_patches: bool
+ subject: str
+
+
+def list_upstream_cherrypicks(patches_json: Path) -> Set[str]:
+ with patches_json.open(encoding="utf-8") as f:
+ applicable_patches = [
+ x
+ for x in json.load(f)
+ if not x.get("platforms") or "chromiumos" in x["platforms"]
+ ]
+
+ # Allow for arbitrary suffixes for patches; some have `-v2`, `_fixed`, etc.
+ sha_re = re.compile(r"cherry/([a-fA-F0-9]{40})\b.*\.patch$")
+ sha_like_patches = set()
+ for p in applicable_patches:
+ m = sha_re.match(p["rel_patch_path"])
+ if m:
+ sha_like_patches.add(m.group(1))
+
+ return sha_like_patches
+
+
+def fetch_commit_subject(llvm_git_dir: Path, sha: str) -> str:
+ result = subprocess.run(
+ ["git", "log", "--format=%s", "-n1", sha],
+ check=True,
+ cwd=llvm_git_dir,
+ encoding="utf-8",
+ stdin=subprocess.DEVNULL,
+ stdout=subprocess.PIPE,
+ # Don't set stderr, since that should only be written to on error (and
+ # `check=True`).
+ )
+ return result.stdout.strip()
+
+
+def write_reverts_as_csv(write_to: TextIO, reverts: List[RevertInfo]):
+ writer = csv.writer(write_to, quoting=csv.QUOTE_ALL)
+ # Write the header.
+ writer.writerow(("SHA", "Reverted SHA", "Has Revert", "Subject"))
+ writer.writerows(
+ (x.revert.sha, x.revert.reverted_sha, x.has_in_patches, x.subject)
+ for x in reverts
+ )
+
+
+def main(argv: List[str]):
+ logging.basicConfig(
+ format=">> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: "
+ "%(message)s",
+ level=logging.INFO,
+ )
+
+ my_dir = Path(__name__).resolve().parent
+
+ parser = argparse.ArgumentParser(
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+ parser.add_argument(
+ "-C",
+ "--git-dir",
+ default=my_dir.parent.parent / "llvm-project",
+ help="LLVM git directory to use.",
+ # Note that this is left as `type=str` because that's what
+ # `revert_checker` expects.
+ type=str,
+ )
+ parser.add_argument(
+ "--llvm-next", action="store_true", help="Use the llvm-next hash"
+ )
+ parser.add_argument(
+ "--llvm-dir",
+ help="Directory containing LLVM ebuilds",
+ type=Path,
+ default=my_dir.parent.parent / "chromiumos-overlay/sys-devel/llvm",
+ )
+ parser.add_argument(
+ "--llvm-head",
+ default="cros/upstream/main",
+ help="ref to treat as 'origin/main' in the given LLVM dir.",
+ )
+ opts = parser.parse_args(argv)
+
+ symbolic_sha = "llvm-next" if opts.llvm_next else "llvm"
+ llvm_sha = get_upstream_patch.resolve_symbolic_sha(
+ symbolic_sha,
+ opts.llvm_dir,
+ )
+ logging.info("Resolved %r as the LLVM SHA to check.", llvm_sha)
+
+ in_tree_cherrypicks = list_upstream_cherrypicks(
+ opts.llvm_dir / "files/PATCHES.json"
+ )
+ logging.info("Identified %d local cherrypicks.", len(in_tree_cherrypicks))
+
+ raw_reverts = revert_checker.find_reverts(
+ opts.git_dir,
+ llvm_sha,
+ opts.llvm_head,
+ )
+
+ llvm_dir = Path(opts.git_dir)
+ # Sort by `has_in_patches`, since that ordering is easier to visually scan.
+ # Note that `sorted` is stable, so any ordering in `find_reverts` will be
+ # preserved secondary to the `has_in_patches` ordering. Reverts not in
+ # PATCHES.json will appear earlier than those that are.
+ reverts = sorted(
+ (
+ RevertInfo(
+ revert=revert,
+ subject=fetch_commit_subject(llvm_dir, revert.sha),
+ has_in_patches=revert.sha in in_tree_cherrypicks,
+ )
+ for revert in raw_reverts
+ ),
+ key=lambda x: x.has_in_patches,
+ )
+
+ print()
+ print("CSV summary of reverts:")
+ write_reverts_as_csv(sys.stdout, reverts)
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/llvm_tools/get_llvm_hash.py b/llvm_tools/get_llvm_hash.py
index fee8e4f6..e9a8990f 100755
--- a/llvm_tools/get_llvm_hash.py
+++ b/llvm_tools/get_llvm_hash.py
@@ -1,43 +1,42 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Returns the latest LLVM version's hash."""
-
import argparse
import contextlib
import functools
import os
+from pathlib import Path
import re
import shutil
import subprocess
import sys
import tempfile
+from typing import Iterator, Optional, Tuple, Union
import git_llvm_rev
-from subprocess_helpers import check_output
-from subprocess_helpers import CheckCommand
+import subprocess_helpers
_LLVM_GIT_URL = (
- "https://chromium.googlesource.com/external/github.com/llvm" "/llvm-project"
+ "https://chromium.googlesource.com/external/github.com/llvm/llvm-project"
)
KNOWN_HASH_SOURCES = {"google3", "google3-unstable", "tot"}
-def GetVersionFrom(src_dir, git_hash):
+def GetVersionFrom(src_dir: Union[Path, str], git_hash: str) -> int:
"""Obtain an SVN-style version number based on the LLVM git hash passed in.
Args:
- src_dir: LLVM's source directory.
- git_hash: The git hash.
+ src_dir: LLVM's source directory.
+ git_hash: The git hash.
Returns:
- An SVN-style version number associated with the git hash.
+ An SVN-style version number associated with the git hash.
"""
version = git_llvm_rev.translate_sha_to_rev(
@@ -48,18 +47,18 @@ def GetVersionFrom(src_dir, git_hash):
return version.number
-def GetGitHashFrom(src_dir, version):
+def GetGitHashFrom(src_dir: Union[Path, str], version: int) -> str:
"""Finds the commit hash(es) of the LLVM version in the git log history.
Args:
- src_dir: The LLVM source tree.
- version: The version number.
+ src_dir: The LLVM source tree.
+ version: The version number.
Returns:
- A git hash string corresponding to the version number.
+ A git hash string corresponding to the version number.
Raises:
- subprocess.CalledProcessError: Failed to find a git hash.
+ subprocess.CalledProcessError: Failed to find a git hash.
"""
return git_llvm_rev.translate_rev_to_sha(
@@ -68,31 +67,31 @@ def GetGitHashFrom(src_dir, version):
)
-def CheckoutBranch(src_dir, branch):
+def CheckoutBranch(src_dir: Union[Path, str], branch: str) -> None:
"""Checks out and pulls from a branch in a git repo.
Args:
- src_dir: The LLVM source tree.
- branch: The git branch to checkout in src_dir.
+ src_dir: The LLVM source tree.
+ branch: The git branch to checkout in src_dir.
Raises:
- ValueError: Failed to checkout or pull branch version
+ ValueError: Failed to checkout or pull branch version
"""
- CheckCommand(["git", "-C", src_dir, "checkout", branch])
- CheckCommand(["git", "-C", src_dir, "pull"])
+ subprocess_helpers.CheckCommand(["git", "-C", src_dir, "checkout", branch])
+ subprocess_helpers.CheckCommand(["git", "-C", src_dir, "pull"])
-def ParseLLVMMajorVersion(cmakelist):
+def ParseLLVMMajorVersion(cmakelist: str):
"""Reads CMakeList.txt file contents for LLVMMajor Version.
Args:
- cmakelist: contents of CMakeList.txt
+ cmakelist: contents of CMakeList.txt
Returns:
- The major version number as a string
+ The major version number as a string
Raises:
- ValueError: The major version cannot be parsed from cmakelist
+ ValueError: The major version cannot be parsed from cmakelist
"""
match = re.search(
r"\n\s+set\(LLVM_VERSION_MAJOR (?P<major>\d+)\)", cmakelist
@@ -103,26 +102,28 @@ def ParseLLVMMajorVersion(cmakelist):
@functools.lru_cache(maxsize=1)
-def GetLLVMMajorVersion(git_hash=None):
+def GetLLVMMajorVersion(git_hash: Optional[str] = None) -> str:
"""Reads llvm/CMakeList.txt file contents for LLVMMajor Version.
Args:
- git_hash: git hash of llvm version as string or None for top of trunk
+ git_hash: git hash of llvm version as string or None for top of trunk
Returns:
- The major version number as a string
+ The major version number as a string
Raises:
- ValueError: The major version cannot be parsed from cmakelist or
- there was a failure to checkout git_hash version
- FileExistsError: The src directory doe not contain CMakeList.txt
+ ValueError: The major version cannot be parsed from cmakelist or
+ there was a failure to checkout git_hash version
+ FileExistsError: The src directory doe not contain CMakeList.txt
"""
src_dir = GetAndUpdateLLVMProjectInLLVMTools()
cmakelists_path = os.path.join(src_dir, "llvm", "CMakeLists.txt")
if git_hash:
- CheckCommand(["git", "-C", src_dir, "checkout", git_hash])
+ subprocess_helpers.CheckCommand(
+ ["git", "-C", src_dir, "checkout", git_hash]
+ )
try:
- with open(cmakelists_path) as cmakelists_file:
+ with open(cmakelists_path, encoding="utf-8") as cmakelists_file:
return ParseLLVMMajorVersion(cmakelists_file.read())
finally:
if git_hash:
@@ -130,29 +131,29 @@ def GetLLVMMajorVersion(git_hash=None):
@contextlib.contextmanager
-def CreateTempLLVMRepo(temp_dir):
+def CreateTempLLVMRepo(temp_dir: str) -> Iterator[str]:
"""Adds a LLVM worktree to 'temp_dir'.
Creating a worktree because the LLVM source tree in
'../toolchain-utils/llvm_tools/llvm-project-copy' should not be modified.
- This is useful for applying patches to a source tree but do not want to modify
- the actual LLVM source tree in 'llvm-project-copy'.
+ This is useful for applying patches to a source tree but do not want to
+ modify the actual LLVM source tree in 'llvm-project-copy'.
Args:
- temp_dir: An absolute path to the temporary directory to put the worktree in
- (obtained via 'tempfile.mkdtemp()').
+ temp_dir: An absolute path to the temporary directory to put the
+ worktree in (obtained via 'tempfile.mkdtemp()').
Yields:
- The absolute path to 'temp_dir'.
+ The absolute path to 'temp_dir'.
Raises:
- subprocess.CalledProcessError: Failed to remove the worktree.
- ValueError: Failed to add a worktree.
+ subprocess.CalledProcessError: Failed to remove the worktree.
+ ValueError: Failed to add a worktree.
"""
abs_path_to_llvm_project_dir = GetAndUpdateLLVMProjectInLLVMTools()
- CheckCommand(
+ subprocess_helpers.CheckCommand(
[
"git",
"-C",
@@ -169,7 +170,7 @@ def CreateTempLLVMRepo(temp_dir):
yield temp_dir
finally:
if os.path.isdir(temp_dir):
- check_output(
+ subprocess_helpers.check_output(
[
"git",
"-C",
@@ -182,24 +183,25 @@ def CreateTempLLVMRepo(temp_dir):
)
-def GetAndUpdateLLVMProjectInLLVMTools():
+def GetAndUpdateLLVMProjectInLLVMTools() -> str:
"""Gets the absolute path to 'llvm-project-copy' directory in 'llvm_tools'.
The intent of this function is to avoid cloning the LLVM repo and then
discarding the contents of the repo. The function will create a directory
in '../toolchain-utils/llvm_tools' called 'llvm-project-copy' if this
directory does not exist yet. If it does not exist, then it will use the
- LLVMHash() class to clone the LLVM repo into 'llvm-project-copy'. Otherwise,
- it will clean the contents of that directory and then fetch from the chromium
- LLVM mirror. In either case, this function will return the absolute path to
- 'llvm-project-copy' directory.
+ LLVMHash() class to clone the LLVM repo into 'llvm-project-copy'.
+ Otherwise, it will clean the contents of that directory and then fetch from
+ the chromium LLVM mirror. In either case, this function will return the
+ absolute path to 'llvm-project-copy' directory.
Returns:
- Absolute path to 'llvm-project-copy' directory in 'llvm_tools'
+ Absolute path to 'llvm-project-copy' directory in 'llvm_tools'
Raises:
- ValueError: LLVM repo (in 'llvm-project-copy' dir.) has changes or failed to
- checkout to main or failed to fetch from chromium mirror of LLVM.
+ ValueError: LLVM repo (in 'llvm-project-copy' dir.) has changes or
+ failed to checkout to main or failed to fetch from chromium mirror of
+ LLVM.
"""
abs_path_to_llvm_tools_dir = os.path.dirname(os.path.abspath(__file__))
@@ -210,11 +212,9 @@ def GetAndUpdateLLVMProjectInLLVMTools():
if not os.path.isdir(abs_path_to_llvm_project_dir):
print(
- (
- f"Checking out LLVM to {abs_path_to_llvm_project_dir}\n"
- "so that we can map between commit hashes and revision numbers.\n"
- "This may take a while, but only has to be done once."
- ),
+ f"Checking out LLVM to {abs_path_to_llvm_project_dir}\n"
+ "so that we can map between commit hashes and revision numbers.\n"
+ "This may take a while, but only has to be done once.",
file=sys.stderr,
)
os.mkdir(abs_path_to_llvm_project_dir)
@@ -222,9 +222,9 @@ def GetAndUpdateLLVMProjectInLLVMTools():
LLVMHash().CloneLLVMRepo(abs_path_to_llvm_project_dir)
else:
# `git status` has a '-s'/'--short' option that shortens the output.
- # With the '-s' option, if no changes were made to the LLVM repo, then the
- # output (assigned to 'repo_status') would be empty.
- repo_status = check_output(
+ # With the '-s' option, if no changes were made to the LLVM repo, then
+ # the output (assigned to 'repo_status') would be empty.
+ repo_status = subprocess_helpers.check_output(
["git", "-C", abs_path_to_llvm_project_dir, "status", "-s"]
)
@@ -239,18 +239,18 @@ def GetAndUpdateLLVMProjectInLLVMTools():
return abs_path_to_llvm_project_dir
-def GetGoogle3LLVMVersion(stable):
+def GetGoogle3LLVMVersion(stable: bool) -> int:
"""Gets the latest google3 LLVM version.
Args:
- stable: boolean, use the stable version or the unstable version
+ stable: boolean, use the stable version or the unstable version
Returns:
- The latest LLVM SVN version as an integer.
+ The latest LLVM SVN version as an integer.
Raises:
- subprocess.CalledProcessError: An invalid path has been provided to the
- `cat` command.
+ subprocess.CalledProcessError: An invalid path has been provided to the
+ `cat` command.
"""
subdir = "stable" if stable else "llvm_unstable"
@@ -266,7 +266,7 @@ def GetGoogle3LLVMVersion(stable):
]
# Get latest version.
- git_hash = check_output(cmd)
+ git_hash = subprocess_helpers.check_output(cmd)
# Change type to an integer
return GetVersionFrom(
@@ -274,20 +274,20 @@ def GetGoogle3LLVMVersion(stable):
)
-def IsSvnOption(svn_option):
+def IsSvnOption(svn_option: str) -> Union[int, str]:
"""Validates whether the argument (string) is a git hash option.
The argument is used to find the git hash of LLVM.
Args:
- svn_option: The option passed in as a command line argument.
+ svn_option: The option passed in as a command line argument.
Returns:
- lowercase svn_option if it is a known hash source, otherwise the svn_option
- as an int
+ lowercase svn_option if it is a known hash source, otherwise the
+ svn_option as an int
Raises:
- ValueError: Invalid svn option provided.
+ ValueError: Invalid svn option provided.
"""
if svn_option.lower() in KNOWN_HASH_SOURCES:
@@ -307,15 +307,17 @@ def IsSvnOption(svn_option):
raise ValueError("Invalid LLVM git hash option provided: %s" % svn_option)
-def GetLLVMHashAndVersionFromSVNOption(svn_option):
+def GetLLVMHashAndVersionFromSVNOption(
+ svn_option: Union[int, str]
+) -> Tuple[str, int]:
"""Gets the LLVM hash and LLVM version based off of the svn option.
Args:
- svn_option: A valid svn option obtained from the command line.
- Ex. 'google3', 'tot', or <svn_version> such as 365123.
+ svn_option: A valid svn option obtained from the command line.
+ Ex. 'google3', 'tot', or <svn_version> such as 365123.
Returns:
- A tuple that is the LLVM git hash and LLVM version.
+ A tuple that is the LLVM git hash and LLVM version.
"""
new_llvm_hash = LLVMHash()
@@ -336,12 +338,12 @@ def GetLLVMHashAndVersionFromSVNOption(svn_option):
return git_hash, version
-class LLVMHash(object):
+class LLVMHash:
"""Provides methods to retrieve a LLVM hash."""
@staticmethod
@contextlib.contextmanager
- def CreateTempDirectory():
+ def CreateTempDirectory() -> Iterator:
temp_dir = tempfile.mkdtemp()
try:
@@ -350,32 +352,33 @@ class LLVMHash(object):
if os.path.isdir(temp_dir):
shutil.rmtree(temp_dir, ignore_errors=True)
- def CloneLLVMRepo(self, temp_dir):
+ def CloneLLVMRepo(self, temp_dir: str) -> None:
"""Clones the LLVM repo.
Args:
- temp_dir: The temporary directory to clone the repo to.
+ temp_dir: The temporary directory to clone the repo to.
Raises:
- ValueError: Failed to clone the LLVM repo.
+ ValueError: Failed to clone the LLVM repo.
"""
-
clone_cmd = ["git", "clone", _LLVM_GIT_URL, temp_dir]
-
- clone_cmd_obj = subprocess.Popen(clone_cmd, stderr=subprocess.PIPE)
- _, stderr = clone_cmd_obj.communicate()
-
+ clone_cmd_obj = subprocess.run(
+ clone_cmd, check=False, stderr=subprocess.PIPE
+ )
if clone_cmd_obj.returncode:
- raise ValueError("Failed to clone the LLVM repo: %s" % stderr)
+ raise ValueError(
+ "Failed to clone the LLVM repo; stderr: "
+ f"{repr(clone_cmd_obj.stderr)}"
+ )
- def GetLLVMHash(self, version):
+ def GetLLVMHash(self, version: int) -> str:
"""Retrieves the LLVM hash corresponding to the LLVM version passed in.
Args:
- version: The LLVM version to use as a delimiter.
+ version: The LLVM version to use as a delimiter.
Returns:
- The hash as a string that corresponds to the LLVM version.
+ The hash as a string that corresponds to the LLVM version.
"""
hash_value = GetGitHashFrom(
@@ -383,26 +386,26 @@ class LLVMHash(object):
)
return hash_value
- def GetGoogle3LLVMHash(self):
+ def GetGoogle3LLVMHash(self) -> str:
"""Retrieves the google3 LLVM hash."""
return self.GetLLVMHash(GetGoogle3LLVMVersion(stable=True))
- def GetGoogle3UnstableLLVMHash(self):
+ def GetGoogle3UnstableLLVMHash(self) -> str:
"""Retrieves the LLVM hash of google3's unstable compiler."""
return self.GetLLVMHash(GetGoogle3LLVMVersion(stable=False))
- def GetTopOfTrunkGitHash(self):
+ def GetTopOfTrunkGitHash(self) -> str:
"""Gets the latest git hash from top of trunk of LLVM."""
path_to_main_branch = "refs/heads/main"
- llvm_tot_git_hash = check_output(
+ llvm_tot_git_hash = subprocess_helpers.check_output(
["git", "ls-remote", _LLVM_GIT_URL, path_to_main_branch]
)
return llvm_tot_git_hash.rstrip().split()[0]
-def main():
+def main() -> None:
"""Prints the git hash of LLVM.
Parses the command line for the optional command line
diff --git a/llvm_tools/get_llvm_hash_unittest.py b/llvm_tools/get_llvm_hash_unittest.py
index 17a094b4..66685ca1 100755
--- a/llvm_tools/get_llvm_hash_unittest.py
+++ b/llvm_tools/get_llvm_hash_unittest.py
@@ -1,61 +1,54 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unit tests for retrieving the LLVM hash."""
-
+import contextlib
import subprocess
import unittest
-import unittest.mock as mock
+from unittest import mock
import get_llvm_hash
-from get_llvm_hash import LLVMHash
+import subprocess_helpers
# We grab protected stuff from get_llvm_hash. That's OK.
# pylint: disable=protected-access
-def MakeMockPopen(return_code):
- def MockPopen(*_args, **_kwargs):
- result = mock.MagicMock()
- result.returncode = return_code
-
- communicate_result = result.communicate.return_value
- # Communicate returns stdout, stderr.
- communicate_result.__iter__.return_value = (None, "some stderr")
- return result
-
- return MockPopen
+def mock_run_results(returncode: int, stderr: bytes) -> mock.MagicMock:
+ m = mock.MagicMock()
+ m.returncode = returncode
+ m.stderr = stderr
+ return m
class TestGetLLVMHash(unittest.TestCase):
"""The LLVMHash test class."""
- @mock.patch.object(subprocess, "Popen")
- def testCloneRepoSucceedsWhenGitSucceeds(self, popen_mock):
- popen_mock.side_effect = MakeMockPopen(return_code=0)
- llvm_hash = LLVMHash()
+ @mock.patch.object(subprocess, "run")
+ def testCloneRepoSucceedsWhenGitSucceeds(self, run_mock):
+ run_mock.return_value = mock_run_results(returncode=0, stderr=b"")
+ llvm_hash = get_llvm_hash.LLVMHash()
into_tempdir = "/tmp/tmpTest"
llvm_hash.CloneLLVMRepo(into_tempdir)
- popen_mock.assert_called_with(
+ run_mock.assert_called_with(
["git", "clone", get_llvm_hash._LLVM_GIT_URL, into_tempdir],
+ check=False,
stderr=subprocess.PIPE,
)
- @mock.patch.object(subprocess, "Popen")
- def testCloneRepoFailsWhenGitFails(self, popen_mock):
- popen_mock.side_effect = MakeMockPopen(return_code=1)
-
- with self.assertRaises(ValueError) as err:
- LLVMHash().CloneLLVMRepo("/tmp/tmp1")
+ @mock.patch.object(subprocess, "run")
+ def testCloneRepoFailsWhenGitFails(self, run_mock):
+ run_mock.return_value = mock_run_results(
+ returncode=1, stderr=b"some stderr"
+ )
- self.assertIn("Failed to clone", str(err.exception.args))
- self.assertIn("some stderr", str(err.exception.args))
+ with self.assertRaisesRegex(ValueError, "Failed to clone.*some stderr"):
+ get_llvm_hash.LLVMHash().CloneLLVMRepo("/tmp/tmp1")
@mock.patch.object(get_llvm_hash, "GetGitHashFrom")
def testGetGitHashWorks(self, mock_get_git_hash):
@@ -67,17 +60,19 @@ class TestGetLLVMHash(unittest.TestCase):
mock_get_git_hash.assert_called_once()
- @mock.patch.object(LLVMHash, "GetLLVMHash")
+ @mock.patch.object(get_llvm_hash.LLVMHash, "GetLLVMHash")
@mock.patch.object(get_llvm_hash, "GetGoogle3LLVMVersion")
def testReturnGoogle3LLVMHash(
self, mock_google3_llvm_version, mock_get_llvm_hash
):
mock_get_llvm_hash.return_value = "a13testhash3"
mock_google3_llvm_version.return_value = 1000
- self.assertEqual(LLVMHash().GetGoogle3LLVMHash(), "a13testhash3")
+ self.assertEqual(
+ get_llvm_hash.LLVMHash().GetGoogle3LLVMHash(), "a13testhash3"
+ )
mock_get_llvm_hash.assert_called_once_with(1000)
- @mock.patch.object(LLVMHash, "GetLLVMHash")
+ @mock.patch.object(get_llvm_hash.LLVMHash, "GetLLVMHash")
@mock.patch.object(get_llvm_hash, "GetGoogle3LLVMVersion")
def testReturnGoogle3UnstableLLVMHash(
self, mock_google3_llvm_version, mock_get_llvm_hash
@@ -85,20 +80,23 @@ class TestGetLLVMHash(unittest.TestCase):
mock_get_llvm_hash.return_value = "a13testhash3"
mock_google3_llvm_version.return_value = 1000
self.assertEqual(
- LLVMHash().GetGoogle3UnstableLLVMHash(), "a13testhash3"
+ get_llvm_hash.LLVMHash().GetGoogle3UnstableLLVMHash(),
+ "a13testhash3",
)
mock_get_llvm_hash.assert_called_once_with(1000)
@mock.patch.object(subprocess, "check_output")
def testSuccessfullyGetGitHashFromToTOfLLVM(self, mock_check_output):
mock_check_output.return_value = "a123testhash1 path/to/main\n"
- self.assertEqual(LLVMHash().GetTopOfTrunkGitHash(), "a123testhash1")
+ self.assertEqual(
+ get_llvm_hash.LLVMHash().GetTopOfTrunkGitHash(), "a123testhash1"
+ )
mock_check_output.assert_called_once()
@mock.patch.object(subprocess, "Popen")
def testCheckoutBranch(self, mock_popen):
- mock_popen.return_value = mock.MagicMock(
- communicate=lambda: (None, None), returncode=0
+ mock_popen.return_value = contextlib.nullcontext(
+ mock.MagicMock(communicate=lambda: (None, None), returncode=0)
)
get_llvm_hash.CheckoutBranch("fake/src_dir", "fake_branch")
self.assertEqual(
@@ -128,7 +126,7 @@ class TestGetLLVMHash(unittest.TestCase):
@mock.patch.object(get_llvm_hash, "GetAndUpdateLLVMProjectInLLVMTools")
@mock.patch.object(get_llvm_hash, "ParseLLVMMajorVersion")
- @mock.patch.object(get_llvm_hash, "CheckCommand")
+ @mock.patch.object(subprocess_helpers, "CheckCommand")
@mock.patch.object(get_llvm_hash, "CheckoutBranch")
@mock.patch(
"get_llvm_hash.open",
diff --git a/llvm_tools/get_patch.py b/llvm_tools/get_patch.py
new file mode 100755
index 00000000..3d89fbc5
--- /dev/null
+++ b/llvm_tools/get_patch.py
@@ -0,0 +1,722 @@
+#!/usr/bin/env python3
+# Copyright 2024 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Get patches from a patch source, and integrate them into ChromiumOS.
+
+Example Usage:
+ # Apply a Pull request.
+ $ get_patch.py -s HEAD p:74791
+ # Apply several patches.
+ $ get_patch.py -s 82e851a407c5 p:74791 47413bb27
+ # Use another llvm-project dir.
+ $ get_patch.py -s HEAD -l ~/llvm-project 47413bb27
+"""
+
+import argparse
+import dataclasses
+import json
+import logging
+from pathlib import Path
+import random
+import re
+import subprocess
+import tempfile
+import textwrap
+from typing import Any, Dict, Iterable, List, Optional, Set, Tuple, Union
+from urllib import request
+
+import atomic_write_file
+import git_llvm_rev
+import patch_utils
+
+
+CHROMIUMOS_OVERLAY_PATH = Path("src/third_party/chromiumos-overlay")
+LLVM_PKG_PATH = CHROMIUMOS_OVERLAY_PATH / "sys-devel/llvm"
+COMPILER_RT_PKG_PATH = CHROMIUMOS_OVERLAY_PATH / "sys-libs/compiler-rt"
+LIBCXX_PKG_PATH = CHROMIUMOS_OVERLAY_PATH / "sys-libs/libcxx"
+LIBUNWIND_PKG_PATH = CHROMIUMOS_OVERLAY_PATH / "sys-libs/llvm-libunwind"
+SCUDO_PKG_PATH = CHROMIUMOS_OVERLAY_PATH / "sys-libs/scudo"
+LLDB_PKG_PATH = CHROMIUMOS_OVERLAY_PATH / "dev-util/lldb-server"
+
+LLVM_PROJECT_PATH = Path("src/third_party/llvm-project")
+PATCH_METADATA_FILENAME = "PATCHES.json"
+
+
+class CherrypickError(ValueError):
+ """ValueError for a cherry-pick has been seen before."""
+
+
+class CherrypickVersionError(ValueError):
+ """ValueError that highlights the cherry-pick is before the start_ref."""
+
+
+@dataclasses.dataclass
+class LLVMGitRef:
+ """Represents an LLVM git ref."""
+
+ git_ref: str
+ _rev: Optional[git_llvm_rev.Rev] = None # Used for caching
+
+ @classmethod
+ def from_rev(cls, llvm_dir: Path, rev: git_llvm_rev.Rev) -> "LLVMGitRef":
+ return cls(
+ git_llvm_rev.translate_rev_to_sha(
+ git_llvm_rev.LLVMConfig("origin", llvm_dir), rev
+ ),
+ _rev=rev,
+ )
+
+ def to_rev(self, llvm_dir: Path) -> git_llvm_rev.Rev:
+ if self._rev:
+ return self._rev
+ self._rev = git_llvm_rev.translate_sha_to_rev(
+ git_llvm_rev.LLVMConfig("origin", llvm_dir),
+ self.git_ref,
+ )
+ return self._rev
+
+
+@dataclasses.dataclass(frozen=True)
+class LLVMPullRequest:
+ """Represents an upstream GitHub Pull Request number."""
+
+ number: int
+
+
+@dataclasses.dataclass
+class PatchContext:
+ """Represents the state of the chromiumos source during patching."""
+
+ llvm_project_dir: Path
+ chromiumos_root: Path
+ start_ref: LLVMGitRef
+ platforms: Iterable[str]
+ dry_run: bool = False
+
+ def apply_patches(
+ self, patch_source: Union[LLVMGitRef, LLVMPullRequest]
+ ) -> None:
+ """Create .patch files and add them to PATCHES.json.
+
+ Post:
+ Unless self.dry_run is True, writes the patch contents to
+ the respective <pkg>/files/ workdir for each applicable
+ patch, and the JSON files are updated with the new entries.
+
+ Raises:
+ TypeError: If the patch_source is not a
+ LLVMGitRef or LLVMPullRequest.
+ """
+ new_patch_entries = self.make_patches(patch_source)
+ self.apply_entries_to_json(new_patch_entries)
+
+ def apply_entries_to_json(
+ self,
+ new_patch_entries: Iterable[patch_utils.PatchEntry],
+ ) -> None:
+ """Add some PatchEntries to the appropriate PATCHES.json."""
+ workdir_mappings: Dict[Path, List[patch_utils.PatchEntry]] = {}
+ for pe in new_patch_entries:
+ workdir_mappings[pe.workdir] = workdir_mappings.get(
+ pe.workdir, []
+ ) + [pe]
+ for workdir, pes in workdir_mappings.items():
+ patches_json_file = workdir / PATCH_METADATA_FILENAME
+ with patches_json_file.open(encoding="utf-8") as f:
+ orig_contents = f.read()
+ old_patch_entries = patch_utils.json_str_to_patch_entries(
+ workdir, orig_contents
+ )
+ indent_len = patch_utils.predict_indent(orig_contents.splitlines())
+ if not self.dry_run:
+ with atomic_write_file.atomic_write(
+ patches_json_file, encoding="utf-8"
+ ) as f:
+ json.dump(
+ [pe.to_dict() for pe in old_patch_entries + pes],
+ f,
+ indent=indent_len,
+ )
+ f.write("\n")
+
+ def make_patches(
+ self, patch_source: Union[LLVMGitRef, LLVMPullRequest]
+ ) -> List[patch_utils.PatchEntry]:
+ """Create PatchEntries for a given LLVM change and returns them.
+
+ Returns:
+ A list of PatchEntries representing the patches for each
+ package for the given patch_source.
+
+ Post:
+ Unless self.dry_run is True, writes the patch contents to
+ the respective <pkg>/files/ workdir for each applicable
+ patch.
+
+ Raises:
+ TypeError: If the patch_source is not a
+ LLVMGitRef or LLVMPullRequest.
+ """
+
+ # This is just a dispatch method to the actual methods.
+ if isinstance(patch_source, LLVMGitRef):
+ return self._make_patches_from_git_ref(patch_source)
+ if isinstance(patch_source, LLVMPullRequest):
+ return self._make_patches_from_pr(patch_source)
+ raise TypeError(
+ f"patch_source was invalid type {type(patch_source).__name__}"
+ )
+
+ def _make_patches_from_git_ref(
+ self,
+ patch_source: LLVMGitRef,
+ ) -> List[patch_utils.PatchEntry]:
+ packages = get_changed_packages(
+ self.llvm_project_dir, patch_source.git_ref
+ )
+ new_patch_entries: List[patch_utils.PatchEntry] = []
+ for workdir in self._workdirs_for_packages(packages):
+ rel_patch_path = f"cherry/{patch_source.git_ref}.patch"
+ if (workdir / "cherry").is_dir():
+ rel_patch_path = f"cherry/{patch_source.git_ref}.patch"
+ else:
+ # Some packages don't have a cherry directory.
+ rel_patch_path = f"{patch_source.git_ref}.patch"
+ if not self._is_valid_patch_range(self.start_ref, patch_source):
+ raise CherrypickVersionError(
+ f"'from' ref {self.start_ref} is later or"
+ f" same as than 'until' ref {patch_source}"
+ )
+ pe = patch_utils.PatchEntry(
+ workdir=workdir,
+ metadata={
+ "title": get_commit_subj(
+ self.llvm_project_dir, patch_source.git_ref
+ ),
+ "info": [],
+ },
+ platforms=list(self.platforms),
+ rel_patch_path=rel_patch_path,
+ version_range={
+ "from": self.start_ref.to_rev(self.llvm_project_dir).number,
+ "until": patch_source.to_rev(self.llvm_project_dir).number,
+ },
+ )
+ # Before we actually do any modifications, check if the patch is
+ # already applied.
+ if self.is_patch_applied(pe):
+ raise CherrypickError(
+ f"Patch at {pe.rel_patch_path}"
+ " already exists in PATCHES.json"
+ )
+ contents = git_format_patch(
+ self.llvm_project_dir,
+ patch_source.git_ref,
+ )
+ if not self.dry_run:
+ _write_patch(pe.title(), contents, pe.patch_path())
+ new_patch_entries.append(pe)
+ return new_patch_entries
+
+ def _make_patches_from_pr(
+ self, patch_source: LLVMPullRequest
+ ) -> List[patch_utils.PatchEntry]:
+ json_response = get_llvm_github_pull(patch_source.number)
+ github_ctx = GitHubPRContext(json_response, self.llvm_project_dir)
+ rel_patch_path = f"{github_ctx.full_title_cleaned}.patch"
+ contents, packages = github_ctx.git_squash_chain_patch()
+ new_patch_entries = []
+ for workdir in self._workdirs_for_packages(packages):
+ pe = patch_utils.PatchEntry(
+ workdir=workdir,
+ metadata={
+ "title": github_ctx.full_title,
+ "info": [],
+ },
+ rel_patch_path=rel_patch_path,
+ platforms=list(self.platforms),
+ version_range={
+ "from": self.start_ref.to_rev(self.llvm_project_dir).number,
+ "until": None,
+ },
+ )
+ # Before we actually do any modifications, check if the patch is
+ # already applied.
+ if self.is_patch_applied(pe):
+ raise CherrypickError(
+ f"Patch at {pe.rel_patch_path}"
+ " already exists in PATCHES.json"
+ )
+ if not self.dry_run:
+ _write_patch(pe.title(), contents, pe.patch_path())
+ new_patch_entries.append(pe)
+ return new_patch_entries
+
+ def _workdirs_for_packages(self, packages: Iterable[Path]) -> List[Path]:
+ return [self.chromiumos_root / pkg / "files" for pkg in packages]
+
+ def is_patch_applied(self, to_check: patch_utils.PatchEntry) -> bool:
+ """Return True if the patch is applied in PATCHES.json."""
+ patches_json_file = to_check.workdir / PATCH_METADATA_FILENAME
+ with patches_json_file.open(encoding="utf-8") as f:
+ patch_entries = patch_utils.json_to_patch_entries(
+ to_check.workdir, f
+ )
+ return any(
+ p.rel_patch_path == to_check.rel_patch_path for p in patch_entries
+ )
+
+ def _is_valid_patch_range(
+ self, from_ref: LLVMGitRef, to_ref: LLVMGitRef
+ ) -> bool:
+ return (
+ from_ref.to_rev(self.llvm_project_dir).number
+ < to_ref.to_rev(self.llvm_project_dir).number
+ )
+
+
+def get_commit_subj(git_root_dir: Path, ref: str) -> str:
+ """Return a given commit's subject."""
+ logging.debug("Getting commit subject for %s", ref)
+ subj = subprocess.run(
+ ["git", "show", "-s", "--format=%s", ref],
+ cwd=git_root_dir,
+ encoding="utf-8",
+ stdout=subprocess.PIPE,
+ check=True,
+ ).stdout.strip()
+ logging.debug(" -> %s", subj)
+ return subj
+
+
+def git_format_patch(git_root_dir: Path, ref: str) -> str:
+ """Format a patch for a single git ref.
+
+ Args:
+ git_root_dir: Root directory for a given local git repository.
+ ref: Git ref to make a patch for.
+
+ Returns:
+ The patch file contents.
+ """
+ logging.debug("Formatting patch for %s^..%s", ref, ref)
+ proc = subprocess.run(
+ ["git", "format-patch", "--stdout", f"{ref}^..{ref}"],
+ cwd=git_root_dir,
+ encoding="utf-8",
+ stdout=subprocess.PIPE,
+ check=True,
+ )
+ contents = proc.stdout.strip()
+ if not contents:
+ raise ValueError(f"No git diff between {ref}^..{ref}")
+ logging.debug("Patch diff is %d lines long", contents.count("\n"))
+ return contents
+
+
+def get_llvm_github_pull(pull_number: int) -> Dict[str, Any]:
+ """Get information about an LLVM pull request.
+
+ Returns:
+ A dictionary containing the JSON response from GitHub.
+
+ Raises:
+ RuntimeError when the network response is not OK.
+ """
+
+ pull_url = (
+ f"https://api.github.com/repos/llvm/llvm-project/pulls/{pull_number}"
+ )
+ # TODO(ajordanr): If we are ever allowed to use the 'requests' library
+ # we should move to that instead of urllib.
+ req = request.Request(
+ url=pull_url,
+ headers={
+ "X-GitHub-Api-Version": "2022-11-28",
+ "Accept": "application/vnd.github+json",
+ },
+ )
+ with request.urlopen(req) as f:
+ if f.status >= 400:
+ raise RuntimeError(
+ f"GitHub response was not OK: {f.status} {f.reason}"
+ )
+ response = f.read().decode("utf-8")
+ return json.loads(response)
+
+
+class GitHubPRContext:
+ """Metadata and pathing context for a GitHub pull request checkout."""
+
+ def __init__(
+ self,
+ response: Dict[str, Any],
+ llvm_project_dir: Path,
+ ) -> None:
+ """Create a GitHubPRContext from a GitHub pulls api call.
+
+ Args:
+ response: A dictionary formed from the JSON sent by
+ the github pulls API endpoint.
+ llvm_project_dir: Path to llvm-project git directory.
+ """
+ try:
+ self.clone_url = response["head"]["repo"]["clone_url"]
+ self._title = response["title"]
+ self.body = response["body"]
+ self.base_ref = response["base"]["sha"]
+ self.head_ref = response["head"]["sha"]
+ self.llvm_project_dir = llvm_project_dir
+ self.number = int(response["number"])
+ self._fetched = False
+ except (ValueError, KeyError):
+ logging.error("Failed to parse GitHub response:\n%s", response)
+ raise
+
+ @property
+ def full_title(self) -> str:
+ return f"[PR{self.number}] {self._title}"
+
+ @property
+ def full_title_cleaned(self) -> str:
+ return re.sub(r"\W", "-", self.full_title)
+
+ def git_squash_chain_patch(self) -> Tuple[str, Set[Path]]:
+ """Replicate a squashed merge commit as a patch file.
+
+ Args:
+ git_root_dir: Root directory for a given local git repository
+ which contains the base_ref.
+ output: File path to write the patch to.
+
+ Returns:
+ The patch file contents.
+ """
+ self._fetch()
+ idx = random.randint(0, 2**32)
+ tmpbranch_name = f"squash-branch-{idx}"
+
+ with tempfile.TemporaryDirectory() as dir_str:
+ worktree_parent_dir = Path(dir_str)
+ commit_message_file = worktree_parent_dir / "commit_message"
+ # Need this separate from the commit message, otherwise the
+ # dir will be non-empty.
+ worktree_dir = worktree_parent_dir / "worktree"
+ with commit_message_file.open("w", encoding="utf-8") as f:
+ f.write(self.full_title)
+ f.write("\n\n")
+ f.write(
+ "\n".join(
+ textwrap.wrap(
+ self.body, width=72, replace_whitespace=False
+ )
+ )
+ )
+ f.write("\n")
+
+ logging.debug("Base ref: %s", self.base_ref)
+ logging.debug("Head ref: %s", self.head_ref)
+ logging.debug(
+ "Creating worktree at '%s' with branch '%s'",
+ worktree_dir,
+ tmpbranch_name,
+ )
+ self._run(
+ [
+ "git",
+ "worktree",
+ "add",
+ "-b",
+ tmpbranch_name,
+ worktree_dir,
+ self.base_ref,
+ ],
+ self.llvm_project_dir,
+ )
+ try:
+ self._run(
+ ["git", "merge", "--squash", self.head_ref], worktree_dir
+ )
+ self._run(
+ [
+ "git",
+ "commit",
+ "-a",
+ "-F",
+ commit_message_file,
+ ],
+ worktree_dir,
+ )
+ changed_packages = get_changed_packages(
+ worktree_dir, (self.base_ref, "HEAD")
+ )
+ patch_contents = git_format_patch(worktree_dir, "HEAD")
+ finally:
+ logging.debug(
+ "Cleaning up worktree and deleting branch %s",
+ tmpbranch_name,
+ )
+ self._run(
+ ["git", "worktree", "remove", worktree_dir],
+ self.llvm_project_dir,
+ )
+ self._run(
+ ["git", "branch", "-D", tmpbranch_name],
+ self.llvm_project_dir,
+ )
+ return (patch_contents, changed_packages)
+
+ def _fetch(self) -> None:
+ if not self._fetched:
+ logging.debug(
+ "Fetching from %s and setting FETCH_HEAD to %s",
+ self.clone_url,
+ self.head_ref,
+ )
+ self._run(
+ ["git", "fetch", self.clone_url, self.head_ref],
+ cwd=self.llvm_project_dir,
+ )
+ self._fetched = True
+
+ @staticmethod
+ def _run(
+ cmd: List[Union[str, Path]],
+ cwd: Path,
+ stdin: int = subprocess.DEVNULL,
+ ) -> subprocess.CompletedProcess:
+ """Helper for subprocess.run."""
+ return subprocess.run(
+ cmd,
+ cwd=cwd,
+ stdin=stdin,
+ stdout=subprocess.PIPE,
+ encoding="utf-8",
+ check=True,
+ )
+
+
+def get_changed_packages(
+ llvm_project_dir: Path, ref: Union[str, Tuple[str, str]]
+) -> Set[Path]:
+ """Returns package paths which changed over a given ref.
+
+ Args:
+ llvm_project_dir: Path to llvm-project
+ ref: Git ref to check diff of. If set to a tuple, compares the diff
+ between the first and second ref.
+
+ Returns:
+ A set of package paths which were changed.
+ """
+ if isinstance(ref, tuple):
+ ref_from, ref_to = ref
+ elif isinstance(ref, str):
+ ref_from = ref + "^"
+ ref_to = ref
+ else:
+ raise TypeError(f"ref was {type(ref)}; need a tuple or a string")
+
+ logging.debug("Getting git diff between %s..%s", ref_from, ref_to)
+ proc = subprocess.run(
+ ["git", "diff", "--name-only", f"{ref_from}..{ref_to}"],
+ check=True,
+ encoding="utf-8",
+ stdout=subprocess.PIPE,
+ cwd=llvm_project_dir,
+ )
+ changed_paths = proc.stdout.splitlines()
+ logging.debug("Found %d changed files", len(changed_paths))
+ # Some LLVM projects are built by LLVM ebuild on x86, so always apply the
+ # patch to LLVM ebuild
+ packages = {LLVM_PKG_PATH}
+ for changed_path in changed_paths:
+ if changed_path.startswith("compiler-rt"):
+ packages.add(COMPILER_RT_PKG_PATH)
+ if "scudo" in changed_path:
+ packages.add(SCUDO_PKG_PATH)
+ elif changed_path.startswith("libunwind"):
+ packages.add(LIBUNWIND_PKG_PATH)
+ elif changed_path.startswith("libcxx") or changed_path.startswith(
+ "libcxxabi"
+ ):
+ packages.add(LIBCXX_PKG_PATH)
+ elif changed_path.startswith("lldb"):
+ packages.add(LLDB_PKG_PATH)
+ return packages
+
+
+def _has_repo_child(path: Path) -> bool:
+ """Check if a given directory has a repo child.
+
+ Useful for checking if a directory has a chromiumos source tree.
+ """
+ child_maybe = path / ".repo"
+ return path.is_dir() and child_maybe.is_dir()
+
+
+def _autodetect_chromiumos_root(
+ parent: Optional[Path] = None,
+) -> Optional[Path]:
+ """Find the root of the chromiumos source tree from the current workdir.
+
+ Returns:
+ The root directory of the current chromiumos source tree.
+ If the current working directory is not within a chromiumos source
+ tree, then this returns None.
+ """
+ if parent is None:
+ parent = Path.cwd()
+ if parent.resolve() == Path.root:
+ return None
+ if _has_repo_child(parent):
+ return parent
+ return _autodetect_chromiumos_root(parent.parent)
+
+
+def _write_patch(title: str, contents: str, path: Path) -> None:
+ """Actually write the patch contents to a file."""
+ # This is mostly separated for mocking.
+ logging.info("Writing patch '%s' to '%s'", title, path)
+ path.write_text(contents, encoding="utf-8")
+
+
+def validate_patch_args(
+ positional_args: List[str],
+) -> List[Union[LLVMGitRef, LLVMPullRequest]]:
+ """Checks that each ref_or_pr_num is in a valid format."""
+ patch_sources = []
+ for arg in positional_args:
+ patch_source: Union[LLVMGitRef, LLVMPullRequest]
+ if arg.startswith("p:"):
+ try:
+ pull_request_num = int(arg.lstrip("p:"))
+ except ValueError as e:
+ raise ValueError(
+ f"GitHub Pull Request '{arg}' was not in the format of"
+ f" 'p:NNNN': {e}"
+ )
+ logging.info("Patching remote GitHub PR '%s'", pull_request_num)
+ patch_source = LLVMPullRequest(pull_request_num)
+ else:
+ logging.info("Patching local ref '%s'", arg)
+ patch_source = LLVMGitRef(arg)
+ patch_sources.append(patch_source)
+ return patch_sources
+
+
+def parse_args() -> argparse.Namespace:
+ """Parse CLI arguments for this script."""
+
+ parser = argparse.ArgumentParser(
+ "get_patch",
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+ parser.add_argument(
+ "-c",
+ "--chromiumos-root",
+ help="""Path to the chromiumos source tree root.
+ Tries to autodetect if not passed.
+ """,
+ )
+ parser.add_argument(
+ "-l",
+ "--llvm",
+ help="""Path to the llvm dir.
+ Tries to autodetect from chromiumos root if not passed.
+ """,
+ )
+ parser.add_argument(
+ "-s",
+ "--start-ref",
+ default="HEAD",
+ help="""The starting ref for which to apply patches.
+ """,
+ )
+ parser.add_argument(
+ "-p",
+ "--platform",
+ action="append",
+ help="""Apply this patch to the give platform. Common options include
+ 'chromiumos' and 'android'. Can be specified multiple times to
+ apply to multiple platforms. If not passed, platform is set to
+ 'chromiumos'.
+ """,
+ )
+ parser.add_argument(
+ "--dry-run",
+ action="store_true",
+ help="Run normally, but don't make any changes. Read-only mode.",
+ )
+ parser.add_argument(
+ "-v",
+ "--verbose",
+ action="store_true",
+ help="Enable verbose logging.",
+ )
+ parser.add_argument(
+ "ref_or_pr_num",
+ nargs="+",
+ help="""Git ref or GitHub PR number to make patches.
+ To patch a GitHub PR, use the syntax p:NNNN (e.g. 'p:123456').
+ """,
+ type=str,
+ )
+ args = parser.parse_args()
+
+ logging.basicConfig(
+ format=">> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: "
+ "%(message)s",
+ level=logging.DEBUG if args.verbose else logging.INFO,
+ )
+
+ args.patch_sources = validate_patch_args(args.ref_or_pr_num)
+ if args.chromiumos_root:
+ if not _has_repo_child(args.chromiumos_root):
+ parser.error("chromiumos root directly passed but has no .repo")
+ logging.debug("chromiumos root directly passed; found and verified")
+ elif tmp := _autodetect_chromiumos_root():
+ logging.debug("chromiumos root autodetected; found and verified")
+ args.chromiumos_root = tmp
+ else:
+ parser.error(
+ "Could not autodetect chromiumos root. Use '-c' to pass the "
+ "chromiumos root path directly."
+ )
+
+ if not args.llvm:
+ if (args.chromiumos_root / LLVM_PROJECT_PATH).is_dir():
+ args.llvm = args.chromiumos_root / LLVM_PROJECT_PATH
+ else:
+ parser.error(
+ "Could not autodetect llvm-project dir. Use '-l' to pass the "
+ "llvm-project directly"
+ )
+ return args
+
+
+def main() -> None:
+ """Entry point for the program."""
+
+ args = parse_args()
+
+ # For the vast majority of cases, we'll only want to set platform to
+ # ["chromiumos"], so let's make that the default.
+ platforms: List[str] = args.platform if args.platform else ["chromiumos"]
+
+ ctx = PatchContext(
+ chromiumos_root=args.chromiumos_root,
+ llvm_project_dir=args.llvm,
+ start_ref=LLVMGitRef(args.start_ref),
+ platforms=platforms,
+ dry_run=args.dry_run,
+ )
+ for patch_source in args.patch_sources:
+ ctx.apply_patches(patch_source)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/llvm_tools/get_patch_unittest.py b/llvm_tools/get_patch_unittest.py
new file mode 100755
index 00000000..8ccdb69b
--- /dev/null
+++ b/llvm_tools/get_patch_unittest.py
@@ -0,0 +1,233 @@
+#!/usr/bin/env python3
+# Copyright 2024 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Tests for get_patch."""
+
+import json
+from pathlib import Path
+import tempfile
+from typing import Any, Dict, Generator, List, Set
+import unittest
+from unittest import mock
+
+import get_patch
+import git_llvm_rev
+
+
+COMMIT_FIXTURES: List[Dict[str, Any]] = [
+ {"subject": "A commit subject", "sha": "abcdef1234567890", "rev": 5},
+ {"subject": "Another commit subject", "sha": "feed9999", "rev": 9},
+]
+
+JSON_FIXTURE: List[Dict[str, Any]] = [
+ {
+ "metadata": {"title": "An existing patch"},
+ "platforms": ["another platform"],
+ "rel_patch_path": "cherry/nowhere.patch",
+ "version_range": {"from": 1, "until": 256},
+ },
+]
+
+
+def _mock_get_commit_subj(_, sha: str) -> str:
+ gen: Generator[Dict[str, Any], None, None] = (
+ fixture for fixture in COMMIT_FIXTURES if fixture["sha"] == sha
+ )
+ return next(gen)["subject"]
+
+
+def _mock_to_rev(sha: get_patch.LLVMGitRef, _) -> git_llvm_rev.Rev:
+ gen: Generator[Dict[str, Any], None, None] = (
+ fixture for fixture in COMMIT_FIXTURES if fixture["sha"] == sha.git_ref
+ )
+ return git_llvm_rev.Rev("main", next(gen)["rev"])
+
+
+def _mock_from_rev(_, rev: git_llvm_rev.Rev) -> get_patch.LLVMGitRef:
+ gen: Generator[Dict[str, Any], None, None] = (
+ fixture for fixture in COMMIT_FIXTURES if fixture["rev"] == rev.number
+ )
+ return get_patch.LLVMGitRef(next(gen)["sha"])
+
+
+def _mock_git_format_patch(*_) -> str:
+ return "[category] This is a fake commit fixture"
+
+
+def _mock_write_patch(*_) -> None:
+ return
+
+
+def _mock_get_changed_packages(*_) -> Set[Path]:
+ return {get_patch.LLVM_PKG_PATH}
+
+
+class TestGetPatch(unittest.TestCase):
+ """Test case harness for get_patch."""
+
+ def setUp(self) -> None:
+ """Set up the mocks and directory structure."""
+
+ self.module_patcher = mock.patch.multiple(
+ "get_patch",
+ get_commit_subj=_mock_get_commit_subj,
+ git_format_patch=_mock_git_format_patch,
+ get_changed_packages=_mock_get_changed_packages,
+ _write_patch=_mock_write_patch,
+ )
+ self.module_patcher.start()
+ self.addCleanup(self.module_patcher.stop)
+ self.llvm_gitsha_patcher = mock.patch.multiple(
+ "get_patch.LLVMGitRef",
+ to_rev=_mock_to_rev,
+ from_rev=_mock_from_rev,
+ )
+ self.llvm_gitsha_patcher.start()
+ self.addCleanup(self.llvm_gitsha_patcher.stop)
+
+ self.llvm_project_dir = Path(tempfile.mkdtemp())
+ self.addCleanup(self.llvm_project_dir.rmdir)
+ self.chromiumos_root = Path(tempfile.mkdtemp())
+ self.addCleanup(self.chromiumos_root.rmdir)
+ self.workdir = self.chromiumos_root / get_patch.LLVM_PKG_PATH / "files"
+ self.workdir.mkdir(parents=True, exist_ok=True)
+
+ def _cleanup_workdir():
+ # We individually clean up these directories as a guarantee
+ # we aren't creating any extraneous files. We don't want to
+ # use shm.rmtree here because we don't want clean up any
+ # files unaccounted for.
+ workdir_recurse = self.workdir
+ while workdir_recurse not in (self.chromiumos_root, Path.root):
+ workdir_recurse.rmdir()
+ workdir_recurse = workdir_recurse.parent
+
+ self.addCleanup(_cleanup_workdir)
+
+ self.patches_json_file = (
+ self.workdir / get_patch.PATCH_METADATA_FILENAME
+ )
+ start_ref = get_patch.LLVMGitRef("abcdef1234567890")
+ self.ctx = get_patch.PatchContext(
+ self.llvm_project_dir,
+ self.chromiumos_root,
+ start_ref,
+ platforms=["some platform"],
+ )
+
+ def write_json_fixture(self) -> None:
+ with self.patches_json_file.open("w", encoding="utf-8") as f:
+ json.dump(JSON_FIXTURE, f)
+ f.write("\n")
+
+ def test_bad_cherrypick_version(self) -> None:
+ """Test that bad cherrypick versions raises."""
+ start_sha_fixture = COMMIT_FIXTURES[0]
+
+ def _try_make_patches():
+ # This fixture is the same as the start_sha.
+ self.ctx.make_patches(
+ get_patch.LLVMGitRef(start_sha_fixture["sha"])
+ )
+
+ self.assertRaises(get_patch.CherrypickVersionError, _try_make_patches)
+
+ def test_make_patches(self) -> None:
+ """Test we can make patch entries from a git commit."""
+
+ fixture = COMMIT_FIXTURES[1]
+ # We manually write and delete this file because it must have the name
+ # as specified by get_patch. tempfile cannot guarantee us this name.
+ self.write_json_fixture()
+ try:
+ entries = self.ctx.make_patches(
+ get_patch.LLVMGitRef(fixture["sha"])
+ )
+ self.assertEqual(len(entries), 1)
+ if entries[0].metadata:
+ self.assertEqual(
+ entries[0].metadata["title"], fixture["subject"]
+ )
+ else:
+ self.fail("metadata was None")
+ finally:
+ self.patches_json_file.unlink()
+
+ def test_apply_patch_to_json(self) -> None:
+ """Test we can apply patches to the JSON file."""
+
+ fixture = COMMIT_FIXTURES[1]
+ fixture_sha = fixture["sha"]
+ expected_json_entry = {
+ "metadata": {"title": fixture["subject"], "info": []},
+ "platforms": ["some platform"],
+ "rel_patch_path": f"cherry/{fixture_sha}.patch",
+ "version_range": {
+ "from": self.ctx.start_ref.to_rev(self.llvm_project_dir).number,
+ "until": fixture["rev"],
+ },
+ }
+ cherrydir = self.workdir / "cherry"
+ cherrydir.mkdir()
+ self._apply_patch_to_json_helper(fixture, expected_json_entry)
+ cherrydir.rmdir()
+
+ def test_apply_patch_to_json_no_cherry(self) -> None:
+ """Test we can apply patches to the JSON file, without a cherry dir."""
+
+ fixture = COMMIT_FIXTURES[1]
+ fixture_sha = fixture["sha"]
+ expected_json_entry = {
+ "metadata": {"title": fixture["subject"], "info": []},
+ "platforms": ["some platform"],
+ "rel_patch_path": f"{fixture_sha}.patch",
+ "version_range": {
+ "from": self.ctx.start_ref.to_rev(self.llvm_project_dir).number,
+ "until": fixture["rev"],
+ },
+ }
+ self._apply_patch_to_json_helper(fixture, expected_json_entry)
+
+ def _apply_patch_to_json_helper(self, fixture, expected_json_entry) -> None:
+ # We manually write and delete this file because it must have the name
+ # as specified by get_patch. tempfile cannot guarantee us this name.
+ self.write_json_fixture()
+ patch_source = get_patch.LLVMGitRef.from_rev(
+ self.llvm_project_dir,
+ git_llvm_rev.Rev("origin", fixture["rev"]),
+ )
+ try:
+ self.ctx.apply_patches(patch_source)
+ with self.patches_json_file.open(encoding="utf-8") as f:
+ edited = json.load(f)
+ self.assertEqual(edited, JSON_FIXTURE + [expected_json_entry])
+ finally:
+ self.patches_json_file.unlink()
+
+ def test_apply_patch_dry_run(self) -> None:
+ """Test dry running patches does nothing."""
+
+ fixture = COMMIT_FIXTURES[1]
+ old_dry_run = self.ctx.dry_run
+ self.ctx.dry_run = True
+ # We manually write and delete this file because it must have the name
+ # as specified by get_patch. tempfile cannot guarantee us this name.
+ self.write_json_fixture()
+ patch_source = get_patch.LLVMGitRef.from_rev(
+ self.llvm_project_dir,
+ git_llvm_rev.Rev("origin", fixture["rev"]),
+ )
+ try:
+ self.ctx.apply_patches(patch_source)
+ with self.patches_json_file.open(encoding="utf-8") as f:
+ maybe_edited = json.load(f)
+ self.assertEqual(maybe_edited, JSON_FIXTURE)
+ finally:
+ self.ctx.dry_run = old_dry_run
+ self.patches_json_file.unlink()
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/llvm_tools/get_upstream_patch.py b/llvm_tools/get_upstream_patch.py
index 415faaa7..52634cd9 100755
--- a/llvm_tools/get_upstream_patch.py
+++ b/llvm_tools/get_upstream_patch.py
@@ -1,5 +1,4 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2020 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -8,7 +7,7 @@
import argparse
import dataclasses
-from datetime import datetime
+import datetime
import json
import logging
import os
@@ -23,7 +22,6 @@ import get_llvm_hash
import git
import git_llvm_rev
import patch_utils
-import update_chromeos_llvm_hash
__DOC_EPILOGUE = """
@@ -48,7 +46,6 @@ class PatchApplicationError(ValueError):
def validate_patch_application(
llvm_dir: Path, svn_version: int, patches_json_fp: Path, patch_props
):
-
start_sha = get_llvm_hash.GetGitHashFrom(llvm_dir, svn_version)
subprocess.run(["git", "-C", llvm_dir, "checkout", start_sha], check=True)
@@ -80,33 +77,33 @@ def add_patch(
patches_dir: str,
relative_patches_dir: str,
start_version: git_llvm_rev.Rev,
- llvm_dir: str,
+ llvm_dir: t.Union[Path, str],
rev: t.Union[git_llvm_rev.Rev, str],
sha: str,
package: str,
- platforms: t.List[str],
+ platforms: t.Iterable[str],
):
"""Gets the start and end intervals in 'json_file'.
Args:
- patches_json_path: The absolute path to PATCHES.json.
- patches_dir: The aboslute path to the directory patches are in.
- relative_patches_dir: The relative path to PATCHES.json.
- start_version: The base LLVM revision this patch applies to.
- llvm_dir: The path to LLVM checkout.
- rev: An LLVM revision (git_llvm_rev.Rev) for a cherrypicking, or a
- differential revision (str) otherwise.
- sha: The LLVM git sha that corresponds to the patch. For differential
- revisions, the git sha from the local commit created by 'arc patch'
- is used.
- package: The LLVM project name this patch applies to.
- platforms: List of platforms this patch applies to.
+ patches_json_path: The absolute path to PATCHES.json.
+ patches_dir: The aboslute path to the directory patches are in.
+ relative_patches_dir: The relative path to PATCHES.json.
+ start_version: The base LLVM revision this patch applies to.
+ llvm_dir: The path to LLVM checkout.
+ rev: An LLVM revision (git_llvm_rev.Rev) for a cherrypicking, or a
+ differential revision (str) otherwise.
+ sha: The LLVM git sha that corresponds to the patch. For differential
+ revisions, the git sha from the local commit created by 'arc patch'
+ is used.
+ package: The LLVM project name this patch applies to.
+ platforms: List of platforms this patch applies to.
Raises:
- CherrypickError: A ValueError that highlights the cherry-pick has been
- seen before.
- CherrypickRangeError: A ValueError that's raised when the given patch
- is from before the start_sha.
+ CherrypickError: A ValueError that highlights the cherry-pick has been
+ seen before.
+ CherrypickRangeError: A ValueError that's raised when the given patch
+ is from before the start_sha.
"""
is_cherrypick = isinstance(rev, git_llvm_rev.Rev)
@@ -146,9 +143,9 @@ def add_patch(
with open(os.path.join(patches_dir, file_name), "wb") as f:
cmd = ["git", "show", sha]
# Only apply the part of the patch that belongs to this package, expect
- # LLVM. This is because some packages are built with LLVM ebuild on X86 but
- # not on the other architectures. e.g. compiler-rt. Therefore always apply
- # the entire patch to LLVM ebuild as a workaround.
+ # LLVM. This is because some packages are built with LLVM ebuild on X86
+ # but not on the other architectures. e.g. compiler-rt. Therefore
+ # always apply the entire patch to LLVM ebuild as a workaround.
if package != "llvm":
cmd.append(package_to_project(package))
subprocess.check_call(cmd, stdout=f, cwd=llvm_dir)
@@ -213,23 +210,24 @@ def parse_ebuild_for_assignment(ebuild_path: str, var_name: str) -> str:
if not orig_line.startswith(var_name_eq):
continue
- # We shouldn't see much variety here, so do the simplest thing possible.
+ # We shouldn't see much variety here, so do the simplest thing
+ # possible.
line = orig_line[len(var_name_eq) :]
# Remove comments
line = line.split("#")[0]
# Remove quotes
- line = shlex.split(line)
- if len(line) != 1:
+ parts = shlex.split(line)
+ if len(parts) != 1:
raise ValueError(
"Expected exactly one quoted value in %r" % orig_line
)
- return line[0].strip()
+ return parts[0].strip()
raise ValueError("No %s= line found in %r" % (var_name, ebuild))
# Resolves a git ref (or similar) to a LLVM SHA.
-def resolve_llvm_ref(llvm_dir: str, sha: str) -> str:
+def resolve_llvm_ref(llvm_dir: t.Union[Path, str], sha: str) -> str:
return subprocess.check_output(
["git", "rev-parse", sha],
encoding="utf-8",
@@ -252,7 +250,7 @@ def package_to_project(package: str) -> str:
# Get the LLVM projects change in the specifed sha
-def get_package_names(sha: str, llvm_dir: str) -> list:
+def get_package_names(sha: str, llvm_dir: t.Union[Path, str]) -> list:
paths = subprocess.check_output(
["git", "show", "--name-only", "--format=", sha],
cwd=llvm_dir,
@@ -266,8 +264,7 @@ def get_package_names(sha: str, llvm_dir: str) -> list:
package = project_to_package(path.split("/")[0])
if package in ("compiler-rt", "libcxx", "libcxxabi", "llvm-libunwind"):
packages.add(package)
- packages = list(sorted(packages))
- return packages
+ return list(sorted(packages))
def create_patch_for_packages(
@@ -276,8 +273,8 @@ def create_patch_for_packages(
start_rev: git_llvm_rev.Rev,
rev: t.Union[git_llvm_rev.Rev, str],
sha: str,
- llvm_dir: str,
- platforms: t.List[str],
+ llvm_dir: t.Union[Path, str],
+ platforms: t.Iterable[str],
):
"""Create a patch and add its metadata for each package"""
for package, symlink in zip(packages, symlinks):
@@ -300,20 +297,15 @@ def create_patch_for_packages(
def make_cl(
- symlinks_to_uprev: t.List[str],
llvm_symlink_dir: str,
branch: str,
commit_messages: t.List[str],
reviewers: t.Optional[t.List[str]],
cc: t.Optional[t.List[str]],
):
- symlinks_to_uprev = sorted(set(symlinks_to_uprev))
- for symlink in symlinks_to_uprev:
- update_chromeos_llvm_hash.UprevEbuildSymlink(symlink)
- subprocess.check_output(
- ["git", "add", "--all"], cwd=os.path.dirname(symlink)
- )
- git.UploadChanges(llvm_symlink_dir, branch, commit_messages, reviewers, cc)
+ subprocess.check_output(["git", "add", "--all"], cwd=llvm_symlink_dir)
+ git.CommitChanges(llvm_symlink_dir, commit_messages)
+ git.UploadChanges(llvm_symlink_dir, branch, reviewers, cc)
git.DeleteBranch(llvm_symlink_dir, branch)
@@ -338,9 +330,8 @@ def find_patches_and_make_cl(
skip_dependencies: bool,
reviewers: t.Optional[t.List[str]],
cc: t.Optional[t.List[str]],
- platforms: t.List[str],
+ platforms: t.Iterable[str],
):
-
converted_patches = [
_convert_patch(llvm_config, skip_dependencies, p) for p in patches
]
@@ -352,11 +343,12 @@ def find_patches_and_make_cl(
raise RuntimeError(f"Found Duplicate SHAs:\n{err_msg}")
# CL Related variables, only used if `create_cl`
- symlinks_to_uprev = []
commit_messages = [
"llvm: get patches from upstream\n",
]
- branch = f'get-upstream-{datetime.now().strftime("%Y%m%d%H%M%S%f")}'
+ branch = (
+ f'get-upstream-{datetime.datetime.now().strftime("%Y%m%d%H%M%S%f")}'
+ )
if create_cl:
git.CreateBranch(llvm_symlink_dir, branch)
@@ -366,22 +358,22 @@ def find_patches_and_make_cl(
for parsed_patch in converted_patches:
# Find out the llvm projects changed in this commit
packages = get_package_names(parsed_patch.sha, llvm_config.dir)
- # Find out the ebuild symlinks of the corresponding ChromeOS packages
- symlinks = chroot.GetChrootEbuildPaths(
+ # Find out the ebuild of the corresponding ChromeOS packages
+ ebuild_paths = chroot.GetChrootEbuildPaths(
chroot_path,
[
"sys-devel/llvm" if package == "llvm" else "sys-libs/" + package
for package in packages
],
)
- symlinks = chroot.ConvertChrootPathsToAbsolutePaths(
- chroot_path, symlinks
+ ebuild_paths = chroot.ConvertChrootPathsToAbsolutePaths(
+ chroot_path, ebuild_paths
)
# Create a local patch for all the affected llvm projects
try:
create_patch_for_packages(
packages,
- symlinks,
+ ebuild_paths,
start_rev,
parsed_patch.rev,
parsed_patch.sha,
@@ -398,7 +390,6 @@ def find_patches_and_make_cl(
successes.append(parsed_patch.sha)
if create_cl:
- symlinks_to_uprev.extend(symlinks)
commit_messages.extend(
[
@@ -428,7 +419,6 @@ def find_patches_and_make_cl(
if successes and create_cl:
make_cl(
- symlinks_to_uprev,
llvm_symlink_dir,
branch,
commit_messages,
@@ -458,12 +448,12 @@ def _convert_patch(
"""Extract git revision info from a patch.
Args:
- llvm_config: LLVM configuration object.
- skip_dependencies: Pass --skip-dependecies for to `arc`
- patch: A single patch referent string.
+ llvm_config: LLVM configuration object.
+ skip_dependencies: Pass --skip-dependecies for to `arc`
+ patch: A single patch referent string.
Returns:
- A [ParsedPatch] object.
+ A [ParsedPatch] object.
"""
# git hash should only have lower-case letters
@@ -480,7 +470,7 @@ def _convert_patch(
cwd=llvm_config.dir,
)
sha = resolve_llvm_ref(llvm_config.dir, "HEAD")
- rev = patch
+ rev: t.Union[git_llvm_rev.Rev, str] = patch
else:
sha = resolve_llvm_ref(llvm_config.dir, patch)
rev = git_llvm_rev.translate_sha_to_rev(llvm_config, sha)
@@ -506,11 +496,11 @@ def get_from_upstream(
create_cl: bool,
start_sha: str,
patches: t.List[str],
- platforms: t.List[str],
- allow_failures: bool,
+ platforms: t.Iterable[str],
+ allow_failures: bool = False,
skip_dependencies: bool = False,
- reviewers: t.List[str] = None,
- cc: t.List[str] = None,
+ reviewers: t.Optional[t.List[str]] = None,
+ cc: t.Optional[t.List[str]] = None,
):
llvm_symlink = chroot.ConvertChrootPathsToAbsolutePaths(
chroot_path,
@@ -554,7 +544,8 @@ def get_from_upstream(
def main():
chroot.VerifyOutsideChroot()
logging.basicConfig(
- format="%(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: %(message)s",
+ format="%(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: "
+ "%(message)s",
level=logging.INFO,
)
@@ -571,8 +562,8 @@ def main():
parser.add_argument(
"--start_sha",
default="llvm-next",
- help="LLVM SHA that the patch should start applying at. You can specify "
- '"llvm" or "llvm-next", as well. Defaults to %(default)s.',
+ help="LLVM SHA that the patch should start applying at. You can "
+ 'specify "llvm" or "llvm-next", as well. Defaults to %(default)s.',
)
parser.add_argument(
"--sha",
diff --git a/llvm_tools/git.py b/llvm_tools/git.py
index 3bb702c9..7ca44b04 100755
--- a/llvm_tools/git.py
+++ b/llvm_tools/git.py
@@ -1,46 +1,31 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2020 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Git helper functions."""
-
import collections
import os
+from pathlib import Path
import re
import subprocess
import tempfile
+from typing import Iterable, Optional, Union
CommitContents = collections.namedtuple("CommitContents", ["url", "cl_number"])
-def InChroot():
- """Returns True if currently in the chroot."""
- return "CROS_WORKON_SRCROOT" in os.environ
-
-
-def VerifyOutsideChroot():
- """Checks whether the script invoked was executed in the chroot.
-
- Raises:
- AssertionError: The script was run inside the chroot.
- """
-
- assert not InChroot(), "Script should be run outside the chroot."
-
-
-def CreateBranch(repo, branch):
+def CreateBranch(repo: Union[Path, str], branch: str) -> None:
"""Creates a branch in the given repo.
Args:
- repo: The absolute path to the repo.
- branch: The name of the branch to create.
+ repo: The absolute path to the repo.
+ branch: The name of the branch to create.
Raises:
- ValueError: Failed to create a repo in that directory.
+ ValueError: Failed to create a repo in that directory.
"""
if not os.path.isdir(repo):
@@ -51,15 +36,15 @@ def CreateBranch(repo, branch):
subprocess.check_output(["repo", "start", branch], cwd=repo)
-def DeleteBranch(repo, branch):
+def DeleteBranch(repo: Union[Path, str], branch: str) -> None:
"""Deletes a branch in the given repo.
Args:
- repo: The absolute path of the repo.
- branch: The name of the branch to delete.
+ repo: The absolute path of the repo.
+ branch: The name of the branch to delete.
Raises:
- ValueError: Failed to delete the repo in that directory.
+ ValueError: Failed to delete the repo in that directory.
"""
if not os.path.isdir(repo):
@@ -73,38 +58,54 @@ def DeleteBranch(repo, branch):
run_checked(["branch", "-q", "-D", branch])
+def CommitChanges(
+ repo: Union[Path, str], commit_messages: Iterable[str]
+) -> None:
+ """Commit changes without uploading them.
+
+ Args:
+ repo: The absolute path to the repo where changes were made.
+ commit_messages: Messages to concatenate to form the commit message.
+ """
+ if not os.path.isdir(repo):
+ raise ValueError("Invalid path provided: %s" % repo)
+
+ # Create a git commit.
+ with tempfile.NamedTemporaryFile(mode="w+t", encoding="utf-8") as f:
+ f.write("\n".join(commit_messages))
+ f.flush()
+
+ subprocess.check_output(["git", "commit", "-F", f.name], cwd=repo)
+
+
def UploadChanges(
- repo, branch, commit_messages, reviewers=None, cc=None, wip=False
-):
+ repo: Union[Path, str],
+ branch: str,
+ reviewers: Optional[Iterable[str]] = None,
+ cc: Optional[Iterable[str]] = None,
+ wip: bool = False,
+) -> CommitContents:
"""Uploads the changes in the specifed branch of the given repo for review.
Args:
- repo: The absolute path to the repo where changes were made.
- branch: The name of the branch to upload.
- commit_messages: A string of commit message(s) (i.e. '[message]'
- of the changes made.
- reviewers: A list of reviewers to add to the CL.
- cc: A list of contributors to CC about the CL.
+ repo: The absolute path to the repo where changes were made.
+ branch: The name of the branch to upload.
+ of the changes made.
+ reviewers: A list of reviewers to add to the CL.
+ cc: A list of contributors to CC about the CL.
+ wip: Whether to upload the change as a work-in-progress.
Returns:
- A nametuple that has two (key, value) pairs, where the first pair is the
- Gerrit commit URL and the second pair is the change list number.
+ A CommitContents value containing the commit URL and change list number.
Raises:
- ValueError: Failed to create a commit or failed to upload the
- changes for review.
+ ValueError: Failed to create a commit or failed to upload the
+ changes for review.
"""
if not os.path.isdir(repo):
raise ValueError("Invalid path provided: %s" % repo)
- # Create a git commit.
- with tempfile.NamedTemporaryFile(mode="w+t") as f:
- f.write("\n".join(commit_messages))
- f.flush()
-
- subprocess.check_output(["git", "commit", "-F", f.name], cwd=repo)
-
# Upload the changes for review.
git_args = [
"repo",
diff --git a/llvm_tools/git_llvm_rev.py b/llvm_tools/git_llvm_rev.py
index 1db94461..51fb6fec 100755
--- a/llvm_tools/git_llvm_rev.py
+++ b/llvm_tools/git_llvm_rev.py
@@ -1,5 +1,4 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -10,12 +9,12 @@ Revision numbers are all of the form '(branch_name, r1234)'. As a shorthand,
r1234 is parsed as '(main, 1234)'.
"""
-
import argparse
+from pathlib import Path
import re
import subprocess
import sys
-import typing as t
+from typing import IO, Iterable, List, NamedTuple, Optional, Tuple, Union
MAIN_BRANCH = "main"
@@ -35,13 +34,27 @@ MAIN_BRANCH = "main"
base_llvm_revision = 375505
base_llvm_sha = "186155b89c2d2a2f62337081e3ca15f676c9434b"
+# Known pairs of [revision, SHA] in ascending order.
+# The first element is the first non-`llvm-svn` commit that exists. Later ones
+# are functional nops, but speed this script up immensely, since `git` can take
+# quite a while to walk >100K commits.
+known_llvm_rev_sha_pairs = (
+ (base_llvm_revision, base_llvm_sha),
+ (425000, "af870e11aed7a5c475ae41a72e3015c4c88597d1"),
+ (450000, "906ebd5830e6053b50c52bf098e3586b567e8499"),
+ (475000, "530d14a99611a71f8f3eb811920fd7b5c4d4e1f8"),
+ (500000, "173855f9b0bdfe45d71272596b510650bfc1ca33"),
+)
+
# Represents an LLVM git checkout:
# - |dir| is the directory of the LLVM checkout
# - |remote| is the name of the LLVM remote. Generally it's "origin".
-LLVMConfig = t.NamedTuple("LLVMConfig", (("remote", str), ("dir", str)))
+LLVMConfig = NamedTuple(
+ "LLVMConfig", (("remote", str), ("dir", Union[Path, str]))
+)
-class Rev(t.NamedTuple("Rev", (("branch", str), ("number", int)))):
+class Rev(NamedTuple("Rev", (("branch", str), ("number", int)))):
"""Represents a LLVM 'revision', a shorthand identifies a LLVM commit."""
@staticmethod
@@ -83,7 +96,7 @@ def is_git_sha(xs: str) -> bool:
)
-def check_output(command: t.List[str], cwd: str) -> str:
+def check_output(command: List[str], cwd: Union[Path, str]) -> str:
"""Shorthand for subprocess.check_output. Auto-decodes any stdout."""
result = subprocess.run(
command,
@@ -130,26 +143,26 @@ def translate_sha_to_rev(llvm_config: LLVMConfig, sha_or_ref: str) -> Rev:
)
sha = sha.strip()
- merge_base = check_output(
- ["git", "merge-base", base_llvm_sha, sha, "--"],
- cwd=llvm_config.dir,
- )
- merge_base = merge_base.strip()
-
- if merge_base == base_llvm_sha:
- result = check_output(
- [
- "git",
- "rev-list",
- "--count",
- "--first-parent",
- f"{base_llvm_sha}..{sha}",
- "--",
- ],
+ for base_rev, base_sha in reversed(known_llvm_rev_sha_pairs):
+ merge_base = check_output(
+ ["git", "merge-base", base_sha, sha, "--"],
cwd=llvm_config.dir,
)
- count = int(result.strip())
- return Rev(branch=MAIN_BRANCH, number=count + base_llvm_revision)
+ merge_base = merge_base.strip()
+ if merge_base == base_sha:
+ result = check_output(
+ [
+ "git",
+ "rev-list",
+ "--count",
+ "--first-parent",
+ f"{base_sha}..{sha}",
+ "--",
+ ],
+ cwd=llvm_config.dir,
+ )
+ count = int(result.strip())
+ return Rev(branch=MAIN_BRANCH, number=count + base_rev)
# Otherwise, either:
# - |merge_base| is |sha| (we have a guaranteed llvm-svn number on |sha|)
@@ -193,22 +206,23 @@ def translate_sha_to_rev(llvm_config: LLVMConfig, sha_or_ref: str) -> Rev:
)
# It seems that some `origin/release/.*` branches have
- # `origin/upstream/release/.*` equivalents, which is... awkward to deal with.
- # Prefer the latter, since that seems to have newer commits than the former.
- # Technically n^2, but len(elements) should be like, tens in the worst case.
+ # `origin/upstream/release/.*` equivalents, which is... awkward to deal
+ # with. Prefer the latter, since that seems to have newer commits than the
+ # former. Technically n^2, but len(elements) should be like, tens in the
+ # worst case.
candidates = [x for x in candidates if f"upstream/{x}" not in candidates]
if len(candidates) != 1:
raise ValueError(
- f"Ambiguity: multiple branches from {llvm_config.remote} have {sha}: "
- f"{sorted(candidates)}"
+ f"Ambiguity: multiple branches from {llvm_config.remote} have "
+ f"{sha}: {sorted(candidates)}"
)
return Rev(branch=candidates[0], number=revision_number)
def parse_git_commit_messages(
- stream: t.Iterable[str], separator: str
-) -> t.Iterable[t.Tuple[str, str]]:
+ stream: Union[Iterable[str], IO[str]], separator: str
+) -> Iterable[Tuple[str, str]]:
"""Parses a stream of git log messages.
These are expected to be in the format:
@@ -272,6 +286,7 @@ def translate_prebase_rev_to_sha(llvm_config: LLVMConfig, rev: Rev) -> str:
stdout=subprocess.PIPE,
encoding="utf-8",
) as subp:
+ assert subp.stdout is not None
for sha, message in parse_git_commit_messages(subp.stdout, separator):
last_line = message.splitlines()[-1]
if last_line.strip() == looking_for:
@@ -283,78 +298,137 @@ def translate_prebase_rev_to_sha(llvm_config: LLVMConfig, rev: Rev) -> str:
raise ValueError(f"No commit with revision {rev} found")
-def translate_rev_to_sha(llvm_config: LLVMConfig, rev: Rev) -> str:
- """Translates a Rev to a SHA.
-
- Raises a ValueError if the given Rev doesn't exist in the given config.
+def translate_rev_to_sha_from_baseline(
+ llvm_config: LLVMConfig,
+ parent_sha: str,
+ parent_rev: int,
+ child_sha: str,
+ child_rev: Optional[int],
+ want_rev: int,
+ branch_name: str,
+) -> str:
+ """Translates a revision number between a parent & child to a SHA.
+
+ Args:
+ llvm_config: LLVM config to use.
+ parent_sha: SHA of the parent that the revision number is a child of.
+ parent_rev: Revision number of `parent_sha`.
+ child_sha: A child of `parent_sha` to find a rev on.
+ child_rev: Optional note of what the child's revision number is.
+ want_rev: The desired revision number between child and parent.
+ branch_name: Name of the branch to refer to if a ValueError is raised.
+
+ Raises:
+ ValueError if the given child isn't far enough away from the parent to
+ find `want_rev`.
"""
- branch, number = rev
-
- if branch == MAIN_BRANCH:
- if number < base_llvm_revision:
- return translate_prebase_rev_to_sha(llvm_config, rev)
- base_sha = base_llvm_sha
- base_revision_number = base_llvm_revision
+ # As a convenience, have a fast path for want_rev < parent_rev. In
+ # particular, branches can hit this case.
+ if want_rev < parent_rev:
+ baseline_git_sha = parent_sha
+ commits_behind_baseline = parent_rev - want_rev
else:
- base_sha = check_output(
- [
- "git",
- "merge-base",
- base_llvm_sha,
- f"{llvm_config.remote}/{branch}",
- ],
- cwd=llvm_config.dir,
- )
- base_sha = base_sha.strip()
- if base_sha == base_llvm_sha:
- base_revision_number = base_llvm_revision
- else:
- base_revision_number = translate_prebase_sha_to_rev_number(
- llvm_config, base_sha
+ if child_rev is None:
+ commits_between_parent_and_child = check_output(
+ [
+ "git",
+ "rev-list",
+ "--count",
+ "--first-parent",
+ f"{parent_sha}..{child_sha}",
+ "--",
+ ],
+ cwd=llvm_config.dir,
)
+ child_rev = parent_rev + int(
+ commits_between_parent_and_child.strip()
+ )
+ if child_rev < want_rev:
+ raise ValueError(
+ "Revision {want_rev} is past "
+ f"{llvm_config.remote}/{branch_name}. Try updating your tree?"
+ )
+ baseline_git_sha = child_sha
+ commits_behind_baseline = child_rev - want_rev
- # Alternatively, we could |git log --format=%H|, but git is *super* fast
- # about rev walking/counting locally compared to long |log|s, so we walk back
- # twice.
- head = check_output(
+ if not commits_behind_baseline:
+ return baseline_git_sha
+
+ result = check_output(
[
"git",
"rev-parse",
"--revs-only",
- f"{llvm_config.remote}/{branch}",
- "--",
+ f"{baseline_git_sha}~{commits_behind_baseline}",
],
cwd=llvm_config.dir,
)
- branch_head_sha = head.strip()
+ return result.strip()
- commit_number = number - base_revision_number
- revs_between_str = check_output(
- [
- "git",
- "rev-list",
- "--count",
- "--first-parent",
- f"{base_sha}..{branch_head_sha}",
- "--",
- ],
+
+def translate_rev_to_sha(llvm_config: LLVMConfig, rev: Rev) -> str:
+ """Translates a Rev to a SHA.
+
+ Raises a ValueError if the given Rev doesn't exist in the given config.
+ """
+ branch, number = rev
+
+ branch_tip = check_output(
+ ["git", "rev-parse", "--revs-only", f"{llvm_config.remote}/{branch}"],
cwd=llvm_config.dir,
- )
- revs_between = int(revs_between_str.strip())
+ ).strip()
- commits_behind_head = revs_between - commit_number
- if commits_behind_head < 0:
- raise ValueError(
- f"Revision {rev} is past {llvm_config.remote}/{branch}. Try updating "
- "your tree?"
+ if branch != MAIN_BRANCH:
+ main_merge_point = check_output(
+ [
+ "git",
+ "merge-base",
+ f"{llvm_config.remote}/{MAIN_BRANCH}",
+ branch_tip,
+ ],
+ cwd=llvm_config.dir,
+ )
+ main_merge_point = main_merge_point.strip()
+ main_rev = translate_sha_to_rev(llvm_config, main_merge_point)
+ return translate_rev_to_sha_from_baseline(
+ llvm_config,
+ parent_sha=main_merge_point,
+ parent_rev=main_rev.number,
+ child_sha=branch_tip,
+ child_rev=None,
+ want_rev=number,
+ branch_name=branch,
)
- result = check_output(
- ["git", "rev-parse", f"{branch_head_sha}~{commits_behind_head}"],
- cwd=llvm_config.dir,
- )
+ if number < base_llvm_revision:
+ return translate_prebase_rev_to_sha(llvm_config, rev)
+
+ # Technically this could be a binary search, but the list has fewer than 10
+ # elems, and won't grow fast. Linear is easier.
+ last_cached_rev = None
+ last_cached_sha = branch_tip
+ for cached_rev, cached_sha in reversed(known_llvm_rev_sha_pairs):
+ if cached_rev == number:
+ return cached_sha
+
+ if cached_rev < number:
+ return translate_rev_to_sha_from_baseline(
+ llvm_config,
+ parent_sha=cached_sha,
+ parent_rev=cached_rev,
+ child_sha=last_cached_sha,
+ child_rev=last_cached_rev,
+ want_rev=number,
+ branch_name=branch,
+ )
- return result.strip()
+ last_cached_rev = cached_rev
+ last_cached_sha = cached_sha
+
+ # This is only hit if `number >= base_llvm_revision` _and_ there's no
+ # coverage for `number` in `known_llvm_rev_sha_pairs`, which contains
+ # `base_llvm_revision`.
+ assert False, "Couldn't find a base SHA for a rev on main?"
def find_root_llvm_dir(root_dir: str = ".") -> str:
@@ -369,7 +443,7 @@ def find_root_llvm_dir(root_dir: str = ".") -> str:
return result.strip()
-def main(argv: t.List[str]) -> None:
+def main(argv: List[str]) -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--llvm_dir",
diff --git a/llvm_tools/git_llvm_rev_test.py b/llvm_tools/git_llvm_rev_test.py
index 86a4b202..dbea0fca 100755
--- a/llvm_tools/git_llvm_rev_test.py
+++ b/llvm_tools/git_llvm_rev_test.py
@@ -1,5 +1,4 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -9,7 +8,6 @@
import unittest
import git_llvm_rev
-from git_llvm_rev import MAIN_BRANCH
import llvm_project
@@ -32,20 +30,21 @@ class Test(unittest.TestCase):
def test_sha_to_rev_on_base_sha_works(self) -> None:
sha = self.rev_to_sha_with_round_trip(
git_llvm_rev.Rev(
- branch=MAIN_BRANCH, number=git_llvm_rev.base_llvm_revision
+ branch=git_llvm_rev.MAIN_BRANCH,
+ number=git_llvm_rev.base_llvm_revision,
)
)
self.assertEqual(sha, git_llvm_rev.base_llvm_sha)
def test_sha_to_rev_prior_to_base_rev_works(self) -> None:
sha = self.rev_to_sha_with_round_trip(
- git_llvm_rev.Rev(branch=MAIN_BRANCH, number=375000)
+ git_llvm_rev.Rev(branch=git_llvm_rev.MAIN_BRANCH, number=375000)
)
self.assertEqual(sha, "2f6da767f13b8fd81f840c211d405fea32ac9db7")
def test_sha_to_rev_after_base_rev_works(self) -> None:
sha = self.rev_to_sha_with_round_trip(
- git_llvm_rev.Rev(branch=MAIN_BRANCH, number=375506)
+ git_llvm_rev.Rev(branch=git_llvm_rev.MAIN_BRANCH, number=375506)
)
self.assertEqual(sha, "3bf7fddeb05655d9baed4cc69e13535c677ed1dd")
@@ -55,13 +54,13 @@ class Test(unittest.TestCase):
# Commit which performed the revert
sha = self.rev_to_sha_with_round_trip(
- git_llvm_rev.Rev(branch=MAIN_BRANCH, number=374895)
+ git_llvm_rev.Rev(branch=git_llvm_rev.MAIN_BRANCH, number=374895)
)
self.assertEqual(sha, "1731fc88d1fa1fa55edd056db73a339b415dd5d6")
# Commit that was reverted
sha = self.rev_to_sha_with_round_trip(
- git_llvm_rev.Rev(branch=MAIN_BRANCH, number=374841)
+ git_llvm_rev.Rev(branch=git_llvm_rev.MAIN_BRANCH, number=374841)
)
self.assertEqual(sha, "2a1386c81de504b5bda44fbecf3f7b4cdfd748fc")
@@ -69,7 +68,9 @@ class Test(unittest.TestCase):
with self.assertRaises(ValueError) as r:
git_llvm_rev.translate_rev_to_sha(
get_llvm_config(),
- git_llvm_rev.Rev(branch=MAIN_BRANCH, number=9999999),
+ git_llvm_rev.Rev(
+ branch=git_llvm_rev.MAIN_BRANCH, number=9999999
+ ),
)
self.assertIn("Try updating your tree?", str(r.exception))
@@ -79,31 +80,55 @@ class Test(unittest.TestCase):
# properties about it.
merge_sha_rev_number = 4496 + git_llvm_rev.base_llvm_revision
sha = self.rev_to_sha_with_round_trip(
- git_llvm_rev.Rev(branch=MAIN_BRANCH, number=merge_sha_rev_number)
+ git_llvm_rev.Rev(
+ branch=git_llvm_rev.MAIN_BRANCH, number=merge_sha_rev_number
+ )
)
self.assertEqual(sha, "0f0d0ed1c78f1a80139a1f2133fad5284691a121")
sha = self.rev_to_sha_with_round_trip(
git_llvm_rev.Rev(
- branch=MAIN_BRANCH, number=merge_sha_rev_number - 1
+ branch=git_llvm_rev.MAIN_BRANCH, number=merge_sha_rev_number - 1
)
)
self.assertEqual(sha, "6f635f90929da9545dd696071a829a1a42f84b30")
sha = self.rev_to_sha_with_round_trip(
git_llvm_rev.Rev(
- branch=MAIN_BRANCH, number=merge_sha_rev_number + 1
+ branch=git_llvm_rev.MAIN_BRANCH, number=merge_sha_rev_number + 1
)
)
self.assertEqual(sha, "199700a5cfeedf227619f966aa3125cef18bc958")
- # NOTE: The below tests have _zz_ in their name as an optimization. Iterating
- # on a quick test is painful when these larger tests come before it and take
- # 7secs to run. Python's unittest module guarantees tests are run in
- # alphabetical order by their method name, so...
+ def test_known_rev_sha_pairs_are_sorted(self):
+ revs = [rev for rev, _ in git_llvm_rev.known_llvm_rev_sha_pairs]
+ self.assertEqual(revs, sorted(revs))
+
+ # NOTE: The below tests have _zz_ in their name as an optimization.
+ # Iterating on a quick test is painful when these larger tests come before
+ # it and take 7secs to run. Python's unittest module guarantees tests are
+ # run in alphabetical order by their method name, so...
#
- # If you're wondering, the slow part is `git branch -r --contains`. I imagine
- # it's going to be very cold code, so I'm not inclined to optimize it much.
+ # If you're wondering, the slow part is `git branch -r --contains`. I
+ # imagine it's going to be very cold code, so I'm not inclined to optimize
+ # it much.
+
+ def test_zz_non_base_rev_sha_pairs_are_correct(self):
+ base_rev_sha_pairs = git_llvm_rev.known_llvm_rev_sha_pairs
+
+ def restore_rev_sha_pairs():
+ git_llvm_rev.known_llvm_rev_sha_pairs = base_rev_sha_pairs
+
+ self.addCleanup(restore_rev_sha_pairs)
+ git_llvm_rev.known_llvm_rev_sha_pairs = (
+ (git_llvm_rev.base_llvm_revision, git_llvm_rev.base_llvm_sha),
+ )
+
+ for rev, cached_sha in base_rev_sha_pairs:
+ got_sha = self.rev_to_sha_with_round_trip(
+ git_llvm_rev.Rev(branch=git_llvm_rev.MAIN_BRANCH, number=rev)
+ )
+ self.assertEqual(cached_sha, got_sha)
def test_zz_branch_revs_work_after_merge_points_and_svn_cutoff(
self,
@@ -119,7 +144,7 @@ class Test(unittest.TestCase):
backing_sha = "c89a3d78f43d81b9cff7b9248772ddf14d21b749"
sha = self.rev_to_sha_with_round_trip(
- git_llvm_rev.Rev(branch=MAIN_BRANCH, number=rev_number)
+ git_llvm_rev.Rev(branch=git_llvm_rev.MAIN_BRANCH, number=rev_number)
)
self.assertEqual(sha, backing_sha)
@@ -134,8 +159,8 @@ class Test(unittest.TestCase):
def test_zz_branch_revs_work_after_merge_points(self) -> None:
# Picking the commit on the 9.x branch after the merge-base for that +
# main. Note that this is where llvm-svn numbers should diverge from
- # ours, and are therefore untrustworthy. The commit for this *does* have a
- # different `llvm-svn:` string than we should have.
+ # ours, and are therefore untrustworthy. The commit for this *does*
+ # have a different `llvm-svn:` string than we should have.
sha = self.rev_to_sha_with_round_trip(
git_llvm_rev.Rev(branch="upstream/release/9.x", number=366427)
)
diff --git a/llvm_tools/git_unittest.py b/llvm_tools/git_unittest.py
index 35ba2430..940f0dba 100755
--- a/llvm_tools/git_unittest.py
+++ b/llvm_tools/git_unittest.py
@@ -1,17 +1,15 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2020 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unit tests for git helper functions."""
-
import os
import subprocess
import tempfile
import unittest
-import unittest.mock as mock
+from unittest import mock
import git
@@ -28,7 +26,8 @@ class HelperFunctionsTest(unittest.TestCase):
path_to_repo = "/invalid/path/to/repo"
branch = "branch-name"
- # Verify the exception is raised when provided an invalid directory path.
+ # Verify the exception is raised when provided an invalid directory
+ # path.
with self.assertRaises(ValueError) as err:
git.CreateBranch(path_to_repo, branch)
@@ -83,11 +82,10 @@ class HelperFunctionsTest(unittest.TestCase):
def testFailedToUploadChangesForInvalidDirectoryPath(self, mock_isdir):
path_to_repo = "/some/path/to/repo"
branch = "update-LLVM_NEXT_HASH-a123testhash3"
- commit_messages = ["Test message"]
# Verify exception is raised when on an invalid repo path.
with self.assertRaises(ValueError) as err:
- git.UploadChanges(path_to_repo, branch, commit_messages)
+ git.UploadChanges(path_to_repo, branch)
self.assertEqual(
str(err.exception), "Invalid path provided: %s" % path_to_repo
@@ -101,7 +99,6 @@ class HelperFunctionsTest(unittest.TestCase):
def testSuccessfullyUploadedChangesForReview(
self, mock_tempfile, mock_commands, mock_isdir
):
-
path_to_repo = "/some/path/to/repo"
branch = "branch-name"
commit_messages = ["Test message"]
@@ -116,11 +113,12 @@ class HelperFunctionsTest(unittest.TestCase):
"+/193147 Fix stdout"
),
]
- change_list = git.UploadChanges(path_to_repo, branch, commit_messages)
+ git.CommitChanges(path_to_repo, commit_messages)
+ change_list = git.UploadChanges(path_to_repo, branch)
self.assertEqual(change_list.cl_number, 193147)
- mock_isdir.assert_called_once_with(path_to_repo)
+ mock_isdir.assert_called_with(path_to_repo)
expected_command = [
"git",
diff --git a/llvm_tools/llvm_bisection.py b/llvm_tools/llvm_bisection.py
index 6cc93aec..2c5bc1a6 100755
--- a/llvm_tools/llvm_bisection.py
+++ b/llvm_tools/llvm_bisection.py
@@ -1,12 +1,10 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Performs bisection on LLVM based off a .JSON file."""
-
import argparse
import enum
import errno
@@ -68,8 +66,8 @@ def GetCommandLineArgs():
help="The bad revision for the bisection.",
)
- # Add argument for the absolute path to the file that contains information on
- # the previous tested svn version.
+ # Add argument for the absolute path to the file that contains information
+ # on the previous tested svn version.
parser.add_argument(
"--last_tested",
required=True,
@@ -124,14 +122,6 @@ def GetCommandLineArgs():
# Add argument for whether to display command contents to `stdout`.
parser.add_argument(
- "--verbose",
- action="store_true",
- help="display contents of a command to the terminal "
- "(default: %(default)s)",
- )
-
- # Add argument for whether to display command contents to `stdout`.
- parser.add_argument(
"--nocleanup",
action="store_false",
dest="cleanup",
@@ -162,25 +152,26 @@ def GetRemainingRange(start, end, tryjobs):
"""Gets the start and end intervals in 'json_file'.
Args:
- start: The start version of the bisection provided via the command line.
- end: The end version of the bisection provided via the command line.
- tryjobs: A list of tryjobs where each element is in the following format:
- [
- {[TRYJOB_INFORMATION]},
- {[TRYJOB_INFORMATION]},
- ...,
- {[TRYJOB_INFORMATION]}
- ]
+ start: The start version of the bisection provided via the command line.
+ end: The end version of the bisection provided via the command line.
+ tryjobs: A list of tryjobs where each element is in the following
+ format:
+ [
+ {[TRYJOB_INFORMATION]},
+ {[TRYJOB_INFORMATION]},
+ ...,
+ {[TRYJOB_INFORMATION]}
+ ]
Returns:
- The new start version and end version for bisection, a set of revisions
- that are 'pending' and a set of revisions that are to be skipped.
+ The new start version and end version for bisection, a set of revisions
+ that are 'pending' and a set of revisions that are to be skipped.
Raises:
- ValueError: The value for 'status' is missing or there is a mismatch
- between 'start' and 'end' compared to the 'start' and 'end' in the JSON
- file.
- AssertionError: The new start version is >= than the new end version.
+ ValueError: The value for 'status' is missing or there is a mismatch
+ between 'start' and 'end' compared to the 'start' and 'end' in the JSON
+ file.
+ AssertionError: The new start version is >= than the new end version.
"""
if not tryjobs:
@@ -240,8 +231,8 @@ def GetRemainingRange(start, end, tryjobs):
# Find all revisions that are to be skipped within 'good_rev' and 'bad_rev'.
#
# NOTE: The intent is to not launch tryjobs between 'good_rev' and 'bad_rev'
- # that have already been marked as 'skip' (this set is used when constructing
- # the list of revisions to launch tryjobs for).
+ # that have already been marked as 'skip' (this set is used when
+ # constructing the list of revisions to launch tryjobs for).
skip_revisions = {
tryjob["rev"]
for tryjob in tryjobs
@@ -292,7 +283,6 @@ def Bisect(
extra_change_lists,
options,
builder,
- verbose,
):
"""Adds tryjobs and updates the status file with the new tryjobs."""
@@ -306,7 +296,6 @@ def Bisect(
extra_change_lists,
options,
builder,
- verbose,
svn_revision,
)
@@ -315,7 +304,7 @@ def Bisect(
# Do not want to lose progress if there is an exception.
if last_tested:
new_file = "%s.new" % last_tested
- with open(new_file, "w") as json_file:
+ with open(new_file, "w", encoding="utf-8") as json_file:
json.dump(
bisect_state, json_file, indent=4, separators=(",", ": ")
)
@@ -327,7 +316,7 @@ def LoadStatusFile(last_tested, start, end):
"""Loads the status file for bisection."""
try:
- with open(last_tested) as f:
+ with open(last_tested, encoding="utf-8") as f:
return json.load(f)
except IOError as err:
if err.errno != errno.ENOENT:
@@ -340,7 +329,7 @@ def main(args_output):
"""Bisects LLVM commits.
Raises:
- AssertionError: The script was run inside the chroot.
+ AssertionError: The script was run inside the chroot.
"""
chroot.VerifyOutsideChroot()
@@ -454,7 +443,6 @@ def main(args_output):
args_output.extra_change_lists,
args_output.options,
args_output.builder,
- args_output.verbose,
)
diff --git a/llvm_tools/llvm_bisection_unittest.py b/llvm_tools/llvm_bisection_unittest.py
index a2bcc90b..1c1c8166 100755
--- a/llvm_tools/llvm_bisection_unittest.py
+++ b/llvm_tools/llvm_bisection_unittest.py
@@ -1,5 +1,4 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -8,12 +7,11 @@
"""Tests for LLVM bisection."""
-
import json
import os
import subprocess
import unittest
-import unittest.mock as mock
+from unittest import mock
import chroot
import get_llvm_hash
@@ -58,8 +56,8 @@ class LLVMBisectionTest(unittest.TestCase):
},
]
- # Tuple consists of the new good revision, the new bad revision, a set of
- # 'pending' revisions, and a set of 'skip' revisions.
+ # Tuple consists of the new good revision, the new bad revision, a set
+ # of 'pending' revisions, and a set of 'skip' revisions.
expected_revisions_tuple = 120, 140, {130}, {135}
self.assertEqual(
@@ -173,7 +171,7 @@ class LLVMBisectionTest(unittest.TestCase):
# Simulate that the status file exists.
with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as f:
+ with open(temp_json_file, "w", encoding="utf-8") as f:
test_helpers.WritePrettyJsonFile(test_bisect_state, f)
self.assertEqual(
@@ -196,12 +194,11 @@ class LLVMBisectionTest(unittest.TestCase):
@mock.patch.object(modify_a_tryjob, "AddTryjob")
def testBisectPassed(self, mock_add_tryjob):
-
git_hash_list = ["a123testhash1", "a123testhash2", "a123testhash3"]
revisions_list = [102, 104, 106]
- # Simulate behavior of `AddTryjob()` when successfully launched a tryjob for
- # the updated packages.
+ # Simulate behavior of `AddTryjob()` when successfully launched a
+ # tryjob for the updated packages.
@test_helpers.CallCountsToMockFunctions
def MockAddTryjob(
call_count,
@@ -212,10 +209,8 @@ class LLVMBisectionTest(unittest.TestCase):
_extra_cls,
_options,
_builder,
- _verbose,
_svn_revision,
):
-
if call_count < 2:
return {"rev": revisions_list[call_count], "status": "pending"}
@@ -240,11 +235,11 @@ class LLVMBisectionTest(unittest.TestCase):
# Create a temporary .JSON file to simulate a status file for bisection.
with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as f:
+ with open(temp_json_file, "w", encoding="utf-8") as f:
test_helpers.WritePrettyJsonFile(bisection_contents, f)
- # Verify that the status file is updated when an exception happened when
- # attempting to launch a revision (i.e. progress is not lost).
+ # Verify that the status file is updated when an exception happened
+ # when attempting to launch a revision (i.e. progress is not lost).
with self.assertRaises(ValueError) as err:
llvm_bisection.Bisect(
revisions_list,
@@ -256,7 +251,6 @@ class LLVMBisectionTest(unittest.TestCase):
args_output.extra_change_lists,
args_output.options,
args_output.builders,
- args_output.verbose,
)
expected_bisection_contents = {
@@ -268,9 +262,9 @@ class LLVMBisectionTest(unittest.TestCase):
],
}
- # Verify that the launched tryjobs were added to the status file when
- # an exception happened.
- with open(temp_json_file) as f:
+ # Verify that the launched tryjobs were added to the status file
+ # when an exception happened.
+ with open(temp_json_file, encoding="utf-8") as f:
json_contents = json.load(f)
self.assertEqual(json_contents, expected_bisection_contents)
@@ -298,7 +292,6 @@ class LLVMBisectionTest(unittest.TestCase):
_mock_get_bad_llvm_hash,
mock_abandon_cl,
):
-
start = 500
end = 502
cl = 1
@@ -368,7 +361,6 @@ class LLVMBisectionTest(unittest.TestCase):
def testMainFailedWithInvalidRange(
self, mock_chromeos_root, mock_outside_chroot, mock_load_status_file
):
-
start = 500
end = 502
@@ -415,7 +407,6 @@ class LLVMBisectionTest(unittest.TestCase):
mock_get_range,
mock_get_revision_and_hash_list,
):
-
start = 500
end = 502
rev = 501
@@ -480,7 +471,6 @@ class LLVMBisectionTest(unittest.TestCase):
mock_get_range,
mock_get_revision_and_hash_list,
):
-
start = 500
end = 502
rev = 501
@@ -547,7 +537,6 @@ class LLVMBisectionTest(unittest.TestCase):
_mock_get_bad_llvm_hash,
mock_abandon_cl,
):
-
start = 500
end = 502
diff --git a/llvm_tools/llvm_project.py b/llvm_tools/llvm_project.py
index 79a6cd2e..961074db 100644
--- a/llvm_tools/llvm_project.py
+++ b/llvm_tools/llvm_project.py
@@ -1,11 +1,9 @@
-# -*- coding: utf-8 -*-
# Copyright 2020 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Module for manipulating llvm-project-copy. Generally intended for tests."""
-
import datetime
import os
import subprocess
@@ -21,7 +19,7 @@ def get_location() -> str:
return os.path.join(my_dir, "llvm-project-copy")
-def ensure_up_to_date():
+def ensure_up_to_date() -> None:
"""Ensures that llvm-project-copy is checked out and semi-up-to-date."""
checkout = get_location()
diff --git a/llvm_tools/manifest_utils.py b/llvm_tools/manifest_utils.py
index 67eae4f3..3d6337bf 100644
--- a/llvm_tools/manifest_utils.py
+++ b/llvm_tools/manifest_utils.py
@@ -11,6 +11,7 @@ on toolchain projects (llvm-project, etc.) which are public.
from pathlib import Path
import shutil
import subprocess
+from typing import List, Union
from xml.etree import ElementTree
import atomic_write_file
@@ -22,14 +23,10 @@ LLVM_PROJECT_PATH = "src/third_party/llvm-project"
class FormattingError(Exception):
"""Error occurred when formatting the manifest."""
- pass
-
class UpdateManifestError(Exception):
"""Error occurred when updating the manifest."""
- pass
-
def make_xmlparser():
"""Return a new xmlparser with custom TreeBuilder."""
@@ -64,7 +61,7 @@ def update_chromeos_manifest(revision: str, src_tree: Path) -> Path:
xmltree = ElementTree.parse(manifest_path, parser)
update_chromeos_manifest_tree(revision, xmltree.getroot())
with atomic_write_file.atomic_write(manifest_path, mode="wb") as f:
- xmltree.write(f, encoding="UTF-8")
+ xmltree.write(f, encoding="utf-8")
format_manifest(manifest_path)
return manifest_path
@@ -99,5 +96,5 @@ def format_manifest(repo_manifest: Path):
raise FormattingError(
"unable to format manifest, 'cros'" " executable not in PATH"
)
- cmd = ["cros", "format", repo_manifest]
+ cmd: List[Union[str, Path]] = ["cros", "format", repo_manifest]
subprocess.run(cmd, check=True)
diff --git a/llvm_tools/manifest_utils_unittest.py b/llvm_tools/manifest_utils_unittest.py
index 9a21d990..8e283e34 100644..100755
--- a/llvm_tools/manifest_utils_unittest.py
+++ b/llvm_tools/manifest_utils_unittest.py
@@ -1,22 +1,20 @@
+#!/usr/bin/env python3
# Copyright 2023 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-import io
-from pathlib import Path
-import re
-import unittest
-from xml.etree import ElementTree
-
-import manifest_utils
-
-
"""Provides utilities to read and edit the ChromiumOS Manifest entries.
While this code reads and edits the internal manifest, it should only operate
on toolchain projects (llvm-project, etc.) which are public.
"""
+import unittest
+from xml.etree import ElementTree
+
+import manifest_utils
+
+
MANIFEST_FIXTURE = """<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<!-- Comment that should not be removed.
diff --git a/llvm_tools/modify_a_tryjob.py b/llvm_tools/modify_a_tryjob.py
index 2ecca800..e5b583c3 100755
--- a/llvm_tools/modify_a_tryjob.py
+++ b/llvm_tools/modify_a_tryjob.py
@@ -5,17 +5,18 @@
"""Modifies a tryjob based off of arguments."""
-
import argparse
import enum
import json
import os
from pathlib import Path
import sys
+from typing import Dict, Iterable, List, Union
import chroot
import failure_modes
import get_llvm_hash
+import git
import update_chromeos_llvm_hash
import update_packages_and_run_tests
import update_tryjob_status
@@ -29,7 +30,7 @@ class ModifyTryjob(enum.Enum):
ADD = "add"
-def GetCommandLineArgs():
+def GetCommandLineArgs() -> argparse.Namespace:
"""Parses the command line for the command line arguments."""
# Default path to the chroot if a path is not specified.
@@ -97,14 +98,6 @@ def GetCommandLineArgs():
help="the path to the chroot (default: %(default)s)",
)
- # Add argument for whether to display command contents to `stdout`.
- parser.add_argument(
- "--verbose",
- action="store_true",
- help="display contents of a command to the terminal "
- "(default: %(default)s)",
- )
-
args_output = parser.parse_args()
if not os.path.isfile(
@@ -132,12 +125,12 @@ def GetCommandLineArgs():
def GetCLAfterUpdatingPackages(
- packages,
- git_hash,
- svn_version,
- chroot_path,
- svn_option,
-):
+ packages: Iterable[str],
+ git_hash: str,
+ svn_version: int,
+ chroot_path: Union[Path, str],
+ svn_option: Union[int, str],
+) -> git.CommitContents:
"""Updates the packages' LLVM_NEXT."""
change_list = update_chromeos_llvm_hash.UpdatePackages(
@@ -149,9 +142,12 @@ def GetCLAfterUpdatingPackages(
chroot_path=Path(chroot_path),
mode=failure_modes.FailureModes.DISABLE_PATCHES,
git_hash_source=svn_option,
- extra_commit_msg=None,
+ extra_commit_msg_lines=None,
)
+ # We are calling UpdatePackages with upload_changes=True, in
+ # which case it should always return a git.CommitContents value.
+ assert change_list is not None
print("\nSuccessfully updated packages to %d" % svn_version)
print("Gerrit URL: %s" % change_list.url)
print("Change list number: %d" % change_list.cl_number)
@@ -160,8 +156,14 @@ def GetCLAfterUpdatingPackages(
def CreateNewTryjobEntryForBisection(
- cl, extra_cls, options, builder, chroot_path, cl_url, revision
-):
+ cl: int,
+ extra_cls: List[int],
+ options: List[str],
+ builder: str,
+ chroot_path: Union[Path, str],
+ cl_url: str,
+ revision,
+) -> Dict:
"""Submits a tryjob and adds additional information."""
# Get the tryjob results after submitting the tryjob.
@@ -193,20 +195,17 @@ def CreateNewTryjobEntryForBisection(
def AddTryjob(
- packages,
- git_hash,
- revision,
- chroot_path,
- extra_cls,
- options,
- builder,
- verbose,
- svn_option,
+ packages: Iterable[str],
+ git_hash: str,
+ revision: int,
+ chroot_path: Union[Path, str],
+ extra_cls: List[int],
+ options: List[str],
+ builder: str,
+ svn_option: Union[int, str],
):
"""Submits a tryjob."""
- update_chromeos_llvm_hash.verbose = verbose
-
change_list = GetCLAfterUpdatingPackages(
packages,
git_hash,
@@ -229,15 +228,14 @@ def AddTryjob(
def PerformTryjobModification(
- revision,
- modify_tryjob,
- status_file,
- extra_cls,
- options,
- builder,
- chroot_path,
- verbose,
-):
+ revision: int,
+ modify_tryjob: ModifyTryjob,
+ status_file: Union[Path, str],
+ extra_cls: List[int],
+ options: List[str],
+ builder: str,
+ chroot_path: Union[Path, str],
+) -> None:
"""Removes, relaunches, or adds a tryjob.
Args:
@@ -250,8 +248,6 @@ def PerformTryjobModification(
builder: The builder to use for 'cros tryjob'.
chroot_path: The absolute path to the chroot (used by 'cros tryjob'
when relaunching a tryjob).
- verbose: Determines whether to print the contents of a command to
- `stdout`.
"""
# Format of 'bisect_contents':
@@ -321,7 +317,6 @@ def PerformTryjobModification(
# Make sure the revision is within the bounds of the start and end of
# the bisection.
elif bisect_contents["start"] < revision < bisect_contents["end"]:
-
(
git_hash,
revision,
@@ -335,7 +330,6 @@ def PerformTryjobModification(
extra_cls,
options,
builder,
- verbose,
revision,
)
@@ -355,7 +349,7 @@ def PerformTryjobModification(
)
-def main():
+def main() -> None:
"""Removes, relaunches, or adds a tryjob."""
chroot.VerifyOutsideChroot()
@@ -372,7 +366,6 @@ def main():
args_output.options,
args_output.builder,
args_output.chroot_path,
- args_output.verbose,
)
diff --git a/llvm_tools/modify_a_tryjob_unittest.py b/llvm_tools/modify_a_tryjob_unittest.py
index 712e2614..8b72ffd7 100755
--- a/llvm_tools/modify_a_tryjob_unittest.py
+++ b/llvm_tools/modify_a_tryjob_unittest.py
@@ -1,15 +1,13 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Tests for modifying a tryjob."""
-
import json
import unittest
-import unittest.mock as mock
+from unittest import mock
import get_llvm_hash
import modify_a_tryjob
@@ -24,10 +22,10 @@ class ModifyATryjobTest(unittest.TestCase):
def testNoTryjobsInStatusFile(self):
bisect_test_contents = {"start": 369410, "end": 369420, "jobs": []}
- # Create a temporary .JSON file to simulate a .JSON file that has bisection
- # contents.
+ # Create a temporary .JSON file to simulate a .JSON file that has
+ # bisection contents.
with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as f:
+ with open(temp_json_file, "w", encoding="utf-8") as f:
test_helpers.WritePrettyJsonFile(bisect_test_contents, f)
revision_to_modify = 369411
@@ -36,8 +34,8 @@ class ModifyATryjobTest(unittest.TestCase):
args_output.builders = None
args_output.options = None
- # Verify the exception is raised there are no tryjobs in the status file
- # and the mode is not to 'add' a tryjob.
+ # Verify the exception is raised there are no tryjobs in the status
+ # file and the mode is not to 'add' a tryjob.
with self.assertRaises(SystemExit) as err:
modify_a_tryjob.PerformTryjobModification(
revision_to_modify,
@@ -47,7 +45,6 @@ class ModifyATryjobTest(unittest.TestCase):
args_output.options,
args_output.builders,
args_output.chroot_path,
- args_output.verbose,
)
self.assertEqual(
@@ -68,10 +65,10 @@ class ModifyATryjobTest(unittest.TestCase):
],
}
- # Create a temporary .JSON file to simulate a .JSON file that has bisection
- # contents.
+ # Create a temporary .JSON file to simulate a .JSON file that has
+ # bisection contents.
with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as f:
+ with open(temp_json_file, "w", encoding="utf-8") as f:
test_helpers.WritePrettyJsonFile(bisect_test_contents, f)
revision_to_modify = 369412
@@ -80,8 +77,9 @@ class ModifyATryjobTest(unittest.TestCase):
args_output.builders = None
args_output.options = None
- # Verify the exception is raised when the index of the tryjob was not
- # found in the status file and the mode is not to 'add' a tryjob.
+ # Verify the exception is raised when the index of the tryjob was
+ # not found in the status file and the mode is not to 'add' a
+ # tryjob.
with self.assertRaises(ValueError) as err:
modify_a_tryjob.PerformTryjobModification(
revision_to_modify,
@@ -91,7 +89,6 @@ class ModifyATryjobTest(unittest.TestCase):
args_output.options,
args_output.builders,
args_output.chroot_path,
- args_output.verbose,
)
self.assertEqual(
@@ -114,10 +111,10 @@ class ModifyATryjobTest(unittest.TestCase):
],
}
- # Create a temporary .JSON file to simulate a .JSON file that has bisection
- # contents.
+ # Create a temporary .JSON file to simulate a .JSON file that has
+ # bisection contents.
with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as f:
+ with open(temp_json_file, "w", encoding="utf-8") as f:
test_helpers.WritePrettyJsonFile(bisect_test_contents, f)
revision_to_modify = 369414
@@ -134,11 +131,10 @@ class ModifyATryjobTest(unittest.TestCase):
args_output.options,
args_output.builders,
args_output.chroot_path,
- args_output.verbose,
)
# Verify that the tryjob was removed from the status file.
- with open(temp_json_file) as status_file:
+ with open(temp_json_file, encoding="utf-8") as status_file:
bisect_contents = json.load(status_file)
expected_file_contents = {
@@ -160,7 +156,6 @@ class ModifyATryjobTest(unittest.TestCase):
def testSuccessfullyRelaunchedTryjob(
self, mock_find_tryjob_index, mock_run_tryjob
):
-
bisect_test_contents = {
"start": 369410,
"end": 369420,
@@ -184,10 +179,10 @@ class ModifyATryjobTest(unittest.TestCase):
mock_run_tryjob.return_value = tryjob_result
- # Create a temporary .JSON file to simulate a .JSON file that has bisection
- # contents.
+ # Create a temporary .JSON file to simulate a .JSON file that has
+ # bisection contents.
with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as f:
+ with open(temp_json_file, "w", encoding="utf-8") as f:
test_helpers.WritePrettyJsonFile(bisect_test_contents, f)
revision_to_modify = 369411
@@ -204,12 +199,11 @@ class ModifyATryjobTest(unittest.TestCase):
args_output.options,
args_output.builders,
args_output.chroot_path,
- args_output.verbose,
)
- # Verify that the tryjob's information was updated after submtting the
- # tryjob.
- with open(temp_json_file) as status_file:
+ # Verify that the tryjob's information was updated after submtting
+ # the tryjob.
+ with open(temp_json_file, encoding="utf-8") as status_file:
bisect_contents = json.load(status_file)
expected_file_contents = {
@@ -247,10 +241,10 @@ class ModifyATryjobTest(unittest.TestCase):
],
}
- # Create a temporary .JSON file to simulate a .JSON file that has bisection
- # contents.
+ # Create a temporary .JSON file to simulate a .JSON file that has
+ # bisection contents.
with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as f:
+ with open(temp_json_file, "w", encoding="utf-8") as f:
test_helpers.WritePrettyJsonFile(bisect_test_contents, f)
revision_to_add = 369411
@@ -261,8 +255,8 @@ class ModifyATryjobTest(unittest.TestCase):
args_output = test_helpers.ArgsOutputTest()
args_output.options = None
- # Verify the exception is raised when the tryjob that is going to added
- # already exists in the status file (found its index).
+ # Verify the exception is raised when the tryjob that is going to
+ # added already exists in the status file (found its index).
with self.assertRaises(ValueError) as err:
modify_a_tryjob.PerformTryjobModification(
revision_to_add,
@@ -272,7 +266,6 @@ class ModifyATryjobTest(unittest.TestCase):
args_output.options,
args_output.builders,
args_output.chroot_path,
- args_output.verbose,
)
self.assertEqual(
@@ -283,24 +276,24 @@ class ModifyATryjobTest(unittest.TestCase):
mock_find_tryjob_index.assert_called_once()
- # Simulate the behavior of `FindTryjobIndex()` when the tryjob was not found.
+ # Simulate the behavior of `FindTryjobIndex()` when the tryjob was not
+ # found.
@mock.patch.object(
update_tryjob_status, "FindTryjobIndex", return_value=None
)
def testSuccessfullyDidNotAddTryjobOutsideOfBisectionBounds(
self, mock_find_tryjob_index
):
-
bisect_test_contents = {
"start": 369410,
"end": 369420,
"jobs": [{"rev": 369411, "status": "bad"}],
}
- # Create a temporary .JSON file to simulate a .JSON file that has bisection
- # contents.
+ # Create a temporary .JSON file to simulate a .JSON file that has
+ # bisection contents.
with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as f:
+ with open(temp_json_file, "w", encoding="utf-8") as f:
test_helpers.WritePrettyJsonFile(bisect_test_contents, f)
# Add a revision that is outside of 'start' and 'end'.
@@ -309,8 +302,8 @@ class ModifyATryjobTest(unittest.TestCase):
args_output = test_helpers.ArgsOutputTest()
args_output.options = None
- # Verify the exception is raised when adding a tryjob that does not exist
- # and is not within 'start' and 'end'.
+ # Verify the exception is raised when adding a tryjob that does not
+ # exist and is not within 'start' and 'end'.
with self.assertRaises(ValueError) as err:
modify_a_tryjob.PerformTryjobModification(
revision_to_add,
@@ -320,7 +313,6 @@ class ModifyATryjobTest(unittest.TestCase):
args_output.options,
args_output.builders,
args_output.chroot_path,
- args_output.verbose,
)
self.assertEqual(
@@ -334,30 +326,31 @@ class ModifyATryjobTest(unittest.TestCase):
# tryjob and constructed the tryjob information (a dictionary).
@mock.patch.object(modify_a_tryjob, "AddTryjob")
# Simulate the behavior of `GetLLVMHashAndVersionFromSVNOption()` when
- # successfully retrieved the git hash of the revision to launch a tryjob for.
+ # successfully retrieved the git hash of the revision to launch a tryjob
+ # for.
@mock.patch.object(
get_llvm_hash,
"GetLLVMHashAndVersionFromSVNOption",
return_value=("a123testhash1", 369418),
)
- # Simulate the behavior of `FindTryjobIndex()` when the tryjob was not found.
+ # Simulate the behavior of `FindTryjobIndex()` when the tryjob was not
+ # found.
@mock.patch.object(
update_tryjob_status, "FindTryjobIndex", return_value=None
)
def testSuccessfullyAddedTryjob(
self, mock_find_tryjob_index, mock_get_llvm_hash, mock_add_tryjob
):
-
bisect_test_contents = {
"start": 369410,
"end": 369420,
"jobs": [{"rev": 369411, "status": "bad"}],
}
- # Create a temporary .JSON file to simulate a .JSON file that has bisection
- # contents.
+ # Create a temporary .JSON file to simulate a .JSON file that has
+ # bisection contents.
with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as f:
+ with open(temp_json_file, "w", encoding="utf-8") as f:
test_helpers.WritePrettyJsonFile(bisect_test_contents, f)
# Add a revision that is outside of 'start' and 'end'.
@@ -384,11 +377,10 @@ class ModifyATryjobTest(unittest.TestCase):
args_output.options,
args_output.builders,
args_output.chroot_path,
- args_output.verbose,
)
# Verify that the tryjob was added to the status file.
- with open(temp_json_file) as status_file:
+ with open(temp_json_file, encoding="utf-8") as status_file:
bisect_contents = json.load(status_file)
expected_file_contents = {
@@ -414,10 +406,10 @@ class ModifyATryjobTest(unittest.TestCase):
"jobs": [{"rev": 369414, "status": "bad"}],
}
- # Create a temporary .JSON file to simulate a .JSON file that has bisection
- # contents.
+ # Create a temporary .JSON file to simulate a .JSON file that has
+ # bisection contents.
with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as f:
+ with open(temp_json_file, "w", encoding="utf-8") as f:
test_helpers.WritePrettyJsonFile(bisect_test_contents, f)
# Add a revision that is outside of 'start' and 'end'.
@@ -427,8 +419,8 @@ class ModifyATryjobTest(unittest.TestCase):
args_output.builders = None
args_output.options = None
- # Verify the exception is raised when the modify a tryjob option does not
- # exist.
+ # Verify the exception is raised when the modify a tryjob option
+ # does not exist.
with self.assertRaises(ValueError) as err:
modify_a_tryjob.PerformTryjobModification(
revision_to_modify,
@@ -438,7 +430,6 @@ class ModifyATryjobTest(unittest.TestCase):
args_output.options,
args_output.builders,
args_output.chroot_path,
- args_output.verbose,
)
self.assertEqual(
diff --git a/llvm_tools/nightly_revert_checker.py b/llvm_tools/nightly_revert_checker.py
index d12464a6..88aac9b7 100755
--- a/llvm_tools/nightly_revert_checker.py
+++ b/llvm_tools/nightly_revert_checker.py
@@ -1,5 +1,4 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2020 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -10,8 +9,8 @@ If any reverts are found that were previously unknown, this cherry-picks them or
fires off an email. All LLVM SHAs to monitor are autodetected.
"""
-
import argparse
+import dataclasses
import io
import json
import logging
@@ -19,22 +18,81 @@ import os
import pprint
import subprocess
import sys
-import typing as t
+import time
+from typing import Any, Callable, Dict, List, NamedTuple, Set, Tuple
-import cros_utils.email_sender as email_sender
-import cros_utils.tiny_render as tiny_render
+from cros_utils import email_sender
+from cros_utils import tiny_render
import get_llvm_hash
import get_upstream_patch
import git_llvm_rev
import revert_checker
-State = t.Any
+ONE_DAY_SECS = 24 * 60 * 60
+# How often to send an email about a HEAD not moving.
+HEAD_STALENESS_ALERT_INTERVAL_SECS = 21 * ONE_DAY_SECS
+# How long to wait after a HEAD changes for the first 'update' email to be sent.
+HEAD_STALENESS_ALERT_INITIAL_SECS = 60 * ONE_DAY_SECS
+
+
+# Not frozen, as `next_notification_timestamp` may be mutated.
+@dataclasses.dataclass(frozen=False, eq=True)
+class HeadInfo:
+ """Information about about a HEAD that's tracked by this script."""
+
+ # The most recent SHA observed for this HEAD.
+ last_sha: str
+ # The time at which the current value for this HEAD was first seen.
+ first_seen_timestamp: int
+ # The next timestamp to notify users if this HEAD doesn't move.
+ next_notification_timestamp: int
+
+ @classmethod
+ def from_json(cls, json_object: Any) -> "HeadInfo":
+ return cls(**json_object)
+
+ def to_json(self) -> Any:
+ return dataclasses.asdict(self)
+
+
+@dataclasses.dataclass(frozen=True, eq=True)
+class State:
+ """Persistent state for this script."""
+
+ # Mapping of LLVM SHA -> List of reverts that have been seen for it
+ seen_reverts: Dict[str, List[str]] = dataclasses.field(default_factory=dict)
+ # Mapping of friendly HEAD name (e.g., main-legacy) to last-known info
+ # about it.
+ heads: Dict[str, HeadInfo] = dataclasses.field(default_factory=dict)
+
+ @classmethod
+ def from_json(cls, json_object: Any) -> "State":
+ # Autoupgrade old JSON files.
+ if "heads" not in json_object:
+ json_object = {
+ "seen_reverts": json_object,
+ "heads": {},
+ }
+
+ return cls(
+ seen_reverts=json_object["seen_reverts"],
+ heads={
+ k: HeadInfo.from_json(v)
+ for k, v in json_object["heads"].items()
+ },
+ )
+
+ def to_json(self) -> Any:
+ return {
+ "seen_reverts": self.seen_reverts,
+ "heads": {k: v.to_json() for k, v in self.heads.items()},
+ }
def _find_interesting_android_shas(
android_llvm_toolchain_dir: str,
-) -> t.List[t.Tuple[str, str]]:
+) -> List[Tuple[str, str]]:
llvm_project = os.path.join(
android_llvm_toolchain_dir, "toolchain/llvm-project"
)
@@ -60,7 +118,7 @@ def _find_interesting_android_shas(
main_legacy = get_llvm_merge_base("aosp/master-legacy") # nocheck
testing_upstream = get_llvm_merge_base("aosp/testing-upstream")
- result = [("main-legacy", main_legacy)]
+ result: List[Tuple[str, str]] = [("main-legacy", main_legacy)]
# If these are the same SHA, there's no point in tracking both.
if main_legacy != testing_upstream:
@@ -75,7 +133,7 @@ def _find_interesting_android_shas(
def _parse_llvm_ebuild_for_shas(
ebuild_file: io.TextIOWrapper,
-) -> t.List[t.Tuple[str, str]]:
+) -> List[Tuple[str, str]]:
def parse_ebuild_assignment(line: str) -> str:
no_comments = line.split("#")[0]
no_assign = no_comments.split("=", 1)[1].strip()
@@ -98,7 +156,7 @@ def _parse_llvm_ebuild_for_shas(
"llvm=%s; llvm_next=%s" % (llvm_hash, llvm_next_hash)
)
- results = [("llvm", llvm_hash)]
+ results: List[Tuple[str, str]] = [("llvm", llvm_hash)]
if llvm_next_hash != llvm_hash:
results.append(("llvm-next", llvm_next_hash))
return results
@@ -106,7 +164,7 @@ def _parse_llvm_ebuild_for_shas(
def _find_interesting_chromeos_shas(
chromeos_base: str,
-) -> t.List[t.Tuple[str, str]]:
+) -> List[Tuple[str, str]]:
llvm_dir = os.path.join(
chromeos_base, "src/third_party/chromiumos-overlay/sys-devel/llvm"
)
@@ -126,7 +184,7 @@ def _find_interesting_chromeos_shas(
return _parse_llvm_ebuild_for_shas(f)
-_Email = t.NamedTuple(
+_Email = NamedTuple(
"_Email",
[
("subject", str),
@@ -139,9 +197,9 @@ def _generate_revert_email(
repository_name: str,
friendly_name: str,
sha: str,
- prettify_sha: t.Callable[[str], tiny_render.Piece],
- get_sha_description: t.Callable[[str], tiny_render.Piece],
- new_reverts: t.List[revert_checker.Revert],
+ prettify_sha: Callable[[str], tiny_render.Piece],
+ get_sha_description: Callable[[str], tiny_render.Piece],
+ new_reverts: List[revert_checker.Revert],
) -> _Email:
email_pieces = [
"It looks like there may be %s across %s ("
@@ -184,11 +242,11 @@ def _generate_revert_email(
)
-_EmailRecipients = t.NamedTuple(
+_EmailRecipients = NamedTuple(
"_EmailRecipients",
[
- ("well_known", t.List[str]),
- ("direct", t.List[str]),
+ ("well_known", List[str]),
+ ("direct", List[str]),
],
)
@@ -205,11 +263,15 @@ def _send_revert_email(recipients: _EmailRecipients, email: _Email) -> None:
def _write_state(state_file: str, new_state: State) -> None:
+ tmp_file = state_file + ".new"
try:
- tmp_file = state_file + ".new"
with open(tmp_file, "w", encoding="utf-8") as f:
json.dump(
- new_state, f, sort_keys=True, indent=2, separators=(",", ": ")
+ new_state.to_json(),
+ f,
+ sort_keys=True,
+ indent=2,
+ separators=(",", ": "),
)
os.rename(tmp_file, state_file)
except:
@@ -222,22 +284,33 @@ def _write_state(state_file: str, new_state: State) -> None:
def _read_state(state_file: str) -> State:
try:
- with open(state_file) as f:
- return json.load(f)
+ with open(state_file, encoding="utf-8") as f:
+ return State.from_json(json.load(f))
except FileNotFoundError:
logging.info(
"No state file found at %r; starting with an empty slate",
state_file,
)
- return {}
+ return State()
+
+@dataclasses.dataclass(frozen=True)
+class NewRevertInfo:
+ """A list of new reverts for a given SHA."""
-def find_shas(
+ friendly_name: str
+ sha: str
+ new_reverts: List[revert_checker.Revert]
+
+
+def locate_new_reverts_across_shas(
llvm_dir: str,
- interesting_shas: t.List[t.Tuple[str, str]],
+ interesting_shas: List[Tuple[str, str]],
state: State,
- new_state: State,
-):
+) -> Tuple[State, List[NewRevertInfo]]:
+ """Locates and returns yet-unseen reverts across `interesting_shas`."""
+ new_state = State()
+ revert_infos = []
for friendly_name, sha in interesting_shas:
logging.info("Finding reverts across %s (%s)", friendly_name, sha)
all_reverts = revert_checker.find_reverts(
@@ -249,42 +322,72 @@ def find_shas(
pprint.pformat(all_reverts),
)
- new_state[sha] = [r.sha for r in all_reverts]
+ new_state.seen_reverts[sha] = [r.sha for r in all_reverts]
- if sha not in state:
+ if sha not in state.seen_reverts:
logging.info("SHA %s is new to me", sha)
existing_reverts = set()
else:
- existing_reverts = set(state[sha])
+ existing_reverts = set(state.seen_reverts[sha])
new_reverts = [r for r in all_reverts if r.sha not in existing_reverts]
if not new_reverts:
logging.info("...All of which have been reported.")
continue
- yield (friendly_name, sha, new_reverts)
+ new_head_info = None
+ if old_head_info := state.heads.get(friendly_name):
+ if old_head_info.last_sha == sha:
+ new_head_info = old_head_info
+
+ if new_head_info is None:
+ now = int(time.time())
+ notify_at = HEAD_STALENESS_ALERT_INITIAL_SECS + now
+ new_head_info = HeadInfo(
+ last_sha=sha,
+ first_seen_timestamp=now,
+ next_notification_timestamp=notify_at,
+ )
+ new_state.heads[friendly_name] = new_head_info
+
+ revert_infos.append(
+ NewRevertInfo(
+ friendly_name=friendly_name,
+ sha=sha,
+ new_reverts=new_reverts,
+ )
+ )
+ return new_state, revert_infos
def do_cherrypick(
chroot_path: str,
llvm_dir: str,
- interesting_shas: t.List[t.Tuple[str, str]],
+ repository: str,
+ interesting_shas: List[Tuple[str, str]],
state: State,
- reviewers: t.List[str],
- cc: t.List[str],
+ reviewers: List[str],
+ cc: List[str],
) -> State:
- new_state: State = {}
- seen: t.Set[str] = set()
- for friendly_name, _sha, reverts in find_shas(
- llvm_dir, interesting_shas, state, new_state
- ):
- if friendly_name in seen:
+ def prettify_sha(sha: str) -> tiny_render.Piece:
+ rev = get_llvm_hash.GetVersionFrom(llvm_dir, sha)
+ return prettify_sha_for_email(sha, rev)
+
+ new_state = State()
+ seen: Set[str] = set()
+
+ new_state, new_reverts = locate_new_reverts_across_shas(
+ llvm_dir, interesting_shas, state
+ )
+
+ for revert_info in new_reverts:
+ if revert_info.friendly_name in seen:
continue
- seen.add(friendly_name)
- for sha, reverted_sha in reverts:
+ seen.add(revert_info.friendly_name)
+ for sha, reverted_sha in revert_info.new_reverts:
try:
- # We upload reverts for all platforms by default, since there's no
- # real reason for them to be CrOS-specific.
+ # We upload reverts for all platforms by default, since there's
+ # no real reason for them to be CrOS-specific.
get_upstream_patch.get_from_upstream(
chroot_path=chroot_path,
create_cl=True,
@@ -296,28 +399,114 @@ def do_cherrypick(
)
except get_upstream_patch.CherrypickError as e:
logging.info("%s, skipping...", str(e))
+
+ maybe_email_about_stale_heads(
+ new_state,
+ repository,
+ recipients=_EmailRecipients(
+ well_known=[],
+ direct=reviewers + cc,
+ ),
+ prettify_sha=prettify_sha,
+ is_dry_run=False,
+ )
return new_state
+def prettify_sha_for_email(
+ sha: str,
+ rev: int,
+) -> tiny_render.Piece:
+ """Returns a piece of an email representing the given sha and its rev."""
+ # 12 is arbitrary, but should be unambiguous enough.
+ short_sha = sha[:12]
+ return tiny_render.Switch(
+ text=f"r{rev} ({short_sha})",
+ html=tiny_render.Link(
+ href=f"https://github.com/llvm/llvm-project/commit/{sha}",
+ inner=f"r{rev}",
+ ),
+ )
+
+
+def maybe_email_about_stale_heads(
+ new_state: State,
+ repository_name: str,
+ recipients: _EmailRecipients,
+ prettify_sha: Callable[[str], tiny_render.Piece],
+ is_dry_run: bool,
+) -> bool:
+ """Potentially send an email about stale HEADs in `new_state`.
+
+ These emails are sent to notify users of the current HEADs detected by this
+ script. They:
+ - aren't meant to hurry LLVM rolls along,
+ - are worded to avoid the implication that an LLVM roll is taking an
+ excessive amount of time, and
+ - are initially sent at the 2 month point of seeing the same HEAD.
+
+ We've had multiple instances in the past of upstream changes (e.g., moving
+ to other git branches or repos) leading to this revert checker silently
+ checking a very old HEAD for months. The intent is to send emails when the
+ correctness of the HEADs we're working with _might_ be wrong.
+ """
+ logging.info("Checking HEAD freshness...")
+ now = int(time.time())
+ stale = sorted(
+ (name, info)
+ for name, info in new_state.heads.items()
+ if info.next_notification_timestamp <= now
+ )
+ if not stale:
+ logging.info("All HEADs are fresh-enough; no need to send an email.")
+ return False
+
+ stale_listings = []
+
+ for name, info in stale:
+ days = (now - info.first_seen_timestamp) // ONE_DAY_SECS
+ pretty_rev = prettify_sha(info.last_sha)
+ stale_listings.append(
+ f"{name} at {pretty_rev}, which was last updated ~{days} days ago."
+ )
+
+ shas_are = "SHAs are" if len(stale_listings) > 1 else "SHA is"
+ email_body = [
+ "Hi! This is a friendly notification that the current upstream LLVM "
+ f"{shas_are} being tracked by the LLVM revert checker:",
+ tiny_render.UnorderedList(stale_listings),
+ tiny_render.line_break,
+ "If that's still correct, great! If it looks wrong, the revert "
+ "checker's SHA autodetection may need an update. Please file a bug "
+ "at go/crostc-bug if an update is needed. Thanks!",
+ ]
+
+ email = _Email(
+ subject=f"[revert-checker/{repository_name}] Tracked branch update",
+ body=email_body,
+ )
+ if is_dry_run:
+ logging.info("Dry-run specified; would otherwise send email %s", email)
+ else:
+ _send_revert_email(recipients, email)
+
+ next_notification = now + HEAD_STALENESS_ALERT_INTERVAL_SECS
+ for _, info in stale:
+ info.next_notification_timestamp = next_notification
+ return True
+
+
def do_email(
is_dry_run: bool,
llvm_dir: str,
repository: str,
- interesting_shas: t.List[t.Tuple[str, str]],
+ interesting_shas: List[Tuple[str, str]],
state: State,
recipients: _EmailRecipients,
) -> State:
def prettify_sha(sha: str) -> tiny_render.Piece:
rev = get_llvm_hash.GetVersionFrom(llvm_dir, sha)
-
- # 12 is arbitrary, but should be unambiguous enough.
- short_sha = sha[:12]
- return tiny_render.Switch(
- text=f"r{rev} ({short_sha})",
- html=tiny_render.Link(
- href="https://reviews.llvm.org/rG" + sha, inner="r" + str(rev)
- ),
- )
+ return prettify_sha_for_email(sha, rev)
def get_sha_description(sha: str) -> tiny_render.Piece:
return subprocess.check_output(
@@ -326,17 +515,18 @@ def do_email(
encoding="utf-8",
).strip()
- new_state: State = {}
- for friendly_name, sha, new_reverts in find_shas(
- llvm_dir, interesting_shas, state, new_state
- ):
+ new_state, new_reverts = locate_new_reverts_across_shas(
+ llvm_dir, interesting_shas, state
+ )
+
+ for revert_info in new_reverts:
email = _generate_revert_email(
repository,
- friendly_name,
- sha,
+ revert_info.friendly_name,
+ revert_info.sha,
prettify_sha,
get_sha_description,
- new_reverts,
+ revert_info.new_reverts,
)
if is_dry_run:
logging.info(
@@ -348,10 +538,14 @@ def do_email(
logging.info("Sending email with subject %r...", email.subject)
_send_revert_email(recipients, email)
logging.info("Email sent.")
+
+ maybe_email_about_stale_heads(
+ new_state, repository, recipients, prettify_sha, is_dry_run
+ )
return new_state
-def parse_args(argv: t.List[str]) -> t.Any:
+def parse_args(argv: List[str]) -> argparse.Namespace:
parser = argparse.ArgumentParser(
description=__doc__,
formatter_class=argparse.RawDescriptionHelpFormatter,
@@ -373,15 +567,19 @@ def parse_args(argv: t.List[str]) -> t.Any:
"--reviewers",
type=str,
nargs="*",
- help="Requests reviews from REVIEWERS. All REVIEWERS must have existing "
- "accounts.",
+ help="""
+ Requests reviews from REVIEWERS. All REVIEWERS must have existing
+ accounts.
+ """,
)
parser.add_argument(
"--cc",
type=str,
nargs="*",
- help="CCs the CL to the recipients. All recipients must have existing "
- "accounts.",
+ help="""
+ CCs the CL or email to the recipients. If in cherry-pick mode, all
+ recipients must have Gerrit accounts.
+ """,
)
subparsers = parser.add_subparsers(dest="repository")
@@ -405,15 +603,14 @@ def parse_args(argv: t.List[str]) -> t.Any:
def find_chroot(
- opts: t.Any, reviewers: t.List[str], cc: t.List[str]
-) -> t.Tuple[str, t.List[t.Tuple[str, str]], _EmailRecipients]:
- recipients = reviewers + cc
+ opts: argparse.Namespace, cc: List[str]
+) -> Tuple[str, List[Tuple[str, str]], _EmailRecipients]:
if opts.repository == "chromeos":
chroot_path = opts.chromeos_dir
return (
chroot_path,
_find_interesting_chromeos_shas(chroot_path),
- _EmailRecipients(well_known=["mage"], direct=recipients),
+ _EmailRecipients(well_known=["mage"], direct=cc),
)
elif opts.repository == "android":
if opts.action == "cherry-pick":
@@ -427,18 +624,19 @@ def find_chroot(
_find_interesting_android_shas(chroot_path),
_EmailRecipients(
well_known=[],
- direct=["android-llvm-dev@google.com"] + recipients,
+ direct=["android-llvm-dev@google.com"] + cc,
),
)
else:
raise ValueError(f"Unknown repository {opts.repository}")
-def main(argv: t.List[str]) -> int:
+def main(argv: List[str]) -> int:
opts = parse_args(argv)
logging.basicConfig(
- format="%(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: %(message)s",
+ format="%(asctime)s: %(levelname)s: "
+ "%(filename)s:%(lineno)d: %(message)s",
level=logging.DEBUG if opts.debug else logging.INFO,
)
@@ -449,18 +647,19 @@ def main(argv: t.List[str]) -> int:
reviewers = opts.reviewers if opts.reviewers else []
cc = opts.cc if opts.cc else []
- chroot_path, interesting_shas, recipients = find_chroot(opts, reviewers, cc)
+ chroot_path, interesting_shas, recipients = find_chroot(opts, cc)
logging.info("Interesting SHAs were %r", interesting_shas)
state = _read_state(state_file)
logging.info("Loaded state\n%s", pprint.pformat(state))
- # We want to be as free of obvious side-effects as possible in case something
- # above breaks. Hence, action as late as possible.
+ # We want to be as free of obvious side-effects as possible in case
+ # something above breaks. Hence, action as late as possible.
if action == "cherry-pick":
new_state = do_cherrypick(
chroot_path=chroot_path,
llvm_dir=llvm_dir,
+ repository=repository,
interesting_shas=interesting_shas,
state=state,
reviewers=reviewers,
@@ -470,8 +669,8 @@ def main(argv: t.List[str]) -> int:
new_state = do_email(
is_dry_run=action == "dry-run",
llvm_dir=llvm_dir,
- repository=repository,
interesting_shas=interesting_shas,
+ repository=repository,
state=state,
recipients=recipients,
)
diff --git a/llvm_tools/nightly_revert_checker_test.py b/llvm_tools/nightly_revert_checker_test.py
index 86b7898a..722ad125 100755
--- a/llvm_tools/nightly_revert_checker_test.py
+++ b/llvm_tools/nightly_revert_checker_test.py
@@ -1,17 +1,15 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2020 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Tests for nightly_revert_checker."""
-
import io
import unittest
-from unittest.mock import patch
+from unittest import mock
-import cros_utils.tiny_render as tiny_render
+from cros_utils import tiny_render
import get_upstream_patch
import nightly_revert_checker
import revert_checker
@@ -44,7 +42,8 @@ class Test(unittest.TestCase):
)
expected_email = nightly_revert_checker._Email(
- subject="[revert-checker/${repo}] new revert discovered across ${name}",
+ subject="[revert-checker/${repo}] new revert discovered across "
+ "${name}",
body=[
"It looks like there may be a new revert across ${name} (",
"pretty_${sha}",
@@ -176,8 +175,8 @@ class Test(unittest.TestCase):
self.assertIn("Failed to detect SHAs", str(e.exception))
- @patch("revert_checker.find_reverts")
- @patch("get_upstream_patch.get_from_upstream")
+ @mock.patch("revert_checker.find_reverts")
+ @mock.patch("get_upstream_patch.get_from_upstream")
def test_do_cherrypick_is_called(self, do_cherrypick, find_reverts):
find_reverts.return_value = [
revert_checker.Revert("12345abcdef", "fedcba54321")
@@ -185,8 +184,9 @@ class Test(unittest.TestCase):
nightly_revert_checker.do_cherrypick(
chroot_path="/path/to/chroot",
llvm_dir="/path/to/llvm",
+ repository="repository_name",
interesting_shas=[("12345abcdef", "fedcba54321")],
- state={},
+ state=nightly_revert_checker.State(),
reviewers=["meow@chromium.org"],
cc=["purr@chromium.org"],
)
@@ -194,8 +194,8 @@ class Test(unittest.TestCase):
do_cherrypick.assert_called_once()
find_reverts.assert_called_once()
- @patch("revert_checker.find_reverts")
- @patch("get_upstream_patch.get_from_upstream")
+ @mock.patch("revert_checker.find_reverts")
+ @mock.patch("get_upstream_patch.get_from_upstream")
def test_do_cherrypick_handles_cherrypick_error(
self, do_cherrypick, find_reverts
):
@@ -208,8 +208,9 @@ class Test(unittest.TestCase):
nightly_revert_checker.do_cherrypick(
chroot_path="/path/to/chroot",
llvm_dir="/path/to/llvm",
+ repository="repository_name",
interesting_shas=[("12345abcdef", "fedcba54321")],
- state={},
+ state=nightly_revert_checker.State(),
reviewers=["meow@chromium.org"],
cc=["purr@chromium.org"],
)
@@ -217,6 +218,128 @@ class Test(unittest.TestCase):
do_cherrypick.assert_called_once()
find_reverts.assert_called_once()
+ def test_sha_prettification_for_email(self):
+ sha = "a" * 40
+ rev = 123456
+ self.assertEqual(
+ nightly_revert_checker.prettify_sha_for_email(sha, rev),
+ tiny_render.Switch(
+ text=f"r{rev} ({sha[:12]})",
+ html=tiny_render.Link(
+ href=f"https://github.com/llvm/llvm-project/commit/{sha}",
+ inner=f"r{rev}",
+ ),
+ ),
+ )
+
+ @mock.patch("time.time")
+ def test_emailing_about_stale_heads_skips_in_simple_cases(self, time_time):
+ now = 1_000_000_000
+ time_time.return_value = now
+
+ def assert_no_email(state: nightly_revert_checker.State):
+ self.assertFalse(
+ nightly_revert_checker.maybe_email_about_stale_heads(
+ state,
+ repository_name="foo",
+ recipients=nightly_revert_checker._EmailRecipients(
+ well_known=[], direct=[]
+ ),
+ prettify_sha=lambda *args: self.fail(
+ "SHAs shouldn't be prettified"
+ ),
+ is_dry_run=True,
+ )
+ )
+
+ assert_no_email(nightly_revert_checker.State())
+ assert_no_email(
+ nightly_revert_checker.State(
+ heads={
+ "foo": nightly_revert_checker.HeadInfo(
+ last_sha="",
+ first_seen_timestamp=0,
+ next_notification_timestamp=now + 1,
+ ),
+ "bar": nightly_revert_checker.HeadInfo(
+ last_sha="",
+ first_seen_timestamp=0,
+ next_notification_timestamp=now * 2,
+ ),
+ }
+ )
+ )
+
+ def test_state_autoupgrades_from_json_properly(self):
+ state = nightly_revert_checker.State.from_json({"abc123": ["def456"]})
+ self.assertEqual(state.seen_reverts, {"abc123": ["def456"]})
+ self.assertEqual(state.heads, {})
+
+ def test_state_round_trips_through_json(self):
+ state = nightly_revert_checker.State(
+ seen_reverts={"abc123": ["def456"]},
+ heads={
+ "head_name": nightly_revert_checker.HeadInfo(
+ last_sha="abc",
+ first_seen_timestamp=123,
+ next_notification_timestamp=456,
+ ),
+ },
+ )
+ self.assertEqual(
+ state, nightly_revert_checker.State.from_json(state.to_json())
+ )
+
+ @mock.patch("time.time")
+ @mock.patch("nightly_revert_checker._send_revert_email")
+ def test_emailing_about_stale_with_one_report(
+ self, send_revert_email, time_time
+ ):
+ def prettify_sha(sha: str) -> str:
+ return f"pretty({sha})"
+
+ now = 1_000_000_000
+ two_days_ago = now - 2 * nightly_revert_checker.ONE_DAY_SECS
+ time_time.return_value = now
+ recipients = nightly_revert_checker._EmailRecipients(
+ well_known=[], direct=[]
+ )
+ self.assertTrue(
+ nightly_revert_checker.maybe_email_about_stale_heads(
+ nightly_revert_checker.State(
+ heads={
+ "foo": nightly_revert_checker.HeadInfo(
+ last_sha="<foo sha>",
+ first_seen_timestamp=two_days_ago,
+ next_notification_timestamp=now - 1,
+ ),
+ "bar": nightly_revert_checker.HeadInfo(
+ last_sha="",
+ first_seen_timestamp=0,
+ next_notification_timestamp=now + 1,
+ ),
+ }
+ ),
+ repository_name="repo",
+ recipients=recipients,
+ prettify_sha=prettify_sha,
+ is_dry_run=False,
+ )
+ )
+ send_revert_email.assert_called_once()
+ recipients, email = send_revert_email.call_args[0]
+
+ self.assertEqual(
+ tiny_render.render_text_pieces(email.body),
+ "Hi! This is a friendly notification that the current upstream "
+ "LLVM SHA is being tracked by the LLVM revert checker:\n"
+ " - foo at pretty(<foo sha>), which was last updated ~2 days "
+ "ago.\n"
+ "If that's still correct, great! If it looks wrong, the revert "
+ "checker's SHA autodetection may need an update. Please file a "
+ "bug at go/crostc-bug if an update is needed. Thanks!",
+ )
+
if __name__ == "__main__":
unittest.main()
diff --git a/llvm_tools/patch_manager.py b/llvm_tools/patch_manager.py
index 4d4e8385..33272286 100755
--- a/llvm_tools/patch_manager.py
+++ b/llvm_tools/patch_manager.py
@@ -10,12 +10,12 @@ import enum
import os
from pathlib import Path
import sys
-from typing import Iterable, List, Optional, Tuple
+from typing import Callable, Iterable, List, Optional, Tuple
-from failure_modes import FailureModes
+import failure_modes
import get_llvm_hash
import patch_utils
-from subprocess_helpers import check_output
+import subprocess_helpers
class GitBisectionCode(enum.IntEnum):
@@ -68,8 +68,8 @@ def GetCommandLineArgs(sys_argv: Optional[List[str]]):
# applicable patches.
parser.add_argument(
"--failure_mode",
- default=FailureModes.FAIL,
- type=FailureModes,
+ default=failure_modes.FailureModes.FAIL,
+ type=failure_modes.FailureModes,
help="the mode of the patch manager when handling failed patches "
"(default: %(default)s)",
)
@@ -80,20 +80,24 @@ def GetCommandLineArgs(sys_argv: Optional[List[str]]):
"application of. Not used in other modes.",
)
+ # Add argument for the option to us git am to commit patch or
+ # just using patch.
+ parser.add_argument(
+ "--git_am",
+ action="store_true",
+ help="If set, use 'git am' to patch instead of GNU 'patch'. ",
+ )
+
# Parse the command line.
return parser.parse_args(sys_argv)
def GetHEADSVNVersion(src_path):
"""Gets the SVN version of HEAD in the src tree."""
-
- cmd = ["git", "-C", src_path, "rev-parse", "HEAD"]
-
- git_hash = check_output(cmd)
-
- version = get_llvm_hash.GetVersionFrom(src_path, git_hash.rstrip())
-
- return version
+ git_hash = subprocess_helpers.check_output(
+ ["git", "-C", src_path, "rev-parse", "HEAD"]
+ )
+ return get_llvm_hash.GetVersionFrom(src_path, git_hash.rstrip())
def GetCommitHashesForBisection(src_path, good_svn_version, bad_svn_version):
@@ -111,6 +115,7 @@ def CheckPatchApplies(
llvm_src_dir: Path,
patches_json_fp: Path,
rel_patch_path: str,
+ patch_cmd: Optional[Callable] = None,
) -> GitBisectionCode:
"""Check that a given patch with the rel_patch_path applies in the stack.
@@ -120,11 +125,13 @@ def CheckPatchApplies(
to identify the SVN version
Args:
- svn_version: SVN version to test at.
- llvm_src_dir: llvm-project source code diroctory (with a .git).
- patches_json_fp: PATCHES.json filepath.
- rel_patch_path: Relative patch path of the patch we want to check. If
- patches before this patch fail to apply, then the revision is skipped.
+ svn_version: SVN version to test at.
+ llvm_src_dir: llvm-project source code diroctory (with a .git).
+ patches_json_fp: PATCHES.json filepath.
+ rel_patch_path: Relative patch path of the patch we want to check. If
+ patches before this patch fail to apply, then the revision is
+ skipped.
+ patch_cmd: Use 'git am' to patch instead of GNU 'patch'.
"""
with patches_json_fp.open(encoding="utf-8") as f:
patch_entries = patch_utils.json_to_patch_entries(
@@ -137,6 +144,7 @@ def CheckPatchApplies(
llvm_src_dir,
patch_entries,
rel_patch_path,
+ patch_utils.git_am,
)
if success:
# Everything is good, patch applied successfully.
@@ -157,29 +165,36 @@ def ApplyPatchAndPrior(
src_dir: Path,
patch_entries: Iterable[patch_utils.PatchEntry],
rel_patch_path: str,
+ patch_cmd: Optional[Callable] = None,
) -> Tuple[bool, List[patch_utils.PatchEntry], List[patch_utils.PatchEntry]]:
"""Apply a patch, and all patches that apply before it in the patch stack.
Patches which did not attempt to apply (because their version range didn't
match and they weren't the patch of interest) do not appear in the output.
- Probably shouldn't be called from outside of CheckPatchApplies, as it modifies
- the source dir contents.
+ Probably shouldn't be called from outside of CheckPatchApplies, as it
+ modifies the source dir contents.
Returns:
- A tuple where:
- [0]: Did the patch of interest succeed in applying?
- [1]: List of applied patches, potentially containing the patch of interest.
- [2]: List of failing patches, potentially containing the patch of interest.
+ A tuple where:
+ [0]: Did the patch of interest succeed in applying?
+ [1]: List of applied patches, potentially containing the patch of
+ interest.
+ [2]: List of failing patches, potentially containing the patch of
+ interest.
"""
- failed_patches = []
+ failed_patches: List[patch_utils.PatchEntry] = []
applied_patches = []
# We have to apply every patch up to the one we care about,
# as patches can stack.
for pe in patch_entries:
is_patch_of_interest = pe.rel_patch_path == rel_patch_path
applied, failed_hunks = patch_utils.apply_single_patch_entry(
- svn_version, src_dir, pe, ignore_version_range=is_patch_of_interest
+ svn_version,
+ src_dir,
+ pe,
+ patch_cmd,
+ ignore_version_range=is_patch_of_interest,
)
meant_to_apply = bool(failed_hunks) or is_patch_of_interest
if is_patch_of_interest:
@@ -205,7 +220,7 @@ def PrintPatchResults(patch_info: patch_utils.PatchInfo):
"""Prints the results of handling the patches of a package.
Args:
- patch_info: A dataclass that has information on the patches.
+ patch_info: A dataclass that has information on the patches.
"""
def _fmt(patches):
@@ -262,7 +277,11 @@ def main(sys_argv: List[str]):
svn_version=args.svn_version,
llvm_src_dir=llvm_src_dir,
patches_json_fp=patches_json_fp,
- continue_on_failure=args.failure_mode == FailureModes.CONTINUE,
+ patch_cmd=patch_utils.git_am
+ if args.git_am
+ else patch_utils.gnu_patch,
+ continue_on_failure=args.failure_mode
+ == failure_modes.FailureModes.CONTINUE,
)
PrintPatchResults(result)
@@ -272,8 +291,9 @@ def main(sys_argv: List[str]):
)
def _disable(args):
+ patch_cmd = patch_utils.git_am if args.git_am else patch_utils.gnu_patch
patch_utils.update_version_ranges(
- args.svn_version, llvm_src_dir, patches_json_fp
+ args.svn_version, llvm_src_dir, patches_json_fp, patch_cmd
)
def _test_single(args):
@@ -282,19 +302,24 @@ def main(sys_argv: List[str]):
"Running with bisect_patches requires the " "--test_patch flag."
)
svn_version = GetHEADSVNVersion(llvm_src_dir)
+ patch_cmd = patch_utils.git_am if args.git_am else patch_utils.gnu_patch
error_code = CheckPatchApplies(
- svn_version, llvm_src_dir, patches_json_fp, args.test_patch
+ svn_version,
+ llvm_src_dir,
+ patches_json_fp,
+ args.test_patch,
+ patch_cmd,
)
# Since this is for bisection, we want to exit with the
# GitBisectionCode enum.
sys.exit(int(error_code))
dispatch_table = {
- FailureModes.FAIL: _apply_all,
- FailureModes.CONTINUE: _apply_all,
- FailureModes.REMOVE_PATCHES: _remove,
- FailureModes.DISABLE_PATCHES: _disable,
- FailureModes.BISECT_PATCHES: _test_single,
+ failure_modes.FailureModes.FAIL: _apply_all,
+ failure_modes.FailureModes.CONTINUE: _apply_all,
+ failure_modes.FailureModes.REMOVE_PATCHES: _remove,
+ failure_modes.FailureModes.DISABLE_PATCHES: _disable,
+ failure_modes.FailureModes.BISECT_PATCHES: _test_single,
}
if args_output.failure_mode in dispatch_table:
diff --git a/llvm_tools/patch_manager_unittest.py b/llvm_tools/patch_manager_unittest.py
index 91573a82..1087727f 100755
--- a/llvm_tools/patch_manager_unittest.py
+++ b/llvm_tools/patch_manager_unittest.py
@@ -39,8 +39,8 @@ class PatchManagerTest(unittest.TestCase):
)
mock_isdir.assert_called_once()
- # Simulate behavior of 'os.path.isfile()' when the patch metadata file is does
- # not exist.
+ # Simulate behavior of 'os.path.isfile()' when the patch metadata file is
+ # does not exist.
@mock.patch.object(Path, "is_file", return_value=False)
def testInvalidPathToPatchMetadataFilePassedAsCommandLineArgument(
self, mock_isfile
@@ -124,6 +124,7 @@ class PatchManagerTest(unittest.TestCase):
dirpath,
patches_path,
"example.patch",
+ patch_utils.gnu_patch,
)
self.assertEqual(result, expected)
m.assert_called()
@@ -164,11 +165,12 @@ class PatchManagerTest(unittest.TestCase):
dirpath,
patches_path,
"example.patch",
+ patch_utils.gnu_patch,
)
self.assertEqual(result, expected)
# Check patch can apply and fail with good return codes.
- def _apply_patch_entry_mock1(v, _, patch_entry, **__):
+ def _apply_patch_entry_mock1(v, _, patch_entry, _func, **__):
return patch_entry.can_patch_version(v), None
_harness2(
@@ -183,7 +185,7 @@ class PatchManagerTest(unittest.TestCase):
)
# Early exit check, shouldn't apply later failing patch.
- def _apply_patch_entry_mock2(v, _, patch_entry, **__):
+ def _apply_patch_entry_mock2(v, _, patch_entry, _func, **__):
if (
patch_entry.can_patch_version(v)
and patch_entry.rel_patch_path == "patch_after.patch"
@@ -198,7 +200,7 @@ class PatchManagerTest(unittest.TestCase):
)
# Skip check, should exit early on the first patch.
- def _apply_patch_entry_mock3(v, _, patch_entry, **__):
+ def _apply_patch_entry_mock3(v, _, patch_entry, _func, **__):
if (
patch_entry.can_patch_version(v)
and patch_entry.rel_patch_path == "another.patch"
diff --git a/llvm_tools/patch_sync/README.md b/llvm_tools/patch_sync/README.md
new file mode 100644
index 00000000..890e2fa3
--- /dev/null
+++ b/llvm_tools/patch_sync/README.md
@@ -0,0 +1,45 @@
+# Overview
+
+See go/llvm-patch-sync for motivation, diagrams, and design docs. The
+`patch_sync` tool also has a detailed `--help`, which can be quickly
+accessed via `cargo run -- --help`, `cargo run -- transpose --help`,
+and `cargo run -- show --help`.
+
+## Building
+
+```rs
+# Release version
+cargo build --release
+
+# Debug version
+cargo build
+```
+
+The executable will then exist at `./target/(debug|release)/patch_sync`.
+
+## Running Unittests
+
+```rs
+cargo test
+```
+
+Because `patch_sync` requires a specific file system layout to work correctly,
+the unittests are unfortunately fairly sparse. Full testing will likely require
+running `patch_sync transpose ...` with the necessary arguments.
+
+## Example Transpose Command
+
+This command will:
+
+1. Sync the Android toolchain and ChromiumOS overlay repositories.
+2. Find any new patches between the current version and the base ref.
+3. Copy any new and applicable patches into each repository.
+
+```
+./patch_sync transpose \
+ --sync \
+ --aosp-checkout "${HOME}/android" \
+ --aosp-base-ref "${base_aosp_git_hash}" \
+ --cros-checkout "${HOME}/chromiumos" \
+ --overlay-base-ref "${base_cros_git_hash}"
+```
diff --git a/llvm_tools/patch_sync/src/main.rs b/llvm_tools/patch_sync/src/main.rs
index a6c340be..5f9b9708 100644
--- a/llvm_tools/patch_sync/src/main.rs
+++ b/llvm_tools/patch_sync/src/main.rs
@@ -42,6 +42,7 @@ fn main() -> Result<()> {
no_commit,
wip,
disable_cq,
+ uprev,
} => transpose_subcmd(TransposeOpt {
cros_checkout_path,
cros_reviewers: cros_reviewers
@@ -59,6 +60,7 @@ fn main() -> Result<()> {
no_commit,
wip,
disable_cq,
+ uprev_ebuilds: uprev,
}),
}
}
@@ -83,6 +85,7 @@ fn show_subcmd(args: ShowOpt) -> Result<()> {
sync_before: sync,
wip_mode: true, // Has no effect, as we're not making changes
enable_cq: false, // Has no effect, as we're not uploading anything
+ uprev_ebuilds: false,
};
ctx.setup()?;
let make_collection = |platform: &str, patches_fp: &Path| -> Result<PatchCollection> {
@@ -122,6 +125,7 @@ struct TransposeOpt {
android_reviewers: Vec<String>,
wip: bool,
disable_cq: bool,
+ uprev_ebuilds: bool,
}
fn transpose_subcmd(args: TransposeOpt) -> Result<()> {
@@ -131,6 +135,7 @@ fn transpose_subcmd(args: TransposeOpt) -> Result<()> {
sync_before: args.sync,
wip_mode: args.wip,
enable_cq: !args.disable_cq,
+ uprev_ebuilds: args.uprev_ebuilds,
};
ctx.setup()?;
let cros_patches_path = ctx.cros_patches_path();
@@ -366,6 +371,10 @@ enum Opt {
#[structopt(short, long)]
sync: bool,
+ /// Revbump/uprev ebuilds during transposing.
+ #[structopt(long)]
+ uprev: bool,
+
/// Print information to stdout
#[structopt(short, long)]
verbose: bool,
diff --git a/llvm_tools/patch_sync/src/version_control.rs b/llvm_tools/patch_sync/src/version_control.rs
index fc6211ae..5d70a4b5 100644
--- a/llvm_tools/patch_sync/src/version_control.rs
+++ b/llvm_tools/patch_sync/src/version_control.rs
@@ -14,7 +14,7 @@ const ANDROID_LLVM_REL_PATH: &str = "toolchain/llvm_android";
// Need to checkout the upstream, rather than the local clone.
const CROS_MAIN_BRANCH: &str = "cros/main";
-const ANDROID_MAIN_BRANCH: &str = "aosp/master"; // nocheck
+const ANDROID_MAIN_BRANCH: &str = "aosp/main";
const WORK_BRANCH_NAME: &str = "__patch_sync_tmp";
/// Context struct to keep track of both ChromiumOS and Android checkouts.
@@ -26,6 +26,8 @@ pub struct RepoSetupContext {
pub sync_before: bool,
pub wip_mode: bool,
pub enable_cq: bool,
+ /// Generally LLVM ebuilds are now 9999 LIVE ebuilds, so only uprev if this is set.
+ pub uprev_ebuilds: bool,
}
impl RepoSetupContext {
@@ -57,7 +59,11 @@ impl RepoSetupContext {
"CrOS LLVM dir {} is not a directory",
llvm_dir.display()
);
- Self::rev_bump_llvm(&llvm_dir)?;
+
+ if self.uprev_ebuilds {
+ Self::rev_bump_llvm(&llvm_dir)?;
+ }
+
let mut extra_args = Vec::new();
for reviewer in reviewers {
extra_args.push("--re");
@@ -254,11 +260,11 @@ impl RepoSetupContext {
/// Create the commit message
fn build_commit_msg(subj: &str, from: &str, to: &str, footer: &str) -> String {
format!(
- "[patch_sync] {}\n\n\
-Copies new PATCHES.json changes from {} to {}.\n
-For questions about this job, contact chromeos-toolchain@google.com\n\n
-{}",
- subj, from, to, footer
+ "[patch_sync] {subj}\n\n\
+Copies new PATCHES.json changes from {from} to {to}.\n
+For questions about this job, contact chromeos-toolchain@google.com\n
+This change is generated automatically by the script go/llvm-patch-sync\n\n
+{footer}",
)
}
}
diff --git a/llvm_tools/patch_utils.py b/llvm_tools/patch_utils.py
index 0c8ad19c..b21cf314 100644
--- a/llvm_tools/patch_utils.py
+++ b/llvm_tools/patch_utils.py
@@ -12,11 +12,22 @@ from pathlib import Path
import re
import subprocess
import sys
-from typing import Any, Dict, IO, Iterable, List, Optional, Tuple
+from typing import (
+ Any,
+ Callable,
+ Dict,
+ IO,
+ Iterable,
+ List,
+ Optional,
+ Tuple,
+ Union,
+)
import atomic_write_file
+APPLIED_RE = re.compile(r"^Applying: (.+) \(#(\d+)\)$")
CHECKED_FILE_RE = re.compile(r"^checking file\s+(.*)$")
HUNK_FAILED_RE = re.compile(r"^Hunk #(\d+) FAILED at.*")
HUNK_HEADER_RE = re.compile(r"^@@\s+-(\d+),(\d+)\s+\+(\d+),(\d+)\s+@@")
@@ -42,11 +53,11 @@ def parse_patch_stream(patch_stream: IO[str]) -> Dict[str, List[Hunk]]:
"""Parse a patch file-like into Hunks.
Args:
- patch_stream: A IO stream formatted like a git patch file.
+ patch_stream: A IO stream formatted like a git patch file.
Returns:
- A dictionary mapping filenames to lists of Hunks present
- in the patch stream.
+ A dictionary mapping filenames to lists of Hunks present
+ in the patch stream.
"""
current_filepath = None
@@ -102,6 +113,12 @@ def parse_failed_patch_output(text: str) -> Dict[str, List[int]]:
raise ValueError("Input stream was not parsable")
hunk_id = int(failed_match.group(1))
failed_hunks[current_file].append(hunk_id)
+ else:
+ failed_applied_patches = APPLIED_RE.match(eline)
+ if failed_applied_patches:
+ current_file = failed_applied_patches.group(1)
+ hunk_id = int(failed_applied_patches.group(2))
+ failed_hunks[current_file].append(hunk_id)
return failed_hunks
@@ -124,7 +141,10 @@ class PatchResult:
for file, hunks in self.failed_hunks.items():
s += f"{file}:\n"
for h in hunks:
- s += f"Lines {h.orig_start} to {h.orig_start + h.orig_hunk_len}\n"
+ s += (
+ f"Lines {h.orig_start} to "
+ f"{h.orig_start + h.orig_hunk_len}\n"
+ )
s += "--------------------\n"
return s
@@ -139,10 +159,12 @@ class PatchEntry:
platforms: Optional[List[str]]
rel_patch_path: str
version_range: Optional[Dict[str, Optional[int]]]
+ verify_workdir: bool = True
+ """Don't verify the workdir exists. Used for testing."""
_parsed_hunks = None
def __post_init__(self):
- if not self.workdir.is_dir():
+ if self.verify_workdir and not self.workdir.is_dir():
raise ValueError(f"workdir {self.workdir} is not a directory")
@classmethod
@@ -150,13 +172,12 @@ class PatchEntry:
"""Instatiate from a dictionary.
Dictionary must have at least the following key:
-
- {
+ {
'rel_patch_path': '<relative patch path to workdir>',
- }
+ }
Returns:
- A new PatchEntry.
+ A new PatchEntry.
"""
return cls(
workdir,
@@ -167,8 +188,16 @@ class PatchEntry:
)
def to_dict(self) -> Dict[str, Any]:
+ # We sort the metadata so that it doesn't matter
+ # how it was passed to patch_utils.
+ if self.metadata is None:
+ sorted_metadata = None
+ else:
+ sorted_metadata = dict(
+ sorted(self.metadata.items(), key=lambda x: x[0])
+ )
out: Dict[str, Any] = {
- "metadata": self.metadata,
+ "metadata": sorted_metadata,
}
if self.platforms:
# To match patch_sync, only serialized when
@@ -214,28 +243,27 @@ class PatchEntry:
return svn_version >= until_v
def apply(
- self, root_dir: Path, extra_args: Optional[List[str]] = None
+ self,
+ root_dir: Path,
+ patch_cmd: Optional[Callable] = None,
+ extra_args: Optional[List[str]] = None,
) -> PatchResult:
"""Apply a patch to a given directory."""
- if not extra_args:
- extra_args = []
# Cmd to apply a patch in the src unpack path.
abs_patch_path = self.patch_path().absolute()
if not abs_patch_path.is_file():
raise RuntimeError(
f"Cannot apply: patch {abs_patch_path} is not a file"
)
- cmd = [
- "patch",
- "-d",
- root_dir.absolute(),
- "-f",
- "-E",
- "-p1",
- "--no-backup-if-mismatch",
- "-i",
- abs_patch_path,
- ] + extra_args
+
+ if not patch_cmd:
+ patch_cmd = gnu_patch
+
+ if patch_cmd == gnu_patch:
+ cmd = patch_cmd(root_dir, abs_patch_path) + (extra_args or [])
+ else:
+ cmd = patch_cmd(abs_patch_path) + (extra_args or [])
+
try:
subprocess.run(
cmd, encoding="utf-8", check=True, stdout=subprocess.PIPE
@@ -244,19 +272,27 @@ class PatchEntry:
parsed_hunks = self.parsed_hunks()
failed_hunks_id_dict = parse_failed_patch_output(e.stdout)
failed_hunks = {}
- for path, failed_hunk_ids in failed_hunks_id_dict.items():
- hunks_for_file = parsed_hunks[path]
- failed_hunks[path] = [
- hunk
- for hunk in hunks_for_file
- if hunk.hunk_id in failed_hunk_ids
- ]
+ if patch_cmd == gnu_patch:
+ for path, failed_hunk_ids in failed_hunks_id_dict.items():
+ hunks_for_file = parsed_hunks[path]
+ failed_hunks[path] = [
+ hunk
+ for hunk in hunks_for_file
+ if hunk.hunk_id in failed_hunk_ids
+ ]
+ elif failed_hunks_id_dict:
+ # use git am
+ failed_hunks = parsed_hunks
+
return PatchResult(succeeded=False, failed_hunks=failed_hunks)
return PatchResult(succeeded=True)
- def test_apply(self, root_dir: Path) -> PatchResult:
+ def test_apply(
+ self, root_dir: Path, patch_cmd: Optional[Callable] = None
+ ) -> PatchResult:
"""Dry run applying a patch to a given directory."""
- return self.apply(root_dir, ["--dry-run"])
+ extra_args = [] if patch_cmd == git_am else ["--dry-run"]
+ return self.apply(root_dir, patch_cmd, extra_args)
def title(self) -> str:
if not self.metadata:
@@ -273,7 +309,7 @@ class PatchInfo:
applied_patches: List[PatchEntry]
failed_patches: List[PatchEntry]
# Can be deleted once legacy code is removed.
- non_applicable_patches: List[str]
+ non_applicable_patches: List[PatchEntry]
# Can be deleted once legacy code is removed.
disabled_patches: List[str]
# Can be deleted once legacy code is removed.
@@ -289,8 +325,8 @@ def json_to_patch_entries(workdir: Path, json_fd: IO[str]) -> List[PatchEntry]:
"""Convert a json IO object to List[PatchEntry].
Examples:
- >>> f = open('PATCHES.json')
- >>> patch_entries = json_to_patch_entries(Path(), f)
+ >>> f = open('PATCHES.json')
+ >>> patch_entries = json_to_patch_entries(Path(), f)
"""
return [PatchEntry.from_dict(workdir, d) for d in json.load(json_fd)]
@@ -299,8 +335,8 @@ def json_str_to_patch_entries(workdir: Path, json_str: str) -> List[PatchEntry]:
"""Convert a json IO object to List[PatchEntry].
Examples:
- >>> f = open('PATCHES.json').read()
- >>> patch_entries = json_str_to_patch_entries(Path(), f)
+ >>> f = open('PATCHES.json').read()
+ >>> patch_entries = json_str_to_patch_entries(Path(), f)
"""
return [PatchEntry.from_dict(workdir, d) for d in json.loads(json_str)]
@@ -309,9 +345,9 @@ def _print_failed_patch(pe: PatchEntry, failed_hunks: Dict[str, List[Hunk]]):
"""Print information about a single failing PatchEntry.
Args:
- pe: A PatchEntry that failed.
- failed_hunks: Hunks for pe which failed as dict:
- filepath: [Hunk...]
+ pe: A PatchEntry that failed.
+ failed_hunks: Hunks for pe which failed as dict:
+ filepath: [Hunk...]
"""
print(f"Could not apply {pe.rel_patch_path}: {pe.title()}", file=sys.stderr)
for fp, hunks in failed_hunks.items():
@@ -328,6 +364,7 @@ def apply_all_from_json(
svn_version: int,
llvm_src_dir: Path,
patches_json_fp: Path,
+ patch_cmd: Optional[Callable] = None,
continue_on_failure: bool = False,
) -> PatchInfo:
"""Attempt to apply some patches to a given LLVM source tree.
@@ -336,11 +373,11 @@ def apply_all_from_json(
the patches are applied.
Args:
- svn_version: LLVM Subversion revision to patch.
- llvm_src_dir: llvm-project root-level source directory to patch.
- patches_json_fp: Filepath to the PATCHES.json file.
- continue_on_failure: Skip any patches which failed to apply,
- rather than throw an Exception.
+ svn_version: LLVM Subversion revision to patch.
+ llvm_src_dir: llvm-project root-level source directory to patch.
+ patches_json_fp: Filepath to the PATCHES.json file.
+ continue_on_failure: Skip any patches which failed to apply,
+ rather than throw an Exception.
"""
with patches_json_fp.open(encoding="utf-8") as f:
patches = json_to_patch_entries(patches_json_fp.parent, f)
@@ -349,7 +386,7 @@ def apply_all_from_json(
applied_patches = []
for pe in patches:
applied, failed_hunks = apply_single_patch_entry(
- svn_version, llvm_src_dir, pe
+ svn_version, llvm_src_dir, pe, patch_cmd
)
if applied:
applied_patches.append(pe)
@@ -379,24 +416,25 @@ def apply_single_patch_entry(
svn_version: int,
llvm_src_dir: Path,
pe: PatchEntry,
+ patch_cmd: Optional[Callable] = None,
ignore_version_range: bool = False,
) -> Tuple[bool, Optional[Dict[str, List[Hunk]]]]:
"""Try to apply a single PatchEntry object.
Returns:
- Tuple where the first element indicates whether the patch applied,
- and the second element is a faild hunk mapping from file name to lists of
- hunks (if the patch didn't apply).
+ Tuple where the first element indicates whether the patch applied, and
+ the second element is a faild hunk mapping from file name to lists of
+ hunks (if the patch didn't apply).
"""
# Don't apply patches outside of the version range.
if not ignore_version_range and not pe.can_patch_version(svn_version):
return False, None
# Test first to avoid making changes.
- test_application = pe.test_apply(llvm_src_dir)
+ test_application = pe.test_apply(llvm_src_dir, patch_cmd)
if not test_application:
return False, test_application.failed_hunks
# Now actually make changes.
- application_result = pe.apply(llvm_src_dir)
+ application_result = pe.apply(llvm_src_dir, patch_cmd)
if not application_result:
# This should be very rare/impossible.
return False, application_result.failed_hunks
@@ -465,7 +503,10 @@ def predict_indent(patches_lines: List[str]) -> int:
def update_version_ranges(
- svn_version: int, llvm_src_dir: Path, patches_json_fp: Path
+ svn_version: int,
+ llvm_src_dir: Path,
+ patches_json_fp: Path,
+ patch_cmd: Optional[Callable] = None,
) -> PatchInfo:
"""Reduce the version ranges of failing patches.
@@ -475,12 +516,13 @@ def update_version_ranges(
Modifies the contents of patches_json_fp.
Args:
- svn_version: LLVM revision number.
- llvm_src_dir: llvm-project directory path.
- patches_json_fp: Filepath to the PATCHES.json file.
+ svn_version: LLVM revision number.
+ llvm_src_dir: llvm-project directory path.
+ patches_json_fp: Filepath to the PATCHES.json file.
+ patch_cmd: option to apply patch.
Returns:
- PatchInfo for applied and disabled patches.
+ PatchInfo for applied and disabled patches.
"""
with patches_json_fp.open(encoding="utf-8") as f:
contents = f.read()
@@ -490,7 +532,7 @@ def update_version_ranges(
contents,
)
modified_entries, applied_patches = update_version_ranges_with_entries(
- svn_version, llvm_src_dir, patch_entries
+ svn_version, llvm_src_dir, patch_entries, patch_cmd
)
with atomic_write_file.atomic_write(patches_json_fp, encoding="utf-8") as f:
_write_json_changes(
@@ -515,19 +557,20 @@ def update_version_ranges_with_entries(
svn_version: int,
llvm_src_dir: Path,
patch_entries: Iterable[PatchEntry],
+ patch_cmd: Optional[Callable] = None,
) -> Tuple[List[PatchEntry], List[PatchEntry]]:
"""Test-able helper for UpdateVersionRanges.
Args:
- svn_version: LLVM revision number.
- llvm_src_dir: llvm-project directory path.
- patch_entries: PatchEntry objects to modify.
+ svn_version: LLVM revision number.
+ llvm_src_dir: llvm-project directory path.
+ patch_entries: PatchEntry objects to modify.
Returns:
- Tuple of (modified entries, applied patches)
+ Tuple of (modified entries, applied patches)
Post:
- Modifies patch_entries in place.
+ Modifies patch_entries in place.
"""
modified_entries: List[PatchEntry] = []
applied_patches: List[PatchEntry] = []
@@ -536,7 +579,7 @@ def update_version_ranges_with_entries(
)
with git_clean_context(llvm_src_dir):
for pe in active_patches:
- test_result = pe.test_apply(llvm_src_dir)
+ test_result = pe.test_apply(llvm_src_dir, patch_cmd)
if not test_result:
if pe.version_range is None:
pe.version_range = {}
@@ -545,7 +588,7 @@ def update_version_ranges_with_entries(
else:
# We have to actually apply the patch so that future patches
# will stack properly.
- if not pe.apply(llvm_src_dir).succeeded:
+ if not pe.apply(llvm_src_dir, patch_cmd).succeeded:
raise RuntimeError(
"Could not apply patch that dry ran successfully"
)
@@ -563,12 +606,12 @@ def remove_old_patches(
each patch entry.
Args:
- svn_version: LLVM SVN version.
- llvm_src_dir: LLVM source directory.
- patches_json_fp: Location to edit patches on.
+ svn_version: LLVM SVN version.
+ llvm_src_dir: LLVM source directory.
+ patches_json_fp: Location to edit patches on.
Returns:
- PatchInfo for modified patches.
+ PatchInfo for modified patches.
"""
with patches_json_fp.open(encoding="utf-8") as f:
contents = f.read()
@@ -595,3 +638,23 @@ def remove_old_patches(
removed_patches=[p.rel_patch_path for p in removed_entries],
modified_metadata=str(patches_json_fp) if removed_entries else None,
)
+
+
+def git_am(patch_path: Path) -> List[Union[str, Path]]:
+ cmd = ["git", "am", "--3way", str(patch_path)]
+ return cmd
+
+
+def gnu_patch(root_dir: Path, patch_path: Path) -> List[Union[str, Path]]:
+ cmd = [
+ "patch",
+ "-d",
+ str(root_dir.absolute()),
+ "-f",
+ "-E",
+ "-p1",
+ "--no-backup-if-mismatch",
+ "-i",
+ str(patch_path),
+ ]
+ return cmd
diff --git a/llvm_tools/patch_utils_unittest.py b/llvm_tools/patch_utils_unittest.py
index dfee55e3..26a211ee 100755
--- a/llvm_tools/patch_utils_unittest.py
+++ b/llvm_tools/patch_utils_unittest.py
@@ -5,6 +5,7 @@
"""Unit tests for the patch_utils.py file."""
+import copy
import io
import json
from pathlib import Path
@@ -51,6 +52,15 @@ a
e = pu.PatchEntry.from_dict(TestPatchUtils._mock_dir(), d)
self.assertEqual(d, e.to_dict())
+ # Test that they aren't serialised the same, as 'd' isn't sorted.
+ self.assertNotEqual(
+ json.dumps(d["metadata"]), json.dumps(e.to_dict()["metadata"])
+ )
+ self.assertEqual(
+ ["info", "other_extra_info", "title"],
+ list(e.to_dict()["metadata"].keys()),
+ )
+
def test_patch_path(self):
"""Test that we can get the full path from a PatchEntry."""
d = TestPatchUtils._default_json_dict()
@@ -159,11 +169,21 @@ a
e = pu.PatchEntry.from_dict(
patch_dir, TestPatchUtils._default_json_dict()
)
+
+ """Make a deepcopy of the case for testing commit patch option."""
+ e1 = copy.deepcopy(e)
+
with mock.patch("pathlib.Path.is_file", return_value=True):
with mock.patch("subprocess.run", mock.MagicMock()):
result = e.apply(src_dir)
self.assertTrue(result.succeeded)
+ """Test that commit patch option works."""
+ with mock.patch("pathlib.Path.is_file", return_value=True):
+ with mock.patch("subprocess.run", mock.MagicMock()):
+ result1 = e1.apply(src_dir, pu.git_am)
+ self.assertTrue(result1.succeeded)
+
def test_parse_failed_patch_output(self):
"""Test that we can call parse `patch` output."""
fixture = """
@@ -250,6 +270,7 @@ Hunk #1 SUCCEEDED at 96 with fuzz 1.
},
),
]
+
patches[0].apply = mock.MagicMock(
return_value=pu.PatchResult(
succeeded=False, failed_hunks={"a/b/c": []}
@@ -261,9 +282,14 @@ Hunk #1 SUCCEEDED at 96 with fuzz 1.
patches[2].apply = mock.MagicMock(
return_value=pu.PatchResult(succeeded=False)
)
+
+ # Make a deepcopy of patches to test commit patch option
+ patches2 = copy.deepcopy(patches)
+
results, _ = pu.update_version_ranges_with_entries(
- 1, dirpath, patches
+ 1, dirpath, patches, pu.gnu_patch
)
+
# We should only have updated the version_range of the first patch,
# as that one failed to apply.
self.assertEqual(len(results), 1)
@@ -272,6 +298,19 @@ Hunk #1 SUCCEEDED at 96 with fuzz 1.
self.assertEqual(patches[1].version_range, {"from": 0, "until": 2})
self.assertEqual(patches[2].version_range, {"from": 4, "until": 5})
+ # Test git am option
+ results2, _ = pu.update_version_ranges_with_entries(
+ 1, dirpath, patches2, pu.git_am
+ )
+
+ # We should only have updated the version_range of the first patch
+ # via git am, as that one failed to apply.
+ self.assertEqual(len(results2), 1)
+ self.assertEqual(results2[0].version_range, {"from": 0, "until": 1})
+ self.assertEqual(patches2[0].version_range, {"from": 0, "until": 1})
+ self.assertEqual(patches2[1].version_range, {"from": 0, "until": 2})
+ self.assertEqual(patches2[2].version_range, {"from": 4, "until": 5})
+
@mock.patch("builtins.print")
def test_remove_old_patches(self, _):
"""Can remove old patches from PATCHES.json."""
diff --git a/llvm_tools/setup_for_workon.py b/llvm_tools/setup_for_workon.py
new file mode 100755
index 00000000..41f3d45c
--- /dev/null
+++ b/llvm_tools/setup_for_workon.py
@@ -0,0 +1,286 @@
+#!/usr/bin/env python3
+# Copyright 2024 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Sets up src/third_party/llvm-project for cros workon from an LLVM ebuild."""
+
+import argparse
+import dataclasses
+import logging
+from pathlib import Path
+import re
+import shlex
+import subprocess
+import sys
+from typing import List, Union
+
+import git_llvm_rev
+
+
+@dataclasses.dataclass(frozen=True)
+class LLVMSourceDir:
+ """An LLVM source dir, with convenient additional accessors."""
+
+ path: Path
+
+ def cros_workon_subdir(self):
+ """Returns the subdir used for communicating with the ebuild."""
+ return self.path / ".ebuild"
+
+
+def apply_patches(
+ llvm_dir: LLVMSourceDir,
+ patch_manager: Path,
+ patch_metadata_file: Path,
+ current_rev: git_llvm_rev.Rev,
+) -> None:
+ """Applies patches using `patch_manager` to `llvm_dir`."""
+ subprocess.run(
+ [
+ patch_manager,
+ f"--svn_version={current_rev.number}",
+ f"--src_path={llvm_dir.path}",
+ f"--patch_metadata_file={patch_metadata_file}",
+ ],
+ check=True,
+ stdin=subprocess.DEVNULL,
+ )
+
+
+def find_ebuild_in_dir(ebuild_dir: Path) -> Path:
+ """Returns the path to a 9999 ebuild in `ebuild_dir`; raises if none."""
+ candidates = list(ebuild_dir.glob("*-9999.ebuild"))
+ if len(candidates) != 1:
+ raise ValueError(
+ f"Expected exactly one 9999 ebuild in {ebuild_dir}; found "
+ f"{candidates}"
+ )
+ return candidates[0]
+
+
+def write_gentoo_cmake_hack(llvm_dir: LLVMSourceDir, ebuild_dir: Path) -> None:
+ """Modifies cmake files in LLVM so cmake.eclass doesn't modify them."""
+ # Upstream's `cmake.eclass` will try to override "dangerous" configurations
+ # that override Gentoo settings. There's no way to skip this override, but
+ # it _does_ have logic to detect if it has already run & skips all
+ # modifications in that case. Since LLVM has no such "dangerous" settings,
+ # and the `9999` ebuild never "goes live," it's safe to skip these.
+
+ # The file to modify is the 'main' cmake file, which is determined based on
+ # `CMAKE_USE_DIR`. Parsing that out isn't _too_ painful, so try it.
+ ebuild_path = find_ebuild_in_dir(ebuild_dir)
+ ebuild_contents = ebuild_path.read_text(encoding="utf-8")
+ cmake_use_dir_re = re.compile(
+ # Use string concatenation rather than re.VERBOSE, since this regex
+ # goes in an error message on failure, and that's _really_ hard to
+ # read.
+ r"^\s*"
+ # While these all use `export`, it's not strictly required by
+ # cmake.eclass.
+ r"(?:export\s+)?" r'CMAKE_USE_DIR="\$\{S\}/([^"]+)"',
+ re.MULTILINE,
+ )
+ cmake_use_dirs = cmake_use_dir_re.findall(ebuild_contents)
+ if len(cmake_use_dirs) != 1:
+ raise ValueError(
+ f"Expected to find 1 match of {cmake_use_dir_re} in "
+ f"{ebuild_path}; found {len(cmake_use_dirs)}"
+ )
+
+ cmake_file = llvm_dir.path / cmake_use_dirs[0] / "CMakeLists.txt"
+ special_marker = "<<< Gentoo configuration >>>"
+ if special_marker in cmake_file.read_text(encoding="utf-8"):
+ return
+
+ with cmake_file.open("a", encoding="utf-8") as f:
+ f.write(f"\n# HACK from setup_from_workon.py:\n# {special_marker}")
+
+
+def write_patch_application_stamp(
+ llvm_dir: LLVMSourceDir, package_name: str
+) -> None:
+ """Writes a stamp file to note that patches have been applied."""
+ stamp_path = (
+ llvm_dir.cros_workon_subdir()
+ / "stamps"
+ / "patches_applied"
+ / package_name
+ )
+ stamp_path.parent.mkdir(parents=True, exist_ok=True)
+ stamp_path.touch()
+
+
+def main(argv: List[str]) -> None:
+ logging.basicConfig(
+ format=">> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: "
+ "%(message)s",
+ level=logging.INFO,
+ )
+
+ my_dir = Path(__file__).resolve().parent
+ parser = argparse.ArgumentParser(
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+ parser.add_argument(
+ "--llvm-dir",
+ type=lambda x: LLVMSourceDir(path=Path(x)),
+ default=LLVMSourceDir(path=my_dir.parent.parent / "llvm-project"),
+ help="Path containing a directory with llvm sources.",
+ )
+ parser.add_argument(
+ "--ebuild-dir",
+ type=Path,
+ help="""
+ Directory of the ebuild we're trying to set up. If this isn't
+ specified, `--package` should be specified, and this will be
+ autodetected. Example: ${cros_overlay}/sys-devel/llvm.
+ """,
+ )
+ parser.add_argument(
+ "--checkout",
+ help="""
+ If specified, the llvm directory will be checked out to the given SHA.
+ """,
+ )
+ parser.add_argument(
+ "--clean-llvm",
+ action="store_true",
+ help="""
+ If passed, a series of commands will be run to reset the LLVM directory
+ to HEAD prior to applying patches. **This flag deletes all staged
+ unstaged changes, and deletes all untracked files**.
+ """,
+ )
+ parser.add_argument(
+ "--package",
+ help="""
+ Name of the package to set up for, in the form '${CATEGORY}/${PN}'.
+ This must be provided unless `--ebuild-dir` is provided. Example:
+ sys-devel/llvm.
+ """,
+ )
+ parser.add_argument(
+ "--no-commit",
+ dest="commit",
+ action="store_false",
+ help="Don't create a commit with all changes applied.",
+ )
+ parser.add_argument(
+ "--workon-board",
+ dest="workon_board",
+ help="""
+ Ensure cros workon for the given board after applying changes.
+ Set to 'host' for working on the host system, and not a board.
+ """,
+ )
+ opts = parser.parse_args(argv)
+
+ ebuild_dir = opts.ebuild_dir
+ package_name = opts.package
+ if not ebuild_dir and not package_name:
+ parser.error(
+ "At least one of --ebuild-dir or --package must be specified."
+ )
+
+ if not ebuild_dir:
+ # All of these are in chromiumos-overlay, so just use that as a basis.
+ ebuild_dir = my_dir.parent.parent / "chromiumos-overlay" / package_name
+ logging.info("Ebuild directory is %s.", ebuild_dir)
+ elif not package_name:
+ package_name = f"{ebuild_dir.parent.name}/{ebuild_dir.name}"
+ logging.info("Package is %s.", package_name)
+
+ git_housekeeping_commands: List[List[Union[Path, str]]] = []
+ if opts.clean_llvm:
+ git_housekeeping_commands += (
+ ["git", "clean", "-fd", "."],
+ ["git", "reset", "--hard", "HEAD"],
+ )
+
+ if opts.checkout:
+ git_housekeeping_commands.append(
+ ["git", "checkout", "--quiet", opts.checkout],
+ )
+
+ for cmd in git_housekeeping_commands:
+ subprocess.run(
+ cmd,
+ cwd=opts.llvm_dir.path,
+ check=True,
+ stdin=subprocess.DEVNULL,
+ )
+
+ rev = git_llvm_rev.translate_sha_to_rev(
+ git_llvm_rev.LLVMConfig(
+ remote="cros",
+ dir=opts.llvm_dir.path,
+ ),
+ subprocess.run(
+ ["git", "rev-parse", "HEAD"],
+ check=True,
+ cwd=opts.llvm_dir.path,
+ stdin=subprocess.DEVNULL,
+ encoding="utf-8",
+ stdout=subprocess.PIPE,
+ ).stdout.strip(),
+ )
+
+ logging.info("Applying patches...")
+ files_dir = ebuild_dir / "files"
+ apply_patches(
+ opts.llvm_dir,
+ patch_manager=files_dir / "patch_manager" / "patch_manager.py",
+ patch_metadata_file=files_dir / "PATCHES.json",
+ current_rev=rev,
+ )
+ write_patch_application_stamp(opts.llvm_dir, package_name)
+ write_gentoo_cmake_hack(opts.llvm_dir, ebuild_dir)
+
+ if opts.commit:
+ subprocess.run(
+ ["git", "add", "."],
+ check=True,
+ cwd=opts.llvm_dir.path,
+ stdin=subprocess.DEVNULL,
+ )
+ subprocess.run(
+ [
+ "git",
+ "commit",
+ "--message",
+ "Patches applied and markers added.",
+ ],
+ check=True,
+ cwd=opts.llvm_dir.path,
+ stdin=subprocess.DEVNULL,
+ )
+
+ if not opts.workon_board:
+ logging.warning(
+ "Didn't ensure 'workon' for any board or host."
+ " Make sure you've called 'cros workon [...] start %s'"
+ " before building!",
+ package_name,
+ )
+ return
+
+ if opts.workon_board == "host":
+ cmd = ["cros", "workon", "--host", "start", package_name]
+ else:
+ cmd = [
+ "cros",
+ "workon",
+ f"-b={opts.workon_board}",
+ "start",
+ package_name,
+ ]
+ subprocess.run(cmd, check=True, stdin=subprocess.DEVNULL)
+ logging.info(
+ "Successfully workon-ed: %s", shlex.join([str(c) for c in cmd])
+ )
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/llvm_tools/subprocess_helpers.py b/llvm_tools/subprocess_helpers.py
index bc87db85..d0c619cb 100644
--- a/llvm_tools/subprocess_helpers.py
+++ b/llvm_tools/subprocess_helpers.py
@@ -1,22 +1,18 @@
-# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Helpers/wrappers for the subprocess module for migration to python3."""
-
import subprocess
def CheckCommand(cmd):
"""Executes the command using Popen()."""
-
- cmd_obj = subprocess.Popen(
- cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding="UTF-8"
- )
-
- stdout, _ = cmd_obj.communicate()
+ with subprocess.Popen(
+ cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, encoding="utf-8"
+ ) as cmd_obj:
+ stdout, _ = cmd_obj.communicate()
if cmd_obj.returncode:
print(stdout)
@@ -26,13 +22,13 @@ def CheckCommand(cmd):
def check_output(cmd, cwd=None):
"""Wrapper for pre-python3 subprocess.check_output()."""
- return subprocess.check_output(cmd, encoding="UTF-8", cwd=cwd)
+ return subprocess.check_output(cmd, encoding="utf-8", cwd=cwd)
def check_call(cmd, cwd=None):
"""Wrapper for pre-python3 subprocess.check_call()."""
- subprocess.check_call(cmd, encoding="UTF-8", cwd=cwd)
+ subprocess.check_call(cmd, encoding="utf-8", cwd=cwd)
# FIXME: CTRL+C does not work when executing a command inside the chroot via
diff --git a/llvm_tools/test_helpers.py b/llvm_tools/test_helpers.py
index 67d88d9f..ea47a695 100644
--- a/llvm_tools/test_helpers.py
+++ b/llvm_tools/test_helpers.py
@@ -1,25 +1,22 @@
-# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Helper functions for unit testing."""
-
-from contextlib import contextmanager
+import contextlib
import json
import os
-from tempfile import mkstemp
+import tempfile
-class ArgsOutputTest(object):
+class ArgsOutputTest:
"""Testing class to simulate a argument parser object."""
def __init__(self, svn_option="google3"):
self.chroot_path = "/abs/path/to/chroot"
self.last_tested = "/abs/path/to/last_tested_file.json"
self.llvm_version = svn_option
- self.verbose = False
self.extra_change_lists = None
self.options = ["latest-toolchain"]
self.builders = ["some-builder"]
@@ -30,21 +27,22 @@ def CallCountsToMockFunctions(mock_function):
"""A decorator that passes a call count to the function it decorates.
Examples:
- @CallCountsToMockFunctions
- def foo(call_count):
- return call_count
- ...
- ...
- [foo(), foo(), foo()]
- [0, 1, 2]
+ @CallCountsToMockFunctions
+ def foo(call_count):
+ return call_count
+ ...
+ ...
+ [foo(), foo(), foo()]
+ [0, 1, 2]
"""
counter = [0]
def Result(*args, **kwargs):
- # For some values of `counter`, the mock function would simulate raising
- # an exception, so let the test case catch the exception via
- # `unittest.TestCase.assertRaises()` and to also handle recursive functions.
+ # For some values of `counter`, the mock function would simulate
+ # raising an exception, so let the test case catch the exception via
+ # `unittest.TestCase.assertRaises()` and to also handle recursive
+ # functions.
prev_counter = counter[0]
counter[0] += 1
@@ -59,8 +57,8 @@ def WritePrettyJsonFile(file_name, json_object):
"""Writes the contents of the file to the json object.
Args:
- file_name: The file that has contents to be used for the json object.
- json_object: The json object to write to.
+ file_name: The file that has contents to be used for the json object.
+ json_object: The json object to write to.
"""
json.dump(file_name, json_object, indent=4, separators=(",", ": "))
@@ -72,11 +70,11 @@ def CreateTemporaryJsonFile():
return CreateTemporaryFile(suffix=".json")
-@contextmanager
+@contextlib.contextmanager
def CreateTemporaryFile(suffix=""):
"""Makes a temporary file."""
- fd, temp_file_path = mkstemp(suffix=suffix)
+ fd, temp_file_path = tempfile.mkstemp(suffix=suffix)
os.close(fd)
diff --git a/llvm_tools/update_chromeos_llvm_hash.py b/llvm_tools/update_chromeos_llvm_hash.py
index 9a8754d4..ea09af48 100755
--- a/llvm_tools/update_chromeos_llvm_hash.py
+++ b/llvm_tools/update_chromeos_llvm_hash.py
@@ -10,14 +10,13 @@ for review.
"""
import argparse
-import datetime
import enum
import os
from pathlib import Path
import re
import subprocess
import textwrap
-from typing import Dict, Iterable, List, Optional
+from typing import Dict, Iterable, Iterator, List, Optional, Union
import atomic_write_file
import chroot
@@ -64,7 +63,7 @@ class PortagePackage:
chromeos_root, package
)
if potential_ebuild_path.is_symlink():
- self.uprev_target = potential_ebuild_path.absolute()
+ self.uprev_target: Optional[Path] = potential_ebuild_path.absolute()
self.ebuild_path = potential_ebuild_path.resolve()
else:
# Should have a 9999 ebuild, no uprevs needed.
@@ -111,7 +110,8 @@ class PortagePackage:
# We can exit early if we're not working with a live ebuild,
# and we don't have something to uprev.
raise RuntimeError(
- f"Cannot update: no live ebuild or symlink found for {self.package}"
+ "Cannot update: no live ebuild or symlink found"
+ f" for {self.package}"
)
UpdateEbuildLLVMHash(
@@ -139,7 +139,7 @@ def defaultCrosRoot() -> Path:
inside of a CrOS checkout, in which case that checkout should be used.
Returns:
- The best guess location for the cros checkout.
+ The best guess location for the cros checkout.
"""
llvm_tools_path = os.path.realpath(os.path.dirname(__file__))
if llvm_tools_path.endswith("src/third_party/toolchain-utils/llvm_tools"):
@@ -151,10 +151,10 @@ def GetCommandLineArgs():
"""Parses the command line for the optional command line arguments.
Returns:
- The log level to use when retrieving the LLVM hash or google3 LLVM version,
- the chroot path to use for executing chroot commands,
- a list of a package or packages to update their LLVM next hash,
- and the LLVM version to use when retrieving the LLVM hash.
+ The log level to use when retrieving the LLVM hash or google3 LLVM
+ version, the chroot path to use for executing chroot commands, a list
+ of a package or packages to update their LLVM next hash, and the LLVM
+ version to use when retrieving the LLVM hash.
"""
# Create parser and add optional command-line arguments.
@@ -170,7 +170,8 @@ def GetCommandLineArgs():
help="the path to the chroot (default: %(default)s)",
)
- # Add argument for specific builds to uprev and update their llvm-next hash.
+ # Add argument for specific builds to uprev and update their llvm-next
+ # hash.
parser.add_argument(
"--update_packages",
default=",".join(DEFAULT_PACKAGES),
@@ -229,7 +230,21 @@ def GetCommandLineArgs():
help="Updates the llvm-project revision attribute"
" in the internal manifest.",
)
-
+ parser.add_argument(
+ "--no_delete_branch",
+ action="store_true",
+ help="Do not delete the created overlay branch.",
+ )
+ parser.add_argument(
+ "--no_upload_changes",
+ action="store_true",
+ help="Do not upload changes to gerrit.",
+ )
+ parser.add_argument(
+ "--no_patching",
+ action="store_true",
+ help="Do not check or update PATCHES.json.",
+ )
# Parse the command line.
return parser.parse_args()
@@ -239,20 +254,20 @@ def UpdateEbuildLLVMHash(
llvm_variant: LLVMVariant,
git_hash: str,
svn_version: int,
-):
+) -> None:
"""Updates the LLVM hash in the ebuild.
The build changes are staged for commit in the temporary repo.
Args:
- ebuild_path: The absolute path to the ebuild.
- llvm_variant: Which LLVM hash to update.
- git_hash: The new git hash.
- svn_version: The SVN-style revision number of git_hash.
+ ebuild_path: The absolute path to the ebuild.
+ llvm_variant: Which LLVM hash to update.
+ git_hash: The new git hash.
+ svn_version: The SVN-style revision number of git_hash.
Raises:
- ValueError: Invalid ebuild path provided or failed to stage the commit
- of the changes or failed to update the LLVM hash.
+ ValueError: Invalid ebuild path provided or failed to stage the commit
+ of the changes or failed to update the LLVM hash.
"""
# For each ebuild, read the file in
@@ -277,17 +292,22 @@ def UpdateEbuildLLVMHash(
)
-def ReplaceLLVMHash(ebuild_lines, llvm_variant, git_hash, svn_version):
+def ReplaceLLVMHash(
+ ebuild_lines: Iterable[str],
+ llvm_variant: LLVMVariant,
+ git_hash: str,
+ svn_version: int,
+) -> Iterator[str]:
"""Updates the LLVM git hash.
Args:
- ebuild_lines: The contents of the ebuild file.
- llvm_variant: The LLVM hash to update.
- git_hash: The new git hash.
- svn_version: The SVN-style revision number of git_hash.
+ ebuild_lines: The contents of the ebuild file.
+ llvm_variant: The LLVM hash to update.
+ git_hash: The new git hash.
+ svn_version: The SVN-style revision number of git_hash.
Yields:
- lines of the modified ebuild file
+ lines of the modified ebuild file
"""
is_updated = False
llvm_regex = re.compile(
@@ -306,17 +326,17 @@ def ReplaceLLVMHash(ebuild_lines, llvm_variant, git_hash, svn_version):
raise ValueError(f"Failed to update {llvm_variant.value}")
-def UprevEbuildSymlink(symlink):
+def UprevEbuildSymlink(symlink: str) -> None:
"""Uprevs the symlink's revision number.
Increases the revision number by 1 and stages the change in
the temporary repo.
Args:
- symlink: The absolute path of an ebuild symlink.
+ symlink: The absolute path of an ebuild symlink.
Raises:
- ValueError: Failed to uprev the symlink or failed to stage the changes.
+ ValueError: Failed to uprev the symlink or failed to stage the changes.
"""
if not os.path.islink(symlink):
@@ -338,20 +358,20 @@ def UprevEbuildSymlink(symlink):
)
-def UprevEbuildToVersion(symlink, svn_version, git_hash):
+def UprevEbuildToVersion(symlink: str, svn_version: int, git_hash: str) -> None:
"""Uprevs the ebuild's revision number.
Increases the revision number by 1 and stages the change in
the temporary repo.
Args:
- symlink: The absolute path of an ebuild symlink.
- svn_version: The SVN-style revision number of git_hash.
- git_hash: The new git hash.
+ symlink: The absolute path of an ebuild symlink.
+ svn_version: The SVN-style revision number of git_hash.
+ git_hash: The new git hash.
Raises:
- ValueError: Failed to uprev the ebuild or failed to stage the changes.
- AssertionError: No llvm version provided for an LLVM uprev
+ ValueError: Failed to uprev the ebuild or failed to stage the changes.
+ AssertionError: No llvm version provided for an LLVM uprev
"""
if not os.path.islink(symlink):
@@ -365,12 +385,11 @@ def UprevEbuildToVersion(symlink, svn_version, git_hash):
raise ValueError("Tried to uprev an unknown package")
if package == "llvm":
new_ebuild, is_changed = re.subn(
- r"(\d+)\.(\d+)_pre([0-9]+)_p([0-9]+)",
- "%s.\\2_pre%s_p%s"
+ r"(\d+)\.(\d+)_pre([0-9]+)(_p[0-9]+)?",
+ "%s.\\2_pre%s"
% (
llvm_major_version,
- svn_version,
- datetime.datetime.today().strftime("%Y%m%d"),
+ str(svn_version),
),
ebuild,
count=1,
@@ -379,7 +398,7 @@ def UprevEbuildToVersion(symlink, svn_version, git_hash):
else:
new_ebuild, is_changed = re.subn(
r"(\d+)\.(\d+)_pre([0-9]+)",
- "%s.\\2_pre%s" % (llvm_major_version, svn_version),
+ "%s.\\2_pre%s" % (llvm_major_version, str(svn_version)),
ebuild,
count=1,
)
@@ -402,14 +421,14 @@ def UprevEbuildToVersion(symlink, svn_version, git_hash):
subprocess.check_output(["git", "-C", symlink_dir, "rm", symlink])
-def RemovePatchesFromFilesDir(patches):
+def RemovePatchesFromFilesDir(patches: Iterable[str]) -> None:
"""Removes the patches from $FILESDIR of a package.
Args:
- patches: A list of absolute paths of patches to remove
+ patches: A list of absolute paths of patches to remove
Raises:
- ValueError: Failed to remove a patch in $FILESDIR.
+ ValueError: Failed to remove a patch in $FILESDIR.
"""
for patch in patches:
@@ -418,15 +437,15 @@ def RemovePatchesFromFilesDir(patches):
)
-def StagePatchMetadataFileForCommit(patch_metadata_file_path):
+def StagePatchMetadataFileForCommit(patch_metadata_file_path: str) -> None:
"""Stages the updated patch metadata file for commit.
Args:
- patch_metadata_file_path: The absolute path to the patch metadata file.
+ patch_metadata_file_path: The absolute path to the patch metadata file.
Raises:
- ValueError: Failed to stage the patch metadata file for commit or invalid
- patch metadata file.
+ ValueError: Failed to stage the patch metadata file for commit or
+ invalid patch metadata file.
"""
if not os.path.isfile(patch_metadata_file_path):
@@ -446,35 +465,38 @@ def StagePatchMetadataFileForCommit(patch_metadata_file_path):
)
-def StagePackagesPatchResultsForCommit(package_info_dict, commit_messages):
+def StagePackagesPatchResultsForCommit(
+ package_info_dict: Dict[str, patch_utils.PatchInfo],
+ commit_messages: List[str],
+) -> List[str]:
"""Stages the patch results of the packages to the commit message.
Args:
- package_info_dict: A dictionary where the key is the package name and the
- value is a dictionary that contains information about the patches of the
- package (key).
- commit_messages: The commit message that has the updated ebuilds and
- upreving information.
+ package_info_dict: A dictionary where the key is the package name and
+ the value is a dictionary that contains information about the patches
+ of the package (key).
+ commit_messages: The commit message that has the updated ebuilds and
+ upreving information.
Returns:
- commit_messages with new additions
+ commit_messages with new additions
"""
# For each package, check if any patches for that package have
# changed, if so, add which patches have changed to the commit
# message.
- for package_name, patch_info_dict in package_info_dict.items():
+ for package_name, patch_info in package_info_dict.items():
if (
- patch_info_dict["disabled_patches"]
- or patch_info_dict["removed_patches"]
- or patch_info_dict["modified_metadata"]
+ patch_info.disabled_patches
+ or patch_info.removed_patches
+ or patch_info.modified_metadata
):
cur_package_header = f"\nFor the package {package_name}:"
commit_messages.append(cur_package_header)
# Add to the commit message that the patch metadata file was modified.
- if patch_info_dict["modified_metadata"]:
- patch_metadata_path = patch_info_dict["modified_metadata"]
+ if patch_info.modified_metadata:
+ patch_metadata_path = patch_info.modified_metadata
metadata_file_name = os.path.basename(patch_metadata_path)
commit_messages.append(
f"The patch metadata file {metadata_file_name} was modified"
@@ -483,33 +505,33 @@ def StagePackagesPatchResultsForCommit(package_info_dict, commit_messages):
StagePatchMetadataFileForCommit(patch_metadata_path)
# Add each disabled patch to the commit message.
- if patch_info_dict["disabled_patches"]:
+ if patch_info.disabled_patches:
commit_messages.append("The following patches were disabled:")
- for patch_path in patch_info_dict["disabled_patches"]:
+ for patch_path in patch_info.disabled_patches:
commit_messages.append(os.path.basename(patch_path))
# Add each removed patch to the commit message.
- if patch_info_dict["removed_patches"]:
+ if patch_info.removed_patches:
commit_messages.append("The following patches were removed:")
- for patch_path in patch_info_dict["removed_patches"]:
+ for patch_path in patch_info.removed_patches:
commit_messages.append(os.path.basename(patch_path))
- RemovePatchesFromFilesDir(patch_info_dict["removed_patches"])
+ RemovePatchesFromFilesDir(patch_info.removed_patches)
return commit_messages
-def UpdatePortageManifests(packages: Iterable[str], chroot_path: Path):
+def UpdatePortageManifests(packages: Iterable[str], chroot_path: Path) -> None:
"""Updates portage manifest files for packages.
Args:
- packages: A list of packages to update manifests for.
- chroot_path: The absolute path to the chroot.
+ packages: A list of packages to update manifests for.
+ chroot_path: The absolute path to the chroot.
Raises:
- CalledProcessError: ebuild failed to update manifest.
+ CalledProcessError: ebuild failed to update manifest.
"""
manifest_ebuilds = chroot.GetChrootEbuildPaths(chroot_path, packages)
for ebuild_path in manifest_ebuilds:
@@ -529,32 +551,37 @@ def UpdatePackages(
git_hash: str,
svn_version: int,
chroot_path: Path,
- mode,
- git_hash_source,
- extra_commit_msg,
-):
+ mode: Optional[failure_modes.FailureModes],
+ git_hash_source: Union[int, str],
+ extra_commit_msg_lines: Optional[Iterable[str]],
+ delete_branch: bool = True,
+ upload_changes: bool = True,
+) -> Optional[git.CommitContents]:
"""Updates an LLVM hash and uprevs the ebuild of the packages.
A temporary repo is created for the changes. The changes are
then uploaded for review.
Args:
- packages: A list of all the packages that are going to be updated.
- manifest_packages: A list of packages to update manifests for.
- llvm_variant: The LLVM hash to update.
- git_hash: The new git hash.
- svn_version: The SVN-style revision number of git_hash.
- chroot_path: The absolute path to the chroot.
- mode: The mode of the patch manager when handling an applicable patch
- that failed to apply.
- Ex. 'FailureModes.FAIL'
- git_hash_source: The source of which git hash to use based off of.
- Ex. 'google3', 'tot', or <version> such as 365123
- extra_commit_msg: extra test to append to the commit message.
+ packages: A list of all the packages that are going to be updated.
+ manifest_packages: A list of packages to update manifests for.
+ llvm_variant: The LLVM hash to update.
+ git_hash: The new git hash.
+ svn_version: The SVN-style revision number of git_hash.
+ chroot_path: The absolute path to the chroot.
+ mode: The mode of the patch manager when handling an applicable patch.
+ If None is passed, the patch manager won't be invoked.
+ that failed to apply.
+ Ex. 'FailureModes.FAIL'
+ git_hash_source: The source of which git hash to use based off of.
+ Ex. 'google3', 'tot', or <version> such as 365123
+ extra_commit_msg_lines: extra lines to append to the commit message.
+ Newlines are added automatically.
+ delete_branch: Delete the git branch as a final step.
+ upload_changes: Upload the commit to gerrit as a CL.
Returns:
- A nametuple that has two (key, value) pairs, where the first pair is the
- Gerrit commit URL and the second pair is the change list number.
+ If upload_changes is set, a git.CommitContents object. Otherwise None.
"""
portage_packages = (PortagePackage(chroot_path, pkg) for pkg in packages)
@@ -580,6 +607,7 @@ def UpdatePackages(
# Holds the list of packages that are updating.
updated_packages: List[str] = []
+ change_list = None
git.CreateBranch(chromiumos_overlay_path, branch_name)
try:
for pkg in portage_packages:
@@ -592,32 +620,41 @@ def UpdatePackages(
commit_lines.extend(manifest_packages)
EnsurePackageMaskContains(chroot_path, git_hash)
# Handle the patches for each package.
- package_info_dict = UpdatePackagesPatchMetadataFile(
- chroot_path, svn_version, updated_packages, mode
- )
- # Update the commit message if changes were made to a package's patches.
- commit_lines = StagePackagesPatchResultsForCommit(
- package_info_dict, commit_lines
- )
- if extra_commit_msg:
- commit_lines.append(extra_commit_msg)
- change_list = git.UploadChanges(
- chromiumos_overlay_path, branch_name, commit_lines
- )
+ if mode is not None:
+ package_info_dict = UpdatePackagesPatchMetadataFile(
+ chroot_path, svn_version, updated_packages, mode
+ )
+ # Update the commit message if changes were made to a package's
+ # patches.
+ commit_lines = StagePackagesPatchResultsForCommit(
+ package_info_dict, commit_lines
+ )
+ if extra_commit_msg_lines:
+ commit_lines.extend(extra_commit_msg_lines)
+ git.CommitChanges(chromiumos_overlay_path, commit_lines)
+ if upload_changes:
+ change_list = git.UploadChanges(
+ chromiumos_overlay_path, branch_name
+ )
finally:
- git.DeleteBranch(chromiumos_overlay_path, branch_name)
+ if delete_branch:
+ git.DeleteBranch(chromiumos_overlay_path, branch_name)
+ else:
+ print(f"Not deleting branch {branch_name}")
return change_list
-def EnsurePackageMaskContains(chroot_path, git_hash):
- """Adds the major version of llvm to package.mask if it's not already present.
+def EnsurePackageMaskContains(
+ chroot_path: Union[Path, str], git_hash: str
+) -> None:
+ """Adds the major version of llvm to package.mask if not already present.
Args:
- chroot_path: The absolute path to the chroot.
- git_hash: The new git hash.
+ chroot_path: The absolute path to the chroot.
+ git_hash: The new git hash.
Raises:
- FileExistsError: package.mask not found in ../../chromiumos-overlay
+ FileExistsError: package.mask not found in ../../chromiumos-overlay
"""
llvm_major_version = get_llvm_hash.GetLLVMMajorVersion(git_hash)
@@ -646,28 +683,28 @@ def UpdatePackagesPatchMetadataFile(
"""Updates the packages metadata file.
Args:
- chroot_path: The absolute path to the chroot.
- svn_version: The version to use for patch management.
- packages: All the packages to update their patch metadata file.
- mode: The mode for the patch manager to use when an applicable patch
- fails to apply.
- Ex: 'FailureModes.FAIL'
+ chroot_path: The absolute path to the chroot.
+ svn_version: The version to use for patch management.
+ packages: All the packages to update their patch metadata file.
+ mode: The mode for the patch manager to use when an applicable patch
+ fails to apply.
+ Ex: 'FailureModes.FAIL'
Returns:
- A dictionary where the key is the package name and the value is a dictionary
- that has information on the patches.
+ A dictionary where the key is the package name and the value is a
+ dictionary that has information on the patches.
"""
- # A dictionary where the key is the package name and the value is a dictionary
- # that has information on the patches.
- package_info = {}
+ # A dictionary where the key is the package name and the value is a
+ # dictionary that has information on the patches.
+ package_info: Dict[str, patch_utils.PatchInfo] = {}
llvm_hash = get_llvm_hash.LLVMHash()
with llvm_hash.CreateTempDirectory() as temp_dir:
with get_llvm_hash.CreateTempLLVMRepo(temp_dir) as dirname:
- # Ensure that 'svn_version' exists in the chromiumum mirror of LLVM by
- # finding its corresponding git hash.
+ # Ensure that 'svn_version' exists in the chromiumum mirror of
+ # LLVM by finding its corresponding git hash.
git_hash = get_llvm_hash.GetGitHashFrom(dirname, svn_version)
move_head_cmd = ["git", "-C", dirname, "checkout", git_hash, "-q"]
subprocess.run(move_head_cmd, stdout=subprocess.DEVNULL, check=True)
@@ -696,9 +733,9 @@ def UpdatePackagesPatchMetadataFile(
src_path = Path(dirname)
with patch_utils.git_clean_context(src_path):
- if (
- mode == failure_modes.FailureModes.FAIL
- or mode == failure_modes.FailureModes.CONTINUE
+ if mode in (
+ failure_modes.FailureModes.FAIL,
+ failure_modes.FailureModes.CONTINUE,
):
patches_info = patch_utils.apply_all_from_json(
svn_version=svn_version,
@@ -718,17 +755,26 @@ def UpdatePackagesPatchMetadataFile(
else:
raise RuntimeError(f"unsupported failure mode: {mode}")
- package_info[cur_package] = patches_info._asdict()
+ package_info[cur_package] = patches_info
return package_info
-def ChangeRepoManifest(git_hash: str, src_tree: Path):
+def ChangeRepoManifest(
+ git_hash: str,
+ src_tree: Path,
+ extra_commit_msg_lines: Optional[Iterable[str]] = None,
+ delete_branch=True,
+ upload_changes=True,
+):
"""Change the repo internal manifest for llvm-project.
Args:
git_hash: The LLVM git hash to change to.
src_tree: ChromiumOS source tree checkout.
+ extra_commit_msg_lines: Lines to append to the commit message.
+ delete_branch: Delete the branch as a final step.
+ upload_changes: Upload the changes to gerrit.
Returns:
The uploaded changelist CommitContents.
@@ -740,7 +786,7 @@ def ChangeRepoManifest(git_hash: str, src_tree: Path):
f"""
manifest: Update llvm-project to {git_hash}
- Upgrade the local LLVM reversion to match the new llvm ebuild
+ Upgrade the local LLVM revision to match the new llvm ebuild
hash. This must be merged along with any chromiumos-overlay
changes to LLVM. Automatic uprevs rely on the manifest hash
to match what is specified by LLVM_HASH.
@@ -755,6 +801,7 @@ def ChangeRepoManifest(git_hash: str, src_tree: Path):
.splitlines()
)
+ change_list = None
git.CreateBranch(manifest_dir, branch_name)
try:
manifest_path = manifest_utils.update_chromeos_manifest(
@@ -764,9 +811,16 @@ def ChangeRepoManifest(git_hash: str, src_tree: Path):
subprocess.run(
["git", "-C", manifest_dir, "add", manifest_path.name], check=True
)
- change_list = git.UploadChanges(manifest_dir, branch_name, commit_lines)
+ if extra_commit_msg_lines:
+ commit_lines.extend(extra_commit_msg_lines)
+ git.CommitChanges(manifest_dir, commit_lines)
+ if upload_changes:
+ change_list = git.UploadChanges(manifest_dir, branch_name)
finally:
- git.DeleteBranch(manifest_dir, branch_name)
+ if delete_branch:
+ git.DeleteBranch(manifest_dir, branch_name)
+ else:
+ print(f"Not deleting branch {branch_name}")
return change_list
@@ -774,7 +828,7 @@ def main():
"""Updates the LLVM next hash for each package.
Raises:
- AssertionError: The script was run inside the chroot.
+ AssertionError: The script was run inside the chroot.
"""
chroot.VerifyOutsideChroot()
@@ -800,6 +854,12 @@ def main():
if not manifest_packages and not args_output.is_llvm_next:
# Set default manifest packages only for the current llvm.
manifest_packages = set(DEFAULT_MANIFEST_PACKAGES)
+
+ if args_output.no_patching:
+ patch_update_mode = None
+ else:
+ patch_update_mode = failure_modes.FailureModes(args_output.failure_mode)
+
change_list = UpdatePackages(
packages=packages,
manifest_packages=manifest_packages,
@@ -807,25 +867,43 @@ def main():
git_hash=git_hash,
svn_version=svn_version,
chroot_path=args_output.chroot_path,
- mode=failure_modes.FailureModes(args_output.failure_mode),
+ mode=patch_update_mode,
git_hash_source=git_hash_source,
- extra_commit_msg=None,
+ extra_commit_msg_lines=None,
+ delete_branch=not args_output.no_delete_branch,
+ upload_changes=not args_output.no_upload_changes,
)
-
- print(f"Successfully updated packages to {git_hash} ({svn_version})")
- print(f"Gerrit URL: {change_list.url}")
- print(f"Change list number: {change_list.cl_number}")
+ if change_list:
+ print(f"Successfully updated packages to {git_hash} ({svn_version})")
+ print(f"Gerrit URL: {change_list.url}")
+ print(f"Change list number: {change_list.cl_number}")
+ else:
+ print("--no-upload passed, did not create a change list")
if args_output.repo_manifest:
print(
f"Updating internal manifest to {git_hash} ({svn_version})...",
end="",
)
- change_list = ChangeRepoManifest(git_hash, args_output.chroot_path)
+ cq_depend_line = (
+ [f"Cq-Depend: chromium:{change_list.cl_number}"]
+ if change_list
+ else None
+ )
+ change_list = ChangeRepoManifest(
+ git_hash,
+ args_output.chroot_path,
+ extra_commit_msg_lines=cq_depend_line,
+ delete_branch=not args_output.no_delete_branch,
+ upload_changes=not args_output.no_upload_changes,
+ )
print(" Done!")
- print("New repo manifest CL:")
- print(f" URL: {change_list.url}")
- print(f" CL Number: {change_list.cl_number}")
+ if change_list:
+ print("New repo manifest CL:")
+ print(f" URL: {change_list.url}")
+ print(f" CL Number: {change_list.cl_number}")
+ else:
+ print("--no-upload passed, did not create a change list")
if __name__ == "__main__":
diff --git a/llvm_tools/update_chromeos_llvm_hash_unittest.py b/llvm_tools/update_chromeos_llvm_hash_unittest.py
index 568242aa..ad0bca75 100755
--- a/llvm_tools/update_chromeos_llvm_hash_unittest.py
+++ b/llvm_tools/update_chromeos_llvm_hash_unittest.py
@@ -5,21 +5,19 @@
"""Unit tests for updating LLVM hashes."""
-
-import collections
-import datetime
import os
from pathlib import Path
import subprocess
import sys
import tempfile
+from typing import Optional, Union
import unittest
-import unittest.mock as mock
+from unittest import mock
import chroot
import failure_modes
import get_llvm_hash
-import git
+import patch_utils
import test_helpers
import update_chromeos_llvm_hash
@@ -31,6 +29,21 @@ import update_chromeos_llvm_hash
class UpdateLLVMHashTest(unittest.TestCase):
"""Test class for updating LLVM hashes of packages."""
+ @staticmethod
+ def _make_patch_entry(
+ relpath: Union[str, Path], workdir: Optional[Path] = None
+ ) -> patch_utils.PatchEntry:
+ if workdir is None:
+ workdir = Path("llvm_tools/update_chromeos_llvm_hash_unittest.py")
+ return patch_utils.PatchEntry(
+ workdir=workdir,
+ rel_patch_path=str(relpath),
+ metadata={},
+ platforms=["chromiumos"],
+ version_range={"from": None, "until": None},
+ verify_workdir=False,
+ )
+
@mock.patch.object(os.path, "realpath")
def testDefaultCrosRootFromCrOSCheckout(self, mock_llvm_tools):
llvm_tools_path = (
@@ -65,7 +78,8 @@ class UpdateLLVMHashTest(unittest.TestCase):
)
self.assertEqual(
- str(err.exception), "Invalid ebuild path provided: %s" % ebuild_path
+ str(err.exception),
+ "Invalid ebuild path provided: %s" % ebuild_path,
)
mock_isfile.assert_called_once()
@@ -75,7 +89,7 @@ class UpdateLLVMHashTest(unittest.TestCase):
def testFailedToUpdateLLVMHash(self, mock_isfile):
# Create a temporary file to simulate an ebuild file of a package.
with test_helpers.CreateTemporaryJsonFile() as ebuild_file:
- with open(ebuild_file, "w") as f:
+ with open(ebuild_file, "w", encoding="utf-8") as f:
f.write(
"\n".join(
[
@@ -108,7 +122,7 @@ class UpdateLLVMHashTest(unittest.TestCase):
def testFailedToUpdateLLVMNextHash(self, mock_isfile):
# Create a temporary file to simulate an ebuild file of a package.
with test_helpers.CreateTemporaryJsonFile() as ebuild_file:
- with open(ebuild_file, "w") as f:
+ with open(ebuild_file, "w", encoding="utf-8") as f:
f.write(
"\n".join(
[
@@ -149,7 +163,7 @@ class UpdateLLVMHashTest(unittest.TestCase):
git_hash = "a123testhash1"
svn_version = 1000
- with open(ebuild_file, "w") as f:
+ with open(ebuild_file, "w", encoding="utf-8") as f:
f.write(
"\n".join(
[
@@ -172,12 +186,11 @@ class UpdateLLVMHashTest(unittest.TestCase):
"Last line in the ebuild",
]
- # Verify the new file contents of the ebuild file match the expected file
- # contents.
- with open(ebuild_file) as new_file:
- file_contents_as_a_list = [cur_line for cur_line in new_file]
+ # Verify the new file contents of the ebuild file match the expected
+ # file contents.
+ with open(ebuild_file, encoding="utf-8") as new_file:
self.assertListEqual(
- file_contents_as_a_list, expected_file_contents
+ new_file.readlines(), expected_file_contents
)
self.assertEqual(mock_isfile.call_count, 2)
@@ -197,7 +210,7 @@ class UpdateLLVMHashTest(unittest.TestCase):
git_hash = "a123testhash1"
svn_version = 1000
- with open(ebuild_file, "w") as f:
+ with open(ebuild_file, "w", encoding="utf-8") as f:
f.write(
"\n".join(
[
@@ -220,12 +233,11 @@ class UpdateLLVMHashTest(unittest.TestCase):
"Last line in the ebuild",
]
- # Verify the new file contents of the ebuild file match the expected file
- # contents.
- with open(ebuild_file) as new_file:
- file_contents_as_a_list = [cur_line for cur_line in new_file]
+ # Verify the new file contents of the ebuild file match the expected
+ # file contents.
+ with open(ebuild_file, encoding="utf-8") as new_file:
self.assertListEqual(
- file_contents_as_a_list, expected_file_contents
+ new_file.readlines(), expected_file_contents
)
self.assertEqual(mock_isfile.call_count, 2)
@@ -242,7 +254,8 @@ class UpdateLLVMHashTest(unittest.TestCase):
git_hash = "badf00d"
mock_llvm_version.return_value = "1234"
- # Verify the exception is raised when a invalid symbolic link is passed in.
+ # Verify the exception is raised when a invalid symbolic link is
+ # passed in.
with self.assertRaises(ValueError) as err:
update_chromeos_llvm_hash.UprevEbuildToVersion(
symlink_path, svn_version, git_hash
@@ -259,7 +272,8 @@ class UpdateLLVMHashTest(unittest.TestCase):
def testFailedToUprevEbuildSymlinkForInvalidSymlink(self, mock_islink):
symlink_path = "/path/to/chroot/package/package.ebuild"
- # Verify the exception is raised when a invalid symbolic link is passed in.
+ # Verify the exception is raised when a invalid symbolic link is
+ # passed in.
with self.assertRaises(ValueError) as err:
update_chromeos_llvm_hash.UprevEbuildSymlink(symlink_path)
@@ -314,7 +328,11 @@ class UpdateLLVMHashTest(unittest.TestCase):
@mock.patch.object(os.path, "realpath")
@mock.patch.object(subprocess, "check_output", return_value=None)
def testSuccessfullyUprevEbuildToVersionLLVM(
- self, mock_command_output, mock_realpath, mock_islink, mock_llvm_version
+ self,
+ mock_command_output,
+ mock_realpath,
+ mock_islink,
+ mock_llvm_version,
):
symlink = "/path/to/llvm/llvm-12.0_pre3_p2-r10.ebuild"
ebuild = "/abs/path/to/llvm/llvm-12.0_pre3_p2.ebuild"
@@ -337,10 +355,7 @@ class UpdateLLVMHashTest(unittest.TestCase):
# Verify commands
symlink_dir = os.path.dirname(symlink)
- timestamp = datetime.datetime.today().strftime("%Y%m%d")
- new_ebuild = (
- "/abs/path/to/llvm/llvm-1234.0_pre1000_p%s.ebuild" % timestamp
- )
+ new_ebuild = "/abs/path/to/llvm/llvm-1234.0_pre1000.ebuild"
new_symlink = new_ebuild[: -len(".ebuild")] + "-r1.ebuild"
expected_cmd = ["git", "-C", symlink_dir, "mv", ebuild, new_ebuild]
@@ -514,27 +529,30 @@ class UpdateLLVMHashTest(unittest.TestCase):
mock_run_cmd.assert_called_once()
def testNoPatchResultsForCommit(self):
- package_1_patch_info_dict = {
- "applied_patches": ["display_results.patch"],
- "failed_patches": ["fixes_output.patch"],
- "non_applicable_patches": [],
- "disabled_patches": [],
- "removed_patches": [],
- "modified_metadata": None,
- }
-
- package_2_patch_info_dict = {
- "applied_patches": ["redirects_stdout.patch", "fix_display.patch"],
- "failed_patches": [],
- "non_applicable_patches": [],
- "disabled_patches": [],
- "removed_patches": [],
- "modified_metadata": None,
- }
+ package_1_patch_info = patch_utils.PatchInfo(
+ applied_patches=[self._make_patch_entry("display_results.patch")],
+ failed_patches=[self._make_patch_entry("fixes_output.patch")],
+ non_applicable_patches=[],
+ disabled_patches=[],
+ removed_patches=[],
+ modified_metadata=None,
+ )
+
+ package_2_patch_info = patch_utils.PatchInfo(
+ applied_patches=[
+ self._make_patch_entry("redirects_stdout.patch"),
+ self._make_patch_entry("fix_display.patch"),
+ ],
+ failed_patches=[],
+ non_applicable_patches=[],
+ disabled_patches=[],
+ removed_patches=[],
+ modified_metadata=None,
+ )
test_package_info_dict = {
- "test-packages/package1": package_1_patch_info_dict,
- "test-packages/package2": package_2_patch_info_dict,
+ "test-packages/package1": package_1_patch_info,
+ "test-packages/package2": package_2_patch_info,
}
test_commit_message = ["Updated packages"]
@@ -553,27 +571,27 @@ class UpdateLLVMHashTest(unittest.TestCase):
def testAddedPatchResultsForCommit(
self, mock_remove_patches, mock_stage_patches_for_commit
):
- package_1_patch_info_dict = {
- "applied_patches": [],
- "failed_patches": [],
- "non_applicable_patches": [],
- "disabled_patches": ["fixes_output.patch"],
- "removed_patches": [],
- "modified_metadata": "/abs/path/to/filesdir/PATCHES.json",
- }
+ package_1_patch_info = patch_utils.PatchInfo(
+ applied_patches=[],
+ failed_patches=[],
+ non_applicable_patches=[],
+ disabled_patches=["fixes_output.patch"],
+ removed_patches=[],
+ modified_metadata="/abs/path/to/filesdir/PATCHES.json",
+ )
- package_2_patch_info_dict = {
- "applied_patches": ["fix_display.patch"],
- "failed_patches": [],
- "non_applicable_patches": [],
- "disabled_patches": [],
- "removed_patches": ["/abs/path/to/filesdir/redirect_stdout.patch"],
- "modified_metadata": "/abs/path/to/filesdir/PATCHES.json",
- }
+ package_2_patch_info = patch_utils.PatchInfo(
+ applied_patches=[self._make_patch_entry("fix_display.patch")],
+ failed_patches=[],
+ non_applicable_patches=[],
+ disabled_patches=[],
+ removed_patches=["/abs/path/to/filesdir/redirect_stdout.patch"],
+ modified_metadata="/abs/path/to/filesdir/PATCHES.json",
+ )
test_package_info_dict = {
- "test-packages/package1": package_1_patch_info_dict,
- "test-packages/package2": package_2_patch_info_dict,
+ "test-packages/package1": package_1_patch_info,
+ "test-packages/package2": package_2_patch_info,
}
test_commit_message = ["Updated packages"]
@@ -661,14 +679,14 @@ class UpdateLLVMHashTest(unittest.TestCase):
@mock.patch("subprocess.check_output")
@mock.patch.object(get_llvm_hash, "GetLLVMMajorVersion")
def testUpdatePackages(
- self, mock_llvm_major_version, mock_check_output, mock_run
+ self, mock_llvm_major_version, _mock_check_output, _mock_run
):
mock_llvm_major_version.return_value = "17"
with tempfile.TemporaryDirectory(
"update_chromeos_llvm_hash.tmp"
) as workdir_str:
src_tree = Path(workdir_str)
- package_dir, ebuild_path, symlink_path = self.setup_mock_src_tree(
+ _package_dir, _ebuild_path, symlink_path = self.setup_mock_src_tree(
src_tree
)
@@ -726,7 +744,9 @@ class UpdateLLVMHashTest(unittest.TestCase):
chroot_path=expected_chroot,
mode=failure_modes.FailureModes.FAIL,
git_hash_source="google3",
- extra_commit_msg=None,
+ extra_commit_msg_lines=None,
+ delete_branch=True,
+ upload_changes=True,
)
mock_outside_chroot.assert_called()
mock_chromeos_root.assert_called()
@@ -768,7 +788,9 @@ class UpdateLLVMHashTest(unittest.TestCase):
chroot_path=expected_chroot,
mode=failure_modes.FailureModes.FAIL,
git_hash_source="google3",
- extra_commit_msg=None,
+ extra_commit_msg_lines=None,
+ delete_branch=True,
+ upload_changes=True,
)
mock_outside_chroot.assert_called()
mock_chromeos_root.assert_called()
@@ -825,7 +847,9 @@ class UpdateLLVMHashTest(unittest.TestCase):
chroot_path=chroot_path,
mode=failure_mode,
git_hash_source=llvm_ver,
- extra_commit_msg=None,
+ extra_commit_msg_lines=None,
+ delete_branch=True,
+ upload_changes=True,
)
mock_outside_chroot.assert_called()
mock_chromeos_root.assert_called()
diff --git a/llvm_tools/update_packages_and_run_tests.py b/llvm_tools/update_packages_and_run_tests.py
index 598d9099..b0655fe2 100755
--- a/llvm_tools/update_packages_and_run_tests.py
+++ b/llvm_tools/update_packages_and_run_tests.py
@@ -5,13 +5,13 @@
"""Runs a tryjob/tryjobs after updating the packages."""
-
import argparse
import datetime
import json
import os
from pathlib import Path
import subprocess
+from typing import Any, Dict, Iterable, List, Optional, Union
import chroot
import failure_modes
@@ -19,10 +19,10 @@ import get_llvm_hash
import update_chromeos_llvm_hash
-VALID_CQ_TRYBOTS = ["llvm", "llvm-next", "llvm-tot"]
+VALID_CQ_TRYBOTS = ("llvm", "llvm-next")
-def GetCommandLineArgs():
+def GetCommandLineArgs() -> argparse.Namespace:
"""Parses the command line for the command line arguments.
Returns:
@@ -156,7 +156,10 @@ def GetCommandLineArgs():
return args_output
-def UnchangedSinceLastRun(last_tested_file, arg_dict):
+def UnchangedSinceLastRun(
+ last_tested_file: Optional[Union[Path, str]],
+ arg_dict: Dict,
+) -> bool:
"""Gets the arguments used for last run
Args:
@@ -184,8 +187,18 @@ def UnchangedSinceLastRun(last_tested_file, arg_dict):
return arg_dict == last_arg_dict
-def AddReviewers(cl, reviewers, chroot_path):
- """Add reviewers for the created CL."""
+def AddReviewers(
+ cl: int,
+ reviewers: Iterable[str],
+ chroot_path: Union[Path, str],
+) -> None:
+ """Add reviewers for the created CL.
+
+ Args:
+ cl: The CL number to add reviewers to.
+ reviewers: Email addresses of reviewers to add.
+ chroot_path: The absolute path to the chroot.
+ """
gerrit_abs_path = os.path.join(chroot_path, "chromite/bin/gerrit")
for reviewer in reviewers:
@@ -194,8 +207,18 @@ def AddReviewers(cl, reviewers, chroot_path):
subprocess.check_output(cmd)
-def AddLinksToCL(tests, cl, chroot_path):
- """Adds the test link(s) to the CL as a comment."""
+def AddLinksToCL(
+ tests: Iterable[Dict[str, Any]],
+ cl: int,
+ chroot_path: Union[Path, str],
+) -> None:
+ """Adds the test link(s) to the CL as a comment.
+
+ Args:
+ tests: Links to the tests.
+ cl: The number of the CL to add the test links to.
+ chroot_path: Absolute path to the chroot.
+ """
# NOTE: Invoking `cros_sdk` does not make each tryjob link appear on its
# own line, so invoking the `gerrit` command directly instead of using
@@ -214,12 +237,17 @@ def AddLinksToCL(tests, cl, chroot_path):
# Testing with tryjobs
-def GetCurrentTimeInUTC():
+def GetCurrentTimeInUTC() -> datetime.datetime:
"""Returns the current time via `datetime.datetime.utcnow()`."""
return datetime.datetime.utcnow()
-def GetTryJobCommand(change_list, extra_change_lists, options, builder):
+def GetTryJobCommand(
+ change_list: int,
+ extra_change_lists: Iterable[int],
+ options: Iterable[str],
+ builder: str,
+) -> List[str]:
"""Constructs the 'tryjob' command.
Args:
@@ -248,7 +276,13 @@ def GetTryJobCommand(change_list, extra_change_lists, options, builder):
return tryjob_cmd
-def RunTryJobs(cl_number, extra_change_lists, options, builders, chroot_path):
+def RunTryJobs(
+ cl_number: int,
+ extra_change_lists: List[int],
+ options: List[str],
+ builders: Iterable[str],
+ chroot_path: Union[Path, str],
+) -> List[Dict]:
"""Runs a tryjob/tryjobs.
Args:
@@ -300,8 +334,12 @@ def RunTryJobs(cl_number, extra_change_lists, options, builders, chroot_path):
def StartRecipeBuilders(
- cl_number, extra_change_lists, options, builders, chroot_path
-):
+ cl_number: int,
+ extra_change_lists: List[int],
+ options: List[str],
+ builders: List[str],
+ chroot_path: Union[Path, str],
+) -> List[Dict]:
"""Launch recipe builders.
Args:
@@ -363,19 +401,17 @@ def StartRecipeBuilders(
# Testing with CQ
-def GetCQDependString(dependent_cls):
+def GetCQDependString(dependent_cls: List[int]) -> Optional[str]:
"""Get CQ dependency string e.g. `Cq-Depend: chromium:MM, chromium:NN`."""
if not dependent_cls:
return None
# Cq-Depend must start a new paragraph prefixed with "Cq-Depend".
- return "\nCq-Depend: " + ", ".join(
- ("chromium:%s" % i) for i in dependent_cls
- )
+ return "Cq-Depend: " + ", ".join(f"chromium:{x}" for x in dependent_cls)
-def GetCQIncludeTrybotsString(trybot):
+def GetCQIncludeTrybotsString(trybot: Optional[str]) -> Optional[str]:
"""Get Cq-Include-Trybots string, for more llvm testings"""
if not trybot:
@@ -386,10 +422,14 @@ def GetCQIncludeTrybotsString(trybot):
# Cq-Include-Trybots must start a new paragraph prefixed
# with "Cq-Include-Trybots".
- return "\nCq-Include-Trybots:chromeos/cq:cq-%s-orchestrator" % trybot
+ return "Cq-Include-Trybots:chromeos/cq:cq-%s-orchestrator" % trybot
-def StartCQDryRun(cl, dependent_cls, chroot_path):
+def StartCQDryRun(
+ cl: int,
+ dependent_cls: List[int],
+ chroot_path: Union[Path, str],
+) -> None:
"""Start CQ dry run for the changelist and dependencies."""
gerrit_abs_path = os.path.join(chroot_path, "chromite/bin/gerrit")
@@ -449,14 +489,22 @@ def main():
llvm_variant = update_chromeos_llvm_hash.LLVMVariant.current
if args_output.is_llvm_next:
llvm_variant = update_chromeos_llvm_hash.LLVMVariant.next
- extra_commit_msg = None
+
+ extra_commit_msg_lines = []
if args_output.subparser_name == "cq":
+ footers = []
cq_depend_msg = GetCQDependString(args_output.extra_change_lists)
if cq_depend_msg:
- extra_commit_msg = cq_depend_msg
+ footers.append(cq_depend_msg)
cq_trybot_msg = GetCQIncludeTrybotsString(args_output.cq_trybot)
if cq_trybot_msg:
- extra_commit_msg += cq_trybot_msg
+ footers.append(cq_trybot_msg)
+
+ # We want a single blank line before any of these, so Git properly
+ # interprets them as a footer.
+ if footers:
+ extra_commit_msg_lines.append("")
+ extra_commit_msg_lines += footers
change_list = update_chromeos_llvm_hash.UpdatePackages(
packages=update_chromeos_llvm_hash.DEFAULT_PACKAGES,
@@ -467,7 +515,7 @@ def main():
chroot_path=Path(args_output.chroot_path),
mode=failure_modes.FailureModes.DISABLE_PATCHES,
git_hash_source=svn_option,
- extra_commit_msg=extra_commit_msg,
+ extra_commit_msg_lines=extra_commit_msg_lines,
)
AddReviewers(
diff --git a/llvm_tools/update_packages_and_run_tests_unittest.py b/llvm_tools/update_packages_and_run_tests_unittest.py
index e62ed04f..76482c4e 100755
--- a/llvm_tools/update_packages_and_run_tests_unittest.py
+++ b/llvm_tools/update_packages_and_run_tests_unittest.py
@@ -1,16 +1,14 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Unittests for running tests after updating packages."""
-
import json
import subprocess
import unittest
-import unittest.mock as mock
+from unittest import mock
import chroot
import get_llvm_hash
@@ -65,7 +63,7 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase):
"tryjob_options": ["latest-toolchain", "hwtest"],
}
- with open(last_tested_file, "w") as f:
+ with open(last_tested_file, "w", encoding="utf-8") as f:
f.write(json.dumps(arg_dict, indent=2))
self.assertEqual(
@@ -136,7 +134,6 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase):
def testSuccessfullySubmittedTryJob(
self, mock_cmd, mock_add_links_to_cl, mock_launch_time
):
-
expected_cmd = [
"cros",
"tryjob",
@@ -189,7 +186,6 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase):
def testSuccessfullySubmittedRecipeBuilders(
self, mock_cmd, mock_add_links_to_cl
):
-
expected_cmd = [
"bb",
"add",
@@ -276,9 +272,8 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase):
mock_update_packages,
mock_run_tryjobs,
):
-
- # Create a temporary file to simulate the last tested file that contains a
- # revision.
+ # Create a temporary file to simulate the last tested file that
+ # contains a revision.
with test_helpers.CreateTemporaryFile() as last_tested_file:
builders = [
"kevin-llvm-next-toolchain-tryjob",
@@ -299,7 +294,7 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase):
"tryjob_options": tryjob_options,
}
# Parepared last tested file
- with open(last_tested_file, "w") as f:
+ with open(last_tested_file, "w", encoding="utf-8") as f:
json.dump(arg_dict, f, indent=2)
# Call with a changed LLVM svn version
@@ -329,9 +324,9 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase):
update_packages_and_run_tests.main()
- # Verify that the lasted tested file has been updated to the new LLVM
- # revision.
- with open(last_tested_file) as f:
+ # Verify that the lasted tested file has been updated to the new
+ # LLVM revision.
+ with open(last_tested_file, encoding="utf-8") as f:
arg_dict = json.load(f)
self.assertEqual(arg_dict["svn_version"], 200)
@@ -347,6 +342,12 @@ class UpdatePackagesAndRunTryjobsTest(unittest.TestCase):
mock_run_tryjobs.assert_called_once()
mock_update_packages.assert_called_once()
+ commit_msg_lines = mock_update_packages.call_args[1][
+ "extra_commit_msg_lines"
+ ]
+ self.assertTrue(
+ isinstance(commit_msg_lines, list), repr(commit_msg_lines)
+ )
class UpdatePackagesAndRunTestCQTest(unittest.TestCase):
@@ -365,14 +366,14 @@ class UpdatePackagesAndRunTestCQTest(unittest.TestCase):
update_packages_and_run_tests.GetCQDependString(
test_single_changelist
),
- "\nCq-Depend: chromium:1234",
+ "Cq-Depend: chromium:1234",
)
self.assertEqual(
update_packages_and_run_tests.GetCQDependString(
test_multiple_changelists
),
- "\nCq-Depend: chromium:1234, chromium:5678",
+ "Cq-Depend: chromium:1234, chromium:5678",
)
def testGetCQIncludeTrybotsString(self):
@@ -390,7 +391,7 @@ class UpdatePackagesAndRunTestCQTest(unittest.TestCase):
update_packages_and_run_tests.GetCQIncludeTrybotsString(
test_valid_trybot
),
- "\nCq-Include-Trybots:chromeos/cq:cq-llvm-next-orchestrator",
+ "Cq-Include-Trybots:chromeos/cq:cq-llvm-next-orchestrator",
)
with self.assertRaises(ValueError) as context:
diff --git a/llvm_tools/update_tryjob_status.py b/llvm_tools/update_tryjob_status.py
index 49c48658..e68bd6a8 100755
--- a/llvm_tools/update_tryjob_status.py
+++ b/llvm_tools/update_tryjob_status.py
@@ -1,12 +1,10 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Updates the status of a tryjob."""
-
import argparse
import enum
import json
@@ -15,7 +13,7 @@ import subprocess
import sys
import chroot
-from test_helpers import CreateTemporaryJsonFile
+import test_helpers
class TryjobStatus(enum.Enum):
@@ -70,8 +68,8 @@ def GetCommandLineArgs():
parser.add_argument(
"--status_file",
required=True,
- help="The absolute path to the JSON file that contains the tryjobs used "
- "for bisecting LLVM.",
+ help="The absolute path to the JSON file that contains the tryjobs "
+ "used for bisecting LLVM.",
)
# Add argument that sets the 'status' field to that value.
@@ -135,19 +133,19 @@ def FindTryjobIndex(revision, tryjobs_list):
'revision.'
Args:
- revision: The revision to search for in the tryjobs.
- tryjobs_list: A list of tryjob dictionaries of the format:
+ revision: The revision to search for in the tryjobs.
+ tryjobs_list: A list of tryjob dictionaries of the format:
{
- 'rev' : [REVISION],
- 'url' : [URL_OF_CL],
- 'cl' : [CL_NUMBER],
- 'link' : [TRYJOB_LINK],
- 'status' : [TRYJOB_STATUS],
- 'buildbucket_id': [BUILDBUCKET_ID]
+ 'rev' : [REVISION],
+ 'url' : [URL_OF_CL],
+ 'cl' : [CL_NUMBER],
+ 'link' : [TRYJOB_LINK],
+ 'status' : [TRYJOB_STATUS],
+ 'buildbucket_id': [BUILDBUCKET_ID]
}
Returns:
- The index within the list or None to indicate it was not found.
+ The index within the list or None to indicate it was not found.
"""
for cur_index, cur_tryjob_dict in enumerate(tryjobs_list):
@@ -161,24 +159,24 @@ def GetCustomScriptResult(custom_script, status_file, tryjob_contents):
"""Returns the conversion of the exit code of the custom script.
Args:
- custom_script: Absolute path to the script to be executed.
- status_file: Absolute path to the file that contains information about the
- bisection of LLVM.
- tryjob_contents: A dictionary of the contents of the tryjob (e.g. 'status',
- 'url', 'link', 'buildbucket_id', etc.).
+ custom_script: Absolute path to the script to be executed.
+ status_file: Absolute path to the file that contains information about
+ the bisection of LLVM.
+ tryjob_contents: A dictionary of the contents of the tryjob (e.g.
+ 'status', 'url', 'link', 'buildbucket_id', etc.).
Returns:
- The exit code conversion to either return 'good', 'bad', or 'skip'.
+ The exit code conversion to either return 'good', 'bad', or 'skip'.
Raises:
- ValueError: The custom script failed to provide the correct exit code.
+ ValueError: The custom script failed to provide the correct exit code.
"""
# Create a temporary file to write the contents of the tryjob at index
# 'tryjob_index' (the temporary file path will be passed into the custom
# script as a command line argument).
- with CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as tryjob_file:
+ with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
+ with open(temp_json_file, "w", encoding="utf-8") as tryjob_file:
json.dump(
tryjob_contents, tryjob_file, indent=4, separators=(",", ": ")
)
@@ -186,10 +184,10 @@ def GetCustomScriptResult(custom_script, status_file, tryjob_contents):
exec_script_cmd = [custom_script, temp_json_file]
# Execute the custom script to get the exit code.
- exec_script_cmd_obj = subprocess.Popen(
+ with subprocess.Popen(
exec_script_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE
- )
- _, stderr = exec_script_cmd_obj.communicate()
+ ) as exec_script_cmd_obj:
+ _, stderr = exec_script_cmd_obj.communicate()
# Invalid exit code by the custom script.
if (
@@ -226,13 +224,13 @@ def UpdateTryjobStatus(revision, set_status, status_file, custom_script):
"""Updates a tryjob's 'status' field based off of 'set_status'.
Args:
- revision: The revision associated with the tryjob.
- set_status: What to update the 'status' field to.
- Ex: TryjobStatus.Good, TryjobStatus.BAD, TryjobStatus.PENDING, or
- TryjobStatus.
- status_file: The .JSON file that contains the tryjobs.
- custom_script: The absolute path to a script that will be executed which
- will determine the 'status' value of the tryjob.
+ revision: The revision associated with the tryjob.
+ set_status: What to update the 'status' field to.
+ Ex: TryjobStatus.Good, TryjobStatus.BAD, TryjobStatus.PENDING, or
+ TryjobStatus.
+ status_file: The .JSON file that contains the tryjobs.
+ custom_script: The absolute path to a script that will be executed
+ which will determine the 'status' value of the tryjob.
"""
# Format of 'bisect_contents':
@@ -246,7 +244,7 @@ def UpdateTryjobStatus(revision, set_status, status_file, custom_script):
# {[TRYJOB_INFORMATION]}
# ]
# }
- with open(status_file) as tryjobs:
+ with open(status_file, encoding="utf-8") as tryjobs:
bisect_contents = json.load(tryjobs)
if not bisect_contents["jobs"]:
@@ -284,7 +282,7 @@ def UpdateTryjobStatus(revision, set_status, status_file, custom_script):
'Invalid "set_status" option provided: %s' % set_status
)
- with open(status_file, "w") as update_tryjobs:
+ with open(status_file, "w", encoding="utf-8") as update_tryjobs:
json.dump(
bisect_contents, update_tryjobs, indent=4, separators=(",", ": ")
)
diff --git a/llvm_tools/update_tryjob_status_unittest.py b/llvm_tools/update_tryjob_status_unittest.py
index fd9250a3..632bab58 100755
--- a/llvm_tools/update_tryjob_status_unittest.py
+++ b/llvm_tools/update_tryjob_status_unittest.py
@@ -1,23 +1,19 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Tests when updating a tryjob's status."""
-
+import contextlib
import json
import os
import subprocess
import unittest
-import unittest.mock as mock
+from unittest import mock
-from test_helpers import CreateTemporaryJsonFile
-from test_helpers import WritePrettyJsonFile
+import test_helpers
import update_tryjob_status
-from update_tryjob_status import CustomScriptStatus
-from update_tryjob_status import TryjobStatus
class UpdateTryjobStatusTest(unittest.TestCase):
@@ -85,23 +81,21 @@ class UpdateTryjobStatusTest(unittest.TestCase):
def testInvalidExitCodeByCustomScript(
self, mock_basename, mock_rename_file, mock_exec_custom_script
):
-
error_message_by_custom_script = "Failed to parse .JSON file"
- # Simulate the behavior of 'subprocess.Popen()' when executing the custom
- # script.
+ # Simulate the behavior of 'subprocess.Popen()' when executing the
+ # custom script.
#
# `Popen.communicate()` returns a tuple of `stdout` and `stderr`.
- mock_exec_custom_script.return_value.communicate.return_value = (
+ popen_result = mock.MagicMock()
+ popen_result.communicate.return_value = (
None,
error_message_by_custom_script,
)
-
- # Exit code of 1 is not in the mapping, so an exception will be raised.
custom_script_exit_code = 1
-
- mock_exec_custom_script.return_value.returncode = (
- custom_script_exit_code
+ popen_result.returncode = custom_script_exit_code
+ mock_exec_custom_script.return_value = contextlib.nullcontext(
+ popen_result
)
tryjob_contents = {
@@ -126,9 +120,9 @@ class UpdateTryjobStatusTest(unittest.TestCase):
% (
custom_script_path,
custom_script_exit_code,
- CustomScriptStatus.GOOD.value,
- CustomScriptStatus.BAD.value,
- CustomScriptStatus.SKIP.value,
+ update_tryjob_status.CustomScriptStatus.GOOD.value,
+ update_tryjob_status.CustomScriptStatus.BAD.value,
+ update_tryjob_status.CustomScriptStatus.SKIP.value,
name_json_file,
error_message_by_custom_script,
)
@@ -159,18 +153,20 @@ class UpdateTryjobStatusTest(unittest.TestCase):
def testValidExitCodeByCustomScript(
self, mock_basename, mock_rename_file, mock_exec_custom_script
):
-
- # Simulate the behavior of 'subprocess.Popen()' when executing the custom
- # script.
+ # Simulate the behavior of 'subprocess.Popen()' when executing the
+ # custom script.
#
# `Popen.communicate()` returns a tuple of `stdout` and `stderr`.
- mock_exec_custom_script.return_value.communicate.return_value = (
+ popen_result = mock.MagicMock()
+ popen_result.communicate.return_value = (
None,
None,
)
-
- mock_exec_custom_script.return_value.returncode = (
- CustomScriptStatus.GOOD.value
+ popen_result.returncode = (
+ update_tryjob_status.CustomScriptStatus.GOOD.value
+ )
+ mock_exec_custom_script.return_value = contextlib.nullcontext(
+ popen_result
)
tryjob_contents = {
@@ -187,7 +183,7 @@ class UpdateTryjobStatusTest(unittest.TestCase):
update_tryjob_status.GetCustomScriptResult(
custom_script_path, status_file_path, tryjob_contents
),
- TryjobStatus.GOOD.value,
+ update_tryjob_status.TryjobStatus.GOOD.value,
)
mock_exec_custom_script.assert_called_once()
@@ -199,22 +195,22 @@ class UpdateTryjobStatusTest(unittest.TestCase):
def testNoTryjobsInStatusFileWhenUpdatingTryjobStatus(self):
bisect_test_contents = {"start": 369410, "end": 369420, "jobs": []}
- # Create a temporary .JSON file to simulate a .JSON file that has bisection
- # contents.
- with CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as f:
- WritePrettyJsonFile(bisect_test_contents, f)
+ # Create a temporary .JSON file to simulate a .JSON file that has
+ # bisection contents.
+ with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
+ with open(temp_json_file, "w", encoding="utf-8") as f:
+ test_helpers.WritePrettyJsonFile(bisect_test_contents, f)
revision_to_update = 369412
custom_script = None
- # Verify the exception is raised when the `status_file` does not have any
- # `jobs` (empty).
+ # Verify the exception is raised when the `status_file` does not
+ # have any `jobs` (empty).
with self.assertRaises(SystemExit) as err:
update_tryjob_status.UpdateTryjobStatus(
revision_to_update,
- TryjobStatus.GOOD,
+ update_tryjob_status.TryjobStatus.GOOD,
temp_json_file,
custom_script,
)
@@ -223,37 +219,36 @@ class UpdateTryjobStatusTest(unittest.TestCase):
str(err.exception), "No tryjobs in %s" % temp_json_file
)
- # Simulate the behavior of `FindTryjobIndex()` when the tryjob does not exist
- # in the status file.
+ # Simulate the behavior of `FindTryjobIndex()` when the tryjob does not
+ # exist in the status file.
@mock.patch.object(
update_tryjob_status, "FindTryjobIndex", return_value=None
)
def testNotFindTryjobIndexWhenUpdatingTryjobStatus(
self, mock_find_tryjob_index
):
-
bisect_test_contents = {
"start": 369410,
"end": 369420,
"jobs": [{"rev": 369411, "status": "pending"}],
}
- # Create a temporary .JSON file to simulate a .JSON file that has bisection
- # contents.
- with CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as f:
- WritePrettyJsonFile(bisect_test_contents, f)
+ # Create a temporary .JSON file to simulate a .JSON file that has
+ # bisection contents.
+ with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
+ with open(temp_json_file, "w", encoding="utf-8") as f:
+ test_helpers.WritePrettyJsonFile(bisect_test_contents, f)
revision_to_update = 369416
custom_script = None
- # Verify the exception is raised when the `status_file` does not have any
- # `jobs` (empty).
+ # Verify the exception is raised when the `status_file` does not
+ # have any `jobs` (empty).
with self.assertRaises(ValueError) as err:
update_tryjob_status.UpdateTryjobStatus(
revision_to_update,
- TryjobStatus.SKIP,
+ update_tryjob_status.TryjobStatus.SKIP,
temp_json_file,
custom_script,
)
@@ -276,33 +271,35 @@ class UpdateTryjobStatusTest(unittest.TestCase):
"jobs": [{"rev": 369411, "status": "pending"}],
}
- # Create a temporary .JSON file to simulate a .JSON file that has bisection
- # contents.
- with CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as f:
- WritePrettyJsonFile(bisect_test_contents, f)
+ # Create a temporary .JSON file to simulate a .JSON file that has
+ # bisection contents.
+ with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
+ with open(temp_json_file, "w", encoding="utf-8") as f:
+ test_helpers.WritePrettyJsonFile(bisect_test_contents, f)
revision_to_update = 369411
- # Index of the tryjob that is going to have its 'status' value updated.
+ # Index of the tryjob that is going to have its 'status' value
+ # updated.
tryjob_index = 0
custom_script = None
update_tryjob_status.UpdateTryjobStatus(
revision_to_update,
- TryjobStatus.GOOD,
+ update_tryjob_status.TryjobStatus.GOOD,
temp_json_file,
custom_script,
)
- # Verify that the tryjob's 'status' has been updated in the status file.
- with open(temp_json_file) as status_file:
+ # Verify that the tryjob's 'status' has been updated in the status
+ # file.
+ with open(temp_json_file, encoding="utf-8") as status_file:
bisect_contents = json.load(status_file)
self.assertEqual(
bisect_contents["jobs"][tryjob_index]["status"],
- TryjobStatus.GOOD.value,
+ update_tryjob_status.TryjobStatus.GOOD.value,
)
mock_find_tryjob_index.assert_called_once()
@@ -317,33 +314,35 @@ class UpdateTryjobStatusTest(unittest.TestCase):
"jobs": [{"rev": 369411, "status": "pending"}],
}
- # Create a temporary .JSON file to simulate a .JSON file that has bisection
- # contents.
- with CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as f:
- WritePrettyJsonFile(bisect_test_contents, f)
+ # Create a temporary .JSON file to simulate a .JSON file that has
+ # bisection contents.
+ with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
+ with open(temp_json_file, "w", encoding="utf-8") as f:
+ test_helpers.WritePrettyJsonFile(bisect_test_contents, f)
revision_to_update = 369411
- # Index of the tryjob that is going to have its 'status' value updated.
+ # Index of the tryjob that is going to have its 'status' value
+ # updated.
tryjob_index = 0
custom_script = None
update_tryjob_status.UpdateTryjobStatus(
revision_to_update,
- TryjobStatus.BAD,
+ update_tryjob_status.TryjobStatus.BAD,
temp_json_file,
custom_script,
)
- # Verify that the tryjob's 'status' has been updated in the status file.
- with open(temp_json_file) as status_file:
+ # Verify that the tryjob's 'status' has been updated in the status
+ # file.
+ with open(temp_json_file, encoding="utf-8") as status_file:
bisect_contents = json.load(status_file)
self.assertEqual(
bisect_contents["jobs"][tryjob_index]["status"],
- TryjobStatus.BAD.value,
+ update_tryjob_status.TryjobStatus.BAD.value,
)
mock_find_tryjob_index.assert_called_once()
@@ -360,15 +359,16 @@ class UpdateTryjobStatusTest(unittest.TestCase):
"jobs": [{"rev": 369411, "status": "skip"}],
}
- # Create a temporary .JSON file to simulate a .JSON file that has bisection
- # contents.
- with CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as f:
- WritePrettyJsonFile(bisect_test_contents, f)
+ # Create a temporary .JSON file to simulate a .JSON file that has
+ # bisection contents.
+ with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
+ with open(temp_json_file, "w", encoding="utf-8") as f:
+ test_helpers.WritePrettyJsonFile(bisect_test_contents, f)
revision_to_update = 369411
- # Index of the tryjob that is going to have its 'status' value updated.
+ # Index of the tryjob that is going to have its 'status' value
+ # updated.
tryjob_index = 0
custom_script = None
@@ -380,8 +380,9 @@ class UpdateTryjobStatusTest(unittest.TestCase):
custom_script,
)
- # Verify that the tryjob's 'status' has been updated in the status file.
- with open(temp_json_file) as status_file:
+ # Verify that the tryjob's 'status' has been updated in the status
+ # file.
+ with open(temp_json_file, encoding="utf-8") as status_file:
bisect_contents = json.load(status_file)
self.assertEqual(
@@ -406,15 +407,16 @@ class UpdateTryjobStatusTest(unittest.TestCase):
],
}
- # Create a temporary .JSON file to simulate a .JSON file that has bisection
- # contents.
- with CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as f:
- WritePrettyJsonFile(bisect_test_contents, f)
+ # Create a temporary .JSON file to simulate a .JSON file that has
+ # bisection contents.
+ with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
+ with open(temp_json_file, "w", encoding="utf-8") as f:
+ test_helpers.WritePrettyJsonFile(bisect_test_contents, f)
revision_to_update = 369411
- # Index of the tryjob that is going to have its 'status' value updated.
+ # Index of the tryjob that is going to have its 'status' value
+ # updated.
tryjob_index = 0
custom_script = None
@@ -426,8 +428,9 @@ class UpdateTryjobStatusTest(unittest.TestCase):
custom_script,
)
- # Verify that the tryjob's 'status' has been updated in the status file.
- with open(temp_json_file) as status_file:
+ # Verify that the tryjob's 'status' has been updated in the status
+ # file.
+ with open(temp_json_file, encoding="utf-8") as status_file:
bisect_contents = json.load(status_file)
self.assertEqual(
@@ -441,7 +444,7 @@ class UpdateTryjobStatusTest(unittest.TestCase):
@mock.patch.object(
update_tryjob_status,
"GetCustomScriptResult",
- return_value=TryjobStatus.SKIP.value,
+ return_value=update_tryjob_status.TryjobStatus.SKIP.value,
)
def testUpdatedTryjobStatusToAutoPassedWithCustomScript(
self, mock_get_custom_script_result, mock_find_tryjob_index
@@ -454,15 +457,16 @@ class UpdateTryjobStatusTest(unittest.TestCase):
],
}
- # Create a temporary .JSON file to simulate a .JSON file that has bisection
- # contents.
- with CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as f:
- WritePrettyJsonFile(bisect_test_contents, f)
+ # Create a temporary .JSON file to simulate a .JSON file that has
+ # bisection contents.
+ with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
+ with open(temp_json_file, "w", encoding="utf-8") as f:
+ test_helpers.WritePrettyJsonFile(bisect_test_contents, f)
revision_to_update = 369411
- # Index of the tryjob that is going to have its 'status' value updated.
+ # Index of the tryjob that is going to have its 'status' value
+ # updated.
tryjob_index = 0
custom_script_path = "/abs/path/to/custom_script.py"
@@ -474,8 +478,9 @@ class UpdateTryjobStatusTest(unittest.TestCase):
custom_script_path,
)
- # Verify that the tryjob's 'status' has been updated in the status file.
- with open(temp_json_file) as status_file:
+ # Verify that the tryjob's 'status' has been updated in the status
+ # file.
+ with open(temp_json_file, encoding="utf-8") as status_file:
bisect_contents = json.load(status_file)
self.assertEqual(
@@ -493,7 +498,6 @@ class UpdateTryjobStatusTest(unittest.TestCase):
def testSetStatusDoesNotExistWhenUpdatingTryjobStatus(
self, mock_find_tryjob_index
):
-
bisect_test_contents = {
"start": 369410,
"end": 369420,
@@ -502,11 +506,11 @@ class UpdateTryjobStatusTest(unittest.TestCase):
],
}
- # Create a temporary .JSON file to simulate a .JSON file that has bisection
- # contents.
- with CreateTemporaryJsonFile() as temp_json_file:
- with open(temp_json_file, "w") as f:
- WritePrettyJsonFile(bisect_test_contents, f)
+ # Create a temporary .JSON file to simulate a .JSON file that has
+ # bisection contents.
+ with test_helpers.CreateTemporaryJsonFile() as temp_json_file:
+ with open(temp_json_file, "w", encoding="utf-8") as f:
+ test_helpers.WritePrettyJsonFile(bisect_test_contents, f)
revision_to_update = 369411
diff --git a/llvm_tools/werror_logs.py b/llvm_tools/werror_logs.py
new file mode 100755
index 00000000..f8a526f1
--- /dev/null
+++ b/llvm_tools/werror_logs.py
@@ -0,0 +1,577 @@
+#!/usr/bin/env python3
+# Copyright 2024 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Helps reason about -Werror logs emitted by the compiler wrapper.
+
+Specifically, this works with the -Werror reports produced by the compiler
+wrapper in FORCE_DISABLE_WERROR mode. It's intended to be run on trees of these
+reports, so devs can run roughly the following commands:
+
+$ apply_force_disable_werror # (There's no actual script to do this today.)
+$ build_packages --board=foo --nousepkg
+$ ./werror_logs.py aggregate --directory=/build/foo/var/lib/chromeos
+
+And see a full aggregation of all warnings that were suppressed in that
+`build_packages` invocation.
+
+It can also be used to fetch warnings reports from CQ runs, for instance,
+$ ./werror_logs.py fetch-cq --cq-orchestrator-id=123456
+
+In this case, it downloads _all -Werror logs_ from children of the given
+cq-orchestrator, and prints the parent directory of all of these reports. If
+you run `aggregate` on this directory, it's highly recommended to use the
+`--canonicalize-board-roots` flag.
+"""
+
+import argparse
+import collections
+import dataclasses
+import json
+import logging
+import multiprocessing.pool
+import os
+from pathlib import Path
+import re
+import shutil
+import subprocess
+import sys
+import tempfile
+import threading
+from typing import Any, Counter, DefaultDict, Dict, IO, Iterable, List, Optional
+
+import cros_cls
+
+
+_DEFAULT_FETCH_DIRECTORY = Path("/tmp/werror_logs")
+
+
+def canonicalize_file_path_board_root(file_path: str) -> str:
+ # Get rid of double slashes, unnecessary directory traversal
+ # (foo/../bar/..), etc. Easier to read this way.
+ file_path = os.path.normpath(file_path)
+ if file_path.startswith("/build/"):
+ i = file_path.find("/", len("/build/"))
+ if i != -1:
+ return f"/build/{{board}}/{file_path[i+1:]}"
+ return file_path
+
+
+@dataclasses.dataclass(frozen=True, eq=True, order=True)
+class ClangWarningLocation:
+ """Represents a location at which a Clang warning was emitted."""
+
+ file: str
+ line: int
+ column: int
+
+ @classmethod
+ def parse(
+ cls, location: str, canonicalize_board_root: bool = False
+ ) -> "ClangWarningLocation":
+ split = location.rsplit(":", 2)
+ if len(split) == 3:
+ file = split[0]
+ if canonicalize_board_root:
+ file = canonicalize_file_path_board_root(file)
+ return cls(file=file, line=int(split[1]), column=int(split[2]))
+ raise ValueError(f"Invalid location: {location!r}")
+
+
+@dataclasses.dataclass(frozen=True, eq=True)
+class ClangWarning:
+ """Represents a Clang warning at a specific location (if applicable)."""
+
+ # The name of the warning, e.g., -Wunused-variable
+ name: str
+ # The message of the warning, e.g., "'allocate' is deprecated."
+ message: str
+ # The location of this warning. Not present for frontend diagnostics.
+ location: Optional[ClangWarningLocation]
+
+ # This parses two kinds of errors:
+ # 1. `clang-17: error: foo [-W...]`
+ # 2. `/file/path:123:45: error: foo [-W...]"
+ _WARNING_RE = re.compile(
+ # Capture the location on its own, since `clang-\d+` is unused below.
+ r"^(?:([^:]*:\d+:\d+)|clang-\d+)"
+ r": error: "
+ # Capture the message
+ r"(.*?)\s+"
+ r"\[(-W[^\][]+)]\s*$"
+ )
+
+ @classmethod
+ def try_parse_line(
+ cls, line: str, canonicalize_board_root: bool = False
+ ) -> Optional["ClangWarning"]:
+ # Fast path: we can expect "error: " in interesting lines. Break early
+ # if that's not present.
+ if "error: " not in line:
+ return None
+
+ m = cls._WARNING_RE.fullmatch(line)
+ if not m:
+ return None
+
+ location, message, warning_flags = m.groups()
+ individual_warning_flags = [
+ x for x in warning_flags.split(",") if x != "-Werror"
+ ]
+
+ # This isn't impossible to handle in theory, just unexpected. Complain
+ # about it.
+ if len(individual_warning_flags) != 1:
+ raise ValueError(
+ f"Weird: parsed warnings {individual_warning_flags} out "
+ f"of {line}"
+ )
+
+ if location is None:
+ parsed_location = None
+ else:
+ parsed_location = ClangWarningLocation.parse(
+ location, canonicalize_board_root
+ )
+ return cls(
+ name=individual_warning_flags[0],
+ message=message,
+ location=parsed_location,
+ )
+
+
+@dataclasses.dataclass(frozen=True, eq=True)
+class WarningInfo:
+ """Carries information about a ClangWarning."""
+
+ packages: DefaultDict[str, int] = dataclasses.field(
+ default_factory=lambda: collections.defaultdict(int)
+ )
+
+
+class UnknownPackageNameError(ValueError):
+ """Raised when a package name can't be determined from a warning report."""
+
+
+@dataclasses.dataclass
+class AggregatedWarnings:
+ """Aggregates warning reports incrementally."""
+
+ num_reports: int = 0
+ # Mapping of warning -> list of packages that emitted it. Warnings in
+ # headers may be referred to by multiple packages.
+ warnings: DefaultDict[ClangWarning, WarningInfo] = dataclasses.field(
+ default_factory=lambda: collections.defaultdict(WarningInfo)
+ )
+
+ _CWD_PACKAGE_RE = re.compile(
+ r"^(?:/build/[^/]+)?/var/(?:cache|tmp)/portage/([^/]+/[^/]+)/"
+ )
+
+ @classmethod
+ def _guess_package_name(cls, report: Dict[str, Any]) -> str:
+ """Tries to guess what package `report` is from.
+
+ Raises:
+ UnknownPackageNameError if the package's name couldn't be
+ determined.
+ """
+ m = cls._CWD_PACKAGE_RE.match(report.get("cwd", ""))
+ if not m:
+ raise UnknownPackageNameError()
+ return m.group(1)
+
+ def add_report_json(
+ self, report_json: Dict[str, Any], canonicalize_board_root: bool = False
+ ) -> int:
+ """Adds the given report, returning the number of warnings parsed.
+
+ Raises:
+ UnknownPackageNameError if the package's name couldn't be
+ determined.
+ """
+ self.num_reports += 1
+ package_name = self._guess_package_name(report_json)
+
+ num_warnings = 0
+ for line in report_json.get("stdout", "").splitlines():
+ if parsed := ClangWarning.try_parse_line(
+ line, canonicalize_board_root
+ ):
+ self.warnings[parsed].packages[package_name] += 1
+ num_warnings += 1
+
+ return num_warnings
+
+ def add_report(
+ self, report_file: Path, canonicalize_board_root: bool = False
+ ) -> None:
+ with report_file.open(encoding="utf-8") as f:
+ report = json.load(f)
+
+ try:
+ n = self.add_report_json(report, canonicalize_board_root)
+ except UnknownPackageNameError:
+ logging.warning(
+ "Failed guessing package name for report at %r; ignoring file",
+ report_file,
+ )
+ return
+
+ if not n:
+ logging.warning(
+ "Report at %r had no parseable warnings", report_file
+ )
+
+
+def print_aligned_counts(
+ name_count_map: Dict[str, int], file: Optional[IO[str]] = None
+) -> None:
+ assert name_count_map
+ # Sort on value, highest first. Name breaks ties.
+ summary = sorted(name_count_map.items(), key=lambda x: (-x[1], x[0]))
+ num_col_width = len(f"{summary[0][1]:,}")
+ name_col_width = max(len(x) for x in name_count_map)
+ for name, count in summary:
+ fmt_name = name.rjust(name_col_width)
+ fmt_count = f"{count:,}".rjust(num_col_width)
+ print(f"\t{fmt_name}: {fmt_count}", file=file)
+
+
+def summarize_per_package_warnings(
+ warning_infos: Iterable[WarningInfo],
+ file: Optional[IO[str]] = None,
+) -> None:
+ warnings_per_package: DefaultDict[str, int] = collections.defaultdict(int)
+ for info in warning_infos:
+ for package_name, warning_count in info.packages.items():
+ warnings_per_package[package_name] += warning_count
+
+ if not warnings_per_package:
+ return
+
+ print("## Per-package warning counts:", file=file)
+ print_aligned_counts(warnings_per_package, file=file)
+
+
+def summarize_warnings_by_flag(
+ warnings: Dict[ClangWarning, WarningInfo],
+ file: Optional[IO[str]] = None,
+) -> None:
+ if not warnings:
+ return
+
+ warnings_per_flag: Counter[str] = collections.Counter()
+ for warning, info in warnings.items():
+ warnings_per_flag[warning.name] += sum(info.packages.values())
+
+ print("## Instances of each fatal warning:", file=file)
+ print_aligned_counts(warnings_per_flag, file=file)
+
+
+def aggregate_reports(opts: argparse.Namespace) -> None:
+ directory = opts.directory
+ aggregated = AggregatedWarnings()
+ for report in directory.glob("**/warnings_report*.json"):
+ logging.debug("Discovered report %s", report)
+ aggregated.add_report(report, opts.canonicalize_board_roots)
+
+ if not aggregated.num_reports:
+ raise ValueError(f"Found no warnings report under {directory}")
+
+ logging.info("Discovered %d report files in total", aggregated.num_reports)
+ summarize_per_package_warnings(aggregated.warnings.values())
+ summarize_warnings_by_flag(aggregated.warnings)
+
+
+def fetch_werror_tarball_links(
+ child_builders: Dict[str, cros_cls.BuildID]
+) -> List[str]:
+ outputs = cros_cls.CQBoardBuilderOutput.fetch_many(child_builders.values())
+ artifacts_links = []
+ for builder_name, out in zip(child_builders, outputs):
+ if out.artifacts_link:
+ artifacts_links.append(out.artifacts_link)
+ else:
+ logging.info("%s had no output artifacts; ignoring", builder_name)
+
+ gsutil_stdout = subprocess.run(
+ ["gsutil", "-m", "ls"] + artifacts_links,
+ check=True,
+ encoding="utf-8",
+ stdin=subprocess.DEVNULL,
+ stdout=subprocess.PIPE,
+ ).stdout
+
+ return [
+ x
+ for x in gsutil_stdout.splitlines()
+ if x.endswith(".fatal_clang_warnings.tar.xz")
+ ]
+
+
+def cq_builder_name_from_werror_logs_path(werror_logs: str) -> str:
+ """Returns the CQ builder given a -Werror logs path.
+
+ >>> cq_builder_name_from_werror_logs_path(
+ "gs://chromeos-image-archive/staryu-cq/"
+ "R123-15771.0.0-94466-8756713501925941617/"
+ "staryu.20240207.fatal_clang_warnings.tar.xz"
+ )
+ "staryu-cq"
+ """
+ return os.path.basename(os.path.dirname(os.path.dirname(werror_logs)))
+
+
+def download_and_unpack_werror_tarballs(
+ unpack_dir: Path, download_dir: Path, gs_urls: List[str]
+):
+ # This is necessary below when we're untarring files. It should trivially
+ # always be the case, and assuming it makes testing easier.
+ assert download_dir.is_absolute(), download_dir
+
+ unpack_dir.mkdir()
+ download_dir.mkdir()
+
+ logging.info(
+ "Fetching and unpacking %d -Werror reports; this may take a bit",
+ len(gs_urls),
+ )
+ # Run the download in a threadpool since we can have >100 logs, and all of
+ # this is heavily I/O-bound.
+ # Max 8 downloads at a time is arbitrary, but should minimize the chance of
+ # rate-limiting. Don't limit `tar xaf`, since those should be short-lived.
+ download_limiter = threading.BoundedSemaphore(8)
+
+ def download_one_url(
+ unpack_dir: Path, download_dir: Path, gs_url: str
+ ) -> Optional[subprocess.CalledProcessError]:
+ """Downloads and unpacks -Werror logs from the given gs_url.
+
+ Leaves the tarball in `download_dir`, and the unpacked version in
+ `unpack_dir`.
+
+ Returns:
+ None if all went well; otherwise, returns the command that failed.
+ All commands have stderr data piped in.
+ """
+ file_targ = download_dir / os.path.basename(gs_url)
+ try:
+ with download_limiter:
+ subprocess.run(
+ ["gsutil", "cp", gs_url, file_targ],
+ check=True,
+ stdin=subprocess.DEVNULL,
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.PIPE,
+ encoding="utf-8",
+ errors="replace",
+ )
+
+ # N.B., file_targ is absolute, so running with `file_targ` while
+ # changing `cwd` is safe.
+ subprocess.run(
+ ["tar", "xaf", file_targ],
+ check=True,
+ cwd=unpack_dir,
+ stdin=subprocess.DEVNULL,
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.PIPE,
+ encoding="utf-8",
+ errors="replace",
+ )
+ except subprocess.CalledProcessError as e:
+ return e
+ return None
+
+ with multiprocessing.pool.ThreadPool() as thread_pool:
+ download_futures = []
+ for gs_url in gs_urls:
+ name = cq_builder_name_from_werror_logs_path(gs_url)
+ unpack_to = unpack_dir / name
+ unpack_to.mkdir()
+ download_to = download_dir / name
+ download_to.mkdir()
+ download_futures.append(
+ (
+ name,
+ thread_pool.apply_async(
+ download_one_url, (unpack_to, download_to, gs_url)
+ ),
+ )
+ )
+
+ num_failures = 0
+ for name, future in download_futures:
+ result = future.get()
+ if not result:
+ continue
+
+ num_failures += 1
+ logging.error(
+ "Downloading %s failed: running %r. Stderr: %r",
+ name,
+ result.cmd,
+ result.stderr,
+ )
+ if num_failures:
+ raise ValueError(f"{num_failures} download(s) failed.")
+
+
+def fetch_cq_reports(opts: argparse.Namespace) -> None:
+ if opts.cl:
+ logging.info(
+ "Fetching most recent completed CQ orchestrator from %s", opts.cl
+ )
+ all_ids = cros_cls.fetch_cq_orchestrator_ids(opts.cl)
+ if not all_ids:
+ raise ValueError(
+ f"No CQ orchestrators found under {opts.cl}. See --help for "
+ "how to pass a build ID directly."
+ )
+ # Note that these cq-orchestrator runs are returned in oldest-to-newest
+ # order. The user probably wants the newest run.
+ cq_orchestrator_id = all_ids[-1]
+ cq_orchestrator_url = cros_cls.builder_url(cq_orchestrator_id)
+ logging.info("Checking CQ run %s", cq_orchestrator_url)
+ else:
+ cq_orchestrator_id = opts.cq_orchestrator_id
+ cq_orchestrator_url = cros_cls.builder_url(cq_orchestrator_id)
+
+ # This is the earliest point at which we can compute this directory with
+ # certainty. Figure it out now and fail early if it exists.
+ output_directory = opts.directory
+ if not output_directory:
+ output_directory = _DEFAULT_FETCH_DIRECTORY / str(cq_orchestrator_id)
+
+ if output_directory.exists():
+ if not opts.force:
+ sys.exit(
+ f"Directory at {output_directory} exists; not overwriting. "
+ "Pass --force to overwrite."
+ )
+ # Actually _remove_ it when we have all logs unpacked and are able to
+ # create the output directory with confidence.
+
+ logging.info("Fetching info on child builders of %s", cq_orchestrator_url)
+ child_builders = cros_cls.CQOrchestratorOutput.fetch(
+ cq_orchestrator_id
+ ).child_builders
+ if not child_builders:
+ raise ValueError(f"No child builders found for {cq_orchestrator_url}")
+
+ logging.info(
+ "%d child builders found; finding associated tarball links",
+ len(child_builders),
+ )
+ werror_links = fetch_werror_tarball_links(child_builders)
+ if not werror_links:
+ raise ValueError(
+ f"No -Werror logs found in children of {cq_orchestrator_url}"
+ )
+
+ logging.info("%d -Werror logs found", len(werror_links))
+ with tempfile.TemporaryDirectory("werror_logs_fetch_cq") as t:
+ tempdir = Path(t)
+ unpack_dir = tempdir / "unpacked"
+ download_and_unpack_werror_tarballs(
+ unpack_dir=unpack_dir,
+ download_dir=tempdir / "tarballs",
+ gs_urls=werror_links,
+ )
+
+ if output_directory.exists():
+ logging.info("Removing output directory at %s", output_directory)
+ shutil.rmtree(output_directory)
+ output_directory.parent.mkdir(parents=True, exist_ok=True)
+ # (Convert these to strs to keep mypy happy.)
+ shutil.move(str(unpack_dir), str(output_directory))
+ logging.info(
+ "CQ logs from %s stored in %s",
+ cq_orchestrator_url,
+ output_directory,
+ )
+
+
+def main(argv: List[str]) -> None:
+ parser = argparse.ArgumentParser(
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+ parser.add_argument(
+ "--debug", action="store_true", help="Enable debug logging"
+ )
+ subparsers = parser.add_subparsers(required=True)
+ # b/318833638: While there's only one subparser here for the moment, more
+ # are expected to come (specifically, one to download logs from a CQ run).
+ aggregate = subparsers.add_parser(
+ "aggregate",
+ help="""
+ Aggregate all -Werror reports beneath a directory. Note that this will
+ traverse all children of the directory, so can be used either on
+ unpacked -Werror reports from CQ builders, or can be used on e.g.,
+ /build/cherry/var/lib/chromeos.
+ """,
+ )
+ aggregate.set_defaults(func=aggregate_reports)
+ aggregate.add_argument(
+ "--canonicalize-board-roots",
+ action="store_true",
+ help="""
+ Converts warnings paths starting with a board root (e.g., /build/atlas)
+ to a form consistent across many boards.
+ """,
+ )
+ aggregate.add_argument(
+ "--directory", type=Path, required=True, help="Directory to inspect."
+ )
+
+ fetch_cq = subparsers.add_parser(
+ "fetch-cq",
+ help="Fetch all -Werror reports for a CQ run.",
+ )
+ fetch_cq.set_defaults(func=fetch_cq_reports)
+ cl_or_cq_orchestrator = fetch_cq.add_mutually_exclusive_group(required=True)
+ cl_or_cq_orchestrator.add_argument(
+ "--cl",
+ type=cros_cls.ChangeListURL.parse_with_patch_set,
+ help="Link to a CL to get the most recent cq-orchestrator from",
+ )
+ cl_or_cq_orchestrator.add_argument(
+ "--cq-orchestrator-id",
+ type=cros_cls.BuildID,
+ help="""
+ Build number for a cq-orchestrator run. Builders invoked by this are
+ examined for -Werror logs.
+ """,
+ )
+ fetch_cq.add_argument(
+ "--directory",
+ type=Path,
+ help=f"""
+ Directory to put downloaded -Werror logs in. Default is a subdirectory
+ of {_DEFAULT_FETCH_DIRECTORY}.
+ """,
+ )
+ fetch_cq.add_argument(
+ "-f",
+ "--force",
+ action="store_true",
+ help="Remove the directory at `--directory` if it exists",
+ )
+
+ opts = parser.parse_args(argv)
+
+ logging.basicConfig(
+ format=">> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: "
+ "%(message)s",
+ level=logging.DEBUG if opts.debug else logging.INFO,
+ )
+
+ assert getattr(opts, "func", None), "Unknown subcommand?"
+ opts.func(opts)
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/llvm_tools/werror_logs_test.py b/llvm_tools/werror_logs_test.py
new file mode 100755
index 00000000..c6489389
--- /dev/null
+++ b/llvm_tools/werror_logs_test.py
@@ -0,0 +1,425 @@
+#!/usr/bin/env python3
+# Copyright 2024 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Tests for werror_logs.py."""
+
+import io
+import logging
+import os
+from pathlib import Path
+import shutil
+import subprocess
+import tempfile
+import textwrap
+from typing import Dict
+import unittest
+from unittest import mock
+
+import werror_logs
+
+
+class SilenceLogs:
+ """Used by Test.silence_logs to ignore all logging output."""
+
+ def filter(self, _record):
+ return False
+
+
+def create_warning_info(packages: Dict[str, int]) -> werror_logs.WarningInfo:
+ """Constructs a WarningInfo conveniently in one line.
+
+ Mostly useful because `WarningInfo` has a defaultdict field, and those
+ don't `assertEqual` to regular dict fields.
+ """
+ x = werror_logs.WarningInfo()
+ x.packages.update(packages)
+ return x
+
+
+class Test(unittest.TestCase):
+ """Tests for werror_logs."""
+
+ def silence_logs(self):
+ f = SilenceLogs()
+ log = logging.getLogger()
+ log.addFilter(f)
+ self.addCleanup(log.removeFilter, f)
+
+ def make_tempdir(self) -> Path:
+ tempdir = tempfile.mkdtemp("werror_logs_test_")
+ self.addCleanup(shutil.rmtree, tempdir)
+ return Path(tempdir)
+
+ def test_clang_warning_parsing_parses_flag_errors(self):
+ self.assertEqual(
+ werror_logs.ClangWarning.try_parse_line(
+ "clang-17: error: optimization flag -foo is not supported "
+ "[-Werror,-Wfoo]"
+ ),
+ werror_logs.ClangWarning(
+ name="-Wfoo",
+ message="optimization flag -foo is not supported",
+ location=None,
+ ),
+ )
+
+ def test_clang_warning_parsing_doesnt_care_about_werror_order(self):
+ self.assertEqual(
+ werror_logs.ClangWarning.try_parse_line(
+ "clang-17: error: optimization flag -foo is not supported "
+ "[-Wfoo,-Werror]"
+ ),
+ werror_logs.ClangWarning(
+ name="-Wfoo",
+ message="optimization flag -foo is not supported",
+ location=None,
+ ),
+ )
+
+ def test_clang_warning_parsing_parses_code_errors(self):
+ self.assertEqual(
+ werror_logs.ClangWarning.try_parse_line(
+ "/path/to/foo/bar/baz.cc:12:34: error: don't do this "
+ "[-Werror,-Wbar]"
+ ),
+ werror_logs.ClangWarning(
+ name="-Wbar",
+ message="don't do this",
+ location=werror_logs.ClangWarningLocation(
+ file="/path/to/foo/bar/baz.cc",
+ line=12,
+ column=34,
+ ),
+ ),
+ )
+
+ def test_clang_warning_parsing_parses_implicit_errors(self):
+ self.assertEqual(
+ werror_logs.ClangWarning.try_parse_line(
+ # N.B., "-Werror" is missing in this message
+ "/path/to/foo/bar/baz.cc:12:34: error: don't do this "
+ "[-Wbar]"
+ ),
+ werror_logs.ClangWarning(
+ name="-Wbar",
+ message="don't do this",
+ location=werror_logs.ClangWarningLocation(
+ file="/path/to/foo/bar/baz.cc",
+ line=12,
+ column=34,
+ ),
+ ),
+ )
+
+ def test_clang_warning_parsing_canonicalizes_correctly(self):
+ canonical_forms = (
+ ("/build/foo/bar/baz.cc", "/build/{board}/bar/baz.cc"),
+ ("///build//foo///bar//baz.cc", "/build/{board}/bar/baz.cc"),
+ ("/build/baz.cc", "/build/baz.cc"),
+ ("/build.cc", "/build.cc"),
+ (".", "."),
+ )
+
+ for before, after in canonical_forms:
+ self.assertEqual(
+ werror_logs.ClangWarning.try_parse_line(
+ f"{before}:12:34: error: don't do this [-Werror,-Wbar]",
+ canonicalize_board_root=True,
+ ),
+ werror_logs.ClangWarning(
+ name="-Wbar",
+ message="don't do this",
+ location=werror_logs.ClangWarningLocation(
+ file=after,
+ line=12,
+ column=34,
+ ),
+ ),
+ )
+
+ def test_clang_warning_parsing_doesnt_canonicalize_if_not_asked(self):
+ self.assertEqual(
+ werror_logs.ClangWarning.try_parse_line(
+ "/build/foo/bar/baz.cc:12:34: error: don't do this "
+ "[-Werror,-Wbar]",
+ canonicalize_board_root=False,
+ ),
+ werror_logs.ClangWarning(
+ name="-Wbar",
+ message="don't do this",
+ location=werror_logs.ClangWarningLocation(
+ file="/build/foo/bar/baz.cc",
+ line=12,
+ column=34,
+ ),
+ ),
+ )
+
+ def test_clang_warning_parsing_skips_uninteresting_lines(self):
+ self.silence_logs()
+
+ pointless = (
+ "",
+ "foo",
+ "error: something's wrong",
+ "clang-14: warning: something's wrong [-Wsomething]",
+ "clang-14: error: something's wrong",
+ )
+ for line in pointless:
+ self.assertIsNone(
+ werror_logs.ClangWarning.try_parse_line(line), line
+ )
+
+ def test_aggregation_correctly_scrapes_warnings(self):
+ aggregated = werror_logs.AggregatedWarnings()
+ aggregated.add_report_json(
+ {
+ "cwd": "/var/tmp/portage/sys-devel/llvm/foo/bar",
+ "stdout": textwrap.dedent(
+ """\
+ Foo
+ clang-17: error: failed to blah [-Werror,-Wblah]
+ /path/to/file.cc:1:2: error: other error [-Werror,-Wother]
+ """
+ ),
+ }
+ )
+ aggregated.add_report_json(
+ {
+ "cwd": "/var/tmp/portage/sys-devel/llvm/foo/bar",
+ "stdout": textwrap.dedent(
+ """\
+ Foo
+ clang-17: error: failed to blah [-Werror,-Wblah]
+ /path/to/file.cc:1:3: error: other error [-Werror,-Wother]
+ Bar
+ """
+ ),
+ }
+ )
+
+ self.assertEqual(aggregated.num_reports, 2)
+ self.assertEqual(
+ dict(aggregated.warnings),
+ {
+ werror_logs.ClangWarning(
+ name="-Wblah",
+ message="failed to blah",
+ location=None,
+ ): create_warning_info(
+ packages={"sys-devel/llvm": 2},
+ ),
+ werror_logs.ClangWarning(
+ name="-Wother",
+ message="other error",
+ location=werror_logs.ClangWarningLocation(
+ file="/path/to/file.cc",
+ line=1,
+ column=2,
+ ),
+ ): create_warning_info(
+ packages={"sys-devel/llvm": 1},
+ ),
+ werror_logs.ClangWarning(
+ name="-Wother",
+ message="other error",
+ location=werror_logs.ClangWarningLocation(
+ file="/path/to/file.cc",
+ line=1,
+ column=3,
+ ),
+ ): create_warning_info(
+ packages={"sys-devel/llvm": 1},
+ ),
+ },
+ )
+
+ def test_aggregation_guesses_packages_correctly(self):
+ aggregated = werror_logs.AggregatedWarnings()
+ cwds = (
+ "/var/tmp/portage/sys-devel/llvm/foo/bar",
+ "/var/cache/portage/sys-devel/llvm/foo/bar",
+ "/build/amd64-host/var/tmp/portage/sys-devel/llvm/foo/bar",
+ "/build/amd64-host/var/cache/portage/sys-devel/llvm/foo/bar",
+ )
+ for d in cwds:
+ # If the directory isn't recognized, this will raise.
+ aggregated.add_report_json(
+ {
+ "cwd": d,
+ "stdout": "clang-17: error: foo [-Werror,-Wfoo]",
+ }
+ )
+
+ self.assertEqual(len(aggregated.warnings), 1)
+ warning, warning_info = next(iter(aggregated.warnings.items()))
+ self.assertEqual(warning.name, "-Wfoo")
+ self.assertEqual(
+ warning_info, create_warning_info({"sys-devel/llvm": len(cwds)})
+ )
+
+ def test_aggregation_raises_if_package_name_cant_be_guessed(self):
+ aggregated = werror_logs.AggregatedWarnings()
+ with self.assertRaises(werror_logs.UnknownPackageNameError):
+ aggregated.add_report_json({})
+
+ def test_warning_by_flag_summarization_works_in_simple_case(self):
+ string_io = io.StringIO()
+ werror_logs.summarize_warnings_by_flag(
+ {
+ werror_logs.ClangWarning(
+ name="-Wother",
+ message="other error",
+ location=werror_logs.ClangWarningLocation(
+ file="/path/to/some/file.cc",
+ line=1,
+ column=2,
+ ),
+ ): create_warning_info(
+ {
+ "sys-devel/llvm": 3000,
+ "sys-devel/gcc": 1,
+ }
+ ),
+ werror_logs.ClangWarning(
+ name="-Wother",
+ message="other error",
+ location=werror_logs.ClangWarningLocation(
+ file="/path/to/some/file.cc",
+ line=1,
+ column=3,
+ ),
+ ): create_warning_info(
+ {
+ "sys-devel/llvm": 1,
+ }
+ ),
+ },
+ file=string_io,
+ )
+ result = string_io.getvalue()
+ self.assertEqual(
+ result,
+ textwrap.dedent(
+ """\
+ ## Instances of each fatal warning:
+ \t-Wother: 3,002
+ """
+ ),
+ )
+
+ def test_warning_by_package_summarization_works_in_simple_case(self):
+ string_io = io.StringIO()
+ werror_logs.summarize_per_package_warnings(
+ (
+ create_warning_info(
+ {
+ "sys-devel/llvm": 3000,
+ "sys-devel/gcc": 1,
+ }
+ ),
+ create_warning_info(
+ {
+ "sys-devel/llvm": 1,
+ }
+ ),
+ ),
+ file=string_io,
+ )
+ result = string_io.getvalue()
+ self.assertEqual(
+ result,
+ textwrap.dedent(
+ """\
+ ## Per-package warning counts:
+ \tsys-devel/llvm: 3,001
+ \t sys-devel/gcc: 1
+ """
+ ),
+ )
+
+ def test_cq_builder_determination_works(self):
+ self.assertEqual(
+ werror_logs.cq_builder_name_from_werror_logs_path(
+ "gs://chromeos-image-archive/staryu-cq/"
+ "R123-15771.0.0-94466-8756713501925941617/"
+ "staryu.20240207.fatal_clang_warnings.tar.xz"
+ ),
+ "staryu-cq",
+ )
+
+ @mock.patch.object(subprocess, "run")
+ def test_tarball_downloading_works(self, run_mock):
+ tempdir = self.make_tempdir()
+ unpack_dir = tempdir / "unpack"
+ download_dir = tempdir / "download"
+
+ gs_urls = [
+ "gs://foo/bar-cq/build-number/123.fatal_clang_warnings.tar.xz",
+ "gs://foo/baz-cq/build-number/124.fatal_clang_warnings.tar.xz",
+ "gs://foo/qux-cq/build-number/125.fatal_clang_warnings.tar.xz",
+ ]
+ named_gs_urls = [
+ (werror_logs.cq_builder_name_from_werror_logs_path(x), x)
+ for x in gs_urls
+ ]
+ werror_logs.download_and_unpack_werror_tarballs(
+ unpack_dir, download_dir, gs_urls
+ )
+
+ # Just verify that this executed the correct commands. Normally this is
+ # a bit fragile, but given that this function internally is pretty
+ # complex (starting up a threadpool, etc), extra checking is nice.
+ want_gsutil_commands = [
+ [
+ "gsutil",
+ "cp",
+ gs_url,
+ download_dir / name / os.path.basename(gs_url),
+ ]
+ for name, gs_url in named_gs_urls
+ ]
+ want_untar_commands = [
+ ["tar", "xaf", gsutil_command[-1]]
+ for gsutil_command in want_gsutil_commands
+ ]
+
+ cmds = []
+ for call_args in run_mock.call_args_list:
+ call_positional_args = call_args[0]
+ cmd = call_positional_args[0]
+ cmds.append(cmd)
+ cmds.sort()
+ self.assertEqual(
+ cmds, sorted(want_gsutil_commands + want_untar_commands)
+ )
+
+ @mock.patch.object(subprocess, "run")
+ def test_tarball_downloading_fails_if_exceptions_are_raised(self, run_mock):
+ self.silence_logs()
+
+ def raise_exception(*_args, check=False, **_kwargs):
+ self.assertTrue(check)
+ raise subprocess.CalledProcessError(returncode=1, cmd=[])
+
+ run_mock.side_effect = raise_exception
+ tempdir = self.make_tempdir()
+ unpack_dir = tempdir / "unpack"
+ download_dir = tempdir / "download"
+
+ gs_urls = [
+ "gs://foo/bar-cq/build-number/123.fatal_clang_warnings.tar.xz",
+ "gs://foo/baz-cq/build-number/124.fatal_clang_warnings.tar.xz",
+ "gs://foo/qux-cq/build-number/125.fatal_clang_warnings.tar.xz",
+ ]
+ with self.assertRaisesRegex(ValueError, r"3 download\(s\) failed"):
+ werror_logs.download_and_unpack_werror_tarballs(
+ unpack_dir, download_dir, gs_urls
+ )
+ self.assertEqual(run_mock.call_count, 3)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/orderfile/post_process_orderfile.py b/orderfile/post_process_orderfile.py
deleted file mode 100755
index d90c1af7..00000000
--- a/orderfile/post_process_orderfile.py
+++ /dev/null
@@ -1,99 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-# Copyright 2019 The ChromiumOS Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Script to do post-process on orderfile generated by C3.
-
-The goal of this script is to take in an orderfile generated by C3, and do
-the following post process:
-
-1. Take in the result of nm command on Chrome binary to find out all the
-Builtin functions and put them after the input symbols.
-
-2. Put special markers "chrome_begin_ordered_code" and "chrome_end_ordered_code"
-in begin and end of the file.
-
-The results of the file is intended to be uploaded and consumed when linking
-Chrome in ChromeOS.
-"""
-
-
-import argparse
-import os
-import sys
-
-
-def _parse_nm_output(stream):
- for line in (line.rstrip() for line in stream):
- if not line:
- continue
-
- pieces = line.split()
- if len(pieces) != 3:
- continue
-
- _, ty, symbol = pieces
- if ty not in "tT":
- continue
-
- # We'll sometimes see synthesized symbols that start with $. There isn't
- # much we can do about or with them, regrettably.
- if symbol.startswith("$"):
- continue
-
- yield symbol
-
-
-def _remove_duplicates(iterable):
- seen = set()
- for item in iterable:
- if item in seen:
- continue
- seen.add(item)
- yield item
-
-
-def run(c3_ordered_stream, chrome_nm_stream, output_stream):
- head_marker = "chrome_begin_ordered_code"
- tail_marker = "chrome_end_ordered_code"
-
- # Filter out $symbols which can come up in the orderfile as well.
- # Linker ignores the whole orderfile if it finds $symb.
- c3_ordered_syms = [
- x.strip()
- for x in c3_ordered_stream.readlines()
- if not x.strip().startswith("$")
- ]
- all_chrome_syms = set(_parse_nm_output(chrome_nm_stream))
- # Sort by name, so it's predictable. Otherwise, these should all land in the
- # same hugepage anyway, so order doesn't matter as much.
- builtin_syms = sorted(
- s for s in all_chrome_syms if s.startswith("Builtins_")
- )
- output = _remove_duplicates(
- [head_marker] + c3_ordered_syms + builtin_syms + [tail_marker]
- )
- output_stream.write("\n".join(output))
-
-
-def main(argv):
- parser = argparse.ArgumentParser()
- parser.add_argument("--chrome_nm", required=True, dest="chrome_nm")
- parser.add_argument("--input", required=True, dest="input_file")
- parser.add_argument("--output", required=True, dest="output_file")
-
- options = parser.parse_args(argv)
-
- if not os.path.exists(options.input_file):
- sys.exit("Input orderfile doesn't exist.")
-
- with open(options.input_file) as in_stream, open(
- options.chrome_nm
- ) as chrome_nm_stream, open(options.output_file, "w") as out_stream:
- run(in_stream, chrome_nm_stream, out_stream)
-
-
-if __name__ == "__main__":
- sys.exit(main(sys.argv[1:]))
diff --git a/orderfile/post_process_orderfile_test.py b/orderfile/post_process_orderfile_test.py
deleted file mode 100755
index 9dd574a8..00000000
--- a/orderfile/post_process_orderfile_test.py
+++ /dev/null
@@ -1,95 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-# Copyright 2019 The ChromiumOS Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Tests for post_process_orderfile.py."""
-
-
-import os
-import shutil
-import tempfile
-import unittest
-
-import post_process_orderfile
-
-
-def _write_nm_file(name):
- with open(name, "w") as out:
- out.write("000001 s NotAValidSymbol1\n")
- out.write("000002 S NotAValidSymbol2\n")
- out.write("000010 t FirstValidSymbol\n")
- out.write("000012 t \n")
- out.write("000020 T Builtins_SecondValidSymbol\n")
- out.write("000030 T $SymbolToIgnore\n")
- out.write("000036 T Builtins_LastValidSymbol\n")
-
-
-def _write_orderfile(name):
- with open(name, "w") as out:
- out.write("SymbolOrdered1\n")
- out.write("$toignore.123\n")
- out.write("SymbolOrdered2\n")
-
-
-def _cleanup(files):
- for f in files:
- shutil.rmtree(f, ignore_errors=True)
-
-
-class Tests(unittest.TestCase):
- """All of our tests for post_process_orderfile."""
-
- # pylint: disable=protected-access
- def test__parse_nm_output(self):
- temp_dir = tempfile.mkdtemp()
- self.addCleanup(_cleanup, [temp_dir])
- chrome_nm_file = os.path.join(temp_dir, "chrome_nm.txt")
- _write_nm_file(chrome_nm_file)
- with open(chrome_nm_file) as f:
- results = list(post_process_orderfile._parse_nm_output(f))
- self.assertEqual(len(results), 3)
- self.assertIn("FirstValidSymbol", results)
- self.assertIn("Builtins_SecondValidSymbol", results)
- self.assertIn("Builtins_LastValidSymbol", results)
-
- def test__remove_duplicates(self):
- duplicates = ["marker1", "marker2", "marker3", "marker2", "marker1"]
- results = list(post_process_orderfile._remove_duplicates(duplicates))
- self.assertEqual(results, ["marker1", "marker2", "marker3"])
-
- def test_run(self):
- temp_dir = tempfile.mkdtemp()
- self.addCleanup(_cleanup, [temp_dir])
- orderfile_input = os.path.join(temp_dir, "orderfile.in.txt")
- orderfile_output = os.path.join(temp_dir, "orderfile.out.txt")
- chrome_nm_file = os.path.join(temp_dir, "chrome_nm.txt")
- _write_nm_file(chrome_nm_file)
- _write_orderfile(orderfile_input)
- with open(orderfile_input) as in_stream, open(
- orderfile_output, "w"
- ) as out_stream, open(chrome_nm_file) as chrome_nm_stream:
- post_process_orderfile.run(in_stream, chrome_nm_stream, out_stream)
-
- with open(orderfile_output) as check:
- results = [x.strip() for x in check.readlines()]
- self.assertEqual(
- results,
- [
- # Start marker should be put first.
- "chrome_begin_ordered_code",
- # Symbols in orderfile come next.
- "SymbolOrdered1",
- "SymbolOrdered2",
- # Builtin functions in chrome_nm come next, and sorted.
- "Builtins_LastValidSymbol",
- "Builtins_SecondValidSymbol",
- # Last symbol should be end marker.
- "chrome_end_ordered_code",
- ],
- )
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/pgo_tools/README.md b/pgo_tools/README.md
new file mode 100644
index 00000000..731fa646
--- /dev/null
+++ b/pgo_tools/README.md
@@ -0,0 +1,17 @@
+# pgo_tools
+
+This directory contains scripts used to generate and vet PGO profiles for LLVM.
+
+If you're a Mage who wants to generate a new PGO profile for the llvm-next
+release, `./generate_llvm_next_pgo.py` is what you should run **outside of a
+chroot**. It will create a new chroot, and generate a profile that's
+backwards-compatible with our bootstrap chroot toolchains. This script takes a
+few dozen minutes, and prints an "upload PGO profile" command at the end.
+
+If you're a user who wants to generate a bespoke PGO profile for LLVM,
+`./generate_pgo_profile.py` is what you want. Run it **inside of a chroot**, and
+it will generate a profile for you with a pretty comprehensive, predefined
+workload (building absl's tests for arm32, arm64, and a few x86_64 configs).
+
+If you want to compare the rough performance of PGO profiles,
+`./benchmark_pgo_profiles.py` may be useful.
diff --git a/pgo_tools/benchmark_pgo_profiles.py b/pgo_tools/benchmark_pgo_profiles.py
new file mode 100755
index 00000000..d6fb4945
--- /dev/null
+++ b/pgo_tools/benchmark_pgo_profiles.py
@@ -0,0 +1,287 @@
+#!/usr/bin/env python3
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Runs benchmarks, given potentially multiple PGO profiles.
+
+**This script is meant to be run from inside of the chroot.**
+
+This script overwrites your chroot's LLVM temporarily, but if it runs to
+completion, it will restore you to your previous version of LLVM. Care is taken
+so that the same baseline LLVM is used to build all LLVM versions this script
+benchmarks.
+"""
+
+import argparse
+import dataclasses
+import enum
+import json
+import logging
+from pathlib import Path
+import shlex
+import shutil
+import subprocess
+import sys
+from typing import IO, List, Optional, Union
+
+import pgo_tools
+
+
+# The full path to where `sys-devel/llvm` expects local profiles to be if
+# `USE=llvm_pgo_use_local` is specified.
+LOCAL_PROFILE_LOCATION = Path(
+ "/mnt/host/source/src/third_party/chromiumos-overlay",
+ "sys-devel/llvm/files/llvm-local.profdata",
+).resolve()
+
+CHROOT_HYPERFINE = Path.home() / ".cargo/bin/hyperfine"
+
+
+class SpecialProfile(enum.Enum):
+ """An enum representing a 'special' (non-Path) profile."""
+
+ REMOTE = enum.auto()
+ NONE = enum.auto()
+
+ def __str__(self) -> str:
+ if self is self.REMOTE:
+ return "@remote"
+ if self is self.NONE:
+ return "@none"
+ raise ValueError(f"Unknown SpecialProfile value: {repr(self)}")
+
+
+@dataclasses.dataclass(frozen=True, eq=True)
+class RunData:
+ """Data describing the results of one hyperfine run."""
+
+ tag: str
+ user_time: float
+ system_time: float
+
+ @staticmethod
+ def from_json(tag: str, json_contents: IO) -> "RunData":
+ """Converts a hyperfine JSON file's contents into a RunData."""
+ results = json.load(json_contents)["results"]
+ if len(results) != 1:
+ raise ValueError(f"Expected one run result; got {results}")
+ return RunData(
+ tag=tag,
+ user_time=results[0]["user"],
+ system_time=results[0]["system"],
+ )
+
+
+ProfilePath = Union[SpecialProfile, Path]
+
+
+def parse_profile_path(path: str) -> ProfilePath:
+ for p in SpecialProfile:
+ if path == str(p):
+ return p
+ return Path(path).resolve()
+
+
+def ensure_hyperfine_is_installed():
+ if CHROOT_HYPERFINE.exists():
+ return
+
+ logging.info("Installing hyperfine for benchmarking...")
+ pgo_tools.run(
+ [
+ "cargo",
+ "install",
+ "hyperfine",
+ ]
+ )
+ assert (
+ CHROOT_HYPERFINE.exists()
+ ), f"hyperfine was installed, but wasn't at {CHROOT_HYPERFINE}"
+
+
+def construct_hyperfine_cmd(
+ llvm_ebuild: Path,
+ profile: ProfilePath,
+ llvm_binpkg: Path,
+ use_thinlto: bool,
+ export_json: Optional[Path] = None,
+) -> pgo_tools.Command:
+ if isinstance(profile, Path):
+ if profile != LOCAL_PROFILE_LOCATION:
+ shutil.copyfile(profile, LOCAL_PROFILE_LOCATION)
+ use_flags = "-llvm_pgo_use llvm_pgo_use_local"
+ elif profile is SpecialProfile.NONE:
+ use_flags = "-llvm_pgo_use"
+ elif profile is SpecialProfile.REMOTE:
+ use_flags = "llvm_pgo_use"
+ else:
+ raise ValueError(f"Unknown profile type: {type(profile)}")
+
+ quickpkg_restore = " ".join(
+ shlex.quote(str(x))
+ for x in pgo_tools.generate_quickpkg_restoration_command(llvm_binpkg)
+ )
+
+ setup_cmd = (
+ f"{quickpkg_restore} && "
+ f"sudo FEATURES=ccache USE={shlex.quote(use_flags)}"
+ # Use buildpkg-exclude so our existing llvm binpackage isn't
+ # overwritten.
+ " emerge sys-devel/llvm --buildpkg-exclude=sys-devel/llvm"
+ )
+
+ if use_thinlto:
+ benchmark_use = "thinlto"
+ else:
+ benchmark_use = "-thinlto"
+
+ ebuild_llvm = (
+ f"sudo USE={shlex.quote(benchmark_use)} "
+ f"ebuild {shlex.quote(str(llvm_ebuild))}"
+ )
+ cmd: pgo_tools.Command = [
+ CHROOT_HYPERFINE,
+ "--max-runs=3",
+ f"--setup={setup_cmd}",
+ f"--prepare={ebuild_llvm} clean prepare",
+ ]
+
+ if export_json:
+ cmd.append(f"--export-json={export_json}")
+
+ cmd += (
+ "--",
+ # At the moment, building LLVM seems to be an OK benchmark. It has some
+ # C in it, some C++, and each pass on Cloudtops takes no more than 7
+ # minutes.
+ f"{ebuild_llvm} compile",
+ )
+ return cmd
+
+
+def validate_profiles(
+ parser: argparse.ArgumentParser, profiles: List[ProfilePath]
+):
+ number_of_path_profiles = 0
+ nonexistent_profiles = []
+ seen_profile_at_local_profile_location = False
+ for profile in profiles:
+ if not isinstance(profile, Path):
+ continue
+
+ if not profile.exists():
+ nonexistent_profiles.append(profile)
+
+ number_of_path_profiles += 1
+ if profile == LOCAL_PROFILE_LOCATION:
+ seen_profile_at_local_profile_location = True
+
+ if number_of_path_profiles > 1 and seen_profile_at_local_profile_location:
+ parser.error(
+ f"Cannot use the path {LOCAL_PROFILE_LOCATION} as a profile if "
+ "there are other profiles specified by path."
+ )
+
+ if nonexistent_profiles:
+ nonexistent_profiles.sort()
+ parser.error(
+ "One or more profiles do not exist: " f"{nonexistent_profiles}"
+ )
+
+
+def run_benchmark(
+ use_thinlto: bool,
+ profiles: List[ProfilePath],
+) -> List[RunData]:
+ """Runs the PGO benchmark with the given parameters.
+
+ Args:
+ use_thinlto: whether to benchmark the use of ThinLTO
+ profiles: profiles to benchmark with
+ collect_run_data: whether to return a CombinedRunData
+
+ Returns:
+ A CombinedRunData instance capturing the performance of the benchmark
+ runs.
+ """
+ ensure_hyperfine_is_installed()
+
+ llvm_ebuild_path = Path(
+ pgo_tools.run(
+ ["equery", "w", "sys-devel/llvm"], stdout=subprocess.PIPE
+ ).stdout.strip()
+ )
+
+ baseline_llvm_binpkg = pgo_tools.quickpkg_llvm()
+ accumulated_run_data = []
+ with pgo_tools.temporary_file(
+ prefix="benchmark_pgo_profile"
+ ) as tmp_json_file:
+ for profile in profiles:
+ cmd = construct_hyperfine_cmd(
+ llvm_ebuild_path,
+ profile,
+ baseline_llvm_binpkg,
+ use_thinlto=use_thinlto,
+ export_json=tmp_json_file,
+ )
+ # Format the profile with `repr(str(profile))` so that we always
+ # get a quoted, but human-friendly, representation of the profile.
+ logging.info(
+ "Profile %r: Running %s",
+ str(profile),
+ " ".join(shlex.quote(str(x)) for x in cmd),
+ )
+ pgo_tools.run(cmd)
+
+ with tmp_json_file.open(encoding="utf-8") as f:
+ accumulated_run_data.append(RunData.from_json(str(profile), f))
+
+ logging.info("Restoring original LLVM...")
+ pgo_tools.run(
+ pgo_tools.generate_quickpkg_restoration_command(baseline_llvm_binpkg)
+ )
+ return accumulated_run_data
+
+
+def main(argv: List[str]):
+ logging.basicConfig(
+ format=">> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: "
+ "%(message)s",
+ level=logging.INFO,
+ )
+
+ parser = argparse.ArgumentParser(
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+ parser.add_argument(
+ "--thinlto",
+ action="store_true",
+ help="If specified, this will benchmark builds with ThinLTO enabled.",
+ )
+ parser.add_argument(
+ "profile",
+ nargs="+",
+ type=parse_profile_path,
+ help=f"""
+ The path to a profile to benchmark. There are two special values here:
+ '{SpecialProfile.REMOTE}' and '{SpecialProfile.NONE}'. For
+ '{SpecialProfile.REMOTE}', this will just use the default LLVM PGO
+ profile for a benchmark run. For '{SpecialProfile.NONE}', all PGO will
+ be disabled for a benchmark run.
+ """,
+ )
+ opts = parser.parse_args(argv)
+
+ pgo_tools.exit_if_not_in_chroot()
+
+ profiles = opts.profile
+ validate_profiles(parser, profiles)
+
+ run_benchmark(opts.thinlto, profiles)
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/pgo_tools/benchmark_pgo_profiles_test.py b/pgo_tools/benchmark_pgo_profiles_test.py
new file mode 100755
index 00000000..7e71c78c
--- /dev/null
+++ b/pgo_tools/benchmark_pgo_profiles_test.py
@@ -0,0 +1,51 @@
+#!/usr/bin/env python3
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+"""Tests for benchmark_pgo_profiles."""
+
+import io
+import json
+import unittest
+
+import benchmark_pgo_profiles
+
+
+class Test(unittest.TestCase):
+ """Tests for benchmark_pgo_profiles."""
+
+ def test_run_data_parsing_succeeds(self):
+ run_data = benchmark_pgo_profiles.RunData.from_json(
+ "foo",
+ io.StringIO(
+ json.dumps(
+ {
+ "results": [
+ {
+ "user": 1.2,
+ "system": 1.3,
+ },
+ ],
+ }
+ )
+ ),
+ )
+
+ self.assertEqual(
+ run_data,
+ benchmark_pgo_profiles.RunData(
+ tag="foo",
+ user_time=1.2,
+ system_time=1.3,
+ ),
+ )
+
+ def test_special_profile_parsing_succeeds(self):
+ for profile in benchmark_pgo_profiles.SpecialProfile:
+ self.assertIs(
+ profile, benchmark_pgo_profiles.parse_profile_path(str(profile))
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/pgo_tools/create_chroot_and_generate_pgo_profile.py b/pgo_tools/create_chroot_and_generate_pgo_profile.py
new file mode 100755
index 00000000..b9e4c62c
--- /dev/null
+++ b/pgo_tools/create_chroot_and_generate_pgo_profile.py
@@ -0,0 +1,260 @@
+#!/usr/bin/env python3
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""This script generates a PGO profile for llvm-next.
+
+Do not run it inside of a chroot. It establishes a chroot of its own.
+"""
+
+import argparse
+import dataclasses
+import logging
+import os
+from pathlib import Path
+import re
+import shlex
+import shutil
+import sys
+from typing import List
+
+import pgo_tools
+
+
+@dataclasses.dataclass(frozen=True)
+class ChrootInfo:
+ """Info that describes a unique chroot."""
+
+ chroot_name: str
+ out_dir_name: str
+
+
+def find_repo_root(base_dir: Path) -> Path:
+ """Returns the root of the user's ChromeOS checkout."""
+ if (base_dir / ".repo").exists():
+ return base_dir
+
+ for parent in base_dir.parents:
+ if (parent / ".repo").exists():
+ return parent
+
+ raise ValueError(f"No repo found above {base_dir}")
+
+
+def create_fresh_bootstrap_chroot(repo_root: Path, chroot_info: ChrootInfo):
+ """Creates a `--bootstrap` chroot without any updates applied."""
+ pgo_tools.run(
+ [
+ "cros_sdk",
+ "--replace",
+ f"--chroot={chroot_info.chroot_name}",
+ f"--out-dir={chroot_info.out_dir_name}",
+ "--bootstrap",
+ "--skip-chroot-upgrade",
+ ],
+ cwd=repo_root,
+ )
+
+
+def generate_pgo_profile(
+ repo_root: Path,
+ chroot_info: ChrootInfo,
+ chroot_output_file: Path,
+ use_var: str,
+):
+ """Generates a PGO profile to `chroot_output_file`."""
+ pgo_tools.run(
+ [
+ "cros_sdk",
+ f"--chroot={chroot_info.chroot_name}",
+ f"--out-dir={chroot_info.out_dir_name}",
+ "--skip-chroot-upgrade",
+ f"USE={use_var}",
+ "--",
+ "/mnt/host/source/src/third_party/toolchain-utils/pgo_tools/"
+ "generate_pgo_profile.py",
+ f"--output={chroot_output_file}",
+ ],
+ cwd=repo_root,
+ )
+
+
+def compress_pgo_profile(pgo_profile: Path) -> Path:
+ """Compresses a PGO profile for upload to gs://."""
+ pgo_tools.run(
+ ["xz", "-9", "-k", pgo_profile],
+ )
+ return Path(str(pgo_profile) + ".xz")
+
+
+def translate_chroot_path_to_out_of_chroot(
+ repo_root: Path, path: Path, info: ChrootInfo
+) -> Path:
+ """Translates a chroot path into an out-of-chroot path."""
+ path_str = str(path)
+ assert path_str.startswith("/tmp"), path
+ # Remove the leading `/` from the output file so it joins properly.
+ return repo_root / info.out_dir_name / str(path)[1:]
+
+
+def locate_current_llvm_ebuild(repo_root: Path) -> Path:
+ """Returns the path to our current LLVM ebuild."""
+ llvm_subdir = (
+ repo_root / "src/third_party/chromiumos-overlay/sys-devel/llvm"
+ )
+ candidates = [
+ x for x in llvm_subdir.glob("*pre*ebuild") if not x.is_symlink()
+ ]
+ assert (
+ len(candidates) == 1
+ ), f"Found {len(candidates)} viable ebuilds; expected 1: {candidates}"
+ return candidates[0]
+
+
+def parse_llvm_next_hash(llvm_ebuild_contents: str) -> List[str]:
+ """Parses the LLVM_NEXT hash from our LLVM ebuild."""
+ matches = re.findall(
+ r'^LLVM_NEXT_HASH="([a-f0-9A-F]{40})" # r\d+$',
+ llvm_ebuild_contents,
+ re.MULTILINE,
+ )
+ assert (
+ len(matches) == 1
+ ), f"Got {len(matches)} matches for llvm hash; expected 1"
+ return matches[0]
+
+
+def determine_upload_command(
+ repo_root: Path, profile_path: Path
+) -> pgo_tools.Command:
+ """Returns a command that can be used to upload our PGO profile."""
+ llvm_ebuild = locate_current_llvm_ebuild(repo_root)
+ llvm_next_hash = parse_llvm_next_hash(
+ llvm_ebuild.read_text(encoding="utf-8")
+ )
+ upload_target = (
+ "gs://chromeos-localmirror/distfiles/llvm-profdata-"
+ f"{llvm_next_hash}.xz"
+ )
+ return [
+ "gsutil",
+ "cp",
+ "-n",
+ "-a",
+ "public-read",
+ profile_path,
+ upload_target,
+ ]
+
+
+def main(argv: List[str]):
+ logging.basicConfig(
+ format=">> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: "
+ "%(message)s",
+ level=logging.INFO,
+ )
+
+ parser = argparse.ArgumentParser(
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+ parser.add_argument(
+ "--chroot",
+ default="llvm-next-pgo-chroot",
+ help="""
+ Name of the chroot to create. Will be clobbered if it exists already.
+ """,
+ )
+ parser.add_argument(
+ "--out-dir",
+ default="llvm-next-pgo-chroot_out",
+ help="""
+ Name of the out/ directory to use. Will be clobbered if it exists
+ already.
+ """,
+ )
+ parser.add_argument(
+ "--upload",
+ action="store_true",
+ help="Upload the profile after creation. Implies --compress.",
+ )
+ parser.add_argument(
+ "--output",
+ type=Path,
+ help="""
+ Additionally put the uncompressed profile at the this path after
+ creation.
+ """,
+ )
+ # This flag is required because the most common use-case (pardon the pun)
+ # for this script is "generate the PGO profile for the next LLVM roll." It:
+ # - seems very easy to forget to apply `USE=llvm-next`,
+ # - is awkward to _force_ llvm-next silently, since the "most common"
+ # use-case is not the _only_ use-case, and
+ # - is awkward to have a duo of `--llvm-next` / `--no-llvm-next` flags,
+ # since a single `--use=` provides way more flexibility.
+ parser.add_argument(
+ "--use",
+ required=True,
+ help="""
+ The value to set for the USE variable when generating the profile. If
+ you're the mage, you want --use=llvm-next. If you don't want to use
+ anything, just pass `--use=`.
+ """,
+ )
+ opts = parser.parse_args(argv)
+
+ pgo_tools.exit_if_in_chroot()
+
+ repo_root = find_repo_root(Path(os.getcwd()))
+ logging.info("Repo root is %s", repo_root)
+
+ logging.info("Creating new SDK")
+ chroot_info = ChrootInfo(opts.chroot, opts.out_dir)
+ try:
+ create_fresh_bootstrap_chroot(repo_root, chroot_info)
+ chroot_profile_path = Path("/tmp/llvm-next-pgo-profile.prof")
+ generate_pgo_profile(
+ repo_root, chroot_info, chroot_profile_path, opts.use
+ )
+ profile_path = translate_chroot_path_to_out_of_chroot(
+ repo_root, chroot_profile_path, chroot_info
+ )
+ if opts.output:
+ shutil.copyfile(profile_path, opts.output)
+
+ compressed_profile_path = compress_pgo_profile(profile_path)
+ upload_command = determine_upload_command(
+ repo_root, compressed_profile_path
+ )
+ if opts.upload:
+ pgo_tools.run(upload_command)
+ else:
+ friendly_upload_command = " ".join(
+ shlex.quote(str(x)) for x in upload_command
+ )
+ logging.info(
+ "To upload the profile, run %r in %r",
+ friendly_upload_command,
+ repo_root,
+ )
+ except:
+ logging.warning(
+ "NOTE: Chroot left at %s and out dir is left at %s. "
+ "If you don't plan to rerun this script, delete them.",
+ chroot_info.chroot_name,
+ chroot_info.out_dir_name,
+ )
+ raise
+ else:
+ logging.info(
+ "Feel free to delete chroot %s and out dir %s when you're done "
+ "with them.",
+ chroot_info.chroot_name,
+ chroot_info.out_dir_name,
+ )
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/pgo_tools/create_chroot_and_generate_pgo_profile_test.py b/pgo_tools/create_chroot_and_generate_pgo_profile_test.py
new file mode 100755
index 00000000..ac5c9b82
--- /dev/null
+++ b/pgo_tools/create_chroot_and_generate_pgo_profile_test.py
@@ -0,0 +1,81 @@
+#!/usr/bin/env python3
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Tests for generate_llvm_next_pgo."""
+
+from pathlib import Path
+import shutil
+import tempfile
+import textwrap
+import unittest
+
+# This script's name makes lines exceed 80 chars if it's not imported `as`
+# something shorter.
+import create_chroot_and_generate_pgo_profile as create_chroot_etc
+
+
+class Test(unittest.TestCase):
+ """Tests for generate_llvm_next_pgo."""
+
+ def make_tempdir(self) -> Path:
+ tempdir = Path(tempfile.mkdtemp(prefix="generate_llvm_next_pgo_test_"))
+ self.addCleanup(lambda: shutil.rmtree(tempdir))
+ return tempdir
+
+ def test_path_translation_works(self):
+ repo_root = Path("/some/repo")
+ chroot_info = create_chroot_etc.ChrootInfo(
+ chroot_name="my-chroot",
+ out_dir_name="my-out",
+ )
+ self.assertEqual(
+ create_chroot_etc.translate_chroot_path_to_out_of_chroot(
+ repo_root, "/tmp/file/path", chroot_info
+ ),
+ repo_root / "my-out" / "tmp/file/path",
+ )
+
+ def test_llvm_ebuild_location(self):
+ tempdir = self.make_tempdir()
+
+ llvm_subdir = (
+ tempdir / "src/third_party/chromiumos-overlay/sys-devel/llvm"
+ )
+ want_ebuild = llvm_subdir / "llvm-18.0.0_pre12345.ebuild"
+ files = [
+ llvm_subdir / "llvm-15.ebuild",
+ llvm_subdir / "llvm-16.0.1-r3.ebuild",
+ want_ebuild,
+ llvm_subdir / "llvm-9999.ebuild",
+ ]
+
+ llvm_subdir.mkdir(parents=True)
+ for f in files:
+ f.touch()
+
+ self.assertEqual(
+ create_chroot_etc.locate_current_llvm_ebuild(tempdir),
+ want_ebuild,
+ )
+
+ def test_llvm_hash_parsing(self):
+ h = create_chroot_etc.parse_llvm_next_hash(
+ textwrap.dedent(
+ """\
+ # Copyright blah blah
+ EAPI=7
+ LLVM_HASH="98f5a340975bc00197c57e39eb4ca26e2da0e8a2" # r496208
+ LLVM_NEXT_HASH="14f0776550b5a49e1c42f49a00213f7f3fa047bf" # r498229
+ # Snip
+ CROS_WORKON_COMMIT=("${LLVM_NEXT_HASH}")
+ """
+ )
+ )
+
+ self.assertEqual(h, "14f0776550b5a49e1c42f49a00213f7f3fa047bf")
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/pgo_tools/ensure_pgo_is_a_win.py b/pgo_tools/ensure_pgo_is_a_win.py
new file mode 100755
index 00000000..a630f94d
--- /dev/null
+++ b/pgo_tools/ensure_pgo_is_a_win.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python3
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Reports how much performance win (in user time) PGO is for LLVM.
+
+**This script is meant to be run from inside of the chroot.**
+
+This is mostly intended to run regularly on Chrotomation, as it's just a super
+thin wrapper around `benchmark_pgo_profiles.py`.
+"""
+
+import argparse
+import logging
+import sys
+from typing import List
+
+import benchmark_pgo_profiles
+import pgo_tools
+
+
+NO_PROFILE = benchmark_pgo_profiles.SpecialProfile.NONE
+DEFAULT_PROFILE = benchmark_pgo_profiles.SpecialProfile.REMOTE
+
+
+def calculate_pgo_speedup(
+ no_profile: benchmark_pgo_profiles.RunData,
+ default_profile: benchmark_pgo_profiles.RunData,
+) -> float:
+ """Returns the speedup attained by applying PGO.
+
+ Returns:
+ Percentage performance difference. If LLVM with PGO takes 100 seconds
+ to run the benchmark, and LLVM without PGO takes 150, this will return
+ 1.5, since 150/100 == 1.5x speedup.
+ """
+ assert default_profile.user_time != 0, "pgo has a user time of 0?"
+ return no_profile.user_time / default_profile.user_time
+
+
+def main(argv: List[str]):
+ logging.basicConfig(
+ format=">> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: "
+ "%(message)s",
+ level=logging.INFO,
+ )
+
+ parser = argparse.ArgumentParser(
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+ parser.add_argument(
+ "--minimum-speedup",
+ type=float,
+ help="""
+ If the win of PGO is less than this, fail. Specified as an integer
+ (--minimum-speedup=1.2 means speedup must be at least 1.2x).
+ """,
+ )
+ opts = parser.parse_args(argv)
+ minimum_speedup = opts.minimum_speedup
+
+ pgo_tools.exit_if_not_in_chroot()
+
+ run_results = benchmark_pgo_profiles.run_benchmark(
+ # It's likely safe to assume that a fast LLVM without ThinLTO is fast
+ # with ThinLTO.
+ use_thinlto=False,
+ profiles=[
+ NO_PROFILE,
+ DEFAULT_PROFILE,
+ ],
+ )
+ assert (
+ len(run_results) == 2
+ ), f"Unexpected number of run results: {len(run_results)}"
+
+ pgo_speedup = calculate_pgo_speedup(
+ no_profile=run_results[0], default_profile=run_results[1]
+ )
+ logging.info("Speedup of PGO is %.2fx", pgo_speedup)
+ if minimum_speedup is not None and minimum_speedup > pgo_speedup:
+ sys.exit(
+ f"Minimum speedup of {minimum_speedup} is greater than "
+ f"observed speedup of {pgo_speedup}. Exiting with error."
+ )
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/pgo_tools/ensure_pgo_is_a_win_test.py b/pgo_tools/ensure_pgo_is_a_win_test.py
new file mode 100755
index 00000000..993094c0
--- /dev/null
+++ b/pgo_tools/ensure_pgo_is_a_win_test.py
@@ -0,0 +1,52 @@
+#!/usr/bin/env python3
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Tests for ensure_pgo_is_a_win."""
+
+from typing import Tuple
+import unittest
+
+import benchmark_pgo_profiles
+import ensure_pgo_is_a_win
+
+
+def synthesize_run_data(
+ no_profile_user_time: float, profile_user_time: float
+) -> Tuple[benchmark_pgo_profiles.RunData, benchmark_pgo_profiles.RunData]:
+ return (
+ benchmark_pgo_profiles.RunData(
+ tag=str(ensure_pgo_is_a_win.NO_PROFILE),
+ user_time=no_profile_user_time,
+ system_time=1,
+ ),
+ benchmark_pgo_profiles.RunData(
+ tag=str(ensure_pgo_is_a_win.DEFAULT_PROFILE),
+ user_time=profile_user_time,
+ system_time=1,
+ ),
+ )
+
+
+class Test(unittest.TestCase):
+ """Tests for ensure_pgo_is_a_win."""
+
+ def test_speedup_calculation_works(self):
+ no_profile, profile = synthesize_run_data(
+ no_profile_user_time=1, profile_user_time=1
+ )
+ self.assertEqual(
+ ensure_pgo_is_a_win.calculate_pgo_speedup(no_profile, profile), 1
+ )
+
+ no_profile, profile = synthesize_run_data(
+ no_profile_user_time=3, profile_user_time=2
+ )
+ self.assertEqual(
+ ensure_pgo_is_a_win.calculate_pgo_speedup(no_profile, profile), 1.5
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/pgo_tools/generate_pgo_profile.py b/pgo_tools/generate_pgo_profile.py
new file mode 100755
index 00000000..e966ad42
--- /dev/null
+++ b/pgo_tools/generate_pgo_profile.py
@@ -0,0 +1,477 @@
+#!/usr/bin/env python3
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Generates a PGO profile for LLVM.
+
+**This script is meant to be run from inside of the chroot.**
+
+Note that this script has a few (perhaps surprising) side-effects:
+1. The first time this is run in a chroot, it will pack up your existing llvm
+ and save it as a binpkg.
+2. This script clobbers your llvm installation. If the script is run to
+ completion, your old installation will be restored. If it does not, it may
+ not be.
+"""
+
+import argparse
+import dataclasses
+import logging
+import os
+from pathlib import Path
+import shlex
+import shutil
+import subprocess
+import sys
+import tempfile
+import textwrap
+from typing import Dict, FrozenSet, List, Optional
+
+import pgo_tools
+
+
+# This script runs `quickpkg` on LLVM. This file saves the version of LLVM that
+# was quickpkg'ed.
+SAVED_LLVM_BINPKG_STAMP = Path("/tmp/generate_pgo_profile_old_llvm.txt")
+
+# Triple to build with when not trying to get backend coverage.
+HOST_TRIPLE = "x86_64-pc-linux-gnu"
+
+# List of triples we want coverage for.
+IMPORTANT_TRIPLES = (
+ HOST_TRIPLE,
+ "x86_64-cros-linux-gnu",
+ "armv7a-cros-linux-gnueabihf",
+ "aarch64-cros-linux-gnu",
+)
+
+# Set of all of the cross-* libraries we need.
+ALL_NEEDED_CROSS_LIBS = frozenset(
+ f"cross-{triple}/{package}"
+ for triple in IMPORTANT_TRIPLES
+ if triple != HOST_TRIPLE
+ for package in ("glibc", "libcxx", "llvm-libunwind", "linux-headers")
+)
+
+
+def ensure_llvm_binpkg_exists() -> bool:
+ """Verifies that we have an LLVM binpkg to fall back on.
+
+ Returns:
+ True if this function actually created a binpkg, false if one already
+ existed.
+ """
+ if SAVED_LLVM_BINPKG_STAMP.exists():
+ pkg = Path(SAVED_LLVM_BINPKG_STAMP.read_text(encoding="utf-8"))
+ # Double-check this, since this package is considered a cache artifact
+ # by portage. Ergo, it can _technically_ be GC'ed at any time.
+ if pkg.exists():
+ return False
+
+ pkg = pgo_tools.quickpkg_llvm()
+ SAVED_LLVM_BINPKG_STAMP.write_text(str(pkg), encoding="utf-8")
+ return True
+
+
+def restore_llvm_binpkg():
+ """Installs the binpkg created by ensure_llvm_binpkg_exists."""
+ logging.info("Restoring non-PGO'ed LLVM installation")
+ pkg = Path(SAVED_LLVM_BINPKG_STAMP.read_text(encoding="utf-8"))
+ assert (
+ pkg.exists()
+ ), f"Non-PGO'ed binpkg at {pkg} does not exist. Can't restore"
+ pgo_tools.run(pgo_tools.generate_quickpkg_restoration_command(pkg))
+
+
+def find_missing_cross_libs() -> FrozenSet[str]:
+ """Returns cross-* libraries that need to be installed for workloads."""
+ equery_result = pgo_tools.run(
+ ["equery", "l", "--format=$cp", "cross-*/*"],
+ check=False,
+ stdout=subprocess.PIPE,
+ )
+
+ # If no matching package is found, equery will exit with code 3.
+ if equery_result.returncode == 3:
+ return ALL_NEEDED_CROSS_LIBS
+
+ equery_result.check_returncode()
+ has_packages = {x.strip() for x in equery_result.stdout.splitlines()}
+ return ALL_NEEDED_CROSS_LIBS - has_packages
+
+
+def ensure_cross_libs_are_installed():
+ """Ensures that we have cross-* libs for all `IMPORTANT_TRIPLES`."""
+ missing_packages = find_missing_cross_libs()
+ if not missing_packages:
+ logging.info("All cross-compiler libraries are already installed")
+ return
+
+ missing_packages = sorted(missing_packages)
+ logging.info("Installing cross-compiler libs: %s", missing_packages)
+ pgo_tools.run(
+ ["sudo", "emerge", "-j", "-G"] + missing_packages,
+ )
+
+
+def emerge_pgo_generate_llvm():
+ """Emerges a sys-devel/llvm with PGO instrumentation enabled."""
+ force_use = (
+ "llvm_pgo_generate -llvm_pgo_use"
+ # Turn ThinLTO off, since doing so results in way faster builds.
+ # This is assumed to be OK, since:
+ # - ThinLTO should have no significant impact on where Clang puts
+ # instrprof counters.
+ # - In practice, both "PGO generated with ThinLTO enabled," and "PGO
+ # generated without ThinLTO enabled," were benchmarked, and the
+ # performance difference between the two was in the noise.
+ " -thinlto"
+ # Turn ccache off, since if there are valid ccache artifacts from prior
+ # runs of this script, ccache will lead to us not getting profdata from
+ # those.
+ " -wrapper_ccache"
+ )
+ use = (os.environ.get("USE", "") + " " + force_use).strip()
+
+ # Use FEATURES=ccache since it's not much of a CPU time penalty, and if a
+ # user runs this script repeatedly, they'll appreciate it. :)
+ force_features = "ccache"
+ features = (os.environ.get("FEATURES", "") + " " + force_features).strip()
+ logging.info("Building LLVM with USE=%s", shlex.quote(use))
+ pgo_tools.run(
+ [
+ "sudo",
+ f"FEATURES={features}",
+ f"USE={use}",
+ "emerge",
+ "sys-devel/llvm",
+ ]
+ )
+
+
+def build_profiling_env(profile_dir: Path) -> Dict[str, str]:
+ profile_pattern = str(profile_dir / "profile-%m.profraw")
+ return {
+ "LLVM_PROFILE_OUTPUT_FORMAT": "profraw",
+ "LLVM_PROFILE_FILE": profile_pattern,
+ }
+
+
+def ensure_clang_invocations_generate_profiles(clang_bin: str, tmpdir: Path):
+ """Raises an exception if clang doesn't generate profraw files.
+
+ Args:
+ clang_bin: the path to a clang binary.
+ tmpdir: a place where this function can put temporary files.
+ """
+ tmpdir = tmpdir / "ensure_profiles_generated"
+ tmpdir.mkdir(parents=True)
+ pgo_tools.run(
+ [clang_bin, "--help"],
+ extra_env=build_profiling_env(tmpdir),
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL,
+ )
+ is_empty = next(tmpdir.iterdir(), None) is None
+ if is_empty:
+ raise ValueError(
+ f"The clang binary at {clang_bin} generated no profile"
+ )
+ shutil.rmtree(tmpdir)
+
+
+def write_unified_cmake_file(
+ into_dir: Path, absl_subdir: Path, gtest_subdir: Path
+):
+ (into_dir / "CMakeLists.txt").write_text(
+ textwrap.dedent(
+ f"""\
+ cmake_minimum_required(VERSION 3.10)
+
+ project(generate_pgo)
+
+ add_subdirectory({gtest_subdir})
+ add_subdirectory({absl_subdir})"""
+ ),
+ encoding="utf-8",
+ )
+
+
+def fetch_workloads_into(target_dir: Path):
+ """Fetches PGO generation workloads into `target_dir`."""
+ # The workload here is absl and gtest. The reasoning behind that selection
+ # was essentially a mix of:
+ # - absl is reasonably-written and self-contained
+ # - gtest is needed if tests are to be built; in order to have absl do much
+ # of any linking, gtest is necessary.
+ #
+ # Use the version of absl that's bundled with ChromeOS at the time of
+ # writing.
+ target_dir.mkdir(parents=True)
+
+ def fetch_and_extract(gs_url: str, into_dir: Path):
+ tgz_full = target_dir / os.path.basename(gs_url)
+ pgo_tools.run(
+ [
+ "gsutil",
+ "cp",
+ gs_url,
+ tgz_full,
+ ],
+ )
+ into_dir.mkdir()
+
+ pgo_tools.run(
+ ["tar", "xaf", tgz_full],
+ cwd=into_dir,
+ )
+
+ absl_dir = target_dir / "absl"
+ fetch_and_extract(
+ gs_url="gs://chromeos-localmirror/distfiles/"
+ "abseil-cpp-a86bb8a97e38bc1361289a786410c0eb5824099c.tar.bz2",
+ into_dir=absl_dir,
+ )
+
+ gtest_dir = target_dir / "gtest"
+ fetch_and_extract(
+ gs_url="gs://chromeos-mirror/gentoo/distfiles/"
+ "gtest-1b18723e874b256c1e39378c6774a90701d70f7a.tar.gz",
+ into_dir=gtest_dir,
+ )
+
+ unpacked_absl_dir = read_exactly_one_dirent(absl_dir)
+ unpacked_gtest_dir = read_exactly_one_dirent(gtest_dir)
+ write_unified_cmake_file(
+ into_dir=target_dir,
+ absl_subdir=unpacked_absl_dir.relative_to(target_dir),
+ gtest_subdir=unpacked_gtest_dir.relative_to(target_dir),
+ )
+
+
+@dataclasses.dataclass(frozen=True)
+class WorkloadRunner:
+ """Runs benchmark workloads."""
+
+ profraw_dir: Path
+ target_dir: Path
+ out_dir: Path
+
+ def run(
+ self,
+ triple: str,
+ extra_cflags: Optional[str] = None,
+ sysroot: Optional[str] = None,
+ ):
+ logging.info(
+ "Running workload for triple %s, extra cflags %r",
+ triple,
+ extra_cflags,
+ )
+ if self.out_dir.exists():
+ shutil.rmtree(self.out_dir)
+ self.out_dir.mkdir(parents=True)
+
+ clang = triple + "-clang"
+ profiling_env = build_profiling_env(self.profraw_dir)
+ if sysroot:
+ profiling_env["SYSROOT"] = sysroot
+
+ cmake_command: pgo_tools.Command = [
+ "cmake",
+ "-G",
+ "Ninja",
+ "-DCMAKE_BUILD_TYPE=RelWithDebInfo",
+ f"-DCMAKE_C_COMPILER={clang}",
+ f"-DCMAKE_CXX_COMPILER={clang}++",
+ "-DABSL_BUILD_TESTING=ON",
+ "-DABSL_USE_EXTERNAL_GOOGLETEST=ON",
+ "-DABSL_USE_GOOGLETEST_HEAD=OFF",
+ "-DABSL_FIND_GOOGLETEST=OFF",
+ ]
+
+ if extra_cflags:
+ cmake_command += (
+ f"-DCMAKE_C_FLAGS={extra_cflags}",
+ f"-DCMAKE_CXX_FLAGS={extra_cflags}",
+ )
+
+ cmake_command.append(self.target_dir)
+ pgo_tools.run(
+ cmake_command,
+ extra_env=profiling_env,
+ cwd=self.out_dir,
+ )
+
+ pgo_tools.run(
+ ["ninja", "-v", "all"],
+ extra_env=profiling_env,
+ cwd=self.out_dir,
+ )
+
+
+def read_exactly_one_dirent(directory: Path) -> Path:
+ """Returns the single Path under the given directory. Raises otherwise."""
+ ents = directory.iterdir()
+ ent = next(ents, None)
+ if ent is not None:
+ if next(ents, None) is None:
+ return ent
+ raise ValueError(f"Expected exactly one entry under {directory}")
+
+
+def run_workloads(target_dir: Path) -> Path:
+ """Runs all of our workloads in target_dir.
+
+ Args:
+ target_dir: a directory that already had `fetch_workloads_into` called
+ on it.
+
+ Returns:
+ A directory in which profraw files from running the workloads are
+ saved.
+ """
+ profraw_dir = target_dir / "profiles"
+ profraw_dir.mkdir()
+
+ out_dir = target_dir / "out"
+ runner = WorkloadRunner(
+ profraw_dir=profraw_dir,
+ target_dir=target_dir,
+ out_dir=out_dir,
+ )
+
+ # Run the workload once per triple.
+ for triple in IMPORTANT_TRIPLES:
+ runner.run(
+ triple, sysroot=None if triple == HOST_TRIPLE else f"/usr/{triple}"
+ )
+
+ # Add a run of ThinLTO, so any ThinLTO-specific lld bits get exercised.
+ # Also, since CrOS uses -Os often, exercise that.
+ runner.run(HOST_TRIPLE, extra_cflags="-flto=thin -Os")
+ return profraw_dir
+
+
+def convert_profraw_to_pgo_profile(profraw_dir: Path) -> Path:
+ """Creates a PGO profile from the profraw profiles in profraw_dir."""
+ output = profraw_dir / "merged.prof"
+ profile_files = list(profraw_dir.glob("profile-*profraw"))
+ if not profile_files:
+ raise ValueError("No profraw files generated?")
+
+ logging.info(
+ "Creating a PGO profile from %d profraw files", len(profile_files)
+ )
+ generate_command = [
+ "llvm-profdata",
+ "merge",
+ "--instr",
+ f"--output={output}",
+ ]
+ pgo_tools.run(generate_command + profile_files)
+ return output
+
+
+def main(argv: List[str]):
+ logging.basicConfig(
+ format=">> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: "
+ "%(message)s",
+ level=logging.DEBUG,
+ )
+
+ parser = argparse.ArgumentParser(
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+ parser.add_argument(
+ "--output",
+ required=True,
+ type=Path,
+ help="Where to put the PGO profile",
+ )
+ parser.add_argument(
+ "--use-old-binpkg",
+ action="store_true",
+ help="""
+ This script saves your initial LLVM installation as a binpkg, so it may
+ restore that installation later in the build. Passing --use-old-binpkg
+ allows this script to use a binpkg from a prior invocation of this
+ script.
+ """,
+ )
+ opts = parser.parse_args(argv)
+
+ pgo_tools.exit_if_not_in_chroot()
+
+ output = opts.output
+
+ llvm_binpkg_is_fresh = ensure_llvm_binpkg_exists()
+ if not llvm_binpkg_is_fresh and not opts.use_old_binpkg:
+ sys.exit(
+ textwrap.dedent(
+ f"""\
+ A LLVM binpkg packed by a previous run of this script is
+ available. If you intend this run to be another attempt at the
+ previous run, please pass --use-old-binpkg (so the old LLVM
+ binpkg is used as our 'baseline'). If you don't, please remove
+ the file referring to it at {SAVED_LLVM_BINPKG_STAMP}.
+ """
+ )
+ )
+
+ logging.info("Ensuring `cross-` libraries are installed")
+ ensure_cross_libs_are_installed()
+ tempdir = Path(tempfile.mkdtemp(prefix="generate_llvm_pgo_profile_"))
+ try:
+ workloads_path = tempdir / "workloads"
+ logging.info("Fetching workloads")
+ fetch_workloads_into(workloads_path)
+
+ # If our binpkg is not fresh, we may be operating with a weird LLVM
+ # (e.g., a PGO'ed one ;) ). Ensure we always start with that binpkg as
+ # our baseline.
+ if not llvm_binpkg_is_fresh:
+ restore_llvm_binpkg()
+
+ logging.info("Building PGO instrumented LLVM")
+ emerge_pgo_generate_llvm()
+
+ logging.info("Ensuring instrumented compilers generate profiles")
+ for triple in IMPORTANT_TRIPLES:
+ ensure_clang_invocations_generate_profiles(
+ triple + "-clang", tempdir
+ )
+
+ logging.info("Running workloads")
+ profraw_dir = run_workloads(workloads_path)
+
+ # This is a subtle but critical step. The LLVM we're currently working
+ # with was built by the LLVM represented _by our binpkg_, which may be
+ # a radically different version of LLVM than what was installed (e.g.,
+ # it could be from our bootstrap SDK, which could be many months old).
+ #
+ # If our current LLVM's llvm-profdata is used to interpret the profraw
+ # files:
+ # 1. The profile generated will be for our new version of clang, and
+ # may therefore be too new for the older version that we still have
+ # to support.
+ # 2. There may be silent incompatibilities, as the stability guarantees
+ # of profraw files are not immediately apparent.
+ logging.info("Restoring LLVM's binpkg")
+ restore_llvm_binpkg()
+ pgo_profile = convert_profraw_to_pgo_profile(profraw_dir)
+ shutil.copyfile(pgo_profile, output)
+ except:
+ # Leave the tempdir, as it might help people debug.
+ logging.info("NOTE: Tempdir will remain at %s", tempdir)
+ raise
+
+ logging.info("Removing now-obsolete tempdir")
+ shutil.rmtree(tempdir)
+ logging.info("PGO profile is available at %s.", output)
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/pgo_tools/generate_pgo_profile_test.py b/pgo_tools/generate_pgo_profile_test.py
new file mode 100755
index 00000000..8265bf45
--- /dev/null
+++ b/pgo_tools/generate_pgo_profile_test.py
@@ -0,0 +1,112 @@
+#!/usr/bin/env python3
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Tests for generate_pgo_profile."""
+
+from pathlib import Path
+import shutil
+import tempfile
+import unittest
+from unittest import mock
+
+import generate_pgo_profile
+import pgo_tools
+
+
+class Test(unittest.TestCase):
+ """Tests for generate_pgo_profile."""
+
+ @mock.patch.object(pgo_tools, "run")
+ def test_find_missing_cross_libs_works_for_empty_results(self, mock_run):
+ mock_run.return_value.returncode = 3
+ mock_run.return_value.stdout = ""
+ self.assertEqual(
+ generate_pgo_profile.find_missing_cross_libs(),
+ generate_pgo_profile.ALL_NEEDED_CROSS_LIBS,
+ )
+
+ mock_run.return_value.returncode = 0
+ self.assertEqual(
+ generate_pgo_profile.find_missing_cross_libs(),
+ generate_pgo_profile.ALL_NEEDED_CROSS_LIBS,
+ )
+
+ @mock.patch.object(pgo_tools, "run")
+ def test_find_missing_cross_libs_filters_results_properly(self, mock_run):
+ mock_run.return_value.returncode = 0
+ mock_run.return_value.stdout = "\n".join(
+ generate_pgo_profile.ALL_NEEDED_CROSS_LIBS
+ )
+ self.assertEqual(generate_pgo_profile.find_missing_cross_libs(), set())
+
+ some_cross_libs = sorted(generate_pgo_profile.ALL_NEEDED_CROSS_LIBS)
+ del some_cross_libs[len(some_cross_libs) // 3 :]
+ mock_run.return_value.stdout = "\n".join(
+ some_cross_libs + ["cross-foo/bar"]
+ )
+
+ expected_result = generate_pgo_profile.ALL_NEEDED_CROSS_LIBS - set(
+ some_cross_libs
+ )
+ self.assertEqual(
+ generate_pgo_profile.find_missing_cross_libs(), expected_result
+ )
+
+ def make_tempdir(self) -> Path:
+ tempdir = Path(tempfile.mkdtemp(prefix="generate_pgo_profile_test_"))
+ self.addCleanup(lambda: shutil.rmtree(tempdir))
+ return tempdir
+
+ def test_read_exactly_one_dirent_works(self):
+ tempdir = self.make_tempdir()
+ ent = tempdir / "one-ent"
+ ent.touch()
+
+ self.assertEqual(
+ generate_pgo_profile.read_exactly_one_dirent(tempdir), ent
+ )
+
+ def test_read_exactly_one_dirent_fails_when_no_ents(self):
+ tempdir = self.make_tempdir()
+ with self.assertRaisesRegex(ValueError, "^Expected exactly one"):
+ generate_pgo_profile.read_exactly_one_dirent(tempdir)
+
+ def test_read_exactly_one_dirent_fails_when_multiple_ents(self):
+ tempdir = self.make_tempdir()
+ (tempdir / "a").touch()
+ (tempdir / "b").touch()
+ with self.assertRaisesRegex(ValueError, "^Expected exactly one"):
+ generate_pgo_profile.read_exactly_one_dirent(tempdir)
+
+ @mock.patch.object(pgo_tools, "run")
+ def test_profraw_conversion_works(self, mock_run):
+ tempdir = self.make_tempdir()
+ profiles = [
+ tempdir / "profile-foo.profraw",
+ tempdir / "profile-bar.profraw",
+ ]
+ not_a_profile = tempdir / "not-a-profile.profraw"
+ for f in profiles + [not_a_profile]:
+ f.touch()
+
+ result = generate_pgo_profile.convert_profraw_to_pgo_profile(tempdir)
+ self.assertNotEqual(result.stem, ".profraw")
+ try:
+ # is_relative_to was added in Py3.9; until the chroot has that,
+ # this code needs to use `relative_to` & check for exceptions.
+ result.relative_to(tempdir)
+ except ValueError:
+ self.fail(f"{result} should be relative to {tempdir}")
+
+ mock_run.assert_called_once()
+ run_cmd = mock_run.call_args[0][0]
+ for p in profiles:
+ self.assertIn(p, run_cmd)
+ self.assertNotIn(not_a_profile, run_cmd)
+ self.assertIn(f"--output={result}", run_cmd)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/pgo_tools/merge_profdata_and_upload.py b/pgo_tools/merge_profdata_and_upload.py
deleted file mode 100755
index bb53ed6c..00000000
--- a/pgo_tools/merge_profdata_and_upload.py
+++ /dev/null
@@ -1,420 +0,0 @@
-#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-# Copyright 2019 The ChromiumOS Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Download profdata from different arches, merge them and upload to gs.
-
-The script is used for updating the PGO profiles for LLVM. The workflow
-is that the script will download profdata from different PGO builds, merge
-them and then upload it to a gs location that LLVM can access.
-
-The simplest way of using this script, is to run:
- ./merge_profdata_and_upload.py --all_latest_profiles
-which will automatically grab profdata from latest PGO generate builders
-for three different architectures and merge them. LLVM hash is also
-detected automatically from the artifacts.
-
-If you want to specify certain llvm hash, run it with:
- ./merge_profdata_and_upload.py --all_latest_profiles --llvm_hash LLVM_HASH
-Note that hash checking will fail if the llvm hash you provided is not the
-same as those in artifacts, or llvm hash in different artifacts are not the
-same.
-
-To only use profiles from buildbucket tasks for PGO generate, run it with:
- ./merge_profdata_and_upload.py -b amd64/bb_id1 -b arm/bb_id2 ...
-The buildbucket id can be found using `bb ls` command after manually launched
-builder finishes.
-
-There is a chance that builders only succeeded partially, in this case, you
-can run this script to merge both profdata from builder scheduled and manually
-launched:
- ./merge_profdata_and_upload.py -l arm -l amd64 -b arm64/bb_id
-In this example, the script will merge profdata from arm and amd64 builder, and
-profdata from an arm64 buildbucket task.
-"""
-
-
-import argparse
-import collections
-import distutils.spawn
-import json
-import os
-import os.path
-import shutil
-import subprocess
-import sys
-import tempfile
-
-
-_LLVM_PROFDATA = "/usr/bin/llvm-profdata"
-_GS_PREFIX = "gs://"
-
-_LLVMMetadata = collections.namedtuple("_LLVMMetadata", ["head_sha"])
-
-
-def _fetch_gs_artifact(remote_name, local_name):
- """Fetch single file from remote gs location to local.
-
- Args:
- remote_name: full gs location to the file.
- local_name: the name of local file to be copied to.
- """
- assert remote_name.startswith(_GS_PREFIX)
- subprocess.check_call(["gsutil", "cp", remote_name, local_name])
-
-
-def _get_gs_profdata(remote_profdata, arch):
- """Fetch and extract profdata from remote gs location.
-
- Args:
- remote_profdata: remote gs location of the profdata tarball.
- arch: directory named with arch to saperate each profdata.
-
- Returns:
- Local location of the extracted profdata.
- """
- tar = "llvm_profdata.tar.xz"
- _fetch_gs_artifact(remote_profdata, tar)
- extract_cmd = ["tar", "-xvf", tar]
-
- profdata_name = subprocess.check_output(extract_cmd).strip()
- # The output of the `tar` command should only contain one line of the
- # extracted profdata name.
- if b".llvm.profdata" not in profdata_name:
- raise RuntimeError("No profdata in the tarball: %s" % remote_profdata)
-
- os.mkdir(arch)
- profdata_loc = os.path.join(arch, "llvm.profdata")
- os.rename(profdata_name, profdata_loc)
- print("Profdata extracted to: %s" % profdata_loc)
- return profdata_loc
-
-
-def _get_gs_metadata(remote_metadata):
- """Fetch metadata from remote gs location and read the LLVM head_sha.
-
- Args:
- remote_metadata: remote gs location of the metadata json file.
-
- Returns:
- LLVM head_sha metadata
- """
- metadata_basename = "llvm_metadata.json"
- _fetch_gs_artifact(remote_metadata, metadata_basename)
-
- with open(metadata_basename) as f:
- result = json.load(f)
-
- return _LLVMMetadata(head_sha=result["head_sha"])
-
-
-def _find_latest_artifacts(gs_url, arch):
- """Fetch the latest profdata and metadata from a give gs location.
-
- Args:
- gs_url: a gs location containing one or more artifacts to fetch.
- arch: the arch profdata collected from.
-
- Returns:
- A tuple of local profdata location and metadata
- """
- assert gs_url.startswith(_GS_PREFIX)
- try:
- # List all artifacts in the gs location and sort by time.
- output = (
- subprocess.check_output(
- ["gsutil", "ls", "-l", gs_url], encoding="utf-8"
- )
- .strip()
- .split("\n")
- )
- lines = sorted(output, key=lambda x: x.split()[1], reverse=True)
- except subprocess.CalledProcessError:
- raise RuntimeError("Artifacts not found: %s" % gs_url)
-
- # Use a loop to go through all artifacts to find the latest profdata.
- # An example of the output of latest builder bucket:
- # pylint: disable=line-too-long
- # 5006528 2020-05-31T10:08:48Z gs://chromeos-toolchain-artifacts/llvm-pgo/arm/llvm-11.0_pre387436_p20200403-r7-a8e5dcb072b1f794883ae8125fb08c06db678d56.llvm.profdata.tar.xz
- # 56 2020-05-31T10:08:48Z gs://chromeos-toolchain-artifacts/llvm-pgo/arm/llvm-11.0_pre387436_p20200403-r7-a8e5dcb072b1f794883ae8125fb08c06db678d56.llvm_metadata.json
- # 5005952 2020-05-24T10:53:34Z gs://chromeos-toolchain-artifacts/llvm-pgo/arm/llvm-11.0_pre387436_p20200403-r5-a8e5dcb072b1f794883ae8125fb08c06db678d56.llvm.profdata.tar.xz
- # 56 2020-05-24T10:53:34Z gs://chromeos-toolchain-artifacts/llvm-pgo/arm/llvm-11.0_pre387436_p20200403-r5-a8e5dcb072b1f794883ae8125fb08c06db678d56.llvm_metadata.json
- # An example for the lines of buildbucket location:
- # 5004260 2020-05-29T09:48:04Z gs://chromeos-image-archive/arm-pgo-generate-llvm-next-toolchain/R85-13254.0.0-1-8879010326583123168/llvm-11.0_pre387436_p20200403-r7-a8e5dcb072b1f794883ae8125fb08c06db678d56.llvm.profdata.tar.xz
- # 56 2020-05-29T09:48:04Z gs://chromeos-image-archive/arm-pgo-generate-llvm-next-toolchain/R85-13254.0.0-1-8879010326583123168/llvm-11.0_pre387436_p20200403-r7-a8e5dcb072b1f794883ae8125fb08c06db678d56.llvm_metadata.json
- # pylint: enable=line-too-long
- profdata_url = ""
- for line in lines:
- url = line.split()[-1]
- if ".llvm.profdata.tar.xz" in url:
- profile_path = _get_gs_profdata(url, arch)
- profdata_url = url
- break
- if not profile_path or not profdata_url:
- raise RuntimeError("No profdata found from %s" % gs_url)
-
- metadata_url = profdata_url.replace(
- ".llvm.profdata.tar.xz", ".llvm_metadata.json"
- )
- metadata = _get_gs_metadata(metadata_url)
- if not metadata:
- raise RuntimeError("No metadata found from %s" % gs_url)
- return metadata, profile_path
-
-
-def _fetch_from_latest(arch):
- """Fetch artifacts from latest builders.
-
- Args:
- arch: the arch profdata collected from.
-
- Returns:
- A tuple of local profdata location and metadata
- """
- print("\nFETCHING LATEST PROFDATA ON %s..." % arch.upper())
- remote_latest = "%schromeos-toolchain-artifacts/llvm-pgo/%s" % (
- _GS_PREFIX,
- arch,
- )
- return _find_latest_artifacts(remote_latest, arch)
-
-
-def _fetch_from_buildbucket(arch, bb):
- """Fetch artifacts from buildbucket task.
-
- Args:
- arch: the arch profdata collected from.
- bb: buildbucket id.
-
- Returns:
- A tuple of local profdata location and metadata
- """
- print("\nFETCHING BUILDBUCKET PROFDATA ON %s..." % arch.upper())
- remote_arch = (
- "%schromeos-image-archive/%s-pgo-generate-llvm-next-toolchain"
- % (
- _GS_PREFIX,
- arch,
- )
- )
- # List all buckets under {arch}-pgo-generate-llvm-next-toolchain and
- # grep with buildbucket id.
- remote_bb = (
- subprocess.check_output(["gsutil", "ls", remote_arch], encoding="utf-8")
- .strip()
- .split("\n")
- )
- for line in remote_bb:
- if bb in line:
- return _find_latest_artifacts(line, arch)
- raise RuntimeError(
- "No matched results found in %s with bb: %s" % (arch, bb)
- )
-
-
-def _merge_profdata(profdata_list, output_name):
- """Merge profdata.
-
- Args:
- profdata_list: list of profdata location of each arch.
- output_name: name of merged profdata.
- """
- merge_cmd = [
- _LLVM_PROFDATA,
- "merge",
- "-output",
- output_name,
- ] + profdata_list
- print("\nMerging PGO profiles.\nCMD: %s" % merge_cmd)
- subprocess.check_call(merge_cmd)
-
-
-def _tar_and_upload_profdata(profdata, name_suffix):
- """Create a tarball of merged profdata and upload to certain gs location.
-
- Args:
- profdata: location of merged profdata.
- name_suffix: usually the LLVM head_sha.
- """
- tarball = "llvm-profdata-%s.tar.xz" % name_suffix
- print("Making profdata tarball: %s" % tarball)
- subprocess.check_call(
- ["tar", "--sparse", "-I", "xz", "-cf", tarball, profdata]
- )
-
- upload_location = "%schromeos-localmirror/distfiles/%s" % (
- _GS_PREFIX,
- tarball,
- )
-
- # TODO: it's better to create a subdir: distfiles/llvm_pgo_profile, but
- # now llvm could only recognize distfiles.
- upload_cmd = [
- "gsutil",
- "-m",
- "cp",
- "-n",
- "-a",
- "public-read",
- tarball,
- upload_location,
- ]
- print("\nUploading tarball to gs.\nCMD: %s\n" % upload_cmd)
-
- # gsutil prints all status to stderr, oddly enough.
- gs_output = subprocess.check_output(
- upload_cmd, stderr=subprocess.STDOUT, encoding="utf-8"
- )
-
- # gsutil exits successfully even if it uploaded nothing. It prints a summary
- # of what all it did, though. Successful uploads are just a progress bar,
- # unsuccessful ones note that items were skipped.
- if "Skipping existing item" in gs_output:
- raise ValueError(
- "Profile upload failed: would overwrite an existing "
- "profile at %s" % upload_location
- )
-
-
-def main():
- parser = argparse.ArgumentParser(
- description=__doc__,
- formatter_class=argparse.RawDescriptionHelpFormatter,
- )
- parser.add_argument(
- "-a",
- "--all_latest_profiles",
- action="store_true",
- help="Merge and upload profiles from the latest builders.",
- )
- parser.add_argument(
- "-l",
- "--latest",
- default=[],
- action="append",
- help="User can specify the profdata from which builder with specific "
- "architecture to download. By default, we merge profdata from arm, "
- "arm64, amd64.",
- )
- parser.add_argument(
- "-b",
- "--buildbucket",
- default=[],
- action="append",
- help="Extra pgo-generate-llvm-next-toolchain buildbucket results to be "
- "used. Format should be: {arch}/{bb_id}.",
- )
- parser.add_argument(
- "-o",
- "--output",
- default="llvm.profdata",
- help="Where to put merged PGO profile. The default is to not save it "
- "anywhere.",
- )
- parser.add_argument(
- "--llvm_hash",
- help="The LLVM hash to select for the profiles. Generally autodetected.",
- )
- args = parser.parse_args()
-
- if not args.all_latest_profiles and not (args.latest or args.buildbucket):
- parser.error(
- "Please specify whether to use latest profiles or "
- "profiles from buildbucket"
- )
-
- if args.all_latest_profiles and (args.latest or args.buildbucket):
- parser.error(
- "--all_latest_profiles cannot be specified together "
- "with --latest or --buildbucket"
- )
-
- latest = (
- ["arm", "arm64", "amd64"] if args.all_latest_profiles else args.latest
- )
-
- all_arch_list = latest.copy()
- arch_bb_list = []
- if args.buildbucket:
- for arch_bb in args.buildbucket:
- arch, bb = arch_bb.split("/")
- arch_bb_list.append((arch, bb))
- all_arch_list.append(arch)
-
- if len(set(all_arch_list)) != len(all_arch_list):
- parser.error("Each arch can be only passed once.")
-
- if not distutils.spawn.find_executable(_LLVM_PROFDATA):
- sys.exit(_LLVM_PROFDATA + " not found; are you in the chroot?")
-
- initial_dir = os.getcwd()
- temp_dir = tempfile.mkdtemp(prefix="merge_pgo")
- success = True
- try:
- os.chdir(temp_dir)
- profdata_list = []
- heads = set()
-
- def append_artifacts(fetched_tuple):
- llvm_metadata, profdata_loc = fetched_tuple
- if os.path.getsize(profdata_loc) < 512 * 1024:
- raise RuntimeError(
- "The PGO profile in local path %s is suspiciously "
- "small. Something might have gone "
- "wrong." % profdata_loc
- )
- heads.add(llvm_metadata.head_sha)
- profdata_list.append(profdata_loc)
-
- for arch in latest:
- append_artifacts(_fetch_from_latest(arch))
-
- for arch, bb in arch_bb_list:
- append_artifacts(_fetch_from_buildbucket(arch, bb))
-
- assert heads, "Didn't fetch anything?"
-
- def die_with_head_complaint(complaint):
- extra = " (HEADs found: %s)" % sorted(heads)
- raise RuntimeError(complaint.rstrip() + extra)
-
- llvm_hash = args.llvm_hash
- if not llvm_hash:
- if len(heads) != 1:
- die_with_head_complaint(
- "%d LLVM HEADs were found, which is more than one. You probably "
- "want a consistent set of HEADs for a profile. If you know you "
- "don't, please specify --llvm_hash, and note that *all* profiles "
- "will be merged into this final profile, regardless of their "
- "reported HEAD." % len(heads)
- )
- (llvm_hash,) = heads
-
- if llvm_hash not in heads:
- assert llvm_hash == args.llvm_hash
- die_with_head_complaint(
- "HEAD %s wasn't found in any fetched artifacts." % llvm_hash
- )
-
- print("\nUsing LLVM hash: %s" % llvm_hash)
-
- _merge_profdata(profdata_list, args.output)
- print("Merged profdata locates at %s" % os.path.abspath(args.output))
- _tar_and_upload_profdata(args.output, name_suffix=llvm_hash)
- print("\nMerged profdata uploaded successfully.")
- except:
- success = False
- raise
- finally:
- os.chdir(initial_dir)
- if success:
- print("Clearing temp directory.")
- shutil.rmtree(temp_dir, ignore_errors=True)
- else:
- print("Script fails, temp directory is at: %s" % temp_dir)
-
-
-if __name__ == "__main__":
- sys.exit(main())
diff --git a/pgo_tools/monitor_pgo_profiles.py b/pgo_tools/monitor_pgo_profiles.py
deleted file mode 100755
index 2c54ee80..00000000
--- a/pgo_tools/monitor_pgo_profiles.py
+++ /dev/null
@@ -1,123 +0,0 @@
-#!/usr/bin/env python3
-# Copyright 2020 The ChromiumOS Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Emails the mage if PGO profile generation hasn't succeeded recently."""
-
-import argparse
-import datetime
-import logging
-import subprocess
-import sys
-from typing import List, NamedTuple, Optional, Tuple
-
-
-PGO_BUILDBOT_LINK = (
- "https://ci.chromium.org/p/chromeos/builders/toolchain/"
- "pgo-generate-llvm-next-orchestrator"
-)
-
-
-class ProfdataInfo(NamedTuple):
- """Data about an llvm profdata in our gs:// bucket."""
-
- date: datetime.datetime
- location: str
-
-
-def parse_date(date: str) -> datetime.datetime:
- time_format = "%Y-%m-%dT%H:%M:%SZ"
- if not date.endswith("Z"):
- time_format += "%z"
- return datetime.datetime.strptime(date, time_format)
-
-
-def fetch_most_recent_profdata(arch: str) -> ProfdataInfo:
- result = subprocess.run(
- [
- "gsutil.py",
- "ls",
- "-l",
- f"gs://chromeos-toolchain-artifacts/llvm-pgo/{arch}/"
- "*.profdata.tar.xz",
- ],
- check=True,
- stdout=subprocess.PIPE,
- encoding="utf-8",
- )
-
- # Each line will be a profdata; the last one is a summary, so drop it.
- infos = []
- for rec in result.stdout.strip().splitlines()[:-1]:
- _size, date, url = rec.strip().split()
- infos.append(ProfdataInfo(date=parse_date(date), location=url))
- return max(infos)
-
-
-def compose_complaint(
- out_of_date_profiles: List[Tuple[datetime.datetime, ProfdataInfo]]
-) -> Optional[str]:
- if not out_of_date_profiles:
- return None
-
- if len(out_of_date_profiles) == 1:
- body_lines = ["1 profile is out of date:"]
- else:
- body_lines = [f"{len(out_of_date_profiles)} profiles are out of date:"]
-
- for arch, profdata_info in out_of_date_profiles:
- body_lines.append(
- f"- {arch} (most recent profile was from {profdata_info.date} at "
- f"{profdata_info.location!r})"
- )
-
- body_lines.append("\n")
- body_lines.append(
- "PTAL to see if the llvm-pgo-generate bots are functioning normally. "
- f"Their status can be found at {PGO_BUILDBOT_LINK}."
- )
- return "\n".join(body_lines)
-
-
-def main() -> None:
- logging.basicConfig(level=logging.INFO)
-
- parser = argparse.ArgumentParser(
- description=__doc__,
- formatter_class=argparse.RawDescriptionHelpFormatter,
- )
- parser.add_argument(
- "--max_age_days",
- # These builders run ~weekly. If we fail to generate two in a row,
- # something's probably wrong.
- default=15,
- type=int,
- help="How old to let profiles get before complaining, in days",
- )
- args = parser.parse_args()
-
- now = datetime.datetime.now()
- logging.info("Start time is %r", now)
-
- max_age = datetime.timedelta(days=args.max_age_days)
- out_of_date_profiles = []
- for arch in ("arm", "arm64", "amd64"):
- logging.info("Fetching most recent profdata for %r", arch)
- most_recent = fetch_most_recent_profdata(arch)
- logging.info("Most recent profdata for %r is %r", arch, most_recent)
-
- age = now - most_recent.date
- if age >= max_age:
- out_of_date_profiles.append((arch, most_recent))
-
- complaint = compose_complaint(out_of_date_profiles)
- if complaint:
- logging.error("%s", complaint)
- sys.exit(1)
-
- logging.info("Nothing seems wrong")
-
-
-if __name__ == "__main__":
- sys.exit(main())
diff --git a/pgo_tools/monitor_pgo_profiles_unittest.py b/pgo_tools/monitor_pgo_profiles_unittest.py
deleted file mode 100755
index e6fc0649..00000000
--- a/pgo_tools/monitor_pgo_profiles_unittest.py
+++ /dev/null
@@ -1,104 +0,0 @@
-#!/usr/bin/env python3
-# Copyright 2020 The ChromiumOS Authors
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Tests for monitor_pgo_profiles."""
-
-import datetime
-import subprocess
-import unittest
-import unittest.mock
-
-import monitor_pgo_profiles
-
-
-class Test(unittest.TestCase):
- """Tests for monitor_pgo_profiles."""
-
- def test_compose_complaint_with_zero_out_of_date(self):
- self.assertIsNone(monitor_pgo_profiles.compose_complaint([]))
-
- def test_compose_complaint_with_one_out_of_date(self):
- profdata_info = monitor_pgo_profiles.ProfdataInfo(
- date=datetime.datetime(2020, 1, 2, 3, 4, 5),
- location="gs://somewhere",
- )
- result = monitor_pgo_profiles.compose_complaint(
- [
- ("some_arch", profdata_info),
- ]
- )
- self.assertEqual(
- result,
- "\n".join(
- (
- "1 profile is out of date:",
- f"- some_arch (most recent profile was from {profdata_info.date} "
- f"at {profdata_info.location!r})",
- "",
- "",
- "PTAL to see if the llvm-pgo-generate bots are functioning "
- "normally. Their status can be found at "
- f"{monitor_pgo_profiles.PGO_BUILDBOT_LINK}.",
- )
- ),
- )
-
- def test_compose_complaint_with_two_out_of_date(self):
- profdata_info_1 = monitor_pgo_profiles.ProfdataInfo(
- date=datetime.datetime(2020, 1, 2, 3, 4, 5),
- location="gs://somewhere",
- )
- profdata_info_2 = monitor_pgo_profiles.ProfdataInfo(
- date=datetime.datetime(2020, 3, 2, 1, 4, 5),
- location="gs://somewhere-else",
- )
- result = monitor_pgo_profiles.compose_complaint(
- [
- ("some_arch", profdata_info_1),
- ("some_other_arch", profdata_info_2),
- ]
- )
- self.assertEqual(
- result,
- "\n".join(
- (
- "2 profiles are out of date:",
- f"- some_arch (most recent profile was from {profdata_info_1.date} "
- f"at {profdata_info_1.location!r})",
- f"- some_other_arch (most recent profile was from "
- f"{profdata_info_2.date} at {profdata_info_2.location!r})",
- "",
- "",
- "PTAL to see if the llvm-pgo-generate bots are functioning "
- "normally. Their status can be found at "
- f"{monitor_pgo_profiles.PGO_BUILDBOT_LINK}.",
- )
- ),
- )
-
- @unittest.mock.patch.object(subprocess, "run")
- def test_fetching_profdata_functions(self, subprocess_run_mock):
- ls_return_value = unittest.mock.MagicMock()
- ls_return_value.stdout = "\n".join(
- (
- " 1234 2020-06-26T05:26:40Z gs://bar",
- " 44 2020-06-23T05:26:40Z gs://foo",
- " 1234 2020-06-25T05:26:40Z gs://zzz",
- )
- )
- subprocess_run_mock.return_value = ls_return_value
-
- most_recent = monitor_pgo_profiles.fetch_most_recent_profdata("arm")
- self.assertEqual(
- most_recent,
- monitor_pgo_profiles.ProfdataInfo(
- date=datetime.datetime(2020, 6, 26, 5, 26, 40),
- location="gs://bar",
- ),
- )
-
-
-if __name__ == "__main__":
- unittest.main()
diff --git a/pgo_tools/pgo_tools.py b/pgo_tools/pgo_tools.py
new file mode 100644
index 00000000..577fa376
--- /dev/null
+++ b/pgo_tools/pgo_tools.py
@@ -0,0 +1,160 @@
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""A collection of tools used by the PGO scripts here."""
+
+import contextlib
+import logging
+import os
+from pathlib import Path
+import re
+import shlex
+import subprocess
+import sys
+import tempfile
+from typing import Any, Dict, Generator, IO, List, Optional, Union
+
+
+Command = List[Union[str, Path]]
+
+
+def run(
+ command: Command,
+ cwd: Optional[Path] = None,
+ check: bool = True,
+ extra_env: Optional[Dict[str, str]] = None,
+ stdout: Union[IO[Any], int, None] = None,
+ stderr: Union[IO[Any], int, None] = None,
+) -> subprocess.CompletedProcess:
+ """Convenient wrapper around subprocess.run."""
+ if extra_env:
+ env = dict(os.environ)
+ env.update(extra_env)
+ else:
+ env = None
+
+ if logging.getLogger().isEnabledFor(logging.DEBUG):
+ c = " ".join(shlex.quote(str(x)) for x in command)
+ dir_extra = f" in {cwd}" if cwd is not None else ""
+ logging.debug("Running `%s`%s", c, dir_extra)
+
+ return subprocess.run(
+ command,
+ check=check,
+ cwd=cwd,
+ env=env,
+ encoding="utf-8",
+ stdin=subprocess.DEVNULL,
+ stdout=stdout,
+ stderr=stderr,
+ )
+
+
+def installed_llvm_has_pgo_generate_enabled() -> bool:
+ """Returns whether the currently-installed LLVM has USE=pgo_generate."""
+ equery_output = run(
+ ["equery", "--no-color", "--no-pipe", "u", "sys-devel/llvm"],
+ stdout=subprocess.PIPE,
+ ).stdout
+
+ # The output of `equery` is in the format:
+ # `${default_state_if_emerged} ${state_of_installed_pkg} llvm_pgo_generate`
+ #
+ # The relevant bit is the second.
+ r = re.compile(r"^ [+-] ([+-]) llvm_pgo_generate\s", re.MULTILINE)
+ results = r.findall(equery_output)
+ if not results:
+ raise ValueError(
+ "No llvm_pgo_generate line found in USE for sys-devel/llvm"
+ )
+
+ if len(results) > 1:
+ raise ValueError(
+ "Multiple llvm_pgo_generate line found in USE for sys-devel/llvm"
+ )
+
+ return results[0] == "+"
+
+
+def quickpkg_llvm() -> Path:
+ """Runs quickpkg to generate an LLVM binpkg."""
+ if installed_llvm_has_pgo_generate_enabled():
+ # If you do want this, feel free to find this check and bypass it.
+ # There's nothing _inherently wrong_ with using a +pgo_generate LLVM.
+ # It'll just take *a lot* of extra time (2.5x+) for no reason. If you
+ # want to start fresh:
+ # ```
+ # sudo rm -rf /var/lib/portage/pkgs/sys-devel/llvm*tbz2 && \
+ # sudo emerge -G sys-devel/llvm
+ # ```
+ raise ValueError(
+ "Base LLVM version has pgo_generate enabled; this is "
+ "almost definitely not what you want. You can "
+ "quickly restore to a non-pgo_generate LLVM by "
+ "running `sudo emerge -G sys-devel/llvm`."
+ )
+
+ logging.info("Building binpackage for existing sys-devel/llvm installation")
+ quickpkg_result = run(
+ ["quickpkg", "sys-devel/llvm"], stdout=subprocess.PIPE
+ ).stdout
+ # We have to scrape for the package's name, since the package generated is
+ # for the _installed_ version of LLVM, which might not match the current
+ # ebuild's version.
+ matches = re.findall(
+ r"Building package for sys-devel/(llvm-[^ ]+) ", quickpkg_result
+ )
+ if len(matches) != 1:
+ raise ValueError(
+ f"Couldn't determine LLVM version from {quickpkg_result!r};"
+ f"candidates: {matches}"
+ )
+
+ llvm_ver = matches[0]
+ pkg = Path("/var/lib/portage/pkgs/sys-devel", llvm_ver + ".tbz2")
+ assert pkg.exists(), f"expected binpkg at {pkg} not found"
+ return pkg
+
+
+def generate_quickpkg_restoration_command(quickpkg_path: Path) -> Command:
+ """Returns a command you can run to restore the quickpkg'ed package."""
+ package_ver = quickpkg_path.stem
+ category = quickpkg_path.parent.name
+ return ["sudo", "emerge", "--usepkgonly", f"={category}/{package_ver}"]
+
+
+def is_in_chroot() -> bool:
+ """Returns whether this script was invoked inside of the chroot."""
+ return Path("/etc/cros_chroot_version").exists()
+
+
+def exit_if_not_in_chroot():
+ """Calls sys.exit if this script was not run inside of the chroot."""
+ if not is_in_chroot():
+ sys.exit("Run me inside of the chroot.")
+
+
+def exit_if_in_chroot():
+ """Calls sys.exit if this script was run inside of the chroot."""
+ if is_in_chroot():
+ sys.exit("Run me outside of the chroot.")
+
+
+@contextlib.contextmanager
+def temporary_file(prefix: Optional[str] = None) -> Generator[Path, None, None]:
+ """Yields a temporary file name, and cleans it up on exit.
+
+ This differs from NamedTemporaryFile in that it doesn't keep a handle to
+ the file open. This is useful if the temporary file is intended to be
+ passed to another process (e.g., through a flag), since that other process
+ might/might not overwite the file, leading to subtle bugs about reusing the
+ File-like aspects of NamedTemporaryFile.
+ """
+ fd, tmp = tempfile.mkstemp(prefix=prefix)
+ tmp_path = Path(tmp)
+ try:
+ os.close(fd)
+ yield tmp_path
+ finally:
+ tmp_path.unlink(missing_ok=True)
diff --git a/pgo_tools/pgo_tools_test.py b/pgo_tools/pgo_tools_test.py
new file mode 100755
index 00000000..ad0e853f
--- /dev/null
+++ b/pgo_tools/pgo_tools_test.py
@@ -0,0 +1,108 @@
+#!/usr/bin/env python3
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Tests for pgo_tools."""
+
+from pathlib import Path
+import textwrap
+import unittest
+from unittest import mock
+
+import pgo_tools
+
+
+class Test(unittest.TestCase):
+ """Tests for pgo_tools."""
+
+ @mock.patch.object(pgo_tools, "run")
+ def test_pgo_generate_checking_works(self, mock_run):
+ equery_u_output = textwrap.dedent(
+ """\
+ [ Legend : U - final flag setting for installation]
+ [ : I - package is installed with flag ]
+ [ Colors : set, unset ]
+ * Found these USE flags for sys-devel/llvm:
+ U I
+ - - llvm-next_pgo_use : <unknown>
+ - - llvm-tot : <unknown>
+ - + llvm_pgo_generate : <unknown>
+ + - llvm_pgo_use : <unknown>
+ """
+ )
+ mock_run.return_value.stdout = equery_u_output
+ self.assertTrue(pgo_tools.installed_llvm_has_pgo_generate_enabled())
+
+ mock_run.assert_called_once()
+
+ mock_run.return_value.stdout = equery_u_output.replace(
+ "+ llvm_pgo_generate", "- llvm_pgo_generate"
+ )
+ self.assertFalse(pgo_tools.installed_llvm_has_pgo_generate_enabled())
+
+ @mock.patch.object(pgo_tools, "run")
+ def test_pgo_generate_checking_raises_on_zero_pgo_updates(self, mock_run):
+ mock_run.return_value.stdout = textwrap.dedent(
+ """\
+ [ Legend : U - final flag setting for installation]
+ - - llvm-next_pgo_use : <unknown>
+ - - llvm-tot : <unknown>
+ + - llvm_pgo_use : <unknown>
+ """
+ )
+ with self.assertRaisesRegex(ValueError, "^No llvm_pgo_generate"):
+ pgo_tools.installed_llvm_has_pgo_generate_enabled()
+
+ @mock.patch.object(pgo_tools, "run")
+ def test_pgo_generate_checking_raises_on_many_pgo_updates(self, mock_run):
+ mock_run.return_value.stdout = textwrap.dedent(
+ """\
+ [ Legend : U - final flag setting for installation]
+ - - llvm-next_pgo_use : <unknown>
+ - - llvm-tot : <unknown>
+ - + llvm_pgo_generate : <unknown>
+ - + llvm_pgo_generate : <unknown>
+ + - llvm_pgo_use : <unknown>
+ """
+ )
+ with self.assertRaisesRegex(ValueError, "^Multiple llvm_pgo_generate"):
+ pgo_tools.installed_llvm_has_pgo_generate_enabled()
+
+ @mock.patch.object(pgo_tools, "run")
+ def test_pgo_generate_ignores_nonexact_use_flags(self, mock_run):
+ mock_run.return_value.stdout = textwrap.dedent(
+ """\
+ [ Legend : U - final flag setting for installation]
+ - - llvm-next_pgo_use : <unknown>
+ - - llvm-tot : <unknown>
+ - + llvm_pgo_generate : <unknown>
+ - - llvm_pgo_generate2 : <unknown>
+ - - 2llvm_pgo_generate : <unknown>
+ + - llvm_pgo_use : <unknown>
+ """
+ )
+ self.assertTrue(pgo_tools.installed_llvm_has_pgo_generate_enabled())
+
+ def test_quickpkg_restoration_works(self):
+ self.assertEqual(
+ pgo_tools.generate_quickpkg_restoration_command(
+ Path("/path/to/sys-devel/llvm-1234-r1.tbz2")
+ ),
+ ["sudo", "emerge", "--usepkgonly", "=sys-devel/llvm-1234-r1"],
+ )
+
+ def test_temporary_file_creation_works(self):
+ with pgo_tools.temporary_file("foo_bar_") as tmp:
+ self.assertTrue(tmp.name.startswith("foo_bar_"), tmp.name)
+ self.assertTrue(tmp.exists())
+ self.assertFalse(tmp.exists())
+
+ def test_temporary_file_deletion_is_fine_if_file_does_not_exist(self):
+ # This test ensures this `with`'s `__exit__` block doesn't `raise`.
+ with pgo_tools.temporary_file("foo_bar_") as tmp:
+ tmp.unlink()
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/pgo_tools/update_llvm_manifest.py b/pgo_tools/update_llvm_manifest.py
new file mode 100755
index 00000000..7fff6f8d
--- /dev/null
+++ b/pgo_tools/update_llvm_manifest.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python3
+# Copyright 2024 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Updates the Manifest file for LLVM.
+
+Often used to pull a new PGO profile in.
+"""
+
+import argparse
+import contextlib
+import logging
+from pathlib import Path
+import re
+import subprocess
+import sys
+from typing import Generator, List
+
+import pgo_tools
+
+
+@contextlib.contextmanager
+def temporarily_add_llvm_next_pgo_to_src_uri(
+ llvm_9999_ebuild: Path,
+) -> Generator[None, None, None]:
+ old_contents = llvm_9999_ebuild.read_text(encoding="utf-8")
+
+ profdata_prefix = "gs://chromeos-localmirror/distfiles/llvm-profdata-"
+ profdata_re = re.compile(
+ # Leave room for a suffix on this, in case we're on the Nth version of
+ # llvm-profdata for some reason.
+ re.escape(profdata_prefix + "${LLVM_HASH}")
+ + r"\S*\.xz\s"
+ )
+ found_urls = list(profdata_re.finditer(old_contents))
+ if len(found_urls) != 1:
+ raise ValueError(
+ f"Want 1 instance of {profdata_re} in {llvm_9999_ebuild}; found "
+ f"{len(found_urls)}"
+ )
+
+ # Insert the new profdata URL right after the old one. The combination of
+ # USE variables gating this file doesn't have to make sense; the URL just
+ # has to be visible to Portage.
+
+ # Note that the regex ended with `\s`, so `.end()` will be after a space.
+ insert_url = profdata_prefix + "${LLVM_NEXT_HASH}.xz "
+ insert_point = found_urls[0].end()
+ new_contents = (
+ old_contents[:insert_point] + insert_url + old_contents[insert_point:]
+ )
+
+ llvm_9999_ebuild.write_text(new_contents, encoding="utf-8")
+ try:
+ yield
+ finally:
+ llvm_9999_ebuild.write_text(old_contents, encoding="utf-8")
+
+
+def update_manifest(llvm_9999_ebuild: Path):
+ subprocess.run(
+ ["ebuild", llvm_9999_ebuild, "manifest"],
+ check=True,
+ stdin=subprocess.DEVNULL,
+ )
+
+
+def main(argv: List[str]) -> None:
+ logging.basicConfig(
+ format=">> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: "
+ "%(message)s",
+ level=logging.INFO,
+ )
+
+ pgo_tools.exit_if_not_in_chroot()
+
+ my_dir = Path(__file__).resolve().parent
+ parser = argparse.ArgumentParser(
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+ parser.add_argument(
+ "--llvm-next",
+ action="store_true",
+ help="Also update for the llvm-next PGO profile.",
+ )
+ parser.add_argument(
+ "--chromiumos-overlay",
+ default=my_dir.parent.parent / "chromiumos-overlay",
+ type=Path,
+ help="The chromiumos-overlay directory to work in. Default %(default)s",
+ )
+ opts = parser.parse_args(argv)
+
+ llvm_9999 = opts.chromiumos_overlay / "sys-devel/llvm/llvm-9999.ebuild"
+ if opts.llvm_next:
+ with temporarily_add_llvm_next_pgo_to_src_uri(llvm_9999):
+ update_manifest(llvm_9999)
+ else:
+ update_manifest(llvm_9999)
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/pgo_tools_rust/pgo_rust.py b/pgo_tools_rust/pgo_rust.py
index fc693169..ecf4f050 100755
--- a/pgo_tools_rust/pgo_rust.py
+++ b/pgo_tools_rust/pgo_rust.py
@@ -303,7 +303,13 @@ def build_rust(
use = (env_use + " " + use).strip()
# -E to preserve environment variables like USE, FEATURES, etc.
run(
- ["sudo", "-E", "emerge", "dev-lang/rust", "dev-lang/rust-host"],
+ [
+ "sudo",
+ "-E",
+ "emerge",
+ "dev-lang/rust-host",
+ "dev-lang/rust",
+ ],
env={"USE": use},
)
@@ -323,6 +329,7 @@ def merge_profdata(llvm_or_frontend, *, source_directory: Path, dest: Path):
dest.parent.mkdir(parents=True, exist_ok=True)
files = list(source_directory.glob("*.profraw"))
+ assert files, f"No profraw files found in {source_directory}"
run([llvm_profdata, "merge", f"--output={dest}"] + files)
diff --git a/run_tests_for.py b/run_tests_for.py
index 46747c43..ef3b669e 100755
--- a/run_tests_for.py
+++ b/run_tests_for.py
@@ -1,6 +1,4 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
-#
# Copyright 2019 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -27,13 +25,13 @@ All tests are run in parallel.
import argparse
import collections
-import signal
import multiprocessing.pool
import os
-import pipes
+import shlex
+import signal
import subprocess
import sys
-from typing import Tuple, Optional
+from typing import Optional, Tuple
TestSpec = collections.namedtuple("TestSpec", ["directory", "command"])
@@ -92,40 +90,42 @@ def _run_test(test_spec: TestSpec, timeout: int) -> Tuple[Optional[int], str]:
# Each subprocess gets its own process group, since many of these tests
# spawn subprocesses for a variety of reasons. If these tests time out, we
# want to be able to clean up all of the children swiftly.
- p = subprocess.Popen(
+ # pylint: disable=subprocess-popen-preexec-fn
+ with subprocess.Popen(
test_spec.command,
cwd=test_spec.directory,
stdin=subprocess.DEVNULL,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
encoding="utf-8",
+ # TODO(b/296616854): This is unsafe, and we should use
+ # process_group=0 when we have upgraded to Python 3.11.
preexec_fn=lambda: os.setpgid(0, 0),
- )
-
- child_pgid = p.pid
- try:
- out, _ = p.communicate(timeout=timeout)
- return p.returncode, out
- except BaseException as e:
- # Try to shut the processes down gracefully.
- os.killpg(child_pgid, signal.SIGINT)
+ ) as p:
+ child_pgid = p.pid
try:
- # 2 seconds is arbitrary, but given that these are unittests,
- # should be plenty of time for them to shut down.
- p.wait(timeout=2)
- except subprocess.TimeoutExpired:
- os.killpg(child_pgid, signal.SIGKILL)
- except:
- os.killpg(child_pgid, signal.SIGKILL)
+ out, _ = p.communicate(timeout=timeout)
+ return p.returncode, out
+ except BaseException as e:
+ # Try to shut the processes down gracefully.
+ os.killpg(child_pgid, signal.SIGINT)
+ try:
+ # 2 seconds is arbitrary, but given that these are unittests,
+ # should be plenty of time for them to shut down.
+ p.wait(timeout=2)
+ except subprocess.TimeoutExpired:
+ os.killpg(child_pgid, signal.SIGKILL)
+ except:
+ os.killpg(child_pgid, signal.SIGKILL)
+ raise
+
+ if isinstance(e, subprocess.TimeoutExpired):
+ # We just killed the entire process group. This should complete
+ # ~immediately. If it doesn't, something is very wrong.
+ out, _ = p.communicate(timeout=5)
+ return (None, out)
raise
- if isinstance(e, subprocess.TimeoutExpired):
- # We just killed the entire process group. This should complete
- # ~immediately. If it doesn't, something is very wrong.
- out, _ = p.communicate(timeout=5)
- return (None, out)
- raise
-
def _python_test_to_spec(test_file):
"""Given a .py file, convert it to a TestSpec."""
@@ -182,9 +182,7 @@ def _run_test_scripts(pool, all_tests, timeout, show_successful_output=False):
if show_successful_output and i:
print("\n")
- pretty_test = " ".join(
- pipes.quote(test_arg) for test_arg in test.command
- )
+ pretty_test = shlex.join(test.command)
pretty_directory = os.path.relpath(test.directory)
if pretty_directory == ".":
test_message = pretty_test
@@ -247,8 +245,8 @@ def _fix_python_path(toolchain_utils):
def _find_forced_subdir_python_tests(test_paths, toolchain_utils):
assert all(os.path.isabs(path) for path in test_paths)
- # Directories under toolchain_utils for which any change will cause all tests
- # in that directory to be rerun. Includes changes in subdirectories.
+ # Directories under toolchain_utils for which any change will cause all
+ # tests in that directory to be rerun. Includes changes in subdirectories.
all_dirs = {
"crosperf",
"cros_utils",
diff --git a/rust-analyzer-chromiumos-wrapper/Cargo.lock b/rust-analyzer-chromiumos-wrapper/Cargo.lock
index aedf8bfc..248b313a 100644
--- a/rust-analyzer-chromiumos-wrapper/Cargo.lock
+++ b/rust-analyzer-chromiumos-wrapper/Cargo.lock
@@ -3,6 +3,15 @@
version = 3
[[package]]
+name = "aho-corasick"
+version = "1.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b2969dcb958b36655471fc61f7e416fa76033bdd4bfed0678d8fee1e2d07a1f0"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
name = "anyhow"
version = "1.0.57"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -21,6 +30,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "112c678d4050afce233f4f2852bb2eb519230b3cf12f33585275537d7e41578d"
[[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
name = "libc"
version = "0.2.126"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -36,6 +51,12 @@ dependencies = [
]
[[package]]
+name = "memchr"
+version = "2.7.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "523dc4f511e55ab87b694dc30d0f820d60906ef06413f93d4d7a1385599cc149"
+
+[[package]]
name = "num_threads"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -45,11 +66,42 @@ dependencies = [
]
[[package]]
+name = "regex"
+version = "1.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
+
+[[package]]
name = "rust-analyzer-chromiumos-wrapper"
version = "0.1.0"
dependencies = [
"anyhow",
+ "lazy_static",
"log",
+ "regex",
"serde_json",
"simplelog",
]
diff --git a/rust-analyzer-chromiumos-wrapper/Cargo.toml b/rust-analyzer-chromiumos-wrapper/Cargo.toml
index 91d0f9a9..a6deac24 100644
--- a/rust-analyzer-chromiumos-wrapper/Cargo.toml
+++ b/rust-analyzer-chromiumos-wrapper/Cargo.toml
@@ -8,7 +8,9 @@ panic = "abort"
[dependencies]
anyhow = "1.0"
+lazy_static = "1.4"
log = { version = "0.4.17" }
+regex = "1.0"
serde_json = "1.0"
simplelog = { version = "0.12.0" }
diff --git a/rust-analyzer-chromiumos-wrapper/README.md b/rust-analyzer-chromiumos-wrapper/README.md
index e834ff34..b9ea20a3 100644
--- a/rust-analyzer-chromiumos-wrapper/README.md
+++ b/rust-analyzer-chromiumos-wrapper/README.md
@@ -19,8 +19,8 @@ to invoke `rust-analyzer` inside the chroot and translate paths. Otherwise, it
will attempt to invoke a `rust-analyzer` outside the chroot and will not
translate paths.
-It supports none of rust-analyzer's command line options, which aren't
-necessary for acting as a LSP server anyway.
+It only supports a limited set of rust-analyzer's command line options, which
+aren't necessary for acting as a LSP server anyway.
## Quickstart
@@ -30,11 +30,20 @@ necessary for acting as a LSP server anyway.
cargo install --path /path-to-a-chromiumos-checkout/src/third_party/toolchain-utils/rust-analyzer-chromiumos-wrapper
```
-Make sure `~/.cargo/bin' is in your PATH, or move/symlink `~/.cargo/bin/rust-analyzer-chromiumos-wrapper` to a location in your PATH.
+Make sure `~/.cargo/bin` is in your PATH, or move/symlink
+`~/.cargo/bin/rust-analyzer-chromiumos-wrapper` to a location in your PATH.
Configure your editor to use the binary `rust-analyzer-chromiumos-wrapper` as
-`rust-analyzer`. In Neovim, if you're using
-[nvim-lspconfig](https://github.com/neovim/nvim-lspconfig), this can be done by
+`rust-analyzer`. This configuration is specific to your editor, but see the
+[Rust analyzer manual] for more about several different editors.
+
+The following sections explain how this can be done for various editors.
+
+[Rust analyzer manual]: https://rust-analyzer.github.io/manual.html
+
+## Neovim
+
+In Neovim, if you're using [nvim-lspconfig], this can be done by
putting the following in your `init.lua`:
```
@@ -43,19 +52,42 @@ require('lspconfig')['rust_analyzer'].setup {
}
```
-This configuration is specific to your editor, but see the
-[Rust analyzer manual](https://rust-analyzer.github.io/manual.html) for
-more about several different editors.
+[nvim-lspconfig]: https://github.com/neovim/nvim-lspconfig
+
+## VSCode
+
+In VSCode the [rust-analyzer extension] handles interaction with the LSP.
+After installation, `rust-analyzer` is configured via `settings.json`. To use
+`rust-analyzer-chromiumos-wrapper` for chromiumos, edit the repositories
+`.vscode/settings.json` file. It should be present in any chromiumos checkout
+that you edited with VSCode.
-Once the above general configuration is set up, you'll need to install
-`rust-analyzer` inside each chroot where you want to edit code:
+Then add the following line:
```
-sudo emerge rust-analyzer
+"rust-analyzer.server.path": "/usr/local/google/home/bkersting/.cargo/bin/rust-analyzer-chromiumos-wrapper"
```
+Due to having all chromiumos crates distributed in the workspace (and no global
+`Cargo.toml` defining the workspace), the crates you would like edit with
+rust-analyzer need to be declared in the `rust-analyzer.linkedProjects`
+setting. If you e.g. want to work on libchromeos-rs, put the following lines
+into `settings.json`:
+```
+"rust-analyzer.linkedProjects": [
+ "/path-to-chromiumos/src/platform2/libchromeos-rs/Cargo.toml",
+]
+```
+
+[rust-analyzer extension]: https://marketplace.visualstudio.com/items?itemName=rust-lang.rust-analyzer
+
## Misc
+Inside chroot we already have a rust-analyzer installation that is installed
+with the rust toolchain.
+
A wrapper isn't necessary for clangd, because clangd supports the option
`--path-mappings` to translate paths. In principle a similar option could be
added to `rust-analyzer`, obviating the need for this wrapper. See this
-[issue on github](https://github.com/rust-lang/rust-analyzer/issues/12485).
+[issue on github].
+
+[issue on github]: https://github.com/rust-lang/rust-analyzer/issues/12485
diff --git a/rust-analyzer-chromiumos-wrapper/src/main.rs b/rust-analyzer-chromiumos-wrapper/src/main.rs
index f59af454..43ca5a3d 100644
--- a/rust-analyzer-chromiumos-wrapper/src/main.rs
+++ b/rust-analyzer-chromiumos-wrapper/src/main.rs
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+use std::collections::HashMap;
use std::env;
use std::fs::File;
use std::io::{self, BufRead, BufReader, BufWriter, Write};
@@ -12,13 +13,17 @@ use std::str::from_utf8;
use std::thread;
use anyhow::{anyhow, bail, Context, Result};
-
+use lazy_static::lazy_static;
use log::trace;
+use regex::Regex;
+
use simplelog::{Config, LevelFilter, WriteLogger};
use serde_json::{from_slice, to_writer, Value};
+const CHROOT_SERVER_PATH: &str = "/usr/sbin/rust-analyzer";
+
fn main() -> Result<()> {
let args = env::args().skip(1);
@@ -28,7 +33,7 @@ fn main() -> Result<()> {
None => {
// It doesn't appear that we're in a chroot. Run the
// regular rust-analyzer.
- return Err(process::Command::new("rust-analyzer").args(args).exec())?;
+ bail!(process::Command::new("rust-analyzer").args(args).exec());
}
};
@@ -39,21 +44,23 @@ fn main() -> Result<()> {
// * We don't support the arguments, so we bail.
// * We still need to do our path translation in the LSP protocol.
fn run(args: &[String]) -> Result<()> {
- return Err(process::Command::new("cros_sdk")
+ bail!(process::Command::new("cros_sdk")
.args(["--", "rust-analyzer"])
.args(args)
- .exec())?;
+ .exec());
}
- if args.iter().any(|x| match x.as_str() {
- "--version" | "--help" | "-h" | "--print-config-schema" => true,
- _ => false,
+ if args.iter().any(|x| {
+ matches!(
+ x.as_str(),
+ "--version" | "--help" | "-h" | "--print-config-schema"
+ )
}) {
// With any of these options rust-analyzer will just print something and exit.
return run(&args);
}
- if !args[0].starts_with("-") {
+ if !args[0].starts_with('-') {
// It's a subcommand, and seemingly none of these need the path translation
// rust-analyzer-chromiumos-wrapper provides.
return run(&args);
@@ -68,26 +75,46 @@ fn main() -> Result<()> {
init_log()?;
+ // Get the rust sysroot, this is needed to translate filepaths to sysroot
+ // related files, e.g. crate sources.
+ let outside_rust_sysroot = {
+ let output = process::Command::new("rustc")
+ .arg("--print")
+ .arg("sysroot")
+ .output()?;
+ if !output.status.success() {
+ bail!("Unable to find rustc installation outside of sysroot");
+ }
+ std::str::from_utf8(&output.stdout)?.to_owned()
+ };
+ let outside_rust_sysroot = outside_rust_sysroot.trim();
+
+ // The /home path inside the chroot is visible outside through "<chromiumos-root>/out/home".
+ let outside_home: &'static str =
+ Box::leak(format!("{}/out/home", chromiumos_root.display()).into_boxed_str());
+
let outside_prefix: &'static str = {
- let path = chromiumos_root
+ let mut path = chromiumos_root
.to_str()
- .ok_or_else(|| anyhow!("Path is not valid UTF-8"))?;
+ .ok_or_else(|| anyhow!("Path is not valid UTF-8"))?
+ .to_owned();
- let mut tmp = format!("file://{}", path);
- if Some(&b'/') != tmp.as_bytes().last() {
- tmp.push('/');
+ if Some(&b'/') == path.as_bytes().last() {
+ let _ = path.pop();
}
// No need to ever free this memory, so let's get a static reference.
- Box::leak(tmp.into_boxed_str())
+ Box::leak(path.into_boxed_str())
};
trace!("Found chromiumos root {}", outside_prefix);
- let inside_prefix: &'static str = "file:///mnt/host/source/";
+ let outside_sysroot_prefix: &'static str =
+ Box::leak(format!("{outside_rust_sysroot}/lib/rustlib").into_boxed_str());
+ let inside_prefix: &'static str = "/mnt/host/source";
let cmd = "cros_sdk";
- let all_args = ["--", "rust-analyzer"]
+ let all_args = ["--", CHROOT_SERVER_PATH]
.into_iter()
.chain(args.iter().map(|x| x.as_str()));
let mut child = KillOnDrop(run_command(cmd, all_args)?);
@@ -95,22 +122,28 @@ fn main() -> Result<()> {
let mut child_stdin = BufWriter::new(child.0.stdin.take().unwrap());
let mut child_stdout = BufReader::new(child.0.stdout.take().unwrap());
+ let replacement_map = {
+ let mut m = HashMap::new();
+ m.insert(outside_prefix, inside_prefix);
+ m.insert(outside_sysroot_prefix, "/usr/lib/rustlib");
+ m.insert(outside_home, "/home");
+ m
+ };
+
let join_handle = {
+ let rm = replacement_map.clone();
thread::spawn(move || {
let mut stdin = io::stdin().lock();
- stream_with_replacement(&mut stdin, &mut child_stdin, outside_prefix, inside_prefix)
+ stream_with_replacement(&mut stdin, &mut child_stdin, &rm)
.context("Streaming from stdin into rust-analyzer")
})
};
+ // For the mapping between inside to outside, we just reverse the map.
+ let replacement_map_rev = replacement_map.iter().map(|(k, v)| (*v, *k)).collect();
let mut stdout = BufWriter::new(io::stdout().lock());
- stream_with_replacement(
- &mut child_stdout,
- &mut stdout,
- inside_prefix,
- outside_prefix,
- )
- .context("Streaming from rust-analyzer into stdout")?;
+ stream_with_replacement(&mut child_stdout, &mut stdout, &replacement_map_rev)
+ .context("Streaming from rust-analyzer into stdout")?;
join_handle.join().unwrap()?;
@@ -174,21 +207,37 @@ fn read_header<R: BufRead>(r: &mut R, header: &mut Header) -> Result<()> {
}
}
-/// Extend `dest` with `contents`, replacing any occurrence of `pattern` in a json string in
-/// `contents` with `replacement`.
-fn replace(contents: &[u8], pattern: &str, replacement: &str, dest: &mut Vec<u8>) -> Result<()> {
- fn map_value(val: Value, pattern: &str, replacement: &str) -> Value {
+/// Extend `dest` with `contents`, replacing any occurrence of patterns in a json string in
+/// `contents` with a replacement.
+fn replace(
+ contents: &[u8],
+ replacement_map: &HashMap<&str, &str>,
+ dest: &mut Vec<u8>,
+) -> Result<()> {
+ fn map_value(val: Value, replacement_map: &HashMap<&str, &str>) -> Value {
match val {
Value::String(s) =>
// `s.replace` is very likely doing more work than necessary. Probably we only need
// to look for the pattern at the beginning of the string.
{
- Value::String(s.replace(pattern, replacement))
+ lazy_static! {
+ static ref SERVER_PATH_REGEX: Regex =
+ Regex::new(r".*/rust-analyzer-chromiumos-wrapper$").unwrap();
+ }
+ // Always replace the server path everywhere.
+ let mut s = SERVER_PATH_REGEX
+ .replace_all(&s, CHROOT_SERVER_PATH)
+ .to_string();
+ // Then replace all mappings we get.
+ for (pattern, replacement) in replacement_map {
+ s = s.replace(pattern, replacement);
+ }
+ Value::String(s.to_string())
}
Value::Array(mut v) => {
for val_ref in v.iter_mut() {
let value = std::mem::replace(val_ref, Value::Null);
- *val_ref = map_value(value, pattern, replacement);
+ *val_ref = map_value(value, replacement_map);
}
Value::Array(v)
}
@@ -196,7 +245,7 @@ fn replace(contents: &[u8], pattern: &str, replacement: &str, dest: &mut Vec<u8>
// Surely keys can't be paths.
for val_ref in map.values_mut() {
let value = std::mem::replace(val_ref, Value::Null);
- *val_ref = map_value(value, pattern, replacement);
+ *val_ref = map_value(value, replacement_map);
}
Value::Object(map)
}
@@ -211,26 +260,25 @@ fn replace(contents: &[u8], pattern: &str, replacement: &str, dest: &mut Vec<u8>
),
Ok(s) => format!("JSON parsing content of length {}:\n{}", contents.len(), s),
})?;
- let mapped_val = map_value(init_val, pattern, replacement);
+ let mapped_val = map_value(init_val, replacement_map);
to_writer(dest, &mapped_val)?;
Ok(())
}
-/// Read LSP messages from `r`, replacing each occurrence of `pattern` in a json string in the
-/// payload with `replacement`, adjusting the `Content-Length` in the header to match, and writing
+/// Read LSP messages from `r`, replacing each occurrence of patterns in a json string in the
+/// payload with replacements, adjusting the `Content-Length` in the header to match, and writing
/// the result to `w`.
fn stream_with_replacement<R: BufRead, W: Write>(
r: &mut R,
w: &mut W,
- pattern: &str,
- replacement: &str,
+ replacement_map: &HashMap<&str, &str>,
) -> Result<()> {
let mut head = Header::default();
let mut buf = Vec::with_capacity(1024);
let mut buf2 = Vec::with_capacity(1024);
loop {
read_header(r, &mut head)?;
- if head.length.is_none() && head.other_fields.len() == 0 {
+ if head.length.is_none() && head.other_fields.is_empty() {
// No content in the header means we're apparently done.
return Ok(());
}
@@ -251,7 +299,7 @@ fn stream_with_replacement<R: BufRead, W: Write>(
trace!("Received payload\n{}", from_utf8(&buf)?);
buf2.clear();
- replace(&buf, pattern, replacement, &mut buf2)?;
+ replace(&buf, replacement_map, &mut buf2)?;
trace!("After replacements payload\n{}", from_utf8(&buf2)?);
@@ -307,7 +355,12 @@ mod test {
json_expected: &str,
) -> Result<()> {
let mut w = Vec::<u8>::with_capacity(read.len());
- stream_with_replacement(&mut read.as_bytes(), &mut w, pattern, replacement)?;
+ let replacement_map = {
+ let mut m = HashMap::new();
+ m.insert(pattern, replacement);
+ m
+ };
+ stream_with_replacement(&mut read.as_bytes(), &mut w, &replacement_map)?;
// serde_json may not format the json output the same as we do, so we can't just compare
// as strings or slices.
@@ -361,4 +414,18 @@ mod test {
\"key3\": \"morereplacementtext\"}, \"key4\": 1}",
)
}
+
+ #[test]
+ fn test_stream_with_replacement_3() -> Result<()> {
+ test_stream_with_replacement(
+ // read
+ "Content-Length: 55\r\n\r\n{\"path\": \"/my_folder/rust-analyzer-chromiumos-wrapper\"}",
+ // pattern
+ "",
+ // replacement
+ "",
+ // json_expected
+ "{\"path\": \"/usr/sbin/rust-analyzer\"}",
+ )
+ }
}
diff --git a/rust_tools/auto_update_rust_bootstrap.py b/rust_tools/auto_update_rust_bootstrap.py
new file mode 100755
index 00000000..09df9bdd
--- /dev/null
+++ b/rust_tools/auto_update_rust_bootstrap.py
@@ -0,0 +1,854 @@
+#!/usr/bin/env python3
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Automatically maintains the rust-bootstrap package.
+
+This script is responsible for:
+ - uploading new rust-bootstrap prebuilts
+ - adding new versions of rust-bootstrap to keep up with dev-lang/rust
+ - removing versions of rust-bootstrap that are no longer depended on by
+ dev-lang/rust
+
+It's capable of (and intended to primarily be used for) uploading CLs to do
+these things on its own, so it can easily be regularly run by Chrotomation.
+"""
+
+import argparse
+import collections
+import dataclasses
+import functools
+import glob
+import logging
+import os
+from pathlib import Path
+import re
+import subprocess
+import sys
+import textwrap
+from typing import Dict, Iterable, List, Optional, Tuple, Union
+
+import copy_rust_bootstrap
+
+
+# The bug to tag in all commit messages.
+TRACKING_BUG = "b:315473495"
+
+# Reviewers for all CLs uploaded.
+DEFAULT_CL_REVIEWERS = (
+ "gbiv@chromium.org",
+ "inglorion@chromium.org",
+)
+
+
+@dataclasses.dataclass(frozen=True, eq=True, order=True)
+class EbuildVersion:
+ """Represents an ebuild version, simplified for rust-bootstrap versions.
+
+ "Simplified," means that no `_pre`/etc suffixes have to be accounted for.
+ """
+
+ major: int
+ minor: int
+ patch: int
+ rev: int
+
+ def prior_minor_version(self) -> "EbuildVersion":
+ """Returns an EbuildVersion with just the major/minor from this one."""
+ return dataclasses.replace(self, minor=self.minor - 1)
+
+ def major_minor_only(self) -> "EbuildVersion":
+ """Returns an EbuildVersion with just the major/minor from this one."""
+ if not self.rev and not self.patch:
+ return self
+ return EbuildVersion(
+ major=self.major,
+ minor=self.minor,
+ patch=0,
+ rev=0,
+ )
+
+ def without_rev(self) -> "EbuildVersion":
+ if not self.rev:
+ return self
+ return dataclasses.replace(self, rev=0)
+
+ def __str__(self):
+ result = f"{self.major}.{self.minor}.{self.patch}"
+ if self.rev:
+ result += f"-r{self.rev}"
+ return result
+
+
+def find_raw_bootstrap_sequence_lines(
+ ebuild_lines: List[str],
+) -> Tuple[int, int]:
+ """Returns the start/end lines of RUSTC_RAW_FULL_BOOTSTRAP_SEQUENCE."""
+ for i, line in enumerate(ebuild_lines):
+ if line.startswith("RUSTC_RAW_FULL_BOOTSTRAP_SEQUENCE=("):
+ start = i
+ break
+ else:
+ raise ValueError("No bootstrap sequence start found in text")
+
+ for i, line in enumerate(ebuild_lines[i + 1 :], i + 1):
+ if line.rstrip() == ")":
+ return start, i
+ raise ValueError("No bootstrap sequence end found in text")
+
+
+def read_bootstrap_sequence_from_ebuild(
+ rust_bootstrap_ebuild: Path,
+) -> List[EbuildVersion]:
+ """Returns a list of EbuildVersions from the given ebuild."""
+ ebuild_lines = rust_bootstrap_ebuild.read_text(
+ encoding="utf-8"
+ ).splitlines()
+ start, end = find_raw_bootstrap_sequence_lines(ebuild_lines)
+ results = []
+ for line in ebuild_lines[start + 1 : end]:
+ # Ignore comments.
+ line = line.split("#", 1)[0].strip()
+ if not line:
+ continue
+ assert len(line.split()) == 1, f"Unexpected line: {line!r}"
+ results.append(parse_raw_ebuild_version(line.strip()))
+ return results
+
+
+def version_listed_in_bootstrap_sequence(
+ ebuild: Path, rust_bootstrap_version: EbuildVersion
+) -> bool:
+ ebuild_lines = ebuild.read_text(encoding="utf-8").splitlines()
+ start, end = find_raw_bootstrap_sequence_lines(ebuild_lines)
+ str_version = str(rust_bootstrap_version.without_rev())
+ return any(
+ line.strip() == str_version for line in ebuild_lines[start + 1 : end]
+ )
+
+
+@functools.lru_cache(1)
+def fetch_most_recent_sdk_version() -> str:
+ """Fetches the most recent official SDK version from gs://."""
+ latest_file_loc = "gs://chromiumos-sdk/cros-sdk-latest.conf"
+ sdk_latest_file = subprocess.run(
+ ["gsutil", "cat", latest_file_loc],
+ check=True,
+ encoding="utf-8",
+ stdin=subprocess.DEVNULL,
+ stdout=subprocess.PIPE,
+ ).stdout.strip()
+
+ latest_sdk_re = re.compile(r'^LATEST_SDK="([0-9\.]+)"$')
+ for line in sdk_latest_file.splitlines():
+ m = latest_sdk_re.match(line)
+ if m:
+ latest_version = m.group(1)
+ logging.info("Detected latest SDK version: %r", latest_version)
+ return latest_version
+ raise ValueError(f"Could not find LATEST_SDK in {latest_file_loc}")
+
+
+def find_rust_bootstrap_prebuilt(version: EbuildVersion) -> Optional[str]:
+ """Returns a URL to a prebuilt for `version` of rust-bootstrap."""
+ # Searching chroot-* is generally unsafe, because some uploads might
+ # include SDK artifacts built by CQ+1 runs, so just use the most recent
+ # verified SDK version.
+ sdk_version = fetch_most_recent_sdk_version()
+
+ # Search for all rust-bootstrap versions rather than specifically
+ # `version`, since gsutil will exit(1) if no matches are found. exit(1) is
+ # desirable if _no rust boostrap artifacts at all exist_, but substantially
+ # less so if this function seeks to just `return False`.
+ gs_glob = (
+ f"gs://chromeos-prebuilt/board/amd64-host/chroot-{sdk_version}"
+ "/packages/dev-lang/rust-bootstrap-*tbz2"
+ )
+
+ logging.info("Searching %s for rust-bootstrap version %s", gs_glob, version)
+ results = subprocess.run(
+ ["gsutil", "ls", gs_glob],
+ check=True,
+ encoding="utf-8",
+ stdin=subprocess.DEVNULL,
+ stdout=subprocess.PIPE,
+ ).stdout.strip()
+
+ binpkg_name_re = re.compile(
+ r"rust-bootstrap-" + re.escape(str(version)) + r"\.tbz2$"
+ )
+ result_lines = results.splitlines()
+ for line in result_lines:
+ result = line.strip()
+ if binpkg_name_re.search(result):
+ logging.info("Found rust-bootstrap prebuilt: %s", result)
+ return result
+ logging.info("Skipped rust-bootstrap prebuilt: %s", result)
+
+ logging.info(
+ "No rust-bootstrap for %s found (regex: %s); options: %s",
+ version,
+ binpkg_name_re,
+ result_lines,
+ )
+ return None
+
+
+def parse_raw_ebuild_version(raw_ebuild_version: str) -> EbuildVersion:
+ """Parses an ebuild version without the ${PN} prefix or .ebuild suffix.
+
+ >>> parse_raw_ebuild_version("1.70.0-r2")
+ EbuildVersion(major=1, minor=70, patch=0, rev=2)
+ """
+ version_re = re.compile(r"(\d+)\.(\d+)\.(\d+)(?:-r(\d+))?")
+ m = version_re.match(raw_ebuild_version)
+ if not m:
+ raise ValueError(f"Version {raw_ebuild_version} can't be recognized.")
+
+ major, minor, patch, rev_str = m.groups()
+ rev = 0 if not rev_str else int(rev_str)
+ return EbuildVersion(
+ major=int(major), minor=int(minor), patch=int(patch), rev=rev
+ )
+
+
+def parse_ebuild_version(ebuild_name: str) -> EbuildVersion:
+ """Parses the version from an ebuild.
+
+ Raises:
+ ValueError if the `ebuild_name` doesn't contain a parseable version.
+ Notably, version suffixes like `_pre`, `_beta`, etc are unexpected in
+ Rust-y ebuilds, so they're not handled here.
+
+ >>> parse_ebuild_version("rust-bootstrap-1.70.0-r2.ebuild")
+ EbuildVersion(major=1, minor=70, patch=0, rev=2)
+ """
+ version_re = re.compile(r"(\d+)\.(\d+)\.(\d+)(?:-r(\d+))?\.ebuild$")
+ m = version_re.search(ebuild_name)
+ if not m:
+ raise ValueError(f"Ebuild {ebuild_name} has no obvious version")
+
+ major, minor, patch, rev_str = m.groups()
+ rev = 0 if not rev_str else int(rev_str)
+ return EbuildVersion(
+ major=int(major), minor=int(minor), patch=int(patch), rev=rev
+ )
+
+
+def collect_ebuilds_by_version(
+ ebuild_dir: Path,
+) -> List[Tuple[EbuildVersion, Path]]:
+ """Returns the latest ebuilds grouped by version.without_rev.
+
+ Result is always sorted by version, latest versions are last.
+ """
+ ebuilds = ebuild_dir.glob("*.ebuild")
+ versioned_ebuilds: Dict[EbuildVersion, Tuple[EbuildVersion, Path]] = {}
+ for ebuild in ebuilds:
+ version = parse_ebuild_version(ebuild.name)
+ version_no_rev = version.without_rev()
+ other = versioned_ebuilds.get(version_no_rev)
+ this_is_newer = other is None or other[0] < version
+ if this_is_newer:
+ versioned_ebuilds[version_no_rev] = (version, ebuild)
+
+ return sorted(versioned_ebuilds.values())
+
+
+def maybe_copy_prebuilt_to_localmirror(
+ copy_rust_bootstrap_script: Path, prebuilt_gs_path: str, dry_run: bool
+) -> bool:
+ upload_to = copy_rust_bootstrap.determine_target_path(prebuilt_gs_path)
+ result = subprocess.run(
+ ["gsutil", "ls", upload_to],
+ check=False,
+ encoding="utf-8",
+ stdin=subprocess.DEVNULL,
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL,
+ )
+
+ if not result.returncode:
+ logging.info("Artifact at %s already exists", upload_to)
+ return False
+
+ cmd: List[Union[Path, str]] = [
+ copy_rust_bootstrap_script,
+ prebuilt_gs_path,
+ ]
+
+ if dry_run:
+ cmd.append("--dry-run")
+
+ subprocess.run(
+ cmd,
+ check=True,
+ stdin=subprocess.DEVNULL,
+ )
+ return True
+
+
+def add_version_to_bootstrap_sequence(
+ ebuild: Path, version: EbuildVersion, dry_run: bool
+):
+ ebuild_lines = ebuild.read_text(encoding="utf-8").splitlines(keepends=True)
+ _, end = find_raw_bootstrap_sequence_lines(ebuild_lines)
+ # `end` is the final paren. Since we _need_ prebuilts for all preceding
+ # versions, always put this a line before the end.
+ ebuild_lines.insert(end, f"\t{version}\n")
+ if not dry_run:
+ ebuild.write_text("".join(ebuild_lines), encoding="utf-8")
+
+
+def is_ebuild_linked_to_in_dir(root_ebuild_path: Path) -> bool:
+ """Returns whether symlinks point to `root_ebuild_path`.
+
+ The only directory checked is the directory that contains
+ `root_ebuild_path`.
+ """
+ assert (
+ root_ebuild_path.is_absolute()
+ ), f"{root_ebuild_path} should be an absolute path."
+ in_dir = root_ebuild_path.parent
+ for ebuild in in_dir.glob("*.ebuild"):
+ if ebuild == root_ebuild_path or not ebuild.is_symlink():
+ continue
+
+ points_to = Path(os.path.normpath(in_dir / os.readlink(ebuild)))
+ if points_to == root_ebuild_path:
+ return True
+ return False
+
+
+def uprev_ebuild(ebuild: Path, version: EbuildVersion, dry_run: bool) -> Path:
+ assert ebuild.is_absolute(), f"{ebuild} should be an absolute path."
+
+ new_version = dataclasses.replace(version, rev=version.rev + 1)
+ new_ebuild = ebuild.parent / f"rust-bootstrap-{new_version}.ebuild"
+ if dry_run:
+ logging.info(
+ "Skipping rename of %s -> %s; dry-run specified", ebuild, new_ebuild
+ )
+ return new_ebuild
+
+ # This condition tries to follow CrOS best practices. Namely:
+ # - If the ebuild is a symlink, move it.
+ # - Otherwise, if the ebuild is a normal file, symlink to it as long as
+ # it has no revision.
+ #
+ # Since rust-bootstrap's functionality relies heavily on `${PV}`, it's
+ # completely expected for cross-${PV} symlinks to exist.
+ uprev_via_rename = (
+ version.rev != 0 or ebuild.is_symlink()
+ ) and not is_ebuild_linked_to_in_dir(ebuild)
+
+ if uprev_via_rename:
+ logging.info("Moving %s -> %s", ebuild, new_ebuild)
+ ebuild.rename(new_ebuild)
+ else:
+ logging.info("Symlinking %s to %s", new_ebuild, ebuild)
+ new_ebuild.symlink_to(ebuild.relative_to(ebuild.parent))
+ return new_ebuild
+
+
+def update_ebuild_manifest(rust_bootstrap_ebuild: Path):
+ subprocess.run(
+ ["ebuild", rust_bootstrap_ebuild, "manifest"],
+ check=True,
+ stdin=subprocess.DEVNULL,
+ )
+
+
+def commit_all_changes(
+ git_dir: Path, rust_bootstrap_dir: Path, commit_message: str
+):
+ subprocess.run(
+ ["git", "add", rust_bootstrap_dir.relative_to(git_dir)],
+ cwd=git_dir,
+ check=True,
+ stdin=subprocess.DEVNULL,
+ )
+ subprocess.run(
+ ["git", "commit", "-m", commit_message],
+ cwd=git_dir,
+ check=True,
+ stdin=subprocess.DEVNULL,
+ )
+
+
+def scrape_git_push_cl_id(git_push_output: str) -> int:
+ id_regex = re.compile(
+ r"^remote:\s+https://chromium-review\S+/\+/(\d+)\s", re.MULTILINE
+ )
+ results = id_regex.findall(git_push_output)
+ if len(results) != 1:
+ raise ValueError(
+ f"Found {len(results)} matches of {id_regex} in"
+ f"{git_push_output!r}; expected 1"
+ )
+ return int(results[0])
+
+
+def upload_changes(git_dir: Path):
+ logging.info("Uploading changes")
+ result = subprocess.run(
+ ["git", "push", "cros", "HEAD:refs/for/main"],
+ check=True,
+ cwd=git_dir,
+ encoding="utf-8",
+ stdin=subprocess.DEVNULL,
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT,
+ )
+ # Print this in case anyone's looking at the output.
+ print(result.stdout, end=None)
+ result.check_returncode()
+
+ cl_id = str(scrape_git_push_cl_id(result.stdout))
+ logging.info("Uploaded crrev.com/c/%s successfully!", cl_id)
+ gerrit_commands = (
+ ["gerrit", "label-v", cl_id, "1"],
+ ["gerrit", "label-cq", cl_id, "1"],
+ ["gerrit", "label-as", cl_id, "1"],
+ ["gerrit", "reviewers", cl_id] + list(DEFAULT_CL_REVIEWERS),
+ ["gerrit", "ready", cl_id],
+ )
+ for command in gerrit_commands:
+ logging.info("Running gerrit command: %s", command)
+ subprocess.run(
+ command,
+ check=True,
+ stdin=subprocess.DEVNULL,
+ )
+
+
+def maybe_add_newest_prebuilts(
+ copy_rust_bootstrap_script: Path,
+ chromiumos_overlay: Path,
+ rust_bootstrap_dir: Path,
+ dry_run: bool,
+) -> bool:
+ """Ensures that prebuilts in rust-bootstrap ebuilds are up-to-date.
+
+ If dry_run is True, no changes will be made on disk. Otherwise, changes
+ will be committed to git locally.
+
+ Returns:
+ True if changes were made (or would've been made, in the case of
+ dry_run being True). False otherwise.
+ """
+ # A list of (version, maybe_prebuilt_location).
+ versions_updated: List[Tuple[EbuildVersion, Optional[str]]] = []
+ for version, ebuild in collect_ebuilds_by_version(rust_bootstrap_dir):
+ logging.info("Inspecting %s...", ebuild)
+ if version.without_rev() in read_bootstrap_sequence_from_ebuild(ebuild):
+ logging.info("Prebuilt already exists for %s.", ebuild)
+ continue
+
+ logging.info("Prebuilt isn't in ebuild; checking remotely.")
+ prebuilt = find_rust_bootstrap_prebuilt(version)
+ if not prebuilt:
+ # `find_rust_bootstrap_prebuilt` handles logging in this case.
+ continue
+
+ # Houston, we have prebuilt.
+ uploaded = maybe_copy_prebuilt_to_localmirror(
+ copy_rust_bootstrap_script, prebuilt, dry_run
+ )
+ add_version_to_bootstrap_sequence(ebuild, version, dry_run)
+ uprevved_ebuild = uprev_ebuild(ebuild, version, dry_run)
+ versions_updated.append((version, prebuilt if uploaded else None))
+
+ if not versions_updated:
+ logging.info("No updates made; exiting cleanly.")
+ return False
+
+ if dry_run:
+ logging.info("Dry-run specified; quit.")
+ return True
+
+ # Just pick an arbitrary ebuild to run `ebuild ... manifest` on; it always
+ # updates for all ebuilds in the same package.
+ update_ebuild_manifest(uprevved_ebuild)
+
+ pretty_artifact_lines = []
+ for version, maybe_gs_path in versions_updated:
+ if maybe_gs_path:
+ pretty_artifact_lines.append(
+ f"- rust-bootstrap-{version.without_rev()} => {maybe_gs_path}"
+ )
+ else:
+ pretty_artifact_lines.append(
+ f"- rust-bootstrap-{version.without_rev()} was already on "
+ "localmirror"
+ )
+
+ pretty_artifacts = "\n".join(pretty_artifact_lines)
+
+ logging.info("Committing changes.")
+ commit_all_changes(
+ chromiumos_overlay,
+ rust_bootstrap_dir,
+ commit_message=textwrap.dedent(
+ f"""\
+ rust-bootstrap: use prebuilts
+
+ This CL used the following rust-bootstrap artifacts:
+ {pretty_artifacts}
+
+ BUG={TRACKING_BUG}
+ TEST=CQ
+ """
+ ),
+ )
+ return True
+
+
+def rust_dir_from_rust_bootstrap(rust_bootstrap_dir: Path) -> Path:
+ """Derives dev-lang/rust's dir from dev-lang/rust-bootstrap's dir."""
+ return rust_bootstrap_dir.parent / "rust"
+
+
+class MissingRustBootstrapPrebuiltError(Exception):
+ """Raised when rust-bootstrap can't be landed due to a missing prebuilt."""
+
+
+def maybe_add_new_rust_bootstrap_version(
+ chromiumos_overlay: Path,
+ rust_bootstrap_dir: Path,
+ dry_run: bool,
+ commit: bool = True,
+) -> bool:
+ """Ensures that there's a rust-bootstrap-${N} ebuild matching rust-${N}.
+
+ Args:
+ chromiumos_overlay: Path to chromiumos-overlay.
+ rust_bootstrap_dir: Path to rust-bootstrap's directory.
+ dry_run: if True, don't commit to git or write changes to disk.
+ Otherwise, write changes to disk.
+ commit: if True, commit changes to git. This value is meaningless if
+ `dry_run` is True.
+
+ Returns:
+ True if changes were made (or would've been made, in the case of
+ dry_run being True). False otherwise.
+
+ Raises:
+ MissingRustBootstrapPrebuiltError if the creation of a new
+ rust-bootstrap ebuild wouldn't be buildable, since there's no
+ rust-bootstrap prebuilt of the prior version for it to sync.
+ """
+ # These are always returned in sorted error, so taking the last is the same
+ # as `max()`.
+ (
+ newest_bootstrap_version,
+ newest_bootstrap_ebuild,
+ ) = collect_ebuilds_by_version(rust_bootstrap_dir)[-1]
+
+ logging.info(
+ "Detected newest rust-bootstrap version: %s", newest_bootstrap_version
+ )
+
+ rust_dir = rust_dir_from_rust_bootstrap(rust_bootstrap_dir)
+ newest_rust_version, _ = collect_ebuilds_by_version(rust_dir)[-1]
+ logging.info("Detected newest rust version: %s", newest_rust_version)
+
+ # Generally speaking, we don't care about keeping up with new patch
+ # releases for rust-bootstrap. It's OK to _initially land_ e.g.,
+ # rust-bootstrap-1.73.1, but upgrades from rust-bootstrap-1.73.0 to
+ # rust-bootstrap-1.73.1 are rare, and have added complexity, so should be
+ # done manually. Hence, only check for major/minor version inequality.
+ if (
+ newest_rust_version.major_minor_only()
+ <= newest_bootstrap_version.major_minor_only()
+ ):
+ logging.info("No missing rust-bootstrap versions detected.")
+ return False
+
+ available_prebuilts = read_bootstrap_sequence_from_ebuild(
+ newest_bootstrap_ebuild
+ )
+ need_prebuilt = newest_rust_version.major_minor_only().prior_minor_version()
+
+ if all(x.major_minor_only() != need_prebuilt for x in available_prebuilts):
+ raise MissingRustBootstrapPrebuiltError(
+ f"want version {need_prebuilt}; "
+ f"available versions: {available_prebuilts}"
+ )
+
+ # Ensure the rust-bootstrap ebuild we're landing is a regular file. This
+ # makes cleanup of the old files trivial, since they're dead symlinks.
+ prior_ebuild_resolved = newest_bootstrap_ebuild.resolve()
+ new_ebuild = (
+ rust_bootstrap_dir
+ / f"rust-bootstrap-{newest_rust_version.without_rev()}.ebuild"
+ )
+ if dry_run:
+ logging.info("Would move %s to %s.", prior_ebuild_resolved, new_ebuild)
+ return True
+
+ logging.info(
+ "Moving %s to %s, and creating symlink at the old location",
+ prior_ebuild_resolved,
+ new_ebuild,
+ )
+ prior_ebuild_resolved.rename(new_ebuild)
+ prior_ebuild_resolved.symlink_to(new_ebuild.relative_to(rust_bootstrap_dir))
+
+ update_ebuild_manifest(new_ebuild)
+ if commit:
+ newest_no_rev = newest_rust_version.without_rev()
+ commit_all_changes(
+ chromiumos_overlay,
+ rust_bootstrap_dir,
+ commit_message=textwrap.dedent(
+ f"""\
+ rust-bootstrap: add version {newest_no_rev}
+
+ Rust is now at {newest_no_rev}; add a rust-bootstrap version so
+ prebuilts can be generated early.
+
+ BUG={TRACKING_BUG}
+ TEST=CQ
+ """
+ ),
+ )
+ return True
+
+
+class OldEbuildIsLinkedToError(Exception):
+ """Raised when a would-be-removed ebuild has symlinks to it."""
+
+
+def find_external_links_to_files_in_dir(
+ in_dir: Path, files: Iterable[Path]
+) -> Dict[Path, List[Path]]:
+ """Returns all symlinks to `files` in `in_dir`, excluding from `files`.
+
+ Essentially, if this returns an empty dict, nothing in `in_dir` symlinks to
+ any of `files`, _except potentially_ things in `files`.
+ """
+ files_set = {x.absolute() for x in files}
+ linked_to = collections.defaultdict(list)
+ for f in in_dir.iterdir():
+ if f not in files_set and f.is_symlink():
+ target = f.parent / os.readlink(f)
+ if target in files_set:
+ linked_to[target].append(f)
+ return linked_to
+
+
+def maybe_delete_old_rust_bootstrap_ebuilds(
+ chromiumos_overlay: Path,
+ rust_bootstrap_dir: Path,
+ dry_run: bool,
+ commit: bool = True,
+) -> bool:
+ """Deletes versions of rust-bootstrap ebuilds that seem unneeded.
+
+ "Unneeded", in this case, is specifically only referencing whether
+ dev-lang/rust (or similar) obviously relies on the ebuild, or whether it's
+ likely that a future version of dev-lang/rust will rely on it.
+
+ Args:
+ chromiumos_overlay: Path to chromiumos-overlay.
+ rust_bootstrap_dir: Path to rust-bootstrap's directory.
+ dry_run: if True, don't commit to git or write changes to disk.
+ Otherwise, write changes to disk.
+ commit: if True, commit changes to git. This value is meaningless if
+ `dry_run` is True.
+
+ Returns:
+ True if changes were made (or would've been made, in the case of
+ dry_run being True). False otherwise.
+
+ Raises:
+ OldEbuildIsLinkedToError if the deletion of an ebuild was blocked by
+ other ebuilds linking to it. It's still 'needed' in this case, but with
+ some human intervention, it can be removed.
+ """
+ rust_bootstrap_versions = collect_ebuilds_by_version(rust_bootstrap_dir)
+ logging.info(
+ "Current rust-bootstrap versions: %s",
+ [x for x, _ in rust_bootstrap_versions],
+ )
+ rust_versions = collect_ebuilds_by_version(
+ rust_dir_from_rust_bootstrap(rust_bootstrap_dir)
+ )
+ # rust_versions is sorted, so taking the last is the same as max().
+ newest_rust_version = rust_versions[-1][0].major_minor_only()
+ need_rust_bootstrap_versions = {
+ rust_ver.major_minor_only().prior_minor_version()
+ for rust_ver, _ in rust_versions
+ }
+ logging.info(
+ "Needed rust-bootstrap versions (major/minor only): %s",
+ sorted(need_rust_bootstrap_versions),
+ )
+
+ discardable_bootstrap_versions = [
+ (version, ebuild)
+ for version, ebuild in rust_bootstrap_versions
+ # Don't remove newer rust-bootstrap versions, since they're likely to
+ # be needed in the future (& may have been generated by this very
+ # script).
+ if version.major_minor_only() not in need_rust_bootstrap_versions
+ and version.major_minor_only() < newest_rust_version
+ ]
+
+ if not discardable_bootstrap_versions:
+ logging.info("No versions of rust-bootstrap are unneeded.")
+ return False
+
+ discardable_ebuilds = []
+ for version, ebuild in discardable_bootstrap_versions:
+ # We may have other files with the same version at different revisions.
+ # Include those, as well.
+ escaped_ver = glob.escape(str(version.without_rev()))
+ discardable = list(
+ ebuild.parent.glob(f"rust-bootstrap-{escaped_ver}*.ebuild")
+ )
+ assert ebuild in discardable, discardable
+ discardable_ebuilds += discardable
+
+ # We can end up in a case where rust-bootstrap versions are unneeded, but
+ # the ebuild is still required. For example, consider a case where
+ # rust-bootstrap-1.73.0.ebuild is considered 'old', but
+ # rust-bootstrap-1.74.0.ebuild is required. If rust-bootstrap-1.74.0.ebuild
+ # is a symlink to rust-bootstrap-1.73.0.ebuild, the 'old' ebuild can't be
+ # deleted until rust-bootstrap-1.74.0.ebuild is fixed up.
+ #
+ # These cases are expected to be rare (this script should never push
+ # changes that gets us into this case, but human edits can), but uploading
+ # obviously-broken changes isn't a great UX. Opt to detect these and
+ # `raise` on them, since repairing can get complicated in instances where
+ # symlinks link to symlinks, etc.
+ has_links = find_external_links_to_files_in_dir(
+ rust_bootstrap_dir, discardable_ebuilds
+ )
+ if has_links:
+ raise OldEbuildIsLinkedToError(str(has_links))
+
+ logging.info("Plan to remove ebuilds: %s", discardable_ebuilds)
+ if dry_run:
+ logging.info("Dry-run specified; removal skipped.")
+ return True
+
+ for ebuild in discardable_ebuilds:
+ ebuild.unlink()
+
+ remaining_ebuild = next(
+ ebuild
+ for _, ebuild in rust_bootstrap_versions
+ if ebuild not in discardable_ebuilds
+ )
+ update_ebuild_manifest(remaining_ebuild)
+ if commit:
+ many = len(discardable_ebuilds) > 1
+ message_lines = [
+ "Rust has moved on in ChromeOS, so",
+ "these ebuilds are" if many else "this ebuild is",
+ "no longer needed.",
+ ]
+ message = textwrap.fill("\n".join(message_lines))
+ commit_all_changes(
+ chromiumos_overlay,
+ rust_bootstrap_dir,
+ commit_message=textwrap.dedent(
+ f"""\
+ rust-bootstrap: remove unused ebuild{"s" if many else ""}
+
+ {message}
+
+ BUG={TRACKING_BUG}
+ TEST=CQ
+ """
+ ),
+ )
+ return True
+
+
+def main(argv: List[str]):
+ logging.basicConfig(
+ format=">> %(asctime)s: %(levelname)s: %(filename)s:%(lineno)d: "
+ "%(message)s",
+ level=logging.INFO,
+ )
+
+ my_dir = Path(__file__).parent.resolve()
+ parser = argparse.ArgumentParser(
+ description=__doc__,
+ formatter_class=argparse.RawDescriptionHelpFormatter,
+ )
+ parser.add_argument(
+ "--chromiumos-overlay",
+ type=Path,
+ default=my_dir.parent.parent / "chromiumos-overlay",
+ )
+ parser.add_argument(
+ "action",
+ choices=("dry-run", "commit", "upload"),
+ help="""
+ What to do. `dry-run` makes no changes, `commit` commits changes
+ locally, and `upload` commits changes and uploads the result to Gerrit,
+ and sets a few labels for convenience (reviewers, CQ+1, etc).
+ """,
+ )
+ opts = parser.parse_args(argv)
+
+ if opts.action == "dry-run":
+ dry_run = True
+ upload = False
+ elif opts.action == "commit":
+ dry_run = False
+ upload = False
+ else:
+ assert opts.action == "upload"
+ dry_run = False
+ upload = True
+
+ rust_bootstrap_dir = opts.chromiumos_overlay / "dev-lang/rust-bootstrap"
+ copy_rust_bootstrap_script = my_dir / "copy_rust_bootstrap.py"
+
+ had_recoverable_error = False
+ # Ensure prebuilts are up to date first, since it allows
+ # `ensure_newest_rust_bootstrap_ebuild_exists` to succeed in edge cases.
+ made_changes = maybe_add_newest_prebuilts(
+ copy_rust_bootstrap_script,
+ opts.chromiumos_overlay,
+ rust_bootstrap_dir,
+ dry_run,
+ )
+
+ try:
+ made_changes |= maybe_add_new_rust_bootstrap_version(
+ opts.chromiumos_overlay, rust_bootstrap_dir, dry_run
+ )
+ except MissingRustBootstrapPrebuiltError:
+ logging.exception(
+ "Ensuring newest rust-bootstrap ebuild exists failed."
+ )
+ had_recoverable_error = True
+
+ try:
+ made_changes |= maybe_delete_old_rust_bootstrap_ebuilds(
+ opts.chromiumos_overlay, rust_bootstrap_dir, dry_run
+ )
+ except OldEbuildIsLinkedToError:
+ logging.exception("An old ebuild is linked to; can't remove it")
+ had_recoverable_error = True
+
+ if upload:
+ if made_changes:
+ upload_changes(opts.chromiumos_overlay)
+ logging.info("Changes uploaded successfully.")
+ else:
+ logging.info("No changes were made; uploading skipped.")
+
+ if had_recoverable_error:
+ sys.exit("Exiting uncleanly due to above error(s).")
+
+
+if __name__ == "__main__":
+ main(sys.argv[1:])
diff --git a/rust_tools/auto_update_rust_bootstrap_test.py b/rust_tools/auto_update_rust_bootstrap_test.py
new file mode 100755
index 00000000..ea58e723
--- /dev/null
+++ b/rust_tools/auto_update_rust_bootstrap_test.py
@@ -0,0 +1,473 @@
+#!/usr/bin/env python3
+# Copyright 2023 The ChromiumOS Authors
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""Tests for auto_update_rust_bootstrap."""
+
+
+import os
+from pathlib import Path
+import shutil
+import tempfile
+import textwrap
+import unittest
+from unittest import mock
+
+import auto_update_rust_bootstrap
+
+
+_GIT_PUSH_OUTPUT = r"""
+remote: Waiting for private key checker: 2/2 objects left
+remote:
+remote: Processing changes: new: 1 (\)
+remote: Processing changes: new: 1 (|)
+remote: Processing changes: new: 1 (/)
+remote: Processing changes: refs: 1, new: 1 (/)
+remote: Processing changes: refs: 1, new: 1 (/)
+remote: Processing changes: refs: 1, new: 1 (/)
+remote: Processing changes: refs: 1, new: 1, done
+remote:
+remote: SUCCESS
+remote:
+remote: https://chromium-review.googlesource.com/c/chromiumos/overlays/chromiumos-overlay/+/5018826 rust-bootstrap: use prebuilts [WIP] [NEW]
+remote:
+To https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay
+ * [new reference] HEAD -> refs/for/main
+"""
+
+
+class Test(unittest.TestCase):
+ """Tests for auto_update_rust_bootstrap."""
+
+ def make_tempdir(self) -> Path:
+ tempdir = Path(
+ tempfile.mkdtemp(prefix="auto_update_rust_bootstrap_test_")
+ )
+ self.addCleanup(shutil.rmtree, tempdir)
+ return tempdir
+
+ def test_git_cl_id_scraping(self):
+ self.assertEqual(
+ auto_update_rust_bootstrap.scrape_git_push_cl_id(_GIT_PUSH_OUTPUT),
+ 5018826,
+ )
+
+ def test_ebuild_linking_logic_handles_direct_relative_symlinks(self):
+ tempdir = self.make_tempdir()
+ target = tempdir / "target.ebuild"
+ target.touch()
+ (tempdir / "symlink.ebuild").symlink_to(target.name)
+ self.assertTrue(
+ auto_update_rust_bootstrap.is_ebuild_linked_to_in_dir(target)
+ )
+
+ def test_ebuild_linking_logic_handles_direct_absolute_symlinks(self):
+ tempdir = self.make_tempdir()
+ target = tempdir / "target.ebuild"
+ target.touch()
+ (tempdir / "symlink.ebuild").symlink_to(target)
+ self.assertTrue(
+ auto_update_rust_bootstrap.is_ebuild_linked_to_in_dir(target)
+ )
+
+ def test_ebuild_linking_logic_handles_indirect_relative_symlinks(self):
+ tempdir = self.make_tempdir()
+ target = tempdir / "target.ebuild"
+ target.touch()
+ (tempdir / "symlink.ebuild").symlink_to(
+ Path("..") / tempdir.name / target.name
+ )
+ self.assertTrue(
+ auto_update_rust_bootstrap.is_ebuild_linked_to_in_dir(target)
+ )
+
+ def test_ebuild_linking_logic_handles_broken_symlinks(self):
+ tempdir = self.make_tempdir()
+ target = tempdir / "target.ebuild"
+ target.touch()
+ (tempdir / "symlink.ebuild").symlink_to("doesnt_exist.ebuild")
+ self.assertFalse(
+ auto_update_rust_bootstrap.is_ebuild_linked_to_in_dir(target)
+ )
+
+ def test_ebuild_linking_logic_only_steps_through_one_symlink(self):
+ tempdir = self.make_tempdir()
+ target = tempdir / "target.ebuild"
+ target.symlink_to("doesnt_exist.ebuild")
+ (tempdir / "symlink.ebuild").symlink_to(target.name)
+ self.assertTrue(
+ auto_update_rust_bootstrap.is_ebuild_linked_to_in_dir(target)
+ )
+
+ def test_raw_bootstrap_seq_finding_functions(self):
+ ebuild_contents = textwrap.dedent(
+ """\
+ # Some copyright
+ FOO=bar
+ # Comment about RUSTC_RAW_FULL_BOOTSTRAP_SEQUENCE=(
+ RUSTC_RAW_FULL_BOOTSTRAP_SEQUENCE=( # another comment
+ 1.2.3 # (with a comment with parens)
+ 4.5.6
+ )
+ """
+ )
+
+ ebuild_lines = ebuild_contents.splitlines()
+ (
+ start,
+ end,
+ ) = auto_update_rust_bootstrap.find_raw_bootstrap_sequence_lines(
+ ebuild_lines
+ )
+ self.assertEqual(start, len(ebuild_lines) - 4)
+ self.assertEqual(end, len(ebuild_lines) - 1)
+
+ def test_collect_ebuilds_by_version_ignores_older_versions(self):
+ tempdir = self.make_tempdir()
+ ebuild_170 = tempdir / "rust-bootstrap-1.70.0.ebuild"
+ ebuild_170.touch()
+ ebuild_170_r1 = tempdir / "rust-bootstrap-1.70.0-r1.ebuild"
+ ebuild_170_r1.touch()
+ ebuild_171_r2 = tempdir / "rust-bootstrap-1.71.1-r2.ebuild"
+ ebuild_171_r2.touch()
+
+ self.assertEqual(
+ auto_update_rust_bootstrap.collect_ebuilds_by_version(tempdir),
+ [
+ (
+ auto_update_rust_bootstrap.EbuildVersion(
+ major=1, minor=70, patch=0, rev=1
+ ),
+ ebuild_170_r1,
+ ),
+ (
+ auto_update_rust_bootstrap.EbuildVersion(
+ major=1, minor=71, patch=1, rev=2
+ ),
+ ebuild_171_r2,
+ ),
+ ],
+ )
+
+ def test_has_prebuilt_works(self):
+ tempdir = self.make_tempdir()
+ ebuild = tempdir / "rust-bootstrap-1.70.0.ebuild"
+ ebuild.write_text(
+ textwrap.dedent(
+ """\
+ # Some copyright
+ FOO=bar
+ # Comment about RUSTC_RAW_FULL_BOOTSTRAP_SEQUENCE=(
+ RUSTC_RAW_FULL_BOOTSTRAP_SEQUENCE=( # another comment
+ 1.67.0
+ 1.68.1
+ 1.69.0
+ )
+ """
+ ),
+ encoding="utf-8",
+ )
+
+ self.assertTrue(
+ auto_update_rust_bootstrap.version_listed_in_bootstrap_sequence(
+ ebuild,
+ auto_update_rust_bootstrap.EbuildVersion(
+ major=1,
+ minor=69,
+ patch=0,
+ rev=0,
+ ),
+ )
+ )
+
+ self.assertFalse(
+ auto_update_rust_bootstrap.version_listed_in_bootstrap_sequence(
+ ebuild,
+ auto_update_rust_bootstrap.EbuildVersion(
+ major=1,
+ minor=70,
+ patch=0,
+ rev=0,
+ ),
+ )
+ )
+
+ def test_ebuild_updating_works(self):
+ tempdir = self.make_tempdir()
+ ebuild = tempdir / "rust-bootstrap-1.70.0.ebuild"
+ ebuild.write_text(
+ textwrap.dedent(
+ """\
+ # Some copyright
+ FOO=bar
+ RUSTC_RAW_FULL_BOOTSTRAP_SEQUENCE=(
+ \t1.67.0
+ \t1.68.1
+ \t1.69.0
+ )
+ """
+ ),
+ encoding="utf-8",
+ )
+
+ auto_update_rust_bootstrap.add_version_to_bootstrap_sequence(
+ ebuild,
+ auto_update_rust_bootstrap.EbuildVersion(
+ major=1,
+ minor=70,
+ patch=1,
+ rev=2,
+ ),
+ dry_run=False,
+ )
+
+ self.assertEqual(
+ ebuild.read_text(encoding="utf-8"),
+ textwrap.dedent(
+ """\
+ # Some copyright
+ FOO=bar
+ RUSTC_RAW_FULL_BOOTSTRAP_SEQUENCE=(
+ \t1.67.0
+ \t1.68.1
+ \t1.69.0
+ \t1.70.1-r2
+ )
+ """
+ ),
+ )
+
+ def test_ebuild_version_parsing_works(self):
+ self.assertEqual(
+ auto_update_rust_bootstrap.parse_ebuild_version(
+ "rust-bootstrap-1.70.0-r2.ebuild"
+ ),
+ auto_update_rust_bootstrap.EbuildVersion(
+ major=1, minor=70, patch=0, rev=2
+ ),
+ )
+
+ self.assertEqual(
+ auto_update_rust_bootstrap.parse_ebuild_version(
+ "rust-bootstrap-2.80.3.ebuild"
+ ),
+ auto_update_rust_bootstrap.EbuildVersion(
+ major=2, minor=80, patch=3, rev=0
+ ),
+ )
+
+ with self.assertRaises(ValueError):
+ auto_update_rust_bootstrap.parse_ebuild_version(
+ "rust-bootstrap-2.80.3_pre1234.ebuild"
+ )
+
+ def test_raw_ebuild_version_parsing_works(self):
+ self.assertEqual(
+ auto_update_rust_bootstrap.parse_raw_ebuild_version("1.70.0-r2"),
+ auto_update_rust_bootstrap.EbuildVersion(
+ major=1, minor=70, patch=0, rev=2
+ ),
+ )
+
+ with self.assertRaises(ValueError):
+ auto_update_rust_bootstrap.parse_ebuild_version("2.80.3_pre1234")
+
+ def test_ensure_newest_version_does_nothing_if_no_new_rust_version(self):
+ tempdir = self.make_tempdir()
+ rust = tempdir / "rust"
+ rust.mkdir()
+ (rust / "rust-1.70.0-r1.ebuild").touch()
+ rust_bootstrap = tempdir / "rust-bootstrap"
+ rust_bootstrap.mkdir()
+ (rust_bootstrap / "rust-bootstrap-1.70.0.ebuild").touch()
+
+ self.assertFalse(
+ auto_update_rust_bootstrap.maybe_add_new_rust_bootstrap_version(
+ tempdir, rust_bootstrap, dry_run=True
+ )
+ )
+
+ @mock.patch.object(auto_update_rust_bootstrap, "update_ebuild_manifest")
+ def test_ensure_newest_version_upgrades_rust_bootstrap_properly(
+ self, update_ebuild_manifest
+ ):
+ tempdir = self.make_tempdir()
+ rust = tempdir / "rust"
+ rust.mkdir()
+ (rust / "rust-1.71.0-r1.ebuild").touch()
+ rust_bootstrap = tempdir / "rust-bootstrap"
+ rust_bootstrap.mkdir()
+ rust_bootstrap_1_70 = rust_bootstrap / "rust-bootstrap-1.70.0-r2.ebuild"
+
+ rust_bootstrap_contents = textwrap.dedent(
+ """\
+ # Some copyright
+ FOO=bar
+ RUSTC_RAW_FULL_BOOTSTRAP_SEQUENCE=(
+ \t1.67.0
+ \t1.68.1
+ \t1.69.0
+ \t1.70.0-r1
+ )
+ """
+ )
+ rust_bootstrap_1_70.write_text(
+ rust_bootstrap_contents, encoding="utf-8"
+ )
+
+ self.assertTrue(
+ auto_update_rust_bootstrap.maybe_add_new_rust_bootstrap_version(
+ tempdir, rust_bootstrap, dry_run=False, commit=False
+ )
+ )
+ update_ebuild_manifest.assert_called_once()
+ rust_bootstrap_1_71 = rust_bootstrap / "rust-bootstrap-1.71.0.ebuild"
+
+ self.assertTrue(rust_bootstrap_1_70.is_symlink())
+ self.assertEqual(
+ os.readlink(rust_bootstrap_1_70),
+ rust_bootstrap_1_71.name,
+ )
+ self.assertFalse(rust_bootstrap_1_71.is_symlink())
+ self.assertEqual(
+ rust_bootstrap_1_71.read_text(encoding="utf-8"),
+ rust_bootstrap_contents,
+ )
+
+ def test_ensure_newest_version_breaks_if_prebuilt_is_not_available(self):
+ tempdir = self.make_tempdir()
+ rust = tempdir / "rust"
+ rust.mkdir()
+ (rust / "rust-1.71.0-r1.ebuild").touch()
+ rust_bootstrap = tempdir / "rust-bootstrap"
+ rust_bootstrap.mkdir()
+ rust_bootstrap_1_70 = rust_bootstrap / "rust-bootstrap-1.70.0-r2.ebuild"
+
+ rust_bootstrap_contents = textwrap.dedent(
+ """\
+ # Some copyright
+ FOO=bar
+ RUSTC_RAW_FULL_BOOTSTRAP_SEQUENCE=(
+ \t1.67.0
+ \t1.68.1
+ \t1.69.0
+ # Note: Missing 1.70.0 for rust-bootstrap-1.71.1
+ )
+ """
+ )
+ rust_bootstrap_1_70.write_text(
+ rust_bootstrap_contents, encoding="utf-8"
+ )
+
+ with self.assertRaises(
+ auto_update_rust_bootstrap.MissingRustBootstrapPrebuiltError
+ ):
+ auto_update_rust_bootstrap.maybe_add_new_rust_bootstrap_version(
+ tempdir, rust_bootstrap, dry_run=True
+ )
+
+ def test_version_deletion_does_nothing_if_all_versions_are_needed(self):
+ tempdir = self.make_tempdir()
+ rust = tempdir / "rust"
+ rust.mkdir()
+ (rust / "rust-1.71.0-r1.ebuild").touch()
+ rust_bootstrap = tempdir / "rust-bootstrap"
+ rust_bootstrap.mkdir()
+ (rust_bootstrap / "rust-bootstrap-1.70.0-r2.ebuild").touch()
+
+ self.assertFalse(
+ auto_update_rust_bootstrap.maybe_delete_old_rust_bootstrap_ebuilds(
+ tempdir, rust_bootstrap, dry_run=True
+ )
+ )
+
+ def test_version_deletion_ignores_newer_than_needed_versions(self):
+ tempdir = self.make_tempdir()
+ rust = tempdir / "rust"
+ rust.mkdir()
+ (rust / "rust-1.71.0-r1.ebuild").touch()
+ rust_bootstrap = tempdir / "rust-bootstrap"
+ rust_bootstrap.mkdir()
+ (rust_bootstrap / "rust-bootstrap-1.70.0-r2.ebuild").touch()
+ (rust_bootstrap / "rust-bootstrap-1.71.0-r1.ebuild").touch()
+ (rust_bootstrap / "rust-bootstrap-1.72.0.ebuild").touch()
+
+ self.assertFalse(
+ auto_update_rust_bootstrap.maybe_delete_old_rust_bootstrap_ebuilds(
+ tempdir, rust_bootstrap, dry_run=True
+ )
+ )
+
+ @mock.patch.object(auto_update_rust_bootstrap, "update_ebuild_manifest")
+ def test_version_deletion_deletes_old_files(self, update_ebuild_manifest):
+ tempdir = self.make_tempdir()
+ rust = tempdir / "rust"
+ rust.mkdir()
+ (rust / "rust-1.71.0-r1.ebuild").touch()
+ rust_bootstrap = tempdir / "rust-bootstrap"
+ rust_bootstrap.mkdir()
+ needed_rust_bootstrap = (
+ rust_bootstrap / "rust-bootstrap-1.70.0-r2.ebuild"
+ )
+ needed_rust_bootstrap.touch()
+
+ # There are quite a few of these, so corner-cases are tested.
+
+ # Symlink to outside of the group of files to delete.
+ bootstrap_1_68_symlink = rust_bootstrap / "rust-bootstrap-1.68.0.ebuild"
+ bootstrap_1_68_symlink.symlink_to(needed_rust_bootstrap.name)
+ # Ensure that absolute symlinks are caught.
+ bootstrap_1_68_symlink_abs = (
+ rust_bootstrap / "rust-bootstrap-1.68.0-r1.ebuild"
+ )
+ bootstrap_1_68_symlink_abs.symlink_to(needed_rust_bootstrap)
+ # Regular files should be no issue.
+ bootstrap_1_69_regular = rust_bootstrap / "rust-bootstrap-1.69.0.ebuild"
+ bootstrap_1_69_regular.touch()
+ # Symlinks linking back into the set of files to delete should also be
+ # no issue.
+ bootstrap_1_69_symlink = (
+ rust_bootstrap / "rust-bootstrap-1.69.0-r2.ebuild"
+ )
+ bootstrap_1_69_symlink.symlink_to(bootstrap_1_69_regular.name)
+
+ self.assertTrue(
+ auto_update_rust_bootstrap.maybe_delete_old_rust_bootstrap_ebuilds(
+ tempdir,
+ rust_bootstrap,
+ dry_run=False,
+ commit=False,
+ )
+ )
+ update_ebuild_manifest.assert_called_once()
+
+ self.assertFalse(bootstrap_1_68_symlink.exists())
+ self.assertFalse(bootstrap_1_68_symlink_abs.exists())
+ self.assertFalse(bootstrap_1_69_regular.exists())
+ self.assertFalse(bootstrap_1_69_symlink.exists())
+ self.assertTrue(needed_rust_bootstrap.exists())
+
+ def test_version_deletion_raises_when_old_file_has_dep(self):
+ tempdir = self.make_tempdir()
+ rust = tempdir / "rust"
+ rust.mkdir()
+ (rust / "rust-1.71.0-r1.ebuild").touch()
+ rust_bootstrap = tempdir / "rust-bootstrap"
+ rust_bootstrap.mkdir()
+ old_rust_bootstrap = rust_bootstrap / "rust-bootstrap-1.69.0-r1.ebuild"
+ old_rust_bootstrap.touch()
+ (rust_bootstrap / "rust-bootstrap-1.70.0-r2.ebuild").symlink_to(
+ old_rust_bootstrap.name
+ )
+
+ with self.assertRaises(
+ auto_update_rust_bootstrap.OldEbuildIsLinkedToError
+ ):
+ auto_update_rust_bootstrap.maybe_delete_old_rust_bootstrap_ebuilds(
+ tempdir, rust_bootstrap, dry_run=True
+ )
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/rust_tools/copy_rust_bootstrap.py b/rust_tools/copy_rust_bootstrap.py
index c32d1fd9..fd6770f7 100755
--- a/rust_tools/copy_rust_bootstrap.py
+++ b/rust_tools/copy_rust_bootstrap.py
@@ -28,15 +28,15 @@ def _is_in_chroot() -> bool:
return Path("/etc/cros_chroot_version").exists()
-def _ensure_pbzip2_is_installed():
- if shutil.which("pbzip2"):
+def _ensure_lbzip2_is_installed():
+ if shutil.which("lbzip2"):
return
- logging.info("Auto-installing pbzip2...")
- subprocess.run(["sudo", "emerge", "-g", "pbzip2"], check=True)
+ logging.info("Auto-installing lbzip2...")
+ subprocess.run(["sudo", "emerge", "-g", "lbzip2"], check=True)
-def _determine_target_path(sdk_path: str) -> str:
+def determine_target_path(sdk_path: str) -> str:
"""Determine where `sdk_path` should sit in localmirror."""
gs_prefix = "gs://"
if not sdk_path.startswith(gs_prefix):
@@ -52,6 +52,7 @@ def _download(remote_path: str, local_file: Path):
subprocess.run(
["gsutil", "cp", remote_path, str(local_file)],
check=True,
+ stdin=subprocess.DEVNULL,
)
@@ -72,7 +73,7 @@ def _debinpkgify(binpkg_file: Path) -> Path:
# which is what our ebuild expects).
tmpdir = binpkg_file.parent
- def _mkstemp(suffix=None) -> str:
+ def _mkstemp(suffix=None) -> Path:
fd, file_path = tempfile.mkstemp(dir=tmpdir, suffix=suffix)
os.close(fd)
return Path(file_path)
@@ -124,7 +125,7 @@ def _debinpkgify(binpkg_file: Path) -> Path:
with tbz2_file.open("wb") as f:
subprocess.run(
[
- "pbzip2",
+ "lbzip2",
"-9",
"-c",
str(decompressed_artifacts_file),
@@ -182,9 +183,9 @@ def main(argv: List[str]):
if not _is_in_chroot():
parser.error("Run me from within the chroot.")
- _ensure_pbzip2_is_installed()
+ _ensure_lbzip2_is_installed()
- target_path = _determine_target_path(opts.sdk_artifact)
+ target_path = determine_target_path(opts.sdk_artifact)
with tempfile.TemporaryDirectory() as tempdir:
download_path = Path(tempdir) / "sdk_artifact"
_download(opts.sdk_artifact, download_path)
diff --git a/rust_tools/rust_uprev.py b/rust_tools/rust_uprev.py
index e9113ea7..ee956137 100755
--- a/rust_tools/rust_uprev.py
+++ b/rust_tools/rust_uprev.py
@@ -11,7 +11,7 @@ removing an old version. When using the tool, the progress can be
saved to a JSON file, so the user can resume the process after a
failing step is fixed. Example usage to create a new version:
-1. (inside chroot) $ ./rust_tools/rust_uprev.py \\
+1. (outside chroot) $ ./rust_tools/rust_uprev.py \\
--state_file /tmp/rust-to-1.60.0.json \\
roll --uprev 1.60.0
2. Step "compile rust" failed due to the patches can't apply to new version.
@@ -26,6 +26,7 @@ See `--help` for all available options.
"""
import argparse
+import functools
import json
import logging
import os
@@ -35,6 +36,8 @@ import re
import shlex
import shutil
import subprocess
+import threading
+import time
from typing import (
Any,
Callable,
@@ -43,6 +46,7 @@ from typing import (
NamedTuple,
Optional,
Protocol,
+ Sequence,
Tuple,
TypeVar,
Union,
@@ -51,11 +55,10 @@ import urllib.request
from llvm_tools import chroot
from llvm_tools import git
-from pgo_tools_rust import pgo_rust
T = TypeVar("T")
-Command = List[Union[str, os.PathLike]]
+Command = Sequence[Union[str, os.PathLike]]
PathOrStr = Union[str, os.PathLike]
@@ -76,15 +79,31 @@ class RunStepFn(Protocol):
...
+def get_command_output(command: Command, *args, **kwargs) -> str:
+ return subprocess.check_output(
+ command, encoding="utf-8", *args, **kwargs
+ ).strip()
+
+
+def _get_source_root() -> Path:
+ """Returns the path to the chromiumos directory."""
+ return Path(get_command_output(["repo", "--show-toplevel"]))
+
+
+SOURCE_ROOT = _get_source_root()
EQUERY = "equery"
GPG = "gpg"
-GSUTIL = "gsutil"
+GSUTIL = "gsutil.py"
MIRROR_PATH = "gs://chromeos-localmirror/distfiles"
-EBUILD_PREFIX = Path("/mnt/host/source/src/third_party/chromiumos-overlay")
+EBUILD_PREFIX = SOURCE_ROOT / "src/third_party/chromiumos-overlay"
CROS_RUSTC_ECLASS = EBUILD_PREFIX / "eclass/cros-rustc.eclass"
# Keyserver to use with GPG. Not all keyservers have Rust's signing key;
# this must be set to a keyserver that does.
GPG_KEYSERVER = "keyserver.ubuntu.com"
+PGO_RUST = Path(
+ "/mnt/host/source"
+ "/src/third_party/toolchain-utils/pgo_tools_rust/pgo_rust.py"
+)
RUST_PATH = Path(EBUILD_PREFIX, "dev-lang", "rust")
# This is the signing key used by upstream Rust as of 2023-08-09.
# If the project switches to a different key, this will have to be updated.
@@ -92,6 +111,11 @@ RUST_PATH = Path(EBUILD_PREFIX, "dev-lang", "rust")
# to verify that the key change is legitimate.
RUST_SIGNING_KEY = "85AB96E6FA1BE5FE"
RUST_SRC_BASE_URI = "https://static.rust-lang.org/dist/"
+# Packages that need to be processed like dev-lang/rust.
+RUST_PACKAGES = (
+ ("dev-lang", "rust-host"),
+ ("dev-lang", "rust"),
+)
class SignatureVerificationError(Exception):
@@ -108,12 +132,6 @@ class SignatureVerificationError(Exception):
self.path = path
-def get_command_output(command: Command, *args, **kwargs) -> str:
- return subprocess.check_output(
- command, encoding="utf-8", *args, **kwargs
- ).strip()
-
-
def get_command_output_unchecked(command: Command, *args, **kwargs) -> str:
# pylint: disable=subprocess-run-check
return subprocess.run(
@@ -141,7 +159,7 @@ class RustVersion(NamedTuple):
return f"{self.major}.{self.minor}.{self.patch}"
@staticmethod
- def parse_from_ebuild(ebuild_name: str) -> "RustVersion":
+ def parse_from_ebuild(ebuild_name: PathOrStr) -> "RustVersion":
input_re = re.compile(
r"^rust-"
r"(?P<major>\d+)\."
@@ -150,7 +168,7 @@ class RustVersion(NamedTuple):
r"(:?-r\d+)?"
r"\.ebuild$"
)
- m = input_re.match(ebuild_name)
+ m = input_re.match(Path(ebuild_name).name)
assert m, f"failed to parse {ebuild_name!r}"
return RustVersion(
int(m.group("major")), int(m.group("minor")), int(m.group("patch"))
@@ -176,8 +194,10 @@ class PreparedUprev(NamedTuple):
"""Container for the information returned by prepare_uprev."""
template_version: RustVersion
- ebuild_path: Path
- bootstrap_version: RustVersion
+
+
+def compute_ebuild_path(category: str, name: str, version: RustVersion) -> Path:
+ return EBUILD_PREFIX / category / name / f"{name}-{version}.ebuild"
def compute_rustc_src_name(version: RustVersion) -> str:
@@ -190,7 +210,10 @@ def compute_rust_bootstrap_prebuilt_name(version: RustVersion) -> str:
def find_ebuild_for_package(name: str) -> str:
"""Returns the path to the ebuild for the named package."""
- return get_command_output([EQUERY, "w", name])
+ return run_in_chroot(
+ [EQUERY, "w", name],
+ stdout=subprocess.PIPE,
+ ).stdout.strip()
def find_ebuild_path(
@@ -306,18 +329,6 @@ def parse_commandline_args() -> argparse.Namespace:
"specified, the tool will remove the oldest version in the chroot",
)
- subparser_names.append("remove-bootstrap")
- remove_bootstrap_parser = subparsers.add_parser(
- "remove-bootstrap",
- help="Remove an old rust-bootstrap version",
- )
- remove_bootstrap_parser.add_argument(
- "--version",
- type=RustVersion.parse,
- required=True,
- help="rust-bootstrap version to remove",
- )
-
subparser_names.append("roll")
roll_parser = subparsers.add_parser(
"roll",
@@ -373,44 +384,39 @@ def parse_commandline_args() -> argparse.Namespace:
def prepare_uprev(
- rust_version: RustVersion, template: Optional[RustVersion]
+ rust_version: RustVersion, template: RustVersion
) -> Optional[PreparedUprev]:
- if template is None:
- ebuild_path = find_ebuild_for_package("rust")
- ebuild_name = os.path.basename(ebuild_path)
- template_version = RustVersion.parse_from_ebuild(ebuild_name)
- else:
- ebuild_path = find_ebuild_for_rust_version(template)
- template_version = template
-
- bootstrap_version = get_rust_bootstrap_version()
+ ebuild_path = find_ebuild_for_rust_version(template)
- if rust_version <= template_version:
+ if rust_version <= template:
logging.info(
"Requested version %s is not newer than the template version %s.",
rust_version,
- template_version,
+ template,
)
return None
logging.info(
- "Template Rust version is %s (ebuild: %r)",
- template_version,
+ "Template Rust version is %s (ebuild: %s)",
+ template,
ebuild_path,
)
- logging.info("rust-bootstrap version is %s", bootstrap_version)
- return PreparedUprev(template_version, Path(ebuild_path), bootstrap_version)
+ return PreparedUprev(template)
def create_ebuild(
- template_ebuild: PathOrStr, pkgatom: str, new_version: RustVersion
-) -> str:
- filename = f"{Path(pkgatom).name}-{new_version}.ebuild"
- ebuild = EBUILD_PREFIX.joinpath(f"{pkgatom}/{filename}")
- shutil.copyfile(template_ebuild, ebuild)
- subprocess.check_call(["git", "add", filename], cwd=ebuild.parent)
- return str(ebuild)
+ category: str,
+ name: str,
+ template_version: RustVersion,
+ new_version: RustVersion,
+) -> None:
+ template_ebuild = compute_ebuild_path(category, name, template_version)
+ new_ebuild = compute_ebuild_path(category, name, new_version)
+ shutil.copyfile(template_ebuild, new_ebuild)
+ subprocess.check_call(
+ ["git", "add", new_ebuild.name], cwd=new_ebuild.parent
+ )
def set_include_profdata_src(ebuild_path: os.PathLike, include: bool) -> None:
@@ -440,25 +446,6 @@ def set_include_profdata_src(ebuild_path: os.PathLike, include: bool) -> None:
Path(ebuild_path).write_text(contents, encoding="utf-8")
-def update_bootstrap_ebuild(new_bootstrap_version: RustVersion) -> None:
- old_ebuild = find_ebuild_path(rust_bootstrap_path(), "rust-bootstrap")
- m = re.match(r"^rust-bootstrap-(\d+.\d+.\d+)", old_ebuild.name)
- assert m, old_ebuild.name
- old_version = RustVersion.parse(m.group(1))
- new_ebuild = old_ebuild.parent.joinpath(
- f"rust-bootstrap-{new_bootstrap_version}.ebuild"
- )
- old_text = old_ebuild.read_text(encoding="utf-8")
- new_text, changes = re.subn(
- r"(RUSTC_RAW_FULL_BOOTSTRAP_SEQUENCE=\([^)]*)",
- f"\\1\t{old_version}\n",
- old_text,
- flags=re.MULTILINE,
- )
- assert changes == 1, "Failed to update RUSTC_RAW_FULL_BOOTSTRAP_SEQUENCE"
- new_ebuild.write_text(new_text, encoding="utf-8")
-
-
def update_bootstrap_version(
path: PathOrStr, new_bootstrap_version: RustVersion
) -> None:
@@ -483,7 +470,7 @@ def ebuild_actions(
cmd = ["ebuild", ebuild_path_inchroot] + actions
if sudo:
cmd = ["sudo"] + cmd
- subprocess.check_call(cmd)
+ run_in_chroot(cmd)
def fetch_distfile_from_mirror(name: str) -> None:
@@ -491,7 +478,7 @@ def fetch_distfile_from_mirror(name: str) -> None:
This ensures that the file exists on the mirror, and
that we can read it. We overwrite any existing distfile
- to ensure the checksums that update_manifest() records
+ to ensure the checksums that `ebuild manifest` records
match the file as it exists on the mirror.
This function also attempts to verify the ACL for
@@ -503,7 +490,7 @@ def fetch_distfile_from_mirror(name: str) -> None:
the file even though we don't own it.
"""
mirror_file = MIRROR_PATH + "/" + name
- local_file = Path(get_distdir(), name)
+ local_file = get_distdir() / name
cmd: Command = [GSUTIL, "cp", mirror_file, local_file]
logging.info("Running %r", cmd)
rc = subprocess.call(cmd)
@@ -552,19 +539,15 @@ it to the local mirror using gsutil cp.
raise Exception("Could not verify that allUsers has READER permission")
-def fetch_bootstrap_distfiles(
- old_version: RustVersion, new_version: RustVersion
-) -> None:
+def fetch_bootstrap_distfiles(version: RustVersion) -> None:
"""Fetches rust-bootstrap distfiles from the local mirror
Fetches the distfiles for a rust-bootstrap ebuild to ensure they
are available on the mirror and the local copies are the same as
the ones on the mirror.
"""
- fetch_distfile_from_mirror(
- compute_rust_bootstrap_prebuilt_name(old_version)
- )
- fetch_distfile_from_mirror(compute_rustc_src_name(new_version))
+ fetch_distfile_from_mirror(compute_rust_bootstrap_prebuilt_name(version))
+ fetch_distfile_from_mirror(compute_rustc_src_name(version))
def fetch_rust_distfiles(version: RustVersion) -> None:
@@ -638,9 +621,9 @@ def fetch_rust_src_from_upstream(uri: str, local_path: Path) -> None:
)
-def get_distdir() -> str:
- """Returns portage's distdir."""
- return get_command_output(["portageq", "distdir"])
+def get_distdir() -> Path:
+ """Returns portage's distdir outside the chroot."""
+ return SOURCE_ROOT / ".cache/distfiles"
def mirror_has_file(name: str) -> bool:
@@ -677,7 +660,7 @@ def mirror_rust_source(version: RustVersion) -> None:
logging.info("%s is present on the mirror", filename)
return
uri = f"{RUST_SRC_BASE_URI}{filename}"
- local_path = Path(get_distdir()) / filename
+ local_path = get_distdir() / filename
mirror_path = f"{MIRROR_PATH}/{filename}"
fetch_rust_src_from_upstream(uri, local_path)
subprocess.run(
@@ -686,12 +669,6 @@ def mirror_rust_source(version: RustVersion) -> None:
)
-def update_manifest(ebuild_file: PathOrStr) -> None:
- """Updates the MANIFEST for the ebuild at the given path."""
- ebuild = Path(ebuild_file)
- ebuild_actions(ebuild.parent.name, ["manifest"])
-
-
def update_rust_packages(
pkgatom: str, rust_version: RustVersion, add: bool
) -> None:
@@ -738,14 +715,14 @@ def update_virtual_rust(
def unmerge_package_if_installed(pkgatom: str) -> None:
"""Unmerges a package if it is installed."""
shpkg = shlex.quote(pkgatom)
- subprocess.check_call(
+ run_in_chroot(
[
"sudo",
"bash",
"-c",
f"! emerge --pretend --quiet --unmerge {shpkg}"
f" || emerge --rage-clean {shpkg}",
- ]
+ ],
)
@@ -781,41 +758,35 @@ def perform_step(
def prepare_uprev_from_json(obj: Any) -> Optional[PreparedUprev]:
if not obj:
return None
- version, ebuild_path, bootstrap_version = obj
+ version = obj[0]
return PreparedUprev(
RustVersion(*version),
- Path(ebuild_path),
- RustVersion(*bootstrap_version),
)
def prepare_uprev_to_json(
prepared_uprev: Optional[PreparedUprev],
-) -> Optional[Tuple[RustVersion, str, RustVersion]]:
+) -> Optional[Tuple[RustVersion]]:
if prepared_uprev is None:
return None
- return (
- prepared_uprev.template_version,
- str(prepared_uprev.ebuild_path),
- prepared_uprev.bootstrap_version,
- )
+ return (prepared_uprev.template_version,)
def create_rust_uprev(
rust_version: RustVersion,
- maybe_template_version: Optional[RustVersion],
+ template_version: RustVersion,
skip_compile: bool,
run_step: RunStepFn,
) -> None:
prepared = run_step(
"prepare uprev",
- lambda: prepare_uprev(rust_version, maybe_template_version),
+ lambda: prepare_uprev(rust_version, template_version),
result_from_json=prepare_uprev_from_json,
result_to_json=prepare_uprev_to_json,
)
if prepared is None:
return
- template_version, template_ebuild, old_bootstrap_version = prepared
+ template_version = prepared.template_version
run_step(
"mirror bootstrap sources",
@@ -836,24 +807,10 @@ def create_rust_uprev(
# to the mirror.
run_step(
"fetch bootstrap distfiles",
- lambda: fetch_bootstrap_distfiles(
- old_bootstrap_version, template_version
- ),
+ lambda: fetch_bootstrap_distfiles(template_version),
)
run_step("fetch rust distfiles", lambda: fetch_rust_distfiles(rust_version))
run_step(
- "update bootstrap ebuild",
- lambda: update_bootstrap_ebuild(template_version),
- )
- run_step(
- "update bootstrap manifest",
- lambda: update_manifest(
- rust_bootstrap_path().joinpath(
- f"rust-bootstrap-{template_version}.ebuild"
- )
- ),
- )
- run_step(
"update bootstrap version",
lambda: update_bootstrap_version(CROS_RUSTC_ECLASS, template_version),
)
@@ -861,46 +818,45 @@ def create_rust_uprev(
"turn off profile data sources in cros-rustc.eclass",
lambda: set_include_profdata_src(CROS_RUSTC_ECLASS, include=False),
)
- template_host_ebuild = EBUILD_PREFIX.joinpath(
- f"dev-lang/rust-host/rust-host-{template_version}.ebuild"
- )
- host_file = run_step(
- "create host ebuild",
- lambda: create_ebuild(
- template_host_ebuild, "dev-lang/rust-host", rust_version
- ),
- )
- run_step(
- "update host manifest to add new version",
- lambda: update_manifest(Path(host_file)),
- )
- target_file = run_step(
- "create target ebuild",
- lambda: create_ebuild(template_ebuild, "dev-lang/rust", rust_version),
- )
+
+ for category, name in RUST_PACKAGES:
+ run_step(
+ f"create new {category}/{name} ebuild",
+ functools.partial(
+ create_ebuild,
+ category,
+ name,
+ template_version,
+ rust_version,
+ ),
+ )
+
run_step(
- "update target manifest to add new version",
- lambda: update_manifest(Path(target_file)),
+ "update dev-lang/rust-host manifest to add new version",
+ lambda: ebuild_actions("dev-lang/rust-host", ["manifest"]),
)
+
run_step(
"generate profile data for rustc",
- lambda: pgo_rust.main(["pgo_rust", "generate"]),
+ lambda: run_in_chroot([PGO_RUST, "generate"]),
+ # Avoid returning subprocess.CompletedProcess, which cannot be
+ # serialized to JSON.
+ result_to_json=lambda _x: None,
)
run_step(
"upload profile data for rustc",
- lambda: pgo_rust.main(["pgo_rust", "upload-profdata"]),
+ lambda: run_in_chroot([PGO_RUST, "upload-profdata"]),
+ # Avoid returning subprocess.CompletedProcess, which cannot be
+ # serialized to JSON.
+ result_to_json=lambda _x: None,
)
run_step(
"turn on profile data sources in cros-rustc.eclass",
lambda: set_include_profdata_src(CROS_RUSTC_ECLASS, include=True),
)
run_step(
- "update host manifest to add profile data",
- lambda: update_manifest(Path(host_file)),
- )
- run_step(
- "update target manifest to add profile data",
- lambda: update_manifest(Path(target_file)),
+ "update dev-lang/rust-host manifest to add profile data",
+ lambda: ebuild_actions("dev-lang/rust-host", ["manifest"]),
)
if not skip_compile:
run_step("build packages", lambda: rebuild_packages(rust_version))
@@ -920,44 +876,38 @@ def create_rust_uprev(
)
-def find_rust_versions_in_chroot() -> List[Tuple[RustVersion, str]]:
+def find_rust_versions() -> List[Tuple[RustVersion, Path]]:
+ """Returns (RustVersion, ebuild_path) for base versions of dev-lang/rust.
+
+ This excludes symlinks to ebuilds, so if rust-1.34.0.ebuild and
+ rust-1.34.0-r1.ebuild both exist and -r1 is a symlink to the other,
+ only rust-1.34.0.ebuild will be in the return value.
+ """
return [
- (RustVersion.parse_from_ebuild(x), os.path.join(RUST_PATH, x))
- for x in os.listdir(RUST_PATH)
- if x.endswith(".ebuild")
+ (RustVersion.parse_from_ebuild(ebuild), ebuild)
+ for ebuild in RUST_PATH.iterdir()
+ if ebuild.suffix == ".ebuild" and not ebuild.is_symlink()
]
-def find_oldest_rust_version_in_chroot() -> RustVersion:
- rust_versions = find_rust_versions_in_chroot()
+def find_oldest_rust_version() -> RustVersion:
+ """Returns the RustVersion of the oldest dev-lang/rust ebuild."""
+ rust_versions = find_rust_versions()
if len(rust_versions) <= 1:
raise RuntimeError("Expect to find more than one Rust versions")
return min(rust_versions)[0]
-def find_ebuild_for_rust_version(version: RustVersion) -> str:
- rust_ebuilds = [
- ebuild for x, ebuild in find_rust_versions_in_chroot() if x == version
- ]
- if not rust_ebuilds:
- raise ValueError(f"No Rust ebuilds found matching {version}")
- if len(rust_ebuilds) > 1:
- raise ValueError(
- f"Multiple Rust ebuilds found matching {version}: "
- f"{rust_ebuilds}"
- )
- return rust_ebuilds[0]
+def find_ebuild_for_rust_version(version: RustVersion) -> Path:
+ """Returns the path of the ebuild for the given version of dev-lang/rust."""
+ return find_ebuild_path(RUST_PATH, "rust", version)
def rebuild_packages(version: RustVersion):
"""Rebuild packages modified by this script."""
# Remove all packages we modify to avoid depending on preinstalled
# versions. This ensures that the packages can really be built.
- packages = [
- "dev-lang/rust",
- "dev-lang/rust-host",
- "dev-lang/rust-bootstrap",
- ]
+ packages = [f"{category}/{name}" for category, name in RUST_PACKAGES]
for pkg in packages:
unmerge_package_if_installed(pkg)
# Mention only dev-lang/rust explicitly, so that others are pulled
@@ -965,7 +915,7 @@ def rebuild_packages(version: RustVersion):
# Packages we modify are listed in --usepkg-exclude to ensure they
# are built from source.
try:
- subprocess.check_call(
+ run_in_chroot(
[
"sudo",
"emerge",
@@ -973,7 +923,7 @@ def rebuild_packages(version: RustVersion):
"--usepkg-exclude",
" ".join(packages),
f"=dev-lang/rust-{version}",
- ]
+ ],
)
except:
logging.warning(
@@ -1013,23 +963,6 @@ def remove_files(filename: PathOrStr, path: PathOrStr) -> None:
subprocess.check_call(["git", "rm", filename], cwd=path)
-def remove_rust_bootstrap_version(
- version: RustVersion,
- run_step: RunStepFn,
-) -> None:
- run_step(
- "remove old bootstrap ebuild",
- lambda: remove_ebuild_version(
- rust_bootstrap_path(), "rust-bootstrap", version
- ),
- )
- ebuild_file = find_ebuild_for_package("rust-bootstrap")
- run_step(
- "update bootstrap manifest to delete old version",
- lambda: update_manifest(ebuild_file),
- )
-
-
def remove_rust_uprev(
rust_version: Optional[RustVersion],
run_step: RunStepFn,
@@ -1037,7 +970,7 @@ def remove_rust_uprev(
def find_desired_rust_version() -> RustVersion:
if rust_version:
return rust_version
- return find_oldest_rust_version_in_chroot()
+ return find_oldest_rust_version()
def find_desired_rust_version_from_json(obj: Any) -> RustVersion:
return RustVersion(*obj)
@@ -1047,22 +980,21 @@ def remove_rust_uprev(
find_desired_rust_version,
result_from_json=find_desired_rust_version_from_json,
)
+
+ for category, name in RUST_PACKAGES:
+ run_step(
+ f"remove old {name} ebuild",
+ functools.partial(
+ remove_ebuild_version,
+ EBUILD_PREFIX / category / name,
+ name,
+ delete_version,
+ ),
+ )
+
run_step(
- "remove target ebuild",
- lambda: remove_ebuild_version(RUST_PATH, "rust", delete_version),
- )
- run_step(
- "remove host ebuild",
- lambda: remove_ebuild_version(
- EBUILD_PREFIX.joinpath("dev-lang/rust-host"),
- "rust-host",
- delete_version,
- ),
- )
- target_file = find_ebuild_for_package("rust")
- run_step(
- "update target manifest to delete old version",
- lambda: update_manifest(target_file),
+ "update dev-lang/rust-host manifest to delete old version",
+ lambda: ebuild_actions("dev-lang/rust-host", ["manifest"]),
)
run_step(
"remove target version from rust packages",
@@ -1070,11 +1002,6 @@ def remove_rust_uprev(
"dev-lang/rust", delete_version, add=False
),
)
- host_file = find_ebuild_for_package("rust-host")
- run_step(
- "update host manifest to delete old version",
- lambda: update_manifest(host_file),
- )
run_step(
"remove host version from rust packages",
lambda: update_rust_packages(
@@ -1106,11 +1033,10 @@ def create_new_repo(rust_version: RustVersion) -> None:
git.CreateBranch(EBUILD_PREFIX, f"rust-to-{rust_version}")
-def build_cross_compiler() -> None:
+def build_cross_compiler(template_version: RustVersion) -> None:
# Get target triples in ebuild
- rust_ebuild = find_ebuild_for_package("rust")
- with open(rust_ebuild, encoding="utf-8") as f:
- contents = f.read()
+ rust_ebuild = find_ebuild_path(RUST_PATH, "rust", template_version)
+ contents = rust_ebuild.read_text(encoding="utf-8")
target_triples_re = re.compile(r"RUSTC_TARGET_TRIPLES=\(([^)]+)\)")
m = target_triples_re.search(contents)
@@ -1130,9 +1056,9 @@ def build_cross_compiler() -> None:
compiler_targets_to_install.append("arm-none-eabi")
logging.info("Emerging cross compilers %s", compiler_targets_to_install)
- subprocess.check_call(
+ run_in_chroot(
["sudo", "emerge", "-j", "-G"]
- + [f"cross-{target}/gcc" for target in compiler_targets_to_install]
+ + [f"cross-{target}/gcc" for target in compiler_targets_to_install],
)
@@ -1145,17 +1071,95 @@ def create_new_commit(rust_version: RustVersion) -> None:
"BUG=None",
"TEST=Use CQ to test the new Rust version",
]
- git.UploadChanges(EBUILD_PREFIX, f"rust-to-{rust_version}", messages)
+ branch = f"rust-to-{rust_version}"
+ git.CommitChanges(EBUILD_PREFIX, messages)
+ git.UploadChanges(EBUILD_PREFIX, branch)
-def main() -> None:
- if not chroot.InChroot():
- raise RuntimeError("This script must be executed inside chroot")
+def run_in_chroot(cmd: Command, *args, **kwargs) -> subprocess.CompletedProcess:
+ """Runs a command in the ChromiumOS chroot.
- logging.basicConfig(level=logging.INFO)
+ This takes the same arguments as subprocess.run(). By default,
+ it uses check=True, encoding="utf-8". If needed, these can be
+ overridden by keyword arguments passed to run_in_chroot().
+ """
+ full_kwargs = dict(
+ {
+ "check": True,
+ "encoding": "utf-8",
+ },
+ **kwargs,
+ )
+ full_cmd = ["cros_sdk", "--"] + list(cmd)
+ logging.info("Running %s", shlex.join(str(x) for x in full_cmd))
+ # pylint: disable=subprocess-run-check
+ # (check is actually set above; it defaults to True)
+ return subprocess.run(full_cmd, *args, **full_kwargs)
- args = parse_commandline_args()
+def sudo_keepalive() -> None:
+ """Ensures we have sudo credentials, and keeps them up-to-date.
+
+ Some operations (notably run_in_chroot) run sudo, which may require
+ user interaction. To avoid blocking progress while we sit waiting
+ for that interaction, sudo_keepalive checks that we have cached
+ sudo credentials, gets them if necessary, then keeps them up-to-date
+ so that the rest of the script can run without needing to get
+ sudo credentials again.
+ """
+ logging.info(
+ "Caching sudo credentials for running commands inside the chroot"
+ )
+ # Exits successfully if cached credentials exist. Otherwise, tries
+ # created cached credentials, prompting for authentication if necessary.
+ subprocess.run(["sudo", "true"], check=True)
+
+ def sudo_keepalive_loop() -> None:
+ # Between credential refreshes, we sleep so that we don't
+ # unnecessarily burn CPU cycles. The sleep time must be shorter
+ # than sudo's configured cached credential expiration time, which
+ # is 15 minutes by default.
+ sleep_seconds = 10 * 60
+ # So as to not keep credentials cached forever, we limit the number
+ # of times we will refresh them.
+ max_seconds = 16 * 3600
+ max_refreshes = max_seconds // sleep_seconds
+ for _x in range(max_refreshes):
+ # Refreshes cached credentials if they exist, but never prompts
+ # for anything. If cached credentials do not exist, this
+ # command exits with an error. We ignore that error to keep the
+ # loop going, so that cached credentials will be kept fresh
+ # again once we have them (e.g. after the next cros_sdk command
+ # successfully authenticates the user).
+ #
+ # The standard file descriptors are all redirected to/from
+ # /dev/null to prevent this command from consuming any input
+ # or mixing its output with that of the other commands rust_uprev
+ # runs (which could be confusing, for example making it look like
+ # errors occurred during a build when they are actually in a
+ # separate task).
+ #
+ # Note: The command specifically uses "true" and not "-v", because
+ # it turns out that "-v" actually will prompt for a password when
+ # sudo is configured with NOPASSWD=all, even though in that case
+ # no password is required to run actual commands.
+ subprocess.run(
+ ["sudo", "-n", "true"],
+ check=False,
+ stdin=subprocess.DEVNULL,
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL,
+ )
+ time.sleep(sleep_seconds)
+
+ # daemon=True causes the thread to be killed when the script exits.
+ threading.Thread(target=sudo_keepalive_loop, daemon=True).start()
+
+
+def main() -> None:
+ chroot.VerifyOutsideChroot()
+ logging.basicConfig(level=logging.INFO)
+ args = parse_commandline_args()
state_file = pathlib.Path(args.state_file)
tmp_state_file = state_file.with_suffix(".tmp")
@@ -1182,27 +1186,36 @@ def main() -> None:
)
if args.subparser_name == "create":
+ sudo_keepalive()
create_rust_uprev(
args.rust_version, args.template, args.skip_compile, run_step
)
elif args.subparser_name == "remove":
remove_rust_uprev(args.rust_version, run_step)
- elif args.subparser_name == "remove-bootstrap":
- remove_rust_bootstrap_version(args.version, run_step)
else:
# If you have added more subparser_name, please also add the handlers
# above
assert args.subparser_name == "roll"
+
+ sudo_keepalive()
+ # Determine the template version, if not given.
+ template_version = args.template
+ if template_version is None:
+ rust_ebuild = find_ebuild_for_package("rust")
+ template_version = RustVersion.parse_from_ebuild(rust_ebuild)
+
run_step("create new repo", lambda: create_new_repo(args.uprev))
if not args.skip_cross_compiler:
- run_step("build cross compiler", build_cross_compiler)
+ run_step(
+ "build cross compiler",
+ lambda: build_cross_compiler(template_version),
+ )
create_rust_uprev(
- args.uprev, args.template, args.skip_compile, run_step
+ args.uprev, template_version, args.skip_compile, run_step
)
remove_rust_uprev(args.remove, run_step)
prepared = prepare_uprev_from_json(completed_steps["prepare uprev"])
assert prepared is not None, "no prepared uprev decoded from JSON"
- remove_rust_bootstrap_version(prepared.bootstrap_version, run_step)
if not args.no_upload:
run_step(
"create rust uprev CL", lambda: create_new_commit(args.uprev)
diff --git a/rust_tools/rust_uprev_test.py b/rust_tools/rust_uprev_test.py
index 3f8c829c..a90f3d10 100755
--- a/rust_tools/rust_uprev_test.py
+++ b/rust_tools/rust_uprev_test.py
@@ -14,8 +14,13 @@ import unittest
from unittest import mock
from llvm_tools import git
-import rust_uprev
-from rust_uprev import RustVersion
+
+
+# rust_uprev sets SOURCE_ROOT to the output of `repo --show-toplevel`.
+# The mock below makes us not actually run repo but use a fake value
+# instead.
+with mock.patch("subprocess.check_output", return_value="/fake/chromiumos"):
+ import rust_uprev
def _fail_command(cmd, *_args, **_kwargs):
@@ -45,7 +50,7 @@ class FetchDistfileTest(unittest.TestCase):
"""Tests rust_uprev.fetch_distfile_from_mirror()"""
@mock.patch.object(
- rust_uprev, "get_distdir", return_value="/fake/distfiles"
+ rust_uprev, "get_distdir", return_value=Path("/fake/distfiles")
)
@mock.patch.object(subprocess, "call", side_effect=_fail_command)
def test_fetch_difstfile_fail(self, *_args) -> None:
@@ -58,7 +63,7 @@ class FetchDistfileTest(unittest.TestCase):
return_value="AccessDeniedException: Access denied.",
)
@mock.patch.object(
- rust_uprev, "get_distdir", return_value="/fake/distfiles"
+ rust_uprev, "get_distdir", return_value=Path("/fake/distfiles")
)
@mock.patch.object(subprocess, "call", return_value=0)
def test_fetch_distfile_acl_access_denied(self, *_args) -> None:
@@ -70,7 +75,7 @@ class FetchDistfileTest(unittest.TestCase):
return_value='[ { "entity": "allUsers", "role": "READER" } ]',
)
@mock.patch.object(
- rust_uprev, "get_distdir", return_value="/fake/distfiles"
+ rust_uprev, "get_distdir", return_value=Path("/fake/distfiles")
)
@mock.patch.object(subprocess, "call", return_value=0)
def test_fetch_distfile_acl_ok(self, *_args) -> None:
@@ -82,7 +87,7 @@ class FetchDistfileTest(unittest.TestCase):
return_value='[ { "entity": "___fake@google.com", "role": "OWNER" } ]',
)
@mock.patch.object(
- rust_uprev, "get_distdir", return_value="/fake/distfiles"
+ rust_uprev, "get_distdir", return_value=Path("/fake/distfiles")
)
@mock.patch.object(subprocess, "call", return_value=0)
def test_fetch_distfile_acl_wrong(self, *_args) -> None:
@@ -102,7 +107,7 @@ class FetchRustSrcFromUpstreamTest(unittest.TestCase):
self._mock_get_distdir = start_mock(
self,
"rust_uprev.get_distdir",
- return_value="/fake/distfiles",
+ return_value=Path("/fake/distfiles"),
)
self._mock_gpg = start_mock(
@@ -304,6 +309,27 @@ class FindEbuildPathTest(unittest.TestCase):
self.assertEqual(result, ebuild)
+class FindRustVersionsTest(unittest.TestCase):
+ """Tests for rust_uprev.find_rust_versions."""
+
+ def test_with_symlinks(self):
+ with tempfile.TemporaryDirectory() as t:
+ tmpdir = Path(t)
+ rust_1_49_1_ebuild = tmpdir / "rust-1.49.1.ebuild"
+ rust_1_50_0_ebuild = tmpdir / "rust-1.50.0.ebuild"
+ rust_1_50_0_r1_ebuild = tmpdir / "rust-1.50.0-r1.ebuild"
+ rust_1_49_1_ebuild.touch()
+ rust_1_50_0_ebuild.touch()
+ rust_1_50_0_r1_ebuild.symlink_to(rust_1_50_0_ebuild)
+ with mock.patch("rust_uprev.RUST_PATH", tmpdir):
+ actual = rust_uprev.find_rust_versions()
+ expected = [
+ (rust_uprev.RustVersion(1, 49, 1), rust_1_49_1_ebuild),
+ (rust_uprev.RustVersion(1, 50, 0), rust_1_50_0_ebuild),
+ ]
+ self.assertEqual(actual, expected)
+
+
class MirrorHasFileTest(unittest.TestCase):
"""Tests for rust_uprev.mirror_has_file."""
@@ -332,7 +358,7 @@ class MirrorRustSourceTest(unittest.TestCase):
start_mock(self, "rust_uprev.GSUTIL", "gsutil")
start_mock(self, "rust_uprev.MIRROR_PATH", "fakegs://fakemirror/")
start_mock(
- self, "rust_uprev.get_distdir", return_value="/fake/distfiles"
+ self, "rust_uprev.get_distdir", return_value=Path("/fake/distfiles")
)
self.mock_mirror_has_file = start_mock(
self,
@@ -455,28 +481,17 @@ class PrepareUprevTest(unittest.TestCase):
"""Tests for prepare_uprev step in rust_uprev"""
def setUp(self):
- self.bootstrap_version = rust_uprev.RustVersion(1, 1, 0)
self.version_old = rust_uprev.RustVersion(1, 2, 3)
self.version_new = rust_uprev.RustVersion(1, 3, 5)
@mock.patch.object(
rust_uprev,
"find_ebuild_for_rust_version",
- return_value="/path/to/ebuild",
+ return_value=Path("/path/to/ebuild"),
)
- @mock.patch.object(rust_uprev, "find_ebuild_path")
@mock.patch.object(rust_uprev, "get_command_output")
- def test_success_with_template(
- self, mock_command, mock_find_ebuild, _ebuild_for_version
- ):
- bootstrap_ebuild_path = Path(
- "/path/to/rust-bootstrap/",
- f"rust-bootstrap-{self.bootstrap_version}.ebuild",
- )
- mock_find_ebuild.return_value = bootstrap_ebuild_path
- expected = rust_uprev.PreparedUprev(
- self.version_old, Path("/path/to/ebuild"), self.bootstrap_version
- )
+ def test_success_with_template(self, mock_command, _ebuild_for_version):
+ expected = rust_uprev.PreparedUprev(self.version_old)
actual = rust_uprev.prepare_uprev(
rust_version=self.version_new, template=self.version_old
)
@@ -488,11 +503,6 @@ class PrepareUprevTest(unittest.TestCase):
"find_ebuild_for_rust_version",
return_value="/path/to/ebuild",
)
- @mock.patch.object(
- rust_uprev,
- "get_rust_bootstrap_version",
- return_value=RustVersion(0, 41, 12),
- )
@mock.patch.object(rust_uprev, "get_command_output")
def test_return_none_with_template_larger_than_input(
self, mock_command, *_args
@@ -503,61 +513,10 @@ class PrepareUprevTest(unittest.TestCase):
self.assertIsNone(ret)
mock_command.assert_not_called()
- @mock.patch.object(rust_uprev, "find_ebuild_path")
- @mock.patch.object(os.path, "exists")
- @mock.patch.object(rust_uprev, "get_command_output")
- def test_success_without_template(
- self, mock_command, mock_exists, mock_find_ebuild
- ):
- rust_ebuild_path = f"/path/to/rust/rust-{self.version_old}-r3.ebuild"
- mock_command.return_value = rust_ebuild_path
- bootstrap_ebuild_path = Path(
- "/path/to/rust-bootstrap",
- f"rust-bootstrap-{self.bootstrap_version}.ebuild",
- )
- mock_find_ebuild.return_value = bootstrap_ebuild_path
- expected = rust_uprev.PreparedUprev(
- self.version_old,
- Path(rust_ebuild_path),
- self.bootstrap_version,
- )
- actual = rust_uprev.prepare_uprev(
- rust_version=self.version_new, template=None
- )
- self.assertEqual(expected, actual)
- mock_command.assert_called_once_with(["equery", "w", "rust"])
- mock_exists.assert_not_called()
-
- @mock.patch.object(
- rust_uprev,
- "get_rust_bootstrap_version",
- return_value=RustVersion(0, 41, 12),
- )
- @mock.patch.object(os.path, "exists")
- @mock.patch.object(rust_uprev, "get_command_output")
- def test_return_none_with_ebuild_larger_than_input(
- self, mock_command, mock_exists, *_args
- ):
- mock_command.return_value = (
- f"/path/to/rust/rust-{self.version_new}.ebuild"
- )
- ret = rust_uprev.prepare_uprev(
- rust_version=self.version_old, template=None
- )
- self.assertIsNone(ret)
- mock_exists.assert_not_called()
-
def test_prepare_uprev_from_json(self):
- ebuild_path = Path("/path/to/the/ebuild")
- json_result = (
- list(self.version_new),
- ebuild_path,
- list(self.bootstrap_version),
- )
+ json_result = (list(self.version_new),)
expected = rust_uprev.PreparedUprev(
self.version_new,
- Path(ebuild_path),
- self.bootstrap_version,
)
actual = rust_uprev.prepare_uprev_from_json(json_result)
self.assertEqual(expected, actual)
@@ -656,61 +615,6 @@ BOOTSTRAP_VERSION="1.3.6"
)
-class UpdateManifestTest(unittest.TestCase):
- """Tests for update_manifest step in rust_uprev"""
-
- @mock.patch.object(rust_uprev, "ebuild_actions")
- def test_update_manifest(self, mock_run):
- ebuild_file = Path("/path/to/rust/rust-1.1.1.ebuild")
- rust_uprev.update_manifest(ebuild_file)
- mock_run.assert_called_once_with("rust", ["manifest"])
-
-
-class UpdateBootstrapEbuildTest(unittest.TestCase):
- """Tests for rust_uprev.update_bootstrap_ebuild()"""
-
- def test_update_bootstrap_ebuild(self):
- # The update should do two things:
- # 1. Create a copy of rust-bootstrap's ebuild with the
- # new version number.
- # 2. Add the old PV to RUSTC_RAW_FULL_BOOTSTRAP_SEQUENCE.
- with tempfile.TemporaryDirectory() as tmpdir_str, mock.patch.object(
- rust_uprev, "find_ebuild_path"
- ) as mock_find_ebuild:
- tmpdir = Path(tmpdir_str)
- bootstrapdir = Path.joinpath(tmpdir, "rust-bootstrap")
- bootstrapdir.mkdir()
- old_ebuild = bootstrapdir.joinpath("rust-bootstrap-1.45.2.ebuild")
- old_ebuild.write_text(
- encoding="utf-8",
- data="""
-some text
-RUSTC_RAW_FULL_BOOTSTRAP_SEQUENCE=(
-\t1.43.1
-\t1.44.1
-)
-some more text
-""",
- )
- mock_find_ebuild.return_value = old_ebuild
- rust_uprev.update_bootstrap_ebuild(rust_uprev.RustVersion(1, 46, 0))
- new_ebuild = bootstrapdir.joinpath("rust-bootstrap-1.46.0.ebuild")
- self.assertTrue(new_ebuild.exists())
- text = new_ebuild.read_text(encoding="utf-8")
- self.assertEqual(
- text,
- """
-some text
-RUSTC_RAW_FULL_BOOTSTRAP_SEQUENCE=(
-\t1.43.1
-\t1.44.1
-\t1.45.2
-)
-some more text
-""",
- )
-
-
class UpdateRustPackagesTests(unittest.TestCase):
"""Tests for update_rust_packages step."""
@@ -775,66 +679,47 @@ class RustUprevOtherStagesTests(unittest.TestCase):
@mock.patch.object(shutil, "copyfile")
@mock.patch.object(subprocess, "check_call")
def test_create_rust_ebuild(self, mock_call, mock_copy):
- template_ebuild = f"/path/to/rust-{self.current_version}-r2.ebuild"
+ template_ebuild = (
+ rust_uprev.EBUILD_PREFIX
+ / f"dev-lang/rust/rust-{self.current_version}.ebuild"
+ )
+ new_ebuild = (
+ rust_uprev.EBUILD_PREFIX
+ / f"dev-lang/rust/rust-{self.new_version}.ebuild"
+ )
rust_uprev.create_ebuild(
- template_ebuild, "dev-lang/rust", self.new_version
+ "dev-lang", "rust", self.current_version, self.new_version
)
mock_copy.assert_called_once_with(
template_ebuild,
- rust_uprev.RUST_PATH.joinpath(f"rust-{self.new_version}.ebuild"),
+ new_ebuild,
)
mock_call.assert_called_once_with(
["git", "add", f"rust-{self.new_version}.ebuild"],
- cwd=rust_uprev.RUST_PATH,
+ cwd=new_ebuild.parent,
)
@mock.patch.object(shutil, "copyfile")
@mock.patch.object(subprocess, "check_call")
def test_create_rust_host_ebuild(self, mock_call, mock_copy):
- template_ebuild = f"/path/to/rust-host-{self.current_version}-r2.ebuild"
+ template_ebuild = (
+ rust_uprev.EBUILD_PREFIX
+ / f"dev-lang/rust-host/rust-host-{self.current_version}.ebuild"
+ )
+ new_ebuild = (
+ rust_uprev.EBUILD_PREFIX
+ / f"dev-lang/rust-host/rust-host-{self.new_version}.ebuild"
+ )
rust_uprev.create_ebuild(
- template_ebuild, "dev-lang/rust-host", self.new_version
+ "dev-lang", "rust-host", self.current_version, self.new_version
)
mock_copy.assert_called_once_with(
template_ebuild,
- rust_uprev.EBUILD_PREFIX.joinpath(
- f"dev-lang/rust-host/rust-host-{self.new_version}.ebuild"
- ),
+ new_ebuild,
)
mock_call.assert_called_once_with(
["git", "add", f"rust-host-{self.new_version}.ebuild"],
- cwd=rust_uprev.EBUILD_PREFIX.joinpath("dev-lang/rust-host"),
- )
-
- @mock.patch.object(rust_uprev, "find_ebuild_for_package")
- @mock.patch.object(subprocess, "check_call")
- def test_remove_rust_bootstrap_version(self, mock_call, *_args):
- bootstrap_path = os.path.join(
- rust_uprev.RUST_PATH, "..", "rust-bootstrap"
- )
- rust_uprev.remove_rust_bootstrap_version(
- self.old_version, lambda *x: ()
- )
- mock_call.has_calls(
- [
- [
- "git",
- "rm",
- os.path.join(
- bootstrap_path,
- "files",
- f"rust-bootstrap-{self.old_version}-*.patch",
- ),
- ],
- [
- "git",
- "rm",
- os.path.join(
- bootstrap_path,
- f"rust-bootstrap-{self.old_version}.ebuild",
- ),
- ],
- ]
+ cwd=new_ebuild.parent,
)
@mock.patch.object(subprocess, "check_call")
@@ -897,25 +782,27 @@ class RustUprevOtherStagesTests(unittest.TestCase):
ebuild_path.parent.joinpath(f"rust-{self.new_version}.ebuild"),
)
- @mock.patch.object(os, "listdir")
- def test_find_oldest_rust_version_in_chroot_pass(self, mock_ls):
+ @mock.patch("rust_uprev.find_rust_versions")
+ def test_find_oldest_rust_version_pass(self, rust_versions):
oldest_version_name = f"rust-{self.old_version}.ebuild"
- mock_ls.return_value = [
- oldest_version_name,
- f"rust-{self.current_version}.ebuild",
- f"rust-{self.new_version}.ebuild",
+ rust_versions.return_value = [
+ (self.old_version, oldest_version_name),
+ (self.current_version, f"rust-{self.current_version}.ebuild"),
+ (self.new_version, f"rust-{self.new_version}.ebuild"),
]
- actual = rust_uprev.find_oldest_rust_version_in_chroot()
+ actual = rust_uprev.find_oldest_rust_version()
expected = self.old_version
self.assertEqual(expected, actual)
- @mock.patch.object(os, "listdir")
- def test_find_oldest_rust_version_in_chroot_fail_with_only_one_ebuild(
- self, mock_ls
+ @mock.patch("rust_uprev.find_rust_versions")
+ def test_find_oldest_rust_version_fail_with_only_one_ebuild(
+ self, rust_versions
):
- mock_ls.return_value = [f"rust-{self.new_version}.ebuild"]
+ rust_versions.return_value = [
+ (self.new_version, f"rust-{self.new_version}.ebuild"),
+ ]
with self.assertRaises(RuntimeError) as context:
- rust_uprev.find_oldest_rust_version_in_chroot()
+ rust_uprev.find_oldest_rust_version()
self.assertEqual(
"Expect to find more than one Rust versions", str(context.exception)
)
@@ -929,10 +816,8 @@ class RustUprevOtherStagesTests(unittest.TestCase):
rust_uprev.EBUILD_PREFIX, f"rust-to-{self.new_version}"
)
- @mock.patch.object(rust_uprev, "get_command_output")
- @mock.patch.object(subprocess, "check_call")
- def test_build_cross_compiler(self, mock_call, mock_output):
- mock_output.return_value = f"rust-{self.new_version}.ebuild"
+ @mock.patch.object(rust_uprev, "run_in_chroot")
+ def test_build_cross_compiler(self, mock_run_in_chroot):
cros_targets = [
"x86_64-cros-linux-gnu",
"armv7a-cros-linux-gnueabihf",
@@ -940,11 +825,13 @@ class RustUprevOtherStagesTests(unittest.TestCase):
]
all_triples = ["x86_64-pc-linux-gnu"] + cros_targets
rust_ebuild = "RUSTC_TARGET_TRIPLES=(" + "\n\t".join(all_triples) + ")"
- mock_open = mock.mock_open(read_data=rust_ebuild)
- with mock.patch("builtins.open", mock_open):
- rust_uprev.build_cross_compiler()
+ with mock.patch("rust_uprev.find_ebuild_path") as mock_find_ebuild_path:
+ mock_path = mock.Mock()
+ mock_path.read_text.return_value = rust_ebuild
+ mock_find_ebuild_path.return_value = mock_path
+ rust_uprev.build_cross_compiler(rust_uprev.RustVersion(7, 3, 31))
- mock_call.assert_called_once_with(
+ mock_run_in_chroot.assert_called_once_with(
["sudo", "emerge", "-j", "-G"]
+ [f"cross-{x}/gcc" for x in cros_targets + ["arm-none-eabi"]]
)
diff --git a/rust_tools/rust_watch.py b/rust_tools/rust_watch.py
index 743396f1..ba760e78 100755
--- a/rust_tools/rust_watch.py
+++ b/rust_tools/rust_watch.py
@@ -1,5 +1,4 @@
#!/usr/bin/env python3
-# -*- coding: utf-8 -*-
# Copyright 2020 The ChromiumOS Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
@@ -94,7 +93,7 @@ class State(NamedTuple):
def parse_release_tags(lines: Iterable[str]) -> Iterable[RustReleaseVersion]:
- """Parses `git ls-remote --tags` output into Rust stable release versions."""
+ """Parses `git ls-remote --tags` output into Rust stable versions."""
refs_tags = "refs/tags/"
for line in lines:
_sha, tag = line.split(None, 1)
@@ -247,7 +246,13 @@ def file_bug(title: str, body: str) -> None:
# (bugs.WellKnownComponents.AndroidRustToolchain, None),
)
for component, assignee in targets:
- bugs.CreateNewBug(component, title, body, assignee)
+ bugs.CreateNewBug(
+ component,
+ title,
+ body,
+ assignee,
+ parent_bug=bugs.RUST_MAINTENANCE_METABUG,
+ )
def maybe_compose_bug(
@@ -286,7 +291,7 @@ def maybe_compose_email(
return None
subject_pieces = []
- body_pieces = []
+ body_pieces: List[tiny_render.Piece] = []
# Separate the sections a bit for prettier output.
if body_pieces:
@@ -360,8 +365,8 @@ def main(argv: List[str]) -> None:
last_gentoo_sha=most_recent_gentoo_commit,
),
)
- # Running through this _should_ be a nop, but do it anyway. Should make any
- # bugs more obvious on the first run of the script.
+ # Running through this _should_ be a nop, but do it anyway. Should make
+ # any bugs more obvious on the first run of the script.
prior_state = read_state(state_file)
logging.info("Last state was %r", prior_state)
@@ -382,30 +387,30 @@ def main(argv: List[str]) -> None:
if maybe_bug is None:
logging.info("No bug to file")
else:
- title, body = maybe_bug
+ bug_title, bug_body = maybe_bug
if opts.skip_side_effects:
logging.info(
"Skipping sending bug with title %r and contents\n%s",
- title,
- body,
+ bug_title,
+ bug_body,
)
else:
logging.info("Writing new bug")
- file_bug(title, body)
+ file_bug(bug_title, bug_body)
if maybe_email is None:
logging.info("No email to send")
else:
- title, body = maybe_email
+ email_title, email_body = maybe_email
if opts.skip_side_effects:
logging.info(
"Skipping sending email with title %r and contents\n%s",
- title,
- tiny_render.render_html_pieces(body),
+ email_title,
+ tiny_render.render_html_pieces(email_body),
)
else:
logging.info("Sending email")
- send_email(title, body)
+ send_email(email_title, email_body)
if opts.skip_state_update:
logging.info("Skipping state update, as requested")
@@ -424,4 +429,4 @@ def main(argv: List[str]) -> None:
if __name__ == "__main__":
- sys.exit(main(sys.argv[1:]))
+ main(sys.argv[1:])
diff --git a/toolchain_utils_githooks/check-presubmit.py b/toolchain_utils_githooks/check-presubmit.py
index 0d2f3b31..2af7569c 100755
--- a/toolchain_utils_githooks/check-presubmit.py
+++ b/toolchain_utils_githooks/check-presubmit.py
@@ -7,6 +7,7 @@
"""Runs presubmit checks against a bundle of files."""
import argparse
+import dataclasses
import datetime
import multiprocessing
import multiprocessing.pool
@@ -17,20 +18,77 @@ import shlex
import shutil
import subprocess
import sys
+import textwrap
import threading
import traceback
-import typing as t
+from typing import (
+ Dict,
+ Iterable,
+ List,
+ NamedTuple,
+ Optional,
+ Sequence,
+ Tuple,
+ Union,
+)
# This was originally had many packages in it (notably scipy)
# but due to changes in how scipy is built, we can no longer install
# it in the chroot. See b/284489250
+#
+# For type checking Python code, we also need mypy. This isn't
+# listed here because (1) only very few files are actually type checked,
+# so we don't pull the dependency in unless needed, and (2) mypy
+# may be installed through other means than pip.
PIP_DEPENDENCIES = ("numpy",)
+# Each checker represents an independent check that's done on our sources.
+#
+# They should:
+# - never write to stdout/stderr or read from stdin directly
+# - return either a CheckResult, or a list of [(subcheck_name, CheckResult)]
+# - ideally use thread_pool to check things concurrently
+# - though it's important to note that these *also* live on the threadpool
+# we've provided. It's the caller's responsibility to guarantee that at
+# least ${number_of_concurrently_running_checkers}+1 threads are present
+# in the pool. In order words, blocking on results from the provided
+# threadpool is OK.
+CheckResult = NamedTuple(
+ "CheckResult",
+ (
+ ("ok", bool),
+ ("output", str),
+ ("autofix_commands", List[List[str]]),
+ ),
+)
+
+
+Command = Sequence[Union[str, os.PathLike]]
+CheckResults = Union[List[Tuple[str, CheckResult]], CheckResult]
+
+
+# The files and directories on which we run the mypy typechecker. The paths are
+# relative to the root of the toolchain-utils repository.
+MYPY_CHECKED_PATHS = (
+ "check_portable_toolchains.py",
+ "cros_utils/bugs.py",
+ "cros_utils/bugs_test.py",
+ "cros_utils/tiny_render.py",
+ "llvm_tools",
+ "pgo_tools",
+ "pgo_tools_rust/pgo_rust.py",
+ "rust_tools",
+ "toolchain_utils_githooks/check-presubmit.py",
+)
+
+
def run_command_unchecked(
- command: t.List[str], cwd: str, env: t.Dict[str, str] = None
-) -> t.Tuple[int, str]:
+ command: Command,
+ cwd: Optional[str] = None,
+ env: Optional[Dict[str, str]] = None,
+) -> Tuple[int, str]:
"""Runs a command in the given dir, returning its exit code and stdio."""
p = subprocess.run(
command,
@@ -51,7 +109,7 @@ def has_executable_on_path(exe: str) -> bool:
return shutil.which(exe) is not None
-def escape_command(command: t.Iterable[str]) -> str:
+def escape_command(command: Iterable[str]) -> str:
"""Returns a human-readable and copy-pastable shell command.
Only intended for use in output to users. shell=True is strongly
@@ -60,7 +118,7 @@ def escape_command(command: t.Iterable[str]) -> str:
return " ".join(shlex.quote(x) for x in command)
-def remove_deleted_files(files: t.Iterable[str]) -> t.List[str]:
+def remove_deleted_files(files: Iterable[str]) -> List[str]:
return [f for f in files if os.path.exists(f)]
@@ -71,7 +129,7 @@ def is_file_executable(file_path: str) -> bool:
# As noted in our docs, some of our Python code depends on modules that sit in
# toolchain-utils/. Add that to PYTHONPATH to ensure that things like `cros
# lint` are kept happy.
-def env_with_pythonpath(toolchain_utils_root: str) -> t.Dict[str, str]:
+def env_with_pythonpath(toolchain_utils_root: str) -> Dict[str, str]:
env = dict(os.environ)
if "PYTHONPATH" in env:
env["PYTHONPATH"] += ":" + toolchain_utils_root
@@ -80,25 +138,84 @@ def env_with_pythonpath(toolchain_utils_root: str) -> t.Dict[str, str]:
return env
-# Each checker represents an independent check that's done on our sources.
-#
-# They should:
-# - never write to stdout/stderr or read from stdin directly
-# - return either a CheckResult, or a list of [(subcheck_name, CheckResult)]
-# - ideally use thread_pool to check things concurrently
-# - though it's important to note that these *also* live on the threadpool
-# we've provided. It's the caller's responsibility to guarantee that at
-# least ${number_of_concurrently_running_checkers}+1 threads are present
-# in the pool. In order words, blocking on results from the provided
-# threadpool is OK.
-CheckResult = t.NamedTuple(
- "CheckResult",
- (
- ("ok", bool),
- ("output", str),
- ("autofix_commands", t.List[t.List[str]]),
- ),
-)
+@dataclasses.dataclass(frozen=True)
+class MyPyInvocation:
+ """An invocation of mypy."""
+
+ command: List[str]
+ # Entries to add to PYTHONPATH, formatted for direct use in the PYTHONPATH
+ # env var.
+ pythonpath_additions: str
+
+
+def get_mypy() -> Optional[MyPyInvocation]:
+ """Finds the mypy executable and returns a command to invoke it.
+
+ If mypy cannot be found and we're inside the chroot, this
+ function installs mypy and returns a command to invoke it.
+
+ If mypy cannot be found and we're outside the chroot, this
+ returns None.
+
+ Returns:
+ An optional tuple containing:
+ - the command to invoke mypy, and
+ - any environment variables to set when invoking mypy
+ """
+ if has_executable_on_path("mypy"):
+ return MyPyInvocation(command=["mypy"], pythonpath_additions="")
+ pip = get_pip()
+ if not pip:
+ assert not is_in_chroot()
+ return None
+
+ def get_from_pip() -> Optional[MyPyInvocation]:
+ rc, output = run_command_unchecked(pip + ["show", "mypy"])
+ if rc:
+ return None
+
+ m = re.search(r"^Location: (.*)", output, re.MULTILINE)
+ if not m:
+ return None
+
+ pythonpath = m.group(1)
+ return MyPyInvocation(
+ command=[
+ "python3",
+ "-m",
+ "mypy",
+ ],
+ pythonpath_additions=pythonpath,
+ )
+
+ from_pip = get_from_pip()
+ if from_pip:
+ return from_pip
+
+ if is_in_chroot():
+ assert pip is not None
+ subprocess.check_call(pip + ["install", "--user", "mypy"])
+ return get_from_pip()
+ return None
+
+
+def get_pip() -> Optional[List[str]]:
+ """Finds pip and returns a command to invoke it.
+
+ If pip cannot be found, this function attempts to install
+ pip and returns a command to invoke it.
+
+ If pip cannot be found, this function returns None.
+ """
+ have_pip = can_import_py_module("pip")
+ if not have_pip:
+ print("Autoinstalling `pip`...")
+ subprocess.check_call(["python", "-m", "ensurepip"])
+ have_pip = can_import_py_module("pip")
+
+ if have_pip:
+ return ["python", "-m", "pip"]
+ return None
def get_check_result_or_catch(
@@ -120,7 +237,7 @@ def get_check_result_or_catch(
def check_isort(
- toolchain_utils_root: str, python_files: t.Iterable[str]
+ toolchain_utils_root: str, python_files: Iterable[str]
) -> CheckResult:
"""Subchecker of check_py_format. Checks python file formats with isort"""
chromite = Path("/mnt/host/source/chromite")
@@ -135,7 +252,7 @@ def check_isort(
)
config_file_flag = f"--settings-file={config_file}"
- command = [isort, "-c", config_file_flag] + python_files
+ command = [str(isort), "-c", config_file_flag] + list(python_files)
exit_code, stdout_and_stderr = run_command_unchecked(
command, cwd=toolchain_utils_root
)
@@ -175,13 +292,13 @@ def check_isort(
def check_black(
- toolchain_utils_root: str, black: Path, python_files: t.Iterable[str]
+ toolchain_utils_root: str, black: Path, python_files: Iterable[str]
) -> CheckResult:
"""Subchecker of check_py_format. Checks python file formats with black"""
# Folks have been bitten by accidentally using multiple formatter
# versions in the past. This is an issue, since newer versions of
# black may format things differently. Make the version obvious.
- command = [black, "--version"]
+ command: Command = [black, "--version"]
exit_code, stdout_and_stderr = run_command_unchecked(
command, cwd=toolchain_utils_root
)
@@ -194,7 +311,7 @@ def check_black(
)
black_version = stdout_and_stderr.strip()
- black_invocation: t.List[str] = [str(black), "--line-length=80"]
+ black_invocation: List[str] = [str(black), "--line-length=80"]
command = black_invocation + ["--check"] + list(python_files)
exit_code, stdout_and_stderr = run_command_unchecked(
command, cwd=toolchain_utils_root
@@ -256,7 +373,52 @@ def check_black(
)
-def check_python_file_headers(python_files: t.Iterable[str]) -> CheckResult:
+def check_mypy(
+ toolchain_utils_root: str,
+ mypy: MyPyInvocation,
+ files: Iterable[str],
+) -> CheckResult:
+ """Checks type annotations using mypy."""
+ fixed_env = env_with_pythonpath(toolchain_utils_root)
+ if mypy.pythonpath_additions:
+ new_pythonpath = (
+ f"{mypy.pythonpath_additions}:{fixed_env['PYTHONPATH']}"
+ )
+ fixed_env["PYTHONPATH"] = new_pythonpath
+
+ # Show the version number, mainly for troubleshooting purposes.
+ cmd = mypy.command + ["--version"]
+ exit_code, output = run_command_unchecked(
+ cmd, cwd=toolchain_utils_root, env=fixed_env
+ )
+ if exit_code:
+ return CheckResult(
+ ok=False,
+ output=f"Failed getting mypy version; stdstreams: {output}",
+ autofix_commands=[],
+ )
+ # Prefix output with the version information.
+ prefix = f"Using {output.strip()}, "
+
+ cmd = mypy.command + ["--follow-imports=silent"] + list(files)
+ exit_code, output = run_command_unchecked(
+ cmd, cwd=toolchain_utils_root, env=fixed_env
+ )
+ if exit_code == 0:
+ return CheckResult(
+ ok=True,
+ output=f"{output}{prefix}checks passed",
+ autofix_commands=[],
+ )
+ else:
+ return CheckResult(
+ ok=False,
+ output=f"{output}{prefix}type errors were found",
+ autofix_commands=[],
+ )
+
+
+def check_python_file_headers(python_files: Iterable[str]) -> CheckResult:
"""Subchecker of check_py_format. Checks python #!s"""
add_hashbang = []
remove_hashbang = []
@@ -303,8 +465,8 @@ def check_python_file_headers(python_files: t.Iterable[str]) -> CheckResult:
def check_py_format(
toolchain_utils_root: str,
thread_pool: multiprocessing.pool.ThreadPool,
- files: t.Iterable[str],
-) -> t.List[CheckResult]:
+ files: Iterable[str],
+) -> CheckResults:
"""Runs black on files to check for style bugs. Also checks for #!s."""
black = "black"
if not has_executable_on_path(black):
@@ -344,15 +506,83 @@ def check_py_format(
return [(name, get_check_result_or_catch(task)) for name, task in tasks]
-def find_chromeos_root_directory() -> t.Optional[str]:
+def file_is_relative_to(file: Path, potential_parent: Path) -> bool:
+ """file.is_relative_to(potential_parent), but for Python < 3.9."""
+ try:
+ file.relative_to(potential_parent)
+ return True
+ except ValueError:
+ return False
+
+
+def is_file_in_any_of(file: Path, files_and_dirs: List[Path]) -> bool:
+ """Returns whether `files_and_dirs` encompasses `file`.
+
+ `files_and_dirs` is considered to encompass `file` if `files_and_dirs`
+ contains `file` directly, or if it contains a directory that is a parent of
+ `file`.
+
+ Args:
+ file: a path to check
+ files_and_dirs: a list of directories to check
+ """
+ # This could technically be made sublinear, but it's running at most a few
+ # dozen times on a `files_and_dirs` that's currently < 10 elems.
+ return any(
+ file == x or file_is_relative_to(file, x) for x in files_and_dirs
+ )
+
+
+def check_py_types(
+ toolchain_utils_root: str,
+ thread_pool: multiprocessing.pool.ThreadPool,
+ files: Iterable[str],
+) -> CheckResults:
+ """Runs static type checking for files in MYPY_CHECKED_FILES."""
+ path_root = Path(toolchain_utils_root)
+ check_locations = [path_root / x for x in MYPY_CHECKED_PATHS]
+ to_check = [
+ x
+ for x in files
+ if x.endswith(".py") and is_file_in_any_of(Path(x), check_locations)
+ ]
+
+ if not to_check:
+ return CheckResult(
+ ok=True,
+ output="no python files to typecheck",
+ autofix_commands=[],
+ )
+
+ mypy = get_mypy()
+ if not mypy:
+ return CheckResult(
+ ok=False,
+ output="mypy not found. Please either enter a chroot "
+ "or install mypy",
+ autofix_commands=[],
+ )
+
+ tasks = [
+ (
+ "check_mypy",
+ thread_pool.apply_async(
+ check_mypy, (toolchain_utils_root, mypy, to_check)
+ ),
+ ),
+ ]
+ return [(name, get_check_result_or_catch(task)) for name, task in tasks]
+
+
+def find_chromeos_root_directory() -> Optional[str]:
return os.getenv("CHROMEOS_ROOT_DIRECTORY")
def check_cros_lint(
toolchain_utils_root: str,
thread_pool: multiprocessing.pool.ThreadPool,
- files: t.Iterable[str],
-) -> t.Union[t.List[CheckResult], CheckResult]:
+ files: Iterable[str],
+) -> CheckResults:
"""Runs `cros lint`"""
fixed_env = env_with_pythonpath(toolchain_utils_root)
@@ -360,9 +590,9 @@ def check_cros_lint(
# We have to support users who don't have a chroot. So we either run `cros
# lint` (if it's been made available to us), or we try a mix of
# pylint+golint.
- def try_run_cros_lint(cros_binary: str) -> t.Optional[CheckResult]:
+ def try_run_cros_lint(cros_binary: str) -> Optional[CheckResult]:
exit_code, output = run_command_unchecked(
- [cros_binary, "lint", "--"] + files,
+ [cros_binary, "lint", "--"] + list(files),
toolchain_utils_root,
env=fixed_env,
)
@@ -392,7 +622,7 @@ def check_cros_lint(
tasks = []
- def check_result_from_command(command: t.List[str]) -> CheckResult:
+ def check_result_from_command(command: List[str]) -> CheckResult:
exit_code, output = run_command_unchecked(
command, toolchain_utils_root, env=fixed_env
)
@@ -503,10 +733,41 @@ def check_go_format(toolchain_utils_root, _thread_pool, files):
)
+def check_no_compiler_wrapper_changes(
+ toolchain_utils_root: str,
+ _thread_pool: multiprocessing.pool.ThreadPool,
+ files: List[str],
+) -> CheckResult:
+ compiler_wrapper_prefix = (
+ os.path.join(toolchain_utils_root, "compiler_wrapper") + "/"
+ )
+ if not any(x.startswith(compiler_wrapper_prefix) for x in files):
+ return CheckResult(
+ ok=True,
+ output="no compiler_wrapper changes detected",
+ autofix_commands=[],
+ )
+
+ return CheckResult(
+ ok=False,
+ autofix_commands=[],
+ output=textwrap.dedent(
+ """\
+ Compiler wrapper changes should be made in chromiumos-overlay.
+ If you're a CrOS toolchain maintainer, please make the change
+ directly there now. If you're contributing as part of a downstream
+ (e.g., the Android toolchain team), feel free to bypass this check
+ and note to your reviewer that you received this message. They can
+ review your CL and commit to the right plate for you. Thanks!
+ """
+ ).strip(),
+ )
+
+
def check_tests(
toolchain_utils_root: str,
_thread_pool: multiprocessing.pool.ThreadPool,
- files: t.List[str],
+ files: List[str],
) -> CheckResult:
"""Runs tests."""
exit_code, stdout_and_stderr = run_command_unchecked(
@@ -526,9 +787,9 @@ def detect_toolchain_utils_root() -> str:
def process_check_result(
check_name: str,
- check_results: t.Union[t.List[CheckResult], CheckResult],
+ check_results: CheckResults,
start_time: datetime.datetime,
-) -> t.Tuple[bool, t.List[t.List[str]]]:
+) -> Tuple[bool, List[List[str]]]:
"""Prints human-readable output for the given check_results."""
indent = " "
@@ -581,7 +842,7 @@ def process_check_result(
def try_autofix(
- all_autofix_commands: t.List[t.List[str]], toolchain_utils_root: str
+ all_autofix_commands: List[List[str]], toolchain_utils_root: str
) -> None:
"""Tries to run all given autofix commands, if appropriate."""
if not all_autofix_commands:
@@ -623,7 +884,7 @@ def try_autofix(
)
-def find_repo_root(base_dir: str) -> t.Optional[str]:
+def find_repo_root(base_dir: str) -> Optional[str]:
current = base_dir
while current != "/":
if os.path.isdir(os.path.join(current, ".repo")):
@@ -636,7 +897,7 @@ def is_in_chroot() -> bool:
return os.path.exists("/etc/cros_chroot_version")
-def maybe_reexec_inside_chroot(autofix: bool, files: t.List[str]) -> None:
+def maybe_reexec_inside_chroot(autofix: bool, files: List[str]) -> None:
if is_in_chroot():
return
@@ -693,27 +954,29 @@ def maybe_reexec_inside_chroot(autofix: bool, files: t.List[str]) -> None:
os.execvp(args[0], args)
+def can_import_py_module(module: str) -> bool:
+ """Returns true if `import {module}` works."""
+ exit_code = subprocess.call(
+ ["python3", "-c", f"import {module}"],
+ stdout=subprocess.DEVNULL,
+ stderr=subprocess.DEVNULL,
+ )
+ return exit_code == 0
+
+
def ensure_pip_deps_installed() -> None:
if not PIP_DEPENDENCIES:
# No need to install pip if we don't have any deps.
return
- if not has_executable_on_path("pip"):
- print("Autoinstalling `pip`...")
- subprocess.check_call(["sudo", "emerge", "dev-python/pip"])
+ pip = get_pip()
+ assert pip, "pip not found and could not be installed"
for package in PIP_DEPENDENCIES:
- exit_code = subprocess.call(
- ["python3", "-c", f"import {package}"],
- stdout=subprocess.DEVNULL,
- stderr=subprocess.DEVNULL,
- )
- if exit_code != 0:
- print(f"Autoinstalling `{package}`...")
- subprocess.check_call(["pip", "install", "--user", package])
+ subprocess.check_call(pip + ["install", "--user", package])
-def main(argv: t.List[str]) -> int:
+def main(argv: List[str]) -> int:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--no_autofix",
@@ -746,12 +1009,14 @@ def main(argv: t.List[str]) -> int:
# Note that we extract .__name__s from these, so please name them in a
# user-friendly way.
- checks = [
+ checks = (
check_cros_lint,
check_py_format,
+ check_py_types,
check_go_format,
check_tests,
- ]
+ check_no_compiler_wrapper_changes,
+ )
toolchain_utils_root = detect_toolchain_utils_root()
@@ -770,8 +1035,6 @@ def main(argv: t.List[str]) -> int:
print("*** Spawning %s" % name)
return name, check_fn(toolchain_utils_root, pool, files)
- # ThreadPool is a ContextManager in py3.
- # pylint: disable=not-context-manager
with multiprocessing.pool.ThreadPool(num_threads) as pool:
all_checks_ok = True
all_autofix_commands = []