- | rssFeed | My book on MSBuild and Team Build | Archives and Categories Wednesday, February 04, 2009

Comments about reusable MSBuild files

A reader of this blog asked me to review some reusable MSBuild file that he created. I won't reveal the details of his files here but here are my comments which are relevant to all reusable MSBuild files.

Properties in targets files

For targets file (MSBuild files designed to be imported by other files) if possible you should always define properties using conditions to ensure that the consumer hasn't alredy defined that value. See my new article MSBuild Best Practices (http://msdn.microsoft.com/en-us/magazine/dd419659.aspx) specifically the section titled "Defining Dynamic Items and Properties".

Assumptions in targets files

Your ProjectOutputHelper.targets file overrides the BuildDependsOn property. This is good and I am sure that it works great, but I don't agree 100% with this approach. You are assuming that the consumers of the file will be importing the Microsoft.Common.targets file which is most likely true, but in my opinion is a bad practice. Better would be to allow consumers of the file to extend the BuildDependsOn. See my new book Inside the Microsoft Build Engine in Chapter 7 you will find a section ‘Creating Reusable Build Elements’ which define some rules for targets files, this is explained more there.

Extendable targets should declare dependencies in a property

All non-internal targets contained inside of targets files should declare the target dependencies inside of a property. This allows consumers to inject steps into specific areas of the build process. For instance from Microsoft.Common.targets:

<PropertyGroup>

    <BuildDependsOn>

        BeforeBuild;

        CoreBuild;

        AfterBuild

    </BuildDependsOn>

</PropertyGroup>

<Target

    Name="Build"

    Condition=" '$(_InvalidConfigurationWarning)' != 'true' "

    DependsOnTargets="$(BuildDependsOn)"

    Outputs="$(TargetPath)"/>

Design incremental targets

If possible you should design your targets to build incrementally ( Chapter 6 of my book explains this) so that the targets that are already up-to-date don’t have to be rebuilt. It is good to get into the habit of creating targets that build incrementally.

Use MSBuild 3.5 Syntax

If you are building with MSBuild 3.5 (.NET 3.5) you should use the new ItemGroup and PropertyGroup elements inside of the targets instead of the CreateProperty and CreateItem task.

msbuild | Visual Studio 2008 Wednesday, February 04, 2009 5:06:59 AM (GMT Standard Time, UTC+00:00)  #     | 
Monday, February 02, 2009

Microsoft Press Blog Posting

The The Microsoft Press team has posted a blog about my book & upcoming articles, you can read it at All Sayed all the time (and MSBuild). These guys make it seem like I'm actually doing something, when in reality I've been on vacation for the past 5 weeks!

Sayed Ibrahim Hashimi

msbuild | Visual Studio 2008 Monday, February 02, 2009 4:17:35 AM (GMT Standard Time, UTC+00:00)  #     | 
Friday, January 30, 2009

Speaking at South Florida .NET Code Camp

I will be speaking on MSBuild at the South Florida .NET Code Camp on Saturday Feb 7. If you are in the area and interested in MSBuild then come and check me out!

Sayed Ibrahim Hashimi

msbuild | Presentations Friday, January 30, 2009 8:10:43 PM (GMT Standard Time, UTC+00:00)  #     | 
Saturday, January 17, 2009

Inside the Microsoft Build Engine: Published and In stock!

My new book Inside the Microsoft Build Engine: Using MSBuild and Team Foundation Build has been published and is now in stock at amazon.com. This book contains 12 chapters, 9 of which are dedicated to MSBuild and the remaining three are Team Build. Two of the MSBuild chapters are dedicated to examples in a cook book fashion, there is one such chapter for the Team Build. This book is the only book that contains this type of coverage of MSBuild. From the begining of the book the MSBuild team was involved, they reviewed every MSBuild chapter and provided invaluable insight. Here is the table of contents for the book:
Chapter 1 : MSBuild Quick Start
Chapter 2 : MSBuild Deep Dive, Part 1
Chapter 3 : MSBuild Deep Dive, Part 2
Chapter 4 : Custom Tasks
Chapter 5 : Custom Loggers
Chapter 6 : Batching and Incremental Builds
Chapter 7 : External Tools
Chapter 8 : Practical Applications, Part 1
Chapter 9 : Practical Applications, Part 2
Chapter 10 : Team Build Quick Start
Chapter 11 : Team Build Deep Dive
Chapter 12 : Team Build Cookbook
App A : New Features in M Build 3.5
App B : MSBuild Common Properties and Items
App C : New Features in Visual Studio Team System 2010 Team Build

