Skip to content

Commit

Permalink
[One .NET] no longer produce .apk for IDE builds
Browse files Browse the repository at this point in the history
Related: dotnet#5436

In "legacy" Xamarin.Android, we have the following behavior:

1. The `Build` target does not produce an `.apk` or sign it.
2. Only `SignAndroidPackage` (or `Install`) would do this.

So if you hit F6, Ctrl+B, Command+B, etc. in Visual Studio, you don't
have to wait on a valid `.apk` file to be produced to get build
results. This is useful for incremental build performance -- and
developers' habit of hitting build all the time.

`dotnet build` has different behavior, because it should inherently
produce something that is runnable. `dotnet build` currently produces
an `.apk` file and signs it.

To match "legacy" Xamarin.Android's behavior in IDEs we could do
something different while in Visual Studio when
`$(BuildingInsideVisualStudio)` is set. This way we get the desired
behavior:

* `dotnet build` at the command-line produces a signed `.apk` file.
* IDEs will not produce an `.apk` on `Build`. However, when "deploy"
  occurs, the `Install` target will handle producing an `.apk` file as
  needed.

This allowed me to update the `PerformanceTest` that was adding
additional time under .NET 6 for producing `.apk` files. Our MSBuild
tests always set `$(BuildingInsideVisualStudio)` for testing.

I also updated the `[Retry]` attributes so the value was in one place.
  • Loading branch information
jonathanpeppers committed Jan 29, 2021
1 parent c33f557 commit b91d719
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 30 deletions.
5 changes: 5 additions & 0 deletions Documentation/guides/OneDotNet.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,11 @@ Play, ad-hoc distribution, etc. It could be able to sign the `.apk` or
`.aab` with different keys. As a starting point, this will currently
copy the output to a `publish` directory on disk.

_NOTE: Behavior inside IDEs will differ. The `Build` target will not
produce an `.apk` file if `$(BuildingInsideVisualStudio)` is `true`.
IDEs will call the `Install` target for deployment, which will produce
the `.apk` file. This behavior matches "legacy" Xamarin.Android._

[illink]: https://github.com/mono/linker/blob/master/src/linker/README.md

### dotnet run
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,13 @@ projects, these properties are set in Xamarin.Android.Legacy.targets.
$(BuildDependsOn);
_CompileDex;
$(_AfterCompileDex);
</BuildDependsOn>
<!--
Outside IDEs: we need to produce an .apk/.aab and sign
Inside IDEs: the Install target produces .apk/.aab files & signs
-->
<BuildDependsOn Condition=" '$(BuildingInsideVisualStudio)' != 'true' ">
$(BuildDependsOn);
_CopyPackage;
_Sign;
</BuildDependsOn>
Expand Down
56 changes: 26 additions & 30 deletions tests/MSBuildDeviceIntegration/Tests/PerformanceTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ namespace Xamarin.Android.Build.Tests
[TestFixture, NonParallelizable]
public class PerformanceTest : DeviceTest
{
const int Retry = 2;
static readonly Dictionary<string, int> csv_values = new Dictionary<string, int> ();

[OneTimeSetUp]
Expand Down Expand Up @@ -43,7 +44,7 @@ public static void Setup ()
}
}

void Profile (ProjectBuilder builder, Action<ProjectBuilder> action, bool additionalTimeForSigning, [CallerMemberName] string caller = null)
void Profile (ProjectBuilder builder, Action<ProjectBuilder> action, [CallerMemberName] string caller = null)
{
if (!csv_values.TryGetValue (caller, out int expected)) {
Assert.Fail ($"No timeout value found for a key of {caller}");
Expand All @@ -52,11 +53,6 @@ void Profile (ProjectBuilder builder, Action<ProjectBuilder> action, bool additi
if (Builder.UseDotNet) {
//TODO: there is currently a slight performance regression in .NET 6
expected += 500;

//NOTE: some tests run `dotnet build`, which would sign the .apk
if (additionalTimeForSigning) {
expected += 500;
}
}

action (builder);
Expand Down Expand Up @@ -111,20 +107,20 @@ XamarinAndroidApplicationProject CreateApplicationProject ()
}

[Test]
[Retry (2)]
[Retry (Retry)]
public void Build_From_Clean_DontIncludeRestore ()
{
var proj = CreateApplicationProject ();
using (var builder = CreateBuilderWithoutLogFile ()) {
builder.AutomaticNuGetRestore = false;
builder.Target = "Build";
builder.Restore (proj);
Profile (builder, b => b.Build (proj), additionalTimeForSigning: true);
Profile (builder, b => b.Build (proj));
}
}

[Test]
[Retry (2)]
[Retry (Retry)]
public void Build_No_Changes ()
{
var proj = CreateApplicationProject ();
Expand All @@ -135,20 +131,20 @@ public void Build_No_Changes ()
builder.AutomaticNuGetRestore = false;

// Profile no changes
Profile (builder, b => b.Build (proj), additionalTimeForSigning: false);
Profile (builder, b => b.Build (proj));

// Change C# and build
proj.MainActivity += $"{Environment.NewLine}//comment";
proj.Touch ("MainActivity.cs");
builder.Build (proj);

// Profile no changes
Profile (builder, b => b.Build (proj), additionalTimeForSigning: false);
Profile (builder, b => b.Build (proj));
}
}

[Test]
[Retry (2)]
[Retry (Retry)]
public void Build_CSharp_Change ()
{
var proj = CreateApplicationProject ();
Expand All @@ -161,12 +157,12 @@ public void Build_CSharp_Change ()
// Profile C# change
proj.MainActivity += $"{Environment.NewLine}//comment";
proj.Touch ("MainActivity.cs");
Profile (builder, b => b.Build (proj), additionalTimeForSigning: false);
Profile (builder, b => b.Build (proj));
}
}

