2017-10-18 22:41:00 +03:00
|
|
|
<?xml version="1.0" encoding="utf-8"?>
|
|
|
|
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
2020-07-21 04:13:47 +03:00
|
|
|
<Import Project="$(MSBuildThisFileDirectory)build-tools\scripts\DotNet.targets" />
|
2019-08-22 21:48:10 +03:00
|
|
|
<Import Project="$(MSBuildThisFileDirectory)build-tools\scripts\ImportExportDocs.targets" />
|
2017-10-18 22:41:00 +03:00
|
|
|
<Import Project="$(MSBuildThisFileDirectory)build-tools\scripts\PrepareWindows.targets" Condition=" '$(OS)' == 'Windows_NT' " />
|
[api-compat] Provide API diffs around API breakage (#4362)
Context: https://github.com/xamarin/xamarin-android/pull/4356
Context: 54beb90bc0f9b003682fb8b907e2519817d8c567
Context: a20be392163df9aed72e9127368c9174ecdd4bdd
The use of `Microsoft.DotNet.ApiCompat.exe` added in 07e74771 has one
major deficiency:
The error messages reported by `Microsoft.DotNet.ApiCompat.exe` are
*awful* and borderline useless or misleading.
For example, consider commit PR #4356, which attempts to bring sanity
and consistency around `$(AndroidPlatformId)` and `Mono.Android.dll`
builds. It contains an API break, which we'll hand wave away and
accept for preview release purposes, in which the property type for
`Android.Telephony.CellInfoGsm.CellIdentity` changes from
`CellIdentityGsm` to `CellIdentity`:
// API-29
namespace Android.Telephony {
public sealed partial class CellInfoGsm: Android.Telephony.CellInfo, Android.OS.IParcelable {
public unsafe Android.Telephony.CellIdentityGsm CellIdentity {
}
}
// API-R
namespace Android.Telephony {
public sealed partial class CellInfoGsm : Android.Telephony.CellInfo, Android.OS.IParcelable {
public unsafe Android.Telephony.CellIdentity CellIdentity {
}
}
This is clearly a break. How does `Microsoft.DotNet.ApiCompat.exe`
report the breakage?
error : MembersMustExist : Member 'Android.Telephony.CellInfoGsm.CellIdentity.get()' does not exist in the implementation but it does exist in the contract.
Which is infuriatingly terrible. The message *implies* that
`Android.Telephony.CellInfoGsm.get_CellIdentity()` doesn't exist, but
it *does* exist. The problem is that the return type changed!
Or consider 54beb90b, in which we now emit a slew of default interface
members within the `Mono.Android.dll` binding, which *should* be API
compatible. `Microsoft.DotNet.ApiCompat.exe` complains as well:
InterfacesShouldHaveSameMembers : Interface member 'Java.Util.Functions.IUnaryOperator.Identity()' is present in the implementation but not in the contract.
What these messages have in common is that they provide no context,
lack important types, and in no way suggest how to *fix* the error
other than to just ignore it.
Overhaul this infrastructure so that crucial context is provided.
The context is provided by using "reference assembly source":
the [`Microsoft.DotNet.GenAPI.exe` utility][0] can be run on an
assembly to generate C# source code that shows the same API but no
implementation:
namespace Android.Accounts
{
[Android.Runtime.RegisterAttribute("android/accounts/AbstractAccountAuthenticator", DoNotGenerateAcw=true, ApiSince=5)]
public abstract partial class AbstractAccountAuthenticator : Java.Lang.Object
{
[Android.Runtime.RegisterAttribute("KEY_CUSTOM_TOKEN_EXPIRY", ApiSince=23)]
public const string KeyCustomTokenExpiry = "android.accounts.expiry";
[Android.Runtime.RegisterAttribute(".ctor", "(Landroid/content/Context;)V", "")]
public AbstractAccountAuthenticator(Android.Content.Context context) { }
Update the `src/Mono.Android` build so that after every build, when
`Microsoft.DotNet.ApiCompat.exe` fails we *also* run
`Microsoft.DotNet.GenAPI.exe` on the generated assembly, then run
`git diff -u` against the recently created assembly and the reference
assembly source for the contract assembly. This allows us to get
*useful diffs* in the API:
Task "Exec" (TaskId:570)
Task Parameter:Command=git diff --no-index "../../tests/api-compatibility/reference/Mono.Android.dll.cs" "/Volumes/Xamarin-Work/xamarin-android/bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v10.0/Mono.Android.dll.cs" (TaskId:570)
diff -u "../../tests/api-compatibility/reference/Mono.Android.dll.cs" "/Volumes/Xamarin-Work/xamarin-android/bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v10.0/Mono.Android.dll.cs" (TaskId:570)
--- ../../tests/api-compatibility/reference/Mono.Android.dll.cs 2020-03-05 13:20:59.000000000 -0500 (TaskId:570)
+++ /Volumes/Xamarin-Work/xamarin-android/bin/Debug/lib/xamarin.android/xbuild-frameworks/MonoAndroid/v10.0/Mono.Android.dll.cs 2020-03-05 13:40:12.000000000 -0500 (TaskId:570)
@@ -27,7 +27,7 @@ (TaskId:570)
{ (TaskId:570)
[Android.Runtime.RegisterAttribute("ACCEPT_HANDOVER", ApiSince=28)] (TaskId:570)
public const string AcceptHandover = "android.permission.ACCEPT_HANDOVER"; (TaskId:570)
- [Android.Runtime.RegisterAttribute("ACCESS_BACKGROUND_LOCATION")] (TaskId:570)
+ [Android.Runtime.RegisterAttribute("ACCESS_BACKGROUND_LOCATION", ApiSince=29)] (TaskId:570)
(The above changes are courtesy commmit 4cd20605, which added
`RegisterAttribute.ApiSince` on a large number of members.)
Finally, how do we update the "contract" `Mono.Android.dll` assembly?
Add a new `tests/api-compatibility/api-compatibility.targets` file
which contains a `UpdateMonoAndroidContract` target which will update
`tests/api-compatibility/reference/Mono.Android.zip` with the contents
of a `cil-strip`'d `Mono.Android.dll` and updated "reference assembly
source".
`Mono.Android.zip` contains a contract from Xamarin.Android 10.2.0.100
for `$(TargetFrameworkVersion)` v10.0.
[0]: https://github.com/dotnet/arcade/tree/bc4fa8e7149769db4efd466f160417a32b11f0bf/src/Microsoft.DotNet.GenAPI
2020-03-06 22:00:25 +03:00
|
|
|
<Import Project="$(MSBuildThisFileDirectory)tests\api-compatibility\api-compatibility.targets" />
|
2017-10-18 22:41:00 +03:00
|
|
|
</Project>
|