This doc aims to describe the Chrome build process that takes a set of .java
files and turns them into a classes.dex
file.
The following have supports_android
and requires_android
set to false by default:
java_library()
: Compiles .java
-> .jar
java_prebuilt()
: Imports a prebuilt .jar
file.The following have supports_android
and requires_android
set to true. They also have a default jar_excluded_patterns
set (more on that later):
android_library()
android_java_prebuilt()
All target names must end with “_java” so that the build system can distinguish them from non-java targets (or other variations).
Most targets produce two separate .jar
files:
.jar
: Used to produce .dex.jar
, which is used on-device..jar
: For use on the host machine (junit_binary
/ java_binary
)..jar
files live in lib.java/
so that they are archived in builder/tester bots (which do not archive obj/
).What are interface jars?:
.class
files with all private symbols and all method bodies removed..jar
files to skip having to be rebuilt when only private implementation details change.For prebuilt .jar
files: we use //third_party/ijar to create interface .jar
files from the prebuilt ones.
For non-prebuilt .jar
files: we use [//third_party/turbine] to create interface
.jarfiles directly from
.javasource files. Turbine is faster than javac because it does not compile method bodies. Although Turbine causes us to compile files twice, it speeds up builds by allowing
javac` compilation of targets to happen concurrently with their dependencies. We also use Turbine to run our annotation processors.
This step is the only step that does not apply to prebuilt targets.
.java
files in a target are compiled by javac
into .class
files..java
files that live within .srcjar
files, referenced through srcjar_deps
.classpath
used when compiling a target is comprised of .jar
files of its deps..jar
file is used..jar
file is used..jar
processing done in subsequent steps does not impact compilation classpath..class
files are zipped into an output .jar
file.This step can be disabled via GN arg: use_errorprone_java_compiler = false
This step happens only when targets have supports_android = true
. It is not applied to .jar
files used by junit_binary
.
//third_party/bazel/desugar
converts certain Java 8 constructs, such as lambdas and default interface methods, into constructs that are compatible with Java 7.This step happens only when this GN arg is set: use_jacoco_coverage = true
This step happens only when targets that have jar_excluded_patterns
or jar_included_patterns
set (e.g. all android_
targets).
.class
files that match the filters from the .jar
. These .class
files are generally those that are re-created with different implementations further on in the build process.R.class
files - a part of Android Resources.GEN_JNI.class
- a part of our JNI glue.AppHooksImpl.class
- how chrome_java
wires up different implementations for non-public builds.This step happens only when targets have supports_android = true
.
.jar
files containing .class
files into .dex.jar
files containing classes.dex
files..class
file is unchanged..dex.jar
files are used directly by incremental install, and are inputs to the Apk step when enable_proguard = false
.is_java_debug = false
, many apk targets do not enable ProGuard (e.g. unit tests).android_apk
and android_bundle_module
template has a nested java_library
target. The nested library includes final copies of files stripped out by prior filtering steps. These files include:R.java
files, created by compile_resources.py
.GEN_JNI.java
for JNI glue.BuildConfig.java
and NativeLibraries.java
(//base dependencies).This step is skipped when building using Incremental Install.
When is_java_debug = true
:
.dex.jar
files into a final .mergeddex.jar
.When is_java_debug = false
:
lib.java
.jar
files and outputs a final .r8dex.jar
..r8dex.jar
for each module.Test APKs are normal APKs that contain an <instrumentation>
tag within their AndroidManifest.xml
. If this tag specifies an android:targetPackage
different from itself, then Android will add that package‘s classes.dex
to the test APK’s Java classpath when run. In GN, you can enable this behavior using the apk_under_test
parameter on instrumentation_test_apk
targets. Using it is discouraged if APKs have proguard_enabled=true
.
When enable_proguard=false
:
When enable_proguard=true
:
-keep
directives are guaranteed to exist after ProGuarding. As a work-around, test APKs include all of the apk-under-test’s libraries directly in its own final dex such that the under-test apk‘s Java code is never used (because it is entirely shadowed by the test apk’s dex).GEN_JNI.java
class be generated that contains all native methods for an APK. There cannot be conflicting GEN_JNI
classes in both the test apk and the apk-under-test, so only the apk-under-test has one generated for it. As a result this, instrumentation test APKs that use apk-under-test cannot use native methods that aren't already part of the apk-under-test.There are two ways to go about generating source files: Annotation Processors and custom build steps.
javac
as part of the compile step..java
directly, but most generate a zip file of sources (called a .srcjar
) to simplify the number of inputs / outputs.jinja_template
: Generates source files using Jinja.java_cpp_template
: Generates source files using the C preprocessor.java_cpp_enum
: Generates @IntDef
s based on enums within .h
files.java_cpp_strings
: Generates String constants based on strings defined in .cc
files.