SharpDevelop Community

Get your problems solved!
Welcome to SharpDevelop Community Sign in | Join | Help
in Search

Daniel Grunwald

MSBuild Multi-Targeting in SharpDevelop

SharpDevelop has had multi-targeting support for a long time - for example, SharpDevelop 2.0 supported targeting .NET 1.0, 1.1 and 2.0. Our original multi-targeting implementation would not only change the target framework, but also use the matching C# compiler version*.

When Visual Studio 2008 and MSBuild 3.5 came along and introduced official multi-targeting support, we separated the 'target framework' and 'compiler version' settings. The 'target framework' setting uses the <TargetFrameworkVersion> MSBuild property, which is the official multi-targeting support as in Visual Studio 2008. The 'compiler version' setting determines the MSBuild ToolsVersion, which controls the version of the C# compiler to use - Visual Studio does not have this feature.

I'll call the latter feature MSBuild Multi-Targeting, as this allows us to pick the MSBuild version to use, and thus enables SharpDevelop to open and edit VS 2005 or 2008 projects without having to upgrade them to the VS 2010 project format.

Unfortunately, life isn't as simple as that. It turns out that MSBuild 4.0 is unable to compile projects with a ToolsVersion lower than 4.0 if the Windows SDK 7.1 is not installed. To allow users to use SharpDevelop without downloading the Windows SDK, we implemented a simple fix: we use MSBuild 3.5 to compile projects with a ToolsVersion of 2.0 or 3.5. This is why SharpDevelop ships with both "ICSharp­Code.Sharp­Develop.Build­Worker40.exe" and "ICSharp­Code.Sharp­Develop.Build­Worker35.exe".

Now what happens if SharpDevelop is run on a machine without .NET 3.5? If the framework specified by the 'ToolsVersion' is missing, SharpDevelop crashed with an MSBuild error when opening the project. There were also crashes when creating/upgrading projects to missing ToolsVersions. Moreover, in the rare scenario where .NET 2.0 and .NET 4.0 are installed, but .NET 3.5 is missing, SharpDevelop was able to open the project but the build worker would crash when trying to compile.

For this reason, the SharpDevelop 4.0 and 4.1 setups require both  .NET 3.5 and .NET 4.0 to be installed. This wasn't an issue when we made that decision - .NET 3.5 is likely to be already installed on most machines. However, Windows 8 will change that - .NET 4.5 is installed by default, but .NET 3.5 is missing. So we added the necessary error handling to SharpDevelop 4.2. The SharpDevelop 4.2 setup no longer requires .NET 3.5 - you'll need it only when targeting .NET 2.0/3.0 or 3.5.

Another issue is that .NET 4.0 does not ship with the Reference Assemblies - you need to install the Windows SDK to get those. This causes MSBuild to reference the assemblies in the GAC instead, which might be a later version (due to installed service packs or in-place upgrades like .NET 4.5), and also emit massive amounts of warnings (one warning per reference). Moreover, it caused the 'Copy Local' flag to default to true for references to .NET assemblies, causing System.dll etc. to be copied into the output directory.

At the time, the reference assemblies were only available as part of Visual Studio 2010 - the free Windows SDK 7.1 was released later. So it was a high priority for us to work around this problem. For this reason, SharpDevelop injects a custom MSBuild .targets file into the project being built: SharpDevelop.TargetingPack.targets. This file runs a simple custom MSBuild task that detects references to default .NET assemblies and sets the 'Copy Local' flag to false. (we also inject several other custom .targets files; for example for running FxCop or StyleCop as part of a build)

We used the Microsoft.Build.Utitilies.dll when implementing this custom task. However, that library ships only with .NET 2.0, not with .NET 4.0, so we had to switch to Microsoft.Build.Utitilies.v4.dll to get the C# 4.0 build working without .NET 2.0. This should not be a problem as the copy local workaround is only included when targeting .NET 4.0 or higher, so we won't try to load it the 3.5 build worker process.

 

To summarize, the SharpDevelop 4.2 setup requires:

  • Windows XP SP2 or higher
  • .NET 4.0 Full (.NET 4.5 Full will also work)
  • VC++ 2008 runtime (part of .NET 3.5 so most people have it already)
  • In the minimal configuration, you can only compile for .NET 4.0 using MSBuild 4.0.

Additionally:

  • If .NET 4.5 is installed, the C# 5 compiler will replace the C# 4 compiler; and .NET 4.5 will appear as an additional target framework.
  • If .NET 3.5 SP1 is installed, you will be able to use .NET 2.0/3.0/3.5 as target framework, and C# 2 and C# 3 as compiler versions.
  • Installing the Windows SDK 7.1 is highly recommended (provides reference assemblies and documentation for code completion).
  • Some SharpDevelop features might require installation of additional tools such as FxCop, StyleCopF#, TortoiseSVN, SHFB.

* Everything said about the C# compiler in this post also applies to the VB compiler.

Published Mar 04 2012, 01:40 PM by DanielGrunwald
Filed under:

Comments

No Comments
Powered by Community Server (Commercial Edition), by Telligent Systems
Don't contact us via this (fleischfalle@alphasierrapapa.com) email address.