Skip to content

Commit

Permalink
[create-vsix] Create .vsix files
Browse files Browse the repository at this point in the history
Visual Studio 2017 uses `.vsix` files for Xamarin.Android SDK support.
A `.vsix` file is [ZIP container with additional metadata][0], and the
[Microsoft.VSSDK.BuildTools NuGet package][1] contains various MSBuild
targets and tools to assist in creating `.vsix` files.

Add a new `build-tools/create-vsix/create-vsix.csproj` project to
create the `bin/Build$(Configuration)/Xamarin.Android.Sdk*.vsix` file,
so that we can plausibly provide per-build OSS Xamarin.Android
releases that work with Visual Studio 2017.

Unfortunately those tools were written on Windows, and not really well
tested on macOS or Linux... In particular, there are case-sensitivity
and directory-separator-char issues with the tooling, necessitating
that `MONO_IOMAP=all` be exported in order to run them:

	MONO_IOMAP=all msbuild build-tools/create-vsix/create-vsix.csproj /p:CreateVsixContainer=True

Meanwhile, we're still attempting to allow things to be built with
`xbuild` [^3]. Thread this needle by "special-casing" the
`$(BuildDependsOn)`, `$(CopyVsixManifestFileDependsOn)`, and
`$(DetokenizeVsixManifestFileDependsOn)` MSBuild properties so that
when the `$(CreateVsixContainer)` MSBuild property is False -- the
default -- no `.vsix` package will be created, and `xbuild` will be
able to build the project.

Similar needle threading is needed to "support" building on Linux: the
Microsoft.VSSDK.BuildTools NuGet package uses case in an inconsistent
fashion -- or is it `nuget`? -- which results in
[failures when building on Linux][2] because `nuget` extracts e.g.:

	packages/Microsoft.VSSDK.BuildTools.15.0.26201/tools/vssdk/Microsoft.VsSDK.targets

while we attempt to `<Import/>` the file:

	packages/Microsoft.VSSDK.BuildTools.15.0.26201//tools/VSSDK/Microsoft.VsSDK.targets

`vssdk` != `VSSDK` on case-sensitive filesystems, so this results in
an error on Ubuntu (and presumably case-senstive macOS as well).

Handle the Linux case by extending the `xbuild` case: *even when*
`$(CreateVsixContainer)` is True, we won't actually build the `.vsix`
unless the `$(VsSDKInstall)` directory exists, which is the
`tools/VSSDK` path.

Building with `$(CreateVsixContainer)` set to True will require using
`msbuild` with `MONO_IOMAP=all` exported, while using case-insensitive
filesystem.

The new `make create-vsix CONFIGURATIONS=Debug` target can be used to
explicitly create the `Xamarin.Android.Sdk.vsix` file.

[0]: https://msdn.microsoft.com/en-us/library/dd997148.aspx
[1]: https://www.nuget.org/packages/Microsoft.VSSDK.BuildTools/
[2]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-anroid-linux-pr-builder/297/consoleText
[^3]: But for how much longer?
  • Loading branch information
jonpryor committed Mar 30, 2017
1 parent 02a2eae commit 6b0dd12
Show file tree
Hide file tree
Showing 17 changed files with 540 additions and 14 deletions.
30 changes: 20 additions & 10 deletions Documentation/UsingJenkinsBuildArtifacts.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@

The [**Project xamarin-android** Jenkins page][xa-jenkins-page] has a link
to the [Latest Azure Artifacts][xa-macOS-azure-artifacts], which contains an
`oss-xamarin.android*.zip` file for every Jenkins build on macOS.
The `oss-xamarin.android*.zip` file can be downloaded and used, without
`oss-xamarin.android*.zip` and `Xamarin.Android.Sdk*.vsix` file for every
Jenkins build on macOS. These files can be downloaded and used, without
requiring a local `xamarin-android` repo build.

[xa-jenkins-page]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/
Expand All @@ -23,20 +23,15 @@ download the `oss-xamarin.android*.zip` file, e.g.

