Zig Build Dependencies
A dependency is code from another package that a program uses. This lesson wires a local package into a program through a path dependency.
A library in a folder
The greetlib folder holds one library file, and the manifest points at it by path.
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "greetapp",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
const greetlib = b.dependency("greetlib", .{});
exe.root_module.addImport("greetlib", greetlib.module("greetlib"));
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);
}
Using more of the library
One wired library can offer many functions, and the program calls each by name.
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "greetapp",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
const greetlib = b.dependency("greetlib", .{});
exe.root_module.addImport("greetlib", greetlib.module("greetlib"));
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);
}
Combining library calls
One program can call several library functions and print each result.
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "greetapp",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
const greetlib = b.dependency("greetlib", .{});
exe.root_module.addImport("greetlib", greetlib.module("greetlib"));
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);
}
Example
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
const exe = b.addExecutable(.{
.name = "greetapp",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
const greetlib = b.dependency("greetlib", .{});
exe.root_module.addImport("greetlib", greetlib.module("greetlib"));
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);
}
Key points
- Dependency: a dependency is code from another package that a program uses.
- Package: a package is a folder with its own build script and manifest.
- Manifest: a manifest is the build.zig.zon file, which lists a package name, version, and its dependencies.
- Path dependency: a path dependency is a dependency that points at a folder inside the project.
- Fingerprint: a fingerprint is a number in the manifest that identifies the package.
- Remote dependency: a remote dependency is a dependency fetched from a network address, so fetching one needs network access.
- Plain zig build still resolves the library, so the program is built without running.
The manifest declares greetlib as a path dependency on the vendor folder. The build script asks for that package by name and wires its module into the program. The program calls the library add function with 3 and 4. The printed sum comes from library code, not from the program file.
Try it Yourself
Edit the code, then press Run.
Running is simulated
Exercise
Which file declares the greetlib path dependency?