Configurations

The following is an example of how to define the set of build configurations:


config
{
   "Debug|Win32" ["MBCS"]
   "Release|Win32" ["MBCS"]
   "Debug Unicode|Win32" ["Debug" "Unicode"]
   "Release Unicode|Win32" ["Release" "Unicode"]
   "Debug|Pocket PC 2003 (ARMV4)" ["WinCE"]
   "Release|Pocket PC 2003 (ARMV4)" ["WinCE"]
   "Debug|Smartphone 2003 (ARMV4)" ["WinCE"]
   "Release|Smartphone 2003 (ARMV4)" ["WinCE"]
}

Each entry is of the form "config|platform" plus optionally a list of any number of white space delimited tags in square brackets. In the above case there are 6 configurations and 3 platforms. The tag "WinCE" has been applied to the last 4 configurations. For a given entry of the form "config|platform", the config is available in a variable named $(CONFIG) and the platform in a variable named $(PLATFORM). E.g. the platform and config names can be used to specify the output file of the linker:


+link
{
   /OUT:"$(EXPORT)/$(PLATFORM)/$(CONFIG)/
   $(PROJNAME).$(TGT_EXTENSION)"
}

A config block can be repeated to add more and more configurations. This can be useful in a @import file which specifies a base set of configurations, yet allows projects to add additional configurations.

Unfortunately in both versions of MSVC that were tried (VC 2005 and VC 2008) the IDE allows the user to select configurations that were never defined, such as Debug Unicode|Pocket PC 2003 (ARMV4)

VC even allows the user to try to build it! Not surprisingly the build fails (e.g. because the additional includes aren’t even defined).

Note that a configuration that targets Win32 must name the platform "Win32" or else MSVC gets upset. It is unknown why this is the case given that every imaginable setting is specified explicitly in the .vcproj file, raising the question of why the platform name is significant.

Configuration lists

Compiler and linker switches can be applied to particular configurations, expressed using combinations of the following:

As an example, the following switches are applied to all con- figurations named "Release" (i.e. irrespective of the target type, platform and compiler)


+cpp("Release")
{
   /Ot
   /FD
   /D "NDEBUG"
}
+link("Release")
{
   /PROFILE
   /MAP:"$(EXPORT)/$(PLATFORM)/$(CONFIG)/$(PROJNAME).map"
   /INCREMENTAL:NO
   /OPT:
   /OPT:ICF
}

Even though there is some risk of confusion to a C/C++ programmer, ’|’ denotes a logical ANDing. This is done because Microsoft have set a precedent for using the syntax config|platform for a particular configuration on a particular platform.

E.g the following switch is applied to the configuration "Release" for platform "Win32"


+cpp("Release|Win32")
{
   /MD
}

The order doesn’t matter - the following works just as well:


+cpp("Win32|Release")
{
   /MD
}

In fact any of the specifiers can be ANDed in this way. E.g. we can use a tag name:


+cpp("Release|WinCE")
{
   /MT
}

A comma delimited list of strings is used for logical ORing. E.g.


+cpp("Debug|WinCE|Console Application|VC9","Debug|Win32|Application")
{
   /MTd
}