Welcome to MSDN Blogs Sign in | Join | Help

Hack the Build: Target Overriding Step-by-Step

Jomo Fisher--John Lam recently mentioned Target Overriding as a useful tool for extending a pre-existing build process. In MSBuild, a target is a grouping of build functionality—there’s a good MSDN article here that gives some details. The build scripts that ship with VS are largely collections of targets that do certain useful things. For example, in Microsoft.CSharp.Targets there is a Compile target that invokes the C# compiler.

 

Target overriding is how you get your code running in someone else’s build script. Here’s how you do it with a C# project in VS Beta1 (the principles apply to any kind of MSBuild project).

 

(1)   Create a new C# Console application call MyApp.

(2)   Turn on the output window—ViewàOther WindowsàOutput—and build. In the output window, you should see that Resgen.exe and Csc.exe were called.

(3)   Find the file MyApp.csproj—this is the MSBuild project file.

(4)   In the same directory as MyApp.csproj, create a file called Override.targets (the actual name doesn’t really matter) with the following XML:

 

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

    <Target Name="Build" Outputs="$(TargetPath)"

       DependsOnTargets="$(BuildDependsOn)">

       <Exec Command="echo My code is running here!!!"/>

    </Target>

</Project>

 

This MSBuild code overrides the Build target with custom behavior.

(5)   Open MyApp.csproj with notepad and look at the very end for an <Import> tag. Add a new import tag.

 

  <Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />

  <Import Project="Override.proj" />

</Project>

 

Now save. If VS is open, you’ll be prompted to reload the project after this step.

(6)   Go back to VS and do Build or Rebuild. You should see your code running in the output window.

 

A few key things to remember:

 

-    The last target seen by MSBuild is the one that is used—this is why we put the <Import> at the end of MyApp.csproj.

-      The overriding target replaces the target that is overridden.

 

If you look in the .targets files that ship with VS Beta1, you’ll see many, many targets. Any of these can be overridden, but some are more useful to override than others. Here are a few interesting candidates, in the order that they build in:

 

PrepareForBuild

PreBuildEvent

UnmanagedUnregistration

ResolveReferences

PrepareResources

ResolveKeySource

Compile

CreateSatelliteAssemblies

BuildManifests

PrepareForRun

UnmanagedRegistration

 

In a future entry, I’ll talk some more about what some of these targets do and how. Also, there are some other ways to change a pre-existing build system—Property Overriding and Target Chaining—that I’d like to talk about.

 

This posting is provided "AS IS" with no warranties, and confers no rights.

Published Thursday, September 16, 2004 5:27 PM by Jomo Fisher

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# re: Hack the Build: Target Overriding Step-by-Step

The way you describe it, <import> seems to work quite similar to Ant's version[1], including the ability to override targets (explained in a bit more detail in [2]).

The major differences I see:

* In Ant, the target that is the "outermost" target will be the one that wins. I.e. if in your example MyApp.csproj contained a target named Build, Ant would use that, but MSBuild would use the one from Override since that's the last one MSBuild sees. Is this correct? Why have you designed it that way? Is there any benefit over a more hierarchical way to control it?

* In Ant you still have access to the overridden target . Let's say your $(MSBuildBinPath)\Microsoft.CSHARP.Targets was named "msbuilddefault" then you could access its Build target as msbuilddefault.Build. Is something similar possible in MSBuild?

[1] http://ant.apache.org/manual/CoreTasks/import.html
[2] http://www.oracle.com/technology/pub/articles/bodewig_ant1.6.html
Friday, September 17, 2004 2:28 AM by Stefan Bodewig

# re: Hack the Build: Target Overriding Step-by-Step

Regarding which target wins:
Yes, MSBuild chooses the last target seen, just as you describe. This pattern still leaves the outermost project in complete control because the overriding targets can always go after the import. If the target goes before the import then it's up to each successive level in the import hierarchy to override or not.

Regarding access to the overridden target:
This feature is definitely useful but, unfortunately, is not available in Beta1. I can’t speak definitively about RTM Whidbey, but I doubt this will make it in before we ship because we’re in hardcore ship mode right now and generally not adding new features unless there is a performance or security rationale.

On the other hand, there are some ways to do this if you have a little cooperation from the targets file that is being imported. I hope to talk more about this in a future blog entry, but if you want to jump in ahead of me then open up Microsoft.Common.Targets and search for the “BuildDependsOn” property. You can override this property to control which targets get called and in what order. All of the properties with the “DependsOn” suffix work this way.

This posting is provided "AS IS" with no warranties, and confers no rights.
Friday, September 17, 2004 1:02 PM by Jomo Fisher

# re: Hack the Build: Target Overriding Step-by-Step

One thing I have learned from complex use of ant's new <import> thingy is that the most wonderful aspect of any inheritance enabled language is the ability to mark something as private.

We dont have that in ant1.6, so you rely on trust that nobody has accidentally overriden something you needed.

More to the point, it makes maintenance harder, as you need to think of obscure names for all your targets to be sure that nothing is using them.

I'm sure we will add a scope attribute before long, for public/private/protected. What is your solution going to be?
Tuesday, September 28, 2004 5:52 PM by Steve Loughran

# re: Hack the Build: Target Overriding Step-by-Step

As we've scaled up our use of MSBuild in our own build labs, we've seen how important private targets are going to become. I'm not sure when we'll implement this, but its definitely something we need to get to.

This posting is provided "AS IS" with no warranties, and confers no rights.
Tuesday, September 28, 2004 7:11 PM by Jomo Fisher

# ^pointer to comments on this topic

more on inheritance plus the need to get at the dependency list of a super target.
Thursday, September 30, 2004 5:27 AM by Steve Loughran

# Compiling license (.licx) files using MSBuild and TFS TeamBuild

Recently, I ran into an issue where my Team Build process would fail when building our main application...

Friday, April 20, 2007 12:31 AM by John Reynolds' Tech Blog

Leave a Comment

(required) 
required 
(required) 

  
Enter Code Here: Required
 
Page view tracker