Commit21f1cb15Recorded25 Apr 2026Repositorysigil-ffi
Extract sigil-ffi from sigil monorepo
Message
First standalone release, extracted via git filter-repo with the two-path twist that preserves vendored dyncall at vendor/dyncall/ (monorepo-root level, not inside the package dir).
Scaffolding:
- README.md (API table + dyncall license note)
- .gitignore (build/, .sigil/, vendor/dyncall/build/)
- manifest.scm (gcc-toolchain + make + pkg-config)
- dev-redirects.sgl (codeberg:sigil/sigil -> ../sigil for sigil-stdlib)
package.sgl changes:
- version: "0.13.1" added
- url: -> https://codeberg.org/sigil/sigil-ffi
- sigil-stdlib swapped to from-git monorepo-resident ^0.13.1
- c-sources / include-dirs paths rewritten ../../vendor/dyncall/... -> vendor/dyncall/... (dyncall now lives at vendor/dyncall/ relative to the extracted repo root)
- ../sigil-lib/include + ../sigil-lib/src dropped from include-dirs
- compile-c-sources flags wrapped in (with-sigil-c-flags ...) per procedures/sigil-package-extraction §6a (native package needs sigil-lib's include paths auto-injected)
Build clean (dyncall + dyncallback compiled, libsigil-ffi.a created, sigil/ffi.sgl compiled). Tests: 20/20 passed.
Changed
.gitignore | 3 +++
README.md | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
dev-redirects.sgl | 6 ++++++
manifest.scm | 7 +++++++
package.sgl | 69 +++++++++++++++++++++++++++++++++++----------------------------------
sigil.lock | 8 ++++++++
6 files changed, 156 insertions(+), 34 deletions(-)Diff
.gitignoreadded
@@ -0,0 +1,3 @@
+1
build/+2
.sigil/+3
vendor/dyncall/build/README.mdadded
@@ -0,0 +1,97 @@
+1
# sigil-ffi+2
+3
Dynamic Foreign Function Interface for [Sigil](https://codeberg.org/sigil/sigil).+4
+5
Call C library functions from Sigil at runtime without writing glue+6
code. Built on a vendored dyncall, which provides portable calling+7
conventions including struct-by-value passing on every supported arch+8
(x86_64, aarch64, arm32, riscv, mips, ppc, sparc, s390, …).+9
+10
## Modules+11
+12
| Module | Purpose |+13
|--------------|----------------------------------------------------|+14
| `(sigil ffi)`| Library load, symbol lookup, call, structs, callbacks |+15
+16
## API summary+17
+18
| Procedure | Purpose |+19
|------------------------------------|----------------------------------------------|+20
| `c-library` | Open a shared library by name |+21
| `c-library-close` | Close a previously opened library |+22
| `c-symbol` | Resolve a symbol in a library |+23
| `c-function` | Bind a function with arg-types and ret-type |+24
| `define-c-library` | Convenience macro for binding many functions |+25
| `c-sizeof` / `c-alignof` | Query size/alignment of an FFI type |+26
| `make-pointer` / `pointer-address` | Build/read raw pointer values |+27
| `pointer-ref` / `pointer-set!` | Dereference a pointer at a typed offset |+28
| `string->pointer` / `pointer->string` | String/pointer round-trip |+29
| `pointer->bytevector` / `bytevector->pointer` | Bytevector bridge |+30
| `c-alloc` / `c-free` / `with-c-alloc` | Manual memory |+31
| `c-errno` / `c-strerror` | errno + strerror access |+32
| `c-struct-layout` / `c-struct-ref` / `c-struct-set!` | Struct field access |+33
| `c-struct->dict` / `dict->c-struct` | Struct/dict marshalling |+34
| `c-callback` / `c-callback-release` | Bind a Scheme procedure as a C callback |+35
+36
FFI type constants: `ffi/void`, `ffi/bool`, `ffi/int8`..`ffi/uint64`,+37
`ffi/float`, `ffi/double`, `ffi/pointer`, `ffi/string`, plus+38
arch-relative `ffi/int`, `ffi/uint`, `ffi/long`, `ffi/ulong`,+39
`ffi/size-t`.+40
+41
## System prerequisites+42
+43
A working C toolchain. dyncall is vendored under `vendor/dyncall/` and+44
compiled in-tree; no system `libdyncall` required. Your platform must+45
be one dyncall supports — see `vendor/dyncall/dyncall/README*` for the+46
arch matrix.+47
+48
## Dependencies+49
+50
- sigil-stdlib+51
+52
## Build+53
+54
```sh+55
sigil deps install+56
sigil build+57
sigil test --report+58
```+59
+60
The first build compiles dyncall + dyncallback (`vendor/dyncall/`)+61
plus `native/ffi.c`. Subsequent builds hit the cache.+62
+63
## Usage+64
+65
```scheme+66
(import (sigil ffi))+67
+68
(define libm (c-library "libm"))+69
(define cbrt (c-function libm "cbrt" (list ffi/double) ffi/double))+70
(cbrt 27.0) ; => 3.0+71
+72
(define libc (c-library "libc"))+73
(define getenv (c-function libc "getenv" (list ffi/string) ffi/string))+74
(getenv "HOME") ; => "/home/you"+75
```+76
+77
`define-c-library` collapses the bind-many-functions pattern:+78
+79
```scheme+80
(import (sigil ffi))+81
+82
(define-c-library libm "libm"+83
(cbrt (ffi/double) ffi/double)+84
(sqrt (ffi/double) ffi/double)+85
(pow (ffi/double ffi/double) ffi/double))+86
+87
(cbrt 27.0) ; => 3.0+88
(pow 2.0 10.0) ; => 1024.0+89
```+90
+91
## License+92
+93
BSD-3-Clause.+94
+95
Vendored dyncall (under `vendor/dyncall/`) is distributed under a+96
permissive ISC-style license — see `vendor/dyncall/LICENSE`.+97
sigil-ffi's own sources are BSD-3-Clause.dev-redirects.sgladded
@@ -0,0 +1,6 @@
+1
;; Development redirects — point dependencies at local Sigil checkout+2
(redirects+3
repos: (list+4
(for-repo+5
url: "codeberg:sigil/sigil"+6
use: (from-path dir: "../sigil"))))manifest.scmadded
@@ -0,0 +1,7 @@
+1
;; sigil-ffi Development Environment+2
;; Use with: guix shell -m manifest.scm+3
+4
(specifications->manifest+5
'("gcc-toolchain"+6
"make"+7
"pkg-config"))package.sglmodified
@@ -6,31 +6,34 @@
6
7
(package 8
name: "sigil-ffi"+9
version: "0.13.1" 10
description: "Dynamic foreign function interface for Sigil"−10
url: "https://codeberg.org/sigil/sigil"+11
url: "https://codeberg.org/sigil/sigil-ffi" 12
license: "BSD-3-Clause" 13
authors: (list "David Wilson <david@daviwil.com>") 14
15
dependencies: (list−15
(from-workspace name: "sigil-stdlib"))+16
(from-git url: "codeberg:sigil/sigil"+17
package: "sigil-stdlib"+18
version: "^0.13.1")) 19
20
;; Native library definition 21
libraries: (list 22
(library 23
name: 'sigil-ffi 24
c-sources: '("native/ffi.c"−22
"../../vendor/dyncall/dyncall/dyncall_api.c"−23
"../../vendor/dyncall/dyncall/dyncall_callvm.c"−24
"../../vendor/dyncall/dyncall/dyncall_callvm_base.c"−25
"../../vendor/dyncall/dyncall/dyncall_vector.c"−26
"../../vendor/dyncall/dyncall/dyncall_callf.c"−27
"../../vendor/dyncall/dyncall/dyncall_aggregate.c"−28
"../../vendor/dyncall/dyncall/dyncall_call.S"−29
"../../vendor/dyncall/dyncallback/dyncall_callback.c"−30
"../../vendor/dyncall/dyncallback/dyncall_thunk.c"−31
"../../vendor/dyncall/dyncallback/dyncall_args.c"−32
"../../vendor/dyncall/dyncallback/dyncall_alloc_wx.c"−33
"../../vendor/dyncall/dyncallback/dyncall_callback_arch.S")+25
"vendor/dyncall/dyncall/dyncall_api.c"+26
"vendor/dyncall/dyncall/dyncall_callvm.c"+27
"vendor/dyncall/dyncall/dyncall_callvm_base.c"+28
"vendor/dyncall/dyncall/dyncall_vector.c"+29
"vendor/dyncall/dyncall/dyncall_callf.c"+30
"vendor/dyncall/dyncall/dyncall_aggregate.c"+31
"vendor/dyncall/dyncall/dyncall_call.S"+32
"vendor/dyncall/dyncallback/dyncall_callback.c"+33
"vendor/dyncall/dyncallback/dyncall_thunk.c"+34
"vendor/dyncall/dyncallback/dyncall_args.c"+35
"vendor/dyncall/dyncallback/dyncall_alloc_wx.c"+36
"vendor/dyncall/dyncallback/dyncall_callback_arch.S") 37
native-init: "sigil__init_sigil_ffi_module")) 38
39
tasks: (list@@ -41,26 +44,24 @@
44
;; Compile FFI native code + vendored dyncall 45
(compile-c-sources 46
sources: '("native/ffi.c"−44
"../../vendor/dyncall/dyncall/dyncall_api.c"−45
"../../vendor/dyncall/dyncall/dyncall_callvm.c"−46
"../../vendor/dyncall/dyncall/dyncall_callvm_base.c"−47
"../../vendor/dyncall/dyncall/dyncall_vector.c"−48
"../../vendor/dyncall/dyncall/dyncall_callf.c"−49
"../../vendor/dyncall/dyncall/dyncall_aggregate.c"−50
"../../vendor/dyncall/dyncall/dyncall_call.S"−51
"../../vendor/dyncall/dyncallback/dyncall_callback.c"−52
"../../vendor/dyncall/dyncallback/dyncall_thunk.c"−53
"../../vendor/dyncall/dyncallback/dyncall_args.c"−54
"../../vendor/dyncall/dyncallback/dyncall_alloc_wx.c"−55
"../../vendor/dyncall/dyncallback/dyncall_callback_arch.S")−56
include-dirs: '("../sigil-lib/include"−57
"../sigil-lib/src"−58
"../../vendor/dyncall/dyncall"−59
"../../vendor/dyncall/dyncallback")−60
flags: '("-std=c99"−61
"-Wall" "-Wextra"−62
"-Wno-unused-parameter"−63
"-D_GNU_SOURCE"))+47
"vendor/dyncall/dyncall/dyncall_api.c"+48
"vendor/dyncall/dyncall/dyncall_callvm.c"+49
"vendor/dyncall/dyncall/dyncall_callvm_base.c"+50
"vendor/dyncall/dyncall/dyncall_vector.c"+51
"vendor/dyncall/dyncall/dyncall_callf.c"+52
"vendor/dyncall/dyncall/dyncall_aggregate.c"+53
"vendor/dyncall/dyncall/dyncall_call.S"+54
"vendor/dyncall/dyncallback/dyncall_callback.c"+55
"vendor/dyncall/dyncallback/dyncall_thunk.c"+56
"vendor/dyncall/dyncallback/dyncall_args.c"+57
"vendor/dyncall/dyncallback/dyncall_alloc_wx.c"+58
"vendor/dyncall/dyncallback/dyncall_callback_arch.S")+59
include-dirs: '("vendor/dyncall/dyncall"+60
"vendor/dyncall/dyncallback")+61
flags: (with-sigil-c-flags '("-std=c99"+62
"-Wall" "-Wextra"+63
"-Wno-unused-parameter"+64
"-D_GNU_SOURCE"))) 65
66
;; Create static library 67
(create-static-librarysigil.lockadded
@@ -0,0 +1,8 @@
+1
;; Auto-generated by sigil deps install. Do not edit.+2
(lock+3
(package name: "sigil-stdlib"+4
url: "codeberg:sigil/sigil"+5
ref: "^0.13.1"+6
sha: "1aea1cecd3487bf07d071da2c1e7eb3cf4bbdb21"+7
package-selector: "sigil-stdlib")+8
)