Wednesday, September 26, 2007

The Death Of Visual Studio Projects, Finally!

Today I created my last voluntary Visual Studio project.

That's it. I'm done. No maas. I can't go on like this.

Don't get me wrong. There is a lot to like here in Visual Studio 2005. I have worked with Visual Studio since it was called Visual C++ 1.0. The IDE, compiler, and especially the debugger has improved tremendously since then.

Debugging, has come a long way. In particular, debugging CWindow.Paint() issues on Windows 3.1 was painful. You'd set a breakpoint, fire up the app, click around, and the breakpoint would get hit. This, of course, would bring the IDE to the foreground, and overwrite your app's window, which you could not see.

What, you want to see your app? That caused another Paint() call, starting the whole thing again. Debugging became an exercise in screen real estate management with 640 by 480 pixels in play.

Nowadays, this and everything else in Visual Studio is improved, with one not-so-slight exception: The project file, and its editor.

I know they have added small gadgets, like wizards, macro support, automatic linking of dependencies, a cute popup dialog for some list editing, and the like, but its just not enough.

The Problem.
Now, I'm not talking about the annoying attempts by the IDE to modify the project file to hook it up to VSS (and the corresponding battles to unlink it). Nor am I talking about the hacks to force a symbol reference because the linker gives an errant warning. I'm not even talking about how the editor rearranges options on you every other release. Those truly stink, but they are not your every day productivity issues.

I'm talking about how long it takes to create a new project and make it correct for your solution. Too long. I'm also talking about how often a project gets checked in to source control and just isn't right, perhaps breaking the Release build, or hard-coding a directory. Too often. These are productivity killers. If you've ever led a project using Visual Studio, you know what I'm talking about. You've got better things to do with your time.

There is a lot at play making sure a project is set up correctly. There are dozens of options: C runtime libraries, include paths, and output directories. Don't forget the naming of DLL files, and their import libraries, plus the symbol definitions you were supposed to add.

Add in a few don't forgets like turning off precompiled headers, changing default optimization to mimimize size, and improving the floating point comparisons.

Then there are library dependencies, which are the worst of all. My project must link in library a.lib, which uses b.lib and forces a transitive dependency on my project. Of course, that's today. Next week, b.lib will be modified, and require c.lib, so my project, along with the dozen or so which link in a.lib and the hundred or so which link in b.lib, will have to change.

And that's just for Debug builds. For Release builds, you get to do it all over again, but change certain entries according to some not-so consistent patterns.

Finally, you need to port your code to another compiler or platform. What then?

This really stinks. We deserve better.

The Solution.
Since joining OCI, I have been introduced to an open-source product called MPC. MPC takes the responsibility for creating and updating project and solution (and make) files out of your (and your team lead's) hands and generates them for you.

MPC generates project, solution, workspace, and make files from a series of MPC files which you create and edit. The MPC system separates the concepts of building a project from consuming a project. Therefore I can describe in great detail how to build a.lib, but also automatically force consumers of a.lib to become consumers of b.lib.

MPC files can inherit from each other to do interesting things like pick up defaults for unit tests or DLLs, for example. Need to target multiple platforms or compilers? MPC takes care of it, out of the box. By default, all projects will follow a consistent rule for output directories, libraries default to DLLs, and C runtimes are Multithreaded.

Its so brilliantly simple that it angered me to not think of this myself. Take a look. This is the answer I've been looking for. More to come...


Jeremy said...

I love MPC. It's really handy when you need to preprocess some of your files for example if you are using Qt or CxxTest.

Jeff Schmitz said...

Thanks Jeremy,

Agree, it pays off big when creating new projects. We use it extensively in cross-platform builds, but I think it has a place in the team environment. Particularly in that it keeps Debug and Release in synch for you. I can't begin to describe how valuable that WOULD HAVE been for me on past projects.

The Schmitzer