Home
Archives
About us...
Advertising
Contacts
Site Map
 

ruby in steel

 

code igniter   php VISUAL STUDIO 2005 INTEGRATION

MSBuild isn’t just a revamped Nmake – it’s now at the heart of Visual Studio - Dermot Hogan looks at the Microsoft alternative to Make...

In this series, Dermot explains how to integrate a programming language into Visual Studio 2005. Part Three: MSBuild (see also: Part One and Part Two)

Build systems have been around for a long time. The classic is ‘make’,  originally distributed with Unix from around 1977. This has been through several variants since then, but all share the same idea of building a ‘target’ from a set of ‘source’ files. The target is generally rebuilt when one or more of the source files is changed.

Make files have generally served well when working in a command line environment – that is, under Windows, you open a command prompt and type away. But generally, they haven’t worked as well when combined with an IDE such as Visual Studio. In older versions of Visual Studio, there was a considerable overlap between what the Make file did – fundamentally connecting inputs to outputs – and the information required to define the structure of a project – folders, hierarchies of files, files that need to be in the IDE but are not part of the output and so on.

A further problem with the older Make systems has been the difficulty of tracking down problems. The syntax of Make is, well, terse. In a big Make file, figuring out what on earth is going on can be quite challenging. Some time ago (1999, I think),  Sun developed Ant – an XML based Make system in which actions and dependencies are described by XML structures. The nice thing about XML is that it is extensible – you can add things as you need them.

xml
The good thing about XML is that it’s extensible. The bad thing is that it’s unreadable: you really need to get a good Sidekick (see below).

And so enter Microsoft. Microsoft is very good at recognising clever ideas and, shall we say, ‘incorporating’ them into its products. Microsoft has taken the Ant ideas and produced a new product, MSBuild, which not only replaces Microsoft’s own Nmake product, it integrates into Visual Studio as well. This is the neat bit: put another way, MSBuild not only describes how a product is to be built, it also describes how the components fit into Visual Studio.

It’s this dual purpose of MSBuild that I think is really good. You can use MSBuild from the command line to build a program (and that is actually one of the best ways of testing it), but you can also use it to define a Visual Studio ‘project’, describing how the project appears in the Solution Explorer. Further, by using the Visual Studio SDK, you can add and manipulate your own property data and store the whole lot in a nice, well structured, MSBuild file.

Basics

There are a number of good tutorials around on how to use MSBuild (see this Microsoft video for a very good guided tour), so I’m not going to try and reproduce those here. But what I found to be missing when I first started looking at MSBuild was a high level view of what you use the individual bits for. That’s what I’ll try and cover here.

First off, MSBuild uses ‘Properties’. A Property is something that has a value and is defined like this:

<Optimize>false</Optimize>

Properties are included in ‘Property Groups’ which can be enabled or disabled. So you might want to turn optimization on  for a debug version like so:

<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
  <Optimize>false</Optimize>
</PropertyGroup>

Essentially, a Property is just a key-value pair. In the example above, the value of ‘Optimize’ is ‘false’.

In conjunction with Properties, MSBuild uses another concept – an ‘Item’. An Item is an input to the build system – a source file or files if you like. An Item has a name, what to include or exclude and a set of ‘meta items’ that you can associate with the Item. Here’s an example from the Steel Ruby programming IDE for Visual Studio which I am currently developing:

<Ruby Include="test.rb">

  <Arguments>1 2</Arguments>

</Ruby>

The Item’s name is ‘Ruby’, and the file to include is ‘test.rb’. The meta-data  here is described by the Arguments tag, and I’m using it to define the arguments that will eventually be passed to the Ruby interpreter itself.

properties
Here’s what the Ruby ‘item’ looks like in the Visual Studio Property Window.

MSBuild will then run the Ruby interpreter on the file like this:

ruby test.rb 1 2

But how does MSBuild actually go about doing the business of running a program? This is done via the third component of MSBuild – the ‘Task’. A Task is always included in a group of related tasks under a ‘Target’. So a basic build sequence might look like this:

<Target Name="BuildRuby" Inputs="@(Ruby)">

  <MakeDir Directories="SyntaxCheck" />

  <SteelRubyBuild RubyFiles="@(Ruby)"

    ProjectDirectory="$(MSBuildProjectDirectory)"

    InterpreterName="$(InterpreterName)"

    RubyLibraryPath="$(LibraryPath)" />

</Target>

Here, under the Target ‘BuildRuby’, I’ve got two Tasks, ‘MakeDir’ and ‘SteelRubyBuild’. The first of these, MakeDir, is a standard MSBuild Task that creates a directory. There are a number of these Tasks covering some commonly used operations. But the more interesting one is the ‘SteelRubyBuild’ Task. This a home grown one. It’s actually a part of a DLL I wrote that contains a number of related Tasks. In this case, this particular Task (written in C#) runs the Ruby interpreter via a .NET Process class. Simple really, but very effective.

One thing to note about this Target is that the inputs to the Target – the input dependencies, to be more accurate – are specified as a list of Items. The syntax is

Inputs="@(Ruby)"

This tells MSBuild to aggregate all the Ruby Items in the build script and to pass the whole shebang to the mechanism that MSBuild uses to determine if the tasks within the target are to be called. You can either get the Target Tasks invoked all the time (as here) or you can use an ‘incremental’ build, which determines which Items are passed to the target Tasks, only if the input Item has been changed.

Note that individual Properties are substituted by the $() syntax:

ProjectDirectory="$(MSBuildProjectDirectory)"

Some Properties are built into MSBuild (like MSBuildProjectDirectory) while other you can define yourself. These Properties are passed as arguments to the tasks which of course do the real work of compiling, linking and so on that any realistic build system requires.

I’ve been using MSBuild for a few months now, and apart from having some initial difficulties with the syntax (it doesn’t seem to have any sort of grammar that I can find), I’ve found it to be a simple and reliable tool. The incorporation of MSBuild into the core of Visual Studio – there’s a powerful way of using MSBuild directly via the BuildEngine .NET classes – is a big plus. Currently, I’ve only just scratched the surface of MSBuild to perform Ruby syntax checking. The next step is to use MSBuild to construct real and complicated web sites. It should be interesting!

msbuild se
Here’s what the MSBuild XML looks like in Visual Studio’s Solution Explorer. There’s one peculiarity – the solution file itself isn’t in MSBuild format. I’d expect to see this remedied in the next version of Visual Studio.


Debugging MSBuild

As I mentioned earlier, one of the problems with the old style Make systems was the lack of any serious debugging facilities. MSBuild does provide quite a decent system for finding out what is going on: simply invoke MSBuild from the command line with the appropriate switches and you’ll get more or less detailed output. One nice touch – the output is in colour! This certainly makes life quite a bit easier when you are trying to see what is happening.

prompt
Debugging MSBuild can often be conveniently done from the command line. There are various levels of diagnostics that you can select. Best of all, the output is colour coded!

There’s one other tool no MSBuild developer should be without: MSBuild Sidekick. This wonderful (and free) gizmo comes courtesy of Attrice Corporation (http://www.attrice.info/msbuild). With it you can display the rather user unfriendly XML in a really easy to follow format. It still seems that the simple ideas are often the best.

sidekick
MSBuild Sidekick displays the XML content of an MSBuild file in a nice structured format. And the cost of MSBuild Sidekick? Zero!

 

June 2006

 


Home | Archives | Contacts

Copyright © 2006 Dark Neon Ltd. :: not to be reproduced without permission