Use all TFM’s with SDK-style projects in Visual Studio for Mac

TL;DR

You can now use SDK-style projects, with all supported TFM’s, in Visual Studio for Mac. See getting started for details.

Issue

While Visual Studio for Mac supports the SDK-style projects, there have been a couple of issues blocking use of TFM’s other than net, netstandard, and netcoreapp.

  1. Those TFM’s are hard-coded and an SDK-style project containing any other target frameworks is blocked.
  2. Xamarin on the Mac has a multi-valued MSBuildExtensionsPath property. That means that it can search for targets in different locations. Unfortunately the logic this works with is limited to the <Import /> element, so if you set properties, as is required to use LanguageTargets, it won’t work. Fortunately, with some brainstorming with Ankit Jain and Mikayla Hutchinson, we found a solution.

Getting Started

You’ll need a few things:

  1. Latest stable channel of Visual Studio for Mac
  2. .NET Core 2 SDK (even if you’re not targeting .NET Standard 2 or .NET Core, the SDK style projects use these targets). Download here.
  3. Matt Ward‘s Extension to VSfM that removes TFM checks on SDK-style projects. Binary | Source. Install by going to Visual Studio -> Extensions... -> Install from file...

Then, create a new SDK-style project and use the latest version of the MSBuild.Sdk.Extras package, at least version 1.1.0-beta.69:

<PackageReference Include="MSBuild.Sdk.Extras" Version="1.1.0-beta.69" PrivateAssets="all" />

At the end of the project file, just before the closing tag, you’ll also need the following, as per the MSBuild SDK Extras readme:

<Import Project="$(MSBuildSDKExtrasTargets)" Condition="Exists('$(MSBuildSDKExtrasTargets)')" />

Here’s a complete example of using the SDK-style projects with an iOS class library:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>xamarinios10</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="MSBuild.Sdk.Extras" Version="1.1.0-beta.69" PrivateAssets="all" />
  </ItemGroup>

  <Import Project="$(MSBuildSDKExtrasTargets)" Condition="Exists('$(MSBuildSDKExtrasTargets)')" />
</Project>

Building these projects

These projects will build in the IDE (VSfM, VS, etc) or the command line. If you use the command line, you must use msbuild, not dotnet build. Keep in mind that with msbuild, you must explicitly call restore first, so your build steps will look like this:

msbuild /t:restore
msbuild /p:Configuration=Release

Notes

For the beta, since it’s a SemVer2 package, you must be using the NuGet v3 feed. If your VSfM prefs have https://www.nuget.org/api/v2/, you need to update that to be https://api.nuget.org/v3/index.json.

Support

If you run into issues, please file a bug on the MSBuild SDK Extras project site: https://github.com/onovotny/MSBuildSdkExtras/issues and reach
me @onovotny.