Sunday, June 27, 2010

Changes to builds for IronPython.SQLite and IronPython.Zlib

I've done some work on the builds for both IronPython.SQLite and IronPython.ZLib; with IronPython 2.7 on the way, the number of variants I need to build is going up. IronPython 2.7 will require .NET 4.0, so that saves me having to build a IronPython 2.7/.NET 2.0 version of everything as well.

Still, three variants is too many to build manually through Visual Studio, which is how I've built everything up to this point. The packaging into a zip file was also done manually. To save the effort, I've adopted psake as a build automation tool. It's based on PowerShell, which is a very nice administrative language (I actually prefer to Python for quick & dirty admin tasks – the horror!). The actually builds are still handled by MSBuild so that I can manage the files in Visual Studio; the psake script calls msbuild to build the library. I also have tasks to clean the source tree and build the .zip packages.

The MSBuild Files

The real trick in this is building an .csproj file that can handle being built for both .NET 2.0 and .NET 4.0. The key to it all is the TargetFrameworkVersion property; by default, it is hardcoded to a specific .NET version (v2.0, v3.5, or v4.0) in the .csproj file. To change it during the build, msbuild needs to know that we might provide it on the command line. If you've ever opened a .csproj file, you make recognize these lines:

<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>

These lines will set the Configuration and Platform properties if they are not already set from the command line; that's what that Condition attribute does. We just need to do the same thing for the TargetFrameworkVersion property:

<TargetFrameworkVersion Condition=" '$(TargetFrameworkVersion)' == '' ">v2.0</TargetFrameworkVersion>

This allows us to change the TargetFrameworkVersion from the command line. For a little future proofing, I add a property for the IronPython version as well:

<IronPythonVersion Condition=" '$(IronPythonVersion)' == '' ">2.6</IronPythonVersion>

The psake file

The psake build script is (by convention) default.ps1; I would have preferred build.ps1, but whatever. The core task is the Build task; all it does is call MSBuild:

task Build -Depends GenVersion {
    exec { 
        msbuild /nologo /verbosity:minimal "$ProjectPath" `
            /t:Build `
            /p:Configuration=$Configuration `
            /p:TargetFrameworkVersion=$TargetFrameworkVersion `
            /p:OutputPath="..\$OutputPath" `
            /p:IronPythonVersion=$IronPythonVersion
    }
}

There are also tasks to build the zip files (requires 7-zip on the build system) and run the tests for the given project. All in all, using psake has been a great move, and while I have a few minor issues with it, I highly recommend it.

Building the Damn Thing

This is all well and good, but how do you actually use it to build it the library? Switch to the build directory, and, in a PwoerShell window, run:

.\psake

That's it, if a default .NET 2.0 Debug build is what you want; it will also run the tests. To build a Release build for .NET 4:

.\psake build –framework 4.0 –parameters @{config='Release'}

Finally, you can build the zip packages:

.\psake package

It's all much simpler than firing up Visual Studio and building zip files by hand.

Visual Studio 2010 Upgrade

I've also upgraded the IronPython.SQLite and IronPython.Zlib solution files to Visual Studio 2010. You can use the free Express editions to build them. Also, none of these changes affect NWSGI, yet.