Makale Özeti

Visual Studio 2005 ile .Net Framework 1.1 için kod derleyin. MSBuild'in hoş özellikleri...

Makale

Visual Studio 2005 ile .Net Runtime 1.1 için kod derlemek

Evet, Visual Studio 2005 çıktı, ama canlı uygulamalar yazanların çoğu, hâlâ Visual Studio 2003 kullanıyor. Yazdığımız kodların çoğu .Net Framewrok 1.1 ile çalışıyor. Bu kodları VS2005 ile açtığımızda, VS2005, proje dosylarını  geri dönülemez şekilde değiştiriyor. 

Doğal olarak Windows Forms veya ASP.Net uygulamaları için Visual Studio 2005'in ürettiği kod yeni özellikleri kullanıyor olacaktır. Ama VS2005'in güzel editör özelliklerini kullanarak hâlâ .Net 1.1 için kod üretmek istiyorsanız aşağıdakileri deneyin.

  1. En alttaki dosya parçacığını, C:\Program Files\msbuild\ dizinine CrossCompile.CSharp.targets dosya adı ile kaydedin.
  2. Visual Studio 2005 ile yeni bir "Class Library" projesi başlatın. Adına MyApp deyin.
  3. Proje dosyaları yaratılınca, (VS2005 açık iken) MyApp.csproj adlı dosyayı (proje dizinin yaratıldığı dizinde bulunan, aynı adlı dizinin içindedir) Notepad ile açın, 
  4. Dosyanın altında bulunan <Import> tagını olduğu gibi;

    <Import Project="$(MSBuildExtensionsPath)\CrossCompile.CSharp.targets" />

    ile değiştirin. (Bu, birinci maddede yarattığımız dosyadır), $(MSBuildExtensionPath) ise, VS2005 ile gelen MSBuild uygulamasının kullandığı sabit, iyi tanımlanmış bir dizin adıdır ve varsayılan değeri C:\Program Files\msbuild\ olarak tanımlanmıştır.
  5. Daha sonra VS2005'i aktif hâle getirdiğinizde, MyApp.csproj bir güvenlik uyarısı çıkacak, ardından da projeyi yeniden açma şeklini soran bir diyalog çıkacaktır. Bunları geçin.
  6. VS2005'te Toolbar'da "Any CPU" yazan SelectList'te "Configuration manager..."i seçin.
  7. Açılan diaylogda "Platform" kolonundaki "Any CPU" yazan SelectList'i açın ve ".Net 1.1" i seçin.
  8. Kodunuzu derleyin...
  9. Derleme sırasında "using System.Collections.Generic;" satırı için hata üretilecektir. Çünkü kodunuz artık .Net 1.1 ile derlenmektedir.

İlle de .Net 1.1 ile çalışacacağım diyorsanız, düşünülebilecek bir alternatiftir. Ayrıca, CrossCompile.CSharp.targets dosyasını inceleyerek, Mono gibi versiyonlar için de çıktı üretebilirsiniz.
Bu yazı Jomo Fischer'in Blog'undan çevrilmiştir http://blogs.msdn.com/jomo_fisher/archive/2005/04/22/410903.aspx.

C:\Program Files\msbuild\CrossCompile.CSharp.targets

