Design

A Build System for Complex Projects: Part 4

By Gigi Sayfan, October 23, 2009

Generating a full-fledged Visual Studio build system for a non-trivial system involves multiple projects

Gigi Sayfan specializes in cross-platform object-oriented programming in C/C++/ C#/Python/Java with emphasis on large-scale distributed systems. He is currently trying to build intelligent machines inspired by the brain at Numenta (www.numenta.com).

This is the fourth article in a series of articles that explore an innovative build system for complicated projects. Part 1 and Part 2 discussed build systems in general and the internals of the ideal build system that can integrate with existing build systems. Part 3 discussed in detail how to the ideal build system works with the NetBeans IDE and can generate its build files. This article will do the same for Microsoft Visual Studio.

Generating the Visual Studio build System

As you recall, Isaac the development manager became a true Invisible Build System (ibs) convert after seeing ibs in action. He gave Bob the mandate to use ibs on Windows to build the company's top-secret project: "Hello World - Enterprise Platinum Edition". The Windows developers of the company sweat by Visual Studio. Visual C++ supports a makefile-like build environment via the NMAKE tool, but it is not very common. Visual Studio provides both an IDE-based build environment for C/C++ projects as well as several alternatives for automated builds from the command line (vcbuild.exe, Visual Studio automation and extensibility object model, direct invocation of devenv.exe). The build files shared by all these approaches (except NMAKE) are the project and the solution. There is one project file per logical project and it encapsulates all the information about a project (same as the Makefile + nbproject directory of NetBeans). The solution is a collection projects and it corresponds the project group of NetBeans.

Figure 1 shows the Visual Studio IDE with the various Hello World projects organized in folders (apps, dlls, hw, and test).

Figure 1

The Visual Studio build System Anatomy

The Visual Studio build files are considerably simpler then NetBeans. There is a single project file, which is a pretty straight forward XML file and there is a solution file, which uses (unfortunately) a proprietary text format. Figure 2 shows the project properties page for the hello_world application. There many many options and settings in GUI and most of them have default values. The project file contains only the settings that differ from the defaults (and settings that don't have defaults and must be specified). The format of the .vcproj file is documented here.

Figure 2

Project file (.vcproj)

The entire build information for a project is stored in a single file. Let's examine the project file for the main hello_world application. I'll analyze it section by section. It all starts with an XML 1.0 tag to indicate it is an XML file and then there is a VisualStudioProject element with various attributes. The important ones are the project type (Visual C++), the version (9.00 for VC++ 2008), the name ("hello_world") and the ProjectGUID, which uniquely identifies this project.

The next section is the platforms section, which determines the target platforms. In this case just Win32:

<Platforms>
<Platform
Name="Win32"
/>
*</Platforms>

There is an empty ToolFiles element. This element can point to custom build rules files. It is straightforward to use custom build rules from the IDE, but doing it programmatically is not documented very well (try this if you must). This capability can be added easily to ibs in a cross-platform way via a callback mechanism where ibs will call back a provided function before/after building each project.

<ToolFiles>
</ToolFiles>

The Configurations element is a collection of Configuration elements. Each configuration element contains a list of Tool elements where each tool is a program that participates in the build process. The most common and important ones are the compiler and linker. Here is the Debug configuration. The Release configuration is very similar:

The References element may contain references to other projects that the current project depends on. The referenced projects will be built before the current project. This is mostly critical for static libraries that need to be linked into an executable or DLL. But, there is also an alternative way of specifying dependencies through the solution file. The same project may belong to multiple solutions (possibly with different references/dependencies). Using the References element in the .vcproj file is not as flexible, but keeps the dependencies with the rest of the project metadata. In this case, I chose to capture the dependencies in the solutions file, so the references element is empty.

<References>
</References>

The Files element simply contains all the project files. There are several filters like Header Files, Resource Files and Source Files. The filters are mostly important for user interface purposes because the different file types are grouped into folders based on the filter. For building purposes the compiler needs to know what extension to use for source files, because these are the files that are actually compiled (header files are always #included by some source file). Files can be specified using relative path or absolute path. It is almost always better to use relative paths, so the same project file can be used in different locations by different users. Also, with ibs every project file resides under the project directory.

The Globals element allows definition of global objects. I'm not sure what are they and how they are supposed to be used. I never had the need for any global object. ibs simply generates an empty Globals element:

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task.
However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Video

This month's Dr. Dobb's Journal

This month,
Dr. Dobb's Journal is devoted to mobile programming. We introduce you to Apple's new Swift programming language, discuss the perils of being the third-most-popular mobile platform, revisit SQLite on Android
, and much more!