Skip to content

Commit 2c7ec12

Browse files
committed
chore(ffi): modernize zig abi layer and project hygiene
1 parent 47b0415 commit 2c7ec12

6 files changed

Lines changed: 220 additions & 296 deletions

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@ Thumbs.db
1313
# Build
1414
/target/
1515
/_build/
16+
/compiler/_build/
17+
/ffi/zig/.zig-cache/
18+
/ffi/zig/zig-out/
1619
/build/
1720
/dist/
1821
/out/
@@ -25,6 +28,7 @@ Thumbs.db
2528

2629
# Rust
2730
# Cargo.lock # Keep for binaries
31+
/compiler/tangle-lsp/Cargo.lock
2832

2933
# Elixir
3034
/cover/

ABI-FFI-README.md

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,4 @@
1-
{{~ Aditionally delete this line and fill out the template below ~}}
2-
3-
# {{PROJECT}} ABI/FFI Documentation
1+
# TANGLE ABI/FFI Documentation
42

53
## Overview
64

@@ -26,7 +24,7 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design:
2624
2725
┌─────────────────────────────────────────────┐
2826
│ C Headers (auto-generated) │
29-
│ generated/abi/{{project}}.h │
27+
│ generated/abi/tangle.h │
3028
└─────────────────┬───────────────────────────┘
3129
3230
│ imported by
@@ -39,7 +37,7 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design:
3937
│ - Memory-safe by default │
4038
└─────────────────┬───────────────────────────┘
4139
42-
│ compiled to lib{{project}}.so/.a
40+
│ compiled to libtangle.so/.a
4341
4442
┌─────────────────────────────────────────────┐
4543
│ Any Language via C ABI │
@@ -50,7 +48,7 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design:
5048
## Directory Structure
5149

5250
```
53-
{{project}}/
51+
tangle/
5452
├── src/
5553
│ ├── abi/ # ABI definitions (Idris2)
5654
│ │ ├── Types.idr # Core type definitions with proofs
@@ -67,11 +65,11 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design:
6765
│ ├── test/
6866
│ │ └── integration_test.zig
6967
│ └── include/
70-
│ └── {{project}}.h # C header (optional, can be generated)
68+
│ └── tangle.h # C header (optional, can be generated)
7169
7270
├── generated/ # Auto-generated files
7371
│ └── abi/
74-
│ └── {{project}}.h # Generated from Idris2 ABI
72+
│ └── tangle.h # Generated from Idris2 ABI
7573
7674
└── bindings/ # Language-specific wrappers (optional)
7775
├── rust/
@@ -199,7 +197,7 @@ zig build test # Run tests
199197

200198
```bash
201199
cd src/abi
202-
idris2 --cg c-header Types.idr -o ../../generated/abi/{{project}}.h
200+
idris2 --cg c-header Types.idr -o ../../generated/abi/tangle.h
203201
```
204202

205203
### Cross-Compile
@@ -222,32 +220,32 @@ zig build -Dtarget=x86_64-windows
222220
### From C
223221

224222
```c
225-
#include "{{project}}.h"
223+
#include "tangle.h"
226224

227225
int main() {
228-
void* handle = {{project}}_init();
226+
void* handle = tangle_init();
229227
if (!handle) return 1;
230228

231-
int result = {{project}}_process(handle, 42);
229+
int result = tangle_process(handle, 42);
232230
if (result != 0) {
233-
const char* err = {{project}}_last_error();
231+
const char* err = tangle_last_error();
234232
fprintf(stderr, "Error: %s\n", err);
235233
}
236234

237-
{{project}}_free(handle);
235+
tangle_free(handle);
238236
return 0;
239237
}
240238
```
241239

242240
Compile with:
243241
```bash
244-
gcc -o example example.c -l{{project}} -L./zig-out/lib
242+
gcc -o example example.c -ltangle -L./zig-out/lib
245243
```
246244

247245
### From Idris2
248246

249247
```idris
250-
import {{PROJECT}}.ABI.Foreign
248+
import TANGLE.ABI.Foreign
251249
252250
main : IO ()
253251
main = do
@@ -264,44 +262,44 @@ main = do
264262
### From Rust
265263

