libmorpheus modernizes the Morpheus
morphological analyzer for Ancient Greek and Latin. It turns the historical C
programs into an installable C17 shared library with a stable, opaque ABI, and
comes with JavaScript and Python bindings.
- Project status
- Bindings
- Build the native library
- Install and consume from C
- Runtime data
- Alpine container images
cruncher- Releases and platform support
- Architecture and provenance
- License
| Available operation | Ancient Greek | Latin | Status |
|---|---|---|---|
| Analyze an inflected form | Yes | Yes | Supported |
| Generate forms from a lemma | Yes | No | Experimental |
The public runtime includes:
- structured, caller-owned analysis and generation results;
- per-request analysis options and generation filters;
- isolated contexts that can be used concurrently;
cruncher, retained as a compatibility client of the public library;- CMake and
pkg-configinstallation metadata.
Note
Native archives and the distributed packages contain no linguistic data. Applications must acquire a compatible stem library separately; see Runtime data.
Bindings expose the native C API to other language ecosystems.
| Binding | Description | Documentation |
|---|---|---|
| Deno 2 | Typed TypeScript API for analysis and experimental Greek generation, published on JSR | Deno binding guide |
| Node.js 20+ | ESM facade over an asynchronous Node-API addon | Node.js binding guide |
| Python 3.11+ | Pure-Python ctypes facade over the stable C ABI |
Python binding guide |
Native consumers should instead use the public C API.
- CMake 3.25 or newer;
- Ninja;
- a C17 compiler.
The alpheios-project reference stemlib is a pinned Git submodule, so clone recursively:
git clone --recurse-submodules \
https://github.com/defense-humanites/libmorpheus.git
cd libmorpheusFor an existing clone:
git submodule update --init --recursiveConfigure, build, and test the development preset:
cmake --preset dev
cmake --build --preset dev
ctest --preset devThis produces build/dev/libmorpheus.so (or the platform equivalent) and, by
default, build/dev/cruncher. The runtime build consumes compiled stemlibs and
does not require Flex.
To use another compiled stemlib for the Alpheios fixture suite:
cmake --preset dev -DMORPHEUS_STEMLIB_DIR=/absolute/path/to/stemlibSanitizer and optimized test configurations are available as separate presets:
cmake --preset sanitizers
cmake --build --preset sanitizers
ctest --preset sanitizerscmake --preset thread-sanitizer
cmake --build --preset thread-sanitizer
ctest --preset thread-sanitizercmake --preset release -DBUILD_TESTING=ON
cmake --build --preset release
ctest --preset releaseThe Release tests also install into a clean prefix and verify the public package boundary.
Install the development build into the prefix of your choice:
cmake --install build/dev --prefix /chosen/prefixThe installation contains the shared library, morpheus/morpheus.h, the
Morpheus::morpheus CMake target, libmorpheus.pc, and cruncher. Runtime data
is not installed with the library.
With CMake:
find_package(Morpheus 0.1 CONFIG REQUIRED)
target_link_libraries(my_analyzer PRIVATE Morpheus::morpheus)With pkg-config:
cc analyzer.c $(pkg-config --cflags --libs libmorpheus)Minimal API use:
#include <stdint.h>
#include <morpheus/morpheus.h>
int main(void) {
morpheus_config config = {
MORPHEUS_ABI_VERSION,
sizeof config,
"/path/to/stemlib",
MORPHEUS_LANGUAGE_GREEK
};
morpheus_context *context = NULL;
morpheus_result *result = NULL;
if (morpheus_open(&config, &context) == MORPHEUS_OK &&
morpheus_analyze(
context,
(const uint8_t *)"a)/nqrwpos",
sizeof "a)/nqrwpos" - 1,
MORPHEUS_OPTION_STRICT_CASE,
&result
) == MORPHEUS_OK) {
for (size_t i = 0; i < morpheus_result_count(result); i++) {
morpheus_analysis analysis;
if (morpheus_result_get(result, i, &analysis) == MORPHEUS_OK) {
/* analysis.lemma, analysis.stem, morphology fields, ... */
}
}
}
morpheus_result_free(result);
morpheus_close(context);
return 0;
}Results preserve Morpheus ordering and duplicates. The caller owns every
successful result until morpheus_result_free(). Distinct contexts may run
concurrently; calls on one context must be serialized. The
public API reference documents the complete ABI, error
statuses, ownership rules, and buffer contracts.
Morpheus reads compiled binary databases called stemlibs. Code and data are versioned and distributed separately.
| Dataset | Analysis | Generation | Repository location |
|---|---|---|---|
perseids-tools |
Greek and Latin | No | stemlib/ |
alpheios-project (pinned) |
Greek | Requires a prepared gener.index |
vendor/alpheios-morpheus/dist/stemlib/ |
From a recursive source checkout, prepare a standalone Alpheios directory with the validated experimental generation index using:
sh tools/prepare-runtime-data.sh "$PWD/morpheus-greek-data"The runtime-data guide records exact pinned revisions, digests, acquisition permissions, and redistribution caveats. The stem-library inventory explains the origin and role of each dataset.
The source checkout can reconstruct complete Greek and Latin stemlibs through an explicit, opt-in production graph. Python 3 is required in addition to the native build requirements; Perl is not required. Configure the internal producers, then invoke the aggregate target:
cmake --preset dev -DMORPHEUS_BUILD_STEMLIB_TOOLS=ON
cmake --build --preset dev --target morpheus_stemlib_productionThe target recreates two isolated stages without modifying the source tree or the checked-in stemlibs:
| Language | Reconstructed stemlib root | Production receipt |
|---|---|---|
| Greek | build/dev/stemlib-production/greek/ |
build/dev/stemlib-production/greek/MORPHEUS-STEMLIB-PRODUCTION-RECEIPT.json |
| Latin | build/dev/stemlib-production/latin/ |
build/dev/stemlib-production/latin/MORPHEUS-STEMLIB-PRODUCTION-RECEIPT.json |
Each root contains its Greek/ or Latin/ runtime tree plus ordered input and
output manifests, provenance, and baseline comparisons. The
morpheus_stemlib_production_greek and
morpheus_stemlib_production_latin targets can be run independently. Repeated
invocations delete and recreate only the corresponding build-tree stage.
Portable developer builds record the local compiler and tool versions. The reference qualification is deliberately stricter and fails configuration unless it runs on Ubuntu 24.04 x86-64 with GCC 14 and Python 3.12:
CC=gcc-14 cmake --preset dev \
-DMORPHEUS_BUILD_STEMLIB_TOOLS=ON \
-DMORPHEUS_STEMLIB_QUALIFICATION_PROFILE=github-ubuntu-24.04-gcc-14-python-3.12
cmake --build --preset dev --target morpheus_stemlib_production
ctest --preset devCI performs two additional clean builds per language, compares their complete outputs and receipts, and checks every reviewed difference against the Perseids and pinned Alpheios baselines. The production manifest documents the 379 source inputs and staging corrections; the production audit records the restored producers, reproducibility proof, and accepted binary-format exceptions.
This facility is internal production and qualification infrastructure. It is not installed, its outputs are not included in native or binding packages, and successful reconstruction does not grant permission to redistribute the linguistic datasets.
For deployment-shape qualification, a second opt-in target filters each fresh stage down to the files read by the runtime and writes deterministic archives, SHA-256 sidecars, and schema-1 runtime receipts:
cmake --build --preset dev --target morpheus_stemlib_runtime_artifactsThe results are written below build/dev/stemlib-runtime-artifacts/. They are
internal test artifacts: CI exercises the complete Greek and Latin fixture
suite after extraction but retains only their receipts and checksums, not the
archives. The target does not make the datasets release assets or establish a
redistribution right. The
redistribution gate records the exact data
trees and licensing evidence and keeps every payload publication channel
closed pending an explicit review.
We provide two Alpine container images to facilitate the use of the library.
The Dockerfile supports linux/amd64 and linux/arm64 with BuildKit/QEMU.
These images are local qualification and application-build targets.
The default Alpine multi-stage image builds and tests the C17 runtime on musl,
then ships the installed library, cruncher, runtime dependencies, and the
prepared alpheios-project stemlib:
docker build --target runtime -t morpheus .
printf 'a)/nqrwpos\n' | docker run --rm -i morpheus -SThe deno-runtime target adds Deno while preinstalling only the native runtime
and prepared data:
docker build --target deno-runtime -t morpheus-deno .Applications consume the binding as a normal JSR dependency. See the Deno binding guide for the preconfigured paths and a consumer example.
The historical command-line interface remains available as a compatibility
client of the library. It reads MORPHLIB as before:
printf 'a)/nqrwpos\n' | \
MORPHLIB="$PWD/vendor/alpheios-morpheus/dist/stemlib" \
build/dev/cruncher -SRetained options include -L for Latin, -S for non-strict case, -n to
ignore accents, -d for database format, -e for numeric feature indices,
-k to retain Beta Code, -l for lemma-only output, and -V for verbs only.
Native v<version> release tags provide data-free archives and SHA-256 files
for:
- Linux x86-64 glibc;
- Linux aarch64 glibc;
- macOS arm64.
The Deno binding has an independent version and uses deno-v<version> tags for
its standalone source archive and JSR publication. Each binding version declares
the native runtime release and ABI it supports.
The Node.js binding is versioned independently with node-v<version> tags. npm
publishes the ESM facade as @libmorpheus/node and a matching optional Node-API
addon for each supported native platform; the runtime and stem data remain
separate, verified acquisitions.
The Python binding is versioned independently with python-v<version> tags and
publishes the pure-Python libmorpheus distribution to PyPI. It uses ctypes,
so one universal wheel supports Python 3.11 and newer while applications provide
the compatible native runtime and stem data separately.
The checksum detects corruption; it is not a release signature. See platform support for the complete qualification matrix and release qualification for the checks required before a tag. Release changes are recorded in the changelog.
Two separate fixture suites prevent stemlib differences from being mistaken for runtime regressions:
legacy_fixtureschecks inherited Greek and Latin expectations against theperseids-toolsdataset;alpheios_greek_fixtureschecks Greek reference cases against the pinned Alpheios dataset.
Public ABI, installed-package, parallel-context, Deno, ASan/UBSan, and TSan tests complement those fixtures.
The current implementation derives from the perseids-tools fork, the only
baseline known to compile before this modernization. The repository bundles its
Greek and Latin stemlib and pins a newer Alpheios Greek stemlib for additional
testing and validation.
Further documentation:
The inherited Makefiles remain as a compatibility check for libs and
cruncher, but new consumers should use CMake and the public ABI. Other
historical programs below src/ are quarantined and excluded from supported
builds.
This is a mixed-license repository:
- inherited engine, bridge, compatibility, and derived internal code remain under MPL-2.0;
- the normalized public API, Deno binding, and marked independently written support files use AGPL-3.0-or-later.
A file's SPDX identifier controls when present; otherwise the root MPL-2.0 license applies. See the licensing guide for the precise file-level boundary and the license inventory for its rationale and provenance.