Static linking
In this blog, we will explore how to link a zig library statically and dynamically.
First lets create a library that contains a function my_add that adds two numbers. Note that instead of pub keyword which we used in previous blog, we will be using export keyword to decorate the my_add function. This tells the zig compiler to expose the my_add function through C ABI.
// libraries__add.zig
export fn my_add(num1: i32, num2: i32) i32 {
return num1 + num2;
}
Build the libraries__add.zig file as a static library using the command zig build-lib -O ReleaseSafe libraries__add.zig. This will output a liblibraries__add.a file on current folder if you are using linux or libraries__add.dll file if you are on windows.
To use this my_add function in our main code to add numbers, we will declare the my_add function's signature in main code using extern keyword. Then at compile time, we will tell the zig compiler to link the liblibraries__add.a/libraries__add.dll with our main output.
// libraries__main1.zig
const std = @import("std");
extern fn my_add(num1: i32, num2: i32) i32;
pub fn main(init: std.process.Init) !void {
// setting up stdout writer
var buffer: [1024]u8 = undefined;
var file_writer = std.Io.File.Writer.init(.stdout(), init.io, &buffer);
var stdout_writer = &file_writer.interface;
try stdout_writer.print("{}+{}={}\n", .{ 5, 6, my_add(5, 6) });
try stdout_writer.flush();
}
Let's build our main code and link liblibraries__add.a/libraries__add.dll with the output using zig build-exe libraries__main1.zig liblibraries__add.a or zig build-exe libraries__main1.zig libraries__add.dll.
The above command will produce a libraries__main1 which when executed will print 5+6=11.
Once libraries__main1 is created, we can delete the liblibraries__add.a/libraries__add.dll file and the libraries__main1 executable will still work. This is because the library was linked statically - the entire library was copied to the final executable. Advantage of doing static linking is creation of a final binary that has no runtime dependency. Disadvantage is duplication across binaries and increased file size. Hence dynamic linking.
Dynamic linking
To dynamically link liblibraries__add.a/libraries__add.dll with libraries__main1, we pass -dynamic flag to the zig compiler when building libraries__add.zig. The build command will look like zig build-lib -O ReleaseSafe -dynamic libraries__add.zig. This will produce a liblibraries__add.so in linux and libraries__add.dll in windows. Even though the file extension is same as earlier in windows, the DLL will be position independent code. The build command for libraries__main1.zig is same. But the difference is that the liblibraries_add.so/libraries__add.dll will be dynamically linked. This means the final executable libraries__main1 will work only if it can find liblibraries_add.so/libraries__add.dll. If not, it will fail.
Thanks for reading. To be continued.
Top comments (0)