Linking
If you want to use internals of a static library, you have to link against it firstly.
You can do it by using Zig build system or manually.
Build System
For the first option you have to edit build.zig
file in the root of your project by adding addObjectFile("path")
to your executable object.
Here is the build file for zig v0.10.1
which is automatically generated by zig init-exe
command with exe.addObjectFile
function call added
const std = @import("std");
pub fn build(b: *std.build.Builder) void {
const mode = b.standardReleaseOptions();
const exe = b.addExecutable("test_exe", "src/main.zig");
exe.setTarget(target);
exe.setBuildMode(mode);
exe.install();
exe.addObjectFile("path/to/file.a(or .lib if on Windows)"); // linking the executable against a "file.a" static library.
const run_cmd = exe.run();
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
const exe_tests = b.addTest("src/main.zig");
exe_tests.setTarget(target);
exe_tests.setBuildMode(mode);
const test_step = b.step("test", "Run unit tests");
test_step.dependOn(&exe_tests.step);
}
Manual linking
To link the library with only using Zig compiler you just need to add it's path into the list of targets like this:
zig build-exe src/main.zig path/to/the/lib.a
Usage
To use exported functions/variables you have to declare them with the extern
keyword. If you want to import something that uses non-primitive type, you should define it yourself.
Usually, library developers provide header(for C) or package(for Zig) files if they want to distribute their library as a static or shared archive. These files contain all exported functions, variables, types, because a common user of a big library don't know anything about what is exported without them.
const std = @import("std");
const EmbeddedFile = struct {
path: [*:0]const u8,
content: [*:0]const u8,
};
// Notice the extern keyword.
// It tells the compiler embedded_files is taken from a shared or static library.
extern const embedded_files: [4]EmbeddedFile;
pub fn main() !void {
for (embedded_files) |file| {
std.debug.print("file:\t\t{s}\n", .{file.path});
std.debug.print("content:\t{s}\n", .{file.content});
}
}
Output:
file: www/x/in.txt
content: text
file: www/emd.txt
content: text
file: www/index.html
content: text
file: www/e2.txt
content: text
Note
The code you provided can't represent the actual internals of the library, because:
- Nothing is exported here
- Slices can not be exported
So I assumed the library looks like this:
const std = @import("std");
const file_paths = [_][]const u8{
"www/x/in.txt",
"www/emd.txt",
"www/index.html",
"www/e2.txt",
};
const EmbeddedFile = extern struct {
path: [*:0]const u8,
content: [*:0]const u8,
};
export const embedded_files = blk: {
var fs: [file_paths.len]EmbeddedFile = undefined;
for (file_paths) |file_path, i| {
const embedded_file = EmbeddedFile{
.path = file_path[0.. :0],
.content = @embedFile(file_path)[0.. :0],
};
fs[i] = embedded_file;
}
break :blk fs;
};