Core User Manual

This manual documents the CC core software. The core is a multi-language library and framework used to build novel applications. It is composed of language-specific collections of interconnected libraries providing an exceptionally powerful development ecosystem.

1. Introduction

Welcome to the core, the primary software development ecosystem of CC.

Here you will find a large collection of interconnected modules and tools which forms the foundation of all applications we produce. The core is designed to be the best toolkit for rapid development of next-gen applications.

To achieve this end we narrow the scope of our work in many ways and have some hard-coded opinions worth mentioning.

For example, we make no efforts to support cross-compilation or porting of our software to devices or operating systems the developer can't fully control such as Windows/MacOS/iOS/Android. We always assume the developer is running a GNU/Linux host.

We also don't obey any rules regarding backward-compatibility. APIs change fast and breaking changes may be introduced without notice.

We track the development branches and host mirrors of all of our major dependencies including SBCL and Emacs as well as libraries including RocksDB and Zstd so that we can incorporate pre-release APIs and our own custom patches as needed. Internally we do not test against public release binaries and only support binaries built from our own mirrors.

2. Overview

The Core itself is not an application but is complex enough that it merits its own dedicated manual. There are dedicated manuals for the applications which are part of the core, so what we are concerned with here is managing and hacking on the source code itself. We are directing our attention inwards, towards the core instead of extending our gaze away from it to see where it leads.

This manual is often technical, but occassionally theoretical in nature and intended for software developers with experience in Linux, Lisp, and Emacs.

The Core is primarily a Lisp code base. Common Lisp is our language of choice and there is a significant amount of Emacs Lisp code too. Other languages which are present include C as well as Rust.

A solid understanding of C is recommended for developing on the Core, but is not a hard requirement. We make heavy use of FFI to communicate with the OS as well as C libraries but we provide high-level Lispy bindings in most cases.

The Rust portions of the code base are currently under construction and isolated from the rest of the Core. In the future we may incorporate it into this manual, but for the purpose of the following we may safely ignore it.

3. Getting Started

3.0.1. Dependencies

  1. Minimum Requirements
    • GNU/Linux, linux-headers
    • C compiler (GCC, MUSL, CLANG)
    • SBCL
    • GNU Emacs
    • Quicklisp
    • RocksDB
    • Zstd
    • Mercurial
    • OpenSSL
    • Treesitter
    • BLAKE3
  2. Optional Requirements
    • Rust
    • X11
    • CUDA
    • Libevdev
    • Libkeyutils
    • Wasmer
    • Libsndfile
    • Libreadline
    • Libssh2
    • Btrfs
    • Podman
    • QEMU
    • CUDA
    • Readline
    • GStreamer
    • Rustls

3.0.2. Bootstrap

Bootstrapping the core can be done via an existing core image or the skel binary in a 'self-bootstrapping' fashion. See the infra project documentation for details on that process.

Bootstrapping from source is quite easy too. All that is needed is to get the source, load the project skelfile and run sk-make.

# clone the source code from a mirror
git clone https://codeberg.org/c-c/core
cd core
sbcl

Then in the SBCL REPL:

(ql:quickload :skel)
(in-package :sk-user)
(init-skel)
(sk-make *skel-project* :all)
:ALL

Installation is trivial and can be done from the same REPL session. By default the core binary will be written to /usr/local/bin/ and a series of symlinks will be created in the same directory - similar to Busybox binaries. Note that this may not work in a SLIME repl since sudo is called and might need input at the terminal.

(sk-make *skel-project* :install-core)

You should see some output like the following:

skel -> core -> /usr/local/bin/
homer -> core -> /usr/local/bin/
packy -> core -> /usr/local/bin/
rdb -> core -> /usr/local/bin/
organ -> core -> /usr/local/bin/
vc -> core -> /usr/local/bin/
gen -> core -> /usr/local/bin/
swm -> core -> /usr/local/bin/

3.0.3. Configuration

The next think you'll want to take care of is user configuration.

  1. Emacs

    If you don't have your own Emacs config you can install the default CC Emacs configuration using the skel command.

    Warning

    that this will mess with your ~/.emacs.d directory:

    cd emacs && skel install
    
    default.el -> /home/ellis/.emacs.d/default.el
    early-init.el -> /home/ellis/.emacs.d/early-init.el
    init.el -> /home/ellis/.emacs.d/init.el
    keys.el -> /home/ellis/.emacs.d/keys.el
    util.el -> /home/ellis/.emacs.d/util.el
    c2.el -> /home/ellis/.emacs.d/lib/c2.el
    exec-path-from-shell.el -> /home/ellis/.emacs.d/lib/exec-path-from-shell.el
    graph.el -> /home/ellis/.emacs.d/lib/graph.el
    inbox.el -> /home/ellis/.emacs.d/lib/inbox.el
    mpk.el -> /home/ellis/.emacs.d/lib/mpk.el
    org-expiry.el -> /home/ellis/.emacs.d/lib/org-expiry.el
    publish.el -> /home/ellis/.emacs.d/lib/publish.el
    scrum.el -> /home/ellis/.emacs.d/lib/scrum.el
    sk.el -> /home/ellis/.emacs.d/lib/sk.el
    skt.el -> /home/ellis/.emacs.d/lib/skt.el
    slime-cape.el -> /home/ellis/.emacs.d/lib/slime-cape.el
    slime-company.el -> /home/ellis/.emacs.d/lib/slime-company.el
    slime-repl-ansi-color.el -> /home/ellis/.emacs.d/lib/slime-repl-ansi-color.el
    sxp.el -> /home/ellis/.emacs.d/lib/sxp.el
    ulang.el -> /home/ellis/.emacs.d/lib/ulang.el
    uml-mode.el -> /home/ellis/.emacs.d/lib/uml-mode.el
    

    The default config supports user customizations in a file with the same name as the current user, so when $USER = ellis then we check for ellis.el and load it if it exists in ~/.emacs.d/.

  2. SBCL
  3. Core Apps

    The core is a single binary which dispatches on argv[0] from the CLI. Each unique symlink to the core binary is treated as a separate dispatch to a 'main' function like so:

    (define-multi-main dispatch-core
      (progn (in-package :core-lisp)
             #+nil ...)
      (:skel (bin/skel::start-skel))
      (:homer (bin/homer::start-homer))
      (:mpk (bin/mpk::start-mpk))
      #+nil ...)
    

    The current apps that read a configuration file on startup are:

    • skel - project management: .skelrc
    • homer - home management: .homerc
    • mpk - media production kit: .mpkrc

    These apps all use the same configuration object protocol from the OBJ/CONFIG package and are serialized to various S-Expression interpretations. Most commonly the 'pretty' format is used which is simply a plist with implied outer parentheses:

    :key1 val1
    :key2 val2
    

    Canonically that would be:

    (:key1 val1
     :key2 val2)
    
    1. Skel

      A skel config in 'canonical' format (plain S-Expression) is written to ~/.skelrc the first time you run it from the CLI, if it does not already exist.

    2. Homer
    3. Mpk

4. Testing