Update the `Build` VSCode task to use
`$(TargetFramework)`=net7.0-android.
Update the `build-sample-under-dotnet` and `run-sample-under-dotnet`
VSCode tasks to generate `.binlog` files, just in case something
doesn't work.
Update the `@(AndroidJavaSource)` Build action:
1. In .NET 7, all `**\*.java` files are automatically added to the
`@(AndroidJavaSource)` Build action.
2. Add `%(AndroidJavaSource.Bind)` item metadata, a boolean value
(default is True) which controls whether or not the file is
compiled and bound *prior* to the C# build.
The combination of these means that custom Java code can be added to
any .NET Android project, and a binding of that Java code will be
usable by the C# code. Both Java code and bindings will be included
in App builds of referencing apps.
There are some restrictions on the Java code. You can only use Java
types or types which are defined in `.jar` or `.aar` files referenced
by the project via `@(AndroidLibrary)` or `@(EmbeddedJar)`. It is
suggested that you *do not* have `publi` Java types which use Java
generics. As with normal bindings, Java generics can cause
significant problems; try to stuck to normal types if you can.
* Add `dotnet-local` scripts to make using in tree dotnet easier.
Lets add a couple of `dotnet-local` scripts which will allow us to
use the in-tree dotnet install easier. Also update the VSCode tasks
to make use of this new script.
Moves the "sandbox" installation of `dotnet` that we use for testing
purposes from `$HOME/android-toolchain/dotnet` into the build tree
at `bin/$(Configuration)/dotnet`.
While this could lead to increased disk usage across some local build
environments it provides a handful of benefits:
Every time `make prepare` or `dotnet build -t:Prepare` runs we would
remove `$HOME/android-toolchain/dotnet` and start fresh. Having it
in a single "global" location is not too desirable when working out
of multiple checkout locations (fork vs non-fork for example), or
when using multiple build configurations at the same time.
This sandbox can also now more easily be removed with a `git clean`
if desirable; we had no "automatic" way to remove the
`$HOME/android-toolchain` installation location previously.
This move will also make it easier to eventually structure our .NET
build output in a way that will allow it to be tested without having
to pack and unpack `.nupkg` files.
Context: https://github.com/dotnet/sdk/issues/21613
`samples/HelloWorld` sample did not build with `dotnet build`.
was not working with `dotnet`. This was related to dotnet/sdk#21613.
For now, don't have `HelloLibrary/HelloLibrary.csproj` nested within
the App project, but instead have the `HelloWorld` App project be a
*sibling* directory to the `HelloLibrary` project.
This allows `samples/HelloWorld/HelloWorld/HelloWorld.csproj` to
build with `dotnet build`.
Update the extensions list to use the correct id for the VSCode
C# extension.
Remove the `nxunitExplorer.nunit` setting as it was causing the unit
tests to not load. This is because the extension is expecting a CIL
image, but we were passing a batch file. As a result none of the
unit tests would load in the IDE.
Add some documentation around using VSCode to run the unit tests and
debug the sample apps. This includes a link to a patched version of
the `testrun.exe` which the `nxunit.explorer` extension uses.
(There is a bug in the extension where tests with parameters will NOT
run or debug. A link to the patched version of the files is included
in the docs. A PR to the upstream extension has also been sent.)
Added the `dotnet-adapter` extension which lets us run the tests
under a `dotnet` context.
Fixes: https://github.com/xamarin/xamarin-android/issues/5944
Context: https://discordapp.com/channels/732297728826277939/732297837953679412/844981772445024306
Context: https://devdiv.visualstudio.com/DevDiv/_build/results?buildId=4791430&view=logs&jobId=9e58dffc-b78a-5028-45f4-4d99f4c2da6c
The `InstallAndRunTests.JsonDeserializationCreatesJavaHandle()` test
no longer runs the `TestBinaryDeserialization()` test on .NET 6, as
`BinaryFormatter` is deprecated and no longer supported in .NET 6:
* 8bff552b2b/accepted/2020/better-obsoletion/binaryformatter-obsoletion.md
The "Run check-boot-times" test has seemingly been failing since
92efdccb6, which introduced a new version of `avdmanager` and changed
the path where our `.avd` files are stored. The corresponding task
and tool have been fixed to know about this new `.avd` home location.
The create and start Android emulator tasks have also been updated for
uniformity. All of these tasks now set [`$(ANDROID_PREFS_ROOT)`][0]
rather than the now deprecated `$(ANDROID_SDK_HOME)` variable.
I have also seen some intermittent test failures on various PR builds
in some of our InstallAndRun emulator tests, and I have bumped the
timeout for those tests.
The `RunWithInterpreterEnabled()` test has been reworked a bit to
ensure that the required logging properties are set, and that we
use `MonitorAdbLogcat()` to help ensure that the app has a chance to
run before we look for the expected message.
The `NuGet.config` file that was added to the samples folder in commit
4201dc18 has been removed, as it cause problems with release builds.
A new VSCode task has been added to generate the config file as
needed for local testing instead.
[0]: https://developer.android.com/studio/command-line/variables.html
Update [`tasks.json`][0] to add the following tasks to VS Code:
* `build-sample`
* `run-sample`
* `build-sample-under-dotnet`
* `run-sample-under-dotnet`
These tasks build or run one of the following projects; when running
the task, the developer will be prompted for which project to use:
* `samples/HelloWorld/HelloWorld.csproj`
* `samples/HelloWorld/HelloWorld.DotNet.csproj`
* `samples/VSAndroidApp/VSAndroidApp.csproj`
These projects may also be debugged within VSCode.
[0]: https://code.visualstudio.com/docs/editor/tasks-v1
Context: https://github.com/xamarin/xamarin-android-tools/pull/101
Context: https://github.com/xamarin/monodroid/pull/1145
We would like to eventually remove the dependency that xamarin/monodroid
has on xamarin/xamarin-android. As a first step towards this effort,
shared MSBuild code is being moved to xamarin/xamarin-android-tools.
`Xamarin.Android.Build.Tasks` has been updated to use the new shared
`Microsoft.Android.Build.BaseTasks` sources. All of the files that were
moved to xamarin/xamarin-android-tools have been deleted.
The inverted monodroid build has been replaced with the new monodroid
build system, see https://github.com/xamarin/monodroid/pull/1145 for
more context. The one build task test that was still being ran from the
xamarin/monodroid repo has been moved into `DebuggingTasksTests.cs`,
which is conditionally included in `Xamarin.Android.Build.Tests`.
Tests associated with the build task source that was moved to
xamarin/xamarin-android-tools have also been moved to a new
`Microsoft.Android.Build.BaseTasks-Tests` assembly in that repo.
Our `NuGet.config` specified a local path to store NuGet packages
(commit 3a4acf5dcb) because some of our projects need to access
various files from the packages, and they need to know where to find
the unpacked content.
However, having the `packages/` directory be a subdirectory within the
`xamarin-android` checkout means that every time the repo is cleaned
e.g. with `git clean -xdf`, the `packages/` directory is removed,
necessitating that the NuGet packages be re-downloaded on the next
`make prepare` invocation.
Fix this conundrum by partially reverting 3a4acf5dcb, removing the
`globalPackagesFolder` setting within `NuGet.config`.
`make prepare`/`xaprepare` will create the file
`bin/Build$(Configuration)/Configuration.Generated.props` and add an
`$(XAPackagesDir)` MSBuild property which contains the detected NuGet
global packages folder location. `Configuration.props` imports the
new `Configuration.Generated.props` file, making `$(XAPackagesDir)`
available to other `.targets` files should they need to access files
located within NuGet packages.
The `$(XAPackagesDir)` variable will contain the first valid path from:
* [The `NUGET_PACKAGES` environment variable][0]
* The parent directory of the parent directory of the
`$(PkgXamarin_LibZipSharp)` MSBuild property, as set by the
[`@(PackageReference.GeneratePathProperty)` metadata][1].
The local NuGet global-packages folder was also needed by some YAML
scripts and `.vscode` files to launch `nunit3-console.exe`.
Replace these `nunit3-console.exe` invocations with calls to the new
`build-tools/scripts/nunit3-console` and
`build-tools/scripts/nunit3-console.cmd` scripts, which will correctly
determine the NuGet packages folder and execute
`nunit3-console.exe` from the `nunit.consolerunner` package.
Both scripts determine the NuGet global-packages folder by using the
first valid path from:
* The `NUGET_PACKAGES` environment variable.
* If `Nuget.exe` was downloaded by a previous `make prepare`
invocation, then by running:
mono .nuget/NuGet.exe locals -list global-packages
* The `$HOME/.nuget/packages` directory (Unix) or
the `%userprofile%\.nuget\packages` directory (Windows).
This removes the need to hardcode package version into our azure
pipeline as well as VSCode configuration. However, both scripts still
have the `nunit.consolerunner` package version embedded in them.
This is done so that we don't need to generate them in scenarios where
`xaprepare` is undesirable to run.
[0]: https://docs.microsoft.com/en-us/nuget/consume-packages/managing-the-global-packages-and-cache-folders
[1]: https://docs.microsoft.com/en-us/nuget/consume-packages/package-references-in-project-files#generatepathproperty
Build `MSBuildDeviceIntegration.csproj` for `netcoreapp3.1`, and add
a new test job for the `MSBuild Emulator Tests` stage.
I added `[Category]` as needed for tests when running under a
`dotnet` context.
Other fixes:
* `PerformanceTest` now builds all projects for a single ABI. This
reduces the time spent in `<ProcessAssemblies/>`. I also added a
500ms buffer for a `dotnet` context and an additional 500ms if
the test would now sign the `.apk` during `dotnet build`.
* If `$(AutomaticNuGetRestore)`=False, `dotnet build` needs to pass
`--no-restore`. This improves `PerformanceTest` times.
* `BundleToolTests` needed many file paths updated.
* Ensure that `AssertDexToolSupported(dexTool)` is called to ignore
tests using `$(AndroidDexTool)`=`dx`.
* The MSBuild tests using `mono/debugger-libs` do not appear to work
in .NET 6; added a new `Debugger` category to ignore them for now.
* A few specific tests are marked `[Category("DotNetIgnore")]` with
an explanation for each.
* The `CustomLinkDescriptionPreserve` test needed to exclude code
relying on `sqlite-net-pcl` as using PCLs do not appear to work
in .NET 6.
Within Visual Studio Code, various tasks were hardcoded to build the
`Debug` configuration. This is annoying if you ever need to build
the `Release` configuration, as VSCode won't help you.
Update the VSCode tasks so that the appropriate build configuration
can be specified when you launch the task. The default configuration
remains `Debug`.
Additionally, add `streetsidesoftware.code-spell-checker` to the
suggested list of extensions.
Fixes: https://github.com/xamarin/xamarin-android/issues/4996
Fixes: https://github.com/xamarin/xamarin-android/issues/5009
Fixes: https://github.com/xamarin/xamarin-android/issues/5147
Changes: 1ac5333ec5...767f647151
* xamarin/monodroid@767f64715: [msbuild] Fast Deployment v2.0 (#1090)
* xamarin/monodroid@0f04ba56d: Merge pull request #1115 from xamarin/remove-xreitem
* xamarin/monodroid@d75341fc3: Remove provisionator file completely
* xamarin/monodroid@b62e8c693: Replace XreItem with supported Xcode and JavaJDK syntax
The Fast Deployment system used for debugging Xamarin.Android apps has
been completely re-written. This is mostly due to changes in Android
which means we can no longer use the external storage directory to
store assemblies.
Fast Deployment works by not including files which change often,
like assemblies, in the actual apk. This means the `.apk` will mostly
not need to be re-installed during a debugging/development session.
Instead the assemblies are "Fast Deployed" to a special directory where
a debug version of our runtime knows where to find them.
Historically this was on the external storage directory such as
/storage/emulated/0/Android/data/com.some.package
/mnt/shell/emulated/0/Android/data/com.some.package
/storage/sdcard/Android/data/com.some.package
With Android 11, these directories are no longer accessible. Instead,
we need to deploy the assemblies into the app's internal `files`
directory. This is usually located in `/data/data/@PACKAGE_NAME@`.
This is not a global writable folder, so we need to use the `run-as`
tool to run all the commands to copy the files into that directory.
The `run-as` tool does not always work on older devices. From this
point on Fast Deployment v2 will only be available on API-21+ devices.
If a certain device does not support the `run-as` tool, then you can
always fall back to debugging without Fast Deployment. While this is
slower, it should still work on most devices.
[`$(AndroidFastDeploymentType)`][0] is still supported. This will
deploy both assemblies, native libraries, typemaps, and `.dex` files to
the `files` directory. Support for Fast Deploying Android resources
and assets was removed in commit f0d565fe, as it required the use of
deprecated API's to work.
The Shared Runtime has also be removed in this new system. Previously,
we used to deploy the BCL and API specific assemblies via separate
`.apk` files. This new system removes the need for that. All the BCL
and API specific assemblies will be deployed to the `files` directory
like all the other assemblies.
The new system is on par with the existing system when it comes to
speed. More improvements are planned in future releases which should
make it much quicker.
Using the `samples\HelloWorld` project these are the performance
differences using `HelloWorld.csproj /restore /t:Install /v:n`:
* Deploy "from Clean"
* v1: 00:00:11.42
* v2: 00:00:11.78 [3% longer]
* Incrementally deploy C#-based change
* v1: 00:00:02.58
* v2: 00:00:02.43 [6% faster]
[0]: https://docs.microsoft.com/en-us/xamarin/android/deploy-test/building-apps/build-properties#androidfastdeploymenttype
There are various tests in `Xamarin.Android.Build.Tests` that execute
MSBuild tasks directly. This means the changes in #4820 are not quite
complete. We need to actually *run* the tests under .NET Core to see
if these tests would pass under a One .NET context.
The solution (you would think), would be to make the test assembly
`netstandard2.0` so you could run either:
> nunit3-console Xamarin.Android.Build.Tests.dll
> dotnet test Xamarin.Android.Build.Tests.dll
`nunit3-console` would execute the tests under .NET framework/Mono and
`dotnet test` would run under .NET Core or .NET 5+.
Unfortunately, `nunit3-console` can't run tests from a
`netstandard2.0` library!
So we multi-target:
<TargetFrameworks>net472;net5.0</TargetFrameworks>
Unfortunately, the `net5.0` causes MSBuild to fail with:
> msbuild Xamarin.Android.sln
...
(GetReferenceAssemblyPaths target) ->
C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Current\Bin\Microsoft.Common.CurrentVersion.targets(1177,5): error MSB3644: The reference assemblies for .NETFramework,Version=v5.0 were not found. To resolve this, install the Developer Pack (SDK/Targeting Pack) for this framework version or retarget your application. You can download .NET Framework Developer Packs at https://aka.ms/msbuild/developerpacks
I think there is some expectation to use `dotnet build` for .NET 5
instead. We don't want to move our *entire* build over to `dotnet
build` yet (we probably can't!), so instead we can do:
<TargetFrameworks>net472;netcoreapp3.1</TargetFrameworks>
This allows `msbuild Xamarin.Android.sln` to continue to work. This
might also be something that gets fixed in a future MSBuild version.
I updated various `.yaml` definitions so we can run NUnit tests via
`nunit3-console` or `dotnet test` as needed.
Other things that broke here:
* We need `Microsoft.NET.Test.Sdk` for `dotnet test` to work.
* `Builder.UseDotNet` can now be set based on a `#if` instead of an
NUnit parameter.
* `Xamarin.Android.Tools.Aidl` needs to be `netstandard2.0`. This
required including a `System.CodeDom` package.
* `Xamarin.Android.Build.Tasks` can't use `FSharp.Core` in
`netcoreapp3.1`. I just removed it, since it is not used.
* Updated various paths to `Xamarin.Android.Build.Tests.dll`.
* Usage of System.Drawing crashed on macOS. I replaced this with
ImageSharp: https://www.nuget.org/packages/SixLabors.ImageSharp/
Update to:
* NUnit 3.12.0
* NUnit.ConsoleRunner 3.11.1
* NUnit3TestAdapter 3.16.1
These are all different numbers, but these are the latest stable
versions on nuget.org.
I also went ahead and consolidated all NUnit `@(PackageReference)` to
a `NUnitReferences.projitems` file. This way we can list the versions
for all NUnit packages in one MSBuild file.
NUnit.ConsoleRunner was still listed in a few other files we will have
to manually update.
Bump to xamarin/monodroid/master@82bea9c6
Changes: 6e43a20e...82bea9c6
The `aapt2 compile` command runs in two modes. The one we currently
use is the `archive` mode: we call `aapt2 compile` with the `--dir`
argument tp gemerate one `.flata` archive for all the files. The
side effect of this is that even if you only change one file, it will
need to regenerate the entire `.flata` archive.
There is a second mode: rather than using `--dir` you just send in a
single file. This then writes a single `.flat` file to the output
directory. While this does mean you have to call `aapt2 compile` for
*every* file, it does mean we can leverage MSBuild's support for
partial targets. This means MSBuild will detect *only* the files
which changed and allow us to call `aapt2 compile` with just the
modified files.
One exception to this new system are references which use the
`%(AndroidSkipResourceProcessing)` metadata. In those cases the
chance of those libraries being updated on a regular basis is quite
low, so in that case using a `flata` archive will be better since the
files won't be changing often.
While this may impact initial build times, the goal is to make
incremental builds quicker. This is especially true for users which
use *lots* of `@(AndroidResource)` items.
A note regarding the `aapt2 daemon` mode: in order to write accented
characters we need to set the `Process.StandardInput` encoding to
UTF-8. This is not possible directly in .NET Standard 2.0. We have
to instead use `Console.InputEncoding`. Also note that we *cannot*
include a BOM when writing the commands. This is because `aapt2` will
try to parse the BOM as command characters.
Finally, the `aapt2 link` command sometimes reports it is "Done"
before it has even written the archive for the file. We can get into
a position where we think we are done but the file is not on disk.
Work around this by including a nasty wait which will poll for the
existence of the expected output file and only return when it exists.
The good news is we know at this point if the command failed or not,
so we can bypass the check on failure.
By using incremental builds, we improve incremental build times:
| Test | Latest Stable | Aapt2 Daemon |
|--------------|---------------|--------------|
| From Clean | 00:00:27.92 | 00:00:27.41 |
| No Changes | 00:00:03.14 | 00:00:03.72 |
| Alter Layout | 00:00:16.37 | 00:00:05.53 |
Note that **Alter Layout** with Aapt2 Daemon runs in 34% of the time.
`check-boot-times` is a tool to be used by the Hyper-V team to be
able to compare performance improvement progress.
Example of a run:
Testing emulator startup times for 1 execution(s). This may take several minutes.
Acceleration type: 0, WHPX (10.0.19041) is installed and usable.
Android emulator version 29.3.5.0 (build_id 6120838) (CL:N/A)
XamarinPerfTest Average Hot Boot Time for 1 run(s) out of 1 request(s): 4224 ms
XamarinPerfTestPixelWithSkin Average Cold Boot Time for 1 run(s) out of 1 request(s): 159600 ms
XamarinPerfTestPixelWithSkin Average Hot Boot Time for 1 run(s) out of 1 request(s): 2695 ms
Testing emulator startup times for 1 execution(s). This may take several minutes.
Acceleration type: 0, HAXM version 7.5.4 (4) is installed and usable.
Android emulator version 29.3.5.0 (build_id 6120838) (CL:N/A)
XamarinPerfTest Average Cold Boot Time for 1 run(s) out of 1 request(s): 23834 ms
XamarinPerfTest Average Hot Boot Time for 1 run(s) out of 1 request(s): 4021 ms
XamarinPerfTestPixelWithSkin Average Cold Boot Time for 1 run(s) out of 1 request(s): 41912 ms
XamarinPerfTestPixelWithSkin Average Hot Boot Time for 1 run(s) out of 1 request(s): 4584 ms
It also helps us track percentage of times emulator failed to boot.
When trying to run the `Run Xamarin.Android Build Tasks Unit Tests`
command in VSCode we get the following error now
error MSB4057: The target "RunNUnitTests" does not exist in the project.
This is because the `RunTest.targets` file is now only imported
when you run against the `Xamarin.Android.sln`, so we need
to update this command to use the correct command line.
`@(PackageReference)` packages install/restore into a default global
folder of `%userprofile%\.nuget\packages` (Windows) or
`$HOME/.nuget/packages` (Linux, macOS).
In order to avoid bloating the home directories on our machines used
locally and in CI, we'll reconfigure the `globalPackagesFolder` path
to point to a `packages` folder nested under `xamarin-android`.
This also allows us to continue to use "known" paths to certain tools
that are used by our tests, such as `nunit3-console.exe`.
Each test in `Xamarin.Android.Build.Tests` copies and uses the
`NuGet.config` file from the xamarin-android repo root. Now that a
`globalPackagesFolder` value is specified there, NuGet restore
behavior for all tests has changed.
A new `globalPackagesFolder` default has now been set for all tests
so that a common folder can be used rather than a `packages` folder
nested under each test directory. Additionally, some tests have been
updated to no longer run in parallel due to restore issues.
Co-Authored-By: Jonathan Peppers <jonathan.peppers@microsoft.com>
The new `Xamarin.Android.code-workspace` and related `.vscode/*`
files will improve the experience of developers to opening the root
folder of a xamarin-android checkout within VSCode.
Developers can build `Xamarin.Android.Build.Tasks.csproj` and
`Xamarin.Android.Build.Tests.csproj`, then run the unit tests.
Unit tests can then be run and debugged if the
[xunit-test-adapter][0] extension is installed.
[0]: https://marketplace.visualstudio.com/items?itemName=wghats.vscode-nxunit-test-adapter