If you are interested in learning MSBuild from scratch, or looking to become a MSBuild expert then this book will help you. If you do get a copy please post a review on amazon.com.

Sayed Ibrahim Hashimi
msbuild | Team Build Saturday, January 17, 2009 4:05:26 AM (GMT Standard Time, UTC+00:00)  #     | 
Tuesday, December 09, 2008

My MSBuild Video on Channel 9

This past weekend I gave a presentation on MSBuild at the Tampa Code Camp, which I'm glad to say went very well. Besides that I met Brian Johnson from Microsoft. He shot a video of me discussion using MSBuild and Web Deployment Projects to automate deployment of Web Projects. You can see the video at http://channel9.msdn.com/posts/brianjo/Sayed-Hashimi-on-MS-Build/

Let me know what you think, I'm pretty excited because this is my first Channel 9 video.

The sample demonstrated here was inspired by some content that can be found in my new book Inside the Microsoft Build Engine. The book will be published the beginning of January, please buy several copies! I will post more detailed information about the book soon, but we have completed working on it.


Sayed Ibrahim Hashimi

msbuild | Channel9 | Video Tuesday, December 09, 2008 5:09:44 AM (GMT Standard Time, UTC+00:00)  #     | 
Friday, December 05, 2008

Speaking at Tampa Code Camp

I am not sure why but for some reason I always manage to post these messages at the last minute, sorry for that. I will be speaking at the Tampa Code Camp on Saturday December 6. We will cover various features of MSBuild. If you are in the area, and interested in MSBuild, please come check out my presentation.

 

Sayed Ibrahim Hashimi

msbuild | Presentations Friday, December 05, 2008 5:35:58 AM (GMT Standard Time, UTC+00:00)  #     | 
Monday, November 10, 2008

Team Build - Creating Delta Builds

Out of the box Team Build does not support Delta Builds. Thomas Janssen has a detailed post Realizing Delta Builds with VSTS Team Build for Delta Deployments which describes how this can be achieved. I have not had the opportunity to try this myself, but the blog post looks very through and informative. You can also download his DeltaBuild.targets file from his blog. I have the following comments relating to this; perhaps he will upgrade this file to reflect these comments.

This guidance is appropriate for target files which are designed to be consumed by others.

Don't override targets like AfterCompileSolution

Don't override targets like AfterCompileSolution. Instead extend the CompileSolutionDependsOn property in the manner:

<PropertyGroup>

<CompileSolutionDependsOn>

$(CompileSolutionDependsOn);

DeltaAfterCompileSolution

</CompileSolutionDependsOn>

</PropertyGroup>

This is because some consumers of this file may have already defined the AfterCompileSolution target. In which case one of them will be overridden.

Notice that I named the new target DeltaAfterCompileSolution. It is a best practice to prefix your targets with a value that should be unique. This will minimize the chances of your targets colliding with those defined by others. For example this could have been named MyAfterCompileSolution, but I bet there are a bunch of these already defined.

DependsOnTargets should always be taken from a property

You should define the DependsOnTargets value inside of a property, just like the MSFT targets files do. For example your DeltaAfterCompileSolution (after being renamed) would look like this:

<PropertyGroup>

<DeltaAfterCompileSolution>

$(DeltaAfterCompileSolution);

SafeCleanBuildResult;

GetLatestVersion;

CollectIncrementalBuildResult;

CreateDeltaBuildResult

</DeltaAfterCompileSolution>

</PropertyGroup>

<Target Name="DeltaAfterCompileSolution"

DependsOnTargets="$(DeltaAfterCompileSolution)">

</Target>

This is because you want users to be able to extend this process similar to how users extend the built-in build process. Without this they may need to modify your file, which is ill-advised because you may make a new release at some point.
Also notice the usage of the $(DeltaAfterCompileSolution) in the declaration of the DeltaAfterCompileSolution property. This is to
preserve any previous values that the user may have defined.

 

