Skip to content

Commit 3d81e19

Browse files
author
Stephen Gutekanst
committed
Zig tips: v0.11 std.build API / package manager changes
Signed-off-by: Stephen Gutekanst <[email protected]>
1 parent 3195a3c commit 3d81e19

File tree

2 files changed

+178
-1
lines changed

2 files changed

+178
-1
lines changed

config.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ baseName = "feed"
1717
noClasses=false
1818

1919
[params]
20-
mainSections = ['2021', '2022']
20+
mainSections = ['2021', '2022', '2023']
2121

2222
[taxonomies]
2323
category = "categories"
Lines changed: 177 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
---
2+
author: "Stephen Gutekanst"
3+
title: "Zig tips: v0.11 std.build API / package manager changes"
4+
date: "2023-02-13"
5+
draft: false
6+
categories:
7+
- zig
8+
- zigtips
9+
description: "With Zig v0.11 will come several changes to the std.build API. We've just updated Mach to the latest nightly Zig version, and wanted to provide some tips on how to update your own Zig code."
10+
images: ["https://user-images.githubusercontent.com/3173176/218508235-43e18733-d18d-428a-8475-737f804f590c.png"]
11+
---
12+
13+
We've just updated [Mach engine](https://machengine.org/) to use the latest Zig nightly version, which includes a fair amount of improvements and breaking changes to the `std.build` API used in `build.zig` files, and figured now would be a good time to share the general changes you may need to make if you want to update your own code.
14+
15+
## Package manager: incoming!
16+
17+
Zig is finally starting to see its package manager and build system shape up, some notable mentions:
18+
19+
* `std.http.Client` and `std.crypto.tls` were added ([#13980](https://github.com/ziglang/zig/pull/13980))
20+
* The package manager MVP landed almost a month ago and has seen steady improvements since ([#14265](https://github.com/ziglang/zig/pull/14265))
21+
* Zig packages can now expose C headers are part of their public API ([#14449](https://github.com/ziglang/zig/pull/14449))
22+
* Transitive dependencies are now handled better ([#14392](https://github.com/ziglang/zig/pull/14392))
23+
* "zig build: The breakings will continue until morale improves." ([#14498](https://github.com/ziglang/zig/pull/14498))
24+
* Zig Object Notation (ZON, an alternative to JSON) was introduced ([#14523](https://github.com/ziglang/zig/pull/14523))
25+
* The caching system is being moved from the compiler to the std lib to start using it in the bulid system ([#14571](https://github.com/ziglang/zig/pull/14571))
26+
* Zig plans to run the build system in a sandboxed WASM environment ([#14286](https://github.com/ziglang/zig/issues/14286))
27+
28+
You can get an overview of progress on the package manager on this [GitHub project board](https://github.com/ziglang/zig/projects/4)
29+
30+
Mach isn't yet using the new package manager: it's improving rapidly, and we plan to make use of it soon, but things are still changing so we've held off for now. What we have done, though, is updated to the latest API and want to share those changes with you.
31+
32+
## Release options have been renamed to optimization
33+
34+
Previously you would've used `b.standardReleaseOptions()` which would provide your `zig build` command with multiple options like `zig build -Drelease-fast=true`, `zig build -Drelease-safe=true`, etc.
35+
36+
It's been renamed to `b.standardOptimizeOption(.{})` and now exposes a single build option `zig build -Doptimize=ReleaseFast`, `zig build -Doptimize=ReleaseSafe`, etc. instead.
37+
38+
```diff
39+
-pub fn build(b: *std.build.Builder) void {
40+
- const mode = b.standardReleaseOptions();
41+
- const target = b.standardTargetOptions(.{});
42+
+pub fn build(b: *std.Build) void {
43+
+ const optimize = b.standardOptimizeOption(.{});
44+
+ const target = b.standardTargetOptions(.{});
45+
```
46+
47+
```diff
48+
-mode: std.builtin.Mode
49+
+optimize: std.builtin.OptimizeMode
50+
```
51+
52+
```diff
53+
-step.build_mode
54+
+step.optimize
55+
```
56+
57+
## Creating tests, libraries, and executables
58+
59+
Creating tests, libraries, and executables now takes a struct with options as the parameter instead of using a setter API:
60+
61+
```diff
62+
-const exe = b.addExecutable("example", "src/main.zig");
63+
-exe.setBuildMode(mode);
64+
-exe.setTarget(target);
65+
+const exe = b.addExecutable(.{
66+
+ .name = "example",
67+
+ .root_source_file = "src/main.zig",
68+
+ .target = target,
69+
+ .optimize = optimize,
70+
+});
71+
```
72+
73+
<details>
74+
<summary>See more examples</summary>
75+
76+
Tests:
77+
78+
```diff
79+
-const main_tests = b.addTestExe("glfw-tests", sdkPath("/src/main.zig"));
80+
-main_tests.setBuildMode(mode);
81+
-main_tests.setTarget(target);
82+
+const main_tests = b.addTest(.{
83+
+ .name = "glfw-tests",
84+
+ .kind = .test_exe,
85+
+ .root_source_file = .{ .path = sdkPath("/src/main.zig") },
86+
+ .target = target,
87+
+ .optimize = optimize,
88+
+});
89+
```
90+
91+
Shared libraries:
92+
93+
```diff
94+
-const lib = b.addSharedLibrary("glfw", null, .unversioned)
95+
-lib.setTarget(target);
96+
-lib.setBuildMode(mode);
97+
+b.addSharedLibrary(.{ .name = "glfw", .target = target, .optimize = optimize })
98+
```
99+
100+
```diff
101+
-const lib = b.addSharedLibrary("machcore", "src/platform/libmachcore.zig", .unversioned);
102+
-lib.setTarget(target);
103+
-lib.setBuildMode(mode);
104+
+const lib = b.addSharedLibrary(.{
105+
+ .name = "machcore",
106+
+ .root_source_file = "src/platform/libmachcore.zig",
107+
+ .target = target,
108+
+ .optimize = optimize
109+
+});
110+
```
111+
112+
Static libraries:
113+
114+
```diff
115+
-const lib = b.addStaticLibrary("basisu-transcoder", null);
116+
-lib.setTarget(target);
117+
-lib.setMode(mode);
118+
+const lib = b.addStaticLibrary(.{
119+
+ .name = "basisu-transcoder",
120+
+ .target = target,
121+
+ .optimize = optimize,
122+
+});
123+
```
124+
125+
</details>
126+
127+
## Renamings
128+
129+
* `std.build.LibExeObjStep` has been renamed to just `std.build.CompileStep` (beautiful!)
130+
* `*std.build.Builder` has been renamed to just `*std.Build` (nice, this is used extensively everywhere!)
131+
132+
## Modules
133+
134+
Units of code you `@import("foo")` (previously known as _packages_) are now known as _modules_, and _packages_ now refers to a piece of code you download/depend on using the Zig package manager. _Libraries_ is reserved for referring to C-style libraries, `.dll`s, etc.
135+
136+
These units of code used to be declared as a `std.build.Pkg` struct:
137+
138+
```zig
139+
pub const my_pkg = std.build.Pkg{
140+
.name = "earcut",
141+
.source = .{ .path = "src/main.zig" },
142+
};
143+
```
144+
145+
And added as a dependency using e.g. `exe.addPackage(my_pkg);`
146+
147+
Now, these are called _modules_ and can be created in a few ways. One is using `b.createModule`:
148+
149+
```zig
150+
const my_module = b.createModule(.{
151+
.source_file = .{ .path = "src/main.zig" },
152+
.dependencies = &.{
153+
.{ .name = "core", .module = core.module(b) },
154+
.{ .name = "ecs", .module = ecs.module(b) },
155+
.{ .name = "sysaudio", .module = sysaudio.module(b) },
156+
},
157+
});
158+
```
159+
160+
And then depend on that module using e.g. `exe.addModule("earcut", my_module);`
161+
162+
Notably, modules are created at _runtime_ via the `*std.Build` now - so you may have some reworking to do if you previously depended on `std.build.Pkg` being a global constant you could rely on at comptime.
163+
164+
Another option, which may be preferred, is via [`addModule`](https://github.com/ziglang/zig/blob/fc48467a97021cb872ff2a947f96e882274c39c1/lib/std/Build.zig#L547-L558). It will make the module available to other packages which depend on this package.
165+
166+
You may also like to know that a _pair of dependency name + the module_ can be represented as [`std.Build.ModuleDependency`](https://github.com/ziglang/zig/blob/fc48467a97021cb872ff2a947f96e882274c39c1/lib/std/Build.zig#L560-L563) now.
167+
168+
We've just gone for an initial 1:1 translation in our code, but adoption of the package manager will likely mean structuring your code a bit differently than the above, and the package manager is still a work-in-progress.
169+
170+
## Thanks for reading
171+
172+
As we work towards Mach v0.2, we're getting more serious about what _stability_ means for us. Our intent is to enable us to move quickly, while also helping you to update your code. We will be achieving this through articles like this which help you understand & update your code to the latest APIs. Hopefully this has helped you! You can find other _zig: Tips_ [here](/categories/zigtips/).
173+
174+
<img align="left" style="max-height: 150px;" src="https://user-images.githubusercontent.com/3173176/187348488-0b52e87d-3a48-421c-9402-be78e32b5a20.png"></img>
175+
Be sure to join the [Mach engine Discord](https://discord.gg/XNG3NZgCqp) where we're building the future of Zig game development.
176+
<br><br>
177+
You can also [sponsor my work](https://github.com/sponsors/slimsag) if you like what I'm doing! :)

0 commit comments

Comments
 (0)