How to properly make a static library and docs

In the process of learning zig I decided to make a simple text UI library for zig
https://github.com/daredemo/simple-text-ui-for-zig.

Topic 1:

But I am confused about what is the correct way to make a sharable static library. The basic examples always use a single .zig for a static library building. Can I have more than one file? Also, from the user’s point of view, how would using my library differ when using a static library versus just copying all the source files and using @import("Panel.zig"), etc?

Topic 2:

Also, I would like to provide nice documentation. Obviously, I would prefer this to be automatically generated. However, I do not want to generate documentation for my test/example files, just the library itself. What is the correct magic that I have to add to the build.zig when my library is built on zig version 0.13.0?

1 Like
  1. Yes, you can have multiple files. Call const foo = @import("foo.zig"); from your root file to access pub functions, variables and constants in foo.zig.
    You can expose your library as a package that have modules. The package is added as a dependency in the users build.zig.zon and your modules can be imported using: @import("terminal") where terminal is a module name. See: How to package a zig source module and how to use it

  1. From a library or executable artifact call getEmittedDocs() to generate documentation. The following example code installs the documentation under zig-out/docs when running zig build docs.
    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);
    
    Note that the documentation engine is a web assembly and a web server is required to serve it. To run a server at port 8000:
    python -m http.server -b 127.0.0.1 8000 -d zig-out/docs/
    
2 Likes

This seems to be the example that I needed! Thanks.

I’ll try it out and let you know if I get it working or if I have more questions.

OK, here’s the first obstacle:

/home/***/Documents/ZIG/simple-text-ui-for-zig/build.zig:38:30: error: no field or member function named 'getEmittedDocs' in 'Build.Module'
        .source_dir = lib_tui.getEmittedDocs(),
                      ~~~~~~~^~~~~~~~~~~~~~~
/home/***/bin/zig/lib/std/Build/Module.zig:1:1: note: struct declared here

Where lib_tui is the variable from b.addModule...

The getEmittedDocs function works with a Compile instance, not a Module. You need to use the result of b.addExecutable, b.addStaticLibrary or b.addObject (recommanded if you don’t want to do anything else with it).

1 Like

This got me closer, but no actual documentation is generated, just landing page for root and link to the src but no docs to the files that I thought it should generate… I tried even adding comptime _= ..., but that didn’t help either.

Here’s part of the build.zig:

...
    const obj_tui = b.addObject(.{
        .name = "tui",
        .root_source_file = b.path("src/root.zig"),
        .target = target,
        .optimize = optimize,
    });

    const install_docs = b.addInstallDirectory(.{
        .source_dir = obj_tui.getEmittedDocs(),
        .install_dir = .prefix,
        .install_subdir = "docs",
    });

    const docs_step = b.step("docs", "Generate documentation");
    docs_step.dependOn(&install_docs.step);

...

And here’s what I have in the src/root.zig:

const Term = @import("ansi_terminal.zig");
const Border = @import("Border.zig");
const CharReader = @import("CharReader.zig");
const Color = @import("Color.zig");
const LibDef = @import("definitions.zig");
const Location = @import("Location.zig");
const Panel = @import("Panel.zig");
const BuffWriter = @import("SimpleBufferedWriter.zig");
const StringStuff = @import("StringStuff.zig");
const TextLine = @import("TextLine.zig");

comptime {
    _ = Term;
    _ = Border;
    _ = CharReader;
    _ = Color;
    _ = LibDef;
    _ = Location;
    _ = Panel;
    _ = BuffWriter;
    _ = StringStuff;
    _ = TextLine;
}

So, there’s still something that I’m missing in this doc generation philosophy.

Interesting, if I click on the src in the root (top-level) view, and then click on any of the “modules” (?) such as TextLine

comptime {
    ...
    _ = TextLine;
    ...
}

that opens a documentation for that file.
I was expecting that I would have some links or even side nav on the root page. It does not feel “natural” that I have to click on src to see documentation.

So, what am I doing wrong?

Use pub to export the symbol and include it in the documentation.
See the zig reference about Doc Comments.

3 Likes

I’d actually very much like the ability to generate developer documentation, which includes all doc comments whether the commented item is public or not. Public-only is a reasonable default, but I quite like the Zig docs browser, and it would be rather nice to be able to use it as a reference when working on code, in addition to just using a library or what have you.

2 Likes

Indeed, it feels like “op-out” would make more sense…

Last question on doc generation:

How do I force the docs location to the project’s root folder?

I don’t feel like adding zig-out/docs in the github repo is the most natural location for documentation.

Set .install_dir to .custom.

    const install_docs = b.addInstallDirectory(.{
        .source_dir = lib.getEmittedDocs(),
        .install_dir = .{
            .custom = "..",
        },
        .install_subdir = "docs",
    });

Custom is relative to prefix=zig-out, .. goes up and creates the documentation in the .install_subdir (i.e. zig-out/../docs).


Since you host the sources on github, you can have the documentation as github-pages generated by github-actions.

For example, in my repository: GitHub - dimdin/zig-recover: zig panic recover
The pages are hosted at: Zig Documentation
and generated using the action: zig-recover/.github/workflows/docs.yml at main · dimdin/zig-recover · GitHub
which calls: zig-recover/build.zig at c2c1ca3f5dc6413896505f5a861a4ab65f79ca5b · dimdin/zig-recover · GitHub

3 Likes