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:
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:
- Update to a specific version. In this case run
fossil tag listto see a list of tags in the repository. Releases are tagged likev0.7.1orv1.0.0. Choose a tag then dofossil checkout <that tag>. - Use the latest trunk code. For this, just do
fossil checkout trunk. - Use a feature branch. New features are (usually) developed in their own
branch. Run
fossil branchto get a listing of these, then dofossil checkout <branch name>to switch to that branch. - Use a specific checkout. Just run
fossil checkout <hash id>to check out a specific checkout. You can runfossil timelineto see a short list of recent checkouts, or dofossil uito 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
MAINfunction is designed to be callable from the REPL as if you're on the command line, where each argument is a string. The--helpand--versionarguments 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.shfile. 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-FNfunction andMUFFLINGmacro to better aid in debugging. Look atsrc/lib/redefines.lispto see how they differ. - If you want to always invoke the Lisp debugger every time a player has an
error, push
:BENBEN-DEBUG-PLAYER-ERRORSonto*FEATURES*and recompile Benben. This will occur within aHANDLER-BINDthat exists within the mainPLAYER-MANAGER'sSUBSYSTEM-STARTmethod. - Unless you're debugging the Original UI, you'll almost certainly want to
load the
startup-scripts/benben-debug.lispinto 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.