tree: 34e584a95e9263eef2bc10e91ba896eda1212b6c [path history] [tgz]
  1. avd/
  2. ci/
  3. coverage/
  4. docs/
  5. expander/
  6. external/
  7. jarjar/
  8. lnzipper/
  9. maven/
  10. native/
  11. perfetto_cfg/
  12. platforms/
  13. qa/
  14. rbe/
  15. sdk/
  16. shell/
  17. src/
  18. test/
  19. testSrc/
  20. toolchains/
  21. validations/
  22. android.bzl
  23. android.sdktools.base.bazel.iml
  24. aosp_studio_linux.sh
  25. bazel
  26. bazel.bzl
  27. bazel.cmd
  28. BUILD
  29. common.bazelrc
  30. coverage.bzl
  31. diff.bzl
  32. emulator.bzl
  33. expand_template.bzl
  34. functions.bzl
  35. gradle.bzl
  36. jarjar_rules.txt
  37. java.bzl
  38. jvm_import.bzl
  39. kotlin.bzl
  40. lint.bzl
  41. maven.bzl
  42. merge_archives.bzl
  43. OWNERS
  44. perfgate_linux.sh
  45. perfgate_win.cmd
  46. platform_specific.bazelrc
  47. proto.bzl
  48. qa_emu_setup.py
  49. README.md
  50. repositories.bzl
  51. robolectric.bzl
  52. stats.sh
  53. status_reader.py
  54. status_reader_test.py
  55. studio_coverage.sh
  56. studio_linux.sh
  57. studio_linux_k2.sh
  58. studio_mac.sh
  59. studio_mac_arm.sh
  60. studio_win.cmd
  61. targets
  62. targets.win
  63. tools.BUILD.bazel
  64. toplevel.bazelignore
  65. toplevel.bazelrc
  66. toplevel.bazelversion
  67. toplevel.WORKSPACE
  68. utils.bzl
  69. vendor.bzl
  70. workspace.py
bazel/README.md

Building and Testing with Bazel

This directory contains the core files to run studio-main tests using bazel.

Warning: This does not currently work for AOSP Issue 126764883. The required binaries are checked in as prebuilts, so you can run tests using Intellij (tools/base and tools/idea projects), Ant (Studio only) and Gradle (Build system and command line tools).

Running bazel

Bazel has the concept of a workspace: the root of all your source files. For us, it is where we repo init our source tree. For google3 vets, this is the “google3” directory. In this document we assume the current directory to be the workspace, but note that bazel can be run from anywhere in the tree.

Bazel is checked-in at tools/base/bazel/bazel. To make things easy you might want to link it like this (assuming ~/bin is in $PATH)

ln -s <workspace>/tools/base/bazel ~/bin/bazel

Then no matter where you are in the workspace, bazel will find the right platform-specific binary and run it.

macOS users:_ You may run into a clang error after reinstalling or updating XCode. To resolve this error, clear bazel of previous configurations with the following command:

$ bazel clean --expunge

Running all the tests

The command to run all the bazel tests run by the PSQ is:

bazel test $(<tools/base/bazel/targets)

The test output is typically present in bazel-testlogs/pkg/target/test.xml (or test.log)

To run all the tests found in tools/base:

bazel test //tools/base/...

To run all the tests in the IntelliJ Android plugin:

bazel test //tools/adt/idea/android/...

Note: The file tools/base/bazel/targets contains the up-to-date list of test targets.

To build Studio without running the tests:

bazel build //tools/adt/idea/...

To run a single test:

# when test splitting is used, specify the $moduleName_tests__all target
bazel test //tools/adt/idea/android:intellij.android.core.tests_tests__all --test_filter=AndroidLayoutDomTest --test_output=streamed

To debug a single test, which will open remote debugging:

bazel test //tools/adt/idea/android:intellij.android.core.tests_tests__all --test_filter=AndroidLayoutDomTest --java_debug

Useful Bazel options

  • --nocache_test_results may be required if you are trying to re-run a test without changing anything.
  • --test_filter=<TestName> to run a specific test (when test splits are not already in use)

Running with coverage

We currently do not use the in-built Bazel coverage support.

To enable a test in coverage runs do the following:

  1. If you used java_test, then you need to replace it with coverage_java_test from //tools/base/bazel:coverage.bzl
  2. Add the test target to the “all” coverage_report in tools/base/bazel/coverage/BUILD for inclusion in overall coverage
  3. (Optional) Create your own coverage_report target in tools/base/bazel/coverage/BUILD for your team/feature

To build a coverage report do: ./tools/base/bazel/coverage/report.sh

BUILD files

BUILD files define a package with a set build and test rules. In order to support Android Studio we created a new kind of rule, that matches an IntelliJ module: the iml_module rule.

Note that we modify these BUILD files manually, so whenever you make a change to an .iml file, its corresponding BUILD file will have to be changed. This should be done using bazel run //tools/base/bazel:iml_to_build. If you create a new .iml file, you must create the corresponding (empty) BUILD file before running iml_to_build.

iml_module

