Skip to content

Building an external Plugin

This page will help you through the process of building an external plugin to be used in Paramita.

Two methods are shown:

  • Using the CLI utilities provided by Paramita
  • Build the plugin manually

Danger

Never run these commands on untrusted sources. The compile process might run arbitrary commands in your machine.

Always check for the sources before running them.

Prerequisites

Before building any plugin, ensure you have:

  • A C++ compiler supporting at least C++17 (e.g., GCC, Clang, MSVC)
  • CMake (version 3.15 or later)
  • The paramita Python package
  • The plugin source code (either from the paramita-plugins repository or your own implementation)

Tip

While this how-to builds a SAT Solver as an example, the process is the same for the other types of plugins.

Using the CLI

Paramita provides a command‑line interface that automates the entire fetch‑configure‑build‑install cycle. It still gives you the flexibility to pass CMake flags, set environment variables, and choose install locations, but without the need to remember each individual command.

Currently the CLI for the plugins support the following commands:

  • paramita plugins list: shows plugins already installed in the default search directories.
  • paramita plugins build <builder> <source-url> [options]: builds a plugin from a source URL.

To build a plugin, provide the builder and a source URL. The URL can point to a full repository or a specific subdirectory; the CLI fetches only what is needed.

Note

Currently, only the cmake builder is supported.

For example, to fetch and build CaDiCaL 3.0.0:

paramita plugins build cmake 'git+https://codeberg.org/paramita/paramita-plugins.git#sat-solvers/cadical-3.0.0'

The git+https://codeberg.org/paramita/paramita-plugins.git points to the sources, and the part after # (in this example, sat-solvers/cadical-3.0.0) is the URL fragment, which is interpreted by Paramita as a subdirectory in the sources pointed by the URL.

Paramita uses urllib to parse these URLs. Some of the most common URL formats are these:

  • file:// points to a local file.
  • git+ssh:// points to a git repository using SSH as authentication.
  • git+https:// points to a git repository using HTTPS as authentication.
  • https:// points to an HTTPS resource.

By default, if only the fragment part is specified, it will point to the paramita-plugins repository. For example, the previous command could have been:

paramita plugins build cmake '#sat-solvers/cadical-3.0.0'

After running this command, the plugin will be installed in a default location, where we can load it using its name:

from paramita.solvers import SatSolver

s = SatSolver.from_name("Cadical300")

Tip

If you used a custom install directory (see below), load by full path or add that directory to the PARAMITA_PLUGIN_PATH environment variable so that from_name can find it.

You can see all the installed plugins in the default locations using paramita plugins list:

$ paramita plugins list

======================================= Paramita::MaxSatSolver =======================================
----------------------------- /home/vscode/.local/share/paramita/plugins -----------------------------
EvalMaxSAT2022  

====================================== Paramita::PbToCnfEncoder ======================================
----------------------------- /home/vscode/.local/share/paramita/plugins -----------------------------
AdderEncoder            BinaryEncoder           IncrAdderEncoder        NestedEncoder           
BddEncoder              BinaryMergeEncoder      IncrCardEncoder         PairwiseEncoder         
BestEncoder             CardEncoder             IncrSwcEncoder          SortingNetworksEncoder  
BimanderEncoder         CommanderEncoder        KProductEncoder         SwcEncoder              

======================================== Paramita::SatSolver =========================================
----------------------------- /home/vscode/.local/share/paramita/plugins -----------------------------
Cadical300 

The list of paths where Paramita will look for plugins is the following:

  1. The PARAMITA_PLUGINS_PATH environment variable.
  2. The ${XDG_DATA_HOME}/paramita/plugins directory. By default, ${XDG_DATA_HOME} is set to ${HOME}/.local/share.
  3. The ${HOME}/.paramita/plugins directory. This is a legacy fallback, we recommend to use any of the previous options.

Customizing the build process

The CLI supports a number of options to customise the build:

Option Description
-i, --install-dir <path> Changes where the plugin will be installed. By default it uses a default location
-w, --work-dir <path> Build directory (a temporary directory is created if not specified)
-j, --jobs <N> Number of parallel jobs (default: 1)
-v, --verbose Show detailed output
-n, --dry-run Preview commands without executing
--no-clean Keep work directory after build
-e, --env KEY=VALUE Set environment variable. It can be specified multiple times
-D, --define KEY=VALUE Pass a CMake cache variable. It can be specified multiple times. This is equivalent to the -D flag for CMake, and can be used to set build type, compiler flags, etc.
--generator <name> CMake generator (equivalent to the -G option for CMake)
--target <name> Build a specific target instead of the default

For instance, to build with optimisations and extra warnings, and install to a custom directory:

paramita plugins build cmake '#sat-solvers/cadical-3.0.0' \
    --define CMAKE_BUILD_TYPE=Release \
    --define CMAKE_CXX_FLAGS="-Wall -Wextra" \
    --install-dir ~/my-plugins \
    --jobs 4

Manually

The manual approach gives you the most fine‑grained control over the build process. You run each step (fetch, configure, build, install) yourself, which is useful for development of plugins.

We will focus on a CMake project, but the steps are extrapolable to other build systems.

First, start by fetching the source. For example, we can start by fetching the sources for the CaDiCaL 3.0.0 plugin:

git clone https://codeberg.org/paramita/paramita-plugins
cd paramita-plugins

In this repo, plugins are organised by type. For example, SAT solvers are under sat-solvers, MaxSAT solvers under maxsat-solvers, etc.

To build a specific plugin, we can point CMake to its sources:

cmake -B tutorial-build -S sat-solvers/cadical-3.0.0 -DCMAKE_INSTALL_PREFIX=./tutorial-install

You can pass any CMake option here: -DCMAKE_BUILD_TYPE=Release, -DCMAKE_CXX_FLAGS="-Wall", etc.

For instance, to enable debug symbols:

cmake -B tutorial-build -S sat-solvers/cadical-3.0.0 \
      -DCMAKE_INSTALL_PREFIX=./tutorial-install \
      -DCMAKE_BUILD_TYPE=Debug

Now compile the plugin:

cmake --build tutorial-build --config Release

Note

The --config flag is only needed for multi‑configuration generators (like Visual Studio). On Unix‑like systems, you can usually omit it.

Finally, install the plugin to the prefix you chose:

cmake --install tutorial-build
or, if you did not use -DCMAKE_INSTALL_PREFIX when configuring the project:
cmake --install tutorial-build --prefix ./tutorial-install

After installation, the shared library (.so on Linux, .dylib on macOS, .dll on Windows) will be placed in the appropriate subdirectory on the tutorial-install directory.

Loading the plugin

Once built, you can load the plugin in Python either by its full path:

from paramita.solvers import SatSolver
solver = SatSolver.dynamic_load("./tutorial-install/lib/paramita/plugins/libsat-solvers-cadical-300.so")

Or, if the install directory is already in Paramita’s default search paths (e.g., ~/.local/share/paramita/plugins/), you can simply use from_name:

solver = SatSolver.from_name("Cadical300")

Rebuilding after changes

If you modify the source, you can rebuild using cmake --build tutorial-build without requiring to reconfigure the project (unless you changed the CMake-related files or some build options).

Which approach should you use?

The CLI is recommended for most users. It abstracts away the steps, handles fetching, and ensures the plugin ends up in a standard location, while still allowing full customisation with the extra flags in the CLI.

The manual approach is useful when you need to see every detail, during development (e.g. debugging a build, applying patches), or when you require a build system other than CMake.

Next steps

After building your plugin, you can: