What's in an add-on?
An add-on is a specification of pieces of a build environment. This is made up of:
OS component models to be evaluated, the results of which will be merged into ./components
Bridge models to be evaluated, the results of which will be merged into .
- Bridge specialization parameters to be passed to a bridge model when it is called
Libraries to be included in ./libs
A binding of other values to be merged into .
An add-on can also specify prerequisite add-ons which it depends upon. (For example, the C++ add-on usually depends on the C add-on as some pieces are shared between them.)
An add-on is a function, usually a Vesta SDL model file, which can be passed to the env_build function provided by std_env.
Here are some example add-on models from the Debian sarge i386 std_env:
lex - lexical analyzer generator
The basics libraries used by Vesta
The Vesta libraries
The zlib compression library
The lim interpreted language (used by mtex)
The mtex documentation system (used for the Vesta man pages)
yacc - a parser generator
Each add-on must have a specific string which is its name. Normally this is the name of the add-on model without the ".ves" extension. Having unique names makes it possible to prevent the same add-on when multiple add-ons depend on them as prerequisites. (See the description of prereqs below.)
Add-on Model Result
An add-on model must return a binding. That binding may contain zero or more of the following names:
Any other names in the result of an add-on model are currently ignored.
If present, the value of component_models must be a binding of one or more OS component models. Each of these will be evaluated with the results being overlayed together to form ./components in the final build environment.
If present, the value of bridges must be a binding of one or more bridge models. Each of these will be evaluated, with the results being recursively overlaid into ..
The name of each bridge model in this binding is significant. If the same name is also present in bridge_params, then the associated value from bridge_params will be passed as the first argument to the bridge model (i.e. as the value of .).
If present, the value of bridge_params must be a binding of parameters to be passed to bridge models when they are called. The names in this binding must match the names in bridges.
It's worth noting that an add-on may specify parameters for any bridge, not just bridges it defines. Before calling any bridge models, all bridge models are gathered first as well as all bridge parameters. The bridge parameters from all add-ons are simply combined with recursive overlay (++), so one add-on can augment or even replace bridge parameters specified by another. However, the order in which they are overlaid is not strictly defined.
If present, the value of libs must be a binding of bindings of functions. Each of these functions must return a value of type LibPkgResult. For example, this SDL model would be an add-on returning libs:
All the libs of all the add-ons will be merged together and passed to the walk_libs functions. After evaluating all the leaf functions and placing the results at the same relative path, the result will be placed in ./libs.
For the full details of how libs is processed to produce ./libs, see the definition of the walk_libs function.
If present, the value of prereqs must be a binding of other add-on models. Each of these will be called and have its result used by std_env when constructing the build environmet. However, each named add-on model will only be called once. This makes it possible to seamlessly handle the case where multiple explicitly requested add-ons have the same prerequisite.
If present, the value of env must be a binding. It will be recursively overlaid into . after everything else has been added to the build environment (i.e. at the end of env_build). This is a sort of "escape hatch" which allows an add-on to arbitrarly augment or replace pieces of the build environment.
When combining the results from different add-ons, checks are performed for name conflicts. This is to prevent, for exmaple, one add-on from and silently replacing a bridge provided by another. (The real intent is to prevent this happening accidentally, and to provide a more helpful error message than the _append primitive function.)
Specifically, the cases which will result in an error message are:
If multiple add-ons return component_models with overlapping names
If an add-on returns component_models with names of default components
Each std_env can include some OS components by default even with no add-ons. Usually these are just the very basic filesystem components needed to load and run programs (such as a run-time loader/linker and basic shared libraries needed by most/all executables).
If multiple add-ons return bridges with overlapping names
If an add-on returns bridges with names of default bridges
Each std_env can also have default bridges. Usually this is just generics.
If multiple add-ons return libs which overlap at the leaf level
Overlaps in the first level of binding are fine. For example, often multiple add-ons will have a "c" sub-binding in their libs, as there are quite a few C libraries.
For the full details of how name conflicts are detected and presented as errors, see the relevant code in env_build which loops over the addons and gathers all component models, bridge models, and libraries.
Note that name conflicts are allowed in other places:
The env from each add-on is simply overlaid into .
The bridge_params form all add-ons are simply combined
The prereqs may of course overlap, but any add-ons with the same name as ones which have already been processed are simply ignored.