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="https://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.