190 likes | 541 Views
Tips & Tricks: Extending MSBuild with Tasks, Loggers, and Targets. Faisal Mohamood (faisalmo@microsoft.com) TLNL01 Program Manager - MSBuild Microsoft Corporation. MSBuild in 5 minutes. The underlying build engine in Visual Studio 2005
E N D
Tips & Tricks: Extending MSBuild with Tasks, Loggers, and Targets Faisal Mohamood (faisalmo@microsoft.com) TLNL01 Program Manager - MSBuild Microsoft Corporation
MSBuild in 5 minutes • The underlying build engine in Visual Studio 2005 • Fully open and published XML file format for describing build • Visual Studio 2005 build is fully customizable • You extend the build by writing managed code (tasks and loggers) • You don’t need the IDE to build Visual Studio projects
MSBuild in 5 minutes <Project xmlns=“http://schemas.microsoft.com/developer/msbuild/2003”> <PropertyGroup> <AppName>MyCoolApp</AppName> <DebugSymbols>true</DebugSymbols> <OutputAssembly>$(AppName).exe</OutputAssembly> </PropertyGroup> <ItemGroup> <Compile Include=“Hello.cs” /> <Compile Include=“Program.cs” /> </ItemGroup> <Target Name=“Build”> <Message Text=“Executing Build Target for App $(AppName)” /> <Csc Sources=“@(Compile)” EmitDebugInformation=“$(DebugSymbols)” OutputAssembly=“$(OutputAssembly)”/> </Target> <Import Project=“Microsoft.CSharp.targets” /> </Project>
#1: Editing a project using Visual Studio 2005 • Opening a project file for edit is 4 clicks away from within Visual Studio! • When editing, you get full Intellisense based on the Project File Format Schema Right Click on the project name in Solution Explorer and “Unload Project” Right Click on the unloaded project in Solution Explorer and “Edit Project”
#2: Customizing the Build • How do I run pre-build and post-build steps using built-in MSBuild features? <ItemGroup> <PublishDir Include=“c:\temp\publish” /> </ItemGroup> <Target Name=“BeforeBuild”> <RemoveDir Directories=“@(PublishDir)” /> </Target> <Target Name=“AfterBuild”> <MakeDir Condition=“!Exists(‘@(PublishDir)’)” Directories=“@(PublishDir)” /> <Copy SourceFiles=“$(TargetPath)” DestinationFolder=“@(PublishDir)” /> </Target>
#3: Customizing with more granularity • How do I run custom steps during arbitrary points in the build process – for example, what if I wanted to delete all files from c:\temp\publish as a part of Clean target? <ItemGroup> <PublishDir Include=“c:\temp\publish” /> </ItemGroup> <PropertyGroup> <CleanDependsOn>$(CleanDependsOn);MyClean </PropertyGroup> <Target Name=“MyClean”> <RemoveDir Directories=“@(PublishDir)” /> </Target>
#4: Using built-in metadata %(FullPath) %(RootDir) %(Filename) %(Extension) %(RelativeDir) %(Directory) %(RecursiveDir) %(Identity) %(ModifiedTime) %(CreationTime) %(AccessedTime) <ItemGroup> <Compile Include=“*.cs” /> </ItemGroup> <Target Name=“BackupSources”> <Copy SourceFiles=“@(Compile)” DestinationFiles=“%(Compile.Filename).bak” /> </Target>
#5: Copying files recursively • How can I use MSBuild constructs to copy all the contents of a folder from one directory to another? • <Project xmlns=“http://schemas.microsoft.com/developer/msbuild/2003”> • <ItemGroup> • <Files Include=“C:\foo\**\*.*” /> • </ItemGroup> • <Target Name=“CopyFilesRecursively”> • <!– How do I copy everything into C:\foocopy ? --> • <Copy SourceFiles=“@(Files)” • DestinationFolder=“C:\foocopy\%(RecursiveDir)” /> • </Target> • </Project>
#6: Building Incrementally <ItemGroup> <XmlFile Include=“*.xml” /> </ItemGroup> <Target Name=“TransformXmlToHtml” > <Xml2Html XmlFiles=“@(XmlFile)” StyleSheet=“stylesheet.xslt” /> </Target> How can I run the target only to transform those XML files that have been added (or changed) since the last build?
#6: Building Incrementally For items that have a 1:1 mapping between inputs and outputs, you can use Target Level Dependency Analysis by explicitly defining your inputs and outputs <ItemGroup> <XmlFile Include=“*.xml” /> </ItemGroup> <Target Name=“TransformXmlToHtml” Inputs=“@(XmlFile)” Outputs=“@(XmlFile->’%(Filename).html’)”> <Xml2Html FilesToTransform=“@(XmlFile)” StyleSheet=“stylesheet.xslt” /> </Target>
#7: Invoking one target from another • A target that has built once will not build again during the same build session <Target Name=“Build” DependsOnTargets=“PreBuild”> <!– Do the build --> </Target> <Target Name=“PostBuild”> <!– Some post-build stuff --> <CallTarget Targets=“RunUnitTests” /> </Target> <Target Name=“PostBuild”> <!– Some post-build stuff --> <MSBuild Projects=“myproject.proj” Targets=“RunUnitTests” /> </Target>
#8: Executing the same target multiple times • How can I invoke the same target more than once? <Target Name=“CalculateUnitTestCoverage”> <Message Text=“Calculating Unit Test Coverage…” /> <!– Code Coverage Logic here --> </Target> <Target Name="BeforeBuild"> <CallTarget Targets="CalculateUnitTestCoverage" /> </Target> <Target Name="AfterBuild"> <CallTarget Targets="CalculateUnitTestCoverage" /> </Target>
#8: Executing the same target multiple times • Invoke the target using the MSBuild task but with different “properties” <Target Name=“CalculateUnitTestCoverage”> <Message Text=“Calculating Unit Test Coverage for Stage $(Stage)” /> <!– Code Coverage Logic here --> </Target> <Target Name="BeforeBuild"> <MSBuild Projects=“$(MSBuildProjectFile)” Targets=“CalculateUnitTestCoverage” Properties=“Stage=BeforeBuild” /> </Target> <Target Name="AfterBuild"> <MSBuild Projects=“$(MSBuildProjectFile)” Targets=“CalculateUnitTestCoverage” Properties=“Stage=AfterBuild” /> </Target>
#9: Gathering performance summary • “Somehow, my build has slowed down tremendously. I need to find out what’s going on!” Use the /ConsoleLoggerParameters switch or the Diagnostic verbosity to gather performance statistics. C:\project> msbuild build.proj /ConsoleLoggerParameters:PerformanceSummary C:\project> msbuild build.proj /verbosity:Diagnostic
How do I do this? • I’ve got a bunch of code that I’d like to open in Visual Studio, but all I have is a ton of source code with no Visual Studio project or solution • I’d like to open for edit and browse using Visual Studio Is this possible?
#10: Coolest trick of the day! • Simply create a .csproj or .vbproj file that recursively adds all files to a Compile item, and additionally imports Microsoft.CSharp.targets or Microsoft.VisualBasic.targets <Project xmlns=“http://schemas.microsoft.com/developer/msbuild/2003”> <ItemGroup> <Compile Include=“$(AppPath)\**\*.vb” /> </ItemGroup> <Import Project=“$(MSBuildBinPath)\Microsoft.VisualBasic.targets” /> </Project>
Additional Resources • Go to the Advanced MSBuild Breakout Session by Rajeev Goel – today @5pm • Stop by the MSBuild table at Ask the Experts – Thursday 6:30pm @ The Big Room • Visit the Tools & Languages Track Lounge (Big Room) • Try out the MSBuild Hands On Lab here at the PDC if you are new to MSBuild • Visit the MSBuild Wiki http://channel9.msdn.com/wiki/default.aspx/MSBuild.HomePage • Post a question on the MSDN Forums – http://forums.microsoft.com/msdn/ShowForum.aspx?ForumID=27 • Send mail to msbuild@microsoft.com
© 2005 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.