-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuild.zig
More file actions
176 lines (154 loc) · 6.82 KB
/
Copy pathbuild.zig
File metadata and controls
176 lines (154 loc) · 6.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
// SPDX-License-Identifier: MPL-2.0
// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
//! Zig FFI Bridge for Proven
//!
//! This build file compiles the Idris 2 RefC output and wraps it in a
//! stable C ABI that can be consumed by Python, Rust, Go, and other languages.
//!
//! Pipeline: Idris2 --codegen refc--> .c files --zig build--> libproven.{so,dylib,dll,a}
//!
//! Build options (pass via -D flags):
//! -Didris-refc=<path> Path to generated RefC .c files (build/refc/)
//! -Didris-refc-runtime=<path> Path to Idris2 RefC runtime headers + libidris2_refc.a
//! -Didris-c-support=<path> Path to Idris2 C support headers (idris_support.h, etc.)
//! -Didris-support-lib=<path> Path to libidris2_support.{a,so}
//!
//! Uses idris2-zig-ffi for generic Idris 2 FFI infrastructure.
const std = @import("std");
/// Configure a compilation step with all Idris2 RefC includes, sources, and libraries.
/// This is the core of the pipeline: it wires up the generated C code, the RefC runtime,
/// and the Idris2 support library so that Zig can link everything into a single artifact.
fn configureRefC(
b: *std.Build,
mod: *std.Build.Module,
refc_path: ?[]const u8,
refc_runtime_path: ?[]const u8,
c_support_path: ?[]const u8,
support_lib_path: ?[]const u8,
) void {
// -----------------------------------------------------------------------
// 1. Generated RefC C sources (from idris2 --codegen refc)
// -----------------------------------------------------------------------
if (refc_path) |rp| {
mod.addIncludePath(.{ .cwd_relative = rp });
if (std.fs.openDirAbsolute(rp, .{ .iterate = true })) |dir_raw| {
var dir = dir_raw;
defer dir.close();
var c_files: std.ArrayListUnmanaged([]const u8) = .empty;
var iter = dir.iterate();
while (iter.next() catch null) |entry| {
if (entry.kind == .file) {
const name = entry.name;
if (std.mem.endsWith(u8, name, ".c")) {
c_files.append(b.allocator, b.allocator.dupe(u8, name) catch @panic("OOM")) catch @panic("OOM");
}
}
}
if (c_files.items.len > 0) {
mod.addCSourceFiles(.{
.root = .{ .cwd_relative = rp },
.files = c_files.items,
.flags = &.{
"-std=c11",
"-fno-strict-aliasing",
"-D_GNU_SOURCE",
},
});
}
} else |_| {
// Directory doesn't exist yet (pre-RefC build)
}
}
// -----------------------------------------------------------------------
// 2. Idris2 RefC runtime headers + static library (libidris2_refc.a)
// -----------------------------------------------------------------------
if (refc_runtime_path) |rrp| {
mod.addIncludePath(.{ .cwd_relative = rrp });
mod.addObjectFile(.{ .cwd_relative = b.fmt("{s}/libidris2_refc.a", .{rrp}) });
}
// -----------------------------------------------------------------------
// 3. Idris2 C support headers (idris_support.h, idris_file.h, etc.)
// -----------------------------------------------------------------------
if (c_support_path) |csp| {
mod.addIncludePath(.{ .cwd_relative = csp });
}
// -----------------------------------------------------------------------
// 4. Idris2 support library (libidris2_support.a / libidris2_support.so)
// -----------------------------------------------------------------------
if (support_lib_path) |slp| {
mod.addLibraryPath(.{ .cwd_relative = slp });
mod.linkSystemLibrary("idris2_support", .{});
}
// -----------------------------------------------------------------------
// 5. System libraries required by RefC runtime
// -----------------------------------------------------------------------
mod.linkSystemLibrary("c", .{});
mod.linkSystemLibrary("pthread", .{});
mod.linkSystemLibrary("m", .{});
mod.linkSystemLibrary("gmp", .{});
}
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// ======================================================================
// Build options for the Idris2 RefC pipeline
// ======================================================================
const refc_path = b.option(
[]const u8,
"idris-refc",
"Path to Idris 2 RefC generated C files (e.g., build/refc/)",
);
const refc_runtime_path = b.option(
[]const u8,
"idris-refc-runtime",
"Path to Idris 2 RefC runtime (headers + libidris2_refc.a)",
);
const c_support_path = b.option(
[]const u8,
"idris-c-support",
"Path to Idris 2 C support headers (idris_support.h, etc.)",
);
const support_lib_path = b.option(
[]const u8,
"idris-support-lib",
"Path to libidris2_support.{a,so} directory",
);
// ======================================================================
// Get idris2-zig-ffi dependency
// ======================================================================
const idris2_zig_ffi_dep = b.dependency("idris2_zig_ffi", .{
.target = target,
.optimize = optimize,
});
const idris2_zig_ffi_mod = idris2_zig_ffi_dep.module("idris2_zig_ffi");
// ======================================================================
// Main library module
// ======================================================================
const proven_mod = b.addModule("proven", .{
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
.imports = &.{
.{ .name = "idris2_zig_ffi", .module = idris2_zig_ffi_mod },
},
});
proven_mod.addIncludePath(b.path("include"));
configureRefC(b, proven_mod, refc_path, refc_runtime_path, c_support_path, support_lib_path);
// ======================================================================
// Static library for embedding (libproven.a)
// ======================================================================
const lib = b.addLibrary(.{
.name = "proven",
.root_module = proven_mod,
});
b.installArtifact(lib);
// ======================================================================
// Tests
// ======================================================================
const mod_tests = b.addTest(.{
.root_module = proven_mod,
});
const run_mod_tests = b.addRunArtifact(mod_tests);
const test_step = b.step("test", "Run library tests");
test_step.dependOn(&run_mod_tests.step);
}