Building a Binary with Chicken Scheme

So that was fucking fun. Seems Chicken’s docs aren’t correct on how to build with modules, because those were added after the dark-ages R5RS it was modelled on.

There is an “egg” system which is used for building the libraries, but it’s difficult to use for making binaries in your own destination dir, and fills your work dir with spam temp files. Unfortunately basically useless for work.

Finally got this working:

src/somelib.scm:

(declare (unit somelib))
(module somelib
    (hello)

(import scheme)

(define (hello) (display "Hello!\n"))
)

src/somemain.scm:

(import scheme
    (chicken load)
)

(cond-expand
    (compiling (declare (uses somelib)))
    (else (load-relative "somelib.scm")))
(import somelib)

(hello)

Don’t you just love that muffin-man-muffin-man repetitious bullshit? declare is for the compiler, load is for the interpreter, then import for both. You import builtins like chicken, but use libraries (aforementioned sdl) without an import. Bizarre and contradictory.

build.zsh: [script updated 2019-06-08]

#!/bin/zsh

# EXE is binary filename
# MAIN is main script
# LIBS is space-delimited, must not include main script

function usage {
    echo "Usage: build.zsh PROJECT || MAIN.scm [LIBS] || ls || -?"
    exit 1
}

if [[ $# -eq 0 || "$1" == "-?" || "$1" == "--help" ]]; then
    usage
fi

case $1 in
    ls)
        echo "Known projects:"
        # Add known projects here
        echo "eldritch test"
        exit 0
    ;;
    eldritch)
        EXE=eldritch
        MAIN=eldritch.scm
        LIBS="marklib.scm marklib-geometry.scm marklib-ansi.scm"
    ;;
    test)
        EXE=marklib-test
        MAIN=marklib-test.scm
        LIBS="marklib.scm marklib-geometry.scm"
    ;;
    *)
        # command-line project: MAIN=$1, LIBS=$2...
        EXE=`basename $1 .scm`
        MAIN=$1
        shift
        LIBS="$*"
    ;;
esac

mkdir -p bin

cd src
for SF in ${=LIBS}; do
    SNAME=`basename $SF .scm`
    echo "Compiling $SF"
    csc -c -j $SNAME $SF -o $SNAME.o || exit 1
done
echo "Compiling $MAIN"
csc -c $MAIN -o `basename $MAIN .scm`.o || exit 1
echo "Linking..."
csc *.o -o ../bin/$EXE || exit 1
rm -f *.o
rm -f *.import.scm
cd ..

echo "Built bin/$EXE"
% ./build.zsh
Built bin/something
% ./bin/something
Hello!

Hello, working native binary! There’s a bunch more stuff about making a deployable app, but I’ll take this for now. My actual program can show a blank green graphics window!