What is the format of module.export?

API_MODULESHORT_NAME				API-owner

	Description of API.

	Defines       : define-list
	Depends on    : feature/tweak/define/api-list
        Conflicts with: tweak/api-list

Examples of API-names: API_HC_MESSAGEHANDLER and API_UTIL_ADVANCED_OPVECTOR.

API-owner
The API owner is the name of the developer responsible for the API. If this value is set to "deprecated" it means the API is no longer available. The API cannot be imported by any other modules, and an error will be produced if tried. Mandatory.
Description
Text describing the API. It must state clearly what the API does and when it can and shall be imported. This description will be read by both module owners and branch managers for products. Can span several lines. Mandatory.
Defines
A list of preprocessor defines separated by "," and/or "and". These will be defined if the API is imported. Mandatory.
Depends on
List of features/tweaks/defines/apis which this API depends on. The features/tweaks/defines/apis must be turned on to be able to import this API. If they are not and someone tries to import the API, an error is produced. The items are separated by "," and/or "and". "nothing" is a valid value. Not mandatory, if left out it means "nothing".
Conflicts with
List of tweaks and apis which cannot be tweaked/imported if this API is imported. The items are separated by "," and/or "and". "nothing" is a valid value. Not mandatory, if left out it means "nothing".

Example of an exported API:

API_UTIL_ADVANCED_OPVECTOR			markus

	Enables an extended API to OpVector which allows
	Sort(), Search(), Add(), Subtract() and Intersect().

	Defines   : ADVANCED_OPVECTOR
	Depends on: nothing

Here the util module exports the API API_UTIL_ADVANCED_OPVECTOR which turns on the define ADVANCED_OPVECTOR. There are no dependencies for this API, which means it can always be imported.

What is the format of module.import?

API_MODULESHORT_NAME				Import-responsible

	Description of why the API is imported.

	Import if: feature/tweak/define/api-list
Import-responsible
The person responsible for the import of the API. This is different from the API owner (but may ofcourse be the same person). Mandatory.
Description
Text describing why the API is imported. Can span several lines. Mandatory.
Import if
List of features/tweak/defines/apis which are required to be turned on for the API to be imported. Several "Import if"-lines can be used to describe an OR-condition for when to import the API. Can be set to "always" if this API for some reason always shall be imported. Mandatory.

Example of API-import with several import-rules:

API_UTIL_ADVANCED_OPVECTOR			someone

	The advanced OpVector functions Sort() and Subtract() are used by search_engine.
	Ecmascript uses the advanced OpVector function Add().

	Import if: FEATURE_SEARCH_ENGINE, FEATURE_DISK
	Import if: FEATURE_ECMASCRIPT

In the example, the preprocessor rule to when to include the API becomes:

#if (FEATURE_SEARCH_ENGINE == YES && FEATURE_DISK == YES) || FEATURE_ECMASCRIPT == YES

The same effect can be created by duplicating the whole API-section several times, like this:

API_UTIL_ADVANCED_OPVECTOR			someone

	The advanced OpVector functions Sort() and Subtract() are used by search_engine.

	Import if: FEATURE_SEARCH_ENGINE, FEATURE_DISK

API_UTIL_ADVANCED_OPVECTOR			someone

	Ecmascript uses the advanced OpVector function Add().

	Import if: FEATURE_ECMASCRIPT

The last method might sometimes be preferable since it makes it possible to easier document the reason for the import and the owner can be different.

How do I change or introduce an API in different mainline configurations

The build-system can be told compile the "current" or "next" mainline configuration. Each mainline configuration has an associated version number. If the setup script finds the file module.export.version or module.import.version, it parses that file instead of the module.export or module.import. Thus an API can be added or changed for only one mainline configuration.

It is recommended to only keep the versiond file module.export.version or module.import.version for the "current" mainline configuration and use the default file for the "next" mainline configuration. Thus on switching the mainline version numbers, the versioned file can be removed and only the not-versioned file remains.

Example: If the "current" mainline version is 2.3 and the "next" mainline version is 2.4, and one module needs to export different APIs for the different mainline configurations, it can use two files:

module.export.2.3
exports all APIs for the "current" = 2.3 mainline configuration.
module.export
exports all APIs for the "next" = 2.4 mainline configuration.

So if you want to add or change an API for the "next" mainline configuration, look for the version number of the "current" mainline configuration in modules/hardcore/version.ini. If the file module.export.current_version exists, you can edit module.export.
Otherwise copy module.export to module.export.current_version, add it to the repository and modify module.export. Thus the "current" mainline configuration remains unchanged.

The same applies if you want to add or change an API for the "current" mainline configuration: look for the version number of the "current" mainline configuration in modules/hardcore/version.ini. If the file module.export.current_version exists, you can edit it
Otherwise copy module.export to module.export.current_version, add it to the repository and modify it. Thus the "next" mainline configuration remains unchanged.

How do I import a new non-released API?

You may at some point want to release a version of your module that uses some new API in another module, which has not yet been introduced.

The easiest thing is to import the API as if it existed. It will generate a warning from the script and the API will not be imported until it has been exported.

Can API's depend on each other?

You can not have circular dependencies. If you have, it will be detected at compile time and generate an error. If you find yourself in a situation that you might need this, feel free to contact the module owner. Maybe we can implement support for circular dependencies if there are good reasons for it.