<!--
Use of included script samples are subject to the terms specified at http://www.microsoft.com/info/cpyright.htm
Written by Jomo Fisher
-->
<Project 
 DefaultTargets="Build" 
 xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

 <!--
 These two property groups inform VS that there is a Platform called .NET 1.1.
 --> 
 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|.NET 1.1' ">
  <DebugSymbols Condition="'$(DebugSymbols)'==''">true</DebugSymbols>
  <DebugType Condition="'$(DebugType)'==''">full</DebugType>
  <Optimize Condition="'$(Optimize)'==''">false</Optimize>
  <OutputPath Condition="'$(OutputPath)'==''">bin\.NET 1.1\Debug\</OutputPath>
  <DefineConstants Condition="'$(DefineConstants)'==''">DEBUG;TRACE</DefineConstants>
  <DefineConstants>$(DefineConstants);TARGETTING_FX_1_1</DefineConstants>
  <ErrorReport></ErrorReport>
  <WarningLevel Condition="'$(WarningLevel)'==''">4</WarningLevel>
  <UseHostCompilerIfAvailable>false</UseHostCompilerIfAvailable>
  <CscToolPath>$(SystemRoot)\Microsoft.NET\Framework\v1.1.4322</CscToolPath>
  <TargetFrameworkVersion>v1.0</TargetFrameworkVersion>
 </PropertyGroup>

 <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|.NET 1.1' ">
  <DebugType Condition="'$(DebugType)'==''">pdbonly</DebugType>
  <Optimize Condition="'$(Optimize)'==''">true</Optimize>
  <OutputPath Condition="'$(OutputPath)'==''">bin\.NET 1.1\Release\</OutputPath>
  <DefineConstants Condition="'$(DefineConstants)'==''">TRACE</DefineConstants>
  <DefineConstants>$(DefineConstants);TARGETTING_FX_1_1</DefineConstants>
  <ErrorReport></ErrorReport>
  <WarningLevel Condition="'$(WarningLevel)'==''">4</WarningLevel>
  <UseHostCompilerIfAvailable>false</UseHostCompilerIfAvailable>
  <CscToolPath>$(SystemRoot)\Microsoft.NET\Framework\v1.1.4322</CscToolPath>
  <TargetFrameworkVersion>v1.0</TargetFrameworkVersion>
 </PropertyGroup>

 <!--
 Import the standard C# targets
 -->
 <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />

 <!--
 Now that the standard targets have been brought in. Override some properties 
 and items it created.
 --> 
 <PropertyGroup>
  <AvailablePlatforms>$(AvailablePlatforms),.NET 1.1</AvailablePlatforms>

  <AssemblySearchPaths Condition=" '$(Platform)' == '.NET 1.1' ">
   {CandidateAssemblyFiles};
   $(ReferencePath);
   {HintPathFromItem};
   {TargetFrameworkDirectory};
   {AssemblyFolders};
   $(OutputPath);
   {GAC}
  </AssemblySearchPaths>

  <TargetFrameworkDirectory Condition=" '$(Platform)' == '.NET 1.1'">
   $(SystemRoot)\Microsoft.NET\Framework\v1.1.4322
  </TargetFrameworkDirectory>

 </PropertyGroup>

 <ItemGroup Condition=" '$(Platform)' == '.NET 1.1'">
  <TargetFrameworkDirectoryItem Include="$(SystemRoot)\Microsoft.NET\Framework\v1.1.4322">
   <InProject>false</InProject>
  </TargetFrameworkDirectoryItem>
 </ItemGroup>

 <!--
 Override this target from Microsoft.Common.Targets so that we can supply our own 
 value for $(TargetFrameworkDirectory). This controls where assembly resolution 
 logic finds FX assemblies.
 -->
 <Target
        Name="GetFrameworkPaths"
        DependsOnTargets="$(GetFrameworkPathsDependsOn)">

  <!-- Get the path to the target .NET framework directory. -->
  <GetFrameworkPath
   Condition=" '$(Platform)' != '.NET 1.1' ">
   <Output TaskParameter="Path" PropertyName="TargetFrameworkDirectory"/>
   <Output TaskParameter="Path" ItemName="TargetFrameworkDirectoryItem"/>
  </GetFrameworkPath>

  <!-- Get the path to the target .NET framework SDK directory. -->
  <GetFrameworkSDKPath
   Condition=" '$(Platform)' != '.NET 1.1' ">
   <Output TaskParameter="Path" PropertyName="TargetFrameworkSDKDirectory"/>
   <Output TaskParameter="Path" ItemName="TargetFrameworkSDKDirectoryItem"/>
  </GetFrameworkSDKPath>

 </Target>

 <!--
 For 1.1 builds, intercept the call to CorResGen target (which generates 2.0 resources) and
 slip in a call to our own CoreResGen_1_1.
 
 Handily, the devices version of the ResGen task is able to call the 1.1 version of 
 ResGen directly.
 -->
 <UsingTask TaskName="CFResGen" AssemblyFile="$(MSBuildBinPath)\Microsoft.CompactFramework.Build.Tasks.dll" />
 <PropertyGroup Condition="'$(Platform)' == '.NET 1.1'">
  <ResGenDependsOn>ResolveAssemblyReferences;BeforeResGen;CoreResGen_1_1;AfterResGen</ResGenDependsOn>
 </PropertyGroup>
 <Target
        Name="CoreResGen_1_1"
        DependsOnTargets="$(CoreResGenDependsOn)">
  
  <CFResGen
            Condition = " '@(ResxWithNoCulture)' != ''"
            Sources = "@(ResxWithNoCulture)"
            UseSourcePath = "$(UseSourcePath)"
            StateFile = "$(IntermediateOutputPath)$(MSBuildProjectFile).CrossCompileResGen.Cache"
            OutputResources = "@(ManifestResourceWithNoCultureName->'$(IntermediateOutputPath)%(Identity).resources')"
        >
   <!-- Appending to 'FilesWritten' list lets us be part of Clean and Incremental Clean. -->
   <Output TaskParameter = "FilesWritten" ItemName="FileWrites"/>
   <Output TaskParameter = "OutputResources" ItemName="ManifestResourceWithNoCulture"/>
  </CFResGen>

  <CFResGen
            Condition = " '@(ResxWithCulture)' != ''"
            Sources = "@(ResxWithCulture)"
            UseSourcePath = "$(UseSourcePath)"
            StateFile = "$(IntermediateOutputPath)$(MSBuildProjectFile).CrossCompileResGen.Cache"
            OutputResources = "@(ManifestResourceWithCultureName->'$(IntermediateOutputPath)%(Identity).resources')"
        >
   <!-- Appending to 'FilesWritten' list lets us be part of Clean and Incremental Clean. -->
   <Output TaskParameter = "FilesWritten" ItemName="FileWrites"/>
   <Output TaskParameter = "OutputResources" ItemName="ManifestResourceWithCulture"/>
   
  </CFResGen>
 </Target>

</Project>