1## Processors
2
3### Proguard {#proguard}
4
5Proguard configurations allow libraries to specify how post-processing tools
6like optimizers and shrinkers should operate on library bytecode. Note that
7while Proguard is the name of a specific tool, a Proguard configuration may be
8read by R8 or any number of other post-processing tools.
9
10NOTE Jetpack libraries **must not** run Proguard on their release artifacts. Do
11not specify `minifyEnabled`, `shrinkResources`, or `proguardFiles` in your build
12configuration.
13
14#### Bundling with a library {#proguard-rules}
15
16**Android libraries (AARs)** can bundle consumer-facing Proguard rules using the
17`consumerProguardFiles` (*not* `proguardFiles`) field in their `build.gradle`
18file's `defaultConfig`:
19
20```
21android {
22    defaultConfig {
23        consumerProguardFiles 'proguard-rules.pro'
24    }
25}
26```
27
28Libraries *do not* need to specify this field on `buildTypes.all`.
29
30**Java-only libraries (JARs)** can bundle consumer-facing Proguard rules by
31placing the file under the `META-INF` resources directory. The file **must** be
32named using the library's unique Maven coordinate to avoid build-time merging
33issues:
34
35```
36<project>/src/main/resources/META-INF/proguard/androidx.core_core.pro
37```
38
39#### Conditional Proguard Rules {#proguard-conditional}
40
41Libraries are strongly encouraged to minimize the number of classes that are
42kept as part of keep rules. More specifically, library authors are expected to
43identify the entry points of their library that call into code paths that may
44require classes to be exempt from proguard rules. This may be due to internal
45reflection usages or JNI code. In the case of JNI code, java/kotlin classes and
46methods that are implemented in native must be exempt in order to avoid JNI
47linking errors in libraries that are consumed by applications built with
48proguard enabled.
49
50A common pattern is to create an annotation class that is used to annotate all
51classes and methods that are to be excluded from proguard obfuscation.
52
53For example:
54
55```
56/// in MyProguardExceptionAnnotation.kt
57internal annotation class MyProguardExemptionAnnotation
58```
59
60Then reference this annotation within your proguard config conditionally
61whenever the public API is consumed that leverages facilities that need to be
62excluded from proguard optimization.
63
64```
65# in proguard-rules.pro
66# The following keeps classes annotated with MyProguardExemptionAnnotation
67# defined above
68-if class androidx.mylibrary.MyPublicApi
69-keep @androidx.mylibrary.MyProguardExemptionAnnotation public class *
70
71# The following keeps methods annotated with MyProguardExcemptionAnnotation
72-if class androidx.mylibrary.MyPublicApi
73-keepclasseswithmembers class * {
74    @androidx.mylibrary.MyProguardExcemptionAnnotation *;
75}
76```
77
78Note that for each public API entry point an additional proguard rule would need
79to be introduced in the corresponding proguard-rules.pro. This is because as of
80writing there is no "or" operator within proguard that can be used to include
81the keep rules for multiple conditions. So each rule would need to be
82copy/pasted for each public API entrypoint.
83