Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Xamarin.Android.Build.Utilities] Add AndroidVersions #599

Merged
merged 1 commit into from
Aug 23, 2017

Conversation

jonpryor
Copy link
Member

Commit 8e7d37b is a sign of duplication: in order to use a
Mono.Android.dll binding assembly, not only do we need to build
the binding assembly, but we also need to update
Xamarin.Android.Build.Utilities.dll to "know" about the new binding
version (to map API level to $(TargetFrameworkVersion)).

Even "better" (worse), if the new API level is a preview, there is
no consistent API level. For example, with API-O, android.jar
isn't at
$(AndroidSdkDirectory)\platforms\android-@API_LEVEL@\android.jar,
where @API_LEVEL@ is 26 (because various codepaths require that the
"api level" be an integer). Instead, it's installed at
$(AndroidSdkDirectory)\platforms\android-O\android.jar, where
O is the "id" of the preview API level.

This "id" is "leaky", in turn requiring that
Xamarin.Android.Build.Tasks.dll also be updated to deal with the
mappings.

Even "better" (worse), if we forget to cross all our our 't's and
dot all of our 'i's, we'll have a binding assembly which can't be
used. (Which is why we needed commit 8e7d37b; without it, the API-O
binding can't be used!)

This is all obviously madness. ;-)

Clean this mess up:

  1. Update src/Mono.Android to create a new AndroidApiInfo.xml
    file within the $(TargetFrameworkDriectory) directory.
    This will contain all the information needed to map Android API
    levels to Ids and Android OS versions and
    $(TargetFrameworkVersion) values.

    <AndroidApiInfo>
      <Id>10</Id>
      <Level>10</Level>
      <Name>Gingerbread</Name>
      <Version>v2.3</Version>
    </AndroidApiInfo>
    
  2. Add a new Xamarin.Android.Build.Utilities.AndroidVersions type
    which looks for and parses these new AndroidApiInfo.xml files.

  3. Fixup all the other places using AndroidVersion.KnownVersions
    and related members to instead use AndroidVersions.

  4. Deprecate all the old APIs which rely on hardcoded data.

The advantage to all this is that we can support new API level
bindings by just building a new Mono.Android.dll and placing an
AndroidApiInfo.xml into the appropriate location (next to
Mono.Android.dll). No further code changes would be required.

