Thursday, August 27, 2009

Visual Studio 2008 and dumbness

I recently started a project to move a rather large win32 codebase from Visual Studio 2003 to Visual Studio 2008. This codebase included a number of projects as well as third party components, some of which are cross-platform open source components that use nmake instead of Visual C++ project files.

Figuring that I wanted to be sure I was running the latest patches/fixes, etc, I installed Service Pack 1 before I went to build any of the components.

Things were going great. I am generally pleased with some of the usability improvements in the product (in particular the ability to view the contents of STL containers in the Visual Studio Debugger).

So I spent a few weeks, and ported over all the code, and have been testing it in my development environment. Last night though, I installed it onto a clean Windows 2008 install, and when I tried to run one of the executables, I got the following error:

C:\myprogram>myprogram
The system cannot execute the specified program.

Looking at the Event Log, I saw the following:

Component identity found in manifest does not match the
identity of the component requested

Syntax error in manifest or policy file "C:\myprogram\
Microsoft.VC90.DebugCRT.MANIFEST" on line 4.

Off to Google... It turns out that Microsoft provided a new version of the CRT with Visual Studio 2008 Service Pack 1 (no surprise there). However, they rigged up the linker so that it only uses the new CRT if you add a specific "#define _BIND_TO_CURRENT_VCLIBS_VERSION" to *every* project you build. There is no way to set it globally in the Visual Studio compiler so that all projects use the CRT that ships with SP1. And to add insult to injury, the SP1 installer *overwrote* the version of the CRT that came with the RTM version, so in order to revert to the original CRT I have to reinstall VS2008 onto a clean workstation to recover the files.

It turns up I'm not the only one who has complained about this.

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=361682

To take a much simpler example, it means that if you do a clean install of Visual Studio 2008, then install SP1, and then create a hello world program that dynamically links against the CRT, that program will not run on any computer other than the one that Visual Studio is installed on. Oh, and you won't get any warnings during compilation. How dumb is that?

So now I get to choose. Do I:
  1. Modify the project files for *every* project I am responsible for, including all the third-party libraries and other dependencies. In cases where the library doesn't use a MSVC project and instead uses nmake, dig through the source to figure out the appropriate place to put the #define. This also means recompiling *EVERYTHING* from source.
  2. Ship with the RTM version of the CRT, and run the risk of bugs that have already been fixed effecting my product.
I can appreciate Microsoft wanting to be able to allow developers to ship with the RTM version of the CRT even though they have the Service Pack installed. But not allowing this to be globally configurable in the compiler and requiring you to edit your source code? What the hell were they thinking?