# Chapter 5 The IDL compiler

omniORBpy uses a new IDL compiler, named omniidl, which is also used by omniORB 3. It consists of a generic front-end parser written in C++, and a number of back-ends written in Python. omniidl is very strict about IDL validity, so you may find that it reports errors in IDL which compiles fine with earlier versions of omniORB, and with other ORBs.
The general form of an omniidl command line is:

> `omniidl` [options]`-b`<back-end>`` [back-end options]`` <file 1>`` <file 2>`` ...

## 5.1 Common options

The following options are common to all back-ends:

`-D` name[`=`value] | Define name for the preprocessor.
`-U` name | Undefine name for the preprocessor.
`-I` dir | Include dir in the preprocessor search path.
`-E` | Only run the preprocessor, sending its output to stdout.
`-Y` cmd | Use cmd as the preprocessor, rather than the normal C preprocessor.
`-N` | Do not run the preprocessor.
`-Wp` arg[,arg...] | Send arguments to the preprocessor.
`-b` back-end | Run the specified back-end. For omniORBpy, use `-bpython`.
`-Wb` arg[,arg...] | Send arguments to the back-end.
`-nf` | Do not warn about unresolved forward declarations.
`-k` | Keep comments after declarations, to be used by some back-ends.
`-K` | Keep comments before declarations, to be used by some back-ends.
`-C` dir | Change directory to dir before writing output files.
`-d` | Dump the parsed IDL then exit, without running a back-end.
`-p` dir | Use dir as a path to find omniidl back-ends.
`-V` | Print version information then exit.
`-u` | Print usage information.
`-v` | Verbose: trace compilation stages.

Most of these options are self explanatory, but some are not so obvious.

### 5.1.1 Preprocessor interactions

IDL is processed by the C preprocessor before omniidl parses it. Unlike the old IDL compiler, which used different C preprocessors on different platforms, omniidl always uses the GNU C preprocessor (which it builds with the name omnicpp). The `-D`, `-U`, and `-I` options are just sent to the preprocessor. Note that the current directory is not on the include search path by default---use ``-I.`' for that. The `-Y` option can be used to specify a different preprocessor to omnicpp. Beware that line directives inserted by other preprocessors are likely to confuse omniidl.

### 5.1.2 Forward-declared interfaces

If you have an IDL file like:

    interface I;
    interface J {
      attribute I the_I;
    };

then omniidl will normally issue a warning:

      test.idl:1: Warning: Forward declared interface `::I' was never
      fully defined

It is illegal to declare such IDL in isolation, but it is valid to define interface `I` in a separate file. If you have a lot of IDL with this sort of construct, you will drown under the warning messages. Use the `-nf` option to suppress them.

### 5.1.3 Comments

By default, omniidl discards comments in the input IDL. However, with the `-k` and `-K` options, it preserves the comments for use by the back-ends. The C++ back-end ignores this information, but it is relatively easy to write new back-ends which do make use of comments.
The two different options relate to how comments are attached to declarations within the IDL. Given IDL like:

    interface I {
      void op1();
      // A comment
      void op2();
    };

the `-k` flag will attach the comment to `op1()`; the `-K` flag will attach it to `op2()`.

## 5.2 Python back-end options

When you specify the Python back-end (with `-bpython`), the following `-Wb` options are available. Note that the `-Wb` options must be specified after the `-bpython` option, so omniidl knows which back-end to give the arguments to.

`-Wbstdout` | Send the generated stubs to standard output, rather than to a file.
`-Wbinline` | Output stubs for #included files in line with the main file.
`-Wbglobal=`g | Use g as the name for the global IDL scope (default `_GlobalIDL`).
`-Wbpackage=`p | Put both Python modules and stub files in package p.
`-Wbmodules=`p | Put Python modules in package p.
`-Wbstubs=`p | Put stub files in package p.

The `-Wbstdout` option is not really useful if you are invoking omniidl yourself. It is used by `omniORB.importIDL()`, described in section 6.10.
When you compile an IDL file which #includes other IDL files, omniidl normally only generates code for the main file, assuming that code for the included files will be generated separately. Instead, you can use the `-Wbinline` option to generate code for the main IDL file and all included files in a single stub file.
Definitions declared at IDL global scope are normally placed in a Python module named ``_GlobalIDL`'. The `-Wbglobal` allows you to change that.
As explained in section 2.2, when you compile an IDL file like:

    // echo_example.idl
    module Example {
      interface Echo {
        string echoString(in string mesg);
      };
    };

omniidl generates directories named `Example` and `Example__POA`, which provide the standard Python mapping modules, and also the file `example_echo_idl.py` which contains the actual definitions. The latter file contains code which inserts the definitions in the standard modules. This arrangement means that it is not possible to move all of the generated code into a Python package by simply placing the files in a suitably named directory. You may wish to do this to avoid clashes with names in use elsewhere in your software.
You can place all generated code in a package using the `-Wbpackage` command line option. For example,

> `omniidl -bpython -Wbpackage=generated echo_example.idl`

creates a directory named ``generated`', containing the generated code. The stub module is now called ``generated.Example`', and the actual stub definitions are in ``generated.example_echo_idl`'. If you wish to split the modules and the stub definitions into different Python packages, you can use the `-Wbmodules` and `-Wbstubs` options.
Note that if you use these options to change the module package, the interface to the generated code is not strictly-speaking CORBA compliant. You may have to change your code if you ever use a Python ORB other than omniORBpy.

## 5.3 Examples

Generate the Python stubs for a file `a.idl`:

> `omniidl -bpython a.idl`

As above, but put the stubs in a package called ``stubs`':

> `omniidl -bpython -Wbstubs=stubs a.idl`

Generate both Python and C++ stubs for two IDL files (requires omniORB 3):

> `omniidl -bpython -bcxx a.idl b.idl`

Just check the IDL files for validity, generating no output:

> `omniidl a.idl b.idl`