nbdkit-cc-plugin(3)

πŸ’œ nbdkit-cc-plugin β€” write tiny nbdkit plugins in inline C (and other languages too, bestie)

okay so first things first, this is a page from the nbdkit manual set (section 3, the library/plugin-function corner of the world, iykyk) ✨


🌸 NAME 🌸

nbdkit-cc-plugin β€” write small nbdkit plugins in inline C (and other languages), no cap fr fr πŸ’…


✨ SYNOPSIS ✨

nbdkit cc /path/to/plugin.c [CC=...] [CFLAGS="..."]
                            [EXTRA_CFLAGS="..."]
                            [other plugin parameters ...]

nbdkit cc - <<'EOF'
... C code ...
EOF

πŸ¦‹ DESCRIPTION πŸ¦‹

okay so picture this: this plugin lets you write small nbdkit(1) plugins in C (plus a few other languages, we'll get there 🫢). When you use this plugin it compiles your source code into a temporary plugin and then just... jumps into your compiled plugin. iconic behavior honestly.

It's somewhat similar to nbdkit-sh-plugin(3), except instead of shell it's C source code. You can also use it to write plugins that are basically "C scripts" β€” yes that's a thing, yes it slaps πŸŽ€

⚠️ Real talk though: this is not the way you normally write nbdkit plugins in C. To understand how to write plugins in C normally, read nbdkit-plugin(3). Don't skip that, bestie, I'm begging 😭

πŸ“ Simple plugin example

Simple plugins from the nbdkit source tree can be compiled and run directly using commands such as:

$ nbdkit cc plugins/example1/example1.c EXTRA_CFLAGS="-I. -Iinclude"

You can also read the source from stdin using -:

$ nbdkit cc - EXTRA_CFLAGS="-I. -Iinclude" \
            < plugins/example1/example1.c

And to replace the compiler flags (full override, we're swapping the whole fit πŸ”₯):

$ nbdkit cc plugins/example1/example1.c \
            CFLAGS="-O3 -mavx2 -fPIC -shared"

🧚 Compiler name and flags

The plugin parameters CC, CFLAGS and EXTRA_CFLAGS (written in uppercase β€” that part matters, lowercase will not hit the same, trust) can be used to control which C compiler and C compiler flags are used.

If not set, the default compiler and flags from when nbdkit was itself compiled from source are used. To see what those were you can do:

$ nbdkit cc --dump-plugin
...
CC=gcc
CFLAGS=-g -O2 -fPIC -shared

The CFLAGS parameter overrides the built-in flags completely. The EXTRA_CFLAGS parameter adds extra flags to the built-in flags. Two different vibes, two different jobs πŸ’«

⭐ Plugin API version

Plugins compiled this way must use the same API version as the cc plugin itself uses. Currently this is NBDKIT_API_VERSION=2.

πŸ’€ C plugin as a self-contained script

You can create a C plugin which is a self-contained script by adding the following lines at the top and ensuring the C source is executable (chmod +x plugin.c):

#if 0
exec nbdkit cc "$0" "$@"
#endif

The script can be run as a command with additional nbdkit flags and plugin parameters, eg:

./plugin.c -f -v
./plugin.c -p 10000 --filter=cow
./plugin.c param=1

🌈 Using this plugin with C++

nbdkit cc CC=g++ source.cpp

C++ plugin scripts can be created similarly to C, but you must add CC=g++ as a parameter to exec nbdkit. Don't forget it or you'll be sad 😭

πŸ¦‹ Using this plugin with OCaml

nbdkit cc CC=ocamlopt \
          CFLAGS="-output-obj -runtime-variant _pic   NBDKit.cmx -cclib -lnbdkitocaml" \
          source.ml

OCaml plugin scripts can be created using this trick:

(*/.)>/dev/null 2>&1
exec nbdkit cc "$0" \
     CC=ocamlopt \
     CFLAGS="-output-obj -runtime-variant _pic   NBDKit.cmx -cclib -lnbdkitocaml" \
     "$@"
*)
(* followed by OCaml code for the plugin here *)

As with C plugin scripts, the file must be executable. See also nbdkit-ocaml-plugin(3). πŸŽ€

🫢 Using this plugin with other programming languages

This plugin can be used with most ahead-of-time compiled programming languages if they can create shared objects (.so files). The only requirement is that the compiler (CC) supports an -o option to write a shared object. That's it, that's the whole gatekeeping situation β€” go wild ✨


πŸŽ€ PARAMETERS πŸŽ€

The script name, or -, must appear as the first parameter. First. Not second. First πŸ‘‘

  • CC=CC β€” override the compiler. See "Compiler name and flags" above πŸ‘†
  • CFLAGS="CFLAGS" β€” override the flags. See "Compiler name and flags" above πŸ‘†
  • EXTRA_CFLAGS="EXTRA_CFLAGS" β€” extra flags added on top of the built-in ones. See "Compiler name and flags" above πŸ‘†

All other parameters on the command line are passed to the plugin. πŸ’…


πŸ”₯ EXAMPLE πŸ”₯

$ nbdkit cc - <<'EOF'
#include <stdint.h>
#include <string.h>

#define NBDKIT_API_VERSION 2
#include <nbdkit-plugin.h>

char data[10*1024*1024];

#define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL

static void *
my_open (int readonly)
{
  return NBDKIT_HANDLE_NOT_NEEDED;
}

static int64_t
my_get_size (void *handle)
{
  return (int64_t) sizeof (data);
}

static int
my_pread (void *handle, void *buf,
          uint32_t count, uint64_t offset,
          uint32_t flags)
{
  memcpy (buf, data+offset, count);
  return 0;
}

static int
my_pwrite (void *handle, const void *buf,
           uint32_t count, uint64_t offset,
           uint32_t flags)
{
  memcpy (data+offset, buf, count);
  return 0;
}

static struct nbdkit_plugin plugin = {
  .name              = "myplugin",
  .open              = my_open,
  .get_size          = my_get_size,
  .pread             = my_pread,
  .pwrite            = my_pwrite,
};

NBDKIT_REGISTER_PLUGIN(plugin)
EOF

look at that. a whole plugin. in a heredoc. we love to see it πŸ₯ΉπŸ’–


πŸ’œ FILES πŸ’œ

  • $plugindir/nbdkit-cc-plugin.so β€” the plugin itself, the main character πŸ’…

Use nbdkit --dump-config to find the location of $plugindir.


🌟 VERSION 🌟

nbdkit-cc-plugin first appeared in nbdkit 1.22. a little baby plugin, now all grown up πŸŽ€


🧚 SEE ALSO 🧚

nbdkit(1), nbdkit-plugin(3), nbdkit-eval-plugin(3), nbdkit-ocaml-plugin(3), nbdkit-sh-plugin(3).

go read those too, bestie, they're literally linked for a reason πŸ“šβœ¨


πŸ‘‘ AUTHORS πŸ‘‘

Richard W.M. Jones β€” the legend, the blueprint πŸ™Œ


Copyright Red Hat


πŸ’€ LICENSE πŸ’€

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

  • Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
  • Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
  • Neither the name of Red Hat nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

okay that's the legal bit, I don't make the rules, I just format them gorgeously πŸ’…

and that's the whole page bestie!! 🫢 this one's nbdkit-1.48.0, dated 2026-08-22, straight from the nbdkit-cc-plugin(3) man page. go compile something cute βœ¨πŸ’–πŸŽ€

πŸ“¦ where this page comes from