You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
595 lines
16 KiB
595 lines
16 KiB
# LLVM Tools
|
|
|
|
## Overview
|
|
|
|
These scripts helps automate tasks such as updating the LLVM next hash,
|
|
determing whether a new patch applies correctly, and patch management.
|
|
|
|
In addition, there are scripts that automate the process of retrieving the
|
|
git hash of LLVM from either google3, top of trunk, or for a specific SVN
|
|
version.
|
|
|
|
**NOTE: All scripts must must be run outside the chroot**
|
|
|
|
**NOTE: sudo must be permissive (i.e. **`cros_sdk`** should NOT prompt for a
|
|
password)**
|
|
|
|
## `update_packages_and_run_tests.py`
|
|
|
|
### Usage
|
|
|
|
This script is used for updating a package's LLVM hash (sys-devel/llvm,
|
|
sys-libs/compiler-rt, sys-libs/libcxx, sys-libs/libcxxabi, and
|
|
sys-libs/llvm-libunwind) and then run tests after updating the git hash.
|
|
There are three ways to test the change, including starting tryjobs,
|
|
recipe builders or using cq+1.
|
|
|
|
An example when this script should be run is when certain boards would like
|
|
to be tested with the updated `LLVM_NEXT_HASH`.
|
|
|
|
For example:
|
|
|
|
```
|
|
$ ./update_packages_and_run_tests.py \
|
|
--is_llvm_next \
|
|
--llvm_version tot \
|
|
tryjobs \
|
|
--options nochromesdk latest-toolchain \
|
|
--builders kevin-release-tryjob nocturne-release-tryjob
|
|
```
|
|
|
|
The above example would update the packages' `LLVM_NEXT_HASH` to the top of
|
|
trunk's git hash and would submit tryjobs for kevin and nocturne boards, passing
|
|
in 'nochromesdk' and 'latest-toolchain' for each tryjob.
|
|
|
|
For help with the command line arguments of the script, run:
|
|
|
|
```
|
|
$ ./update_packages_and_run_tests.py --help
|
|
```
|
|
|
|
Similarly as the previous example, but for updating `LLVM_HASH` to
|
|
google3 and test with cq+1:
|
|
|
|
```
|
|
$ ./update_packages_and_run_tests.py \
|
|
--llvm_version google3 \
|
|
cq
|
|
```
|
|
|
|
Similarly as the previous example, but for updating `LLVM_NEXT_HASH` to
|
|
the git hash of revision 367622 and test with recipe builders:
|
|
|
|
```
|
|
$ ./update_packages_and_run_tests.py \
|
|
--is_llvm_next \
|
|
--llvm_version 367622 \
|
|
recipe \
|
|
--options -nocanary \
|
|
--builders chromeos/toolchain/kevin-llvm chromeos/toolchain/nocturne-llvm
|
|
```
|
|
|
|
## `update_chromeos_llvm_hash.py`
|
|
|
|
### Usage
|
|
|
|
This script is used for updating a package's/packages' LLVM hashes and
|
|
creating a change list of those changes which will uploaded for review. For
|
|
example, some changes that would be included in the change list are
|
|
the updated ebuilds, changes made to the patches of the updated packages such
|
|
as being removed or an updated patch metadata file. These changes are determined
|
|
by the `--failure_mode` option.
|
|
|
|
An example where this script would be used is when multiple packages need to
|
|
have their `LLVM_NEXT_HASH` updated.
|
|
|
|
For example:
|
|
|
|
```
|
|
$ ./update_chromeos_llvm_hash.py \
|
|
--update_packages sys-devel/llvm sys-libs/compiler-rt \
|
|
--is_llvm_next \
|
|
--llvm_version google3 \
|
|
--failure_mode disable_patches
|
|
```
|
|
|
|
The example above would update sys-devel/llvm and sys-libs/compiler-rt's
|
|
`LLVM_NEXT_HASH` to the latest google3's git hash of LLVM. And the change list
|
|
may include patches that were disabled for either sys-devel/llvm or
|
|
sys-libs/compiler-rt.
|
|
|
|
For help with the command line arguments of the script, run:
|
|
|
|
```
|
|
$ ./update_chromeos_llvm_hash.py --help
|
|
```
|
|
|
|
For example, to update `LLVM_HASH` to top of trunk of LLVM:
|
|
|
|
```
|
|
$ ./update_chromeos_llvm_hash.py \
|
|
--update_packages sys-devel/llvm sys-libs/compiler-rt \
|
|
--llvm_version tot \
|
|
--failure_mode disable_patches
|
|
```
|
|
|
|
For example, to create a roll CL to the git hash of revision 367622:
|
|
|
|
```
|
|
$ ./update_chromeos_llvm_hash.py \
|
|
--update_packages sys-devel/llvm sys-libs/compiler-rt \
|
|
sys-libs/libcxx sys-libs/libcxxabi sys-libs/llvm-libunwind \
|
|
--llvm_version 367622 \
|
|
--failure_mode disable_patches
|
|
```
|
|
|
|
## `llvm_patch_management.py`
|
|
|
|
### Usage
|
|
|
|
This script is used to test whether a newly added patch in a package's patch
|
|
metadata file would apply successfully. The script is also used to make sure
|
|
the patches of a package applied successfully, failed, etc., depending on the
|
|
failure mode specified.
|
|
|
|
An example of using this script is when multiple packages would like to be
|
|
tested when a new patch was added to their patch metadata file.
|
|
|
|
For example:
|
|
|
|
```
|
|
$ ./llvm_patch_management.py \
|
|
--packages sys-devel/llvm sys-libs/compiler-rt \
|
|
--failure_mode continue
|
|
```
|
|
|
|
The above example tests sys-devel/llvm and sys-libs/compiler-rt patch metadata
|
|
file with the failure mode `continue`.
|
|
|
|
For help with the command line arguments of the script, run:
|
|
|
|
```
|
|
$ ./llvm_patch_management.py --help
|
|
```
|
|
|
|
## `patch_manager.py`
|
|
|
|
### Usage
|
|
|
|
This script is used when when all the command line arguments are known such as
|
|
testing a specific metadata file or a specific source tree.
|
|
|
|
For help with the command line arguments of the script, run:
|
|
|
|
```
|
|
$ ./patch_manager.py --help
|
|
```
|
|
|
|
For example, to see all the failed (if any) patches:
|
|
|
|
```
|
|
$ ./patch_manager.py \
|
|
--svn_version 367622 \
|
|
--patch_metadata_file /abs/path/to/patch/file \
|
|
--filesdir_path /abs/path/to/$FILESDIR \
|
|
--src_path /abs/path/to/src/tree \
|
|
--failure_mode continue
|
|
```
|
|
|
|
For example, to disable all patches that failed to apply:
|
|
|
|
```
|
|
$ ./patch_manager.py \
|
|
--svn_version 367622 \
|
|
--patch_metadata_file /abs/path/to/patch/file \
|
|
--filesdir_path /abs/path/to/$FILESDIR \
|
|
--src_path /abs/path/to/src/tree \
|
|
--failure_mode disable_patches
|
|
```
|
|
|
|
For example, to remove all patches that no longer apply:
|
|
|
|
```
|
|
$ ./patch_manager.py \
|
|
--svn_version 367622 \
|
|
--patch_metadata_file /abs/path/to/patch/file \
|
|
--filesdir_path /abs/path/to/$FILESDIR \
|
|
--src_path /abs/path/to/src/tree \
|
|
--failure_mode remove_patches
|
|
```
|
|
|
|
For example, to bisect a failing patch and stop at the first bisected patch:
|
|
|
|
```
|
|
$ ./patch_manager.py \
|
|
--svn_version 367622 \
|
|
--patch_metadata_file /abs/path/to/patch/file \
|
|
--filesdir_path /abs/path/to/$FILESDIR \
|
|
--src_path /abs/path/to/src/tree \
|
|
--failure_mode bisect_patches \
|
|
--good_svn_version 365631
|
|
```
|
|
|
|
For example, to bisect a failing patch and then continue bisecting the rest of
|
|
the failed patches:
|
|
|
|
```
|
|
$ ./patch_manager.py \
|
|
--svn_version 367622 \
|
|
--patch_metadata_file /abs/path/to/patch/file \
|
|
--filesdir_path /abs/path/to/$FILESDIR \
|
|
--src_path /abs/path/to/src/tree \
|
|
--failure_mode bisect_patches \
|
|
--good_svn_version 365631 \
|
|
--continue_bisection True
|
|
```
|
|
|
|
## LLVM Bisection
|
|
|
|
### `llvm_bisection.py`
|
|
|
|
#### Usage
|
|
|
|
This script is used to bisect a bad revision of LLVM. After the script finishes,
|
|
the user requires to run the script again to continue the bisection. Intially,
|
|
the script creates a JSON file that does not exist which then continues
|
|
bisection (after invoking the script again) based off of the JSON file.
|
|
|
|
For example, assuming the revision 369420 is the bad revision:
|
|
|
|
```
|
|
$ ./llvm_bisection.py \
|
|
--parallel 3 \
|
|
--start_rev 369410 \
|
|
--end_rev 369420 \
|
|
--last_tested /abs/path/to/tryjob/file/ \
|
|
--extra_change_lists 513590 \
|
|
--builder eve-release-tryjob \
|
|
--options latest-toolchain
|
|
```
|
|
|
|
The above example bisects the bad revision (369420), starting from the good
|
|
revision 369410 and launching 3 tryjobs in between if possible (`--parallel`).
|
|
Here, the `--last_tested` path is a path to a JSON file that does not exist. The
|
|
tryjobs are tested on the eve board. `--extra_change_lists` and `--options`
|
|
indicate what parameters to pass into launching a tryjob.
|
|
|
|
For help with the command line arguments of the script, run:
|
|
|
|
```
|
|
$ ./llvm_bisection.py --help
|
|
```
|
|
|
|
### `auto_llvm_bisection.py`
|
|
|
|
#### Usage
|
|
|
|
This script automates the LLVM bisection process by using `cros buildresult` to
|
|
update the status of each tryjob.
|
|
|
|
An example when this script would be used to do LLVM bisection overnight
|
|
because tryjobs take very long to finish.
|
|
|
|
For example, assuming the good revision is 369410 and the bad revision is
|
|
369420, then:
|
|
|
|
```
|
|
$ ./auto_llvm_bisection.py --start_rev 369410 --end_rev 369420 \
|
|
--last_tested /abs/path/to/last_tested_file.json \
|
|
--extra_change_lists 513590 1394249 \
|
|
--options latest-toolchain nochromesdk \
|
|
--chroot_path /path/to/chromeos/chroot \
|
|
--builder eve-release-tryjob
|
|
```
|
|
|
|
The example above bisects LLVM between revision 369410 and 369420. If the file
|
|
exists, the script resumes bisection. Otherwise, the script creates the file
|
|
provided by `--last_tested`. `--extra_change_lists` and `--options` are used for
|
|
each tryjob when being submitted. Lastly, the tryjobs are launched for the board
|
|
provided by `--builder` (in this example, for the eve board).
|
|
|
|
For help with the command line arguments of the script, run:
|
|
|
|
```
|
|
$ ./auto_llvm_bisection.py --help
|
|
```
|
|
|
|
### `update_tryjob_status.py`
|
|
|
|
#### Usage
|
|
|
|
This script updates a tryjob's 'status' value when bisecting LLVM. This script
|
|
can use the file that was created by `llvm_bisection.py`.
|
|
|
|
An example when this script would be used is when the result of tryjob that was
|
|
launched was 'fail' (due to flaky infra) but it should really have been
|
|
'success'.
|
|
|
|
For example, to update a tryjob's 'status' to 'good':
|
|
|
|
```
|
|
$ ./update_tryjob_status.py \
|
|
--set_status good \
|
|
--revision 369412 \
|
|
--status_file /abs/path/to/tryjob/file
|
|
```
|
|
|
|
The above example uses the file in `--status_file` to update a tryjob in that
|
|
file that tested the revision 369412 and sets its 'status' value to 'good'.
|
|
|
|
For help with the command line arguments of the script, run:
|
|
|
|
```
|
|
$ ./update_tryjob_status.py --help
|
|
```
|
|
|
|
For example, to update a tryjob's 'status' to 'bad':
|
|
|
|
```
|
|
$ ./update_tryjob_status.py \
|
|
--set_status bad \
|
|
--revision 369412 \
|
|
--status_file /abs/path/to/tryjob/file
|
|
```
|
|
|
|
For example, to update a tryjob's 'status' to 'pending':
|
|
|
|
```
|
|
$ ./update_tryjob_status.py \
|
|
--set_status pending \
|
|
--revision 369412 \
|
|
--status_file /abs/path/to/tryjob/file
|
|
```
|
|
|
|
For example, to update a tryjob's 'status' to 'skip':
|
|
|
|
```
|
|
$ ./update_tryjob_status.py \
|
|
--set_status skip \
|
|
--revision 369412 \
|
|
--status_file /abs/path/to/tryjob/file
|
|
```
|
|
|
|
For example, to update a tryjob's 'status' based off a custom script exit code:
|
|
|
|
```
|
|
$ ./update_tryjob_status.py \
|
|
--set_status custom_script \
|
|
--revision 369412 \
|
|
--status_file /abs/path/to/tryjob/file \
|
|
--custom_script /abs/path/to/script.py
|
|
```
|
|
|
|
### `update_all_tryjobs_with_auto.py`
|
|
|
|
#### Usage
|
|
|
|
This script updates all tryjobs that are 'pending' to the result provided by
|
|
`cros buildresult`.
|
|
|
|
For example:
|
|
|
|
```
|
|
$ ./update_all_tryjobs_with_auto.py \
|
|
--last_tested /abs/path/to/last_tested_file.json \
|
|
--chroot_path /abs/path/to/chroot
|
|
```
|
|
|
|
The above example will update all tryjobs whose 'status' is 'pending' in the
|
|
file provided by `--last_tested`.
|
|
|
|
For help with the command line arguments of the script, run:
|
|
|
|
```
|
|
$ ./update_all_tryjobs_with_auto.py --help
|
|
```
|
|
|
|
### `modify_a_tryjob.py`
|
|
|
|
#### Usage
|
|
|
|
This script modifies a tryjob directly given an already created tryjob file when
|
|
bisecting LLVM. The file created by `llvm_bisection.py` can be used in this
|
|
script.
|
|
|
|
An example when this script would be used is when a tryjob needs to be manually
|
|
added.
|
|
|
|
For example:
|
|
|
|
```
|
|
$ ./modify_a_tryjob.py \
|
|
--modify_a_tryjob add \
|
|
--revision 369416 \
|
|
--extra_change_lists 513590 \
|
|
--options latest-toolchain \
|
|
--builder eve-release-tryjob \
|
|
--status_file /abs/path/to/tryjob/file
|
|
```
|
|
|
|
The above example creates a tryjob that tests revision 369416 on the eve board,
|
|
passing in the extra arguments (`--extra_change_lists` and `--options`). The
|
|
tryjob is then inserted into the file passed in via `--status_file`.
|
|
|
|
For help with the command line arguments of the script, run:
|
|
|
|
```
|
|
$ ./modify_a_tryjob.py --help
|
|
```
|
|
|
|
For example, to remove a tryjob that tested revision 369412:
|
|
|
|
```
|
|
$ ./modify_a_tryjob.py \
|
|
--modify_a_tryjob remove \
|
|
--revision 369412 \
|
|
--status_file /abs/path/to/tryjob/file
|
|
```
|
|
|
|
For example, to relaunch a tryjob that tested revision 369418:
|
|
|
|
```
|
|
$ ./modify_a_tryjob.py \
|
|
--modify_a_tryjob relaunch \
|
|
--revision 369418 \
|
|
--status_file /abs/path/to/tryjob/file
|
|
```
|
|
|
|
## Other Helpful Scripts
|
|
|
|
### `get_llvm_hash.py`
|
|
|
|
#### Usage
|
|
|
|
The script has a class that deals with retrieving either the top of trunk git
|
|
hash of LLVM, the git hash of google3, or a specific git hash of a SVN version.
|
|
It also has other functions when dealing with a git hash of LLVM.
|
|
|
|
In addition, it has a function to retrieve the latest google3 LLVM version.
|
|
|
|
For example, to retrieve the top of trunk git hash of LLVM:
|
|
|
|
```
|
|
from get_llvm_hash import LLVMHash
|
|
|
|
LLVMHash().GetTopOfTrunkGitHash()
|
|
```
|
|
|
|
For example, to retrieve the git hash of google3:
|
|
|
|
```
|
|
from get_llvm_hash import LLVMHash
|
|
|
|
LLVMHash().GetGoogle3LLVMHash()
|
|
```
|
|
|
|
For example, to retrieve the git hash of a specific SVN version:
|
|
|
|
```
|
|
from get_llvm_hash import LLVMHash
|
|
|
|
LLVMHash().GetLLVMHash(<svn_version>)
|
|
```
|
|
|
|
For example, to retrieve the latest google3 LLVM version:
|
|
|
|
```
|
|
from get_llvm_hash import GetGoogle3LLVMVersion
|
|
|
|
GetGoogle3LLVMVersion(stable=True)
|
|
```
|
|
|
|
### `git_llvm_rev.py`
|
|
|
|
This script is meant to synthesize LLVM revision numbers, and translate between
|
|
these synthesized numbers and git SHAs. Usage should be straightforward:
|
|
|
|
```
|
|
~> ./git_llvm_rev.py --llvm_dir llvm-project-copy/ --rev r380000
|
|
6f635f90929da9545dd696071a829a1a42f84b30
|
|
~> ./git_llvm_rev.py --llvm_dir llvm-project-copy/ --sha 6f635f90929da9545dd696071a829a1a42f84b30
|
|
r380000
|
|
~> ./git_llvm_rev.py --llvm_dir llvm-project-copy/ --sha origin/some-branch
|
|
r387778
|
|
```
|
|
|
|
**Tip**: if you put a symlink called `git-llvm-rev` to this script somewhere on
|
|
your `$PATH`, you can also use it as `git llvm-rev`.
|
|
|
|
### `cherrypick_cl.py`
|
|
|
|
#### Usage
|
|
|
|
This script updates the proper ChromeOS packages with an LLVM cherrypick of your choosing, and
|
|
copies the cherrypick into patch folders of the packages.
|
|
|
|
Usage:
|
|
|
|
```
|
|
./cherrypick_cl.py --chroot_path /abs/path/to/chroot --start_sha llvm
|
|
--sha 174c3eb69f19ff2d6a3eeae31d04afe77e62c021 --sha 174c3eb69f19ff2d6a3eeae31d04afe77e62c021
|
|
```
|
|
|
|
It tries to autodetect a lot of things (e.g., packages changed by each sha,
|
|
their ebuild paths, the "start"/"end" revisions to set, etc.) By default the
|
|
script creates a local patch. Use --create_cl option to create a CL instead. For
|
|
more information, please see the `--help`
|
|
|
|
### `revert_checker.py`
|
|
|
|
This script reports reverts which happen 'across' a certain LLVM commit.
|
|
|
|
To clarify the meaning of 'across' with an example, if we had the following
|
|
commit history (where `a -> b` notes that `b` is a direct child of `a`):
|
|
|
|
123abc -> 223abc -> 323abc -> 423abc -> 523abc
|
|
|
|
And where 423abc is a revert of 223abc, this revert is considered to be 'across'
|
|
323abc. More generally, a revert A of a parent commit B is considered to be
|
|
'across' a commit C if C is a parent of A and B is a parent of C.
|
|
|
|
Usage example:
|
|
|
|
```
|
|
./revert_checker.py -C llvm-project-copy 123abc 223abc 323abc
|
|
```
|
|
|
|
In the above example, the tool will scan all commits between 123abc and 223abc,
|
|
and all commits between 123abc and 323abc for reverts of commits which are
|
|
parents of 123abc.
|
|
|
|
### `nightly_revert_checker.py`
|
|
|
|
This is an automated wrapper around `revert_checker.py`. It checks to see if any
|
|
new reverts happened across toolchains that we're trying to ship since it was
|
|
last run. If so, it sends emails to appropriate groups.
|
|
|
|
Usage example:
|
|
```
|
|
PYTHONPATH=../ ./nightly_revert_checker.py \
|
|
--state_file state.json \
|
|
--llvm_dir llvm-project-copy \
|
|
--chromeos_dir ../../../../
|
|
```
|
|
|
|
### `bisect_clang_crashes.py`
|
|
|
|
This script downloads clang crash diagnoses from
|
|
gs://chromeos-toolchain-artifacts/clang-crash-diagnoses and sends them to 4c for
|
|
bisection.
|
|
|
|
Usage example:
|
|
|
|
```
|
|
$ ./bisect_clang_crashes.py --4c 4c-cli --state_file ./output/state.json
|
|
```
|
|
|
|
The above command downloads the artifacts of clang crash diagnoses and send them
|
|
to 4c server for bisection. The summary of submitted jobs will be saved in
|
|
output/state.json under the current path. The output directory will be created
|
|
automatically if it does not exist yet. To get more information of the submitted
|
|
jobs, please refer to go/4c-cli.
|
|
|
|
### `upload_lexan_crashes_to_forcey.py`
|
|
|
|
This script downloads clang crash diagnoses from Lexan's bucket and sends them
|
|
to 4c for bisection.
|
|
|
|
Usage example:
|
|
|
|
```
|
|
$ ./upload_lexan_crashes_to_forcey.py --4c 4c-cli \
|
|
--state_file ./output/state.json
|
|
```
|
|
|
|
The above command downloads the artifacts of clang crash diagnoses and send them
|
|
to 4c server for bisection. The summary of submitted jobs will be saved in
|
|
output/state.json under the current path. The output directory will be created
|
|
automatically if it does not exist yet. To get more information of the submitted
|
|
jobs, please refer to go/4c-cli.
|
|
|
|
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.
|