[oss-xa-macOS]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android/lastSuccessfulBuild/Azure/processDownloadRequest/xamarin-android/oss-xamarin.android_v7.2.99.19_Darwin-x86_64_master_3b893cd.zip

Windows users using Visual Studio 2017 may instead download the
`Xamarin.Android.Sdk*.vsix` file.

macOS users may just extract this into their **Downloads** folder using
**Archive Utility.app** or `unzip` from **Terminal.app**. This will result
in a file such as:

$HOME/Downloads/oss-xamarin.android_v7.2.99.19_Darwin-x86_64_master_3b893cd/bin/Debug/bin/xabuild

Windows users should right-click this file within Explorer and click
**Extract All...**, and in the **Extract Compressed (Zipped) Folders** dialog
enter a *short* path such as `C:\xa-sdk`. This is necessary because some
of the contained filenames are quite long. This will result in a path
such as:

C:\xa-sdk\oss-xamarin.android_v7.2.99.19_Darwin-x86_64_master_3b893cd\bin\Debug\bin\mono-symbolicate.cmd

Linux/x86_64 users can go to the
[Latest xamarin-android-linux Azure Artifacts page][xa-linux-azure-artifacts]
and download the `oss-xamarin.android*.zip` file, e.g.
Expand All @@ -45,6 +40,20 @@ and download the `oss-xamarin.android*.zip` file, e.g.
[xa-linux-azure-artifacts]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android-linux/lastSuccessfulBuild/Azure/
[oss-xa-Linux]: https://jenkins.mono-project.com/view/Xamarin.Android/job/xamarin-android-linux/lastSuccessfulBuild/Azure/processDownloadRequest/xamarin-android/oss-xamarin.android_v7.2.99.19_Linux-x86_64_master_3b893cd.zip

## Windows Installation

Windows users can right-click the `oss-xamarin.android*.zip` file within
Windows Explorer and click **Extract All...**, and in the
**Extract Compressed (Zipped) Folders** dialog enter a *short* path such as
`C:\xa-sdk`. This is necessary because some of the contained filenames are
quite long. This will result in a path such as:

C:\xa-sdk\oss-xamarin.android_v7.2.99.19_Darwin-x86_64_master_3b893cd\bin\Debug\bin\mono-symbolicate.cmd

Alternatively, if you download the `Xamarin.Android.Sdk*.vsix` file, you can
double-click the file to install the Xamarin.Android SDK extension into
Visual Studio 2017.

# Using Jenkins Build Artifacts