@jonpryor jonpryor added do-not-merge PR should not be merged. enhancement Proposed change to current functionality. labels May 20, 2017
@jonpryor jonpryor assigned garuma and dellis1972 and unassigned garuma and dellis1972 May 20, 2017
@jonpryor jonpryor requested review from dellis1972 and garuma May 20, 2017 03:37
@jonpryor jonpryor force-pushed the jonp-probe-known-versions branch from be66d1a to 067d133 Compare May 20, 2017 03:40
@@ -4,6 +4,7 @@ namespace Xamarin.Android.Build.Utilities
{
public class AndroidVersion
{
[Obsolete ("Use AndroidVersions.MaxVersion.ApiLevel", error:true)]
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

...which doesn't exist. Oops.

Anyway, it's not used in this project, due to error:true. Do we really need to track MaxApiLevel?

@garuma
Copy link
Contributor

garuma commented May 20, 2017

Excellent. Now the question is how do we propagate that to the IDEs. I see two options:

  • Update androidtools to also lookup that file instead of the hardcoded list. It makes it possible to have newer XA work with the same IDE but we still get code duplication (albeit we don't have to make change to it)
  • Expose that API information through an MSBuild target outputting items with the right metadata that is stored by the IDE. No androidtools needed.

Both approach have pro and cons, first might be easier to implement for now though

@jonpryor
Copy link
Member Author

  • Expose that API information through an MSBuild target outputting items with the right metadata that is stored by the IDE. No androidtools needed.

That's an interesting idea, but if we went for the MSBuild-specific approach, why bother with half of this code at all? We could provide AndroidApiInfo.targets files, one per API level, and <Import/> the mess of them within a <Target/>.

(That might not be a bad idea, actually. More thought is required.)

As for the integration idea, there is already (kinda, sorta) a plan (-ish) for that: xamarin-android-tools, which is kinda/sorta the "open-source" parts of androidtools. We'd "just" need to update the IDEs to use xamarin-android-tools.

However, I want to do some API cleanups ("breaks"!) as part of this, which is a discussion for another time. It's basically the only time we can do such cleanups, as it would be in a new assembly...

@mhutch
Copy link
Contributor

mhutch commented May 23, 2017

I don't think it really make sense to get this info though MSBuild calls since it doesn't depend on the state of the project at all.

@jonpryor
Copy link
Member Author

jonpryor commented Aug 2, 2017

The problem in macOS+xbuild PR Build 952 is our old nemesis, xbuild, which looks at GetReferenceAssemblyPaths.RootPath after $XBUILD_FRAMEWORK_FOLDERS_PATH and /Library/Frameworks/Mono.framework/External. This means that when Xamarin.Android.NUniteLite.csproj is built, the wrong directory used:

Building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android-pr-builder/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android-pr-builder/xamarin-android/bin/Debug/lib/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
         Target _GetReferenceAssemblyPaths:
         Task "GetReferenceAssemblyPaths"
                 Using task GetReferenceAssemblyPaths from Microsoft.Build.Tasks.GetReferenceAssemblyPaths, Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
                 Looking for framework 'MonoAndroid,Version=v1.0' in root path '/Library/Frameworks/Mono.framework/External/xbuild-frameworks'
                 Found framework definition list '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/RedistList/FrameworkList.xml' for framework 'MonoAndroid,Version=v1.0'
         Done executing task "GetReferenceAssemblyPaths"
         Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android-pr-builder/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj".
Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android-pr-builder/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android-pr-builder/xamarin-android/bin/Debug/lib/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.

Since the system-wide directory is used here -- a directory which does not, cannot, contain the new AndroidApiInfo.xml files -- everything that depends on AndroidVersions fails. (This despite the fact that I do not want to be using the system-wide directory!)

There are two plausible fixes that bear investigation:

  1. Dump xbuild, migrate to msbuild. Note that the macOS+msbuild PR Build succeeded. This is because msbuild is awesome, except for the terrible parts I hate.

    The problem with this is that msbuild on Linux is a bit of an unknown; @atsushieno has lost lots of time trying to get msbuild working on his machine. If there's a Linux distro with a prebuilt msbuild which works, that's one thing, but that's not the situation for everyone.

  2. Don't build with xbuild, build with xabuild (which overrides $XBUILD_FRAMEWORK_FOLDERS_PATH).

    This should allow things to work, but I'm not sure what the downlevel effects may be.

@jonpryor jonpryor force-pushed the jonp-probe-known-versions branch 3 times, most recently from 3bf9f56 to 95eab39 Compare August 2, 2017 20:15
@jonpryor
Copy link
Member Author

jonpryor commented Aug 2, 2017

Next in our comedy of "ow! make it stop!", using xabuild to build things kind of worked: macOS+xbuild was able to build (if not pass all the unit tests), while macOS+msbuild couldn't build, because msbuild couldn't resolve .NETFramework,Version=v4.6.1.

Fix that issue by improving xabuild to not only symlink the contents of $mono_prefix/lib/mono/xbuild/* into bin/Debug/lib/xamarin.android/xbuild, but to also symlink the contents of $mono_prefix/lib/mono/xbuild-frameworks/* into bin/Debug/lib/xamarin.android/xbuild-frameworks. This allows macOS+msbuild to build, but broke macOS+xbuild.

(Back and forth we swing!)

The most recent failure is "fun": the <GetReferenceAssemblyPaths/> task reads document('FrameworkList.xml')/FileList/@TargetFrameworkDirectory, and appends that to the value of $(TargetFrameworkRootPath)/the probed framework directory.

For context, redistlist_dir=bin/Debug/lib/xamarin.android/xbuild-frameworks/.NETFramework/v4.6.1/RedistList, and framework_dir=..\..\..\..\4.6.1-api. The result is that, after <GetReferenceAssemblyPaths/> completes, xbuild is trying to look for assemblies in the path bin/Debug/lib/xamarin.android/4.6.1-api, which does not exist.

(Hacking xbuild internals for fun and profit?)

At this point, I'm not sure how to fix this, much less elegantly fix this, short of "kill xbuild, msbuild all the things!"

Which, to be fair, is looking really appealing right now...

@jonpryor jonpryor force-pushed the jonp-probe-known-versions branch from 95eab39 to 9c8925a Compare August 3, 2017 18:05
jonpryor added a commit to jonpryor/xamarin-android that referenced this pull request Aug 3, 2017
Commit 8e7d37b is a sign of duplication: in order to use a
`Mono.Android.dll` binding assembly, not only do we need to *build*
the binding assembly, but we *also* need to update
`Xamarin.Android.Build.Utilities.dll` to "know" about the new binding
version (to map API level to `$(TargetFrameworkVersion)`).

Even "better" (worse), if the new API level is a *preview*, there is
no *consistent* API level. For example, with API-O, `android.jar`
isn't at
`$(AndroidSdkDirectory)\platforms\android-@API_LEVEL@\android.jar`,
where `@API_LEVEL@` is 26 (because various codepaths require that the
"api level" be an integer). Instead, it's installed at
`$(AndroidSdkDirectory)\platforms\android-O\android.jar`, where
`O` is the "id" of the preview API level.

This "id" is "leaky", in turn requiring that
`Xamarin.Android.Build.Tasks.dll` *also* be updated to deal with the
mappings.

Even "better" (worse), if we *forget* to cross all our our 't's and
dot all of our 'i's, we'll have a binding assembly which can't be
used. (Which is why we needed commit 8e7d37b; without it, the API-O
binding can't be used!)

This is all obviously madness. ;-)

Clean this mess up:

 1. Update `src/Mono.Android` to create a new `AndroidApiInfo.xml`
    file within the `$(TargetFrameworkVersion)` directory.
    This will contain all the information needed to map Android API
    levels to Ids and Android OS versions and
    `$(TargetFrameworkVersion)` values.

    ```
    <AndroidApiInfo>
      <Id>10</Id>
      <Level>10</Level>
      <Name>Gingerbread</Name>
      <Version>v2.3</Version>
    </AndroidApiInfo>
    ```

 2. Add a new `Xamarin.Android.Build.Utilities.AndroidVersions` type
    which looks for and parses these new `AndroidApiInfo.xml` files.

 3. Fixup all the other places using `AndroidVersion.KnownVersions`
    and related members to instead use `AndroidVersions`.

 4. Deprecate all the old APIs which rely on hardcoded data.

The advantage to all this is that we can support new API level
bindings by just building a new `Mono.Android.dll` and placing an
`AndroidApiInfo.xml` into the appropriate location (next to
`Mono.Android.dll`). No further code changes would be required.

Related: The build system still has a nasy habit of using system-wide
directories to resolve files we'd really rather it not, e.g. in
[xamarin-android/master build dotnet#503][m503]:

[m503]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/503/consoleText

	Building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _GetReferenceAssemblyPaths:
	  Task "GetReferenceAssemblyPaths"
	    Using task GetReferenceAssemblyPaths from Microsoft.Build.Tasks.GetReferenceAssemblyPaths, Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
	    Looking for framework 'MonoAndroid,Version=v1.0' in root path '/Library/Frameworks/Mono.framework/External/xbuild-frameworks'
	    Found framework definition list '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/RedistList/FrameworkList.xml' for framework 'MonoAndroid,Version=v1.0'
	  Done executing task "GetReferenceAssemblyPaths"
	  Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj".
	Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _SetLatestTargetFrameworkVersion:
	  Task "ResolveSdks"
	    ReferenceAssemblyPaths:
	      /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/

Note the use of the path
`/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0`.

This *was* "fine" -- if undesirable -- but with the introduction of
`AndroidVersions` and `AndroidApiInfo.xml` files within the frameworks
directory, everything falls apart, becuase the system install
*does not have* the `AndroidApiInfo.xml` files, so
*NO API LEVELS ARE FOUND*.

Oops.

The only way to fix this is to use `$XBUILD_FRAMEWORK_FOLDERS_PATH`,
and the sanest way to do *that* is to use `tools/scripts/xabuild` for
the primary build.

Unfortunately, using `xabuild` for the primary build breaks the
`msbuild`-based build, as it can't resolve the
`.NETFramework,Version=v4.6.1` framework.

Context: dotnet#599 (comment)

Split the difference here by introducing `$(_SLN_BUILD)`: use
`xabuild` when building with `xbuild`, and continue using `msbuild`
when building with `msbuild`.
@jonpryor jonpryor force-pushed the jonp-probe-known-versions branch from 9c8925a to cd7da91 Compare August 16, 2017 20:36
jonpryor added a commit to jonpryor/xamarin-android that referenced this pull request Aug 16, 2017
Commit 8e7d37b is a sign of duplication: in order to use a
`Mono.Android.dll` binding assembly, not only do we need to *build*
the binding assembly, but we *also* need to update
`Xamarin.Android.Build.Utilities.dll` to "know" about the new binding
version (to map API level to `$(TargetFrameworkVersion)`).

Even "better" (worse), if the new API level is a *preview*, there is
no *consistent* API level. For example, with API-O, `android.jar`
isn't at
`$(AndroidSdkDirectory)\platforms\android-@API_LEVEL@\android.jar`,
where `@API_LEVEL@` is 26 (because various codepaths require that the
"api level" be an integer). Instead, it's installed at
`$(AndroidSdkDirectory)\platforms\android-O\android.jar`, where
`O` is the "id" of the preview API level.

This "id" is "leaky", in turn requiring that
`Xamarin.Android.Build.Tasks.dll` *also* be updated to deal with the
mappings.

Even "better" (worse), if we *forget* to cross all our our 't's and
dot all of our 'i's, we'll have a binding assembly which can't be
used. (Which is why we needed commit 8e7d37b; without it, the API-O
binding can't be used!)

This is all obviously madness. ;-)

Clean this mess up:

 1. Update `src/Mono.Android` to create a new `AndroidApiInfo.xml`
    file within the `$(TargetFrameworkVersion)` directory.
    This will contain all the information needed to map Android API
    levels to Ids and Android OS versions and
    `$(TargetFrameworkVersion)` values.

    ```
    <AndroidApiInfo>
      <Id>10</Id>
      <Level>10</Level>
      <Name>Gingerbread</Name>
      <Version>v2.3</Version>
    </AndroidApiInfo>
    ```

 2. Add a new `Xamarin.Android.Build.Utilities.AndroidVersions` type
    which looks for and parses these new `AndroidApiInfo.xml` files.

 3. Fixup all the other places using `AndroidVersion.KnownVersions`
    and related members to instead use `AndroidVersions`.

 4. Remove all the old APIs which rely on hardcoded data.

The advantage to all this is that we can support new API level
bindings by just building a new `Mono.Android.dll` and placing an
`AndroidApiInfo.xml` into the appropriate location (next to
`Mono.Android.dll`). No further code changes would be required.

Related: The build system still has a nasy habit of using system-wide
directories to resolve files we'd really rather it not, e.g. in
[xamarin-android/master build dotnet#503][m503]:

[m503]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/503/consoleText

	Building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _GetReferenceAssemblyPaths:
	  Task "GetReferenceAssemblyPaths"
	    Using task GetReferenceAssemblyPaths from Microsoft.Build.Tasks.GetReferenceAssemblyPaths, Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
	    Looking for framework 'MonoAndroid,Version=v1.0' in root path '/Library/Frameworks/Mono.framework/External/xbuild-frameworks'
	    Found framework definition list '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/RedistList/FrameworkList.xml' for framework 'MonoAndroid,Version=v1.0'
	  Done executing task "GetReferenceAssemblyPaths"
	  Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj".
	Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _SetLatestTargetFrameworkVersion:
	  Task "ResolveSdks"
	    ReferenceAssemblyPaths:
	      /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/

Note the use of the path
`/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0`.

This *was* "fine" -- if undesirable -- but with the introduction of
`AndroidVersions` and `AndroidApiInfo.xml` files within the frameworks
directory, everything falls apart, becuase the system install
*does not have* the `AndroidApiInfo.xml` files, so
*NO API LEVELS ARE FOUND*.

Oops.

The only way to fix this is to use `$XBUILD_FRAMEWORK_FOLDERS_PATH`,
and the sanest way to do *that* is to use `tools/scripts/xabuild` for
the primary build.

Unfortunately, using `xabuild` for the primary build breaks the
`msbuild`-based build, as it can't resolve the
`.NETFramework,Version=v4.6.1` framework.

Context: dotnet#599 (comment)

Split the difference here by introducing `$(_SLN_BUILD)`: use
`xabuild` when building with `xbuild`, and continue using `msbuild`
when building with `msbuild`.
@jonpryor jonpryor force-pushed the jonp-probe-known-versions branch from cd7da91 to 8728168 Compare August 16, 2017 20:42
jonpryor added a commit to jonpryor/xamarin-android that referenced this pull request Aug 16, 2017
Commit 8e7d37b is a sign of duplication: in order to use a
`Mono.Android.dll` binding assembly, not only do we need to *build*
the binding assembly, but we *also* need to update
`Xamarin.Android.Build.Utilities.dll` to "know" about the new binding
version (to map API level to `$(TargetFrameworkVersion)`).

Even "better" (worse), if the new API level is a *preview*, there is
no *consistent* API level. For example, with API-O, `android.jar`
isn't at
`$(AndroidSdkDirectory)\platforms\android-@API_LEVEL@\android.jar`,
where `@API_LEVEL@` is 26 (because various codepaths require that the
"api level" be an integer). Instead, it's installed at
`$(AndroidSdkDirectory)\platforms\android-O\android.jar`, where
`O` is the "id" of the preview API level.

This "id" is "leaky", in turn requiring that
`Xamarin.Android.Build.Tasks.dll` *also* be updated to deal with the
mappings.

Even "better" (worse), if we *forget* to cross all our our 't's and
dot all of our 'i's, we'll have a binding assembly which can't be
used. (Which is why we needed commit 8e7d37b; without it, the API-O
binding can't be used!)

This is all obviously madness. ;-)

Clean this mess up:

 1. Update `src/Mono.Android` to create a new `AndroidApiInfo.xml`
    file within the `$(TargetFrameworkVersion)` directory.
    This will contain all the information needed to map Android API
    levels to Ids and Android OS versions and
    `$(TargetFrameworkVersion)` values.

    ```
    <AndroidApiInfo>
      <Id>10</Id>
      <Level>10</Level>
      <Name>Gingerbread</Name>
      <Version>v2.3</Version>
    </AndroidApiInfo>
    ```

 2. Add a new `Xamarin.Android.Build.Utilities.AndroidVersions` type
    which looks for and parses these new `AndroidApiInfo.xml` files.

 3. Fixup all the other places using `AndroidVersion.KnownVersions`
    and related members to instead use `AndroidVersions`.

 4. Remove all the old APIs which rely on hardcoded data.

The advantage to all this is that we can support new API level
bindings by just building a new `Mono.Android.dll` and placing an
`AndroidApiInfo.xml` into the appropriate location (next to
`Mono.Android.dll`). No further code changes would be required.

Related: The build system still has a nasy habit of using system-wide
directories to resolve files we'd really rather it not, e.g. in
[xamarin-android/master build dotnet#503][m503]:

[m503]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/503/consoleText

	Building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _GetReferenceAssemblyPaths:
	  Task "GetReferenceAssemblyPaths"
	    Using task GetReferenceAssemblyPaths from Microsoft.Build.Tasks.GetReferenceAssemblyPaths, Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
	    Looking for framework 'MonoAndroid,Version=v1.0' in root path '/Library/Frameworks/Mono.framework/External/xbuild-frameworks'
	    Found framework definition list '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/RedistList/FrameworkList.xml' for framework 'MonoAndroid,Version=v1.0'
	  Done executing task "GetReferenceAssemblyPaths"
	  Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj".
	Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _SetLatestTargetFrameworkVersion:
	  Task "ResolveSdks"
	    ReferenceAssemblyPaths:
	      /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/

Note the use of the path
`/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0`.

This *was* "fine" -- if undesirable -- but with the introduction of
`AndroidVersions` and `AndroidApiInfo.xml` files within the frameworks
directory, everything falls apart, becuase the system install
*does not have* the `AndroidApiInfo.xml` files, so
*NO API LEVELS ARE FOUND*.

Oops.

The only way to fix this is to use `$XBUILD_FRAMEWORK_FOLDERS_PATH`,
and the sanest way to do *that* is to use `tools/scripts/xabuild` for
the primary build.

Unfortunately, using `xabuild` for the primary build breaks the
`msbuild`-based build, as it can't resolve the
`.NETFramework,Version=v4.6.1` framework.

Context: dotnet#599 (comment)

Split the difference here by introducing `$(_SLN_BUILD)`: use
`xabuild` when building with `xbuild`, and continue using `msbuild`
when building with `msbuild`.
<Name>O Preview</Name>
<Level>26</Level>
<Id>O</Id>
<Stable>False</Stable>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should probably change this to True...

@jonpryor jonpryor force-pushed the jonp-probe-known-versions branch from 8728168 to 570bcda Compare August 16, 2017 20:45
jonpryor added a commit to jonpryor/xamarin-android that referenced this pull request Aug 16, 2017
Commit 8e7d37b is a sign of duplication: in order to use a
`Mono.Android.dll` binding assembly, not only do we need to *build*
the binding assembly, but we *also* need to update
`Xamarin.Android.Build.Utilities.dll` to "know" about the new binding
version (to map API level to `$(TargetFrameworkVersion)`).

Even "better" (worse), if the new API level is a *preview*, there is
no *consistent* API level. For example, with API-O, `android.jar`
isn't at
`$(AndroidSdkDirectory)\platforms\android-@API_LEVEL@\android.jar`,
where `@API_LEVEL@` is 26 (because various codepaths require that the
"api level" be an integer). Instead, it's installed at
`$(AndroidSdkDirectory)\platforms\android-O\android.jar`, where
`O` is the "id" of the preview API level.

This "id" is "leaky", in turn requiring that
`Xamarin.Android.Build.Tasks.dll` *also* be updated to deal with the
mappings.

Even "better" (worse), if we *forget* to cross all our our 't's and
dot all of our 'i's, we'll have a binding assembly which can't be
used. (Which is why we needed commit 8e7d37b; without it, the API-O
binding can't be used!)

This is all obviously madness. ;-)

Clean this mess up:

 1. Update `src/Mono.Android` to create a new `AndroidApiInfo.xml`
    file within the `$(TargetFrameworkVersion)` directory.
    This will contain all the information needed to map Android API
    levels to Ids and Android OS versions and
    `$(TargetFrameworkVersion)` values.

    ```
    <AndroidApiInfo>
      <Id>10</Id>
      <Level>10</Level>
      <Name>Gingerbread</Name>
      <Version>v2.3</Version>
    </AndroidApiInfo>
    ```

 2. Add a new `Xamarin.Android.Build.Utilities.AndroidVersions` type
    which looks for and parses these new `AndroidApiInfo.xml` files.

 3. Fixup all the other places using `AndroidVersion.KnownVersions`
    and related members to instead use `AndroidVersions`.

 4. Remove all the old APIs which rely on hardcoded data.

The advantage to all this is that we can support new API level
bindings by just building a new `Mono.Android.dll` and placing an
`AndroidApiInfo.xml` into the appropriate location (next to
`Mono.Android.dll`). No further code changes would be required.

Related: The build system still has a nasy habit of using system-wide
directories to resolve files we'd really rather it not, e.g. in
[xamarin-android/master build dotnet#503][m503]:

[m503]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/503/consoleText

	Building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _GetReferenceAssemblyPaths:
	  Task "GetReferenceAssemblyPaths"
	    Using task GetReferenceAssemblyPaths from Microsoft.Build.Tasks.GetReferenceAssemblyPaths, Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
	    Looking for framework 'MonoAndroid,Version=v1.0' in root path '/Library/Frameworks/Mono.framework/External/xbuild-frameworks'
	    Found framework definition list '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/RedistList/FrameworkList.xml' for framework 'MonoAndroid,Version=v1.0'
	  Done executing task "GetReferenceAssemblyPaths"
	  Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj".
	Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _SetLatestTargetFrameworkVersion:
	  Task "ResolveSdks"
	    ReferenceAssemblyPaths:
	      /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/

Note the use of the path
`/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0`.

This *was* "fine" -- if undesirable -- but with the introduction of
`AndroidVersions` and `AndroidApiInfo.xml` files within the frameworks
directory, everything falls apart, becuase the system install
*does not have* the `AndroidApiInfo.xml` files, so
*NO API LEVELS ARE FOUND*.

Oops.

The only way to fix this is to use `$XBUILD_FRAMEWORK_FOLDERS_PATH`,
and the sanest way to do *that* is to use `tools/scripts/xabuild` for
the primary build.

Unfortunately, using `xabuild` for the primary build breaks the
`msbuild`-based build, as it can't resolve the
`.NETFramework,Version=v4.6.1` framework.

Context: dotnet#599 (comment)

Split the difference here by introducing `$(_SLN_BUILD)`: use
`xabuild` when building with `xbuild`, and continue using `msbuild`
when building with `msbuild`.
@jonpryor jonpryor force-pushed the jonp-probe-known-versions branch from 570bcda to e77f581 Compare August 17, 2017 15:59
jonpryor added a commit to jonpryor/xamarin-android that referenced this pull request Aug 17, 2017
Commit 8e7d37b is a sign of duplication: in order to use a
`Mono.Android.dll` binding assembly, not only do we need to *build*
the binding assembly, but we *also* need to update
`Xamarin.Android.Build.Utilities.dll` to "know" about the new binding
version (to map API level to `$(TargetFrameworkVersion)`).

Even "better" (worse), if the new API level is a *preview*, there is
no *consistent* API level. For example, with API-O, `android.jar`
isn't at
`$(AndroidSdkDirectory)\platforms\android-@API_LEVEL@\android.jar`,
where `@API_LEVEL@` is 26 (because various codepaths require that the
"api level" be an integer). Instead, it's installed at
`$(AndroidSdkDirectory)\platforms\android-O\android.jar`, where
`O` is the "id" of the preview API level.

This "id" is "leaky", in turn requiring that
`Xamarin.Android.Build.Tasks.dll` *also* be updated to deal with the
mappings.

Even "better" (worse), if we *forget* to cross all our our 't's and
dot all of our 'i's, we'll have a binding assembly which can't be
used. (Which is why we needed commit 8e7d37b; without it, the API-O
binding can't be used!)

This is all obviously madness. ;-)

Clean this mess up:

 1. Update `src/Mono.Android` to create a new `AndroidApiInfo.xml`
    file within the `$(TargetFrameworkVersion)` directory.
    This will contain all the information needed to map Android API
    levels to Ids and Android OS versions and
    `$(TargetFrameworkVersion)` values.

    ```
    <AndroidApiInfo>
      <Id>10</Id>
      <Level>10</Level>
      <Name>Gingerbread</Name>
      <Version>v2.3</Version>
    </AndroidApiInfo>
    ```

 2. Add a new `Xamarin.Android.Build.Utilities.AndroidVersions` type
    which looks for and parses these new `AndroidApiInfo.xml` files.

 3. Fixup all the other places using `AndroidVersion.KnownVersions`
    and related members to instead use `AndroidVersions`.

 4. Remove all the old APIs which rely on hardcoded data.

The advantage to all this is that we can support new API level
bindings by just building a new `Mono.Android.dll` and placing an
`AndroidApiInfo.xml` into the appropriate location (next to
`Mono.Android.dll`). No further code changes would be required.

Related: The build system still has a nasy habit of using system-wide
directories to resolve files we'd really rather it not, e.g. in
[xamarin-android/master build dotnet#503][m503]:

[m503]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/503/consoleText

	Building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _GetReferenceAssemblyPaths:
	  Task "GetReferenceAssemblyPaths"
	    Using task GetReferenceAssemblyPaths from Microsoft.Build.Tasks.GetReferenceAssemblyPaths, Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
	    Looking for framework 'MonoAndroid,Version=v1.0' in root path '/Library/Frameworks/Mono.framework/External/xbuild-frameworks'
	    Found framework definition list '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/RedistList/FrameworkList.xml' for framework 'MonoAndroid,Version=v1.0'
	  Done executing task "GetReferenceAssemblyPaths"
	  Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj".
	Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _SetLatestTargetFrameworkVersion:
	  Task "ResolveSdks"
	    ReferenceAssemblyPaths:
	      /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/

Note the use of the path
`/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0`.

This *was* "fine" -- if undesirable -- but with the introduction of
`AndroidVersions` and `AndroidApiInfo.xml` files within the frameworks
directory, everything falls apart, becuase the system install
*does not have* the `AndroidApiInfo.xml` files, so
*NO API LEVELS ARE FOUND*.

Oops.

The only way to fix this is to use `$XBUILD_FRAMEWORK_FOLDERS_PATH`,
and the sanest way to do *that* is to use `tools/scripts/xabuild` for
the primary build.

Unfortunately, using `xabuild` for the primary build breaks the
`msbuild`-based build, as it can't resolve the
`.NETFramework,Version=v4.6.1` framework.

Context: dotnet#599 (comment)

Split the difference here by introducing `$(_SLN_BUILD)`: use
`xabuild` when building with `xbuild`, and continue using `msbuild`
when building with `msbuild`.
@jonpryor jonpryor force-pushed the jonp-probe-known-versions branch from e77f581 to 54316cf Compare August 17, 2017 19:04
jonpryor added a commit to jonpryor/xamarin-android that referenced this pull request Aug 17, 2017
Commit 8e7d37b is a sign of duplication: in order to use a
`Mono.Android.dll` binding assembly, not only do we need to *build*
the binding assembly, but we *also* need to update
`Xamarin.Android.Build.Utilities.dll` to "know" about the new binding
version (to map API level to `$(TargetFrameworkVersion)`).

Even "better" (worse), if the new API level is a *preview*, there is
no *consistent* API level. For example, with API-O, `android.jar`
isn't at
`$(AndroidSdkDirectory)\platforms\android-@API_LEVEL@\android.jar`,
where `@API_LEVEL@` is 26 (because various codepaths require that the
"api level" be an integer). Instead, it's installed at
`$(AndroidSdkDirectory)\platforms\android-O\android.jar`, where
`O` is the "id" of the preview API level.

This "id" is "leaky", in turn requiring that
`Xamarin.Android.Build.Tasks.dll` *also* be updated to deal with the
mappings.

Even "better" (worse), if we *forget* to cross all our our 't's and
dot all of our 'i's, we'll have a binding assembly which can't be
used. (Which is why we needed commit 8e7d37b; without it, the API-O
binding can't be used!)

This is all obviously madness. ;-)

Clean this mess up:

 1. Update `src/Mono.Android` to create a new `AndroidApiInfo.xml`
    file within the `$(TargetFrameworkVersion)` directory.
    This will contain all the information needed to map Android API
    levels to Ids and Android OS versions and
    `$(TargetFrameworkVersion)` values.

    ```
    <AndroidApiInfo>
      <Id>10</Id>
      <Level>10</Level>
      <Name>Gingerbread</Name>
      <Version>v2.3</Version>
    </AndroidApiInfo>
    ```

 2. Add a new `Xamarin.Android.Build.Utilities.AndroidVersions` type
    which looks for and parses these new `AndroidApiInfo.xml` files.

 3. Fixup all the other places using `AndroidVersion.KnownVersions`
    and related members to instead use `AndroidVersions`.

 4. Remove all the old APIs which rely on hardcoded data.

The advantage to all this is that we can support new API level
bindings by just building a new `Mono.Android.dll` and placing an
`AndroidApiInfo.xml` into the appropriate location (next to
`Mono.Android.dll`). No further code changes would be required.

Related: The build system still has a nasy habit of using system-wide
directories to resolve files we'd really rather it not, e.g. in
[xamarin-android/master build dotnet#503][m503]:

[m503]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/503/consoleText

	Building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _GetReferenceAssemblyPaths:
	  Task "GetReferenceAssemblyPaths"
	    Using task GetReferenceAssemblyPaths from Microsoft.Build.Tasks.GetReferenceAssemblyPaths, Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
	    Looking for framework 'MonoAndroid,Version=v1.0' in root path '/Library/Frameworks/Mono.framework/External/xbuild-frameworks'
	    Found framework definition list '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/RedistList/FrameworkList.xml' for framework 'MonoAndroid,Version=v1.0'
	  Done executing task "GetReferenceAssemblyPaths"
	  Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj".
	Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _SetLatestTargetFrameworkVersion:
	  Task "ResolveSdks"
	    ReferenceAssemblyPaths:
	      /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/

Note the use of the path
`/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0`.

This *was* "fine" -- if undesirable -- but with the introduction of
`AndroidVersions` and `AndroidApiInfo.xml` files within the frameworks
directory, everything falls apart, becuase the system install
*does not have* the `AndroidApiInfo.xml` files, so
*NO API LEVELS ARE FOUND*.

Oops.

The only way to fix this is to use `$XBUILD_FRAMEWORK_FOLDERS_PATH`,
and the sanest way to do *that* is to use `tools/scripts/xabuild` for
the primary build.

Unfortunately, using `xabuild` for the primary build breaks the
`msbuild`-based build, as it can't resolve the
`.NETFramework,Version=v4.6.1` framework.

Context: dotnet#599 (comment)

Split the difference here by introducing `$(_SLN_BUILD)`: use
`xabuild` when building with `xbuild`, and continue using `msbuild`
when building with `msbuild`.
@jonpryor jonpryor force-pushed the jonp-probe-known-versions branch from 54316cf to 4c26e75 Compare August 17, 2017 21:33
jonpryor added a commit to jonpryor/xamarin-android that referenced this pull request Aug 17, 2017
Commit 8e7d37b is a sign of duplication: in order to use a
`Mono.Android.dll` binding assembly, not only do we need to *build*
the binding assembly, but we *also* need to update
`Xamarin.Android.Build.Utilities.dll` to "know" about the new binding
version (to map API level to `$(TargetFrameworkVersion)`).

Even "better" (worse), if the new API level is a *preview*, there is
no *consistent* API level. For example, with API-O, `android.jar`
isn't at
`$(AndroidSdkDirectory)\platforms\android-@API_LEVEL@\android.jar`,
where `@API_LEVEL@` is 26 (because various codepaths require that the
"api level" be an integer). Instead, it's installed at
`$(AndroidSdkDirectory)\platforms\android-O\android.jar`, where
`O` is the "id" of the preview API level.

This "id" is "leaky", in turn requiring that
`Xamarin.Android.Build.Tasks.dll` *also* be updated to deal with the
mappings.

Even "better" (worse), if we *forget* to cross all our our 't's and
dot all of our 'i's, we'll have a binding assembly which can't be
used. (Which is why we needed commit 8e7d37b; without it, the API-O
binding can't be used!)

This is all obviously madness. ;-)

Clean this mess up:

 1. Update `src/Mono.Android` to create a new `AndroidApiInfo.xml`
    file within the `$(TargetFrameworkVersion)` directory.
    This will contain all the information needed to map Android API
    levels to Ids and Android OS versions and
    `$(TargetFrameworkVersion)` values.

    ```
    <AndroidApiInfo>
      <Id>10</Id>
      <Level>10</Level>
      <Name>Gingerbread</Name>
      <Version>v2.3</Version>
    </AndroidApiInfo>
    ```

 2. Add a new `Xamarin.Android.Build.Utilities.AndroidVersions` type
    which looks for and parses these new `AndroidApiInfo.xml` files.

 3. Fixup all the other places using `AndroidVersion.KnownVersions`
    and related members to instead use `AndroidVersions`.

 4. Remove all the old APIs which rely on hardcoded data.

The advantage to all this is that we can support new API level
bindings by just building a new `Mono.Android.dll` and placing an
`AndroidApiInfo.xml` into the appropriate location (next to
`Mono.Android.dll`). No further code changes would be required.

Related: The build system still has a nasy habit of using system-wide
directories to resolve files we'd really rather it not, e.g. in
[xamarin-android/master build dotnet#503][m503]:

[m503]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/503/consoleText

	Building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _GetReferenceAssemblyPaths:
	  Task "GetReferenceAssemblyPaths"
	    Using task GetReferenceAssemblyPaths from Microsoft.Build.Tasks.GetReferenceAssemblyPaths, Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
	    Looking for framework 'MonoAndroid,Version=v1.0' in root path '/Library/Frameworks/Mono.framework/External/xbuild-frameworks'
	    Found framework definition list '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/RedistList/FrameworkList.xml' for framework 'MonoAndroid,Version=v1.0'
	  Done executing task "GetReferenceAssemblyPaths"
	  Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj".
	Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _SetLatestTargetFrameworkVersion:
	  Task "ResolveSdks"
	    ReferenceAssemblyPaths:
	      /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/

Note the use of the path
`/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0`.

This *was* "fine" -- if undesirable -- but with the introduction of
`AndroidVersions` and `AndroidApiInfo.xml` files within the frameworks
directory, everything falls apart, becuase the system install
*does not have* the `AndroidApiInfo.xml` files, so
*NO API LEVELS ARE FOUND*.

Oops.

The only way to fix this is to use `$XBUILD_FRAMEWORK_FOLDERS_PATH`,
and the sanest way to do *that* is to use `tools/scripts/xabuild` for
the primary build.

Unfortunately, using `xabuild` for the primary build breaks the
`msbuild`-based build, as it can't resolve the
`.NETFramework,Version=v4.6.1` framework.

Context: dotnet#599 (comment)

Split the difference here by introducing `$(_SLN_BUILD)`: use
`xabuild` when building with `xbuild`, and continue using `msbuild`
when building with `msbuild`.
@jonpryor jonpryor force-pushed the jonp-probe-known-versions branch from 4c26e75 to 51d213c Compare August 21, 2017 19:10
jonpryor added a commit to jonpryor/xamarin-android that referenced this pull request Aug 21, 2017
Commit 8e7d37b is a sign of duplication: in order to use a
`Mono.Android.dll` binding assembly, not only do we need to *build*
the binding assembly, but we *also* need to update
`Xamarin.Android.Build.Utilities.dll` to "know" about the new binding
version (to map API level to `$(TargetFrameworkVersion)`).

Even "better" (worse), if the new API level is a *preview*, there is
no *consistent* API level. For example, with API-O, `android.jar`
isn't at
`$(AndroidSdkDirectory)\platforms\android-@API_LEVEL@\android.jar`,
where `@API_LEVEL@` is 26 (because various codepaths require that the
"api level" be an integer). Instead, it's installed at
`$(AndroidSdkDirectory)\platforms\android-O\android.jar`, where
`O` is the "id" of the preview API level.

This "id" is "leaky", in turn requiring that
`Xamarin.Android.Build.Tasks.dll` *also* be updated to deal with the
mappings.

Even "better" (worse), if we *forget* to cross all our our 't's and
dot all of our 'i's, we'll have a binding assembly which can't be
used. (Which is why we needed commit 8e7d37b; without it, the API-O
binding can't be used!)

This is all obviously madness. ;-)

Clean this mess up:

 1. Update `src/Mono.Android` to create a new `AndroidApiInfo.xml`
    file within the `$(TargetFrameworkVersion)` directory.
    This will contain all the information needed to map Android API
    levels to Ids and Android OS versions and
    `$(TargetFrameworkVersion)` values.

    ```
    <AndroidApiInfo>
      <Id>10</Id>
      <Level>10</Level>
      <Name>Gingerbread</Name>
      <Version>v2.3</Version>
    </AndroidApiInfo>
    ```

 2. Add a new `Xamarin.Android.Build.Utilities.AndroidVersions` type
    which looks for and parses these new `AndroidApiInfo.xml` files.

 3. Fixup all the other places using `AndroidVersion.KnownVersions`
    and related members to instead use `AndroidVersions`.

 4. Remove all the old APIs which rely on hardcoded data.

The advantage to all this is that we can support new API level
bindings by just building a new `Mono.Android.dll` and placing an
`AndroidApiInfo.xml` into the appropriate location (next to
`Mono.Android.dll`). No further code changes would be required.

Related: The build system still has a nasy habit of using system-wide
directories to resolve files we'd really rather it not, e.g. in
[xamarin-android/master build dotnet#503][m503]:

[m503]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/503/consoleText

	Building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _GetReferenceAssemblyPaths:
	  Task "GetReferenceAssemblyPaths"
	    Using task GetReferenceAssemblyPaths from Microsoft.Build.Tasks.GetReferenceAssemblyPaths, Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
	    Looking for framework 'MonoAndroid,Version=v1.0' in root path '/Library/Frameworks/Mono.framework/External/xbuild-frameworks'
	    Found framework definition list '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/RedistList/FrameworkList.xml' for framework 'MonoAndroid,Version=v1.0'
	  Done executing task "GetReferenceAssemblyPaths"
	  Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj".
	Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _SetLatestTargetFrameworkVersion:
	  Task "ResolveSdks"
	    ReferenceAssemblyPaths:
	      /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/

Note the use of the path
`/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0`.

This *was* "fine" -- if undesirable -- but with the introduction of
`AndroidVersions` and `AndroidApiInfo.xml` files within the frameworks
directory, everything falls apart, becuase the system install
*does not have* the `AndroidApiInfo.xml` files, so
*NO API LEVELS ARE FOUND*.

Oops.

The only way to fix this is to use `$XBUILD_FRAMEWORK_FOLDERS_PATH`,
and the sanest way to do *that* is to use `tools/scripts/xabuild` for
the primary build.

Unfortunately, using `xabuild` for the primary build breaks the
`msbuild`-based build, as it can't resolve the
`.NETFramework,Version=v4.6.1` framework.

Context: dotnet#599 (comment)

Split the difference here by introducing `$(_SLN_BUILD)`: use
`xabuild` when building with `xbuild`, and continue using `msbuild`
when building with `msbuild`.
@jonpryor jonpryor force-pushed the jonp-probe-known-versions branch from 51d213c to 2644e1d Compare August 21, 2017 19:11
jonpryor added a commit to jonpryor/xamarin-android that referenced this pull request Aug 21, 2017
Commit 8e7d37b is a sign of duplication: in order to use a
`Mono.Android.dll` binding assembly, not only do we need to *build*
the binding assembly, but we *also* need to update
`Xamarin.Android.Build.Utilities.dll` to "know" about the new binding
version (to map API level to `$(TargetFrameworkVersion)`).

Even "better" (worse), if the new API level is a *preview*, there is
no *consistent* API level. For example, with API-O, `android.jar`
isn't at
`$(AndroidSdkDirectory)\platforms\android-@API_LEVEL@\android.jar`,
where `@API_LEVEL@` is 26 (because various codepaths require that the
"api level" be an integer). Instead, it's installed at
`$(AndroidSdkDirectory)\platforms\android-O\android.jar`, where
`O` is the "id" of the preview API level.

This "id" is "leaky", in turn requiring that
`Xamarin.Android.Build.Tasks.dll` *also* be updated to deal with the
mappings.

Even "better" (worse), if we *forget* to cross all our our 't's and
dot all of our 'i's, we'll have a binding assembly which can't be
used. (Which is why we needed commit 8e7d37b; without it, the API-O
binding can't be used!)

This is all obviously madness. ;-)

Clean this mess up:

 1. Update `src/Mono.Android` to create a new `AndroidApiInfo.xml`
    file within the `$(TargetFrameworkVersion)` directory.
    This will contain all the information needed to map Android API
    levels to Ids and Android OS versions and
    `$(TargetFrameworkVersion)` values.

    ```
    <AndroidApiInfo>
      <Id>10</Id>
      <Level>10</Level>
      <Name>Gingerbread</Name>
      <Version>v2.3</Version>
    </AndroidApiInfo>
    ```

 2. Add a new `Xamarin.Android.Build.Utilities.AndroidVersions` type
    which looks for and parses these new `AndroidApiInfo.xml` files.

 3. Fixup all the other places using `AndroidVersion.KnownVersions`
    and related members to instead use `AndroidVersions`.

 4. Remove all the old APIs which rely on hardcoded data.

The advantage to all this is that we can support new API level
bindings by just building a new `Mono.Android.dll` and placing an
`AndroidApiInfo.xml` into the appropriate location (next to
`Mono.Android.dll`). No further code changes would be required.

Related: The build system still has a nasy habit of using system-wide
directories to resolve files we'd really rather it not, e.g. in
[xamarin-android/master build dotnet#503][m503]:

[m503]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/503/consoleText

	Building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _GetReferenceAssemblyPaths:
	  Task "GetReferenceAssemblyPaths"
	    Using task GetReferenceAssemblyPaths from Microsoft.Build.Tasks.GetReferenceAssemblyPaths, Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
	    Looking for framework 'MonoAndroid,Version=v1.0' in root path '/Library/Frameworks/Mono.framework/External/xbuild-frameworks'
	    Found framework definition list '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/RedistList/FrameworkList.xml' for framework 'MonoAndroid,Version=v1.0'
	  Done executing task "GetReferenceAssemblyPaths"
	  Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj".
	Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _SetLatestTargetFrameworkVersion:
	  Task "ResolveSdks"
	    ReferenceAssemblyPaths:
	      /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/

Note the use of the path
`/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0`.

This *was* "fine" -- if undesirable -- but with the introduction of
`AndroidVersions` and `AndroidApiInfo.xml` files within the frameworks
directory, everything falls apart, becuase the system install
*does not have* the `AndroidApiInfo.xml` files, so
*NO API LEVELS ARE FOUND*.

Oops.

The only way to fix this is to use `$XBUILD_FRAMEWORK_FOLDERS_PATH`,
and the sanest way to do *that* is to use `tools/scripts/xabuild` for
the primary build.

Unfortunately, using `xabuild` for the primary build breaks the
`msbuild`-based build, as it can't resolve the
`.NETFramework,Version=v4.6.1` framework.

Context: dotnet#599 (comment)

Split the difference here by introducing `$(_SLN_BUILD)`: use
`xabuild` when building with `xbuild`, and continue using `msbuild`
when building with `msbuild`.
@jonpryor jonpryor force-pushed the jonp-probe-known-versions branch from 2644e1d to 4365424 Compare August 21, 2017 19:13
jonpryor added a commit to jonpryor/xamarin-android that referenced this pull request Aug 21, 2017
Commit 8e7d37b is a sign of duplication: in order to use a
`Mono.Android.dll` binding assembly, not only do we need to *build*
the binding assembly, but we *also* need to update
`Xamarin.Android.Build.Utilities.dll` to "know" about the new binding
version (to map API level to `$(TargetFrameworkVersion)`).

Even "better" (worse), if the new API level is a *preview*, there is
no *consistent* API level. For example, with API-O, `android.jar`
isn't at
`$(AndroidSdkDirectory)\platforms\android-@API_LEVEL@\android.jar`,
where `@API_LEVEL@` is 26 (because various codepaths require that the
"api level" be an integer). Instead, it's installed at
`$(AndroidSdkDirectory)\platforms\android-O\android.jar`, where
`O` is the "id" of the preview API level.

This "id" is "leaky", in turn requiring that
`Xamarin.Android.Build.Tasks.dll` *also* be updated to deal with the
mappings.

Even "better" (worse), if we *forget* to cross all our our 't's and
dot all of our 'i's, we'll have a binding assembly which can't be
used. (Which is why we needed commit 8e7d37b; without it, the API-O
binding can't be used!)

This is all obviously madness. ;-)

Clean this mess up:

 1. Update `src/Mono.Android` to create a new `AndroidApiInfo.xml`
    file within the `$(TargetFrameworkVersion)` directory.
    This will contain all the information needed to map Android API
    levels to Ids and Android OS versions and
    `$(TargetFrameworkVersion)` values.

    ```
    <AndroidApiInfo>
      <Id>10</Id>
      <Level>10</Level>
      <Name>Gingerbread</Name>
      <Version>v2.3</Version>
    </AndroidApiInfo>
    ```

 2. Add a new `Xamarin.Android.Build.Utilities.AndroidVersions` type
    which looks for and parses these new `AndroidApiInfo.xml` files.

 3. Fixup all the other places using `AndroidVersion.KnownVersions`
    and related members to instead use `AndroidVersions`.

 4. Remove all the old APIs which rely on hardcoded data.

The advantage to all this is that we can support new API level
bindings by just building a new `Mono.Android.dll` and placing an
`AndroidApiInfo.xml` into the appropriate location (next to
`Mono.Android.dll`). No further code changes would be required.

Related: The build system still has a nasy habit of using system-wide
directories to resolve files we'd really rather it not, e.g. in
[xamarin-android/master build dotnet#503][m503]:

[m503]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/503/consoleText

	Building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _GetReferenceAssemblyPaths:
	  Task "GetReferenceAssemblyPaths"
	    Using task GetReferenceAssemblyPaths from Microsoft.Build.Tasks.GetReferenceAssemblyPaths, Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
	    Looking for framework 'MonoAndroid,Version=v1.0' in root path '/Library/Frameworks/Mono.framework/External/xbuild-frameworks'
	    Found framework definition list '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/RedistList/FrameworkList.xml' for framework 'MonoAndroid,Version=v1.0'
	  Done executing task "GetReferenceAssemblyPaths"
	  Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj".
	Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _SetLatestTargetFrameworkVersion:
	  Task "ResolveSdks"
	    ReferenceAssemblyPaths:
	      /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/

Note the use of the path
`/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0`.

This *was* "fine" -- if undesirable -- but with the introduction of
`AndroidVersions` and `AndroidApiInfo.xml` files within the frameworks
directory, everything falls apart, becuase the system install
*does not have* the `AndroidApiInfo.xml` files, so
*NO API LEVELS ARE FOUND*.

Oops.

The only way to fix this is to use `$XBUILD_FRAMEWORK_FOLDERS_PATH`,
and the sanest way to do *that* is to use `tools/scripts/xabuild` for
the primary build.

Unfortunately, using `xabuild` for the primary build breaks the
`msbuild`-based build, as it can't resolve the
`.NETFramework,Version=v4.6.1` framework.

Context: dotnet#599 (comment)

Split the difference here by introducing `$(_SLN_BUILD)`: use
`xabuild` when building with `xbuild`, and continue using `msbuild`
when building with `msbuild`.
@jonpryor jonpryor force-pushed the jonp-probe-known-versions branch from 4365424 to 5f003ce Compare August 22, 2017 13:01
jonpryor added a commit to jonpryor/xamarin-android that referenced this pull request Aug 22, 2017
Commit 8e7d37b is a sign of duplication: in order to use a
`Mono.Android.dll` binding assembly, not only do we need to *build*
the binding assembly, but we *also* need to update
`Xamarin.Android.Build.Utilities.dll` to "know" about the new binding
version (to map API level to `$(TargetFrameworkVersion)`).

Even "better" (worse), if the new API level is a *preview*, there is
no *consistent* API level. For example, with API-O, `android.jar`
isn't at
`$(AndroidSdkDirectory)\platforms\android-@API_LEVEL@\android.jar`,
where `@API_LEVEL@` is 26 (because various codepaths require that the
"api level" be an integer). Instead, it's installed at
`$(AndroidSdkDirectory)\platforms\android-O\android.jar`, where
`O` is the "id" of the preview API level.

This "id" is "leaky", in turn requiring that
`Xamarin.Android.Build.Tasks.dll` *also* be updated to deal with the
mappings.

Even "better" (worse), if we *forget* to cross all our our 't's and
dot all of our 'i's, we'll have a binding assembly which can't be
used. (Which is why we needed commit 8e7d37b; without it, the API-O
binding can't be used!)

This is all obviously madness. ;-)

Clean this mess up:

 1. Update `src/Mono.Android` to create a new `AndroidApiInfo.xml`
    file within the `$(TargetFrameworkVersion)` directory.
    This will contain all the information needed to map Android API
    levels to Ids and Android OS versions and
    `$(TargetFrameworkVersion)` values.

    ```xml
    <AndroidApiInfo>
      <Id>10</Id>
      <Level>10</Level>
      <Name>Gingerbread</Name>
      <Version>v2.3</Version>
    </AndroidApiInfo>
    ```

 2. Add a new `Xamarin.Android.Build.Utilities.AndroidVersions` type
    which looks for and parses these new `AndroidApiInfo.xml` files.

 3. Fixup all the other places using `AndroidVersion.KnownVersions`
    and related members to instead use `AndroidVersions`.

 4. Remove all the old APIs which rely on hardcoded data.

The advantage to all this is that we can support new API level
bindings by just building a new `Mono.Android.dll` and placing an
`AndroidApiInfo.xml` into the appropriate location (next to
`Mono.Android.dll`). No further code changes would be required.

Related: The build system still has a nasy habit of using system-wide
directories to resolve files we'd really rather it not, e.g. in
[xamarin-android/master build dotnet#503][m503]:

[m503]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/503/consoleText

	Building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _GetReferenceAssemblyPaths:
	  Task "GetReferenceAssemblyPaths"
	    Using task GetReferenceAssemblyPaths from Microsoft.Build.Tasks.GetReferenceAssemblyPaths, Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
	    Looking for framework 'MonoAndroid,Version=v1.0' in root path '/Library/Frameworks/Mono.framework/External/xbuild-frameworks'
	    Found framework definition list '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/RedistList/FrameworkList.xml' for framework 'MonoAndroid,Version=v1.0'
	  Done executing task "GetReferenceAssemblyPaths"
	  Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj".
	Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _SetLatestTargetFrameworkVersion:
	  Task "ResolveSdks"
	    ReferenceAssemblyPaths:
	      /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/

Note the use of the path
`/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0`.

This *was* "fine" -- if undesirable -- but with the introduction of
`AndroidVersions` and `AndroidApiInfo.xml` files within the frameworks
directory, everything falls apart, becuase the system install
*does not have* the `AndroidApiInfo.xml` files, so
*NO API LEVELS ARE FOUND*.

Oops.

The only way to fix this is to use `$XBUILD_FRAMEWORK_FOLDERS_PATH`,
and the sanest way to do *that* is to use `tools/scripts/xabuild` for
the primary build.

Unfortunately, using `xabuild` for the primary build breaks the
`msbuild`-based build, as it can't resolve the
`.NETFramework,Version=v4.6.1` framework.

Context: dotnet#599 (comment)

Split the difference here by introducing `$(_SLN_BUILD)`: use
`xabuild` when building with `xbuild`, and continue using `msbuild`
when building with `msbuild`.
@jonpryor jonpryor force-pushed the jonp-probe-known-versions branch from 5f003ce to b4d8733 Compare August 22, 2017 13:04
jonpryor added a commit to jonpryor/xamarin-android that referenced this pull request Aug 22, 2017
Commit 8e7d37b is a sign of duplication: in order to use a
`Mono.Android.dll` binding assembly, not only do we need to *build*
the binding assembly, but we *also* need to update
`Xamarin.Android.Build.Utilities.dll` to "know" about the new binding
version (to map API level to `$(TargetFrameworkVersion)`).

Even "better" (worse), if the new API level is a *preview*, there is
no *consistent* API level. For example, with API-O, `android.jar`
isn't at
`$(AndroidSdkDirectory)\platforms\android-@API_LEVEL@\android.jar`,
where `@API_LEVEL@` is 26 (because various codepaths require that the
"api level" be an integer). Instead, it's installed at
`$(AndroidSdkDirectory)\platforms\android-O\android.jar`, where
`O` is the "id" of the preview API level.

This "id" is "leaky", in turn requiring that
`Xamarin.Android.Build.Tasks.dll` *also* be updated to deal with the
mappings.

Even "better" (worse), if we *forget* to cross all our our 't's and
dot all of our 'i's, we'll have a binding assembly which can't be
used. (Which is why we needed commit 8e7d37b; without it, the API-O
binding can't be used!)

This is all obviously madness. ;-)

Clean this mess up:

 1. Update `src/Mono.Android` to create a new `AndroidApiInfo.xml`
    file within the `$(TargetFrameworkVersion)` directory.
    This will contain all the information needed to map Android API
    levels to Ids and Android OS versions and
    `$(TargetFrameworkVersion)` values.

    ```xml
    <AndroidApiInfo>
      <Id>10</Id>
      <Level>10</Level>
      <Name>Gingerbread</Name>
      <Version>v2.3</Version>
    </AndroidApiInfo>
    ```

 2. Add a new `Xamarin.Android.Build.Utilities.AndroidVersions` type
    which looks for and parses these new `AndroidApiInfo.xml` files.

 3. Fixup all the other places using `AndroidVersion.KnownVersions`
    and related members to instead use `AndroidVersions`.

 4. Remove all the old APIs which rely on hardcoded data.

The advantage to all this is that we can support new API level
bindings by just building a new `Mono.Android.dll` and placing an
`AndroidApiInfo.xml` into the appropriate location (next to
`Mono.Android.dll`). No further code changes would be required.

Related: The build system still has a nasy habit of using system-wide
directories to resolve files we'd really rather it not, e.g. in
[xamarin-android/master build dotnet#503][m503]:

[m503]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/503/consoleText

	Building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _GetReferenceAssemblyPaths:
	  Task "GetReferenceAssemblyPaths"
	    Using task GetReferenceAssemblyPaths from Microsoft.Build.Tasks.GetReferenceAssemblyPaths, Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
	    Looking for framework 'MonoAndroid,Version=v1.0' in root path '/Library/Frameworks/Mono.framework/External/xbuild-frameworks'
	    Found framework definition list '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/RedistList/FrameworkList.xml' for framework 'MonoAndroid,Version=v1.0'
	  Done executing task "GetReferenceAssemblyPaths"
	  Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj".
	Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _SetLatestTargetFrameworkVersion:
	  Task "ResolveSdks"
	    ReferenceAssemblyPaths:
	      /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/

Note the use of the path
`/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0`.

This *was* "fine" -- if undesirable -- but with the introduction of
`AndroidVersions` and `AndroidApiInfo.xml` files within the frameworks
directory, everything falls apart, becuase the system install
*does not have* the `AndroidApiInfo.xml` files, so
*NO API LEVELS ARE FOUND*.

Oops.

The only way to fix this is to use `$XBUILD_FRAMEWORK_FOLDERS_PATH`,
and the sanest way to do *that* is to use `tools/scripts/xabuild` for
the primary build.

Unfortunately, using `xabuild` for the primary build breaks the
`msbuild`-based build, as it can't resolve the
`.NETFramework,Version=v4.6.1` framework.

Context: dotnet#599 (comment)

Split the difference here by introducing `$(_SLN_BUILD)`: use
`xabuild` when building with `xbuild`, and continue using `msbuild`
when building with `msbuild`.
@@ -166,7 +166,7 @@ static string NullIfEmpty (string value)
return null;
int vn;
if (!int.TryParse (version, out vn))
vn = AndroidVersion.MaxApiLevel;
return null;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jonpryor should we be returning null here?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess this should be AndroidVersions. MaxStableVersion ?

<_Line Include="@(_ApiInfo->' &lt;Stable>%(Stable)&lt;/Stable>')" />
<_Line Include="&lt;/AndroidApiInfo&gt;" />
</ItemGroup>
<Message Text="# jonp: _Line=@(_Line)" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jonpryor can we remove the debug message :)

Copy link
Contributor

@dellis1972 dellis1972 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A couple of changes needed. see comments

@jonpryor jonpryor force-pushed the jonp-probe-known-versions branch from b4d8733 to 4321044 Compare August 22, 2017 14:55
jonpryor added a commit to jonpryor/xamarin-android that referenced this pull request Aug 22, 2017
Commit 8e7d37b is a sign of duplication: in order to use a
`Mono.Android.dll` binding assembly, not only do we need to *build*
the binding assembly, but we *also* need to update
`Xamarin.Android.Build.Utilities.dll` to "know" about the new binding
version (to map API level to `$(TargetFrameworkVersion)`).

Even "better" (worse), if the new API level is a *preview*, there is
no *consistent* API level. For example, with API-O, `android.jar`
isn't at
`$(AndroidSdkDirectory)\platforms\android-@API_LEVEL@\android.jar`,
where `@API_LEVEL@` is 26 (because various codepaths require that the
"api level" be an integer). Instead, it's installed at
`$(AndroidSdkDirectory)\platforms\android-O\android.jar`, where
`O` is the "id" of the preview API level.

This "id" is "leaky", in turn requiring that
`Xamarin.Android.Build.Tasks.dll` *also* be updated to deal with the
mappings.

Even "better" (worse), if we *forget* to cross all our our 't's and
dot all of our 'i's, we'll have a binding assembly which can't be
used. (Which is why we needed commit 8e7d37b; without it, the API-O
binding can't be used!)

This is all obviously madness. ;-)

Clean this mess up:

 1. Update `src/Mono.Android` to create a new `AndroidApiInfo.xml`
    file within the `$(TargetFrameworkVersion)` directory.
    This will contain all the information needed to map Android API
    levels to Ids and Android OS versions and
    `$(TargetFrameworkVersion)` values.

    ```xml
    <AndroidApiInfo>
      <Id>10</Id>
      <Level>10</Level>
      <Name>Gingerbread</Name>
      <Version>v2.3</Version>
    </AndroidApiInfo>
    ```

 2. Add a new `Xamarin.Android.Build.Utilities.AndroidVersions` type
    which looks for and parses these new `AndroidApiInfo.xml` files.

 3. Fixup all the other places using `AndroidVersion.KnownVersions`
    and related members to instead use `AndroidVersions`.

 4. Remove all the old APIs which rely on hardcoded data.

The advantage to all this is that we can support new API level
bindings by just building a new `Mono.Android.dll` and placing an
`AndroidApiInfo.xml` into the appropriate location (next to
`Mono.Android.dll`). No further code changes would be required.

Related: The build system still has a nasy habit of using system-wide
directories to resolve files we'd really rather it not, e.g. in
[xamarin-android/master build dotnet#503][m503]:

[m503]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/503/consoleText

	Building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _GetReferenceAssemblyPaths:
	  Task "GetReferenceAssemblyPaths"
	    Using task GetReferenceAssemblyPaths from Microsoft.Build.Tasks.GetReferenceAssemblyPaths, Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
	    Looking for framework 'MonoAndroid,Version=v1.0' in root path '/Library/Frameworks/Mono.framework/External/xbuild-frameworks'
	    Found framework definition list '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/RedistList/FrameworkList.xml' for framework 'MonoAndroid,Version=v1.0'
	  Done executing task "GetReferenceAssemblyPaths"
	  Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj".
	Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _SetLatestTargetFrameworkVersion:
	  Task "ResolveSdks"
	    ReferenceAssemblyPaths:
	      /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/

Note the use of the path
`/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0`.

This *was* "fine" -- if undesirable -- but with the introduction of
`AndroidVersions` and `AndroidApiInfo.xml` files within the frameworks
directory, everything falls apart, becuase the system install
*does not have* the `AndroidApiInfo.xml` files, so
*NO API LEVELS ARE FOUND*.

Oops.

The only way to fix this is to use `$XBUILD_FRAMEWORK_FOLDERS_PATH`,
and the sanest way to do *that* is to use `tools/scripts/xabuild` for
the primary build.

Unfortunately, using `xabuild` for the primary build breaks the
`msbuild`-based build, as it can't resolve the
`.NETFramework,Version=v4.6.1` framework.

Context: dotnet#599 (comment)

Split the difference here by introducing `$(_SLN_BUILD)`: use
`xabuild` when building with `xbuild`, and continue using `msbuild`
when building with `msbuild`.
Commit 8e7d37b is a sign of duplication: in order to use a
`Mono.Android.dll` binding assembly, not only do we need to *build*
the binding assembly, but we *also* need to update
`Xamarin.Android.Build.Utilities.dll` to "know" about the new binding
version (to map API level to `$(TargetFrameworkVersion)`).

Even "better" (worse), if the new API level is a *preview*, there is
no *consistent* API level. For example, with API-O, `android.jar`
isn't at
`$(AndroidSdkDirectory)\platforms\android-@API_LEVEL@\android.jar`,
where `@API_LEVEL@` is 26 (because various codepaths require that the
"api level" be an integer). Instead, it's installed at
`$(AndroidSdkDirectory)\platforms\android-O\android.jar`, where
`O` is the "id" of the preview API level.

This "id" is "leaky", in turn requiring that
`Xamarin.Android.Build.Tasks.dll` *also* be updated to deal with the
mappings.

Even "better" (worse), if we *forget* to cross all our our 't's and
dot all of our 'i's, we'll have a binding assembly which can't be
used. (Which is why we needed commit 8e7d37b; without it, the API-O
binding can't be used!)

This is all obviously madness. ;-)

Clean this mess up:

 1. Update `src/Mono.Android` to create a new `AndroidApiInfo.xml`
    file within the `$(TargetFrameworkVersion)` directory.
    This will contain all the information needed to map Android API
    levels to Ids and Android OS versions and
    `$(TargetFrameworkVersion)` values.

    ```xml
    <AndroidApiInfo>
      <Id>10</Id>
      <Level>10</Level>
      <Name>Gingerbread</Name>
      <Version>v2.3</Version>
    </AndroidApiInfo>
    ```

 2. Add a new `Xamarin.Android.Build.Utilities.AndroidVersions` type
    which looks for and parses these new `AndroidApiInfo.xml` files.

 3. Fixup all the other places using `AndroidVersion.KnownVersions`
    and related members to instead use `AndroidVersions`.

 4. Remove all the old APIs which rely on hardcoded data.

The advantage to all this is that we can support new API level
bindings by just building a new `Mono.Android.dll` and placing an
`AndroidApiInfo.xml` into the appropriate location (next to
`Mono.Android.dll`). No further code changes would be required.

Related: The build system still has a nasy habit of using system-wide
directories to resolve files we'd really rather it not, e.g. in
[xamarin-android/master build dotnet#503][m503]:

[m503]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/503/consoleText

	Building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _GetReferenceAssemblyPaths:
	  Task "GetReferenceAssemblyPaths"
	    Using task GetReferenceAssemblyPaths from Microsoft.Build.Tasks.GetReferenceAssemblyPaths, Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
	    Looking for framework 'MonoAndroid,Version=v1.0' in root path '/Library/Frameworks/Mono.framework/External/xbuild-frameworks'
	    Found framework definition list '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/RedistList/FrameworkList.xml' for framework 'MonoAndroid,Version=v1.0'
	  Done executing task "GetReferenceAssemblyPaths"
	  Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj".
	Done building target "_GetReferenceAssemblyPaths" in project "/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/src/Xamarin.Android.NUnitLite/Xamarin.Android.NUnitLite.csproj" ("/Users/builder/jenkins/workspace/xamarin-android/xamarin-android/bin/Debug/lib/xamarin.android/xbuild/Xamarin/Android/Xamarin.Android.Common.targets"); "_SetLatestTargetFrameworkVersion" depends on it.
	  Target _SetLatestTargetFrameworkVersion:
	  Task "ResolveSdks"
	    ReferenceAssemblyPaths:
	      /Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/

Note the use of the path
`/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0`.

This *was* "fine" -- if undesirable -- but with the introduction of
`AndroidVersions` and `AndroidApiInfo.xml` files within the frameworks
directory, everything falls apart, becuase the system install
*does not have* the `AndroidApiInfo.xml` files, so
*NO API LEVELS ARE FOUND*.

Oops.

The only way to fix this is to use `$XBUILD_FRAMEWORK_FOLDERS_PATH`,
and the sanest way to do *that* is to use `tools/scripts/xabuild` for
the primary build.

Unfortunately, using `xabuild` for the primary build breaks the
`msbuild`-based build, as it can't resolve the
`.NETFramework,Version=v4.6.1` framework.

Context: dotnet#599 (comment)

Split the difference here by introducing `$(_SLN_BUILD)`: use
`xabuild` when building with `xbuild`, and continue using `msbuild`
when building with `msbuild`.
@jonpryor jonpryor force-pushed the jonp-probe-known-versions branch from 4321044 to e3b64af Compare August 22, 2017 14:58
@jonpryor jonpryor merged commit 8942eca into dotnet:master Aug 23, 2017
jonpryor added a commit that referenced this pull request Aug 23, 2017
Commit 8942eca [broke the build][xa554]:

[xa554]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/554/

	error XA0000: Could not determine $(TargetFrameworkVersion) for API level '26.'

The cause of the failure is that we're using `xbuild` within the
`make leeroy-all` target, but [we need to use `xabuild`][xbuild-paths]:

[xbuild-paths]: #599 (comment)

	Task "GetReferenceAssemblyPaths"
	  Using task GetReferenceAssemblyPaths from Microsoft.Build.Tasks.GetReferenceAssemblyPaths, Microsoft.Build.Tasks.Core, Version=14.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
	  Looking for framework 'MonoAndroid,Version=v1.0' in root path '/Library/Frameworks/Mono.framework/External/xbuild-frameworks'
	  Found framework definition list '/Library/Frameworks/Mono.framework/External/xbuild-frameworks/MonoAndroid/v1.0/RedistList/FrameworkList.xml' for framework 'MonoAndroid,Version=v1.0'
	Done executing task "GetReferenceAssemblyPaths"

`xbuild` is trying to use the *system-wide*
`/Library/Frameworks/Mono.framework/External/xbuild-frameworks`
directory, which *cannot* contain the now-required
`AndroidApiInfo.xml` files which are needed for probing.

Fix the `make leeroy-all` target to use `$(_SLN_BUILD)`, just as the
`make all` target does, so that the correct paths are used.
@jonpryor jonpryor mentioned this pull request Oct 26, 2017
jonpryor pushed a commit that referenced this pull request Mar 16, 2020
Changes: dotnet/java-interop@27cfd45...bd7c60a

  * dotnet/java-interop@bd7c60a: [generator] Support //interface/@no-alternatives (#601)
  * dotnet/java-interop@105d544: [generator] Remove interface alternatives w/ interface-constants (#600)
  * dotnet/java-interop@b255981: [build] Remove extraneous `nuget restore`s (#599)
  * dotnet/java-interop@2a59c40: [CI] Specify our PR build trigger in YAML. (#598)
  * dotnet/java-interop@0a3354b: [Java.Interop.Tools.Cecil] use File.Exists instead of DirectoryGetFile (#596)

Reduces the `<LinkAssembliesNoShrink/>` task time from about 711ms to
426ms for a small test Xamarin.Forms app on an initial clean build.

Updates `generator --lang-features=interface-constants` output so that
we stop emitting the `*Consts` classes in API-R.

API Breakages:

  * `tests/api-compatibility/acceptable-breakages-v10.0.99.txt`:
    These are because we are no longer generating the `*Consts` types
    when for Default Interface Methods are enabled.

  * `tests/api-compatibility/acceptable-breakages-v10.0.txt`:
    These are because there was a bug where we were not generating
    `[Obsolete]` on fields that were turned into properties.  Now the
    attribute is generated in API-28 (the "contract"), but they are no
    longer marked as deprecated by Google in API-29
    (the "implementation"), so they appear as removing the attribute.

  * `tests/api-compatibility/acceptable-breakages-v8.0.txt`:
    As with v10.0, a "prop-ified" field was missing `[Obsolete]`, and
    Google later un-deprecated the field.
@github-actions github-actions bot locked and limited conversation to collaborators Feb 5, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
do-not-merge PR should not be merged. enhancement Proposed change to current functionality.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants