From 558356149bb3dfa398a2d06702116865a49ac42a Mon Sep 17 00:00:00 2001 From: Ivan FB Date: Mon, 4 May 2026 11:18:32 +0200 Subject: [PATCH] better comments about where genBindings() should be invoked --- examples/nim_timer/nim_timer.nim | 7 +++++++ ffi/internal/ffi_macro.nim | 14 ++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/examples/nim_timer/nim_timer.nim b/examples/nim_timer/nim_timer.nim index 5e152ec..947e749 100644 --- a/examples/nim_timer/nim_timer.nim +++ b/examples/nim_timer/nim_timer.nim @@ -65,6 +65,13 @@ proc nimtimerComplex*( return ok(ComplexResponse(summary: summary, itemCount: count, hasNote: req.note.isSome)) +# --- genBindings() must come AFTER every {.ffi.} / {.ffiCtor.} annotation --- +# Each pragma populates ffiProcRegistry / ffiTypeRegistry at compile time as +# the compiler processes the AST. genBindings() reads those registries to emit +# the binding files, so placing it any earlier would produce incomplete output. +# In a multi-file library, import all sub-modules first and call genBindings() +# once, at the bottom of the top-level compilation-root file. +# This call is a no-op unless -d:ffiGenBindings is passed to the compiler. genBindings() # reads -d:ffiOutputDir, -d:ffiNimSrcRelPath, -d:targetLang from compile flags proc nimtimer_destroy*(ctx: pointer) {.dynlib, exportc, cdecl, raises: [].} = diff --git a/ffi/internal/ffi_macro.nim b/ffi/internal/ffi_macro.nim index 6f4203e..7bc7c09 100644 --- a/ffi/internal/ffi_macro.nim +++ b/ffi/internal/ffi_macro.nim @@ -1461,8 +1461,18 @@ macro genBindings*( outputDir: static[string] = ffiOutputDir, nimSrcRelPath: static[string] = ffiNimSrcRelPath, ): untyped = - ## Generates binding files for the language set by -d:targetLang=. - ## Supported values: "rust" (default), "cpp" (case-insensitive). + ## Emits C++ or Rust binding files from the compile-time FFI registries. + ## + ## PLACEMENT REQUIREMENT: genBindings() must be called AFTER every {.ffi.} + ## and {.ffiCtor.} annotation in the compilation unit. Each pragma populates + ## ffiProcRegistry and ffiTypeRegistry as the compiler expands the AST; + ## calling genBindings() earlier produces incomplete bindings. + ## + ## In a single-file library, place it at the bottom of the file. + ## In a multi-file library, import all sub-modules first and call + ## genBindings() once at the bottom of the top-level compilation-root file. + ## + ## Supported languages (-d:targetLang): "rust" (default), "cpp". ## Output path and nim source path default to -d:ffiOutputDir and ## -d:ffiNimSrcRelPath, or can be passed as explicit arguments. ## This macro is a no-op unless -d:ffiGenBindings is set.