: junc++ion generate

JunC++ion ANT Reference

Prerequisites

Codemesh provides you with a set of custom ANT tasks for generating C++ proxy types. The custom tasks require ANT 1.6.5 or higher. The code generator itself requires Java 7 or higher.

ANT Configuration

The custom tasks and their related types are bundled in the ant-terp.jar file, which resides in JunC++ion's lib directory. As with any ANT extensions, you need to make them available to ANT at runtime. Please note that the ANT tasks in the ant-terp.jar file rely on types in the other bundled jar files, so they need to be available too.

There are multiple ways to do it, but most commonly you just add the directory containing your jar files to ANT's library path every time you invoke ANT, for example:

  ant -lib /opt/junc++ion-4.8.212/lib ...

This makes the entire code generator codebase available to ANT.

Make sure to enclose a path containing spaces in doublequotes so the shell will parse your command correctly. This is more commonly an issue on Windows when the code generator is installed under the Program Files or Program Files (x86) directories, for example:

  ant -lib "C:\Program Files\junc++ion-4.8.212\lib" ...

If you choose to copy the jar files to locations outside the code generator directory (for example to another directory that is already configured to be on ANT's library path) you might need to perform additional configurations in your ANT script or the environment because by default the code generator tasks expect to be located in a code generator distribution.

Your Basic Code Generation build.xml File

The code generator task is implemented by the com.codemesh.terp.ant.codegen.CodeGeneratorImpl type. You could use a taskdef to map that type to any name you wish, but we tied some internal smarts to its mapped name so we recommend that you stick with the junction name.

We supply you with two properties files in the lib directory that contain all task- and type-definitions that you need. For code generation your only need to reference the codemesh_tasks.properties file in your build script to make the code generator task available under its expected junction name.

With the code generator's lib directory on ANT's classpath, you can simply reference the properties file by name in a <taskdef> invocation as shown in the build file snippet below.

<project name="proxygen" basedir="."
         default="generate"
         description="Generate the proxy types"
>

  <taskdef resource="codemesh_tasks.properties"/>

  <target name="generate">
    <junction>
    </junction>
  </target>

</project>

While the above snippet shows the basic project setup, it does not do anything useful yet. We need to give JunC++ion a model file to work on. You provide the model file in your build script via a nested <modelfile> element as shown in the snippet below:

<project name="proxygen" basedir="."
         default="generate"
         description="Generate the proxy types"
>

  <taskdef resource="codemesh_tasks.properties"/>

  <target name="generate">

    <junction>
      <modelfile file="mymodel.jmm" />
    </junction>

  </target>

</project>

For simple builds the above snippet may be totally sufficient but we put a lot of thought into making the code generator host- and user-portable. To that effect we support model file variables (as described elsewhere) that can be set via command line options. In the CLI reference we describe the -D and -p options that allow you to define variables from a name/value pair or a properties file respectively.

Clearly our ANT task needs to also support these features. This is achieved via the optional <buildproperty>, <modelproperty> and <modelproperties> elements. The former element expects name and value attributes, the latter a file attribute referring to an existing properties file. The following snippet illustrates:

<project name="proxygen" basedir="."
         default="generate"
         description="Generate the proxy types"
>

  <taskdef resource="codemesh_tasks.properties"/>

  <property name="cppTargetDir" value="${basedir}/cpp" />
  <property name="version" value="1.0.0" />

  <target name="generate">

    <junction>
      <buildproperty name="cppTargetDir" />
      <modelproperty name="cppProjectVersion" value="^v('${version}')" />
      <modelproperties file="${hostname}-tocpp.properties" />
      <modelfile file="mymodel.jmm" />
    </junction>

  </target>

</project>

In the above snippet we define two build properties (cppTargetDir and version) that are given default values. cppTargetDir is the name of the model property that governs where the C++ proxy types are generated, version shall be a version number passed in by our build system.

Nested in the <junction> task are the three ways of providing one or more model property overrides. The <modelproperty> element expects both a name and a value attribute to be set. The <buildproperty> element just needs to be given a name attribute which it expects to refer to an existing, defined ANT property. This is essentially a shorthand that saves you the hassle of specifying both name and value when you just want to pass an already defined property unmodified to the code generator.

The <modelproperties> element expects a file attribute to be set, referencing a properties file containing one name/value pair per line. This element gives us a great way of configuring a bunch of settings together. The most common use case for that element is a buildhost configuration file that defined all the host-specific properties like jdk, etc.

It should be noted that like most Codemesh ANT elements, all nested <junction> elements support if and unless attributes. These attributes accept expressions as values. Please see the model file reference for more details. We recommend that you not go wild with conditionals in your code generator configuration because it can make your builds harder to debug, but the ability is there.