C/C++ code generator in MSBuild (Part 0)

A while back I had need to create a C code generator for MSBuild. The desire was to integrate with a native Visual Studio project.

This series of posts will cover how to create an MSBuild task that invokes a code generator which has unknown include dependencies. There will be a mix of languages:

First, a brief overview of common ways one may integrate a code generator with MSBuild.

Custom Build Steps

For simple code generators one can get away with using a custom build step. These are convenient in that they can be easily set up through the Visual Studio GUI. Custom Build Step For a code generator, one would need to ensure that the build step is performed prior to the code compilation.

Custom build steps have a few limitations:

Experience has shown that people start with a simple code generator and a custom build step. Then as their code generator gets more complex the code generator itself starts to turn into a mini build system due to the limitations of a custom build step. Finally they may force the code generator to always run in order to ensure it picks up dependencies that weren’t able to be communicated through the custom build step. Then the code generator will conditionally output code only if it changed, so that anything it depends on doesn’t unecessarily compile.

Just like the compiler will always turn a code file into an object file, a code generator should always generate the code. The build system should decide if and when the code generator runs.

Tasks

Tasks are the MSBuild term for operations performed as part of the build. A coleague of mine once said

A build system can be thought of as a task scheduler

This quote and MSBuild’s use of the term task seem to corroborate each other.

MSbuild itself is pretty generic. I believe most if not all of the build operations performed by MSBuild are done via pre-packaged tasks in dlls. These tasks just happen to normally be loaded by the common projects people use.

Using tasks requires more work, in that one must implement a C# class and provide either a dll or inline the code into the build files. However, tasks provide the full capabilities of the .Net framework as well as allowing one to determine dependencies at build time.

The approach taken in this series will be to utilize a task and go through the steps of developing, integrating and debugging a code generator implemented as a task.

Resources

These resources will be used throughout this series.