### Install Zig using Package Managers Source: https://ziglang.org/learn/getting-started Commands to install Zig using various package managers on different operating systems. ```bash # Windows (WinGet) winget install -e --id zig.zig # Windows (Chocolatey) choco install zig # Windows (Scoop) scoop install zig scoop bucket add versions scoop install versions/zig-dev # macOS (Homebrew) brew install zig # macOS (MacPorts) sudo port install zig ``` -------------------------------- ### Initialize and Run Zig 'Hello World' Source: https://ziglang.org/learn/getting-started Commands to create a new Zig project, initialize it with default files, compile, and run the 'Hello World' application. ```bash mkdir hello-world cd hello-world zig init zig build run ``` -------------------------------- ### Zig Build Script for Executable and Installation Source: https://ziglang.org/learn/build-system Defines a Zig build script to create an executable named 'hello' from 'src/main.zig', set optimization level, and add an installation artifact. The script depends on the 'target' variable and ensures the installation step is executed. ```zig const optimize = b.standardOptimizeOption(.{}); const exe = b.addExecutable(.{ .name = "hello", .root_module = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, }), }); const install_artifact = b.addInstallArtifact(exe, .{ .dest_dir = .{ .override = .prefix }, }); b.getInstallStep().dependOn(&install_artifact.step); ``` -------------------------------- ### Zig Shell Command for Conditional Build Source: https://ziglang.org/learn/build-system Example shell command to build the Zig project and enable the 'enable-demo' option, which installs the demo executable alongside the library. ```shell `zig build --summary all -Denable-demo` ``` -------------------------------- ### Zig Shell Command for Building Source: https://ziglang.org/learn/build-system Example shell command to build the Zig project with the '--summary all' flag, which provides detailed output of the build process steps and their outcomes. ```shell `zig build --summary all` ``` -------------------------------- ### Set Zig PATH on Linux, macOS, BSD Source: https://ziglang.org/learn/getting-started Appends the Zig binary directory to the PATH environment variable by adding an export line to a shell startup script (e.g., .profile, .zshrc). ```bash export PATH=$PATH:~/path/to/zig ``` -------------------------------- ### Zig: Simple Executable Creation Source: https://ziglang.org/learn/build-system This snippet demonstrates how to create a simple executable 'Hello World!' program using Zig. It includes the Zig source file and the corresponding build script that compiles and installs the executable. ```zig const std = @import("std"); pub fn main() !void { std.debug.print("Hello World!\n", .{}); } ``` ```zig const std = @import("std"); pub fn build(b: *std.Build) void { const exe = b.addExecutable(.{ .name = "hello", .root_module = b.createModule(.{ .root_source_file = b.path("hello.zig"), .target = b.graph.host, }), }); b.installArtifact(exe); } ``` -------------------------------- ### Shell Command to Build Zig Project Source: https://ziglang.org/learn/build-system This snippet shows the shell command used to build the Zig project. The command `zig build --summary all` compiles the project, runs any necessary tools (like the code generator), and installs the final executable. The output provides a summary of the build steps, indicating success or failure for each phase, including compilation, running artifacts, and installation. ```shell $ `zig build --summary all` Build Summary: 5/5 steps succeeded install success └─ install hello success └─ compile exe hello Debug native success 1s MaxRSS:121M └─ run exe generate_struct (person.zig) success 358us MaxRSS:3M └─ compile exe generate_struct Debug native success 2s MaxRSS:121M ``` -------------------------------- ### Shell Command to Build Project with Generated Archive Source: https://ziglang.org/learn/build-system This command executes the Zig build process. It compiles the main application, generates a version file, packages the application executable and version file into a tarball named `project.tar.gz`, and then installs this archive. The output summary details each step, including file writing, tar command execution, and installation. ```shell $ `zig build --summary all` Build Summary: 5/5 steps succeeded install success └─ install generated to project.tar.gz success └─ run tar (project.tar.gz) success 981ms MaxRSS:2M └─ WriteFile project/app success └─ compile exe app Debug native success 1s MaxRSS:126M ``` -------------------------------- ### Zig Build Output Directory Structure Source: https://ziglang.org/learn/build-system Illustrates the expected directory structure after a successful Zig build process, showing the 'zig-out' directory containing the installed executable 'hello' and the 'word.txt' artifact. ```text zig-out ├── hello └── word.txt ``` -------------------------------- ### Define Zig Application and Build Configuration Source: https://ziglang.org/learn/build-system This snippet shows a basic Zig program 'hello.zig' that prints 'Hello World!'. The 'build.zig' file configures the build system to compile 'hello.zig' into an executable named 'hello' and installs it. It also defines a 'run' step that depends on the execution of the compiled artifact. ```zig const std = @import("std"); pub fn main() !void { std.debug.print("Hello World!\n", .{}); } ``` ```zig const std = @import("std"); pub fn build(b: *std.Build) void { const exe = b.addExecutable(.{ .name = "hello", .root_module = b.createModule(.{ .root_source_file = b.path("hello.zig"), .target = b.graph.host, }), }); b.installArtifact(exe); const run_exe = b.addRunArtifact(exe); const run_step = b.step("run", "Run the application"); run_step.dependOn(&run_exe.step); } ``` -------------------------------- ### Configurable Build Options in Zig Source: https://ziglang.org/learn/build-system Demonstrates how to use `b.option` in a `build.zig` script to allow users and dependent projects to configure build settings. This example shows how to conditionally set the target operating system based on a boolean option. ```zig const std = @import("std"); pub fn build(b: *std.Build) void { const windows = b.option(bool, "windows", "Target Microsoft Windows") orelse false; const exe = b.addExecutable(.{ .name = "hello", .root_module = b.createModule(.{ .root_source_file = b.path("example.zig"), .target = b.resolveTargetQuery(.{ .os_tag = if (windows) .windows else null, }), }), }); b.installArtifact(exe); } ``` -------------------------------- ### Set Zig PATH on Windows (System-wide) Source: https://ziglang.org/learn/getting-started Adds the Zig installation directory to the system-wide PATH environment variable on Windows. Requires running PowerShell as an administrator. Ensure the path points to your Zig installation. ```powershell [Environment]::SetEnvironmentVariable( "Path", [Environment]::GetEnvironmentVariable("Path", "Machine") + ";C:\\your-path\\zig-windows-x86_64-your-version", "Machine" ) ``` -------------------------------- ### Set Zig PATH on Windows (User-level) Source: https://ziglang.org/learn/getting-started Adds the Zig installation directory to the user-level PATH environment variable on Windows. This can be run from a standard PowerShell instance. Ensure the path points to your Zig installation. ```powershell [Environment]::SetEnvironmentVariable( "Path", [Environment]::GetEnvironmentVariable("Path", "User") + ";C:\\your-path\\zig-windows-x86_64-your-version", "User" ) ``` -------------------------------- ### Zig Unit Test Example Source: https://ziglang.org/learn/build-system A simple Zig unit test that initializes an ArrayList, appends an integer, and then expects that the appended integer is successfully retrieved. ```zig const std = @import("std"); test "simple test" { var list = std.ArrayList(i32).init(std.testing.allocator); defer list.deinit(); try list.append(42); try std.testing.expectEqual(@as(i32, 42), list.pop()); } ``` -------------------------------- ### Zig Build Command Help Source: https://ziglang.org/learn/overview Displays the help menu for the `zig build` command, outlining available steps (e.g., install, run, test) and various general and project-specific options for configuring the build process. ```bash $ zig build --help Usage: zig build [steps] [options] Steps: install (default) Copy build artifacts to prefix path uninstall Remove build artifacts from prefix path run Run the app test Run unit tests General Options: -p, --prefix [path] Where to install files (default: zig-out) --prefix-lib-dir [path] Where to install libraries --prefix-exe-dir [path] Where to install executables --prefix-include-dir [path] Where to install C header files --release[=mode] Request release mode, optionally specifying a preferred optimization mode: fast, safe, small -fdarling, -fno-darling Integration with system-installed Darling to execute macOS programs on Linux hosts (default: no) -fqemu, -fno-qemu Integration with system-installed QEMU to execute foreign-architecture programs on Linux hosts (default: no) --glibc-runtimes [path] Enhances QEMU integration by providing glibc built for multiple foreign architectures, allowing execution of non-native programs that link with glibc. -frosetta, -fno-rosetta Rely on Rosetta to execute x86_64 programs on ARM64 macOS hosts. (default: no) -fwasmtime, -fno-wasmtime Integration with system-installed wasmtime to execute WASI binaries. (default: no) -fwine, -fno-wine Integration with system-installed Wine to execute Windows programs on Linux hosts. (default: no) -h, --help Print this help and exit -l, --list-steps Print available steps --verbose Print commands before executing them --color [auto|off|on] Enable or disable colored error messages --prominent-compile-errors Buffer compile errors and display at end --summary [mode] Control the printing of the build summary all Print the build summary in its entirety new Omit cached steps failures (Default) Only print failed steps none Do not print the build summary -j Limit concurrent jobs (default is to use all CPU cores) --maxrss Limit memory usage (default is to use available memory) --skip-oom-steps Instead of failing, skip steps that would exceed --maxrss --fetch Exit after fetching dependency tree --watch Continuously rebuild when source files are modified --fuzz Continuously search for unit test failures --debounce Delay before rebuilding after changed file detected -fincremental Enable incremental compilation -fno-incremental Disable incremental compilation Project-Specific Options: -Dtarget=[string] The CPU architecture, OS, and ABI to build for -Dcpu=[string] Target CPU features to add or subtract -Dofmt=[string] Target object format -Ddynamic-linker=[string] Path to interpreter on the target system -Doptimize=[enum] Prioritize performance, safety, or binary size Supported Values: Debug ReleaseSafe ReleaseFast ReleaseSmall System Integration Options: --search-prefix [path] Add a path to look for binaries, libraries, headers --sysroot [path] Set the system root directory (usually /) --libc [file] Provide a file which specifies libc paths ``` -------------------------------- ### C Interoperability in Zig Source: https://ziglang.org/learn/samples An example of importing a C header file (`raylib.h`) and linking against C libraries (`libc` and `raylib`) to create a basic window with raylib. This highlights Zig's seamless C interop. ```zig // build with `zig build-exe c-interop.zig -lc -lraylib` const ray = @cImport({ @cInclude("raylib.h"); }); pub fn main() void { const screenWidth = 800; const screenHeight = 450; ray.InitWindow(screenWidth, screenHeight, "raylib [core] example - basic window"); defer ray.CloseWindow(); ray.SetTargetFPS(60); while (!ray.WindowShouldClose()) { ray.BeginDrawing(); defer ray.EndDrawing(); ray.ClearBackground(ray.RAYWHITE); ray.DrawText("Hello, World!", 190, 200, 20, ray.LIGHTGRAY); } } ``` -------------------------------- ### Create word.txt using jq (Build Script) Source: https://ziglang.org/learn/build-system This Zig build script uses the 'jq' system command to extract a specific language string from 'words.json' and save it to 'word.txt'. It depends on 'jq' being installed on the system. The output is captured and installed as a file. ```zig const std = @import("std"); pub fn build(b: *std.Build) void { const lang = b.option([]const u8, "language", "language of the greeting") orelse "en"; const tool_run = b.addSystemCommand(&.{"jq"}); tool_run.addArgs(&.{ b.fmt( \.["{s}"] , .{lang}), "-r", // raw output to omit quotes around the selected string }); tool_run.addFileArg(b.path("words.json")); const output = tool_run.captureStdOut(); b.getInstallStep().dependOn(&b.addInstallFileWithDir(output, .prefix, "word.txt").step); const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); const exe = b.addExecutable(.{ .name = "hello", .root_module = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, }), }); const install_artifact = b.addInstallArtifact(exe, .{ .dest_dir = .{ .override = .prefix }, }); b.getInstallStep().dependOn(&install_artifact.step); } ``` -------------------------------- ### Execute Zig Application using Build Command Source: https://ziglang.org/learn/build-system This example demonstrates how to run a compiled Zig application using the custom 'run' step defined in the 'build.zig' file. The command 'zig build run' compiles the application if necessary and then executes it. The output shows the application's print statement and a summary of the build process. ```shell $ `zig build run --summary all` Hello World! Build Summary: 3/3 steps succeeded run success └─ run exe hello success 233us MaxRSS:1M └─ compile exe hello Debug native success 1s MaxRSS:118M ``` -------------------------------- ### Example Zig Build Command with Version Option Source: https://ziglang.org/learn/build-system This shell command illustrates how to build a Zig project and pass a custom version string using the `-Dversion` flag. This option is then made available to the Zig code through the build system's configuration mechanism. ```shell $ zig build -Dversion=1.2.3 --summary all ``` -------------------------------- ### Example Zig Build Command with Custom Options Source: https://ziglang.org/learn/build-system This is a shell command demonstrating how to build a Zig project with specific target and optimization settings. The `-Dtarget` flag specifies the target architecture, OS, and ABI, while `-Doptimize` selects the optimization level. The `--summary all` flag provides detailed build information. ```shell $ zig build -Dtarget=x86_64-windows -Doptimize=ReleaseSmall --summary all ``` -------------------------------- ### Execute Zig build command Source: https://ziglang.org/learn/build-system This shell command builds the Zig project, specifying the language for the greeting using a build option. It also shows the summary of the build steps and installation process. ```shell $ `zig build -Dlanguage=ja --summary all` ``` -------------------------------- ### Zig Build Test Execution Output Source: https://ziglang.org/learn/build-system Example output from running Zig unit tests using the build script, showing test steps, compilation status, and any encountered errors during testing across different targets. ```shell $ `zig build test --summary all` test └─ run test └─ compile test Debug native 1 errors /home/ci/actions-runner-website/_work/www.ziglang.org/www.ziglang.org/zig-code/build-system/unit-testing/main.zig:4:34: error: struct 'array_list.Aligned(i32,null)' has no member named 'init' var list = std.ArrayList(i32).init(std.testing.allocator); ~~~~~~~~~~~~~~~~~~^~~~~ /home/ci/deps/zig-x86_64-linux-0.15.1/lib/std/array_list.zig:606:12: note: struct declared here return struct { ^~~~~~ error: the following command failed with 1 compilation errors: /home/ci/deps/zig-x86_64-linux-0.15.1/zig test -Mroot=/home/ci/actions-runner-website/_work/www.ziglang.org/www.ziglang.org/zig-code/build-system/unit-testing/main.zig --cache-dir /home/ci/actions-runner-website/_work/www.ziglang.org/www.ziglang.org/zig-code/build-system/unit-testing/.zig-cache --global-cache-dir /home/ci/.cache/zig --name test --zig-lib-dir /home/ci/deps/zig-x86_64-linux-0.15.1/lib/ --listen=- test └─ run test └─ compile test Debug aarch64-macos 1 errors /home/ci/actions-runner-website/_work/www.ziglang.org/www.ziglang.org/zig-code/build-system/unit-testing/main.zig:4:34: error: struct 'array_list.Aligned(i32,null)' has no member named 'init' var list = std.ArrayList(i32).init(std.testing.allocator); ~~~~~~~~~~~~~~~~~~^~~~~ /home/ci/deps/zig-x86_64-linux-0.15.1/lib/std/array_list.zig:606:12: note: struct declared here return struct { ^~~~~~ error: the following command failed with 1 compilation errors: /home/ci/deps/zig-x86_64-linux-0.15.1/zig test -target aarch64-macos -mcpu baseline -Mroot=/home/ci/actions-runner-website/_work/www.ziglang.org/www.ziglang.org/zig-code/build-system/unit-testing/main.zig --cache-dir /home/ci/actions-runner-website/_work/www.ziglang.org/www.ziglang.org/zig-code/build-system/unit-testing/.zig-cache --global-cache-dir /home/ci/.cache/zig --name test --zig-lib-dir /home/ci/deps/zig-x86_64-linux-0.15.1/lib/ --listen=- test └─ run test └─ compile test Debug x86_64-linux 1 errors /home/ci/actions-runner-website/_work/www.ziglang.org/www.ziglang.org/zig-code/build-system/unit-testing/main.zig:4:34: error: struct 'array_list.Aligned(i32,null)' has no member named 'init' var list = std.ArrayList(i32).init(std.testing.allocator); ~~~~~~~~~~~~~~~~~~^~~~~ /home/ci/deps/zig-x86_64-linux-0.15.1/lib/std/array_list.zig:606:12: note: struct declared here return struct { ^~~~~~ error: the following command failed with 1 compilation errors: ``` -------------------------------- ### Shell Command to Display Build Summary Source: https://ziglang.org/learn/build-system A shell command to execute the Zig build system and display a detailed summary of all build steps, including compilation and installation times. This is useful for diagnosing build performance and success rates. ```shell $ `zig build --summary all` ``` -------------------------------- ### Zig Build System: Handling Generated Files with WriteFiles Source: https://ziglang.org/learn/build-system This section demonstrates how to use Zig's build system to generate files and package them. The `build.zig` file utilizes `b.addWriteFiles()` to create a directory for generated content. It copies an executable artifact and a version string into this directory. Subsequently, a `tar` command is used to archive these generated files, which is then installed as a distributable artifact. ```zig const std = @import("std"); pub fn main() !void { std.debug.print("hello world\n", .{}); } ``` ```zig const std = @import("std"); pub fn build(b: *std.Build) void { const exe = b.addExecutable(.{ .name = "app", .root_module = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = b.graph.host, }), }); const version = b.option([]const u8, "version", "application version string") orelse "0.0.0"; const wf = b.addWriteFiles(); const app_exe_name = b.fmt("project/{s}", .{exe.out_filename}); _ = wf.addCopyFile(exe.getEmittedBin(), app_exe_name); _ = wf.add("project/version.txt", version); const tar = b.addSystemCommand(&.{ "tar", "czf" }); tar.setCwd(wf.getDirectory()); const out_file = tar.addOutputFileArg("project.tar.gz"); tar.addArgs(&.{"project/"}); const install_tar = b.addInstallFileWithDir(out_file, .prefix, "project.tar.gz"); b.getInstallStep().dependOn(&install_tar.step); } ``` -------------------------------- ### Zig Build Script for Static Library and Executable Source: https://ziglang.org/learn/build-system Configures a Zig build for a static library named 'fizzbuzz' and an executable named 'demo'. The executable links against the static library. Includes an option to conditionally install the 'demo' executable. ```zig const std = @import("std"); pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); const libfizzbuzz = b.addLibrary(.{ .name = "fizzbuzz", .linkage = .static, .root_module = b.createModule(.{ .root_source_file = b.path("fizzbuzz.zig"), .target = target, .optimize = optimize, }), }); const exe = b.addExecutable(.{ .name = "demo", .root_module = b.createModule(.{ .root_source_file = b.path("demo.zig"), .target = target, .optimize = optimize, }), }); exe.linkLibrary(libfizzbuzz); b.installArtifact(libfizzbuzz); if (b.option(bool, "enable-demo", "install the demo too") orelse false) { b.installArtifact(exe); } } ``` -------------------------------- ### Zig: Handling Errors with 'catch' Source: https://ziglang.org/learn/overview Illustrates how to handle errors using the 'catch' keyword. This example explicitly catches a file opening error, prints a message, and then proceeds to write to the file (if successfully opened). ```zig const std = @import("std"); pub fn main() void { const file: std.fs.File = std.fs.cwd().openFile("does_not_exist/foo.txt", .{}) catch |err| label: { std.debug.print("unable to open file: {}\n", .{err}); break :label .stderr(); }; file.writeAll("all your codebase are belong to us\n") catch return; } ``` -------------------------------- ### Configure Multi-Target Builds in Zig Source: https://ziglang.org/learn/build-system This Zig code defines build targets for different architectures and operating systems. It iterates through these targets, compiling an executable for each and configuring the installation path to be specific to the target triple. Dependencies include the Zig standard library. ```zig const std = @import("std"); const targets: []const std.Target.Query = &.{ .{ .cpu_arch = .aarch64, .os_tag = .macos }, .{ .cpu_arch = .aarch64, .os_tag = .linux }, .{ .cpu_arch = .x86_64, .os_tag = .linux, .abi = .gnu }, .{ .cpu_arch = .x86_64, .os_tag = .linux, .abi = .musl }, .{ .cpu_arch = .x86_64, .os_tag = .windows }, }; pub fn build(b: *std.Build) !void { for (targets) |t| { const exe = b.addExecutable(.{ .name = "hello", .root_module = b.createModule(.{ .root_source_file = b.path("hello.zig"), .target = b.resolveTargetQuery(t), .optimize = .ReleaseSafe, }), }); const target_output = b.addInstallArtifact(exe, .{ .dest_dir = .{ .override = .{ .custom = try t.zigTriple(b.allocator), }, }, }); b.getInstallStep().dependOn(&target_output.step); } } ``` -------------------------------- ### Integrate cURL Library with Zig Source: https://ziglang.org/learn/samples This Zig code snippet demonstrates how to use the cURL library to make an HTTP GET request to 'https://ziglang.org'. It initializes cURL, sets up an easy handle, configures options like the URL and a write callback function to capture the response, performs the request, and prints the response size and content. Dependencies include libcurl and C build tools. Error handling for cURL operations is included. ```zig // compile with `zig build-exe zig-curl-test.zig --library curl --library c $(pkg-config --cflags libcurl)` const std = @import("std"); const cURL = @cImport({ @cInclude("curl/curl.h"); }); pub fn main() !void { var arena_state = std.heap.ArenaAllocator.init(std.heap.c_allocator); defer arena_state.deinit(); const allocator = arena_state.allocator(); // global curl init, or fail if (cURL.curl_global_init(cURL.CURL_GLOBAL_ALL) != cURL.CURLE_OK) return error.CURLGlobalInitFailed; defer cURL.curl_global_cleanup(); // curl easy handle init, or fail const handle = cURL.curl_easy_init() orelse return error.CURLHandleInitFailed; defer cURL.curl_easy_cleanup(handle); var response_buffer = std.ArrayList(u8).init(allocator); // superfluous when using an arena allocator, but // important if the allocator implementation changes defer response_buffer.deinit(); // setup curl options if (cURL.curl_easy_setopt(handle, cURL.CURLOPT_URL, "https://ziglang.org") != cURL.CURLE_OK) return error.CouldNotSetURL; // set write function callbacks if (cURL.curl_easy_setopt(handle, cURL.CURLOPT_WRITEFUNCTION, writeToArrayListCallback) != cURL.CURLE_OK) return error.CouldNotSetWriteCallback; if (cURL.curl_easy_setopt(handle, cURL.CURLOPT_WRITEDATA, &response_buffer) != cURL.CURLE_OK) return error.CouldNotSetWriteCallback; // perform if (cURL.curl_easy_perform(handle) != cURL.CURLE_OK) return error.FailedToPerformRequest; std.log.info("Got response of {d} bytes", .{response_buffer.items.len}); std.debug.print("{s}\n", .{response_buffer.items}); } fn writeToArrayListCallback(data: *anyopaque, size: c_uint, nmemb: c_uint, user_data: *anyopaque) callconv(.C) c_uint { var buffer: *std.ArrayList(u8) = @alignCast(@ptrCast(user_data)); var typed_data: [*]u8 = @ptrCast(data); buffer.appendSlice(typed_data[0 .. nmemb * size]) catch return 0; return nmemb * size; } ``` -------------------------------- ### Zig: Execute JSON Word Selector Tool at Build-Time Source: https://ziglang.org/learn/build-system This Zig build script configures and runs a tool ('word_select') during the build process. The tool reads from a JSON file, selects a word based on a language argument, and writes it to a text file. The output file is then installed as part of the build artifacts. It depends on the Zig build system and standard library. ```zig const std = @import("std"); pub fn build(b: *std.Build) void { const lang = b.option([]const u8, "language", "language of the greeting") orelse "en"; const tool = b.addExecutable(.{ .name = "word_select", .root_module = b.createModule(.{ .root_source_file = b.path("tools/word_select.zig"), .target = b.graph.host, }), }); const tool_step = b.addRunArtifact(tool); tool_step.addArg("--input-file"); tool_step.addFileArg(b.path("tools/words.json")); tool_step.addArg("--output-file"); const output = tool_step.addOutputFileArg("word.txt"); tool_step.addArgs(&.{ "--lang", lang }); b.getInstallStep().dependOn(&b.addInstallFileWithDir(output, .prefix, "word.txt").step); const target = b.standardTargetOptions(.{}); } ``` -------------------------------- ### Zig Compile-time Code Execution with comptime and Assertions Source: https://ziglang.org/learn/overview This example demonstrates Zig's comptime keyword for evaluating code at compile time. It includes a recursive Fibonacci function and a test case that uses comptime to assert the length of a dynamically sized array. This highlights how comptime can be used for compile-time checks and computations. ```zig const std = @import("std"); const assert = std.debug.assert; fn fibonacci(x: u32) u32 { if (x <= 1) return x; return fibonacci(x - 1) + fibonacci(x - 2); } test "compile-time evaluation" { var array: [fibonacci(6)]i32 = undefined; @memset(&array, 42); comptime { assert(array.len == 12345); } } ``` -------------------------------- ### Emit Sine Wave using libsoundio in Zig Source: https://ziglang.org/learn/overview This Zig code snippet demonstrates how to integrate with the C 'libsoundio' library to generate and play a sine wave. It utilizes Zig's @cImport to directly include the 'soundio/soundio.h' header, enabling the use of C functions and types within Zig. The code defines a write callback function that generates audio samples and plays them through the default audio output device. It requires the 'soundio' library to be installed and linked during compilation. ```zig const c = @cImport(@cInclude("soundio/soundio.h")); const std = @import("std"); fn sio_err(err: c_int) !void { switch (err) { c.SoundIoErrorNone => {}, c.SoundIoErrorNoMem => return error.NoMem, c.SoundIoErrorInitAudioBackend => return error.InitAudioBackend, c.SoundIoErrorSystemResources => return error.SystemResources, c.SoundIoErrorOpeningDevice => return error.OpeningDevice, c.SoundIoErrorNoSuchDevice => return error.NoSuchDevice, c.SoundIoErrorInvalid => return error.Invalid, c.SoundIoErrorBackendUnavailable => return error.BackendUnavailable, c.SoundIoErrorStreaming => return error.Streaming, c.SoundIoErrorIncompatibleDevice => return error.IncompatibleDevice, c.SoundIoErrorNoSuchClient => return error.NoSuchClient, c.SoundIoErrorIncompatibleBackend => return error.IncompatibleBackend, c.SoundIoErrorBackendDisconnected => return error.BackendDisconnected, c.SoundIoErrorInterrupted => return error.Interrupted, c.SoundIoErrorUnderflow => return error.Underflow, c.SoundIoErrorEncodingString => return error.EncodingString, else => return error.Unknown, } } var seconds_offset: f32 = 0; fn write_callback( maybe_outstream: ?[*]c.SoundIoOutStream, frame_count_min: c_int, frame_count_max: c_int, ) callconv(.C) void { _ = frame_count_min; const outstream: *c.SoundIoOutStream = &maybe_outstream.?[0]; const layout = &outstream.layout; const float_sample_rate: f32 = @floatFromInt(outstream.sample_rate); const seconds_per_frame = 1.0 / float_sample_rate; var frames_left = frame_count_max; while (frames_left > 0) { var frame_count = frames_left; var areas: [*]c.SoundIoChannelArea = undefined; sio_err(c.soundio_outstream_begin_write( maybe_outstream, @ptrCast(&areas), &frame_count, )) catch |err| std.debug.panic("write failed: {s}", .{@errorName(err)}); if (frame_count == 0) break; const pitch = 440.0; const radians_per_second = pitch * 2.0 * std.math.pi; var frame: c_int = 0; while (frame < frame_count) : (frame += 1) { const float_frame: f32 = @floatFromInt(frame); const sample = std.math.sin((seconds_offset + float_frame * seconds_per_frame) * radians_per_second); { var channel: usize = 0; while (channel < @as(usize, @intCast(layout.channel_count))) : (channel += 1) { const channel_ptr = areas[channel].ptr; const sample_ptr: *f32 = @alignCast(@ptrCast(&channel_ptr[@intCast(areas[channel].step * frame)])); sample_ptr.* = sample; } } } const float_frame_count: f32 = @floatFromInt(frame_count); seconds_offset += seconds_per_frame * float_frame_count; sio_err(c.soundio_outstream_end_write(maybe_outstream)) catch |err| std.debug.panic("end write failed: {s}", .{@errorName(err)}); frames_left -= frame_count; } } pub fn main() !void { const soundio = c.soundio_create(); defer c.soundio_destroy(soundio); try sio_err(c.soundio_connect(soundio)); c.soundio_flush_events(soundio); const default_output_index = c.soundio_default_output_device_index(soundio); if (default_output_index < 0) return error.NoOutputDeviceFound; const device = c.soundio_get_output_device(soundio, default_output_index) orelse return error.OutOfMemory; defer c.soundio_device_unref(device); std.debug.print("Output device: {s} ", .{device.*.name}); const outstream = c.soundio_outstream_create(device) orelse return error.OutOfMemory; defer c.soundio_outstream_destroy(outstream); outstream.*.format = c.SoundIoFormatFloat32NE; outstream.*.write_callback = write_callback; try sio_err(c.soundio_outstream_open(outstream)); try sio_err(c.soundio_outstream_start(outstream)); while (true) c.soundio_wait_events(soundio); } ``` -------------------------------- ### Build Executable with Standard Target and Optimization Options Source: https://ziglang.org/learn/build-system This snippet demonstrates how to define a Zig executable and configure its target and optimization level using Zig's standard build options. It takes target and optimization settings from the command line. The 'hello.zig' file is the entry point for the executable. ```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 = "hello", .root_module = b.createModule(.{ .root_source_file = b.path("hello.zig"), .target = target, .optimize = optimize, }), }); b.installArtifact(exe); } ``` ```zig const std = @import("std"); pub fn main() !void { std.debug.print("Hello World!\n", .{}); } ``` -------------------------------- ### Zig Build Command Help and Options Source: https://ziglang.org/learn/build-system Provides an overview of the `zig build` command-line interface, including available steps, general options, project-specific options, system integration options, and advanced configurations. This helps users understand how to invoke the build process and customize it. ```shell $ `zig build --help` Usage: /home/ci/deps/zig-x86_64-linux-0.15.1/zig build [steps] [options] Steps: install (default) Copy build artifacts to prefix path uninstall Remove build artifacts from prefix path General Options: -p, --prefix [path] Where to install files (default: zig-out) --prefix-lib-dir [path] Where to install libraries --prefix-exe-dir [path] Where to install executables --prefix-include-dir [path] Where to install C header files --release[=mode] Request release mode, optionally specifying a preferred optimization mode: fast, safe, small -fdarling, -fno-darling Integration with system-installed Darling to execute macOS programs on Linux hosts (default: no) -fqemu, -fno-qemu Integration with system-installed QEMU to execute foreign-architecture programs on Linux hosts (default: no) --libc-runtimes [path] Enhances QEMU integration by providing dynamic libc (e.g. glibc or musl) built for multiple foreign architectures, allowing execution of non-native programs that link with libc. -frosetta, -fno-rosetta Rely on Rosetta to execute x86_64 programs on ARM64 macOS hosts. (default: no) -fwasmtime, -fno-wasmtime Integration with system-installed wasmtime to execute WASI binaries. (default: no) -fwine, -fno-wine Integration with system-installed Wine to execute Windows programs on Linux hosts. (default: no) -h, --help Print this help and exit -l, --list-steps Print available steps --verbose Print commands before executing them --color [auto|off|on] Enable or disable colored error messages --prominent-compile-errors Buffer compile errors and display at end --summary [mode] Control the printing of the build summary all Print the build summary in its entirety new Omit cached steps failures (Default) Only print failed steps none Do not print the build summary -j Limit concurrent jobs (default is to use all CPU cores) --maxrss Limit memory usage (default is to use available memory) --skip-oom-steps Instead of failing, skip steps that would exceed --maxrss --fetch[=mode] Fetch dependency tree (optionally choose laziness) and exit needed (Default) Lazy dependencies are fetched as needed all Lazy dependencies are always fetched --watch Continuously rebuild when source files are modified --debounce Delay before rebuilding after changed file detected --webui[=ip] Enable the web interface on the given IP address --fuzz Continuously search for unit test failures (implies '--webui') --time-report Force full rebuild and provide detailed information on compilation time of Zig source code (implies '--webui') -fincremental Enable incremental compilation -fno-incremental Disable incremental compilation Project-Specific Options: -Dwindows=[bool] Target Microsoft Windows System Integration Options: --search-prefix [path] Add a path to look for binaries, libraries, headers --sysroot [path] Set the system root directory (usually /) --libc [file] Provide a file which specifies libc paths --system [pkgdir] Disable package fetching; enable all integrations -fsys=[name] Enable a system integration -fno-sys=[name] Disable a system integration Available System Integrations: Enabled: (none) - Advanced Options: ``` -------------------------------- ### Hello World in Zig Source: https://ziglang.org/learn/samples A minimal Zig program that prints 'hello world!' to the standard output. This serves as a basic entry point for learning Zig. ```zig const std = @import("std"); pub fn main() !void { try std.fs.File.stdout().writeAll("hello world!\n"); } ``` -------------------------------- ### Zig Tokenizing String with Optional While Loop Source: https://ziglang.org/learn/overview Example of tokenizing a string in Zig using `std.mem.tokenizeAny` and iterating with a `while` loop. This demonstrates processing of tokens, where `it.next()` returns an optional item. ```zig const std = @import("std"); pub fn main() void { const msg = "hello this is dog"; var it = std.mem.tokenizeAny(u8, msg, " "); while (it.next()) |item| { std.debug.print("{s}\n", .{item}); } } ``` -------------------------------- ### Memory Leak Detection in Zig Source: https://ziglang.org/learn/samples Illustrates how to use `std.heap.GeneralPurposeAllocator` to detect memory leaks and double frees. The example intentionally omits freeing allocated memory to demonstrate the error reporting. ```zig const std = @import("std"); pub fn main() !void { var general_purpose_allocator = std.heap.GeneralPurposeAllocator(.{}){}; defer std.debug.assert(general_purpose_allocator.deinit() == .ok); const gpa = general_purpose_allocator.allocator(); const u32_ptr = try gpa.create(u32); _ = u32_ptr; // silences unused variable error // oops I forgot to free! } ``` -------------------------------- ### Override Zig Lib Directory Path Source: https://ziglang.org/learn/build-system Specify a custom directory for Zig's standard library. This option is generally not needed unless you are working with a custom Zig installation. ```zig // Override Zig lib directory // zig build --zig-lib-dir /path/to/zig/lib ``` -------------------------------- ### Zig: Errors as Values (Ignored) Source: https://ziglang.org/learn/overview Demonstrates how Zig treats errors as values, and the compiler enforces that they are not ignored. This example shows a compile-time error when an error union is discarded without explicit handling. ```zig const std = @import("std"); pub fn main() void { _ = std.fs.cwd().openFile("does_not_exist/foo.txt", .{}); } ``` -------------------------------- ### Initialize Zig Project Source: https://ziglang.org/learn/overview Initializes a new Zig project, creating essential files such as `build.zig`, `build.zig.zon`, and source directories. This command sets up the basic structure for a Zig project. ```bash $ zig init info: created build.zig info: created build.zig.zon info: created src/main.zig info: created src/root.zig info: see `zig build --help` for a menu of options ``` -------------------------------- ### Build Zig Executable and Embed Output Source: https://ziglang.org/learn/build-system This build script configures the Zig build system to compile a tool ('word_select.zig'), run it to generate an output file ('word.txt'), and then embed that output file into the main executable ('hello'). It demonstrates how to define build steps, run tools, and manage dependencies between artifacts. ```zig const std = @import("std"); pub fn build(b: *std.Build) void { const lang = b.option([]const u8, "language", "language of the greeting") orelse "en"; const tool = b.addExecutable(.{ .name = "word_select", .root_module = b.createModule(.{ .root_source_file = b.path("tools/word_select.zig"), .target = b.graph.host, }), }); const tool_step = b.addRunArtifact(tool); tool_step.addArg("--input-file"); tool_step.addFileArg(b.path("tools/words.json")); tool_step.addArg("--output-file"); const output = tool_step.addOutputFileArg("word.txt"); tool_step.addArgs(&.{ "--lang", lang }); const target = b.standardTargetOptions(.{}); const optimize = b.standardOptimizeOption(.{}); const exe = b.addExecutable(.{ .name = "hello", .root_module = b.createModule(.{ .root_source_file = b.path("src/main.zig"), .target = target, .optimize = optimize, }), }); exe.root_module.addAnonymousImport("word", .{ .root_source_file = output, }); b.installArtifact(exe); } ``` -------------------------------- ### Configure Build for Protocol Generation in Zig Source: https://ziglang.org/learn/build-system This Zig build script configures a project with an executable named 'demo' and a separate executable 'proto_gen' for generating protocol files. It sets up a build step 'update-protocol' that depends on 'proto_gen' to run and update 'src/protocol.zig'. This demonstrates how to manage generated source files within a Zig project's build process. ```zig const std = @import("std"); pub fn build(b: *std.Build) void { const target = b.standardTargetOptions(.{}); const exe = b.addExecutable(.{ .name = "demo", .root_source_file = b.path("src/main.zig"), .target = target, }); b.installArtifact(exe); const proto_gen = b.addExecutable(.{ .name = "proto_gen", .root_source_file = b.path("tools/proto_gen.zig"), .target = target, }); const run = b.addRunArtifact(proto_gen); const generated_protocol_file = run.addOutputFileArg("protocol.zig"); const wf = b.addUpdateSourceFiles(); wf.addCopyFileToSource(generated_protocol_file, "src/protocol.zig"); const update_protocol_step = b.step("update-protocol", "update src/protocol.zig to latest"); update_protocol_step.dependOn(&wf.step); } fn detectWhetherToEnableLibFoo() bool { return false; } ```