Mumei can load external code-generation emitters at runtime from dynamic libraries. A plugin implements mumei_core::emitter::Emitter, exports the expected ABI symbols, and is installed under ~/.mumei/emitters/<name>/.
[package]
name = "mumei-emit-noop"
version = "0.1.0"
edition = "2021"
[lib]
crate-type = ["cdylib"]
[dependencies]
mumei-core = { git = "https://github.com/mumei-lang/mumei", package = "mumei-core" }When developing against a local checkout, replace the dependency with:
mumei-core = { path = "../mumei/mumei-core" }Every plugin must export:
mumei_emitter_abi_version() -> u32mumei_create_emitter() -> EmitterPluginHandle
The ABI version must match mumei_core::emitter::EMITTER_ABI_VERSION.
use mumei_core::emitter::{Artifact, BoxedEmitter, Emitter, EmitterPluginHandle, EMITTER_ABI_VERSION};
use mumei_core::hir::HirAtom;
use mumei_core::parser::ExternBlock;
use mumei_core::verification::{ModuleEnv, MumeiResult};
use std::path::Path;
struct NoopEmitter;
impl Emitter for NoopEmitter {
fn emit(
&self,
_hir_atom: &HirAtom,
_output_path: &Path,
_module_env: &ModuleEnv,
_extern_blocks: &[ExternBlock],
) -> MumeiResult<Vec<Artifact>> {
Ok(Vec::new())
}
}
#[no_mangle]
pub extern "C" fn mumei_emitter_abi_version() -> u32 {
EMITTER_ABI_VERSION
}
#[no_mangle]
pub extern "C" fn mumei_create_emitter() -> EmitterPluginHandle {
let emitter: BoxedEmitter = Box::new(NoopEmitter);
EmitterPluginHandle::from_boxed(emitter)
}EmitterPluginHandle is a #[repr(C)] two-pointer handle carrying the trait object's data and vtable pointers explicitly. Do not export *mut dyn Emitter directly across the C ABI boundary.
Build the plugin:
cargo build --releaseInstall it into the emitter directory matching the --emit name:
mkdir -p ~/.mumei/emitters/noop
# Linux
cp target/release/libmumei_emit_noop.so ~/.mumei/emitters/noop/
# macOS
cp target/release/libmumei_emit_noop.dylib ~/.mumei/emitters/noop/
# Windows
copy target\release\mumei_emit_noop.dll %USERPROFILE%\.mumei\emitters\noop\Run Mumei with the plugin:
mumei build src/main.mm --emit noopFor --emit <name>, Mumei searches:
- Linux:
~/.mumei/emitters/<name>/libmumei_emit_<name>.so - macOS:
~/.mumei/emitters/<name>/libmumei_emit_<name>.dylib - Windows:
~/.mumei/emitters/<name>/mumei_emit_<name>.dll
The host loads an external emitter once per mumei build invocation and reuses that object for every atom emitted in the build. It keeps the dynamic library loaded while the emitter object is alive. emit() calls are wrapped in a panic catcher, so plugin panics become MumeiError diagnostics instead of unwinding through Mumei.