How To: Build Non-MSBuild Projects with MSBuild

Software Development December 11th, 2007

Building non-MSBuild projects is possible. For example you have to build VS2003, Installer, C++, Delphi projects etc. How can you do it? It’s simple.

The MSBuild has a built-in task: Exec task. This task calls cmd.exe instead of directly invoking a process and runs the specified program or command with the specified arguments. You can use it in order to build non-MSBuild projects.

For example, in order to build a Visual Studio 2003 Project you should modify the MSBuild file as:

   1:  <PropertyGroup>
   2:  <VS2003_Devenv>$(ProgramFiles)\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.com</VS2003_Devenv>
   3:  <VS2003_SolutionName>$(SolutionRoot)\vs2003\VS2003Application\VS2003SLN.sln</VS2003_SolutionName>
   4:  <VS2003_Configuration>Debug</VS2003_Configuration>
   5:  </PropertyGroup>
   6:   
   7:   
   8:  <Target Name="AfterCompile">
   9:  <Exec Command="&quot;$(VS2003_Devenv)&quot; &quot;$(VS2003_SolutionName)&quot; /build $(VS2003_Configuration)"/>
  10:   
  11:  <MakeDir
  12:  Directories="$(BinariesRoot)\$(VS2003_Configuration)"
  13:  Condition="!Exists('$(BinariesRoot)\$(VS2003_Configuration)')" />
  14:   
  15:  <Copy
  16:  SourceFiles="$(SolutionRoot)\vs2003\VS2003Application\bin\$(VS2003_Configuration)\**\*.*"      
  17:  DestinationFiles="$(SolutionRoot)\vs2003\VS2003Application\bin\$(VS2003_Configuration)\**\*.* ->'$(BinariesRoot)\$(VS2003_Configuration)\%(RecursiveDir)%(Filename)%(Extension)')"
  18:  />
  19:  </Target>

Read here for more information about the target names and the MSBuild configuration file.

First declare some variables to use them during the build. (Lines 1 – 5) . Next in the AfterCompile target, use the MSBuild Exec task to build the VS2003 project by invoking the devenv.com program (Lines 9 -10). After that make a directory (using MakeDir task) for the output (if not exists) (Lines 11 – 13). Finally copy (using the Copy task)the output files to the build binaries root (Lines 15 – 18).

Notice that this assumes VS 2003 is installed on the build machine.

Good Luck!

Tags:

Create custom task for MSBuild – Step by Step

Software Development October 10th, 2007

This is the 2nd post in the msbuild posts series. The first post was an introduction to MSBuild and give you tasting of the basics.

In order to extend Team Foundation Build by plugging in your own logic and tasks, you must write a custom task and use it in your build script (the .proj file).

Custom MSBuild task must be implemented as a .NET class that implements the ITask interface, which is defined in the Microsoft.Build.Framework.dll assembly. You can implement your task in the following two ways:

  1. Derive your class directly from ITask and implement the methods on this interface. or
  2. Derive your class from the helper class, Task (an abstract base class that is a default implementation for BuildEngine and HostObject properties) which is defined in the Microsoft.Build.Utilities.dll assembly. Choosing this option makes it easier to log events from your task.

In both cases you must implement (ITask) or override (Task) it’s Execute method. I override this mwthod with a very simple logic to just log a string value to the Build log as you see below.

Step 1 – Creating project

Create Class Library project with a class and a reference to Microsoft.Build.Utilities assembly. I’ll derive the class from the Task abstract class and override the Execute method.

Step 2 – Writing the task

Execute function must return true if task has executed successfully otherwise it must return false. Now I will add my code to the Execute method – this is my logic which I want to be executed during the build process. I also add a property to the class (Message) and set an attribute to it [Required] (line 29) – this indicates that msbuild must pass a parameter to the task. The Log ( line 17,24) object I use is the LoggingHelper of the Build Utilities (defined at Microsoft.Build.Utilities.dll )

   1:  using System;
   2:  using System.Collections.Generic;
   3:  using System.Text;
   4:  using Microsoft.Build.Utilities;
   5:  using Microsoft.Build.Framework;
   6:   
   7:  namespace MSBuildTasks
   8:  {
   9:      public class MyTask:Task
  10:      {
  11:          private string message;
  12:   
  13:          public override bool Execute()
  14:          {
  15:              try
  16:              {
  17:                  Log.LogMessage(
  18:                      String.Format("This is the message from my task: {0}",
  19:                      message));
  20:                  return true;
  21:              }
  22:              catch
  23:              {
  24:                  Log.LogError("Error occured in my task!");
  25:                  return false;
  26:              }
  27:          }
  28:   
  29:          [Required]
  30:          public string Message
  31:          {
  32:              get { return message; }
  33:              set { message = value; }
  34:          } 
  35:   
  36:      }
  37:  }

Now compile the project.

Step 3 – Registering the task in MSBuild file

Now we need to import and register this custom task to the MSBuild file we want to extend (This is because MSBuild must know how to locate the assembly that contains the task class.) . We’ll do it by editing the .proj file of the build and add a <UsingTask> element which is a direct child of root <Project> element.  This element has a TaskName attribute to get the name of the task class and an AssemblyFile attribute to get the name or address of the assembly where this class is implemented in.

<UsingTask TaskName="MSBuildTasks.MyTask" AssemblyFile="C:\Work\Projects\Samples\MSBuild\MSBuildTasks\bin\Debug\MSBuildTasks.dll"/>

Step 4 – Calling the task from MSBuild

Calling the task depends on the point in the build process where we want to call. We should choose the point in the process that we want to call the task and add the following under it:

   1:  <Target Name="MyTaskTarget">
   2:      <MyTask Message="Hi MSBuild" />
   3:    </Target>

