Next: Overview of Reika [Contents][Index]
This manual is for Reika (v0.0.3, 31 December 2025), a dependency manager and build initiator.
Next: Basic Usage, Previous: Reika, Up: Reika [Contents][Index]
Reika is a dependency manager and build initiator, written entirely in the Crystal programming language. That is, it doesn’t perform the actual build/compilation itself, but simply ensures dependencies can be found in-tree, and then initiates the build process. It is primarily intended for Common Lisp projects, though it is not necessarily limited to this language. Projects are defined in a Project File (reika.rbp), and can have both multiple targets and custom options.
Next: Project Files, Previous: Overview of Reika, Up: Reika [Contents][Index]
Reika is built around “commands”, where the command dictates how Reika
behaves. Usually you use the build command, but there are actually a
few different commands. To see a list of commands, run Reika like this:
reika help
Then, to run a command, just replace help with the name of the
command. To see additional help information for that specific command, add
--help after the command name. For example, to see help for the
clean command, run Reika like this:
reika clean --help
Next: Commands, Up: Basic Usage [Contents][Index]
Projects that are designed for Reika will have a project file named reika.rbp in the root of their directory. This file defines how to build the project’s targets.
To build the default target, simply run:
reika build
This will cause Reika to first ensure all needed dependencies are satisfied,
possibly downloading them as-needed. After these have been satisfied, Reika
will start the build. Dependencies will be either Fossil or Git repositories,
so be sure you have both of those installed on your system and somewhere in your
$PATH before running Reika.
Projects can define various options in their Project File. To see if this is the case, run Reika like this:
reika build --help
This will output both Reika’s own help documentation, as well as all of the project’s options and their descriptions. Using these is as simple as passing them as command line options. For example, if you see an option called --with-foo, then you can enable this option like this:
reika build --with-foo
Some options are simple flag options such as in the above example, but others may expect you to provide a value. You can tell that an option expects a value when it’s displayed with an extra “x” after the name. For example, if you see an option called --using-bar x, then you know --using-bar expects a value. To give it one (say the value “69abc”), you can call Reika like this:
reika build --using-bar 69abc
You can specify as many options as you need. All of Reika’s commands are documented in the next section.
Previous: Building a Project Using Reika, Up: Basic Usage [Contents][Index]
helpThis command simply lists all of the available commands, and gives you a brief overview of how to run Reika.
versionThis command shows the current version of Reika and some license information.
updateThis cause Reika to update all dependencies for a project. That is, it ensures
all dependencies are downloaded and that the correct version/tag is checked out
for each one. This will also run post-download commands for all
dependencies that contain that key. If a dependency has already been
downloaded, and a tag/version is not found in the downloaded dependency, you
should try running force-update instead.
force-updateThis cause Reika to update and synchronize all dependencies for a project. That
is, it ensures all dependencies are downloaded, fully synchronized with the
upstream repository, and that the correct version/tag is checked out for each
one. This will also run post-download commands for all
dependencies that contain that key.
buildThis first checks that all of the dependencies are updated and checked out at
the correct version (any post-download command is not run).
Then, this will initiate the build process defined in the Project File.
cleanThis removes any existing files defined in the Project File’s
clean-files key. Only files that exist are removed. When doing
the deletion, Reika does an equivalent of rm -rf, so directories can
also be removed.
Next: How Reika Works, Previous: Basic Usage, Up: Reika [Contents][Index]
Up: Project Files [Contents][Index]
Reika Project Files are written in a format called
RSConf. This format is
similar to both JSON and YAML, and is specifically meant for configuration
files. Anyone familiar with either JSON or YAML should be pretty comfortable
using it. All Project Files must use the filename reika.rbp, and must be
located in the root of your project’s directory.
The following is an example of a fairly simple project file, along with comments giving a brief explanation of the various keys. Don’t worry, these will be explained in depth soon.
name: "Neat Project" ;; Human-readable name, just for metadata
license: "AGPLv3" ;; License of the project, just metadata
;; Authors of this project. Just more metadata.
authors: [
"Remilia Scarlet <remilia@posteo.jp>"
]
;; Files that will be removed when running "reika clean". These are removed
;; with an equivalent to "rm -rf".
clean-files: [
"bin/neat-project"
"bin/" ;; Directories are fine, too
]
;; Defines how to build the project. The key of each element in this key
;; becomes the name of a build target.
build: {
binary: {
;; If you specify a build-file, then this is a Common Lisp Project. This
;; must be a Lisp file, which will be called by the compiler. Put your code
;; to build your binary into it (e.g., calls to SB-EXT:SAVE-LISP-AND-DIE).
;;
;; Only SBCL is supported right now. Other Lisps that come with their own
;; ASDF implementation will be supported in the future.
build-file: "make-neat-project.lisp"
lisp: "sbcl" ;; Which implementation to use for the build.
;; The other option is to use a "cmd" instead of "build-file". When you do
;; this, then "cmd" is just a command that gets called using the shell. It
;; could be something as simple as a call to "make" or a shell script, or a
;; complicated call to some sort of compiler.
}
}
;; Defines additional command line arguments for this project. Use these to
;; pass build options to your build-file.
options: [
{
name: "compress" ;; This makes an argument called "--compress"
type: "flag" ;; Or "string" for an argument that takes a string
;; When an "env" key is present, then calling this option on the command
;; line will set this as an environment variable and pass it to the build.
;; For flag arguments, this sets the environment variable to "1". For
;; string arguments, it sets it to whatever was passed to the option on the
;; command line.
;;
;; This works for both "cmd" and "build-file" builds.
env: "XQATOOL_COMPRESS"
help: "Produce a compressed binary."
}
;; When the "feature" key is used, then this will be pushed onto *FEATURES*
;; at build time. Flag options require either "feature" or "env". String
;; options only require "env", but can also use "feature".
{
name: "neat-feature"
type: "flag"
feature: ":some-feature" ;; Note that "feature" is ignored for "cmd" builds.
help: "Enable a Neat Feature!"
}
]
;; Dependencies can be either Fossil repos, Git repos, or local directories.
;; Mercurial will be added soon. There can be no dependencies, or as many as
;; you need.
dependencies: {
;; The name of the dependency doesn't matter as long as it's unique. It's
;; just used for informational display.
cl-sdm: {
;; The type of this dependency. Can be "fossil", "git", or "local".
type: "fossil"
;; If the type is "fossil" or "git", then this is the URL to the
;; repository. If the type is "local", then this should be the full path
;; to the directory.
location: "https://chiselapp.com/user/MistressRemilia/repository/cl-sdm/"
;; The version, branch, checkout, commit, tag, etc. to check out. This is
;; ignored for "local" dependencies.
tag: "trunk"
}
}
Next: Build Keys, Up: Format Overview [Contents][Index]
| Key Name | Description |
|---|---|
name
| The name of this project. Must be a string, and must be provided. This is only used for informational purposes. |
license
| The license that this project falls under. Must be a string, and must be provided. This is only used for informational purposes. |
authors
| The authors of the project. Must be a list of strings, and is optional. This is only used for informational purposes. |
clean-files
| A list of files to clean when the clean command is used. Must be a
list of strings, and is optional. When doing the deletion, Reika does an
equivalent of rm -rf, so directories can also be removed. |
extra-help
| Additional help text that is appended to the output of --help when
that is used on the build, update, and
force-update commands. Must be a string, and is optional. Whitespace
at the start and end of the string is automatically stripped. |
build
| Defines the list of build targets. This must be an object, where the keys are the names of the targets, and the values are objects defining each target. See Build Keys. |
options
| Defines a list of options for the project. This must be a list of objects where each object defines an option. These options become project-specific command line arguments, and are used to control build behavior. See Option Keys. |
dependencies
| Defines the list of dependencies for the project. This must be an object, where
the keys are the names of the dependencies, and the values are objects defining
each dependency. The dependencies key is optional. See Dependency Keys. |
Next: Option Keys, Previous: Top-level Keys, Up: Format Overview [Contents][Index]
| Key Name | Description |
|---|---|
build-file
| This must be either a string or nil. When this is a string, it must be
the path to a Common Lisp file, relative to where the project file is located.
This file will be used during the build and will be passed to the Common Lisp
implementation on the command line for loading. Using this key defines the
project as a Common Lisp Project. Only one of build-file and
cmd can be used. |
cmd
| This must be either a string or nil. When this is a string, it defines
the project as a Generic Project, and will be treated as a command that will be
called by Reika using the shell when performing a build. Only one of
build-file and cmd can be used. |
lisp
| This tells Reika what Common Lisp implementation to use for the build. It is
only used when build-file is used, and is ignored otherwise. This is
optional, and must be a string when supplied. The only currently supported
value is the string "sbcl", which tells Reika to use Steel Bank
Common Lisp (SBCL). |
extra-lisp-args
| This key is optional and must be a list of strings. These are additional
arguments that will be passed when calling the Common Lisp implementation. It
is only used when build-file is used, otherwise it is ignored. When
specifying arguments that take a value, you must separate the value from the
option. For example, if you would normally use --dynamic-space-size 8192 on the command line, and wish to use this in the build, then you would
specify --dynamic-space-size and 8192 as two separate
strings. |
default
| This declares whether or not this target is the default target. Using this key
is optional, and it must be a boolean value (true or
false). If you don’t specifically add this key, the default is
false unless there is only one target for the entire project, in
which case the default is true. Each project must have exactly one
default target. |
pre-build-cmd
| This is a command that should be executed by the shell after the dependencies are updated, and before the build is initated. Using this key is optional, and it must be a string when used. |
post-build-cmd
| This is a command that should be executed by the shell after a build successfully completes. Using this key is optional, and it must be a string when used. |
Next: Dependency Keys, Previous: Build Keys, Up: Format Overview [Contents][Index]
| Key Name | Description |
|---|---|
name
| The name of the option. This is required and must be a string. It also cannot
start with dashes, must be at least two characters long, and cannot be one of
the built-in command line options. Do not add - or -- to
the beginning this string; this will be handled automatically by Reika. |
type
| The type of the option. This is required and must be a string. There are two
supported types: "flag" (which are options that do not take a value)
and "string" (options that require a value).
When using a |
help
| A string that describes what this options does. This is required and must be a
string. It will be shown when using --help together with the
build command. If this is a "string" option, then the
extra “x” will automatically be added by Reika, so there is no need to specify
this yourself. |
feature
| A Common Lisp feature that will be pushed onto the Common Lisp implementation’s
*FEATURES* when this option is called. This key is optional and must
be a string. You should almost always specify a Common Lisp keyword as this
key’s value, for example feature: ":some-feature". |
env
| Defines an environment variable that will be defined when this option is used.
These environment variables are passed to the Common Lisp implementation when
performing the build. This key is optional and must be a string.
When the option is a |
Next: Version Object Keys, Previous: Option Keys, Up: Format Overview [Contents][Index]
| Key Name | Description |
|---|---|
type
| The type of the dependency. This is required and must be a string. There are
three supported types: "fossil", "git", and
"local".
When updating dependencies, Reika will clone |
location
| Where to find this dependency. This is required and must be a string. For
"fossil" and "git" dependencies, this must be a URI, and
will be passed to the Fossil or Git program. For "local"
dependencies, this should be a path name (either a full path, or relative to
where the Project File is located) pointing to the dependency. |
local
| This is optional and must be a string or nil. When this is a string,
then it is used as a “local name” for this dependency within the
deps/ directory. For example, if you have a "fossil"
dependency with a location of
"https://fossil.cyberia9.org/cl-remimatrix/", and local is
set to "foo", then you will end up with a directory named
deps/foo/ after the dependency has been cloned. |
tag
| This indicates which branch/tag/version/etc to check out for the dependency. It
is only used for dependencies that are not of type "local". This is
optional and must be a string, an object, or nil. When it is
nil or not specified, then the default is "trunk".
String values are checked out verbatim, so if this is equal to When this is an object, then it must be a Version Object. See Version Object Keys. |
Previous: Dependency Keys, Up: Format Overview [Contents][Index]
| Key Name | Description |
|---|---|
version
| A version number. This is required and must be a string. This key is treated
as a Semantic Version. It will also handle versions that start with
"v" or "version-". |
mod
| A version modifier that indicates how the version is to be interpreted. This is
required and must be a string. The only supported values are
"or_later, "this_minor, and "strict.
When this is When this is When this is |
Next: Index, Previous: Project Files, Up: Reika [Contents][Index]
This chapter describes how Reika works internally. If you are only interested in using Reika to build a piece of software, then you can skip this chapter. However, if you are interested in integrating Reika into your project, then read on to understand how Reika works.
Reika is primarily a dependency manager and build initiator. That is, it doesn’t perform the actual build/compilation itself, but simply initiates the process. It is primarily designed for Common Lisp projects that produce binary executables, but can (in theory) be used with other languages as well (though this is not officially supported). These two types of projects are called Common Lisp Projects and Generic Projects, respectively. Likewise, their corresponding build processes are called Common Lisp Builds and Generic Builds. These will be described in the following sections.
Next: Generic Builds, Up: How Reika Works [Contents][Index]
Unlike many other dependency managers, Reika specifically does NOT solve dependencies, and this is by design. So if your project has a dependency on some package X, and X has a dependency on Y, then you must list both X and Y in your project file as dependencies. There are three reasons for this design:
Next: Common Lisp Builds, Previous: A Note on Dependencies, Up: How Reika Works [Contents][Index]
Generic Builds are simple, so we’ll cover those first. These are defined by the
presence of a cmd key in the Project File. See Build Keys. For a
Generic Build, the value of this key is just a command that Reika will pass to
the shell for execution. Thus you can use this to call an external Makefile, a
Rakefile, a shell script, a compiler, and so on.
Keep in mind that special handling of the dependencies are done with this type
of build; Reika just ensures that the dependencies have been cloned to the
deps/ directory and that their check outs are correct. It is up to
you to actually utilize them with your command. Reika will, however, still pass
environment variables (specified using option in the Project File) on
through to the command.
Next: The Build File, Previous: Generic Builds, Up: How Reika Works [Contents][Index]
Reika has been specifically designed to hide as much of the Common Lisp build process from the end user as possible, making it easy for people not accustomed to Common Lisp to build software written in the language. Essentially, if the user has to see a REPL, use Quicklisp, or mess with ASDF in any way, then Reika is not doing its job. Instead, you as a project’s developer hide as many of Common Lisp’s intricacies as possible using Reika’s features. It does this using a Project File, and a Build File.
The Project File is a special file named reika.rbp located in the root of your project’s source tree. See Project Files. Build Files are described later in this chapter.
Before a build is initiated, Reika will ensure that all required dependencies are placed into a special directory named deps/, which will be created in the root of your project’s source tree. These dependencies are either cloned (in the case of Fossil and Git dependencies) or symlinked (for local dependencies) into this deps/ directory prior to the build. Reika will also ensure that each dependency is at the correct checkout/tag/branch/etc. This last step is only done for Fossil and Git dependencies. Once the dependencies have been checked, Reika begins the process of a Common Lisp Build.
Common Lisp Builds are what Reika was originally designed to perform. When
doing this type of build, Reika first constructs a set of arguments that it will
pass to the selected Common Lisp implementation. This list of arguments begins
with any arguments that are defined in the Project File’s
extra-lisp-args key. See Build Keys.
After these arguments will be an argument to ensure ASDF is loaded, followed by another argument that clears the ASDF central registry. This is important, as it is key to how Reika performs Common Lisp Builds. After this, Reika looks at all of the dependencies it put into deps/, then generates more arguments to place the directories of these dependencies onto the ASDF central registry, thereby recreating it. It also places the project’s root directory into the ASDF central registry.
Following this, Reika processes any project-specific options that were called.
If an option requires a feature symbol be placed into *FEATURES*,
then it will generate an argument to do this. It also takes note of any
environment variables it needs to define for later use.
Finally, Reika looks at the build-file key in the Project File and
generates an argument to load this into the Common Lisp implementation. It is
this file that performs the actual build itself. Usually this means that
this file contains a call into the function that dumps a binary, such as
sb-ext:save-lisp-and-die for SBCL.
Once it constructs this set of arguments, the Common Lisp implementation is called with them, as well as any environment variables that were set with the options defined in the project file.
Previous: Common Lisp Builds, Up: How Reika Works [Contents][Index]
The Build File (which is pointed to by the build-file key in the
Project File) is a file containing Common Lisp code that performs the actual
build process. This file is only used for Common Lisp Projects. Reika will use
this file in conjunction with the selected Common Lisp implementation to perform
the build. For Common Lisp Builds, there is one Build File per target. A Build
File can be as simple as something like this (assuming SBCL is used):
(asdf:load-system :my-program)
(let* ((outdir (merge-pathnames #P"./bin/"))
(filename (merge-pathnames outdir "my-program"))
(toplevel 'my-program:main))
(ensure-directories-exist outdir)
(sb-ext:save-lisp-and-die
filename
:executable t
:toplevel toplevel
:save-runtime-options t
:purify t))
There are many ways to write a Build File, including ways to call into ASDF to produce a binary. Options defined in the Project File that declare environment variables should also be processed by your Build File, as these are intended to control the behavior of the build. How this is accomplished depends on the Common Lisp implementation, but one possible solution with SBCL may look like the following:
(cond ((equalp (sb-posix:getenv "COOL_PROGRAM_MODE") "release") (format t "Doing a release build...~%") ;; ... more code ... ) ((equalp (sb-posix:getenv "COOL_PROGRAM_MODE") "debug") (format t "Doing a debug build...~%") ;; ... more code ... ) (t (format *error-output* "ERROR: bad program mode!~%") (sb-ext:exit :code 1)))
You can also define options in the Project File that push new features onto the
*FEATURES* variable in Common Lisp, which you can then use in your
code to do conditional building. For example, if you have an option in your
Project File that declares feature: ":foo-bar", then you might have
code inside your Common Lisp program that looks like this:
(defun foo ()
#-foo-bar
(progn
(format t "The foobar feature was disabled at build time...~%")
;; ... more code ...
)
#+foo-bar
(progn
(format t "The foobar feature was enabled at build time...~%")
;; ... more code ...
))
Previous: How Reika Works, Up: Reika [Contents][Index]
| Jump to: | B C D G I P |
|---|
| Jump to: | B C D G I P |
|---|