How to create Visual Studio project files

From MailWasher Server

Unfortunately Visual C does not use the GNU-style autotools system, so seperate project files must be maintained for Windows development.

This page explains the non-default settings we use in the Visual C project files. Since we already have project files for the libraries and applications currently in the package, these instructions are only needed when new libraries or programs are created.

This document assumes you have followed the instructions to set up the build environment as documented.

Contents

Creating the blank project file

When creating a new Visual C project file, you first need to decide what type of project it is. MailWasher Server projects are either:

  1. console apps (for example, all the library test applications), and many of the debugging tools (eg. the config dump program). For such an application, choose "Win32 Console Project".
  2. daemons, for example the MPD and MWI. To make a project for a daemon, choose "Win32 Project" - DaemonLib provides the WinMain and service handling implementation. (Note that DaemonLib makes it easy to run the daemon on a console for debugging - more on that later - so you do not need to choose the console project option to do that.)
  3. static libraries, for example each of the FCL libraries, the MailWasher Server 'common' library, and the HTTP server library. We always use static libraries - we wouldn't get any benefit from having these libraries in DLLs and then we'd have to worry about the usual 'DLL hell' problems with changing ABIs and version co-existance. To create a static library, again use "Win32 Project"; on the next dialog, the "Win32 Application Wizard" go to the "Application Settings" page and choose "Static Library". Make sure that the "Add support for MFC" option is unchecked.

For all three types of projects, if this is a cross-platform project (that is, if the thing you're creating a project for will also be used on unix/linux), check the "Empty project" box, as we don't use the default files Visual Studio adds (they aren't cross-platform; CppLib takes care of our platform-specific dependencies).

Add the project files

Next you should add the .cpp and .h files to the project (if they've already been written). We do this first so that we can then see the C -specific options for the project.

Then, open the project options. Choose the "All Configurations" option from the drop-down at the top-left of the dialog, so our changes below apply to both the Debug and Active configurations.

Add the include paths

In the "General" C/C group (if in the future you ever find you don't have this section, cancel the dialog, drill down into the project's "Source Files" group, and then re-open the project dialog - it doesn't show the C/C options if it hasn't noticed it's a C/C project).

Add the paths to get back to the root FCL directory and to the mwserver "src" directory to the "Additional Include Directories". You don't need to add the path to each individual library that you use as we always #include "TheFCLProjectName/TheUnitHeader.h" instead of just #include "TheUnitHeader.h".

You must be careful to always use relative paths here, as otherwise others won't be able to compile the project unless they happen to check out to the same place. Visual Studio's directory selection dialog will usually give a full path if you use that, but it has a nice autocomplete that works even with relative paths if you start typing using the '...' button.

Set the compiler options

Turn "Detect 64-bit portability issues" off. Most of these warnings are bogus - our code has always run on 64-bit platforms, but the Visual C compiler complains about a number of default conversions that are, in fact, generally portable (eg. size_t to unsigned int). (One day we will go through and see if any of these warnings are relevant.)

Go to the "Code Generation" section. Change to the "Debug" configuration, and change the runtime library to "Multi-threaded Debug". Change to the "Active" configuration and change the runtime library to "Multi-threaded". (Note that it is necessary to select the appropriate RTL in all apps - including .lib projects, which don't actually get linked against the RTL themselves, and including the single-threaded console test apps, as they must be compiled with the same RTL setting as was used for all the .libs it uses, eg. CppLib; it's not just a link-time thing.)

Change back to "All configurations".

Go to the "Language" section and turn "Force for loop conformance" on and "Enable run-time type info" on - both of these are basic C compliance settings, and are necessary for Visual C to compile portable code - and so are necessary, at least in the case of the for-loop scope setting, for code written by developers using Visual C to work properly with other compilers also.

Add any third-party library dependencies

If this is a threaded program (daemon or console app, rather than a static library), go to the "Linker" group's "Input" section and add pthreadVC.lib, the pthreads import library (we do link pthreads dynamically at present). Single-threaded console apps and static libraries do not need this.

Set the arguments for debugging

Finally, if this is a daemon, add "/console" to the Debugging "Command Arguments" setting. When DaemonLib's WinMain implementation runs and sees this option, it will open up a console instead of starting as a service. To shut down the service, don't stop the program; type Ctrl C in the console window instead. This initiates an orderly shutdown (orderly in that it has the same effect as stopping the service would).