mix mob.regen_driver_tab (mob_dev v0.5.2)

Copy Markdown View Source

Regenerates the per-app static-NIF table source files in priv/generated/driver_tab_ios.zig and priv/generated/driver_tab_android.zig.

These files are linked before libbeam.a so they override BEAM's empty built-in erts_static_nif_tab[]. Without them, load_nif/2 falls back to dlopen, which is broken on iOS (App Store rejects bundled .dylibs) and on Android (RTLDLOCAL hides parent's `enif*` symbols from children).

mix mob.regen_driver_tab              # regenerate both platforms (default: Zig)
mix mob.regen_driver_tab --format c   # emit driver_tab_*.c instead (hand-editable C)
mix mob.regen_driver_tab --check      # verify on-disk matches manifest, exit non-zero on drift

Format

Zig is the default as of Phase 6a iter 4 — it uses comptime gates instead of #ifdef for guarded NIFs (e.g. iOS sqlite3_nif device-only), and Zig's export keyword produces the same C-ABI symbols libbeam.a expects. --format c is still supported for anyone who wants a hand-editable C dispatch table. Both formats produce equivalent behavior at link time.

C NIF authors are unaffected by the default: their c_src/<name>.c files compile via the usual path, and the Zig dispatch table calls their <name>_nif_init() function through standard C ABI (extern fn <name>_nif_init() callconv(.c)).

Where the NIF list comes from

MobDev.StaticNifs.default_nifs/0 baked-in defaults are merged with any :static_nifs set in mob.exs:

config :mob_dev,
  static_nifs: [
    %{module: :my_native, archs: [:all]}
  ]

See MobDev.StaticNifs for the entry schema and arch values.

Why a Mix task and not a build-time generator

The output is committed to the app's repo so reviewers can see what's in the static-link surface. It also lets non-Mob build tools (e.g. xcodebuild invoked outside mix mob.deploy) pick up the file as plain source. The task is fast (deterministic file generation) so re-running it on every mix compile is cheap.

Drift detection

mob.doctor runs --check mode and reports any drift between the manifest and the on-disk files. CI can do the same.