On a side note, if you are looking for more detailed information regarding Team Build, there will be three chapters of my new book Inside the Microsoft® Build Engine: Mastering MSBuild and Team Build which will be published in January 2009. Sample chapters will be available at that link shortly.

Thanks,

Sayed Ibrahim Hashimi

Team Build | Team Build | Visual Studio 2008 Monday, November 10, 2008 4:43:46 AM (GMT Standard Time, UTC+00:00)  #     | 
Friday, October 10, 2008

Speaking at the Tallahassee Code Camp

I will be speaking at the Tallahassee Code Camp on Saturday 11, 2008. I will be presenting MSBuild there. I think I should have posted this blog earlier but I've been too busy writing my new book!

Sayed Ibrahim Hashimi

Friday, October 10, 2008 5:06:42 AM (GMT Daylight Time, UTC+01:00)  #     | 
Monday, September 08, 2008

MSBuild: Exec Task

I was looking at the documentation for the Exec task (yes I'm writing a new MSBuild book!) and discovered that it is lacking. So I decided to post the complete list of properties here. So here it is for those of you using it.

Name

Description 

Command 

The command which is to be executed. This is the only required parameter.

CustomErrorRegularExpression *

If provided this will be the regex used to determine if an error occurred.

CustomWarningRegularExpression *

If provided this will be the regex used to determine that a warning occurred.

ExitCode

Output property containing the exit code provided by the executed command.

IgnoreExitCode

If true then the Exec task will not fail the build based on the exit code. Otherwise the build is failed for any non-zero exit code.

IgnoreStandardErrorWarningFormat *

If true the output is not examined for errors and warnings.

Outputs

An input/output parameter that contains the output items from the task. This is not set by the Exec task itself but made available to be set by the consumer.

StdErrEncoding

An input/output parameter that specifies the encoding that is used for the standard error stream.

StdOutEncoding

An input/output parameter that specifies the encoding that is used for the standard output stream.

Timeout

Specifies the timout, in milliseconds for the command. After the specified amount of time has passed the command will be terminated. By default there is no timeout

ToolPath

Specifies the location of the tool.

WorkingDirectory 

Specifies the working directory.

* Denotes new properties in MSBuild 3.5

There is a slightly new behavior in this version of the task relating to detecting errors & warnings from the output of the command. Take a look at the forum entry Exec task and "error :" in output.

More to come on the new book later keep an eye here soon. If you have ideas about specific examples that should be demonstrated let me know, for example; how to zip a set of file, how to ftp files to a server, your example here, etc.

Sayed Ibrahim Hashimi

msbuild | Visual Studio 2008 Monday, September 08, 2008 5:23:19 AM (GMT Daylight Time, UTC+01:00)  #     | 
Wednesday, July 30, 2008

IList Randomize Extension Method

I looked around for an extension method that would just randomize a list. I found a couple but they either didn't seem to work right or the modified the collection itself instead of creating a new collection and returning that. So I created one, it is pretty simple anywayz. The definition for it is shown below.

public static class IListExtensions
{
    public static IList<T> Randomize<T>(this IList<T> input)
    {
        if (input == null)
        { throw new ArgumentException("input"); }

        var test = (from p in input
                    select new { Id = rand.Next(), ListObject = p }).OrderBy(t => t.Id);

        IList<T> randomList = new List<T>();
        foreach (var item in test)
        {
            randomList.Add(item.ListObject);
        }

        return randomList;
    }

    static Random rand = new Random();
}

From here we use this method just like any other IList method, an example is shown below.

public void SampleRandomize()
{
    int numElemnets = 10;
    IList<int> numList = new List<int>();
    for (int i = 0; i < numElemnets; i++)
    {
        numList.Add(i);
    }

    IList<int> radnomList = numList.Randomize();

    for (int i = 0; i < randomList.Count; i++)
    {
        System.Diagnostics.Debug.WriteLine(string.Format("i: {0}", randomList[i]));
    }
}

I think it's pretty cool how you can create methods that can be soo easily used thanks to extension methods.


Sayed Ibrahim Hashimi

Visual Studio 2008 | CSharp3 Wednesday, July 30, 2008 6:31:15 AM (GMT Daylight Time, UTC+01:00)  #     |