[Test]
[Retry (2)]
[Retry (Retry)]
public void Build_AndroidResource_Change ()
{
var proj = CreateApplicationProject ();
Expand All @@ -178,12 +174,12 @@ public void Build_AndroidResource_Change ()
// Profile AndroidResource change
proj.LayoutMain += $"{Environment.NewLine}<!--comment-->";
proj.Touch ("Resources\\layout\\Main.axml");
Profile (builder, b => b.Build (proj), additionalTimeForSigning: true);
Profile (builder, b => b.Build (proj));
}
}

[Test]
[Retry (2)]
[Retry (Retry)]
public void Build_AndroidAsset_Change ()
{
var bytes = new byte [1024*1024*10];
Expand Down Expand Up @@ -215,12 +211,12 @@ public void Build_AndroidAsset_Change ()
libBuilder.Build (lib);
builder.Target = "SignAndroidPackage";
// Profile AndroidAsset change
Profile (builder, b => b.Build (proj), additionalTimeForSigning: false);
Profile (builder, b => b.Build (proj));
}
}

[Test]
[Retry (2)]
[Retry (Retry)]
public void Build_Designer_Change ()
{
var proj = CreateApplicationProject ();
Expand All @@ -236,12 +232,12 @@ public void Build_Designer_Change ()
builder.RunTarget (proj, "SetupDependenciesForDesigner", parameters: parameters);

// Profile AndroidResource change
Profile (builder, b => b.Build (proj), additionalTimeForSigning: true);
Profile (builder, b => b.Build (proj));
}
}

[Test]
[Retry (2)]
[Retry (Retry)]
public void Build_JLO_Change ()
{
var className = "Foo";
Expand All @@ -257,12 +253,12 @@ public void Build_JLO_Change ()
// Profile Java.Lang.Object rename
className = "Foo2";
proj.Touch ("Foo.cs");
Profile (builder, b => b.Build (proj), additionalTimeForSigning: true);
Profile (builder, b => b.Build (proj));
}
}

[Test]
[Retry (2)]
[Retry (Retry)]
public void Build_AndroidManifest_Change ()
{
var proj = CreateApplicationProject ();
Expand All @@ -274,12 +270,12 @@ public void Build_AndroidManifest_Change ()
// Profile AndroidManifest.xml change
proj.AndroidManifest += $"{Environment.NewLine}<!--comment-->";
proj.Touch ("Properties\\AndroidManifest.xml");
Profile (builder, b => b.Build (proj), additionalTimeForSigning: true);
Profile (builder, b => b.Build (proj));
}
}

[Test]
[Retry (2)]
[Retry (Retry)]
public void Build_CSProj_Change ()
{
var proj = CreateApplicationProject ();
Expand All @@ -292,7 +288,7 @@ public void Build_CSProj_Change ()
proj.Sources.Add (new BuildItem ("None", "Foo.txt") {
TextContent = () => "Bar",
});
Profile (builder, b => b.Build (proj), additionalTimeForSigning: true);
Profile (builder, b => b.Build (proj));
}
}

Expand All @@ -314,7 +310,7 @@ public void Build_CSProj_Change ()
[Test]
[TestCaseSource (nameof (XAML_Change))]
[Category ("UsesDevice")]
[Retry (2)]
[Retry (Retry)]
public void Build_XAML_Change (bool produceReferenceAssembly, bool install)
{
if (install) {
Expand Down Expand Up @@ -381,16 +377,16 @@ public void Build_XAML_Change (bool produceReferenceAssembly, bool install)
lib.Touch ("MyPage.xaml");
libBuilder.Build (lib, doNotCleanupOnUpdate: true);
if (install) {
Profile (appBuilder, b => b.Install (app, doNotCleanupOnUpdate: true), additionalTimeForSigning: false, caller);
Profile (appBuilder, b => b.Install (app, doNotCleanupOnUpdate: true), caller);
} else {
Profile (appBuilder, b => b.Build (app, doNotCleanupOnUpdate: true), additionalTimeForSigning: false, caller);
Profile (appBuilder, b => b.Build (app, doNotCleanupOnUpdate: true), caller);
}
}
}

[Test]
[Category ("UsesDevice")]
[Retry (2)]
[Retry (Retry)]
public void Install_CSharp_Change ()
{
AssertCommercialBuild (); // This test will fail without Fast Deployment
Expand All @@ -406,7 +402,7 @@ public void Install_CSharp_Change ()
// Profile C# change
proj.MainActivity += $"{Environment.NewLine}//comment";
proj.Touch ("MainActivity.cs");
Profile (builder, b => b.Install (proj), additionalTimeForSigning: false);
Profile (builder, b => b.Install (proj));
}
}
}
Expand Down

0 comments on commit b91d719

Please sign in to comment.