Home

Sponsors

Download

Install

Running

Examples

Tcl Scripts

News

Future Work

Copyright

Supported Platforms

CABLE generates C++ code that is to be built by your compiler. This has several implications on platform support:
  • Generated code cannot have errors according to your compiler. Although CABLE generates valid C++ code, not all compilers accept all valid C++ code.
  • Generated code is very specific to the real types of every function argument and return type. If any are library defined types, then they must match the types in the library provided by your compiler. Since GCC-XML is used to parse the classes to be wrapped, and therefore the libraries provided by the compiler, CABLE can only support compilers supported by GCC-XML.
Currently, the supported platforms are:
  • GCC 3.2.x, 3.1.x, 3.0.x, and 2.95.x on UNIX and Cygwin
  • MIPSpro 7.3 on IRIX
  • Visual C++ 7.0 (MSDev.NET) on Windows
  • Visual C++ 6.0, service pack 5 on Windows
  • Intel C++ 5.0 within Visual C++ 6.0 on Windows
Currently, the supported interpreted languages are:
  • Tcl 8.0 and above.

Running CABLE

In general, there are four steps to produce wrappers with CABLE.
  1. Write the CABLE configuration file.
  2. Run cable to generate wrappers.
  3. Compile the generated code.
  4. Link the wrappers into a package.

Writing the CABLE Configuration File

The CABLE configuration file is written in C++. Here is the basic layout:
  // Define your classes or include headers.
  
  #ifdef CABLE_CONFIGURATION
  namespace _cable_
  {
    const char* const group="MyGroup1";
    const char* const package="MyPackage";
    const char* const groups[]={"MyGroup1"};
    namespace wrappers
    {
      // List class wrappers as typedefs.
      // Name of typedef will be wrapped name.
    }
  }
  // Additional code to ensure implicit instantiation of
  // class templates that are to be wrapped.
  #endif
The beginning of the configuration file must provide the code defining the C++ classes to be wrapped. The generated code will acutally #include the configuration file, but will not define CABLE_CONFIGURATION. Therefore, all CABLE-related code should be placed inside the configuration section. This approach allows one to define a class and wrap it all in a single file.

Cable configuration code is placed in the _cable_ namespace. This avoids name conflicts with classes getting wrapped.

The group setting must be initialized by a string literal, and must be a valid C-identifier. It names the set of wrappers defined in this particular configuration file.

The package setting must be initialized by a string literal, and must be a valid C-identifier. It gives the name of the package of wrappers to be generated.

The groups setting must be initialized by an array of string literals. They name the set of groups to be combined into this package of wrappers. When the package is built, code generated from all the groups listed here (each with its own configuration) should be compiled and linked together.

Wrappers produced from several configuration files can be combined into a single package. Each group's configuration file needs only know the name of the group. Only a single master package configuration file needs the package and groups settings. This file may or may not contain any class wrappers. The generated code will contain package-level initialization code for all the groups in the package.

The _cable_::wrappers namespace should contain a list of typedefs for the classes to be wrapped. For example,

  typedef ::Foo Foo;
  typedef ::Bar<int> Bar_int;
will produce class wrappers called "Foo" (wrapping class Foo), and "Bar_int" (wrapping class template instantiation Bar<int>). Nested namespaces are allowed, and the names will be used in the generated language. For example,
  namespace zot { typedef ::Foo Foo; }
will produced a class wrapper called "zot::Foo". The actual format of the "zot::" prefix is dependent on the target language.

Finally, after the _cable_ namespace has been closed, one must write code to force implicit instantiations of class templates. This is necessary to get GCC-XML to dump proper descriptions of class template instantiations. For the above example, we can use this code to make sure that Bar<int> is properly instantiated:

  void force_instantiation()
  {
    sizeof(Bar<int>);
  }
See the Examples page for a complete configuration file.

Running cable to Generate Wrappers

CABLE is run as a command-line executable called "cable". Here is its basic usage:
  cable config.cxx <language-name> output.cxx [options]
Cable will internally run GCC-XML on the input configuration file and parse the result. Any preprocessor options (like -I or -D) that are given to cable will automatically be passed on to GCC-XML. If the gccxml executable is not in your path, you can set CABLE_GCCXML in your environment to point at it. Alternatively, you can specify the executable's location with the --gccxml option.

The language name should specify the language for the generated wrappers. Currently, only Tcl is supported. It is specified by the "-tcl" option. The output file name must immediately follow the language name because future versions of CABLE may allow generation of wrappers for more than one language at a time.

Compiling the Generated Wrappers

The generated output file should be compiled by the same compiler that GCC-XML is configured to simulate. Building the generated code requires that the include path contain the CABLE include-file directory. This will be in one of these places:
  • If CABLE is running from its build tree, use the top-level CABLE source diretory.
  • If CABLE is running from an installation directory, use PREFIX/include/Cable. This is valid only on UNIX platforms.

Linking Wrappers into a Library

Once all the wrappers in the package have been compiled, they should be linked into a library. The package should link to the CABLE facility library for the corresponding language. Currently, this is always the "CableTclFacility" library since only Tcl wrapping is supported.