Notes from Daily Encounters with Technology RSS 2.0
 
# Saturday, February 11, 2012

Last week I was configuring the build server to compile its first Visual C++ 2010 project. I took the approach of using MsBuild on the project file (.vcxproj) as I am already doing it with the .NET projects. This worked just fine on my development machine with Visual Studio 2010 installed. It soon turned out not to be as easy as I expected it to be. The build failed as follows:

C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppBuild.targets(297,5): 
warning MSB8003: Could not find WindowsSDKDir variable from the registry. 
TargetFrameworkVersion or PlatformToolset may be set to an invalid version number.

C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\Platforms\Win32\Microsoft.Cpp.Win32.Targets(57,5): 
error MSB6006: "CL.exe" exited with code -1073741515.

My first thought was that there were some files missing since there was no Visual Studio installed on the build machine. Running the build command in a regular command prompt resulted in the same error after an additional message box popped up:

The program can't start because mspdb100.dll is missing from your computer. Try reinstalling the program to fix this problem.

This was to be expected. Even on my development machine it is necessary to start the build from the Visual Studio Command Prompt for it to work. Its replacement on the build machine is Windows SDK 7.1 Command Prompt, part of Microsoft Windows SDK for Windows 7 and .NET Framework 4. From this command prompt the build worked flawlessly on the build machine as well. It seems we’re getting closer to the source of the problem… The command prompt is initialized by first calling SetEnv.cmd from the Windows SDK installation (by default in C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin) to set the required environment variables. By doing the same in the build script before calling MsBuild should do the trick for the continuous integration server as well.

Well, here lied the real problem. To simplify CruiseControl.net project configuration the build scripts are written in NAnt. Calling a batch script from NAnt is not a problem of course, there is the exec task for doing that, but any changes to the environment variables are preserved only for the duration of this task. This means we haven’t achieved anything by calling SetEnv.cmd before the msbuild task since any changes made by it are lost. The only way to make this work is by creating another batch script which calls both SetEnv.cmd and MSBuild immediately after it:

call "C:\Program Files\Microsoft SDKs\Windows\v7.1\bin\Setenv.cmd" /Release /x86
msbuild myproj.vcxproj /verbosity:minimal

It’s not ideal but it’s the only way I could make it work. Fortunately this batch script shouldn’t be changing much since everything else is configured inside the project file. I’d still prefer a solution which would allow calling MsBuild directly from NAnt though.

Saturday, February 11, 2012 8:25:45 PM (Central European Standard Time, UTC+01:00)  #    Comments [0] - Trackback
Development | C++ | NAnt | Software | CruiseControl
# Saturday, January 14, 2012

NuGet is a valuable tool for managing references to external libraries in your projects. If you’re not using it yet, you owe it to yourself to try it out and see what you’re missing. Though, that’s not what this post is about. Not only are NuGet packages a great way to distribute publically available libraries, they can be used just as well for custom internal libraries with their own release management which are used in multiple projects. Since there’s a lot of information already available on this topic, instead of repeating it I’ll rather link to it from one place and add a few helpful hints and tricks along the way.

The first step is to create a NuGet package from your library. To do it you need NuGet.exe, it’s not enough to have NuGet Package Manager Visual Studio extension installed, neither is that necessary when this step is being done on your build server. Although it is possible to create a package directly from a Visual Studio project, I strongly suggest to put in a little extra effort from the beginning and use a convention based working directory instead. It gives you many more options which you’re going to miss very soon if you do it the easy way. Don’t forget to set the correct version in the manifest file during each build -  it is only done automatically for you when using a project file as the source. This short NAnt task should do the trick (CCNetLabel property contains the desired version since this is being built with CruiseControl.NET):

<xmlpoke file="MyLibrary.nuspec"
         xpath="package/metadata/version"
         value="${CCNetLabel}" />

Once *.nupkg files are being generated on every build of the library, it’s time to set up an internal feed to distribute them. While it is possible to host a proper feed in IIS, a poor man’s version in the form of a file share will work just as well. Just create a shared folder somewhere on your network (e.g. \\buildserver\NuGet) and copy every generated package file into it. Now you can instruct your developers to add this feed to their NuGet configuration and they can start referencing your libraries the same way they are already used to with libraries from the official NuGet gallery:

NuGet Package Manager Package Sources Settings

You could already stop at this point but I’m convinced that you should go one step further and take care of package restore to avoid putting the libraries in your source control system. There are only three easy steps to follow:

  • Open Package Manager Console Window (Tools > Library Package Manager > Package Manager Console menu item in Visual Studio with NuGet Package Manager installed).
  • Run the following commands:
Install-Package NuGetPowerTools
Enable-PackageRestore
  • Instead of the packages folder put the .nuget folder into source control (both are inside the solution folder).

Once this is done, NuGet will always make sure the correct versions of all the packages are present locally before the build starts. There’s even no need to have NuGet Package Manager installed for this to work. There’s only one more change required to make this work flawlessly with the internal feed that we have set up. Open up the NuGet.targets file in the generated .nuget folder and add this feed to the PackageSources property group:

<PackageSources>\\buildserver\NuGet -source https://go.microsoft.com/fwlink/?LinkID=230477</PackageSources>

Without this modification the package won’t be found if NuGet is not properly configured for the user the build is running under (the package sources configuration is stored in %APPDATA%\NuGet\NuGet.config). The second feed in my case is the official one which you should always add as well so that the public libraries can still be found.

Saturday, January 14, 2012 5:30:40 PM (Central European Standard Time, UTC+01:00)  #    Comments [0] - Trackback
Development | NAnt | NuGet | Software | VisualStudio
Page 1 of 1 in the DevelopmentNAnt category
Sponsored Ads

About Me
Twitter
Support charity with the Humble Bundle Mojam livestream event! http://t.co/9c91hoB9 via @humble 4 days ago
Damir's Corner: Peculiarities of Subversion Path Based Authorization http://t.co/YTFpisrY 4 days ago
These 50 Photos Will Blow you Away http://t.co/HeD6HWit via @photoshoptalent 4 days ago
Another good reason for everyone to rather use Virtual CloneDrive instead http://t.co/ecLmrjZb 9 days ago
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

All Content © 2012, Damir Arh, M. Sc. Send mail to the author(s) - Privacy Policy - Sign In
Based on DasBlog theme 'Business' created by Christoph De Baene (delarou)
Social Network Icon Pack by Komodo Media, Rogie King is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.