Building Benben

These instructions will explain how to build Benben from source. Benben is written in Common Lisp, and building it is very different from building a C, Crystal, or Rust program, so please read these instructions carefully.

Note that these instructions are for the trunk and the upcoming v1.0 release planned for late 2026. If you want to build v0.7.1 or earlier, please consult Building Benben (old) instead.

If you have trouble, please stop by the Official Benben Matrix Room. We'll be glad to help!

Dependencies

There are four conceptual sets of dependencies:

  1. A Common Lisp implementation (SBCL).
  2. C/C++ libraries.
  3. Reika.
  4. Git and Fossil.

You'll need SBCL, preferably a recent version. SBCL 2.3.11 or later is required, and SBCL 2.5.x or later is recommended. Older SBCL versions may work, but are not officially supported. Other Lisp implementations will NOT work, are NOT supported, and will NOT be supported in the future.

Your copy of SBCL will need these packages included with it, otherwise Benben will not build. These are usually included by default, especially if you install SBCL using your system's package manager:

  • sb-posix
  • sb-thread

These are likely good to have as well, and will probably be included if you install using your system's package manager:

  • sb-unicode
  • sb-simd (on x86-64 platforms)

You can test for these by starting SBCL and typing (require 'sb-posix), replacing the sb-posix part as-needed.

C/C++ Dependencies

Required C/C++ libraries:

  • libzstd
  • S-Lang (2.3.2 or higher)
  • libmpg123 (1.29 or higher)
  • libxmp (4.6.0 or higher recommended)
  • libsidplayfp (2.1.0 or higher recommended)
  • libwavpack (5.0 or higher recommended)
  • libopus (1.3.0 or higher recommended)
  • libao (1.2.0 or higher recommended)
  • libremicsid

Optional C libraries:

  • libasound (only when the ALSA driver is enabled)
  • libout123 (only when the out123 driver is enabled)

Some of the Quicklisp-installable Common Lisp dependencies may have additional C/C++ library requirements and are not listed here.

Important: static libraries are not supported.

Reika

Reika is a dependency manager and build initiator that is written in Crystal. It vastly simplifies the handling of all the Common Lisp dependencies for Benben. Its homepage has information on how to build Reika. Don't worry, it's easy, all you need is Crystal. After you build Reika, place its binary somewhere in your $PATH or where you can find it.

Optional Dependencies Needed for Building

These programs are only needed if you want to build the manual.

  • rst2man
  • gzip
  • texi2any

A Special Note About the C/C++ Dependencies

SBCL binaries behave differently than, say, C or Crystal binaries when it comes to shared libraries.

For the C/C++ dependencies, it is highly recommended that they be installed where the dlopen() function can find them. If you install these dependencies from your system's package manager, then you're likely fine and can move on to the next section.

The dlopen() function is used by the Lisp system to load shared libraries both at build time, and at run time. See man 3 dlopen for information on where dlopen() searches for shared library files. Usually this means one of the directories listed in the $LD_LIBRARY_PATH environment variable.

If libraries are not installed where dlopen() can automatically find them, then you must specify the path with the $LD_LIBRARY_PATH environment variable both at build time, and every time you run Benben. This information is not stored in the binary. For example:

# When building Benben
LD_LIBRARY_PATH="/path/to/so/directory:$LD_LIBRARY_PATH" ./build.sh <build options...>

# And then when running it
LD_LIBRARY_PATH="/path/to/so/directory:$LD_LIBRARY_PATH" benben <music files>

So if (as an example) you install libremicsid into /home/user/libs, then the $LD_LIBRARY_PATH environment must include /home/user/libs, and this must be set both when you build Benben, and every time you run it. You may want to set the environment variable in your shell's startup script (e.g. ~/.bashrc or similar) to make it easy.

tl;dr: make sure the C/C++ libraries are in one of the directories listed in your $LD_LIBRARY_PATH environment variable. When in doubt, the safest bet for most Linux distributions is to install them into /usr/lib.

A Note for Package Maintainers

It's highly recommended you clear out your fasl cache prior to building Benben. This will ensure Benben gets built with the correct compiler policies applied. A common way to do this is to run rm -rf ~/.cache/common-lisp/ prior to running the build script.

Getting Benben's Sources

Benben is hosted on a Fossil repository, and cloning it is very simple:

$ fossil clone https://chiselapp.com/user/MistressRemilia/repository/benben/
$ cd benben

Building Benben with Reika

Reika vastly simplifies building Benben. To start, do reika update from the directory where you cloned Benben. This will tell Reika to pull in all the Common Lisp dependencies that are needed and store them in the deps/ directory.

After that, just run reika build --opt-mode release. You will have a binary in the bin/ directory.

Important: Do NOT strip the resulting binary. It will not function if you do. Have I mentioned Common Lisp binaries behave differently?

You can run reika build --help to see a list of available options. In many cases you won't need to use any of them, though it will allow you to customize the build. However, if your copy of SBCL does not include the SB-SIMD package, you're on a non-x86-64 platform (e.g. ARM AArch64), or you're on a CPU older than Intel's Broadwell microarchitecture, then you will have to pass the --no-simd option to Reika. This will result in a slightly slower binary.

Building remote-benben with Reika

Just run reika build -t remote. The binary will be in the bin/ directory. You may wish to add the --compress option for this one to make the binary a bit smaller.

Building the Manual with Reika

Just run reika build -t manual. The manpage will be in man/, while the PDF and HTML versions will be in man/texi/.

Updating to a Newer Version

If you want to update to a new version of Benben, start out by doing a fossil sync to pull in changes in the repository. After this you have four options:

  1. Update to a specific version. In this case run fossil tag list to see a list of tags in the repository. Releases are tagged like v0.7.1 or v1.0.0. Choose a tag then do fossil checkout <that tag>.
  2. Use the latest trunk code. For this, just do fossil checkout trunk.
  3. Use a feature branch. New features are (usually) developed in their own branch. Run fossil branch to get a listing of these, then do fossil checkout <branch name> to switch to that branch.
  4. Use a specific checkout. Just run fossil checkout <hash id> to check out a specific checkout. You can run fossil timeline to see a short list of recent checkouts, or do fossil ui to open up the repository in your browser to look around. Welcome to the awesomeness that is Fossil :D

After this, run reika force-update to ensure your dependencies are up-to-date. Then do your normal reika build ... stuff.

What to Do When it Doesn't Work

First, make sure you're at the latest version of Reika. It's still pretty new and is getting adjustments from time to time. Next, make sure you have all of the C/C++ libraries installed.

If you get an error like "Package ASDF does not exist", then you may have an SBCL that (for whatever reason) does not ship with ASDF internally. This is a Lisp component that loads libraries into the Lisp compiler, and it normally comes packaged with SBCL. When you run into this error message, try downloading the source code for ASDF (it's just one file), then build Benben like this:

reika build --asdf <path to that asdf.lisp file> --opt-mode release

That tells Reika to setup the Lisp compiler so that it uses an external copy of ASDF.

When all else fails, hop on over to the official Matrix room and ask for help. You can ping Remilia if you need. Or, email Remilia:

zremiliaz@postzeoz.jpz (My real address does not contain Z's)

Advanced Stuff

Everything below here is only of interest if you're wanting to work on Benben.

Hacking On or Developing Benben

If you want to work on Benben, then you'll probably need to set up your Lisp environment so that it can find all of the dependencies. How you do this is up to you, but one option is to tell ASDF to look in the deps/ folder that Reika creates. That's a bit beyond the scope of this document, but you can find info about this here.

There are some startup scripts in the startup-scripts/ directory that may help you get up and running. These all assume that ADSF can find the Lisp dependencies.

Debug Stuff

Benben contains various internal debugging instruments that may be useful if you're hacking on the code. Here are some tips for debugging:

  • Benben's MAIN function is designed to be callable from the REPL as if you're on the command line, where each argument is a string. The --help and --version arguments even work. For example, I (Remilia) do this a lot: (benben:main "-L" "--ui" "minimal" "/mnt/storage/music/Industrial/KMFDM/kmfdm.jspf")
  • Benben's Minimal UI is great for debugging most of the code. All messages get logged to your REPL's output. In fact, that's why and how the Minimal UI started life.
  • To debug Benben's Original UI code, you'll want to start your Lisp process with the start-with-swank.sh file. This will load Benben, then start up a new Swank listener that you can connect to via Slime or similar. The script takes a few options as well, so check ./start-with-swank.sh --help.
  • Benben (and SatouSynth) redefines CL-SDM's DEFINE-TYPED-FN function and MUFFLING macro to better aid in debugging. Look at src/lib/redefines.lisp to see how they differ.
  • If you want to always invoke the Lisp debugger every time a player has an error, push :BENBEN-DEBUG-PLAYER-ERRORS onto *FEATURES* and recompile Benben. This will occur within a HANDLER-BIND that exists within the main PLAYER-MANAGER's SUBSYSTEM-START method.
  • Unless you're debugging the Original UI, you'll almost certainly want to load the startup-scripts/benben-debug.lisp into your REPL. This sets up most of the debugging options by pushing these symbols onto *FEATURES*: :REMIAUDIO-EXTRA-CHECKS, :NEVER-APPLY-BLOCK-COMPILATION, :SATOU-NEVER-INLINE, :SATOU-DEBUG, :SATOU-VERBOSE-DEBUG, :BENBEN-NEVER-INLINE, :BENBEN-DEBUG, :BENBEN-VERBOSE-DEBUG.