MobDev.TfliteNif (mob_dev v0.5.11)

Copy Markdown View Source

Cross-compiles tflite_nif.c (the NIF wrapping TensorFlow Lite's C API) for one Android or iOS target ABI and archives the result as libtflite_nif.a. The archive gets static-linked into the user app's main native binary alongside crypto.a, libemlx.a, and any other static NIFs.

Companion bits

  • Native libsMobDev.TfliteDownloader fetches the TFLite native libraries (AAR for Android, xcframework tarball for iOS) and supplies headers + the runtime library that gets linked into the launcher binary alongside this archive.
  • C sourcetflite_nif.c ships in the :nx_tflite_mob Hex dep (the user adds {:nx_tflite_mob, ...} to their mix.exs when they run mix mob.enable tflite). This module looks it up via :code.lib_dir(:nx_tflite_mob).
  • Static-NIF table entry:tflite_nif is registered in MobDev.StaticNifs.default_nifs/0 with guard MOB_STATIC_TFLITE_NIF. The guard threads into build_device.zig as tflite_static and is set to true when the project enables this feature.

Same constraints as every other NIF mob ships on phones:

  • Android. dlopen'd children inherit RTLD_LOCAL, hiding the parent's enif_* symbols from a separately-loaded libtflite_nif.so. on_load then fails with "cannot locate symbol". Static linking sidesteps that — BEAM finds tflite_nif_nif_init via dlsym(RTLD_DEFAULT) against the main app binary.
  • iOS. App Store forbids loading unsigned dylibs / dlopen; every NIF must already be present in the signed binary.

The TFLite runtime itself (libtensorflowlite_jni.so on Android, TensorFlowLiteC.framework on iOS) IS allowed to load via the normal dynamic-linker path: it's code-signed (iOS) or part of the standard jniLibs/ contract (Android). Only the NIF init has to be static.

Per-target deltas

TargetSourceCompilernm symbol
android_arm64NDK aarch64 clangaarch64 crosstflite_nif_nif_init
android_arm32NDK arm clangarm cross (armv7-a)tflite_nif_nif_init
ios_simxcrun iphonesimulatorarm64-apple-ios-simulator_tflite_nif_nif_init
ios_devicexcrun iphoneosarm64-apple-ios_tflite_nif_nif_init

STATIC_ERLANG_NIF_LIBNAME

We pass -DSTATIC_ERLANG_NIF_LIBNAME=tflite_nif to make ERL_NIF_INIT emit symbol tflite_nif_nif_init. That matches the convention used by MobDev.NxEigenNif (nx_eigennx_eigen_nif_init) and what MobDev.StaticNifs.init_fn/1 derives for the :tflite_nif module entry.

Summary

Functions

Base CFLAGS shared across all targets. Public for testing.

Compile + archive + verify libtflite_nif.a for one target.

Assemble full CFLAGS for a target plus include / framework search paths.

Per-target spec. Public for testing.

All known TFLite NIF targets.

Functions

base_cflags()

@spec base_cflags() :: [String.t()]

Base CFLAGS shared across all targets. Public for testing.

build(target_id, opts \\ [])

@spec build(
  atom(),
  keyword()
) :: {:ok, map()} | MobDev.Release.Errors.t()

Compile + archive + verify libtflite_nif.a for one target.

Options:

  • :nx_tflite_mob_dir — path to the :nx_tflite_mob Hex dep (the dir containing c_src/tflite_nif.c). Required.
  • :tflite_dir — path returned by MobDev.TfliteDownloader.ensure/1 for this target. Required.
  • :erts_include — per-target erts-VSN/include/ dir. Required.
  • :out_dir — where the archive + object subdir get written. Required.
  • :ndk_root — Android NDK root (Android targets only; defaults to ~/Library/Android/sdk/ndk/<NdkVersion.effective()>).

cflags(target, includes, frameworks \\ [])

@spec cflags(
  %MobDev.TfliteNif.Target{
    extra_cflags: term(),
    id: term(),
    nm_symbol: term(),
    tools_fn: term()
  },
  [Path.t()],
  [Path.t()]
) :: [String.t()]

Assemble full CFLAGS for a target plus include / framework search paths.

includes are -I-prefixed; frameworks are -F-prefixed (iOS only — ignored on Android targets). Order is preserved.

target_spec(atom)

@spec target_spec(atom()) :: %MobDev.TfliteNif.Target{
  extra_cflags: term(),
  id: term(),
  nm_symbol: term(),
  tools_fn: term()
}

Per-target spec. Public for testing.

targets()

@spec targets() :: [atom()]

All known TFLite NIF targets.