Skip to content

Latest commit

 

History

History
217 lines (157 loc) · 5.56 KB

File metadata and controls

217 lines (157 loc) · 5.56 KB

mxpkg — Modula-2 Package Manager

mxpkg is a self-hosted package manager for Modula-2, written in Modula-2 itself. It reads m2.toml manifests, resolves dependencies, and invokes mx to build projects.

Quick start

# Bootstrap: build mxpkg from source using mxpkg0
cd path/to/m2
cargo build --release         # build mx
cd tools/mxpkg0
cargo build --release         # build bootstrapper
cargo run -- build            # build mxpkg using mx

# The self-hosted binary is at tools/mxpkg/target/mxpkg

Commands

mxpkg init

Create a new m2.toml manifest template in the current directory.

mxpkg build [--release]

Build the package. Reads m2.toml, resolves dependencies, constructs the mx command, and compiles. Output goes to target/<name>.

  • --release — pass -O2 to mx

mxpkg run [--release] [-- args...]

Build and immediately run the package. Arguments after -- are passed to the program.

mxpkg resolve

Validate dependencies and generate/update m2.lock.

mxpkg publish

Publish the package to the registry. Enforces: valid semver, no duplicates, version >= latest.

mxpkg fetch <name> <version>

Download a package from the registry to the local cache.

mxpkg version

Print the mxpkg version.

mxpkg clean

Remove build artifacts.

mxpkg check

Validate the manifest and lockfile.

mxpkg verify

Verify lockfile integrity (SHA-256 hashes).

Package manifest (m2.toml)

INI-like format with key=value pairs and [section] headers:

# m2.toml - package manifest
manifest_version=1
name=hello
version=0.1.0
edition=pim4
entry=src/Main.mod
m2plus=false
includes=src

[deps]
mylib=path:../mylib
otherlib=0.2.0

[cc]
cflags=-Wall
ldflags=-L/usr/local/lib
libs=m pthread
extra-c=libs/helper.c
frameworks=CoreFoundation

[test]
entry=tests/Main.mod
includes=tests

[features]
threading=false
gc=false

Core fields

Key Description Default
name Package name (required)
version Semantic version X.Y.Z (required)
entry Path to the main module src/Main.mod
m2plus Enable M2+ extensions false
edition Set to m2plus for extensions pim4
includes Space-separated include directories
manifest_version Manifest format version 1

[deps] section

[deps]
mylib=path:../mylib         # local path dependency
otherlib=0.2.0              # registry dependency (semver)

Each dependency must have its own m2.toml. Its include directories are added to the compiler's search path.

[cc] section

C compiler integration. All values are space-separated lists.

Key Description
cflags Extra C compiler flags
ldflags Linker flags
libs Libraries to link (names only, not -l prefix)
extra-c Extra C source files to compile and link
frameworks macOS frameworks

These are transitive — a dependency's [cc] settings propagate to dependents.

[test] section

Key Description Default
entry Test entry point module tests/Main.mod
includes Test-only include directories

[features] section

Define feature gates for conditional compilation:

[features]
threading=false
gc=false

Features are enabled via --feature flags and control (*$IF name*) pragmas in source.

[registry] section

[registry]
url=https://registry.example.com

Lockfile (m2.lock)

Generated by mxpkg resolve. Records the resolved dependency graph with integrity hashes:

[package]
name=hello
version=0.1.0

[dep.mylib]
version=0.1.0
source=local
sha256=abc123def456...
path=../mylib

Do not edit manually. Regenerate with mxpkg resolve.

The lockfile's content hash (Lockfile::content_hash(), FNV-1a 64-bit) is used by the LSP server as a cache key — changes to m2.lock invalidate the analysis cache and trigger reindexing.

Registry and cache

Path Contents
~/.mxpkg/registry/ Package index and published packages
~/.mxpkg/cache/ Downloaded package cache

Semver resolution

Registry dependencies use semver ranges:

  • ^1.2.3 — compatible with 1.2.3 (>=1.2.3, <2.0.0)
  • ~1.2.3 — patch-level changes (>=1.2.3, <1.3.0)
  • >=1.0.0 — minimum version
  • 1.2.3 — exact version

Architecture

mxpkg is self-hosted: written in Modula-2, compiled by mx. The bootstrapping chain is:

  1. cargo build — build the mx compiler (Rust)
  2. mxpkg0 build — the Rust bootstrapper compiles mxpkg using mx
  3. mxpkg build — mxpkg can now build itself and other packages

Module structure

Module Purpose
Main CLI entry point, command dispatch
Manifest Parse and query m2.toml files
Builder Construct and execute mx commands
Lockfile Read and write m2.lock files
Resolver Validate dependencies, generate lockfile
Registry Package publishing, fetching, version lookup
Semver Semantic version parsing, comparison, range matching
Sys Foreign C bindings to libs/m2sys/

C shim (libs/m2sys/)

Provides capabilities not available in standard Modula-2:

  • File I/O (read, write, stat, mkdir, rmdir)
  • Process execution (exec, wait)
  • SHA-256 hashing
  • Path utilities (join, basename, dirname)
  • Tar archive creation

The M2 Sys module binds to these via DEFINITION MODULE FOR "C".

Bootstrap integrity

bootstrap.lock contains entry_sha256 and tree_sha256 for verifying that the bootstrapped mxpkg binary matches expectations.