Here’s a quick example of a project setup that you could reference to get started:
If we assume the following directory structure:
.
library/
add.zig
multiply.zig
library.zig
build.zig
build.zig.zon
program/
program.zig
build.zig
build.zig.zon
We want the package named library
to export two modules named add
and multiply
, as well as a convenience module library
that re-exports both add
and multiply
.
// library/add.zig
pub fn addInt(a: i32, b: i32) i32 {
return a + b;
}
pub fn addFloat(a: f32, b: f32) f32 {
return a + b;
}
// library/multiply.zig
pub fn multiplyInt(a: i32, b: i32) i32 {
return a * b;
}
pub fn multiplyFloat(a: f32, b: f32) f32 {
return a * b;
}
// library/library.zig
pub const add = @import("add");
pub const multiply = @import("multiply");
To export these modules, we need to set up the library
package’s build scripts as follows:
// library/build.zig
const std = @import("std");
pub fn build(b: *std.Build) void {
// Note:
// 'b.createModule()' creates a private module.
// 'b.addModule()' creates a public module that can be imported by other build scripts.
// Smaller modules that can be imported individually:
const add_mod = b.addModule("add", .{
.root_source_file = .{ .path = "add.zig" },
});
const multiply_mod = b.addModule("multiply", .{
.root_source_file = .{ .path = "multiply.zig" },
});
// One big module that imports and re-exports the smaller modules:
const library_mod = b.addModule("library", .{
.root_source_file = .{ .path = "library.zig" },
.imports = &.{
.{ .name = "add", .module = add_mod },
.{ .name = "multiply", .module = multiply_mod },
},
});
_ = library_mod;
}
// library/build.zig.zon
.{
.name = "library",
.version = "0.0.0",
.dependencies = .{},
.paths = .{
"",
},
}
Now we have everything we need to be able to add library
as a dependency.
For our program
package which builds an executable, we would like to use the modules exported by the library
package like this:
// program/program.zig
const std = @import("std");
const add = @import("add");
const multiply = @import("multiply");
pub fn main() void {
std.debug.print("{d}\n", .{add.addInt(1, 2)});
std.debug.print("{d}\n", .{multiply.multiplyFloat(3.3, 4.4)});
}
To add the library
package as a dependency, we first add it to program/build.zig.zon
:
// program/build.zig.zon
.{
.name = "program",
.version = "0.0.0",
.dependencies = .{
.library = .{
.path = "../library",
},
},
.paths = .{
"",
},
}
(Side note: .path
here is used for relative packages on disk. If you want to fetch a package over the net (for example, from a public git repo), you use the .url
and .hash
fields. You can run the zig fetch
command like zig fetch https://example.com/library.tar.gz --save=library
to add these fields automatically. And for more general documentation on build.zig.zon
, refer to the output from running zig init
or check out the docs in the ziglang repo.)
Finally, update program/build.zig
to resolve the dependency and import the modules:
// program/build.zig
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "program",
.root_source_file = .{ .path = "program.zig" },
.target = target,
.optimize = optimize,
});
// Resolve the 'library' dependency.
const library_dep = b.dependency("library", .{});
// Import the smaller 'add' and 'multiply' modules exported by the library.
exe.root_module.addImport("add", library_dep.module("add"));
exe.root_module.addImport("multiply", library_dep.module("multiply"));
// But we could also import the larger module if we prefer.
// In this case we would need to update the imports in 'program.zig'
// to '@import("library")' directly.
//exe.root_module.addImport("library", library_dep.module("library"));
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}
I hope this is enough as an example to get you started converting some of your source files into a reusable library