Mark Needham

Thoughts on Software Development

Archive for the ‘Build’ Category

Macros in nant

without comments

One of my favourite features of ant is the ability to create macros where you can define common behaviour and then call it from the rest of your build script.

Unfortunately that task doesn’t come with nant and it’s not available on nant-contrib either.

We were using a very roundabout way to build the various projects in our solution.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<target name="compile">  
  <foreach item="Folder" property="folderName">
    <in>
      <items>
        <include name="${project::get-base-directory()}\Project1" />
        <include name="${project::get-base-directory()}\Project2" />                
      </items>
    </in>
    <do>
      <property name="project.name" value="${path::get-file-name(folderName)}" />
      <property name="project.file" value="${project.name}.csproj" />
                
      <exec program="/path/to/msbuild3.5/">
        <arg value="${folderName}\${project.file}" />
        <arg value="/p:OutputPath=${build.dir}\${project.name}\" />
      </exec>                                
    </do>                
  </foreach>        
</target>

Horrendous! Luckily I happened to be emailing back and forth with Bernardo about Stormwind at the time and he mentioned that there was in fact a task.

I added the Macros dll to the build file and voila:

1
2
3
4
<target name="compile">
  <compile-project projectfile="\path\to\Project1\Project1.csproj" />
  <compile-project projectfile="\path\to\Project2\Project2.csproj" />
</target>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<macrodef name="compile-project">
  <attributes>
          <attribute name="projectfile"/>
  </attributes>

  <sequential>
    <property name="project.name" value="${path::get-file-name-without-extension(projectfile)}" />
                
    <exec program="${msbuild}">
      <arg value="${projectfile}" />
      <arg value="/p:OutputPath=${build.dir}\${project.name}\" />
    </exec>        
  </sequential>
</macrodef>

Further instructions on using the macrodef task are here.

Written by Mark Needham

August 14th, 2008 at 9:49 pm

Posted in Build

Tagged with , ,

msbuild – Use OutputPath instead of OutDir

with 8 comments

We’ve been using msbuild to build our project files on my current project and a colleague and I noticed some strange behaviour when trying to set the directory that the output should be built to.

The problem was whenever we tried to set the output directory (using OutDir) to somewhere where there was a space in the directory name it would just fail catastrophically. We spent ages searching for the command line documentation before finding it here.

According to this though:

“OutputPath: This property is typically specified in the project file and resembles OutDir. OutputPath has been deprecated and OutDir should be used instead whenever possible. ”

We decided to try changing OutDir to OutputPath and it started working again! The code is simple, but for those wondering:

1
2
3
4
<exec program="\path\to\msbuild35">
  <arg value="${projectfile}" />
  <arg value="/p:OutputPath=${build.dir}\${project.name}\" />
</exec>

I can’t decide whether the documentation is just wrong or if it’s now a convention that you can’t have spaces in your build output path. Surely the former?

Written by Mark Needham

August 14th, 2008 at 7:54 pm

Posted in Build

Tagged with ,

Getting the current working directory from DOS or Batch file

with 21 comments

In the world of batch files I’ve been trying for ages to work out how to get the current/present working directory to make the batch script I’m working on a bit more flexible.

In Unix it’s easy, just call ‘pwd’ and you have it. I wasn’t expecting something that simple in Windows but it is! A call to ‘cd’ is all that’s needed. If you need to set it in a batch script the following line does the trick:


set WORKING_DIRECTORY=%cd%

I was surprised that something so simple (I do now feel like an idiot) wasn’t easier to find on Google. I ended up going via Experts Exchange (how they end up with such high search results when you have to pay to see the information is beyond me) and several other verbose ways of solving the problem before finally coming across this article which explained it.

Written by Mark Needham

August 12th, 2008 at 10:37 pm

Posted in Batch Scripting,Build

Tagged with ,

Spaces in batch scripts

without comments

Since reading The Pragmatic Programmer I’ve become a bit of an automation junkie and writing batch scripts falls right under that category.

Unfortunately, nearly every single time I write one I forget that Windows really hates it when you have spaces in variable assignments, and I forget how to print out a usage message if the right number of parameters are not passed in.

So as much for me as for everyone else, this is how you do it:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@ECHO off
IF [%1]==[] GOTO usage
IF [%2]==[] GOTO usage

set VAR1=%1
set VAR2=%2

rem important client stuff

goto end

:usage
echo Usage: script.bat var1 var2

:end
echo Script finished

Written by Mark Needham

August 8th, 2008 at 8:10 pm

Posted in Build

Tagged with

TeamCity’s strange default build location

without comments

We’ve been using TeamCity on my current project and it’s proven to be fairly impressive in general.

We’re running quite a few different builds which have dependencies on each other and it’s been pretty much one click on the web admin tool to get that set up.

One thing that had me really confused is the default location it chooses to build from. The problem is that it seems to change arbitrarily, with the folder name it builds in being calculated from a VSC hash (not sure quite how that’s worked out but there we go).

I had (naively) assumed that the default build location would always stay the same and was therefore referencing this location from our build script. Turns out it can change whenever it feels like it!

Our 15:38 build was built to c:/TeamCity/Agent/c734523aedrte but our 15:40 build was built to c:/TeamCity/Agent/d6420ghi2.

Cue much confusion as I repeatedly looked at the first folder trying desperately to work out why nothing was being checked out. Eventually, more by fluke than skill, I figured it out and our build is now being built to c:/WorkingDirectory every time.

Lesson learnt: Take control and set your default directory, don’t let TeamCity do it for you!

Written by Mark Needham

August 8th, 2008 at 7:52 pm