$Date: 2004/10/19 09:20:36 $ |
The lcgdict command is used to generate the C++ code that will be used to populate the LCG dictionary when it will be loaded into an application. It is available from the SEAL installation <prefix>/SEAL_X_Y_Z/<arch>/bin. For more detailed information refer to the lcgdict command page.
lcgdict headerfile1.h [headerfile2.h] [options] [pre-processor options]
-s <file>, --selection_file=<file> -o <file>, --output <file> Output file name. If an existing directory is specified instead of a file, then a filename will be build using the name of the input file and will be placed in the given directory. <headerfile>_dict.cpp --reflex Generate dictionary code compliant to Reflex --pool Generate minimal dictionary required for POOL persistency --deep Generate dictionary for all dependent classes --split Generate separate file for stub functions. Option sometimes needed on Windows. --gccxmlpath=<path> Path path where the gccxml tool is installed. If not defined the standard PATH environ variable is used -c <file>, --capabilities=<file> -h, --help Print this help
The output of the lcgdict command (one or more xxxx_dict.cpp files and possibly a "SEAL capabilities file can be compiled and linked into a shareable library (.so on Linux, .dll on Windows). To build the library you will need to compile and link against the Dicitonary/ReflectionBuilder package.
> g++ -o libMyClassDict.so -fpic -shared MyClass_dict.cpp -I<prefix>/SEAL_x_y_z/include -L<prefix>/<arch>/lib -llcg_ReflectionBuilder
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 can be extended later. Here is an example:
<lcgdict> <class name="A" id="01366d42-c04e-11d1-b1c0-00c04fc2f3ff"/> <class name="B"> <field name="m_transient" transient="true"/> </class> <class name="std::pair<double,std::string>" id="01366d42-c04e-11d1-b1c0-00c04fc2f3ef"/> <class pattern="std::vector<*>" type="vector" /> </lcgdict>
More details on selection files.
(*) Note that the "class id" is still required by POOL current release and that it must be a GUID in all upper case. This requisite will not be needed in upcoming releases.
To facilitate and automate the creation of dictionary libraries for your packages a set of conventions and makefile fragments has been setup.
The expected package structure is as follows:
<Package>/ <Package>/ public interfaces of the package (as usual) src/ standard source files for the package (to produce lib<Package>.so ) dict/ Directory containing the following (to produce lib<Package>Dict.so) - BuildFile SCRAM file indicating from which header files to generate the dictionary (see later) - Selection file to select and qualify extra dictionary information (see later) tests/ Unit tests (as usual) test1/ test2/ ...
Typing scram b in the /dict directory of anywhere above should just build the dictionary library.
This is used to indicate the header files from which you will like to generate the dictionary from. In addition you can specify the options to the lcgdict command.
The conventions are:
Define the variable DICT_FILES to the list of header files for which dictionaries should be generated. Typically this is something like $(LOCALTOP)/src/Xyz/Foo/Foo/Bar.h if you follow the SPI conventions; use $(wildcard) for all headers.
lcgdict is used to produce X_dict.cpp for each X.h in $(DICT_FILES).
Each such generation can be given separate options. Define X_h_DICT_OPTS to options to pass to lcgdict (e.g. "--deep --pool"). See example.
<Use name=Xyz/Foo>, <Use name=Dictionary/DictionaryGenerator> (the former is the package itself to get its include dir and library, which the dictionary library must link against)
Here is an example:
<Use name=Xyz/Foo> <Use name=Dictionary/DictionaryGenerator> DICT_FILES = $(LOCALTOP)/$(THISDIR)/../test/simple/simple.h simple_h_DICT_OPTS = --select=$(LOCALTOP)/$(THISDIR)/selection.xml
The creating a SEAL module (refer to module HowTo) is desired for enabling the automatic loading of the dictionary library when a class definition is required add few lines in the BuildFile
<Use name=Xyz/Foo> <Use name=Dictionary/DictionaryGenerator> include $(LOCALTOP)/config/module.mk DICT_FILES = $(LOCALTOP)/$(THISDIR)/../test/simple/simple.h simple_h_DICT_OPTS = --select=$(LOCALTOP)/$(THISDIR)/selection.xml -c capabilities.cpp files += capabilities.cpp
To facilitate and automate the creation of dictionary libraries for your packages a set of CMT patterns have been made available from the SEAL interface package. The requirement file looks as follows:
use SEAL v* apply_pattern lcg_dictionary dictionary=MyPackage \ headerfiles=../dict/MyClass.h \ selectionfile=../dict/selection.xml \ options="-c capabilties.cpp"
The result will be a dictionary shared library called MyPackageDict.so[.dll]
In large projects consisting of many C++ packages is common practice to generate more that 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 ReflectionBuiler package have protections against defining the dictionary of a class more than once, in general, should be avoided. The main reasons are:
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.