# pcb-rnd - plugin development - API and initialization

Since plugins are managed by puplug, the minimal API a plugin must provide is as defined by the puplug project. This document describes that API with any pcb-rnd aspects included.

A minimalistic example of a plugin's main source file implementation can be found in the plugin template.

## copyright banner

For core plugins the copyright banner is standard and shall not be changed (except for the year and name in the copyright line). All manually written .c files and any non-trivial .h file must have the banner. License: core plugins must be GPL2+.

External plugins can choose a different license banner, but since pcb-rnd is licensed under the GPL, they shall choose a license that is compatible with the GPL for run-time dynamic linking.

## headers and watchdogs

If the plugin consists of multiple source files compiled as separate compilation units (multiple .o files), there will be header (.h) files. The header watchdog #defines shall be PCB_PLUGINNAME_H, unless PLUGINNAME is short and generic and/or conflicts with already existing core or core plugin watchdogs. In that case use PCB_CPLUG_PLUGINNAME_H

For external plugins, always use PCB_EPLUG_PLUGINNAME_H.

## #includes

The first include in any .c file must be "config.h", to ensure configuration time detected libc feature macros are. The .h files shall not include "config.h".

The plugin shall #include pcb-rnd core's "plugins.h" for the mandatory PCB_API_CHK_VER call. This also requires <stdio.h>.

## int pplg_check_ver_pluginname(int ver_needed)

This function is called by puplug before the plugin is initialized. The code that triggered the load may have specified a required API version number in ver_needed and the plugin needs to decide if it can serve all functionality of that version - if so, it should return 0 and initializing the plugin will proceed. How the version number is interpreted is up to the plugin: can be a serially incremented number, a bitfield, a date encoded.

Most pcb-rnd plugins will not need this and can safely return 0 without even checking ver_needed. For pcb-rnd plugins the only situation when using this API makes sense is for external (non-core) lib plugins that other external plugins are likely to depend on.

## void pplg_uninit_pluginname(void)

Called before unloading the plugin. This often happens before quitting pcb-rnd, even for builtin (static linked) plugins, but for a dynamically loaded plugin it can happen any time while pcb-rnd is running.

The plugin needs to free all memory allocated and unregister from all central pcb-rnd infrastructure. The plugin must assume pcb-rnd will not exit after plugin uninitialization.

The rule of thumb is: anything registered in the init() callback must have an unregister call in this uninit() callback.

## int pplg_init_pluginname(void)

Called after the plugin is loaded and version is checked, before any other plugin function or variable is accessed.

The plugin should set up its own infrastructure and register actions, callbacks, hooks, tools, etc. in central infrastructure.

Each plugin is loaded and initialized only once at a time (there are no multiple parallel instances of the same plugin), but it is possible to load-unload the same plugin multiple times during a single pcb-rnd session.

Before the init does anything else, it must issue a PCB_API_CHK_VER. This macro checks for ABI compatibility between the plugin and the core and returns failure on incompatibility (useful in the dynamic plugin load setup).

The init call shall return 0 on success and anything else on failure. After a failure, the plugin is unloaded - without a call to uninit. Thus on failure the init function needs to clean up any effect of partial initialization or registration before returning.

## conventions

These functions are implemented in the main c file of the plugin, which is called pluginname.c. These functions are normally the last ones on the bottom of the file. They are never exposed in header files.