Bug 10948 - Need to allow overriding Reference Assemblies path
Summary: Need to allow overriding Reference Assemblies path
Alias: None
Product: Android
Classification: Xamarin
Component: MSBuild ()
Version: 4.6.x
Hardware: PC Mac OS
: Low normal
Target Milestone: ---
Assignee: Atsushi Eno
Depends on:
Reported: 2013-03-06 15:17 UTC by Jonathan Pryor
Modified: 2013-09-13 10:23 UTC (History)
3 users (show)

Is this bug a regression?: ---
Last known good build:

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description Jonathan Pryor 2013-03-06 15:17:42 UTC
It is frequently desirable to have multiple versions of Xamarin.Android installed onto a machine. This is currently ~impossible because the toolchain assumes single directories, e.g.

C:\Program Files (x86)\MSBuild\Xamarin\Android\*
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\MonoAndroid\*

The former is $(MSBuildExtensionsPath); the latter is where our profile assemblies are installed, primarily so that Visual Studio can find them.

The former can (or should be able to) be overridable by setting MSBuildExtensionsPath (though that may be less than desirable...)

The latter cannot be overridden at all. That's a problem.

Add a way to set the Reference Assemblies directory via an MSBuild property.
Comment 1 Jonathan Pryor 2013-03-06 16:23:13 UTC
It looks like this should use the $(TargetFrameworkRootPath) MSBuild property.
Comment 2 Atsushi Eno 2013-06-04 03:49:51 UTC
I believe it is implemented in master msbuild tasks. Reopen if that's not what you expected. [master f28a2d8]
Comment 4 Jonathan Pryor 2013-06-04 11:13:58 UTC
Let's restate the _intent_ of this bug.

A _Windows_ developer should be able to:

1. Install the Android SDK+NDK "somewhere"

2. Extract our installer .msi:

    > mkdir C:\XA-4.7.6
    > msiexec /a mono-android-4.7.06000.msi /qb TARGETDIR=C:\XA-4.7.6

    This will create, among other dirs:
        C:\XA-4.7.6\PFILES\Reference Assemblies\Microsoft\Framework\MonoAndroid

3. Build using the SDKs extracted in (1) and (2):

    > msbuild /p:AndroidSdkDirectory=Path\From\(1) ^
        /p:AndroidNdkDirectory=Path\From\(1) ^
        /p:MSBuildExtensionsPath=C:\XA-4.7.6\PFILES\MSBuild ^
        /p:TargetFrameworkRootPath=C:\XA-4.7.6\PFILES\Reference Assemblies\Microsoft\Framework\MonoAndroid

    Or something quasi-equivalent to that.

If a full, "real" install of Xamarin.Android is required, this bug is not fixed. If registry entries are required, this bug is not fixed. If config files are required...this bug is not fixed. ;-)
Comment 7 Atsushi Eno 2013-06-04 19:36:35 UTC
That sounds like it's not only about assembly reference resolution and takes a lot more time to enhance our toolchain.
Comment 10 Jonathan Pryor 2013-09-13 10:23:32 UTC
Fixed in monodroid/65360003 (mostly in monodroid/fe02f03e).

There are 6 MSBuild properties/environment variables which control where assemblies are found and where the Xamarin.Android utilities are located:

  * $(AndroidSdkDirectory): The location of the Android SDK.
    If not specified, is looked up via Registry entry.

  * $(AndroidNdkDirectory): The location of the Android NDK.
    If not specified, is looked up via Registry entry.

  * $(JavaSdkDirectory): The location of the Java SDK/JDK.
    If not specified, is looked up via Registry entry.

  * $(MonoAndroidBinDirectory): The location of `mandroid` (OS X)
    or mandroid.exe (Windows). Can be autodetected based on
    Defaults to %ProgramFiles(x86)%\MSBuild\Xamarin\Android.

  * $(MonoAndroidToolsDirectory): The location of
    Defaults to %ProgramFiles(x86)%\MSBuild\Xamarin\Android.

  * $(TargetFrameworkRootPath): The location of the Xamarin.Android
    framework assemblies (mscorlib.dll, Mono.Android.dll, etc.).
    This is a "normal" MSBuild framework directory, i.e. it should NOT
    be the directory that contains Mono.Android.dll but its
    parent's parent's directory


 1. Download the .msi, e.g. mono-android-4.8.03162.msi.

 2. Extract the .msi:
    > mkdir C:\XA-4.8.3
    > msiexec /a mono-android-4.7.06000.msi /qb TARGETDIR=C:\XA-4.8.3

    As a correction to Comment #4, the directories of interest are actually:
        C:\XA-4.8.3\Reference Assemblies\Microsoft\Framework

 3. Build the project, setting _at least_ the $(MSBuildExtensionsPath), $(TargetFrameworkRootPath), and $(MonoAndroidToolsDirectory):

    > msbuild /t:SignAndroidPackage Project.csproj ^
    /p:Configuration=Release /v:diag ^
    /p:MSBuildExtensionsPath=E:\XA-4.8.3\MSBuild ^
    /p:MonoAndroidToolsDirectory=E:\XA-4.8.3\MSBuild\Xamarin\Android ^ 
    /p:TargetFrameworkRootPath="E:\XA-4.8.3\Reference Assemblies\Microsoft\Framework"

The above will create the bin\Release\*-Signed.apk file, suitable for device installs.

To verify proper behavior, view the MSBuild log output and check for the following:

* Task "ResolveSdks"

>     ReferenceAssemblyPaths: E:\XA-4.8.3\Reference Assemblies\Microsoft\Framework\MonoAndroid\v1.0\

The ReferenceAssemblyPaths input value should be a subdirectory of the $(TargetFrameworkRootPath) value.

>     MonoAndroidBinPath: E:\XA-4.8.3\MSBuild\Xamarin\Android
>     MonoAndroidToolsPath: E:\XA-4.8.3\MSBuild\Xamarin\Android

These should match the MSBuild /p: values.

* Search the log output for "Xamarin.Android.Common.targets". It should be found in the $(MSBuildExtensionsPath) override.

> Target "_SetLatestTargetFrameworkVersion" in file "E:\XA-4.8.3\MSBuild\Xamarin\Android\Xamarin.Android.Common.targets" from project "E:\Development\Projects\Scratch.HelloXamarin\Scratch.HelloXamarin.csproj" (target "_CheckProjectItems" depends on it):

* Search the log output for "Mono.Android.dll". It should be found under $(TargetFrameworkRootPath):

>   Primary reference "Mono.Android, Version=, Culture=neutral, PublicKeyToken=84e04ff9cfb79065".
>       Resolved file path is "E:\XA-4.8.3\Reference Assemblies\Microsoft\Framework\MonoAndroid\v2.2\Mono.Android.dll".

* Search the log output for "C:\Program Files (x86)\MSBuild". No matches should be found.