How to build VST plugins on Windows with Visual Studio Express

Recently, Microsoft announced that it would offer Visual Studio Express free of charge forever. Though the Express version of Visual C++ (hereafter referred to as VC++) has some limitations, it's still a great tool and it's nice to see Microsoft taking some steps to support the developers writing software for their platform. This document will describe how to get VC++ installed and building VST plugins. It assumes that you have prior experience developing VST plugins, and are familiar with the structure and layout of the VST SDK.

Requirements:

1. Installing VC++
First, download VC++ and install it. The standard installation should be OK, but you can choose to perform a custom installation if you don't want documentation or other stuff installed with it. Before installing VC++, you must remove any other versions of VC++ on your computer. Next, download and install the Platform SDK, which will provide you with the standard header files and libraries you'll need to build software. You may choose to install VC++ anywhere on your hard drive, but the default location is C:\Program Files\Microsoft Visual Studio 8. This document will use to refer to whatever path you chose to install to.
Optional -- remove intellisense VC++ includes a technology called intellisense which indexes one's source code to create nifty little menus for tab-completing functions, variables, and other stuff. While intellisense can be very helpful, but it also uses a lot of CPU and frequently runs in the background, which can be very irritating with large projects or when working on slower machines. To disable intellisense, delete the following file (when VC++ is closed): \VC\vcpackages\feacp.dll. This will not effect VC++ in any way other than it not being able to run intellisense on your projects anymore.

2. Create your project
Create a new project of type "Class Library", which we'll call SampleProject. You can remove all of the files that VC++ creates for you, but keep the resource.h and SampleProject.rc files, and remove any references to these files (such as "SampleProject.ico" being listed in the resource file). Add your source code files and the files from the VST SDK. Now go to the project settings either by double clicking on the project name in the Property Manager or in the menu under Project -> SampleProject Properties. Make the following changes to the project for all build configurations:
General
Character Set - Not Set
Common Language Runtime Support - No Common Language Runtime Support
C/C++
Additional Include Directories - Should contain "C:\Program Files\Microsoft Platform SDK\Include" (in quotes), path to your VST SDK top level directory (called vstsdk2.4 by default), the vstsdk2.4\public_sdk\source\vst2.x directory, VSTGUI SDK directory (if used), your source code directory, and other directories which you may have header files stored in.
Preprocessor Definitions - WINDOWS;_WINDOWS;WIN32;_USRDLL;_USE_MATH_DEFINES should be defined at a very minimum. If you wish to use Libpng, add USE_LIBPNG=1. _CRT_SECURE_NO_DEPRECATE is also nice to define, or else you'll get lots of compiler nags and warnings. It also may be necessary to define VST_FORCE_DEPRECATED=0 in some circumstances.
Runtime Library - Multi-threaded. Multi-threaded debug may be used for debug builds. This will build the VC++ common runtime library statically into your plugin, increasing its size by approximately 200Kb. If you choose to use the CRL as a dynamic library, then you must also distribute a copy of the CRL with your application, which complicates deployment and distribution.
Create/Use Precompiled Header - Not Using Precompiled Headers
Browse Information - None
Advanced -> Compile As - Default
Linker
Additional Library Directories - "C:\Program Files\Microsoft Platform SDK\Lib" (in quotes) , as well as directories to other libaries which you might be using
Additional Dependencies - libcmt.lib uuid.lib shell32.lib ole32.lib gdi32.lib User32.lib advapi32.lib, as well as zlib.lib libpng.lib if you wish to have. For debug builds, you may instead use shell32.lib msvcrtd.lib ole32.lib gdi32.lib User32.lib advapi32.lib. Some of these libraries may not be necessary when building non-GUI plugins, but in this case the linker will not incur any additional overhead, since no symbols from these libraries will actually be linked into your plugin.
Ignore Specific Library - msvcrt.lib;libc.lib;msvcrtd.lib;libcd.lib;libcmtd.lib. For debug builds, use libcmt.lib;libcmtd.lib;msvcrt.lib
Module Definition File - SampleProject.def, which is a plaintext file you must create in your project. This file should contain the following text: LIBRARY SAMPLEPROJECT
EXPORTS
VSTPluginMain
main=VSTPluginMain This file will tell the compiler where to find the main() method in your code. If you are using the 2.4 SDK, then the file vstplugmain.cpp will take care of this for you. If you are using the 2.3 SDK, then you must declare your main method as such: AEffect *main_plugin (audioMasterCallback audioMaster)

3. Adding support for VSTGUI
To include VSTGUI support in your plugin, simply add the VSTGUI files into your project in addition to your own editor class. At a very minimum, these are aeffguieditor.cpp, vstcontrols.cpp, and vstgui.cpp.

4. Adding support for PNG graphics
If you would like to use PNG's in your plugin instead of BMP graphics, you will need to also build your own version of libpng and zlib. Download the source code for both libraries from the links given in the "Requirements" section of the document and place them in the same directory. There is a Visual Studio project for libpng which will also build zlib for you; it is located in the "projects\visualc71" directory. In order to get the projects to build correctly, you'll need to rename the source code directories to simply "libpng" and "zlib", removing the version numbers from the directory name.
When you open the project up, VC++ will run you through the project conversion wizard. Convert the project, and change the "Runtime Library" settings in both libpng and zlib to be Multi-Threaded, as described above. Unless this step is performed, the dependency on the CLR will be present in your project. Next, choose the LIB ASM Release or LIB Release build style and build the project; if you build the libraries as DLL's, you will be unable to statically link them into your plugin. The project should build ok, but throw a few errors when attempting to run the pngtest files. You can ignore these problems, as the libraries will still be correctly compiled and can now be linked to your project.
Visual Studio doesn't need to have the libraries within your actual project. Instead, place the libraries in a directory of your choosing and be sure to add this path to the list of "Additional Library Directories" in the Linker preferences for your project. You may choose to place the libraries in the same directory as the Microsoft Platform SDK stuff, but I personally prefer to keep them in a separate directory checked into CVS. Also be sure to add references to libpng.lib and zlib.lib for your project in the "Additional Dependencies" section of your Linker preferences for the project.
Next, you need your actual graphics to the project. Unfortunately, VC++ Express does not include a resource editor, as this is one of the features in the commercial versions of Visual Studio. However, making the changes by hand is not too difficult. In the SampleProject.rc file, add references to your graphics in the DATA section like so:

IDB_BITMAP1 PNG DISCARDABLE "../resources/bmp10001.png"
IDB_BITMAP2 PNG DISCARDABLE "../resources/bmp10002.png"


The path must be relative to the location of the project file. Then, in resource.h, add the following proprocessor definitions:

#define IDB_BITMAP1 1
#define IDB_BITMAP2 2

Now you can use IDB_BITMAP1 in your code when creating new CBitmap objects.

5. Final considerations
VC++ ships with an optimizing compiler, but sometimes the compiler will choke on certain files and optimization must be disabled. In particular, I have experienced this with Laurent de Soras' FFTReal libraries, since they are written as template classes. In general, however, optimization is a good idea, as is Eliminating Unreferenced Data (in the linker settings). The "Whole Program Optimization" setting appears tempting, but usually results in dozens of build errors and problems, so it's best to avoid this. Also, be sure to use the optimization features of this compiler and linker, as they can greatly boost runtime performance.