1. 程式人生 > >自定義Msbuild target,學習MSBuild如何編譯後執行任務

自定義Msbuild target,學習MSBuild如何編譯後執行任務

1.自定義Msbuild target

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003"
DefaultTargets="CompileAll"
ToolsVersion="3.5">
	<!-- import system common Task targets-->
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <!-- Import Project="c:\.net3.5\Microsoft.Csharp.targets" /    -->

   <PropertyGroup>
      <!-- This AppName thing is the base name of your DLL or EXE -->
      <AppName>YourAppNameHere</AppName>
   </PropertyGroup>

   <!-- This build file compiles each .cs file into its own exe -->

   <PropertyGroup Condition="'$(Configuration)'==''">
      <Configuration>Debug</Configuration>
   <!-- Default -->
   </PropertyGroup>

   <PropertyGroup Condition="'$(Configuration)'=='Debug'">

      <Optimize>false</Optimize>
      <DebugSymbols>true</DebugSymbols>
      <!-- <OutputPath>.\bin</OutputPath>  -->
      <OutputPath>.\</OutputPath>
      <OutDir>.\</OutDir>
      <IntermediateOutputPath>.\</IntermediateOutputPath>
   </PropertyGroup>
   <!-- Specify the inputs by type and file name -->

   <ItemGroup>
      <CSFile Include="*.cs"/>
   </ItemGroup>

   <!-- specify reference assemblies for all builds in this project -->
   <ItemGroup>
      <Reference Include="mscorlib" />
      <Reference Include="System" />
      <Reference Include="System.Core" />
      <Reference Include="System.Data" />
      <Reference Include="System.Data.Linq" />
      <Reference Include="System.ServiceModel" />
      <Reference Include="System.ServiceModel.Web" />
      <Reference Include="System.Runtime.Serialization" />
      <!-- <Reference Include=".\ObjectDumper.dll" /> -->
   </ItemGroup>
   <Target Name="CompileAll" 
   <!-- ResolveAssemblyReferences will resolve $(Reference) to generate $(ReferencePath) -->
      DependsOnTargets="ResolveAssemblyReferences">
      <Message Text="Reference = @(Reference)" />
      <Message Text="ReferencePath = @(ReferencePath)" />
      <!-- Message Text="MS Build Tools path:  $(MSBuildToolsPath)" / -->
      <!-- Run the Visual C# compilation on all the .cs files. -->
      <CSC Sources="@(CSFile)"
         References="@(ReferencePath)"
         OutputAssembly="$(OutputPath)\$(AppName).exe"
         EmitDebugInformation="$(DebugSymbols)"
         TargetType="exe"
         Toolpath="$(MSBuildToolsPath)"
         Nologo="true"
      />
   </Target>
   <!-- redefine the Clean target, from the Microsoft.csharp.targets file.  (Last definition wins) -->

   <Target Name="Clean">
      <Delete Files="$(OutputPath)\$(AppName).exe"/>
      <Delete Files="$(OutputPath)\$(AppName).pdb"/>
      <Delete Files="%(CSFile.identity)~"/>
      <Delete Files="build.xml~"/>
   </Target>
</Project>

2.使用官方MSbuild構建專案

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" DefaultTargets="Build">
  <PropertyGroup>
    <OutputType>exe</OutputType>
    <PlatformTarget>AnyCPU</PlatformTarget>
    <OutputPath>bin\</OutputPath>
    <AssemblyName>$(CsFile)</AssemblyName>
  </PropertyGroup>

  <ItemGroup>
    <Reference Include="System.dll"/>
    <Reference Include="..\libs\customdll.dll"/>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="$(CsFile)" />
  </ItemGroup>
  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

msbuild在編譯完畢後執行其他任務的幾種方式

  1. 用PreBuild和PostBuild這2個事件,這個適合呼叫簡單的指令碼的需求,比如複製檔案,或者呼叫一個外部命令,直接用這個就行了。這個可以直接在Visual Studio裡設定,相對容易。
  2. 重寫預設的AfterBuild Target。說到Target,就要順帶提一下Task。Task和Target是msbuild裡專門用來執行任務的元素,具體區別是task是msbuild裡可以執行的最小單元任務,targets則是一系列的task的組合。AfterBuild target預設會在編譯完畢後觸發,我們可以通過取消csproj檔案裡的AfterBuild Target的註釋來加上我們要在編譯完跑的指令碼。有一點要注意的就是要保證AfterBuild Target必須出現在其他的Target import之後。
    用AfterTargets屬性,這個是msbuild 4以上的版本才支援的。比如 則定義了Optimize這個target依賴於Compile,必須等到Compile結束後才跑。
  3. 擴充套件BuildDependsOn列表,這個是最高階也是最靈活的用法。如果你需要跑一堆複雜的指令碼,並且它們之間還有依賴關係,那用這個就最合適了。

擴充套件BuildDependsOn列表

可以在專案檔案的末尾宣告另一個名為 BuildDependsOn 的屬性,從而對此屬性值進行覆蓋。 將以前的 BuildDependsOn 屬性包括在新屬性中,便可以將新目標新增到目標列表的開頭和結尾。 例如:

<PropertyGroup>  
    <BuildDependsOn>  
        MyCustomTarget1;  
        $(BuildDependsOn);  
        MyCustomTarget2  
    </BuildDependsOn>  
</PropertyGroup>  
  
<Target Name="MyCustomTarget1">  
    <Message Text="Running MyCustomTarget1..."/>  
</Target>  
<Target Name="MyCustomTarget2">  
    <Message Text="Running MyCustomTarget2..."/>  
</Target>  

通常被覆蓋的“DependsOn”屬性

屬性名 說明
BuildDependsOn 希望在整個生成過程之前或之後插入自定義目標時要覆蓋的屬性。
CleanDependsOn 希望清理自定義生成過程的輸出時要覆蓋的屬性。
CompileDependsOn 希望在編譯步驟之前或之後插入自定義過程時要覆蓋的屬性。