xref: /aosp_15_r20/build/soong/docs/resources.md (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1*333d2b36SAndroid Build Coastguard Worker## Soong Android Resource Compilation
2*333d2b36SAndroid Build Coastguard Worker
3*333d2b36SAndroid Build Coastguard WorkerThe Android build process involves several steps to compile resources into a format that the Android app can use
4*333d2b36SAndroid Build Coastguard Workerefficiently in android_library, android_app and android_test modules.  See the
5*333d2b36SAndroid Build Coastguard Worker[resources documentation](https://developer.android.com/guide/topics/resources/providing-resources) for general
6*333d2b36SAndroid Build Coastguard Workerinformation on resources (with a focus on building with Gradle).
7*333d2b36SAndroid Build Coastguard Worker
8*333d2b36SAndroid Build Coastguard WorkerFor all modules, AAPT2 compiles resources provided by directories listed in the resource_dirs directory (which is
9*333d2b36SAndroid Build Coastguard Workerimplicitly set to `["res"]` if unset, but can be overridden by setting the `resource_dirs` property).
10*333d2b36SAndroid Build Coastguard Worker
11*333d2b36SAndroid Build Coastguard Worker## android_library with resource processor
12*333d2b36SAndroid Build Coastguard WorkerFor an android_library with resource processor enabled (currently by setting `use_resource_processor: true`, but will be
13*333d2b36SAndroid Build Coastguard Workerenabled by default in the future):
14*333d2b36SAndroid Build Coastguard Worker- AAPT2 generates the `package-res.apk` file with a resource table that contains all resources from the current
15*333d2b36SAndroid Build Coastguard Workerandroid_library module.  `package-res.apk` files from transitive dependencies are passed to AAPT2 with the `-I` flag to
16*333d2b36SAndroid Build Coastguard Workerresolve references to resources from dependencies.
17*333d2b36SAndroid Build Coastguard Worker- AAPT2 generates an R.txt file that lists all the resources provided by the current android_library module.
18*333d2b36SAndroid Build Coastguard Worker- ResourceProcessorBusyBox reads the `R.txt` file for the current android_library and produces an `R.jar` with an
19*333d2b36SAndroid Build Coastguard Worker`R.class` in the package listed in the android_library's `AndroidManifest.xml` file that contains java fields for each
20*333d2b36SAndroid Build Coastguard Workerresource ID.  The resource IDs are non-final, as the final IDs will not be known until the resource table of the final
21*333d2b36SAndroid Build Coastguard Workerandroid_app or android_test module is built.
22*333d2b36SAndroid Build Coastguard Worker- The android_library's java and/or kotlin code is compiled with the generated `R.jar` in the classpath, along with the
23*333d2b36SAndroid Build Coastguard Worker`R.jar` files from all transitive android_library dependencies.
24*333d2b36SAndroid Build Coastguard Worker
25*333d2b36SAndroid Build Coastguard Worker## android_app or android_test with resource processor
26*333d2b36SAndroid Build Coastguard WorkerFor an android_app or android_test with resource processor enabled (currently by setting `use_resource_processor: true`,
27*333d2b36SAndroid Build Coastguard Workerbut will be enabled by default in the future):
28*333d2b36SAndroid Build Coastguard Worker- AAPT2 generates the `package-res.apk` file with a resource table that contains all resources from the current
29*333d2b36SAndroid Build Coastguard Workerandroid_app or android_test, as well as all transitive android_library modules referenced via `static_libs`.  The
30*333d2b36SAndroid Build Coastguard Workercurrent module is overlaid on dependencies so that resources from the current module replace resources from dependencies
31*333d2b36SAndroid Build Coastguard Workerin the case of conflicts.
32*333d2b36SAndroid Build Coastguard Worker- AAPT2 generates an R.txt file that lists all the resources provided by the current android_app or android_test, as
33*333d2b36SAndroid Build Coastguard Workerwell as all transitive android_library modules referenced via `static_libs`.  The R.txt file contains the final resource
34*333d2b36SAndroid Build Coastguard WorkerID for each resource.
35*333d2b36SAndroid Build Coastguard Worker- ResourceProcessorBusyBox reads the `R.txt` file for the current android_app or android_test, as well as all transitive
36*333d2b36SAndroid Build Coastguard Workerandroid_library modules referenced via `static_libs`, and produces an `R.jar` with an `R.class` in the package listed in
37*333d2b36SAndroid Build Coastguard Workerthe android_app or android_test's `AndroidManifest.xml` file that contains java fields for all local or transitive
38*333d2b36SAndroid Build Coastguard Workerresource IDs.  In addition, it creates an `R.class` in the package listed in each android_library dependency's
39*333d2b36SAndroid Build Coastguard Worker`AndroidManifest.xml` file that contains final resource IDs for the resources that were found in that library.
40*333d2b36SAndroid Build Coastguard Worker- The android_app or android_test's java and/or kotlin code is compiled with the current module's `R.jar` in the
41*333d2b36SAndroid Build Coastguard Workerclasspath, but not the `R.jar` files from transitive android_library dependencies.  The `R.jar` file is also merged into
42*333d2b36SAndroid Build Coastguard Workerthe program  classes that are dexed and placed in the final APK.
43*333d2b36SAndroid Build Coastguard Worker
44*333d2b36SAndroid Build Coastguard Worker## android_app, android_test or android_library without resource processor
45*333d2b36SAndroid Build Coastguard WorkerFor an android_app, android_test or android_library without resource processor enabled (current the default, or
46*333d2b36SAndroid Build Coastguard Workerexplicitly set with `use_resource_processor: false`):
47*333d2b36SAndroid Build Coastguard Worker- AAPT2 generates the `package-res.apk` file with a resource table that contains all resources from the current
48*333d2b36SAndroid Build Coastguard Workerandroid_app, android_test or android_library module, as well as all transitive android_library modules referenced via
49*333d2b36SAndroid Build Coastguard Worker`static_libs`.  The current module is overlaid on dependencies so that resources from the current module replace
50*333d2b36SAndroid Build Coastguard Workerresources from dependencies in the case of conflicts.
51*333d2b36SAndroid Build Coastguard Worker- AAPT2 generates an `R.java` file in the package listed in each the current module's `AndroidManifest.xml` file that
52*333d2b36SAndroid Build Coastguard Workercontains resource IDs for all resources from the current module as well as all transitive android_library modules
53*333d2b36SAndroid Build Coastguard Workerreferenced via `static_libs`.  The same `R.java` containing all local and transitive resources is also duplicated into
54*333d2b36SAndroid Build Coastguard Workerevery package listed in an `AndroidManifest.xml` file in any static `android_library` dependency.
55*333d2b36SAndroid Build Coastguard Worker- The module's java and/or kotlin code is compiled along with all the generated `R.java` files.
56*333d2b36SAndroid Build Coastguard Worker
57*333d2b36SAndroid Build Coastguard Worker
58*333d2b36SAndroid Build Coastguard Worker## Downsides of legacy resource compilation without resource processor
59*333d2b36SAndroid Build Coastguard Worker
60*333d2b36SAndroid Build Coastguard WorkerCompiling resources without using the resource processor results in a generated R.java source file for every transitive
61*333d2b36SAndroid Build Coastguard Workerpackage that contains every transitive resource.  For modules with large transitive dependency trees this can be tens of
62*333d2b36SAndroid Build Coastguard Workerthousands of resource IDs duplicated in tens to a hundred java sources.  These java sources all have to be compiled in
63*333d2b36SAndroid Build Coastguard Workerevery successive module in the dependency tree, and then the final R8 step has to drop hundreds of thousands of
64*333d2b36SAndroid Build Coastguard Workerunreferenced fields.  This results in significant build time and disk usage increases over building with resource
65*333d2b36SAndroid Build Coastguard Workerprocessor.
66*333d2b36SAndroid Build Coastguard Worker
67*333d2b36SAndroid Build Coastguard Worker## Converting to compilation with resource processor
68*333d2b36SAndroid Build Coastguard Worker
69*333d2b36SAndroid Build Coastguard Worker### Reference resources using the package name of the module that includes them.
70*333d2b36SAndroid Build Coastguard WorkerConverting an android_library module to build with resource processor requires fixing any references to resources
71*333d2b36SAndroid Build Coastguard Workerprovided by android_library dependencies to reference the R classes using the package name found in the
72*333d2b36SAndroid Build Coastguard Worker`AndroidManifest.xml` file of the dependency.  For example, when referencing an androidx resource:
73*333d2b36SAndroid Build Coastguard Worker```java
74*333d2b36SAndroid Build Coastguard WorkerView.inflate(mContext, R.layout.preference, null));
75*333d2b36SAndroid Build Coastguard Worker```
76*333d2b36SAndroid Build Coastguard Workermust be replaced with:
77*333d2b36SAndroid Build Coastguard Worker```java
78*333d2b36SAndroid Build Coastguard WorkerView.inflate(mContext, androidx.preference.R.layout.preference, null));
79*333d2b36SAndroid Build Coastguard Worker```
80*333d2b36SAndroid Build Coastguard Worker
81*333d2b36SAndroid Build Coastguard Worker### Use unique package names for each module in `AndroidManifest.xml`
82*333d2b36SAndroid Build Coastguard Worker
83*333d2b36SAndroid Build Coastguard WorkerEach module will produce an `R.jar` containing an `R.class` in the package specified in it's `AndroidManifest.xml`.
84*333d2b36SAndroid Build Coastguard WorkerIf multiple modules use the same package name they will produce conflicting `R.class` files, which can cause some
85*333d2b36SAndroid Build Coastguard Workerresource IDs to appear to be missing.
86*333d2b36SAndroid Build Coastguard Worker
87*333d2b36SAndroid Build Coastguard WorkerIf existing code has multiple modules that contribute resources to the same package, one option is to move all the
88*333d2b36SAndroid Build Coastguard Workerresources into a single resources-only `android_library` module with no code, and then depend on that from all the other
89*333d2b36SAndroid Build Coastguard Workermodules.