Skip to content

Commit 4bb4b2e

Browse files
jonathanpeppersatsushieno
authored andcommitted
[Xamarin.Android.Build.Tasks] D8 and R8 integration (dotnet#2019)
Fixes: dotnet#1423 Fixes: dotnet#2040 Bumps to r8/d8-1.2@125b72. ~~ Overview ~~ This enables `d8` and `r8` integration for Xamarin.Android. `d8` is a "next-generation" dex compiler (over `dx`), and `r8` is a replacement for ProGuard. For full details on the feature, see `Documentation/guides/D8andR8.md`. ~~ MSBuild targets changes ~~ New MSBuild properties include: - `$(AndroidDexTool)` - an enum-style property with options `dx` and `d8`. Defaults to `dx`. - `$(AndroidLinkTool)` - an enum-style property, that can be left blank to disable code shrinking. Valid values are `proguard` and `r8`. Existing MSBuild properties still retain the old behavior: - `$(AndroidEnableProguard)` will set `$(AndroidLinkTool)` to `proguard`, although it is no longer used internally by Xamarin.Android targets. - `$(AndroidEnableDesugar)` will default to `true` if `d8` or `r8` are used. New MSBuild tasks include: - `<D8/>`: runs `d8.jar` with the required options for Xamarin.Android. - `<R8/>`: subclasses `<D8/>`, and adds functionality for multi-dex and code-shrinking. Additionally, any new MSBuild targets are placed in a new `Xamarin.Android.D8.targets` file. This is good first step to make `Xamarin.Android.Common.targets` smaller. Additionally: * `build.props` is now invalidated via the `$(AndroidDexTool)` and `$(AndroidLinkTool)` properties, instead of `$(AndroidEnableProguard)` * `build.props` is invalidated via `$(AndroidEnableDesugar)` * Refactored `$(IntermediateOutputPath)_dex_stamp` stamp file in `_CompileToDalvikWithDx` and `_CompileToDalvikWithD8` to match the new convention of `$(_AndroidStampDirectory)_CompileToDalvik.stamp` * `*.dex` files weren't in `@(FileWrites)`?! * `<CompileToDalvik/>` had a `DexOutputs` output property that was completely unused, so I removed it. Also removed extra log messages. ~~ Test changes ~~ Tests that need to validate various combinations of properties are now using parameters such as: [Values ("dx", "d8")] string dexTool, [Values ("", "proguard", "r8")] string linkTool Set on the `XamarinAndroidApplicationProject` such as: var proj = new XamarinAndroidApplicationProject { DexTool = dexTool, LinkTool = linkTool, }; In other cases, a simple `useD8` flag was added to set `DexTool="d8"`. Since adding test parameters, exponentially causes our test cases to expand, I removed some non-essential parameters: - `BuildProguardEnabledProject()` dropped `useLatestSdk`, as it does not seem applicable here (and is deprecated). Otherwise would have 24 test cases... - `BuildApplicationWithSpacesInPath()` dropped `isRelease` and defaulted it to `true`. We aren't going to likely encounter issues with spaces in a path that happen *only* in a `Debug` build. Otherwise we would have 24 test cases here... - `Desugar()` dropped `enableDesugar` because it is certain this application project will not build *without* desugar. We don't need to test this, and would have 24 test cases otherwise... Also dropped some `[TestCaseSource]` attributes where the `[Values]` parameter was much cleaner. ~~ Changes to test/sample projects ~~ `HelloWorld` - `$(AndroidDexTool)` set to `d8` if unspecified, so we can track the performance benefit. `Xamarin.Forms Integration` - uses `d8` and `$(AndroidLinkTool)` set to `r8`, using a `proguard.cfg` file for Xamarin.Forms. Will help us track startup performance benefits of Java code shrinking and build performance. `Mono.Android-Tests` - uses `d8` and `$(AndroidLinkTool)` set to `r8`, to verify these on-device tests pass. `Runtime-MultiDex` - `$(AndroidDexTool)` set to `d8` if unspecified, to validate multi-dex is working properly with `d8`. ~~ xamarin-android build changes ~~ The `<DownloadUri/>` MSBuild task now has an optional `HashHeader` property. When set, an http HEAD request is made to the URL, and the destination file path gets a suffix added for the value. `DownloadUri.DestinationFiles` is changed to an `[Output]` property, as the destination paths could change due to the `HashHeader`. Chromium's `depot_tools` are downloaded the same as all of our other dependencies. As the `depot_tools` distribution filename is unversioned, we use the `x-goog-hash` header to derive a "version" so that we don't needlessly download the file. ~~ Deployment changes ~~ Three new files will need to be included in Xamarin.Android installers: - `d8.jar` - `r8.jar` - `Xamarin.Android.D8.targets` ~~ General changes ~~ * Fixed doc for `xa4304` error code * Added `xa4305` error code for `CompileToDalvik`, `R8`, and `<CreateMultiDexMainDexClassList/>` * Removed log messages in `<CreateMultiDexMainDexClassList/>` ~~ Performance Comparison ~~ | MSBuild Target | Options Enabled | Time | APK size (bytes) | dex size (bytes) | | --- | --- | ---: | ---: | ---: | | _CompileToDalvikWithDx | n/a | 11074ms | 13378157 | 3894720 | | _CompileToDalvikWithD8 | d8, (desugar enabled) | 8543ms | 13124205 | 3314064 | | _CompileToDalvikWithD8 | d8, (desugar disabled) | 9550ms | 13124205 | 3314064 | | _CompileToDalvikWithDx | multi-dex | 15632ms | 13390498 | 3916496 | | _CompileToDalvikWithD8 | d8, multi-dex | 25979ms | 13054626 | 3264096 | | _CompileToDalvikWithDx | proguard | 11903ms | 12804717 | 2446964 | | _CompileToDalvikWithD8 | d8, r8 | 13799ms | 12513901 | 1835588 | | _CompileToDalvikWithDx | multi-dex, proguard | 17279ms | 12804770 | 2449512 | | _CompileToDalvikWithD8 | d8, multi-dex, r8 | 13792ms | 12513954 | 1837588 | *NOTE: desugar is enabled by default with d8/r8* I timed this builds with [this script][powershell_script], with a "Hello World" Xamarin.Forms app. Build logs here: [d8andr8.zip][d8andr8_zip] One can draw their own conclusions on which options are faster, better, smaller. See further detail in `D8andR8.md`. [powershell_script]: https://github.com/jonathanpeppers/HelloWorld/blob/39e2854f6ca39c0941fb8bd6f2a16d8b7663003e/build.ps1 [d8andr8_zip]: https://github.com/xamarin/xamarin-android/files/2470385/d8andr8.zip Co-authored-by: Atsushi Eno <[email protected]>
1 parent faaa908 commit 4bb4b2e

35 files changed

+1134
-233
lines changed

Diff for: .gitmodules

+4
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@
3838
path = external/proguard
3939
url = https://github.com/xamarin/proguard.git
4040
branch = master
41+
[submodule "external/r8"]
42+
path = external/r8
43+
url = https://r8.googlesource.com/r8
44+
branch = d8-1.2
4145
[submodule "external/sqlite"]
4246
path = external/sqlite
4347
url = https://github.com/xamarin/sqlite.git

Diff for: Configuration.props

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@
6464
<CmakePath Condition=" '$(CmakePath)' == '' ">$(AndroidSdkCmakeDirectory)\bin\cmake</CmakePath>
6565
<NinjaPath Condition=" '$(NinjaPath)' == '' ">$(AndroidSdkCmakeDirectory)\bin\ninja</NinjaPath>
6666
<AntDirectory>$(AndroidToolchainDirectory)\ant</AntDirectory>
67+
<ChromeToolsDirectory>$(AndroidToolchainDirectory)\depot_tools</ChromeToolsDirectory>
6768
<AntToolPath>$(AntDirectory)\bin</AntToolPath>
6869
<AndroidSupportedHostJitAbis Condition=" '$(AndroidSupportedHostJitAbis)' == '' ">$(HostOS)</AndroidSupportedHostJitAbis>
6970
<AndroidSupportedTargetJitAbis Condition=" '$(AndroidSupportedTargetJitAbis)' == '' ">armeabi-v7a:x86</AndroidSupportedTargetJitAbis>

Diff for: Documentation/README.md

+1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
* [Build Process](guides/BuildProcess.md)
2121
* [`.axml` CodeBehind Support](guides/LayoutCodeBehind.md)
2222
* [MSBuild Best Practices](guides/MSBuildBestPractices.md)
23+
* [D8 and R8 Integration](guides/D8andR8.md)
2324

2425

2526
# Building from Source

Diff for: Documentation/guides/BuildProcess.md

+35
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,28 @@ when packaing Release applications.
210210

211211
This property is `False` by default.
212212

213+
- **AndroidD8JarPath** &ndash; The path to `d8.jar` for use with the
214+
d8 dex-compiler. Defaults to a path in the Xamarin.Android
215+
installation. For further information see our documentation on [D8
216+
and R8][d8-r8].
217+
218+
- **AndroidDexTool** &ndash; An enum-style property with valid
219+
values of `dx` or `d8`. Indicates which Android [dex][dex]
220+
compiler is used during the Xamarin.Android build process.
221+
Currently defaults to `dx`. For further information see our
222+
documentation on [D8 and R8][d8-r8].
223+
224+
[dex]: https://source.android.com/devices/tech/dalvik/dalvik-bytecode
225+
[d8-r8]: D8andR8.md
226+
227+
- **AndroidEnableDesugar** &ndash; A boolean property that
228+
determines if `desugar` is enabled. Android does not currently
229+
support all Java 8 features, and the default toolchain implements
230+
the new language features by performing bytecode transformations,
231+
called `desugar`, on the output of the `javac` compiler. Defaults
232+
to `False` if using `AndroidDexTool=dx` and defaults to `True` if
233+
using `AndroidDexTool=d8`.
234+
213235
- **AndroidEnableMultiDex** &ndash; A boolean property that
214236
determines whether or not multi-dex support will be used in the
215237
final `.apk`.
@@ -360,6 +382,14 @@ when packaing Release applications.
360382
<AndroidLinkSkip>Assembly1;Assembly2</AndroidLinkSkip>
361383
```
362384
385+
- **AndroidLinkTool** &ndash; An enum-style property with valid
386+
values of `proguard` or `r8`. Indicates which code shrinker is
387+
used for Java code. Currently defaults to an empty string, or
388+
`proguard` if `$(AndroidEnableProguard)` is `True`. For further
389+
information see our documentation on [D8 and R8][d8-r8].
390+
391+
[d8-r8]: D8andR8.md
392+
363393
- **LinkerDumpDependencies** &ndash; A bool property which enables
364394
generating of linker dependencies file. This file can be used as
365395
input for
@@ -381,6 +411,11 @@ when packaing Release applications.
381411
produce the actual `AndroidManifest.xml`.
382412
The `$(AndroidManifest)` must contain the package name in the `/manifest/@package` attribute.
383413

414+
- **AndroidR8JarPath** &ndash; The path to `r8.jar` for use with the
415+
r8 dex-compiler and shrinker. Defaults to a path in the
416+
Xamarin.Android installation. For further information see our
417+
documentation on [D8 and R8][d8-r8].
418+
384419
- **AndroidSdkBuildToolsVersion** &ndash; The Android SDK
385420
build-tools package provides the **aapt** and **zipalign** tools,
386421
among others. Multiple different versions of the build-tools package

Diff for: Documentation/guides/D8andR8.md

+270
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,270 @@
1+
This is the D8 and R8 integration specification for Xamarin.Android.
2+
3+
# What is D8? What is R8?
4+
5+
At a high level, here are the steps that occur during an Android
6+
application's Java compilation:
7+
- `javac` compiles Java code
8+
- `desugar` remove's the "sugar" (from Java 8 features) that are not
9+
fully supported on Android
10+
- ProGuard shrinks compiled Java code
11+
- `dx` "dexes" compiled Java code into Android [dex][dex] format. This
12+
is an alternate Java bytecode format supported by the Android
13+
platform.
14+
15+
This process has a few issues, such as:
16+
- [proguard](https://www.guardsquare.com/en/products/proguard/manual)
17+
is made by a third party, and aimed for Java in general (not Android
18+
specific)
19+
- `dx` is slower than it _could_ be
20+
21+
So in 2017, Google announced a "next-generation" dex compiler named
22+
[D8](https://android-developers.googleblog.com/2017/08/next-generation-dex-compiler-now-in.html).
23+
24+
- D8 is a direct replacement for `dx`
25+
- R8 is a replacement for ProGuard, that also "dexes" at the same
26+
time. If using R8, a D8 call is not needed.
27+
28+
Both tools have support for various other Android-specifics:
29+
- Both `desugar` by default unless the `--no-desugaring` switch is
30+
specified
31+
- Both support [multidex][multidex], although `d8` does not have
32+
support for using the ProGuard rules format (the
33+
`--main-dex-rules` switch).
34+
- R8 has full support for [multidex][multidex].
35+
36+
Additionally, R8 is geared to be backwards compatible to ProGuard.
37+
It uses the same file format for configuration and command-line
38+
parameters as ProGuard. However, at the time of writing this, there
39+
are still several flags/features not implemented in R8 yet.
40+
41+
For more information on how R8 compares to ProGuard, please see
42+
[this comparison from the ProGuard team](https://www.guardsquare.com/en/blog/proguard-and-r8).
43+
44+
You can find the source for D8 and R8 at:
45+
<https://r8.googlesource.com/r8/>
46+
47+
For reference, `d8 --help`:
48+
```
49+
Usage: d8 [options] <input-files>
50+
where <input-files> are any combination of dex, class, zip, jar, or apk files
51+
and options are:
52+
--debug # Compile with debugging information (default).
53+
--release # Compile without debugging information.
54+
--output <file> # Output result in <outfile>.
55+
# <file> must be an existing directory or a zip file.
56+
--lib <file> # Add <file> as a library resource.
57+
--classpath <file> # Add <file> as a classpath resource.
58+
--min-api # Minimum Android API level compatibility
59+
--intermediate # Compile an intermediate result intended for later
60+
# merging.
61+
--file-per-class # Produce a separate dex file per input class
62+
--no-desugaring # Force disable desugaring.
63+
--main-dex-list <file> # List of classes to place in the primary dex file.
64+
--version # Print the version of d8.
65+
--help # Print this message.
66+
```
67+
68+
For reference, `r8 --help`:
69+
```
70+
Usage: r8 [options] <input-files>
71+
where <input-files> are any combination of dex, class, zip, jar, or apk files
72+
and options are:
73+
--release # Compile without debugging information (default).
74+
--debug # Compile with debugging information.
75+
--output <file> # Output result in <file>.
76+
# <file> must be an existing directory or a zip file.
77+
--lib <file> # Add <file> as a library resource.
78+
--min-api # Minimum Android API level compatibility.
79+
--pg-conf <file> # Proguard configuration <file>.
80+
--pg-map-output <file> # Output the resulting name and line mapping to <file>.
81+
--no-tree-shaking # Force disable tree shaking of unreachable classes.
82+
--no-minification # Force disable minification of names.
83+
--no-desugaring # Force disable desugaring.
84+
--main-dex-rules <file> # Proguard keep rules for classes to place in the
85+
# primary dex file.
86+
--main-dex-list <file> # List of classes to place in the primary dex file.
87+
--main-dex-list-output <file> # Output the full main-dex list in <file>.
88+
--version # Print the version of r8.
89+
--help # Print this message.
90+
```
91+
92+
# What did Xamarin.Android do *before* D8/R8?
93+
94+
In other words, what is currently happening *before* we introduce D8/R8 support?
95+
96+
1. The [Javac](https://github.com/xamarin/xamarin-android/blob/221a2190ebb3aaec9ecd9b1cf8f7f6174c43153a/src/Xamarin.Android.Build.Tasks/Tasks/Javac.cs)
97+
MSBuild task compiles `*.java` files to a `classes.zip` file.
98+
2. The [Desugar](https://github.com/xamarin/xamarin-android/blob/221a2190ebb3aaec9ecd9b1cf8f7f6174c43153a/src/Xamarin.Android.Build.Tasks/Tasks/Desugar.cs)
99+
MSBuild task "desugars" using `desugar_deploy.jar` if
100+
`$(AndroidEnableDesugar)` is `True`.
101+
3. The [Proguard](https://github.com/xamarin/xamarin-android/blob/221a2190ebb3aaec9ecd9b1cf8f7f6174c43153a/src/Xamarin.Android.Build.Tasks/Tasks/Proguard.cs)
102+
MSBuild task shrinks the compiled Java code if
103+
`$(AndroidEnableProguard)` is `True`. Developers may also supply
104+
custom proguard configuration files via `ProguardConfiguration`
105+
build items.
106+
4. The [CreateMultiDexMainDexClassList](https://github.com/xamarin/xamarin-android/blob/221a2190ebb3aaec9ecd9b1cf8f7f6174c43153a/src/Xamarin.Android.Build.Tasks/Tasks/CreateMultiDexMainDexClassList.cs)
107+
MSBuild task runs `proguard` to generate a final, combined
108+
`multidex.keep` file if `$(AndroidEnableMultiDex)` is `True`.
109+
Developers can also supply custom `multidex.keep` files via
110+
`MultiDexMainDexList` build items.
111+
5. The [CompileToDalvik](https://github.com/xamarin/xamarin-android/blob/221a2190ebb3aaec9ecd9b1cf8f7f6174c43153a/src/Xamarin.Android.Build.Tasks/Tasks/CompileToDalvik.cs)
112+
MSBuild task runs `dx.jar` to generate a final `classes.dex` file
113+
in `$(IntermediateOutputPath)android\bin`. If `multidex` is
114+
enabled, a `classes2.dex` (and potentially more) are also generated
115+
in this location.
116+
117+
# What does this process look like with D8 / R8 enabled?
118+
119+
Xamarin.Android now has two new MSBuild tasks: `<R8/>` and `<D8/>`.
120+
121+
1. The [Javac](https://github.com/xamarin/xamarin-android/blob/221a2190ebb3aaec9ecd9b1cf8f7f6174c43153a/src/Xamarin.Android.Build.Tasks/Tasks/Javac.cs)
122+
MSBuild task will remain unchanged.
123+
2. `D8` will run if `$(AndroidEnableMultiDex)` is `False`,
124+
`$(AndroidLinkTool)` is not `r8`, and "desugar" by default.
125+
3. Otherwise, `R8` will run if `$(AndroidEnableMultiDex)` is `True` or
126+
`$(AndroidLinkTool)` is `r8` and will also "desugar" by default.
127+
128+
So in addition to be being faster in general (if Google's claims are
129+
true), we will be calling a *single* command line tool to produce dex
130+
files!
131+
132+
# So how do developers use it? What are sensible MSBuild property defaults?
133+
134+
Currently, a `csproj` file might have the following properties:
135+
```xml
136+
<Project>
137+
<PropertyGroup>
138+
<AndroidEnableProguard>True</AndroidEnableProguard>
139+
<AndroidEnableMultiDex>True</AndroidEnableMultiDex>
140+
<AndroidEnableDesugar>True</AndroidEnableDesugar>
141+
</PropertyGroup>
142+
</Project>
143+
```
144+
145+
To enable the new behavior, we have introduced two new enum-style
146+
properties:
147+
- `$(AndroidDexTool)` - supports `dx` or `d8`
148+
- `$(AndroidLinkTool)` - supports `proguard` or `r8`
149+
150+
But for an existing project, a developer could opt-in to the new
151+
behavior with two properties:
152+
```xml
153+
<Project>
154+
<PropertyGroup>
155+
<AndroidEnableProguard>True</AndroidEnableProguard>
156+
<AndroidEnableMultiDex>True</AndroidEnableMultiDex>
157+
<AndroidEnableDesugar>True</AndroidEnableDesugar>
158+
<!--New properties-->
159+
<AndroidDexTool>d8</AndroidDexTool>
160+
<AndroidLinkTool>r8</AndroidLinkTool>
161+
</PropertyGroup>
162+
</Project>
163+
```
164+
165+
There should be two new MSBuild properties to configure here, because:
166+
- You could use `D8` in combination with `proguard`, as `R8` is not
167+
"feature complete" in comparison to `proguard`.
168+
- You may not want to use code shrinking at all, but still use `D8`
169+
instead of `dx`.
170+
- You shouldn't be able to use `dx` in combination with `R8`, it
171+
doesn't make sense.
172+
- Developers should be able to use the existing properties for
173+
enabling code shrinking, `multidex`, and `desugar`.
174+
175+
Our reasonable defaults would be:
176+
- If `AndroidDexTool` is omitted, `dx` and `CompileToDalvik`
177+
should be used. Until D8/R8 integration is deemed stable and enabled
178+
by default.
179+
- If `AndroidDexTool` is `d8` and `AndroidEnableDesugar` is
180+
omitted, `AndroidEnableDesugar` should be enabled.
181+
- If `AndroidLinkTool` is omitted and `AndroidEnableProguard` is
182+
`true`, we should default `AndroidLinkTool` to `proguard`.
183+
184+
MSBuild properties default to:
185+
```xml
186+
<AndroidDexTool Condition=" '$(AndroidDexTool)' == '' ">dx</AndroidDexTool>
187+
<!--NOTE: $(AndroidLinkTool) would be blank if code shrinking is not used at all-->
188+
<AndroidLinkTool Condition=" '$(AndroidLinkTool)' == '' And '$(AndroidEnableProguard)' == 'True' ">proguard</AndroidLinkTool>
189+
<AndroidEnableDesugar Condition=" '$(AndroidEnableDesugar)' == '' And ('$(AndroidDexTool)' == 'd8' Or '$(AndroidLinkTool)' == 'r8') ">True</AndroidEnableDesugar>
190+
```
191+
192+
If a user specifies combinations of properties:
193+
- `AndroidDexTool` = `d8` and `AndroidEnableProguard` = `True`
194+
- `AndroidLinkTool` will get set to `proguard`
195+
- `AndroidDexTool` = `dx` and `AndroidLinkTool` = `r8`
196+
- This combination doesn't really *make sense*, but we don't need to
197+
do anything: only `R8` will be called because it dexes and shrinks
198+
at the same time.
199+
- `AndroidEnableDesugar` is enabled when omitted, if either `d8` or
200+
`r8` are used
201+
202+
For new projects that want to use D8/R8, code shrinking, and
203+
`multidex`, it would make sense to specify:
204+
```xml
205+
<Project>
206+
<PropertyGroup>
207+
<AndroidEnableMultiDex>True</AndroidEnableMultiDex>
208+
<AndroidDexTool>d8</AndroidDexTool>
209+
<AndroidLinkTool>r8</AndroidLinkTool>
210+
</PropertyGroup>
211+
</Project>
212+
```
213+
214+
# Additional D8 / R8 settings?
215+
216+
`--debug` or `--release` needs to be explicitly specified for both D8
217+
and R8. We use the [AndroidIncludeDebugSymbols][debug_symbols]
218+
property for this.
219+
220+
`$(AndroidD8ExtraArguments)` and `$(AndroidR8ExtraArguments)` can be
221+
used to explicitly pass additional flags to D8 and R8.
222+
223+
# How are we compiling / shipping D8 and R8?
224+
225+
We have added a submodule to `xamarin-android` for
226+
[r8](https://r8.googlesource.com/r8/). It will be pinned to a commit
227+
with a reasonable release tag, such as `1.2.50` for now.
228+
229+
To build r8, we have to:
230+
- Download and unzip a tool named [depot_tools][depot_tools] from the
231+
Chromium project
232+
- Put the path to `depot_tools` in `$PATH`
233+
- Run `gclient` so it will download/bootstrap gradle, python, and
234+
other tools
235+
- Run `python tools\gradle.py d8 r8` to compile `d8.jar` and `r8.jar`
236+
- We will need to ship `d8.jar` and `r8.jar` in our installers,
237+
similar to how we are shipping `desugar_deploy.jar`
238+
239+
# Performance Comparison
240+
241+
| MSBuild Target | Options Enabled | Time | APK size (bytes) | dex size (bytes) |
242+
| --- | --- | ---: | ---: | ---: |
243+
| _CompileToDalvikWithDx | n/a | 11074ms | 13378157 | 3894720 |
244+
| _CompileToDalvikWithD8 | d8, (desugar enabled) | 8543ms | 13124205 | 3314064 |
245+
| _CompileToDalvikWithD8 | d8, (desugar disabled) | 9550ms | 13124205 | 3314064 |
246+
| _CompileToDalvikWithDx | multi-dex | 15632ms | 13390498 | 3916496 |
247+
| _CompileToDalvikWithD8 | d8, multi-dex | 25979ms | 13054626 | 3264096 |
248+
| _CompileToDalvikWithDx | proguard | 11903ms | 12804717 | 2446964 |
249+
| _CompileToDalvikWithD8 | d8, r8 | 13799ms | 12513901 | 1835588 |
250+
| _CompileToDalvikWithDx | multi-dex, proguard | 17279ms | 12804770 | 2449512 |
251+
| _CompileToDalvikWithD8 | d8, multi-dex, r8 | 13792ms | 12513954 | 1837588 |
252+
253+
_NOTE: desugar is enabled by default with d8/r8_
254+
255+
I timed this builds with [this script][powershell_script], with a "Hello World" Xamarin.Forms app. Build logs here: [d8andr8.zip][d8andr8_zip]
256+
257+
One can draw their own conclusions on which options are faster, better, smaller.
258+
259+
Some of my thoughts:
260+
- Default options for d8 and r8 seem to be faster?
261+
- Disabling `desugar` is slower?
262+
- Enabling `multi-dex` makes the dex file larger, because new classes are required. The app wasn't large enough to warrant a `classes2.dex`.
263+
- `d8` does not support multi-dex, and so choosing `d8` + `multi-dex` actually runs `r8` with `--no-tree-shaking --no-minification`. These options are _slower_?
264+
265+
[dex]: https://source.android.com/devices/tech/dalvik/dalvik-bytecode
266+
[multidex]: https://developer.android.com/studio/build/multidex
267+
[debug_symbols]: https://github.com/xamarin/xamarin-android/blob/221a2190ebb3aaec9ecd9b1cf8f7f6174c43153a/src/Xamarin.Android.Build.Tasks/Xamarin.Android.Common.targets#L315-L336
268+
[depot_tools]: http://commondatastorage.googleapis.com/chrome-infra-docs/flat/depot_tools/docs/html/depot_tools_tutorial.html
269+
[powershell_script]: https://github.com/jonathanpeppers/HelloWorld/blob/39e2854f6ca39c0941fb8bd6f2a16d8b7663003e/build.ps1
270+
[d8andr8_zip]: https://github.com/xamarin/xamarin-android/files/2470385/d8andr8.zip

Diff for: Documentation/guides/MSBuildBestPractices.md

+14
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,20 @@ use `Inputs` or `Outputs`.
201201

202202
# Best Practices for Xamarin.Android MSBuild targets
203203

204+
## Naming in Xamarin.Android targets
205+
206+
As mentioned [above](/MSBuildBestPractices.md#naming), a good amount
207+
of consideration should be done before adding new public-facing
208+
MSBuild properties. This is pretty clear when adding a new feature,
209+
since an obvious feature flag will be needed to enable it.
210+
211+
The main thing to keep in mind here is that almost all of our
212+
public-facing MSBuild properties should be prefixed with `Android`.
213+
This is a good convention so it is easy to know which properties are
214+
specific to Xamarin.Android, and this will prevent them from
215+
conflicting with MSBuild properties from other products. All MSBuild
216+
properties are effectively "global variables"...
217+
204218
## Stamp Files
205219

206220
From now on, we should try to put new stamp files in

Diff for: Documentation/guides/messages/xa4304.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Compiler Error XA4304
1+
# Compiler Warning XA4304
22

33
The `Proguard` MSBuild task encountered a proguard configuration file
44
that was not found on disk. These files are generally declared in your

0 commit comments

Comments
 (0)