Multi-Target - James Montemagno https://staging.montemagno.com/tag/multi-target/ https://staging.montemagno.com/content/images/2017/08/MonogramIcon_Orange_NoBuffer.png Multi-Target - James Montemagno https://staging.montemagno.com/tag/multi-target/ Hugo -- gohugo.io Tue, 13 Oct 2026 22:20:07 GMT 60 Multi-Targeting: Where Did My Files Go? Fixing .NET Core 2.1 SDK Issues https://staging.montemagno.com/multi-targeting-where-did-my-files-go-fixing-net-core-2-1-sdk-issues/ 5b7ade4acce53300bfd41234 Tue, 21 Aug 2018 20:45:00 GMT I love multi-targeting for creating libraries, and it is at the core of all of my plugins and Xamarin.Essentials. If you don't know what multi-targeting is don't worry as it is pretty rare that you would need to use it if you are creating apps. Most likely you will want to use multi-targeting in creating cross-platform libraries. In the past you would have to create multiple libraries for each target framework (such as iOS or Android) that you wanted to support if there was platform specific code. With the new SDK style projects you can set the TargetFrameworks property and specify as many as you would like.

Here is Xamarin.Essentials that supports iOS, Android, UWP, and .NET Standard 1.0/2.0:

<TargetFrameworks>netstandard1.0;netstandard2.0;Xamarin.iOS10;MonoAndroid71;MonoAndroid80;MonoAndroid81;uap10.0.16299</TargetFrameworks>

What is amazing is that all of your files can live together and can be conditionally compiled so only certain files get compiled for a specific platform:

<ItemGroup>
    <Compile Include="**\*.shared.cs" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard')) ">
    <Compile Include="**\*.netstandard.cs" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('uap10.0')) ">
    <Compile Include="**\*.uwp.cs" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('MonoAndroid')) ">
    <Compile Include="**\*.android.cs" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('Xamarin.iOS')) ">
    <Compile Include="**\*.ios.cs" />
</ItemGroup>

This allows super beautiful project structures:

Capture

It also means that you can conditionally compile your code too:

#if NETSTANDARD1_0
    // do something for .net standard 1.0
#elif __ANDROID__
    // else for Android
#else
    // anything else.
#endif

This all works thanks to Oren Novotny's amazing library MSBuild SDK Extras, which is easily configured by adding a nuget to all projects and adding a single import at the bottom of your csproj:

<ItemGroup>
    <PackageReference Include="MSBuild.Sdk.Extras" Version="1.6.47" PrivateAssets="All" />
    <Compile Include="**\*.shared.cs" />
</ItemGroup>
<Import Project="$(MSBuildSDKExtrasTargets)" Condition="Exists('$(MSBuildSDKExtrasTargets)')" />

Enter .NET Core SDK 2.1

Since this is sort of "unofficial" special tooling magic, sometimes things can break and recently when I installed .NET Core SDK 2.1 all my files went missing for iOS/Android/UWP. If we toggle on "show all files" they are totally there and get compiled but now intellisense stops working:

Missing

We reported it and worked with the .NET team on how to resolve it.

Fix 1: Include Workaround

The work around from the .NET team was to add an additional include at the bottom of our csproj that basically includes any .cs files and excludes defaults.

<ItemGroup>
    <PackageReference Include="MSBuild.Sdk.Extras" Version="1.6.47" PrivateAssets="All" />
    <Compile Include="**\*.shared.cs" />
</ItemGroup>
<ItemGroup>
    <None Include="**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>
<Import Project="$(MSBuildSDKExtrasTargets)" Condition="Exists('$(MSBuildSDKExtrasTargets)')" />

Fix 2: Update to 1.6.47 of Sdk Extras & Project Type

I work extremely closely with Oren and whenever something happens with Essentials I freak out :) So when we had Fix 1 in place and working the next natural thing was to roll it into the official NuGet! Last week Oren did just this!

The only thing here is that we will want to ensure we upgrade to his new project type instead of using the PackageReference and Import. He outlines it great in his documentation.

In short instead of adding any nugets or imports we will replace:

<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">

with

<Project Sdk="MSBuild.Sdk.Extras/1.6.47">

Of course if you are using other types of files you may need to go back to Fix 1 to add them in manually, but his system is very smart. Be sure to report any bugs over to Oren on his GitHub repo.

]]>
Converting Xamarin Libraries to SDK Style & Multi-Targeted Projects https://staging.montemagno.com/converting-xamarin-libraries-to-sdk-style-multi-targeted-projects/ 5af9d3b5dc592200bfc94017 Mon, 14 May 2018 22:00:00 GMT If you are like me you may have a lot of standard Xamarin.iOS and Xamarin.Android libraries sitting around. They aren't plugins, but they do extend a single platform with custom functionality and controls. Wouldn't it be great if you could update them to the new SDK Style projects which use Package References, auto-NuGet packaging, and load WAY faster?!?!? It is all crazy simple to do just like converting old PCLs to .NET Standard. If you are setting up CI this is going to be a huge time saver as you can set it up in VSTS in minutes (blog coming this week).

Unload that Project

First things first, we need to get at that raw .csproj madness. Right click on the project and click Unload Project. Then right click again and select Edit *.csproj:

UnloadProject

Delete Everything!

That is right! Delete it all because we don't need it at all!

Replace it with my base project information. It is a bit verbose but based on the type of library you are creating there are some special things that you may want to include such as Android resources.

Note: I like to only compile items that end in .shared.cs, .ios.cs, or .android.cs to keep it tidy, but you can easily change what you compile into your library in the project structure.

Right click and re-load the project!

New-project

Spice it up

Now you can go in and any NuGets you may need with the PackageReference node in the ItemGroup of your choosing. Additionally, you can also turn on Multi-Targeting to generate both an iOS and Android (or whatever else like UWP and netstandard) by change TargetFramework to TargetFrameworks and specifying more frameworks.

Multi-Target

NuGet that Library

What is great about the SDK style projects is that you don't need a .nuspec at all for your NuGet and it can be generated automatically at build time! Whoa! Amazing Yes! You can also see the contents with the NuGet Package Explorer

All you need to do is turn on GeneratePackageOnBuild in the Release property group and then add the following items to the main PropertyGroup for the NuGet's information:

You can read more about these attributes over on the NuGet documentation.

Now when you compile in release mode you get a full NuGet with your library:

NuGet-1

SDK and Multi-Target Everything

If you have multiple libraries like me or building multiple libraries from a single solution you can also look into Directory.Build.props and Directory.Build.targets that enable you to group common properties together for a full solution.

I have gone through just about every project I have created and switched over to this new style of project because CI is so simple with it that I can manage a full CI/CD cycle for all of my libraries from one location:

Release

Check back later this week for my blog on how to take the SDK style projects that we have here and set them up for CI in VSTS.

See Me Convert a Library Live!

Because I love seeing things in action I walk through the exact steps here in this short video:

]]>