iml_module(name, srcs, test_srcs, exclude, resources, test_resources, deps, test_runtime_deps,
visibility, exports,javacopts, test_data, test_timeout, test_class, test_shard_count, tags)

This rule will generate the targets:

  • name: The production library for this module.
  • name_testlib: The test library for this module.
  • name_tests: The test target to run this module's tests.

Example

iml_module(
    name = "android",
    srcs = ["src/main/java"],
    resources = ["src/main/resources"],
    test_data = glob(["testData/**"]),
    test_resources = ["src/test/resources"],
    test_srcs = ["src/test/java"],
    deps = [
        "//a/module/only/needed/in/tests:name[module, test]",
        "//a/standard/java/dependency:dep",
        "//path/to/libs:junit-4.12[test]",
        "//path/to/module:name[module]",
    ],
)
AttributeDescription
nameThe name of the rule (usually matching Studio's module name).
srcsA list of directories containing the sources. .java, .groovy, .kotlin and .form files are supported.
resourcesA list directories with the production resources.
depsA tag-enhanced list of dependencies, of the form //label[tag1,tag2,...]. Supported tags are: module, for iml_module dependencies, and test for test only dependencies.
test_srcsA list of directories with the test sources.
test_resourcesA list of directories with the test resources.
test_dataA list of files needed to run the test.
excludeA list of files to be excluded from both src and test_srcs. This requires a change to tools/idea/.idea/compiler.xml
test_timeoutThe timeout value of the test, see: blaze timeout

A major difference with actual iml modules is that in bazel we must specify the files needed to run the tests. These files are known as runfiles and are specified via the test_data attribute. This is essential to determining which test targets need to be run when an arbitrary file has changed.

More details on the implementation of the iml_module rule can be found in docs/iml-module.md.

Circular Dependencies

Just don't. IntelliJ has support for circular dependencies of modules, but we do not use it in our code base.

Fetching new Maven Dependencies

In order to fetch new Maven artifacts into the local Maven repository under //prebuilts/tools/common/m2/, follow these steps:

  1. Add the dependency to the ARTIFACTS or DATA in the tools/base/bazel/maven/artifacts.bzl file.
  • In most cases, it should be added to DATA. For instance, if the artifact is only used in the data section of rules (e.g., it's used as a Gradle dependency artifact in tests), or if the artifact is going to be used to build Android Studio (i.e., added to an IntelliJ IDEA library either in .idea/libraries/*.xml, or an inline library in *.iml files), then use DATA. Note that the Android Studio build case requires running iml_to_build which generates a java_import rule that wraps the files listed in the library.

  • If you need to use the artifact directly in the deps or runtime_deps section of a (maven|kotlin|java)_library rule, then add it to ARTIFACTS. This will bring the artifact, and all of its transitive depdendencies to the Java classpath of such rules that depend on it.

  1. Use the following script to download the artifacts and update the BUILD.maven file.

Note that it's worth checking that your prebuilts/tools/common/m2/repository is clean before you start. You can clean it with git clean -fdx

tools/base/bazel/maven/maven_fetch.sh
  1. In order to use the new artifact, use @maven//: prefix. If you added your artifact to artifacts, then do not add the artifact version, if you added your artifact to data, then use the artifact version. E.g., @maven//:com.google.guava.guava" (for artifacts) @maven//:com.google.guava.guava_30.1-jre` (for data).

    • The @maven// prefix points to a dynamically generated Bazel-external repository. You can access the generated file at $REPO/bazel-studio-main/external/maven/BUILD.
  2. Check-in your new artifact (and any new transitive dependencies) under //prebuilts/tools/common/m2/.

  3. Check-in generated changes to the tools/base/bazel/maven/BUILD.maven file.

If you are making changes to the list of artifacts, it is also useful to run tools/base/bazel/maven/maven_clean.sh as well to ensure that unused dependencies are removed and the prebuilts are cleaned up before uploading.

See the toplevel.WORKSPACE file for examples on how to express non-jar dependency types and classifiers (e.g., linux-x86_64).

Updating Library Versions

Find the existing library in tools/base/bazel/maven/artifacts.bzl and update it to the new version.

For some dependencies (those used by AGP) you'll also need to go and update tools/buildSrc/base/dependencies.properties.

Then run tools/base/bazel/maven/maven_fetch.sh to download the libraries into prebuilts. This will update tools/base/bazel/maven/BUILD.maven.

You'll now need to go and update any hardcoded references to the old version. This can include xml files in .idea/libraries and .iml files. After this, you may want to also run bazel run //tools/base/bazel:iml_to_build.

For some libraries there may also be a few other things to think of:

  • If the download contains executables to be executed directly by the build (such as the proto compiler), go and chmod +x the files; the script doesn't do that.)

  • For the protobuf-java library, you'll need to go and also extract the .proto files from within the dependency jar and place them in an include/ folder; see the previous version of the library for an example.

You may also want to delete the previous version of the library from the prebuilts. To do that, first remove the corresponding entries from the BUILD.maven script, and then run the maven_fetch.sh script again. If that brings the binaries back, they're needed by a transitive dependency.