## Command-line use: Linux and macOS
Expand Down Expand Up @@ -104,6 +113,7 @@ For example (using the paths from [Android SDK Setup](#Android_SDK_Setup)):
samples\HelloWorld\HelloWorld.csproj

<a name="Android_SDK_Setup" />

# Android SDK Setup

Please see the [Android Studio][android-studio] page to download the
Expand Down
11 changes: 11 additions & 0 deletions Xamarin.Android.sln
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "javadoc2mdoc", "tools\javad
EndProject
Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Xamarin.Android.Build.Tests.Shared", "src\Xamarin.Android.Build.Tasks\Tests\Xamarin.Android.Build.Tests\Xamarin.Android.Build.Tests.Shared.shproj", "{BD1D66BF-5AC7-4926-8EBE-B2198A112EB0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "create-vsix", "build-tools\create-vsix\create-vsix.csproj", "{94756FEB-1F64-411D-A18E-81B5158F776A}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|AnyCPU = Debug|AnyCPU
Expand Down Expand Up @@ -489,6 +491,14 @@ Global
{A87352E6-CE7F-4346-B6B1-586AE931C0A7}.XAIntegrationDebug|AnyCPU.Build.0 = Debug|Any CPU
{A87352E6-CE7F-4346-B6B1-586AE931C0A7}.XAIntegrationRelease|AnyCPU.ActiveCfg = Debug|Any CPU
{A87352E6-CE7F-4346-B6B1-586AE931C0A7}.XAIntegrationRelease|AnyCPU.Build.0 = Debug|Any CPU
{94756FEB-1F64-411D-A18E-81B5158F776A}.Debug|AnyCPU.ActiveCfg = Debug|Any CPU
{94756FEB-1F64-411D-A18E-81B5158F776A}.Debug|AnyCPU.Build.0 = Debug|Any CPU
{94756FEB-1F64-411D-A18E-81B5158F776A}.Release|AnyCPU.ActiveCfg = Release|Any CPU
{94756FEB-1F64-411D-A18E-81B5158F776A}.Release|AnyCPU.Build.0 = Release|Any CPU
{94756FEB-1F64-411D-A18E-81B5158F776A}.XAIntegrationDebug|AnyCPU.ActiveCfg = Debug|Any CPU
{94756FEB-1F64-411D-A18E-81B5158F776A}.XAIntegrationDebug|AnyCPU.Build.0 = Debug|Any CPU
{94756FEB-1F64-411D-A18E-81B5158F776A}.XAIntegrationRelease|AnyCPU.ActiveCfg = Debug|Any CPU
{94756FEB-1F64-411D-A18E-81B5158F776A}.XAIntegrationRelease|AnyCPU.Build.0 = Debug|Any CPU
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{8FF78EB6-6FC8-46A7-8A15-EBBA9045C5FA} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
Expand Down Expand Up @@ -540,6 +550,7 @@ Global
{E0890301-F75F-40E7-B008-54C28B3BA542} = {864062D3-A415-4A6F-9324-5820237BA058}
{A87352E6-CE7F-4346-B6B1-586AE931C0A7} = {864062D3-A415-4A6F-9324-5820237BA058}
{BD1D66BF-5AC7-4926-8EBE-B2198A112EB0} = {CAB438D8-B0F5-4AF0-BEBD-9E2ADBD7B483}
{94756FEB-1F64-411D-A18E-81B5158F776A} = {E351F97D-EA4F-4E7F-AAA0-8EBB1F2A4A62}
EndGlobalSection
GlobalSection(MonoDevelopProperties) = preSolution
Policies = $0
Expand Down
1 change: 1 addition & 0 deletions build-tools/create-vsix/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Xamarin.Android.Sdk.pkgdef
27 changes: 27 additions & 0 deletions build-tools/create-vsix/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
using System.Reflection;
using System.Runtime.CompilerServices;

// Information about this assembly is defined by the following attributes.
// Change them to the values specific to your project.

[assembly: AssemblyTitle ("Xamarin.Android.Sdk")]
[assembly: AssemblyDescription ("")]
[assembly: AssemblyConfiguration ("")]
[assembly: AssemblyCompany ("")]
[assembly: AssemblyProduct ("Xamarin.Android.Sdk")]
[assembly: AssemblyCopyright ("")]
[assembly: AssemblyTrademark ("")]
[assembly: AssemblyCulture ("")]

// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}".
// The form "{Major}.{Minor}.*" will automatically update the build and revision,
// and "{Major}.{Minor}.{Build}.*" will update just the revision.

[assembly: AssemblyVersion ("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

// The following attributes are used to specify the signing key for the assembly,
// if desired. See the Mono documentation for more information about signing.

//[assembly: AssemblyDelaySign(false)]
//[assembly: AssemblyKeyFile("")]
Binary file not shown.
140 changes: 140 additions & 0 deletions build-tools/create-vsix/VSPackage.resx
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
VS SDK Notes: This resx file contains the resources that will be consumed from your package by Visual Studio.
For example, Visual Studio will attempt to load resource '400' from this resource stream when it needs to
load your package's icon. Because Visual Studio will always look in the VSPackage.resources stream first for
resources it needs, you should put additional resources that Visual Studio will load directly into this resx
file.
Resources that you would like to access directly from your package in a strong-typed fashion should be stored
in Resources.resx or another resx file.
-->
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="110" xml:space="preserve">
<value>Xamarin.Android SDK</value>
</data>
<data name="112" xml:space="preserve">
<value>Xamarin.Android Reference Assemblies and MSBuild support.</value>
</data>
<data name="400" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources/AndroidSdkPackage.ico;System.Drawing.Icon, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>
Binary file not shown.
92 changes: 92 additions & 0 deletions build-tools/create-vsix/create-vsix.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\packages\Microsoft.VSSDK.BuildTools.15.0.26201\build\Microsoft.VSSDK.BuildTools.props" Condition="Exists('..\..\packages\Microsoft.VSSDK.BuildTools.15.0.26201\build\Microsoft.VSSDK.BuildTools.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{94756FEB-1F64-411D-A18E-81B5158F776A}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>Xamarin.Android.Sdk</RootNamespace>
<AssemblyName>Xamarin.Android.Sdk</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<CreateVsixContainer Condition=" '$(CreateVsixContainer)' == '' ">False</CreateVsixContainer>
<CopyBuildOutputToOutputDirectory>False</CopyBuildOutputToOutputDirectory>
<CopyOutputSymbolsToOutputDirectory>False</CopyOutputSymbolsToOutputDirectory>
<GeneratePkgDefFile>False</GeneratePkgDefFile>
<IncludeAssemblyInVSIXContainer>False</IncludeAssemblyInVSIXContainer>
<IncludeCopyLocalReferencesInVSIXContainer>False</IncludeCopyLocalReferencesInVSIXContainer>
<IncludeDebugSymbolsInLocalVSIXDeployment>False</IncludeDebugSymbolsInLocalVSIXDeployment>
<IncludeDebugSymbolsInVSIXContainer>False</IncludeDebugSymbolsInVSIXContainer>
<IsProductComponent Condition=" '$(IsProductComponent)' == '' ">False</IsProductComponent>
<_BuildVsix Condition=" '$(CreateVsixContainer)' == 'True' And Exists ('$(VsSDKInstall)') ">True</_BuildVsix>
<_BuildVsix Condition=" '$(_BuildVsix)' == '' ">False</_BuildVsix>
</PropertyGroup>
<Import Project="..\..\Configuration.props" />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug</OutputPath>
<DefineConstants>DEBUG;</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Optimize>true</Optimize>
<OutputPath>bin\Release</OutputPath>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<ConsolePause>false</ConsolePause>
</PropertyGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<Content Include="Resources\AndroidSdkPackage.ico" />
<Content Include="Xamarin.Android.Sdk.pkgdef">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<IncludeInVSIX>True</IncludeInVSIX>
</Content>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="VSPackage.resx">
<MergeWithCTO>True</MergeWithCTO>
<ManifestResourceName>VSPackage</ManifestResourceName>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
<None Include="source.extension.vsixmanifest">
<SubType>Designer</SubType>
</None>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(VsSDKInstall)\Microsoft.VsSDK.targets" Condition=" '$(_BuildVsix)' == 'True' " />
<PropertyGroup Condition=" '$(_BuildVsix)' == 'True' ">
<BuildDependsOn>
_CreateDependencies;
$(BuildDependsOn);
_CopyToBuildConfiguration
</BuildDependsOn>
</PropertyGroup>
<!-- Hacks to allow "building" with xbuild -->
<PropertyGroup Condition=" '$(_BuildVsix)' == 'False' ">
<BuildDependsOn>
_CreateDependencies;
$(BuildDependsOn);
</BuildDependsOn>
<CopyVsixManifestFileDependsOn />
<DetokenizeVsixManifestFileDependsOn />
</PropertyGroup>
<Import Project="create-vsix.targets" />
<Import Project="..\..\packages\Microsoft.VSSDK.BuildTools.15.0.26201\build\Microsoft.VSSDK.BuildTools.targets" Condition="Exists('..\..\packages\Microsoft.VSSDK.BuildTools.15.0.26201\build\Microsoft.VSSDK.BuildTools.targets')" />
<ItemGroup>
<ProjectReference Include="..\xa-prep-tasks\xa-prep-tasks.csproj">
<Project>{7CE69551-BD73-4726-ACAA-AAF89C84BAF8}</Project>
<Name>xa-prep-tasks</Name>
<ReferenceOutputAssembly>False</ReferenceOutputAssembly>
<Private>False</Private>
</ProjectReference>
</ItemGroup>
</Project>
Loading

0 comments on commit 6b0dd12

Please sign in to comment.