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 -> .jarjava_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).
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 in parallel with subsequent steps.
//third_party/ijar converts the .jar into an .interface.jar, which is a copy of the input with all non-public symbols and function bodies removed..interface.jar files to skip having to be rebuilt when only private implementation details change..interface.jar as outputs. Ninja's restat=1 feature then causes dependent targets to be rebuilt only when the .interface.jar changes. Final dex targets are always rebuilt because they depend on the non-.interface.jar through a depfile.//build/android/bytecode runs on the compiled .jar in order to:deps.This step happens only when targets have supports_android = true.
//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 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 this GN arg is set: use_jacoco_coverage = true
.jar is copied into $root_build_dir/lib.java (under target-specific subdirectories) so that it will be included by bot archive steps..jar files are the ones used when running java_binary and junit_binary targets.This step happens only when targets have supports_android = true.
.jar files containing .class files into .dex.jar files containing .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 .dex.zip.When is_java_debug = false:
lib.java .jar files and outputs a final .dex.zip..dex.zip with the code from all modules.This step happens only when is_java_debug = false.
.dex.zip into per-module .dex.zip files.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 @IntDefs based on enums within .h files.java_cpp_strings: Generates String constants based on strings defined in .cc files.We use several tools for static analysis.
use_errorprone_java_compiler.@GuardedBy annotations.chromium_code = false (e.g. for //third_party).disable_android_lint@TargetApi annotations (ensure you don't call a function that does not exist on all versions of Android unless guarded by an version check).chromium_code = false (e.g. for //third_party).deps are not missing any entries._BANNED_JAVA_FUNCTIONS._AndroidSpecificOnUploadChecks().@SuppressWarnings annotations..java files via git cl format.// clang-format off ... non-formatted code here ... // clang-format on