Generating Visual Studio projects
<terp.cpp> task allows you specify the optional nested <generatevsproject/> element. When present, this element causes the generation of a Visual Studio project file suitable for building the C++ project.
When you look at all the features of terp, for example:
- arbitrary pre- and postbuild ANT task invocations
- dynamic source code generation with template expansions
- dynamic resource file generation
- conditional compiler switches
- iteration over different compiler versions
just to name a few, it becomes clear that not the entire functionality of a
<terp.cpp> invocation can be captured in a Visual Studio project file. Similarly, Visual Studio is far more than a simple C++ build engine. It allows you to invoke the entire Microsoft tool chain from within one centralized solution.
Why bother generating a Visual Studio project file?
There must be people out there who are in similar situations as we are:
- you have a C++ product that has to be built, tested, and maintained on multiple platforms, Windows being one of them.
- you need a build solution that works on all platforms.
- you have at least a few developers who like working primarily on Windows.
Let's face it: if you are working on Windows in C++ there's a 99% chance that you are using Visual Studio. You are used to editing source files in Visual Studio, you are used to debugging your solution in Visual Studio, you do your iterative development in Visual Studio.
It is nice to have a build solution that can give you a Visual Studio project file that you can use for all these tasks.
What are the limitations?
As already outlined above, we cannot capture everything, but we strive to continuously make the integration of terp and Visual Studio more powerful. Here are the limitations that we have encountered (there are likely more):
- if you generate dynamic sources, you need to specify filenames, best in a meaningful, nested location. If the files are generated in Java's temporary directory, they are likely gone by the time you open your generated project file.
- the terp Visual Studio project generator does not understand all command line switches. When you specify additional options via free form
<option>elements, they are likely to be missing in the generated project.
- terp's focus is multiplatform builds. It does not understand IDL, ODL, and other Microsoft sources (yet). If you have additional sources of these types, there's no way (yet) to add them to the project.
- Visual Studio project files generally contain at least two configurations: a Release and a Debug configuration. terp creates project files with just one configuration. It is named Release or Debug based on the absence or presence of a debug command line switch.
Can I work around some of these limitations?
We use our built-in default project templates to generate the project files. You can specify your own templates that contain your own, hard-coded default settings. Using your own template is the easiest and most powerful option for customizing the generated project.
In addition to that you have to remember that (modern) Visual Studio project files are just XML files. You can transform them very easily using an XSLT transformation. For example:
- you could programmatically add or modify certain build options in the generated project file.
- you could combine a release and a debug project into one project.
It really isn't that hard to fix up or modify a generated project, as long as you have a good starting point.
Please help us out if you find yourself in need of a parametrization or a feature that you believe should be part of terp. Send us your project file (or template), the compiler switch you wish to see integrated, and we'll make an effort to update terp.
The <generatevsproject/> attributes
All attributes are optional. If you add generated projects to a solution or create project to project relationships, you will typically wish to specify the
guid attribute to make sure that the relationship between solution and project is maintained correctly.
Optional attribute overriding the unique project identifier. If not specified, a new project identifier is used every time the project is re-generated.
Optional attribute overriding the project name. If not specified, project name is derived from
<terp.cpp compiler="^msvc(15)"> <generatevsproject name="myproj.14" version="14" /> <generatevsproject name="myproj.15" /> </terp.cpp>
Here we build with MSVC++ 15, but we generate two project files, one for MSVC++ 15 (Visual Studio 2005) and one for MSVC++ 14 (Visual Studio 2003).
Optional attribute overriding the template being used for the generated project files. The default templates are embedded in the terp ANT task jar file but we bundle copies for customization here. These files are template files, not valid XML files, so you probably need to view them in a text editor rather than your browser.
Optional attribute overriding the compiler (Visual Studio) version for which we generate the project. If not specified, the configured compiler's version is used to determine proper project file template.
How does the template expansion work?
When processed, the
<generatevsproject/> element sets up a map with key/value pairs for the variables that are known to the code generator. These variables can then be used in a terp template. The default templates are stored in our jar file, so you cannot modify them, but we ship copies in the
doc/ant/templates directory. You probably want to use one of the templates there as a starting point for your customization because then you can see all the variable names and how they are being used.
Once you have created your own template, make it part of your source tree and reference it by name, for example:
<terp.cpp ... > <generatevsproject template="../templates/myproject.tpl" /> </terp.cpp>