266264
```rust
267-
#[link(name = "{{project}}")]
265+
#[link(name = "tangle")]
268266
extern "C" {
269-
fn {{project}}_init() -> *mut std::ffi::c_void;
270-
fn {{project}}_free(handle: *mut std::ffi::c_void);
271-
fn {{project}}_process(handle: *mut std::ffi::c_void, input: u32) -> i32;
267+
fn tangle_init() -> *mut std::ffi::c_void;
268+
fn tangle_free(handle: *mut std::ffi::c_void);
269+
fn tangle_process(handle: *mut std::ffi::c_void, input: u32) -> i32;
272270
}
273271

274272
fn main() {
275273
unsafe {
276-
let handle = {{project}}_init();
274+
let handle = tangle_init();
277275
assert!(!handle.is_null());
278276

279-
let result = {{project}}_process(handle, 42);
277+
let result = tangle_process(handle, 42);
280278
assert_eq!(result, 0);
281279

282-
{{project}}_free(handle);
280+
tangle_free(handle);
283281
}
284282
}
285283
```
286284

287285
### From Julia
288286

289287
```julia
290-
const lib{{project}} = "lib{{project}}"
288+
const libtangle = "libtangle"
291289

292290
function init()
293-
handle = ccall((:{{project}}_init, lib{{project}}), Ptr{Cvoid}, ())
291+
handle = ccall((:tangle_init, libtangle), Ptr{Cvoid}, ())
294292
handle == C_NULL && error("Failed to initialize")
295293
handle
296294
end
297295

298296
function process(handle, input)
299-
result = ccall((:{{project}}_process, lib{{project}}), Cint, (Ptr{Cvoid}, UInt32), handle, input)
297+
result = ccall((:tangle_process, libtangle), Cint, (Ptr{Cvoid}, UInt32), handle, input)
300298
result
301299
end
302300

303301
function cleanup(handle)
304-
ccall((:{{project}}_free, lib{{project}}), Cvoid, (Ptr{Cvoid},), handle)
302+
ccall((:tangle_free, libtangle), Cvoid, (Ptr{Cvoid},), handle)
305303
end
306304

307305
# Usage
@@ -355,7 +353,7 @@ When modifying the ABI/FFI:
355353

356354
2. **Generate C header**
357355
```bash
358-
idris2 --cg c-header src/abi/Types.idr -o generated/abi/{{project}}.h
356+
idris2 --cg c-header src/abi/Types.idr -o generated/abi/tangle.h
359357
```
360358

361359
3. **Update FFI implementation** (`ffi/zig/src/main.zig`)

ffi/zig/build.zig

Lines changed: 34 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// {{PROJECT}} FFI Build Configuration
1+
// TANGLE FFI Build Configuration
22
// SPDX-License-Identifier: PMPL-1.0-or-later
33

44
const std = @import("std");
@@ -7,88 +7,60 @@ pub fn build(b: *std.Build) void {
77
const target = b.standardTargetOptions(.{});
88
const optimize = b.standardOptimizeOption(.{});
99

10-
// Shared library (.so, .dylib, .dll)
11-
const lib = b.addSharedLibrary(.{
12-
.name = "{{project}}",
10+
const root_module = b.createModule(.{
1311
.root_source_file = b.path("src/main.zig"),
1412
.target = target,
1513
.optimize = optimize,
14+
.link_libc = true,
1615
});
1716

18-
// Set version
19-
lib.version = .{ .major = 0, .minor = 1, .patch = 0 };
20-
21-
// Static library (.a)
22-
const lib_static = b.addStaticLibrary(.{
23-
.name = "{{project}}",
24-
.root_source_file = b.path("src/main.zig"),
25-
.target = target,
26-
.optimize = optimize,
17+
const lib = b.addLibrary(.{
18+
.name = "tangle",
19+
.root_module = root_module,
20+
.linkage = .dynamic,
21+
.version = .{ .major = 0, .minor = 1, .patch = 0 },
2722
});
28-
29-
// Install artifacts
3023
b.installArtifact(lib);
31-
b.installArtifact(lib_static);
3224

33-
// Generate header file for C compatibility
34-
const header = b.addInstallHeader(
35-
b.path("include/{{project}}.h"),
36-
"{{project}}.h",
37-
);
38-
b.getInstallStep().dependOn(&header.step);
25+
const lib_static = b.addLibrary(.{
26+
.name = "tangle",
27+
.root_module = b.createModule(.{
28+
.root_source_file = b.path("src/main.zig"),
29+
.target = target,
30+
.optimize = optimize,
31+
.link_libc = true,
32+
}),
33+
.linkage = .static,
34+
});
35+
b.installArtifact(lib_static);
3936

40-
// Unit tests
41-
const lib_tests = b.addTest(.{
37+
const unit_mod = b.createModule(.{
4238
.root_source_file = b.path("src/main.zig"),
4339
.target = target,
4440
.optimize = optimize,
41+
.link_libc = true,
4542
});
43+
const unit_tests = b.addTest(.{ .root_module = unit_mod });
44+
const run_unit_tests = b.addRunArtifact(unit_tests);
4645

47-
const run_lib_tests = b.addRunArtifact(lib_tests);
48-
49-
const test_step = b.step("test", "Run library tests");
50-
test_step.dependOn(&run_lib_tests.step);
51-
52-
// Integration tests
53-
const integration_tests = b.addTest(.{
46+
const integration_mod = b.createModule(.{
5447
.root_source_file = b.path("test/integration_test.zig"),
5548
.target = target,
5649
.optimize = optimize,
50+
.link_libc = true,
5751
});
52+
integration_mod.addImport("tangle", root_module);
5853

59-
integration_tests.linkLibrary(lib);
60-
54+
const integration_tests = b.addTest(.{ .root_module = integration_mod });
6155
const run_integration_tests = b.addRunArtifact(integration_tests);
6256

63-
const integration_test_step = b.step("test-integration", "Run integration tests");
64-
integration_test_step.dependOn(&run_integration_tests.step);
65-
66-
// Documentation
67-
const docs = b.addTest(.{
68-
.root_source_file = b.path("src/main.zig"),
69-
.target = target,
70-
.optimize = .Debug,
71-
});
72-
73-
const docs_step = b.step("docs", "Generate documentation");
74-
docs_step.dependOn(&b.addInstallDirectory(.{
75-
.source_dir = docs.getEmittedDocs(),
76-
.install_dir = .prefix,
77-
.install_subdir = "docs",
78-
}).step);
79-
80-
// Benchmark (if needed)
81-
const bench = b.addExecutable(.{
82-
.name = "{{project}}-bench",
83-
.root_source_file = b.path("bench/bench.zig"),
84-
.target = target,
85-
.optimize = .ReleaseFast,
86-
});
87-
88-
bench.linkLibrary(lib);
57+
const unit_step = b.step("test", "Run Zig unit tests");
58+
unit_step.dependOn(&run_unit_tests.step);
8959

90-
const run_bench = b.addRunArtifact(bench);
60+
const integration_step = b.step("test-integration", "Run Zig integration tests");
61+
integration_step.dependOn(&run_integration_tests.step);
9162

92-
const bench_step = b.step("bench", "Run benchmarks");
93-
bench_step.dependOn(&run_bench.step);
63+
const all_step = b.step("test-all", "Run all Zig tests");
64+
all_step.dependOn(&run_unit_tests.step);
65+
all_step.dependOn(&run_integration_tests.step);
9466
}

0 commit comments

Comments
 (0)