Targeting Everett/Ranier (.NET 1.1/1.0) from Visual Studio 2005
For some time now I have been wanting to build Everett/.NET 1.1 Projects using Whidbey. The solution I had been using up until this point was
Robert McLaws'
MSBuild Compatibility Toolkit. I appreciated Robert's work but it was missing the mark in a few ways:
- Prebuild, clean, etc... never run for targets other than 2.0.
- It doesn't work for referenced assemblies (other than those in the .NET Framework)
- It ignores VS configurations. In theory, v1.1 should be its own configuration.
- It doesn't leverage the properties or targets in Microsoft.Common.Targets.
None of these are show stoppers but I decided to see if I could come up with a different approach. I paired with Michael Stokesbary on the task and the following solution is what we came up with a little help from Alex Kipman:
Step 1
In this step you need to fix an oversite on Microsoft's part and change an entry at the bottom of
%windir%\Microsoft.NET\Framework\v2.0.40607\Microsoft.CSharp.targets
In the Csc target, change the UseHostCompilerIfAvailable to
UseHostCompilerIfAvailable="$(UseHostCompilerIfAvailable)"
This is the only edit to a Microsoft file and this "fix" will be in future releases of MSBuild (the change has already been checked in).
Step 2
Open your csproj file and add the following configuration:
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug.Everett|AnyCPU' ">
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<!-- Add NET11 to #if' your NET 1.1 code and #else your NET 2.0 code. -->
<DefineConstants>DEBUG;TRACE;NET11</DefineConstants>
<!-- Set the path that you want your v1.1 targets to compile to -->
<OutputPath>bin\v1.1\Debug\</OutputPath>
<!-- Modify the version number depending on what version you are compiling for. -->
<CscToolPath>$(WINDIR)\Microsoft.NET\Framework\v1.1.4322</CscToolPath>
<ResGenToolPath>C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.1\Bin</ResGenToolPath>
<TargetFrameworkDirectory>$(WINDIR)\Microsoft.NET\Framework\v1.1.4322</TargetFrameworkDirectory>
<TargetFrameworkVersion>v1.1</TargetFrameworkVersion>
<BuildingInsideVisualStudio>false</BuildingInsideVisualStudio>
<UseHostCompilerIfAvailable>false</UseHostCompilerIfAvailable>
</PropertyGroup>
You need to change the version path if you wish to compile for Ranier/.Net 1.0 and specify your language ToolPath if you are not C# inclined.
Step 3
At the bottom of your file (properties that appear last will override earlier properties) add the following property group.
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug.Everett|AnyCPU' ">
<BuildingInsideVisualStudio>false</BuildingInsideVisualStudio>
<ReferencePath>$(ReferencePath);$(WINDIR)\Microsoft.NET\Framework\v1.1.4322</ReferencePath>
</PropertyGroup>
Step 4
Add the following target to the end of the file (before the </Project> tag obviously.
<Target Name="GetFrameworkPaths" DependsOnTargets="$(GetFrameworkPathsDependsOn)" >
<CreateProperty Value="$(WINDIR)\Microsoft.NET\Framework\v1.1.4322"
Condition="'$(Configuration)|$(Platform)' == 'Debug.Everett|AnyCPU' ">
<Output PropertyName="TargetFrameworkDirectory" TaskParameter="Value" />
</CreateProperty>
<!-- Get the path to the target .NET framework directory. -->
<GetFrameworkPath Condition=" '$(Configuration)|$(Platform)' != 'Debug.Everett|AnyCPU' ">
<Output TaskParameter="Path" PropertyName="TargetFrameworkDirectory"/>
</GetFrameworkPath>
<!-- Get the path to the target .NET framework SDK directory. -->
<GetFrameworkSDKPath >
<Output TaskParameter="Path" PropertyName="TargetFrameworkSDKDirectory"/>
</GetFrameworkSDKPath>
</Target>
Step 5 (optional)
To see what version of the framework was used you can optionally add the following postbuild step:
<PropertyGroup Condition="">
<PostBuildEvent>
CALL "%VS80COMNTOOLS%\vsvars32.bat" > NUL
ildasm "$(TargetPath)" /TEXT/NOIL /ITEM="" | FIND /I "Metadata version"
</PostBuildEvent>
</PropertyGroup>
Step 6
In order for the configuration to show up in the Visual Studio UI (at least until the next release) you will need to edit your solution file either via VS.NET or within a text file. You need to add the following inside the GlobalSection(ProjectConfigurationPlatforms) = postSolution section:
{<Your.Project.Guid>}.Debug.Everett|Any CPU.ActiveCfg = Debug.Everett|Any CPU
{<Your.Project.Guid>}.Debug.Everett|Any CPU.Build.0 = Debug.Everett |Any CPU
Notes
- I believe that Robert McLaws will be updating his MSBuild compatibility toolkit to use the above solution.
- I did not do this on my own. As already mentioned, Michael Stokesbary paired with me throughout the process, even when meeting with the MSBuild team to discuss our solution and a few issues we encountered.
- Other assistants were Anson Horton, Luke Hoban, Robert McLaws, Kieran Mockford, and Alex Kipman.
- In an upcoming release there will be an easy way to add targets that are machine wide, until then, the above target (Step 4) needs to be added (or imported) to all csproj file or added to Microsoft.Common.Targets..
Update:
Wednesday, December 15, 2004 3:36:48 AM (Pacific Standard Time, UTC-08:00)
Computer Related | .NetTracked by:
http://www.theharters.com/blogs/PermaLink.aspx?guid=442e8dc1-f7c0-4713-a34e-0acc... [Pingback]