Line 2 calls the task. The message here is the required parameter to pass to the task.

Step 5 – Running the MSBuild file

After all of that you should run the msbuild file.

This is my MSBuild file (.proj extension)

<?xml version="1.0" encoding="utf-8"?><Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">  <UsingTask TaskName="MSBuildTasks.MyTask"            AssemblyFile="C:\MSBuildTasks\MSBuildTasks.dll" />  <Target Name="MyTaskTarget">    <MyTask Message = "Hi MsBuild"/>  </Target></Project>

This is the output of the example.

msbuild

Enjoy!!

See you in the next post of the MSBuild series.

Technorati Tags:

Tags:

MSBuild basics

Software Development September 30th, 2007

First posted at: http://blogs.microsoft.co.il/blogs/maordavid/archive/2007/09/30/msbuild-basics.aspx

One of the most technologies I like is MSBuild. I found that I didn’t dedicate too much writing time about it in this blog. I think and feel that I really neglect MSBuild at my blog…:(

This post will be the first of series of posts about this technology.

So lets start with the basics of MSBuild.

The Microsoft Build Engine (MSBuild) is the new build platform for Microsoft and Visual Studio. MSBuild is completely transparent with regards to how it processes and builds software, enabling developers to orchestrate and build products in build lab environments where Visual Studio is not installed.

Quote from Microsoft site.

 

In principle, this definition is really injustice for MSBuild. When I read it I insulted for MSBuild. For me, MSBuild is a high level scripting technology. I can use MSBuild almost for everything. NOT only build!

The introduction of MSBuild as an official utility was very welcome among the development community as it provides close integration with the existing project and solution files created by Visual Studio. This close integration cuts down on the amount of detail necessary for the build scripts.T he MSBuild utility comes with .NET 2.0 and is available with the runtime even if Visual Studio is not installed.

MSBuild based on XML-based project. (like csproj,vbproj…)

The basic elements of the MSBuild project file format are:

  1. PropertyGroup
  2. ItemGroup
  3. Target
  4. Tasks

 

PropertyGroup

Properties are defined in the PropertyGroup element. You can simply add an arbitrary element and enclose the assigned value within that element. Properties represent key/value pairs that can be used to configure builds. Example of PropertyGroup:

<PropertyGroup>    <AppName>My application name</AppName>    <AppDir>C:\Apps</AppDir>    <ThirdPartyDir>C:\3rdParty</ThirdPartyDir></PropertyGroup>

ItemGroup

Defining lists is done within an ItemGroup element. You will want to use a list with a Task occasionally, such as copying a group of files to another folder. Below is an example of an ItemGroup.Items are declared in the project file by creating an element with the name of the item collection as a child of an ItemGroup element. Example of ItemGroup:

<ItemGroup>    <FilesToCopy Include = "file1.cs"/>    <FilesToCopy Include = "file2.cs"/></ItemGroup>

 

You reference item collections throughout the project file with the syntax @(ItemGroupName). In thus case, you reference the item group with @(FilesToCopy).

Targets

Targets group tasks together in a particular order and expose sections of the project file as entry points into the build process. Targets are often grouped into logical sections to allow for expansion and increase readability.

Targets are declared in the project file with the Target element. For example, the target bellow occurs after build finished.

<Target Name="AfterBuild">    Do something....</Target>

Tasks

Tasks are reusable units of executable code used by MSBuild projects to perform build operations. For example, a task might create directories and copy files. Once created, tasks can be shared and reused.

You execute a task in an MSBuild project file by creating an element with the name of the task as a child of a Target element.

MSBuild shipped with a alot of built in tasks. For example: MakeDir,Copy and more.

See below an example for using tasks:

<Target Name="AfterBuild">    <MakeDir Directories="$(AppDir)" />    <Copy SourceFiles="$(FilesToCopy)" DestinationFolder="$(AppDir)" /></Target>

Next in the series I’ll dive deeper with the msbuild script.

The msbuild script below is a demonstration about my earlier sentence: “I can use MSBuild almost for everything”. Save this as .proj file, and execute it from VS2005 command prompt as: msbuild YourSavedFileName

This script only opens windows calculator…

<?xml version="1.0" encoding="utf-8"?><Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">    <Target Name="Build" >        <Message Text="Executing calculator" />        <Exec Command="calc" />    </Target></Project>  

 

Technorati Tags:

Tags:

Building .NET 3.0 projects from Team Foundation Build 2005 not supported

Software Development, Team System September 8th, 2007

Building .NET 3.0/3.5 projects from Team Foundation Build 2005 not supported. Team Foundation Build 2005 will always invoke the 2.0 Framework’s MSBuild.exe, which does not support building solutions that target the 3.5 Framework.  (The 3.0 Framework shipped with Vista, while the 3.5 Framework is shipping with VS 2008.)

The 3.5 Framework includes new MSBuild bits which allow multi-targeting – i.e. MSBuild 3.5 can target the 2.0 Framework.

We can convert our solution to VS2008 beta 2 and target the solution to .NET framework 2.0. It’s not enough. When we’ll try to build this solution with Team Foundation Build 2005, we’ll get an error MSB5014 – File format version is not recognized.

The MSBuild blog has great post about MSBuild, Orcas, and Multi-targeting. Find it here.

Tags: , ,

SqlBuildTask timeout

Software Development, Team System September 8th, 2007

I built a big DB Dude project from MSBuild command line and got a timeout error.

MSBUILD : Build error TSD158: Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.

The default timeout for query execution is 60 seconds and stored in the registry. We can extend the query timeout by changing these values. The registry entries are:

HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0\DBPro\Database\QueryTimeoutSeconds

HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0\DBPro\Database\LongRunningQueryTimeoutSeconds

Tags: , ,