Skip to content

getting started

Gordon Heydon edited this page Sep 18, 2026 · 4 revisions

Getting Started

Build

Requires CMake, Ninja, LLVM, and LMDB (brew install llvm cmake ninja lmdb; libedit ships with macOS).

cmake -S . -B build -G Ninja -DCMAKE_PREFIX_PATH=/opt/homebrew/opt/llvm
ninja -C build

This produces build/bin/{mvx-basic,mvx,mvx-lmdbd}, the runtime and storage drivers in build/lib/, and the system account — the compiled standard verbs and master VOC — in build/system/.

Run the test suite any time with:

ninja -C build check

Install

cmake --install lays the build tree down as a self-contained, relocatable prefix:

cmake --install build --prefix ~/.local

It writes:

path contents
<prefix>/bin mvx, mvx-basic, mvx-lmdbd, mvx-convert-acct, mvx-git
<prefix>/lib libmvxrt, the storage drivers, mvx_crt.o
<prefix>/share/mvx/system the standard verbs and master VOC, plus the bundled packages

Packages come with it. The install also downloads the published MVPKG (the package manager) and the git package: their verbs and libraries go into the system account, their commands into <prefix>/bin. So GIT works at the TCL prompt, mvx-git works at the shell, and MVPKG is there to install anything else. They are downloaded already built, and each is checked against the checksum published beside it.

A package brings what it needs. A package declares its own dependencies, and the install reads them: they are resolved through the package registry and installed with it, without asking. MVPKG declares curl, so an installed toolchain has HTTPS — which is how MVPKG reaches the registry at all. Optional dependencies are left alone, and a dependency that does not apply to MVX (a package that is built into the runtime here) is skipped.

A package that cannot run here is not installed. Before anything is copied, the install checks that the native libraries a package ships can actually load on this machine. If one cannot, the package is skipped and the warning names the missing library:

mvx: git 2.0.4 needs a library this machine does not have:
            libmvxgit.so: libgit2.so.1.7
     Skipping it -- the toolchain is installed and every other command
     stays clean.

That is a whole skip, not a partial install: the runtime opens every library in the system account, so one that cannot load would print an error on every command afterwards. Install the library (on Debian and Ubuntu, apt-get install libgit2-1.7; on Rocky and RHEL 8, dnf install libgit2_1.7 from EPEL) and add the package with MVPKG install git.

The install asks which version. For each package it lists the published releases and offers the latest stable one, the newest release at each less-stable level that is newer than it, and the nightly dev build last:

git -- which version?
  1) 2.0.4         stable   latest stable  [default]
  2) 2.1.0-rc3     rc
  3) 2.1.0-beta6   beta
  4) dev           dev      nightly, rebuilt in place
  s) skip -- do not install git
Choice [1]:

Enter takes the latest stable; s skips that package. Only versions with a build for your platform are offered.

With nobody at the terminal — CI, a script, anything with stdin not a terminal — there is no prompt and each package's latest stable release is installed. An unattended install never picks a pre-release: a package with no stable release is skipped, with a warning.

To install an exact version instead, set it when configuring, and that package is not asked about:

cmake -S . -B build -DMVX_PACKAGE_VERSION_mvpkg=1.24.1 -DMVX_PACKAGE_VERSION_git=2.0.4

MVX_INSTALL_PROMPT=always or never forces the prompt on or off. The release list comes from the GitHub API, which is rate-limited; set GITHUB_TOKEN if installs run somewhere that shares an IP address.

-DMVX_BUNDLED_PACKAGES="" turns the bundled packages off; the default is git.

MVPKG publishes Linux builds for x86-64 and arm64; git publishes x86-64 only. Where a package has no build — macOS, say, or git on arm64 — the install warns and carries on: the toolchain installs, without it.

The standard verbs are re-cataloged with the installed compiler as part of the install, so their runtime paths point at <prefix>/lib. Put <prefix>/bin on your PATH and mvx runs from anywhere — it finds the runtime, drivers, and system account relative to its own location, so no environment variables are needed and the whole prefix can be moved or renamed as a unit. The MVXSYSTEM, MVXDRIVERS, and MVXBIN variables still override those locations when you want them to.

Your first program

cat > hello.b <<'EOF'
/**
 * @file hello
 */
PRINT "hello from MVX"
FOR I = 1 TO 3
   PRINT "counting ":I
NEXT I
EOF
build/bin/mvx-basic hello.b -o hello && ./hello

Compile errors arrive on stderr as item:line: message. Debugging works out of the box: lldb ./hello, then b hello.b:5, run.

Your first account

An account is a directory holding MV files. Log on to a directory:

build/bin/mvx -a myaccount

If the directory is not yet an MVX account, an interactive session asks before creating one (UniData-style):

Directory /path/myaccount is not an MVX account.
Create one here? (y/N) y
Created MVX account in /path/myaccount

Answer n and nothing is created. scripts/mkaccount.sh myaccount still creates an account non-interactively. Either way a .mvx descriptor file marks the directory as an account — the authoritative marker, since the VOC itself may be a named database inside the LMDB environment or on a daemon rather than a file on disk. The prompt shows the account name. Standard verbs come from the system account; try:

myaccount> CREATE-FILE CUSTOMERS
myaccount> ED CUSTOMERS C1
  (I to insert lines, "." ends input, FI files the record)
myaccount> CT CUSTOMERS C1
myaccount> LISTF
myaccount> OFF

Writing and cataloging programs

Source lives in a directory file, conventionally BP:

myaccount> CREATE-FILE BP DIR

Edit myaccount/BP/MYPROG with any editor (it is a plain text file), then — with developer privilege — compile and publish it as a verb:

MVXPRIV=developer build/bin/mvx -a myaccount
myaccount> BASIC BP MYPROG        (compile only - syntax check)
myaccount> CATALOG BP MYPROG      (compile, link, add to the VOC)
myaccount> MYPROG SOME ARGS

A source whose first statement is SUBROUTINE catalogs into LIB/ as a shared library instead, resolved at CALL time.

Privilege tiers

$MVXPRIV selects the tier: unset is restricted (no compiling, no Unix escapes), developer adds BASIC/CATALOG/COMPILE(), and unrestricted adds ! and SH. The default is deny.

Clone this wiki locally