Generating and viewing documentation of all files in a library

Hello,

I have a library which I’m in the process of documenting. The project contains a root.zig file in the src/ directory.
This file calls other .zig files located in different sub-directories within src/.

All files are documented using //!.

When I run zig build test, zig build docs, python3 -m http.server 8080 -d zig-out/docs, and then navigate to http://127.0.0.1:8080/ in the browser, I can only see the documentation for src/root.zig.

How can I also view the documentation of src/foo/one.zig and src/bar/two.zig ?


For a minimal reproducible example, consider the below:

  • Project layout:

    .
    ├── build.zig
    ├── build.zig.zon
    ├── src
    │   ├── bar
    │   │    └── two.zig
    │   ├── foo
    │   │    └── one.zig
    │   └── root.zig
    
  • build.zig:

    const std = @import("std");
    
    pub fn build(b: *std.Build) void {
        const target = b.standardTargetOptions(.{});
        const optimize = b.standardOptimizeOption(.{});
    
        const lib = b.addStaticLibrary(.{
            .name = "lib",
            .root_source_file = b.path("src/root.zig"),
            .target = target,
            .optimize = optimize,
        });
        b.installArtifact(lib);
    
        const lib_unit_tests = b.addTest(.{
            .root_source_file = b.path("src/root.zig"),
            .target = target,
            .optimize = optimize,
        });
    
        const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
    
        const test_step = b.step("test", "Run unit tests");
        test_step.dependOn(&run_lib_unit_tests.step);
    
        const install_docs = b.addInstallDirectory(.{
            .source_dir = lib.getEmittedDocs(),
            .install_dir = .prefix,
            .install_subdir = "docs",
        });
    
        const docs_step = b.step("docs", "Generate documentation");
        docs_step.dependOn(&install_docs.step);
    }
    
  • build.zig.zon:

    .{
        .name = .playground,
    
        .version = "0.0.0",
    
        .fingerprint = 0xdc1888482ef92b69
    
        .minimum_zig_version = "0.14.0",
    
        .dependencies = .{},
    
        .paths = .{
            "build.zig",
            "build.zig.zon",
            "src",
            // For example...
            //"LICENSE",
            //"README.md",
        },
    }
    
  • src/root.zig

    //! By convention, root.zig is the root source file when making a library. If
    //! you are making an executable, the convention is to delete this file and
    //! start with main.zig instead.
    const std = @import("std");
    
    pub fn main() !void {
        // Prints to stderr (it's a shortcut based on `std.io.getStdErr()`)
        std.debug.print("All your {s} are belong to us.\n", .{"codebase"});
    }
    
    test "run all unit tests" {
        _ = @import("foo/one.zig");
        _ = @import("bar/two.zig");
    }
    
  • src/foo/one.zig:

    //! Brief description of one.zig split over two lines
    //! Adds two numbers
    const std = @import("std");
    const testing = std.testing;
    
    pub export fn add(a: i32, b: i32) i32 {
        return a + b;
    }
    
    test add {
        try testing.expect(add(3, 7) == 10);
    }
    
  • src/bar/two.zig is similar - it subtracts instead.

The documentation is generated for lib.getEmittedDocs(), but this does not run tests and the imports are not included in the build.
Either change test to comptime in root.zig or use lib_unit_tests to generate documentation.

I’m looking to avoid comptime.

Could you give me an example of using lib_unit_tests to generate documentation ?