Note: this section makes extensive use of OTF-specific terminology that is explained in detail in the design concepts page. If you haven't read that page, you should do so before continuing.

Usage Outline

In the broadest terms, the procedure for using the OTF in writing a biochemical application is as follows:

  1. Create the input for genlib -- the input is typically a file listing the components requested for inclusion in the generated library as well as customization C++ code, specially marked up for recognition by genlib.
  2. Run genlib to create the compiled library and class interface header files -- by default both are deposited in a subdirectory named lib.
  3. If any compilation errors are encountered, correct the input and repeat step 2.
  4. Compile the complete application with the generated header files and link with the compiled library.

Input Preparation

This section will lay out the general procedure of developing your genlib input and may gloss over fine detail. Questions of exact syntax, etc., can be resolved by consulting the genlib reference page.

Component inclusion

The first step in input preparation is to decide which available toolkit components to request for inclusion in the generated classes. Requests for inclusion are typically found at the top of the input and are composed of the keyword implementation followed by the name of an implementation of that component, e.g.:

implementation Molecule/default;
implementation Molecule/PDBio_default;

The name of the implementation is composed of the toolkit name and the component implementation file name, separated by a '/'. If the component is in a subtoolkit, then the subtoolkit name (or names, for sub-subtoolkits) would follow the main toolkit name but proceed the component name, with '/'s separating the names.

If a genlib input file contained only implementation statements, then genlib would generate code for a set of classes (e.g. Molecule, Atom, etc.) with the specified genericly useful features included. To make these classes useful to a particular application, specialized features need to be added...

Customization

The vast bulk of the application-specific customization is in the form of C++ code written by the application developer, specially marked up so that genlib knows where to place the code in the generated classes. The code markup tags are:

members
Additions to the class interface (header file).
code
Implementation of functions specified in members tag.
inlinecode
Same as code, except inlined.
constructor
Code added to constructor(s).
destructor
Code added to destructor.

Besides code markup tags, there are some other statements that genlib interprets that are pertinent to class customization. They are:

includefile
Specify a file to be included in class interface
provide container
Specify that a class needs to have a container of instances of, or references to, another class.
container
The OTF supports a wide variety of container types, but some applications may need to make use of custom containers. The container statement is employed to communicate a custom container's syntax and semantics to genlib, so that the container can be used in other genlib statements.

Running genlib

After creating an input file, running genlib with that file as input and no command line options will do the following:

  1. Create a subdirectory named lib. All further work by genlib occurs in this subdirectory.
  2. Compose requested classes into Class.h and Class.cc files.
  3. Create a lib.h file that includes all the Class.h files as well as all the inline functions. This lib.h file gets included in all the Class.cc files (rather than including Class.h).
  4. Create a Makefile.
  5. Compile the sources into a library named liblib.a.

Via command line options, it is possible to override the default library name (lib), the default compiler (g++), etc. The Command Line Use section of the genlib manual page covers these options in detail and should be perused in any case.

Genlib errors

There are two types of errors that can result from running genlib: errors from genlib itself, and errors from the compilation of the assembled C++ code. Errors from genlib itself should be fairly self-explanatory. If you encounter a genlib error that you don't understand, please send mail to otf@cgl.ucsf.edu so that we can explain the error and also improve the error text to make it more understandable in the future.

Errors during compilation will refer to line numbers in the composed code modules, rather than in the genlib input file. To correct the errors, you should refer to the code module mentioned in the error message, identify the error and its correction and then go back to the input file and make the correction and rerun genlib. Making the correction directly in the code module and running make will work to recompile the library, but in the long run it is better to correct the input file so that if you decide to add or subtract components, etc., then rerunning genlib will generate correct code and you won't have to redo all your corrections.

Compiling the Application

To employ the class library created by genlib, it is necessary to include the lib/lib.h file in any code modules that use the generated classes, and to link the object files with the lib/liblib.a archive. That's all there is to it.