To create different variants of the same feature, but avoid code duplications within plugins, you have multiple options\+:


\begin{DoxyItemize}
\item Define a needs clause in a \href{/home/jenkins/workspace/libelektra-release/doc/CONTRACT.ini}{\tt contract} and reuse another plugin as it is. This should be preferred for filter and validation tasks.
\item Have common code together in a helper library (or core library), see the C\+Make function {\ttfamily add\+\_\+lib} for creating such a library (in the folder libs). This should be used for rather common functionality that might be useful for many plugins or even applications.
\item Have configuration for plugins (See \href{https://doc.libelektra.org/api/master/html/group__plugin.html}{\tt elektra\+Plugin\+Get\+Config()} and dynamically switch with {\ttfamily if} according to the configuration. This should be preferred when you want to (de)activate some features of a plugin at run-\/time.
\item Or use compilation variants to compile the plugin code multiple times with different {\ttfamily C\+O\+M\+P\+I\+L\+E\+\_\+\+D\+E\+F\+I\+N\+I\+T\+I\+O\+NS} (that are Macro definitions). This should be preferred when different macro definitions lead to different plugins. It should especially be used when the resulting plugins have different dependencies\+: it is possible to have different {\ttfamily L\+I\+N\+K\+\_\+\+L\+I\+B\+R\+A\+R\+I\+ES}.
\end{DoxyItemize}

The advantage of compilation variants are\+:


\begin{DoxyItemize}
\item No run-\/time overhead
\item Can be used during bootstrapping (when no configuration is available)
\item Different compilation variants can be built at once (no recompilation with different C\+Make flags required)
\item Different compilation variants can have different dependencies
\item Different compilation variants can be mounted without {\ttfamily \#refnames}
\end{DoxyItemize}

To use compilation variants, add your plugin in the C\+Make Cache Variable {\ttfamily P\+L\+U\+G\+I\+NS} multiple times. Then there can be an arbitrary number of variants. As naming convention you should have a base name with an additional variant appended with underscore, e.\+g.\+:


\begin{DoxyCode}
myplugin\_varianta;myplugin\_variantb
\end{DoxyCode}


In the C\+Make\+Lists.\+txt of your plugin, you have two options. Option (A)\+: When you can easily enlist every variant you simply list all plugins one after the other ({\itshape outside of} {\ttfamily if (D\+E\+P\+E\+N\+D\+E\+N\+C\+Y\+\_\+\+P\+H\+A\+SE)})\+:


\begin{DoxyCode}
add\_plugin(myplugin\_varianta
        SOURCES      <your sources for varianta here..>
        COMPILE\_DEFINITIONS   VARIANTA ELEKTRA\_VARIANT=varianta
        LINK\_LIBRARIES <libraries for varianta>
        )
add\_plugin(myplugin\_variantb
        SOURCES      <your sources for variantb here..>
        COMPILE\_DEFINITIONS   VARIANTB  ELEKTRA\_VARIANT=variantb
        LINK\_LIBRARIES <libraries for variantb>
        )
\end{DoxyCode}


Option (B)\+: If you cannot enlist every possible compilation variant, you can iterate over all P\+L\+U\+G\+I\+NS and check which names are requested. Then you create a plugin for every name that matches\+:


\begin{DoxyCode}
foreach (plugin $\{PLUGINS\})
        if ($\{plugin\} MATCHES "myplugin\_.*")
                # somehow process the variant names and include
                # or change sources and compile definitions
                # based on that.
                add\_plugin($\{plugin\}
                SOURCES      <your sources here..>
                COMPILE\_DEFINITIONS   <definitions here..>
                        ELEKTRA\_VARIANT=$\{plugin without prefix\}
        LINK\_LIBRARIES <libraries for variantb>
        if ($\{plugin\} MATCHES "ALL")
                # handle categories of plugins
                add\_plugin(myplugin\_all1, ...)
                add\_plugin(myplugin\_all2, ...)
\end{DoxyCode}


For the categories such as {\ttfamily A\+LL}, however, you need to automatically append (using {\ttfamily add\+\_\+plugin}) a useful set of plugins.

Note that every plugin needs to have {\ttfamily E\+L\+E\+K\+T\+R\+A\+\_\+\+V\+A\+R\+I\+A\+NT} differently set in {\ttfamily C\+O\+M\+P\+I\+L\+E\+\_\+\+D\+E\+F\+I\+N\+I\+T\+I\+O\+NS}, otherwise you will get a linker error that {\ttfamily libelektra\+\_\+$<$pluginname$>$\+\_\+\+L\+T\+X\+\_\+elektra\+Plugin\+Symbol} has multiple definitions.

Now every public function of the plugin conflicts with itself. To avoid that, you can use\+:


\begin{DoxyItemize}
\item static functions, but they are only visible within one file. This should be preferred, when possible.
\item use helper libraries using {\ttfamily add\+\_\+lib} to share code between compilation variants (only if code is also potentially useful for other plugins/applications)
\item Get a unique name for every variant using the macro {\ttfamily \hyperlink{group__plugin_gacb05c902e4014535589db4193da87460}{E\+L\+E\+K\+T\+R\+A\+\_\+\+P\+L\+U\+G\+I\+N\+\_\+\+F\+U\+N\+C\+T\+I\+O\+N(myplugin, open)}} where myplugin is the name of the plugin and the second argument is how the function should be called.
\item Including a readme for every variant (with {\ttfamily \#ifdef} for different text) using the macro {\ttfamily \#include \hyperlink{group__plugin_gabdcb97b05a83130c32bbde75db80fc50}{E\+L\+E\+K\+T\+R\+A\+\_\+\+R\+E\+A\+D\+M\+E(myplugin)}}
\end{DoxyItemize}

As a summary, you can have many plugins build out of the same source. Using {\ttfamily pluginname\+\_\+variantnames} many plugins will be compiled, each with other {\ttfamily S\+O\+U\+R\+C\+ES} or {\ttfamily C\+O\+M\+P\+I\+L\+E\+\_\+\+D\+E\+F\+I\+N\+I\+T\+I\+O\+NS} and even {\ttfamily L\+I\+N\+K\+\_\+\+L\+I\+B\+R\+A\+R\+I\+ES}\+: If you, e.\+g. just set the variants name as macro you can use


\begin{DoxyCode}
\textcolor{preprocessor}{#ifdef varianta}
\textcolor{preprocessor}{#endif}
\end{DoxyCode}


within the code and can have two plugins\+: one (called {\ttfamily myplugin\+\_\+varianta}) compiled included the {\ttfamily \#ifdef} the other (base variant called {\ttfamily myplugin}) without.

Currently compilation variants are used in \href{https://master.libelektra.org/src/plugins/resolver/resolver.c}{\tt the resolver plugin}. 