I’m a long-time MSBuild fan. Now that it’s open source,I’ve even played with bootstrapping it with xbuildto use it even on Mac. It works like a charm, for the most part 🙂
I’ve always wished I could just reuse fragments of MSBuild targets that aregeneric enough to fit in lots of projects. Things like determining whetherwe’re being built with XBuild or MSBuild,determining the location of Git,or the particular assembly location for a CodeTaskAssembly(which isn’t exactly trivial).Those kinds of things are probably a few lines of XML that could even bedistributed via NuGet.
And so I started doing just that for my own stuff, and thus MSBuilderwas born. It is sort of like NetFxbut for MSBuild rather than .NET code. It may still suffer from that project’s Achilles heelthough, namely, discoverability. But with any luck, the extremely low barrier of entry forcontributors, plus the almost real-time pull-request building and subsequent nuget publishing,thanks to a paid super-responsive AppVeyor-basedCI system, will make it useful enough to gain traction. Time will tell.
In the meantime, I’ve already added a few very useful MSBuilder blocks already:
One of my most frequently used ones is surely MSBuilder.DumpItems.Whenever I’m tweaking MSBuild targets, especially if they are the built-in ones in eitherMSBuild/CSharp itself, or WiX, I more often than not want to inspect what various item groupscontain at certain points, as well as potentially useful item metadata I might want to usefor my task at hand.
For example, say you want to do something interesting with project referencesthat requires you to know precisely what’s going on in the built-in targets after projectand assembly references are resolved. You can just create a console app, install the package
install-package MSBuilder.DumpItems
and edit the .csproj to dump items on AfterBuild for inspection of the items built by oneof the many targets involving ResolveReferences,such as the _ResolvedProjectReferencePaths whichlooks kinda interesting:
<Target Name="AfterBuild"> <DumpItems Items="@(_ResolvedProjectReferencePaths)" /></Target>
And you get a full dump of all those items and their metadata, right in the Visual Studiooutput window, such as:
2>AfterBuild:2> Item: C:DeleteConsoleApplication13srcConsoleApplication1ClassLibrary1binDebugClassLibrary1.dll2> AccessedTime=2015-07-19 01:18:52.21707762> BuildReference=true2> Configuration=Debug2> CreatedTime=2015-07-19 01:16:15.39990532> DefiningProjectDirectory=C:Program Files (x86)MSBuild12.0bin2> DefiningProjectExtension=.targets2> DefiningProjectFullPath=C:Program Files (x86)MSBuild12.0binMicrosoft.Common.CurrentVersion.targets2> DefiningProjectName=Microsoft.Common.CurrentVersion2> Directory=DeleteConsoleApplication13srcConsoleApplication1ClassLibrary1binDebug2> Extension=.dll2> Filename=ClassLibrary12> FullConfiguration=Debug|AnyCPU2> FullPath=C:DeleteConsoleApplication13srcConsoleApplication1ClassLibrary1binDebugClassLibrary1.dll2> Identity=C:DeleteConsoleApplication13srcConsoleApplication1ClassLibrary1binDebugClassLibrary1.dll2> ModifiedTime=2015-07-19 01:18:52.20707602> MSBuildSourceProjectFile=C:DeleteConsoleApplication13srcConsoleApplication1ClassLibrary1ClassLibrary1.csproj2> MSBuildSourceTargetName=GetTargetPath2> Name=ClassLibrary12> OriginalItemSpec=..ClassLibrary1ClassLibrary1.csproj2> OriginalProjectReferenceItemSpec=..ClassLibrary1ClassLibrary1.csproj2> OutputItemType=2> Platform=AnyCPU2> Project={e9288a56-aa1b-4127-97c5-7b3a6d487d63}2> RecursiveDir=2> ReferenceOutputAssembly=true2> ReferenceSourceTarget=ProjectReference2> RelativeDir=C:DeleteConsoleApplication13srcConsoleApplication1ClassLibrary1binDebug2> RootDir=C:2> SetConfiguration=Configuration=Debug2> SetPlatform=Platform=AnyCPU2> Targets=2>2>Build succeeded.
As I come across more useful bits of MSBuild thatare generic enough that deserve becoming MSBuilder blocks, I’ll surely publish them, so stay tunned.
Enjoy!