Open haxscramper opened 3 years ago
All declared procedures go though the helper macro that conditionally adds dynlib macro. It can also conditionally enable certain elements of the API or hide them as needed. (Maybe map to .error.
that would show needed version).
It's a user responsibility to provide correct version information, either from the build system, or from CLI (all via passed defines). Wrappers have default values for the defines, so wrapper should work even without versioning data.
It is possible to hide API elements from the exported module (which corresponds to the header files), but sometimes modules themselves are renamed or deleted - this would cause accumulation of changes over time (module paths from each processed version would be accumulated over time, even though after certain library versions they would no longer be available). For example, if file old.h
defined a struct and then moved (just moved, not edited) it to new.h
I would have two copies of the same struct - one in old.nim
and one in new.nim
. Same applies to all functions and procedures moved between files.
But, this would allow wrapper users to support any version they want using
when <one version range>:
import old # annotated with old "header"
export old
else:
import new # annotated with new "header"
export new
It might be possible to provide predefined helper modules like this - select a specific version and track movements for API elements from it, generating required version branching as needed. Although I don't feel like it is a specifically useful feature, certainly not a high priority.
Determining what exactly has changed might be tricky, especially due to the https://github.com/haxscramper/hcparse/issues/21. It might eventually come down to diffs for heterogeneous trees, and then I try to produce minimal diff.
It is not problematic for functions - adding new arguments makes it a different function, so I will just put maximum allowed range boundary and then create new proc with different arguments.
This could've worked for types as well - different field means new type. This would create even larger wrappers since I would copy almost the same definition over and over again, but it is the simplest solution.
If I'm aiming for full automation of the wrapper generation, I also need to figure out a way to account for library updates. My current idea for implementation (open for discussion):
And I can generate additional pragma annotations on the wrapped procs, like
where
libgitVersion
is defined asI already have the whole library API in the form of IR that can be saved in json form (and actually intended to be saved). I can annotate things with
interopSince: (0, 0, 0)
by default. When the user re-generates wrappers, I read back generated sources. If something changed, I add newinteropSince
version.Alternatively, if you have your
.nim
file and generated it again, it will update bindings and not generate everything anew. This might require a little more verbose annotations, likeSo I could update wrappers even if there is no json IR saved, or if user want to add custom code directly to the wrapper.