Schema, defaults, and C-source generation for the static NIF table.
The static NIF table lives in two C files inside an app's project:
priv/generated/driver_tab_ios.c
priv/generated/driver_tab_android.cBoth are linked before libbeam.a so they override BEAM's empty
built-in erts_static_nif_tab[]. With these in place, load_nif/2
resolves to the in-binary init function instead of falling back to
dlopen, which fails on iOS (App Store rejects bundled .dylibs) and
on Android (RTLDLOCAL hides the parent's `enif*` symbols from
child libraries).
Declaring NIFs
An app's mob.exs may add to or override the defaults via the
:static_nifs key:
config :mob_dev,
static_nifs: [
%{module: :my_native, archs: [:all]}
]Each entry is a map with these fields:
| Field | Type | Default | Meaning |
|---|---|---|---|
:module | atom | required | Erlang module name |
:init | string | derived | Init fn name. Defaults to <mod>_nif_init |
:builtin | boolean | false | True for OTP-shipped libs |
:archs | [atom] | [:all] | Where this NIF should appear |
:guard | string | none | Macro naming a narrowed entry (see below) |
:extra_static_libs | map | none | Per-ABI archives to link with this NIF |
Valid :archs values: :all, :ios, :android, :ios_sim,
:ios_device, :android_arm64, :android_arm32.
When :archs is a strict subset of a target platform's archs (e.g.
[:ios_device] for iOS), set :guard to a C-identifier macro name. The
generated tables select a guarded project entry on exactly the targets its
:archs cover, by the compiler's own target: the Zig table gates it on
@import("builtin").target (the simulator ABI on iOS, the CPU on Android),
and the C table wraps the forward declaration and row in #if <arch test>
(TARGET_OS_SIMULATOR, __aarch64__, __arm__, or 1 when the entry covers
the platform). No build option is involved, so it works with any app's
build files (MOB-376). The guards of the built-in NIFs in default_nifs/0
are different: each is a feature switch that mob_new's build files set
(build_options.<flag> for Zig, -D<guard> for C).
Defaults
See default_nifs/0 for the baked-in NIF set. It mirrors the hand-edited
driver_tab_ios.c / driver_tab_android.c files mob shipped through
v0.5.18 — regen/1 against an empty user list produces byte-equivalent
output to those files.
Summary
Functions
Returns the baked-in NIF set used by every Mob app.
Generates the driver_tab source for one platform.
True when the entry carries a :guard key. A built-in NIF's guard (e.g.
MOB_STATIC_EMLX_NIF) is a feature switch the build sets: #ifdef in C, a
build_options flag in Zig. A project NIF's guard selects the entry on the
targets its :archs cover, by the compiler's target, and is always on when
the archs cover the whole platform.
Returns the init function name for an entry — either the explicit :init
value or the conventional <module>_nif_init.
Returns true if the entry's archs are a strict subset of the platform's
archs (i.e. it's present on this platform but not all of its arches). Such
an entry needs a :guard, so the generated tables register it only on its
archs.
Returns true if the entry should appear in the generated file for this platform (i.e. its archs intersect the platform's archs).
Combines the defaults with a user list (typically from
Application.get_env(:mob_dev, :static_nifs, [])).
Validates a single entry, returning :ok or {:error, reason}.
Types
@type arch() ::
:all
| :ios
| :android
| :ios_sim
| :ios_device
| :android_arm64
| :android_arm32
@type extra_static_lib_arch() ::
:ios_sim | :ios_device | :android_arm64 | :android_arm32 | :android_x86_64
@type platform() :: :ios | :android | arch()
Functions
@spec default_nifs() :: [nif_entry()]
Returns the baked-in NIF set used by every Mob app.
These match the hand-edited driver_tab_*.c files in mob ≤ 0.5.18.
Users append to this list via :static_nifs in mob.exs.
Generates the driver_tab source for one platform.
Format is :c by default (produces driver_tab_<platform>.c matching
the hand-edited reference files byte-for-byte). Pass format: :zig
for the Phase 6a Zig output — same semantics, structured as
comptime-friendly Zig (extern struct ABI types, export for the
C-callable symbols, if (sqlite_static) ... else ... in place of
#ifdef).
Pure function — given the same nif list it always produces the same bytes.
True when the entry carries a :guard key. A built-in NIF's guard (e.g.
MOB_STATIC_EMLX_NIF) is a feature switch the build sets: #ifdef in C, a
build_options flag in Zig. A project NIF's guard selects the entry on the
targets its :archs cover, by the compiler's target, and is always on when
the archs cover the whole platform.
Returns the init function name for an entry — either the explicit :init
value or the conventional <module>_nif_init.
Returns true if the entry's archs are a strict subset of the platform's
archs (i.e. it's present on this platform but not all of its arches). Such
an entry needs a :guard, so the generated tables register it only on its
archs.
Returns true if the entry should appear in the generated file for this platform (i.e. its archs intersect the platform's archs).
Combines the defaults with a user list (typically from
Application.get_env(:mob_dev, :static_nifs, [])).
Later entries with the same :module override earlier ones. This lets
users replace a default entry — e.g. drop :sqlite3_nif by setting
archs: [] — without forking the default list.
Validates a single entry, returning :ok or {:error, reason}.