Producting dictionary source code with genreflex
The genreflex command is used to generate the C++ code from header
files that will be used to populate the C++ Reflection information
when it will be loaded into an application. It is based on the
GCC_XML open-source C++ parser,
a C++ front-end to GCC, which is currently able to deal with the
language in its entirety.
The genreflex command is directly available from the Reflex installation's
binary directory.
It requires to have access to an installation of GCC_XML which
should be made available in one of the following ways.
- passing the option --gccxmlpath=/dir/to/gccxml/bin to the genreflex
invocation
- a file gccxmlpath.py in the location of the genreflex python
files which contains the path to the gccxml binary directory
e.g.
gccxmlpath='/usr/local/gccxml/bin'
- lookup of gccxml in the PATH (not implemented yet)
- a default location in /afs/cern.ch/sw/lcg/external/gccxml/...
Command syntax
genreflex headerfile1.h [headerfile2.h] [options] [pre-processor options]
The genreflex command produces a C++ file per input header file
with the name by default <header>_rflx.cpp containing the
definition of the dictionary for one or more classes available
from the header files. The resulting file will need to be compiled
and linked to produce a dictionary library (dynamically loadable
library) that will be later loaded by the application requiring
the dictionary.
Command Options
-s <file>, --selection_file=<file>
-o <file>, --output <file>
-c <file>, --capabilities=<file>
--pool
--deep
--comments
--no_membertypedefs
--fail_on_warnings
--gccxmlpath=<path>
--quiet
--debug
-h, --help
-s, --selection_file=<selectionFile.xml>
The XML selection file is optional. It is used by the lcgdict
command to select from the classes accessible from the input header
file, which ones are going to produce dictionary information. In
addition, extra information attached to the dictionary can be added.
What information will be attached to dictionaries and can be extended
later. Here is an example of selection file:
There is also more detailed information available about selection
file syntax.
<lcgdict>
[<selection>]
<class [name="classname"] [pattern="wildname"] [id="xxxx"] [type="vector"]/>
<class name="classname" >
<field name="m_transient" transient="true"/>
<field name="m_anothertransient" transient="true"/>
</class>
[</selection>]
<exclusion>
<class [name="classname"] [pattern="wildname"] />
<method name="unwanted" />
</class>
...
</lcgdict>
If no selection file is specified, by default, the lcgdict command
will generate the dictionary for the classes directly defined
at input header file and will ignore any class defined in any
included file. In may occur that the compiler generates "hiddden" implementation specific classes and therefore
these classes will appear unfortunately in the list of classes for which to
generate the dictionary. To avoid compiler depend behavior it is recommend
to use a selection file to explicitly select the classes.
Classes matching the specific class name (when using attribute "name")
or a pattern name with wildcards (when using attribute "pattern")
in the <selection> block will be selected. The wildcard characters
are: "*" for any undetermined number of characters and "?" for
a single one. Notice that the character "*" is interpreted
as a wildcard character in patterns instead of the C/C++ pointer.
Classes matching the specific class name or a pattern name in the <exclusion> block
will be excluded if selected in the selection block.
Extra reflection information can be added for classes, methods
and fields:
- id -- class ID
- type -- class container type
- transient -- to indicate that the field
is transient
-o, --output=<file>|<dir>
The -o option specifies the output directory if the name specified
is a directory name, otherwise it is interpreted as a file name.
The default output is the current directory with the name <header_file>_dict.cpp.
-c, --capabilities=<file>
The -c option tells the lcgdict command to collect all the names
of the classes for which the dictionary is generated and produce
a function used by the SEAL Plugin Manager to obtain this list.
The output capabilities file will located in the same directory
as the <header>_dict.cpp file and will need to be compiled
and linked with the rest of the other generated files to produce
the dictionary library.
--pool
This option tells the lcgdict command to generate the reflection
information only for the class data members and their constructors
and destructors. This option is useful for obtaining more compact
dictionary libraries for projects interested in using only the
POOL persistency system.
--comments
This will add comments of data and functionmembers (in the same
line) as a property to the reflection information.
--no_member_typedefs
By default the reflection information for typedefs inside a class
is generated automatically. This option will disable these typedef
generations
--fail_on_warnings
This will make the genreflex command fail if warnings (e.g. classes
in a selection file are not found) are issued.
--deep
This option tells the lcgdict command to generate the dictionary
for all the classes in the current header files and an all reachable
classes (as members and bases classes)
--gccxmlpath=<path>
Option to set the path where to find the the gccxml command. The
default is to look in the current PATH.
--quiet
This option will remove printout on the screen
--debug
This option will keep the intermediate xml file (output from the
gccxml step)
C-preprocessor options: -D -I -U -P
Any C-preprocessor is accepted as lcgdict command option. These
options are passed directly to the gcc_xml command (gcc compiler).
The selection file syntax
Syntax Description
The pseudo syntax description can be seen in the table below.
<lcgdict>
[<selection>]
<class [name="classname"] [pattern="wildname"]
[file_name="filename"] [file_pattern="wildname"]
[id="xxxx"] [type="vector"] [anypropertykey="prop value"]/>
<class name="classname" >
<field name="m_transient" transient="true"/>
<field name="m_withpropertiesattached" prop1="prop1 value" prop2="prop2 value"/>
<function [name="funcname"] [pattern="wildname"] />
[</selection>]
<exclusion>
<class [name="classname"] [pattern="wildname"] />
<method name="unwanted" />
</class>
...
</lcgdict>
Description of elements and attributes
<lcgdict>
Sub elements: <selection> <exclusion>
<class> <function>
Attributes: none
The root element of the xml file. It has to be present. |
|
<selection>
Sub elements: <class> <function>
Attributes: none
The selection element is only mandatory if the <exclusion> element
is used in the same file. Otherwise all sub-elements of <lcgdict>
are supposed to be included in the dictionary. |
|
<exclusion>
Sub elements: <class> <function>
Attributes: none
If a selection element is present it is also possible to exclude types
following the same patterns as for selection |
|
<class>
Sub elements: <field> <properties>
<method>
Attributes:
Attribute name |
Description |
name |
The exact name of the class to be filtered |
pattern |
A pattern matching a set of classes |
file_name |
The exact file name to be filtered. All classes contained in the
file will be selected |
file_pattern |
A pattern matching a set of files |
id |
The class ID (used for POOL persistency) |
type |
The class type (used for POOL persistency) |
All classes matching the patterns or names in the attributes will be
selected. The "name", "pattern", "file_name"
and "file_pattern" attributes are mutual exclusive. |
|
<function>
Sub elements: none
Attributes:
Attribute name |
Description |
name |
The exact name of the function |
pattern |
A pattern matching a set of functions |
All function matching the attributes of the function element will be
selected and dictionaries will be created for them. The "name"
and "pattern" attributes are mutual exclusive. |
|
<field>
Sub elements: none
Attributes:
Attribute name |
Description |
name |
The exact name of the field |
transient |
If set to true a property (transient/true) will be set for this
member (used for POOL persistency) |
The <field> element is mainly used for POOL persistency to mark
if some of the data members of a class shall be skipped when the class
is written to a persistent medium |
|
<method>
Sub elements: none
Attributes:
Attribute name |
Description |
name |
The name of the method to be excluded |
The <method> element is used to exclude the dictionary generation
from classes which match the given attributes. |
Generating Dictionaries for large projects
In large projects consisting of many C++ packages is common practice to generate
more than a single dictionary library. Typically, the dictionary library for
a set of classes will be build in the same package where the classes are defined,
but the problem may arise for classes that are used by several packages and
are not part of the project itself. For example, it is not obvious which is
the package in charge of creating the dictionary for standard classes like
std::vector<int>. Although the Reflex package has protections
against defining the dictionary of a class more than once, in general, should
be avoided. The main reasons are:
- Waste of disk and memory space. The size of the dictionary for a Class
maybe non-negligible is the Class is complex.
- If the class dictionary has
been build with no default options (specification of transient data members,
class ID, etc.) and perhaps different for the different libraries, the
dictionary loading order may have undesirable effects.
Precautions need to
be taken to generate the dictionary for all Class only once. Also
it is very important to achieve "complete" dictionaries
without forgetting classes that participate as data members,
base classes or argument types in all required classes. Utilities have been
developed to check completeness at the project level.
|