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{/doc/CONTRACT.ini}{\texttt{ 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 CMake 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}{\texttt{ 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 COMPILE\+\_\+\+DEFINITIONS} (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 LINK\+\_\+\+LIBRARIES}.
\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 CMake flags required)
\item Different compilation variants can have different dependencies
\item Different compilation variants can be mounted without {\ttfamily \#refnames}
\end{DoxyItemize}\hypertarget{md_doc_tutorials_compilation_variants_autotoc_md3755}{}\doxysection{How to use It}\label{md_doc_tutorials_compilation_variants_autotoc_md3755}
To use compilation variants, add your plugin in the CMake Cache Variable {\ttfamily PLUGINS} 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}{0}
\DoxyCodeLine{myplugin\_varianta;myplugin\_variantb}

\end{DoxyCode}


In the CMake\+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 (DEPENDENCY\+\_\+\+PHASE)})\+:


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

\end{DoxyCode}


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


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

\end{DoxyCode}


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

Note that every plugin needs to have {\ttfamily ELEKTRA\+\_\+\+VARIANT} differently set in {\ttfamily COMPILE\+\_\+\+DEFINITIONS}, otherwise you will get a linker error that {\ttfamily libelektra\+\_\+$<$pluginname$>$\+\_\+\+LTX\+\_\+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 \mbox{\hyperlink{group__plugin_gacb05c902e4014535589db4193da87460}{ELEKTRA\+\_\+\+PLUGIN\+\_\+\+FUNCTION(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 \mbox{\hyperlink{group__plugin_gabdcb97b05a83130c32bbde75db80fc50}{ELEKTRA\+\_\+\+README(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 SOURCES} or {\ttfamily COMPILE\+\_\+\+DEFINITIONS} and even {\ttfamily LINK\+\_\+\+LIBRARIES}\+: If you, e.\+g. just set the variants name as macro you can use


\begin{DoxyCode}{0}
\DoxyCodeLine{\textcolor{preprocessor}{\#ifdef varianta}}
\DoxyCodeLine{\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}{\texttt{ the resolver plugin}}. 