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 | Preprocessor macro that gates the entry |
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 preprocessor macro that the
build defines only on those archs. The generated C file wraps both the
forward declaration and the table row in #ifdef <guard>.
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. The guard is the user's
explicit opt-in (e.g. MOB_STATIC_EMLX_NIF) and gets emitted as a
preprocessor #ifdef in C output or a comptime const in Zig output,
independent of whether the entry's archs narrow the 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). When
true, the generated entry must be wrapped in #ifdef <guard>.
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 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. The guard is the user's
explicit opt-in (e.g. MOB_STATIC_EMLX_NIF) and gets emitted as a
preprocessor #ifdef in C output or a comptime const in Zig output,
independent of whether the entry's archs narrow the 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). When
true, the generated entry must be wrapped in #ifdef <guard>.
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}.