04/11/2010 Update: If you are interested in using older compilers with Visual Studio 2010, there is an interesting solution by Owen Wengerd, described here.
The Microsoft Visual C++ 6.0 is a product that has been present for a long time. A lot of software was written with it, carefully tailored around the many bugs of the compiler. The IDE itself is not too pretty and lacks a lot of functionality that we expect modern IDEs to have. It’s a pitty that we have to use it to maintain legacy code.
Well, turns out this is not the case. There is a way to use the Visual Studio 2008 IDE with all its capabilities, and have it compile the code using Visual C++ 6.0 compiler. There is some fiddling with options to be done in order to have everything compile and link without errors, but I find that once the project is set up I can enjoy the features of Visual Studio 2008.
|Works On My Machine Disclaimer: This is released with exactly zero warranty or support. If it deletes files or kills your family pet, you have been warned. It might work great, and it might not.|
Starting Visual Studio 2008 with Visual C++ 6.0 Environment
All Visual Studio IDEs since the ancient Visual Studio 6.0 have had a convenient switch: /useenv. The documentation for the switch states the following:
“Starts Visual Studio and uses the environment variables for PATH, INCLUDE, LIBS, and LIBPATH in the VC++ Directories dialog box.”
Combined with the vcvars32.bat file that Visual Studio installations traditionally create, this switch gives us the ability to run any Visual Studio IDE with any version of the compiler and support tools. That’s in theory, of course. I only tried Visual Studio 2005 and Visual Studio 2008 IDEs with Visual C++ 6.0 tools.
For convience, I have a batch file that first sets up the environment for Visual C++ 6.0 and then starts Visual Studio 2008 with the /useenv switch:
call "C:\Program Files (x86)\Microsoft Visual Studio\VC98\Bin\VCVARS32.BAT" start "" "C:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\IDE\devenv.exe" /useenv
I use ‘start’ instead of directly running devenv.exe in order to immediately close the window that opens for the batch file. ‘start’ command will run devenv.exe asynchronously and the process started for the batch file will exit. Of course, the paths in the batch file are specific to my machine. They may be different on other systems, depending on where the products have been installed.
Setting C++ Compiler Options
The first part is done – Visual Studio 2008 has been started and it will use the correct environment settings. To verify this, go to Tools/Options/Projects and Solutions/VC++ Directories. You should see something similar to this:
Notice that the first four paths actually reference folders in the Visual C++ 6.0 installation. You will find similar references in “Include files” and “Library files” directories.
This all looks great, but if you create a new VC++ console application and try to build it, you will be greeted with some errors:
As the compilers have evolved, so have their options. The VS 2008 IDE supports more options than the old VC6 compiler. In order for the IDE to pass correct options to the VC6 compiler, we need to do some tweaking.
The first warning above comes from an apparently unknown option related to error reporting. A quick search through the properties of the project gives us this:
Setting this option to Default will cause it to be omitted from the options passed to the compiler.
The other two problematic messages involve a strange character. When compiling, IDE first creates a special file (called response file) containing all options for the compiler, including the names of the source files and the compiler reads this file to determine what needs to be done. In Visual Studio 6.0 that file is regular ASCII text file, while newer versions of Visual Studio use Unicode encoding by default. To instruct Visual Studio 2008 not to use Unicode, we need to set options for the compiler and for the linker:
Setting these option to No will cause the response files to be created as plain ASCII, just as the VC6 compiler needs. If you have a static library project, you would have to do this in the librarian’s options as well.
After these changes, we can build the project again:
Again, hunting for the /RTC1 option brings us to this property screen:
Setting the Basic Runtime Checks to Default will again solve the warning issue.
The linker’s /INCREMENTAL option was supported in VC6, but with a different syntax. In VC6 you can use either /INCREMENTAL:YES or /INCREMENTAL:NO, but you can’t specify /INCREMENTAL by itself. Fortunately, we don’t have to give up incremental linking, but we have to specify the correct option manually. First, we need to set the Enable Incremental Linking option to Default:
Then, we need to manually include this option in linker’s Command Line:
Compiling again will produce some new issues:
The actual error here is that the IDE is instructing the linker to create a manifest file, which is not supported by VC6 linker. To turn this off, we need to go to linker’s Manifest File properties:
And set the Generate Manifest option to No. In order to take care of the other unknown options DYNAMICBASE, NXCOMPAT and ERRORREPORT:PROMPT, we need to go to linker’s Advanced properties and set the corresponding properties to Default:
Compiling now finally yields an error-free output:
The linker warning here cannot be removed, but is completely harmless.
Although everything compiles and links now, you will soon notice that the enitre project is being rebuilt every time. It seems that Visual Studio determines what needs to be built by reading the program database that is created by the compiler, and it expects the database to have a certain name. By default, Visual Studio 2008 uses vc90.pdb as the name of the program database, but Visual Studio 6.0 uses vc60.pdb. To change this, open the C/C++ properties window again:
After this, your project will rebuild once again and generate the vc60.pdb database. Subsequent builds should be incremental, as expected.
Wrapping It All Up
Depending on your project’s requirements and options, you might need to tweak some more options. However, the two techniques presented here (setting to Default and manually specifying in Command Line) should get you through it. In the end, it is up to you to decide whether it is all worth it. To me, having a much better debugger and not needing to close the solution in order to attach it to a process are more than worth a little fiddling with options.
As Christian I reported in the comments, you might need to add compiler options /FD /GR /GX and linker options /pdbtype:sept /machine:I386.