views:

89

answers:

1

The Overview

I am working on a Continuous Integration build of a MFC appliction via CruiseControl.net and VS2010. When building my .sln, a "Visual Studio" CCNet task (<devenv/>) works, but a simple MSBuild wrapper script (see below) run via the CCNet <msbuild/> task fails with errors like:

  • error RC1015: cannot open include file 'winres.h'..
  • error C1083: Cannot open include file: 'afxwin.h': No such file or directory
  • error C1083: Cannot open include file: 'afx.h': No such file or directory

The Question

How can I adjust the build environment of my msbuild wrapper so that the application builds correctly? (Pretty clearly the MFC paths aren't right for the msbuild environment, but how do i fix it for MSBuild+VS2010+MFC+CCNet?)

Background Details

  • We have successfully upgraded an MFC application (.exe with some MFC extension .dlls) to Visual Studio 2010 and can compile the application without issue on developer machines.
  • Now I am working on compiling the application on the CI server environment
  • I did a full installation of VS2010 (Professional) on the build server. In this way, I knew everything I needed would be on the machine (one way or another) and that this would be consistent with developer machines.
  • VS2010 is correctly installed on the CI server, and the devenv task works as expected
  • I now have a wrapper MSBuild script that does some extended version processing and then builds the .sln for the application via an MSBuild task.
  • This wrapper script is run via CCNet's MSBuild task and fails with the above mentioned errors

The Simple MSBuild Wrapper

<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build"
   xmlns="http://schemas.microsoft.com/developer/msbuild/2003"&gt;
  <Target Name="Build">
    <!-- Doing some versioning stuff here-->
    <MSBuild Projects="target.sln" 
      Properties="Configuration=ReleaseUnicode;Platform=Any CPU;..." />
  </Target>
</Project>

My Assumptions

  • This seems to be a missing/wrong configuration of include paths to standard header resources of the MFC persuasion
  • I should be able to coerce the MSBuild environment to consider the relevant resource files from my VS2010 install and have this approach work.
  • Given the vs2010 msbuild support for visual c++ projects (.vcxproj), shouldn't msbuilding a solution be pretty close to compiling via visual studio?

But how do I do that? Am I setting Environment variables? Registry settings? I can see how one can inject additional directories in some cases, but this seems to need a more systemic configuration at the compiler defaults level.

Update 1

This appears to only ever happen in two cases: resource compilation (rc.exe), and precompiled header (stdafx.h) compilation, and only for certain projects? I was thinking it was across the board, but indeed it appears only to be in these cases. I guess I will keep digging and hope someone has some insight they would be willing to share...

Solution

I made two adjustments to get this working. The first was to pull a 3rd-party project from my solution and build it independently (it had the lion's share of errors). By checking in it's binary to source control (like many of the other 3rd-party libraries) I was linking to it without issue. As many would point out, however, this was just an avoidance of the problem.

The second part of the solution was incidentally found, but explicitly implied by the checklist of W. Craig Trader's suggestion. That is, I pulled source code to my working directory on the server manually and built the solution manually in visual studio. Whatever path/environment/configuration state issue that existed was ironed out by actually firing up visual studio for that ccnet service user. It certainly makes sense in retrospect.

+1  A: 

There are too many variables to predict exactly where the problem lies, but here's a list of things I'd check/do to run this to ground:

  • Ensure that the CC.net service is running as a domain user (so it can have access to network resources) and that user has the same permissions as a regular developer. The CC.net service user should be a unique user (not one of the developers) (I prefer to run CC.net with the most restrictive permissions possible, in order to drive out developer-induced bugs during unit testing. Since most developers are administrators on their development PCs, this can lead to code that needs to run as an administrator.)

  • Did you install VS2010 as the CC.net service user? If not, check the environment settings for the installing user -- it may have additional path settings that need to be added for the CC.net service user.

  • Turn on CC.net console logging and increase the log level to the maximum, then watch what happens when a build starts. This will be verbose, but can include useful details about the build environment.

  • What happens when a developer logs into the CC.net server, checks out your solution, and builds it locally. Does it build correctly?

  • In the past, I've found it necessary to run Visual Studio (using command-line parameters) to build solutions because there weren't msbuild tasks for all of the project types (particularly non-WiX installer projects). What changes if you do this on the CC.net server?

Craig Trader
My solution ended up being an amalgamate of some of your suggestions, but this checklist addresses my ultimate problem (even though I found the solution independantly). Thanks for taking the time to make suggestions on such an ugly and open-ended problem.
ee
Sorry I didn't see the question earlier.
Craig Trader