|
Plugins are a way to tremendously extend SmartEiffel's capacities by adding libraries that look, feel and behave as native libraries (the SmartEiffel-provided libraries). They are an extension of the well-known Eiffel mechanism: externals.
Plugins aim at back-end independance: it means that potentially, the same library could be used with either compile_to_c or compile_to_jvm. Note that we envision other back-ends in the future, so the plugins system is really an important one.
How does it work? |
There are two related parts in a plugin:
The Eiffel side is pure Eiffel code, but uses external statements that access to the external side of the plugin.
The compiler maps the external calls to the Eiffel parts, using helper files provided by the plugin.
The Eiffel side |
The Eiffel side of the plugin is made of external statements. The require syntax is:
feature my_plugin_feature is external "plug_in" alias "{ location: "/path/to/my/plugins/directory" module_name: "my_plugin" feature_name: "feature" }"Of course, a feature can take arguments and return a result! (That's an external after all). Beware that you should only pass and return really basic types to an external feature: either a basic expanded object (INTEGER, BOOLEAN and so on) or a POINTER (the classic use is a_string.to_external).
The location points to the directory wher you store one or more of your plugins. It may contain environment variables (either genuine environment variables, or variables defined in the [Environment] section of your configuration file). For example, the standard libraries of SmartEiffel are defined with the following location:
location: "${sys}plugins"
The module_name is indeed the name of the plugin. It should be a subdirectory of the location and contain a directory per backend (e.g. "c" for the C backend and "java" for the Java backend). The contents of each backend-subdirectory depends on the backend, and will be explained in further details below.
At last, the feature_name is the name of the feature, function, method or whatever is called in that backend (e.g. C backend calls a function, whereas a Java backend calls a method.) Whatever; it's a feature.
The C backend |
The C backend expects files in a subdirectory of your plugin named "c". The recognized files are:
The .c files and then .h files are included in alphabetical order. It helps if some dependancy management has to take place between the files of your plugin.
The libs file and the paths file use a
.INI-like syntax (the same syntax as the configuration file).
The recognized sections are those named after the operating system the
plugin is compiled with, maybe suffixed by the used C compiler (system
and compiler are separated by a dot). The known operating systems are
the ones used by the os key in the configuration file. The known compilers
are the ones used with c_modes.
The keys are merely informative, but the values are used by the
generated command line (resp. using -l and -L or
whatever equivalent).
For an example, look at the Vision configuration files.
The Java backend |
to be written