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.


Comment Section

Comments are closed.