TL;DR - Newbie confused about Modules vs. Libraries, interacting with them in the build system and subsequent usage in code. Looking for insights into how more experienced folks are approaching it.
Been playing with zig over the weekend and have been having a grand old time with it. Managed to get a basic SDL workflow up and running and have even drawn some circles!
During my travels I ran into a couple of things with the build system that have me scratching my head. These issues aren't so much implementation questions so much as me trying to adopt the mindset of what these specific pieces are trying to do and when to use them.
When you create a new project you get root.zig and main.zig and in the build system, the following occurs
const lib = b.addStaticLibrary(.{
.name = "learning",
// In this case the main source file is merely a path, however, in more
// complicated build scripts, this could be a generated file.
.root_source_file = b.path("src/root.zig"),
.target = target,
.optimize = optimize,
});
// This declares intent for the library to be installed into the standard
// location when the user invokes the "install" step (the default step when
// running `zig build`).
b.installArtifact(lib);
const exe = b.addExecutable(.{
.name = "learning",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
// This declares intent for the executable to be installed into the
// standard location when the user invokes the "install" step (the default
// step when running `zig build`).
b.installArtifact(exe);
I understand what all of these steps are doing on paper but its not incredibly clear WHY these are being done.
A: Because the root static library is redundant from the start not even imported into main
B: Its not clear how to import that other than @import("root.zig") which doesn't need the static library anyways.
So when is it considered "best practice" to go with the static lib approach? Should this be the default? It doesn't help that I also get error: unable to add module 'learning': already exists as 'root.zig' when trying to test how to actually import said static library.
Next up we have modules! Which added another layer of confusion.
See the following code:
const cpu_lib = b.addModule("cpu", .{
.root_source_file = b.path("src/lib/cpu.zig"),
});
exe.root_module.addImport("cpu", cpu_lib);
This is another way of bringing in code it seems. Which one should I choose in what scenarios? This has me scratching my head, more so when compounded with the previous point.
My final point of confusion. Needing to pass things to either exe or exe.root_module there are functions with the same name that exists under both types of *Compile and *Module but require different arguments and (I'm assuming) likely do different things.
This did lead to some headaches in trying to make code available to exe especially when trying to include SDL
For example:
const sdl_include_path = .{ .cwd_relative = "/opt/homebrew/Cellar/sdl2/2.32.0/include/SDL2/" };
const sdl_link_path = .{ .cwd_relative = "/opt/homebrew/Cellar/sdl2/2.32.0/lib/" };
exe.root_module.addIncludePath(sdl_include_path);
exe.root_module.addLibraryPath(sdl_link_path);
exe.root_module.linkSystemLibrary("SDL2", .{});
(Ignore the hardcoded paths...I'm lazy)
Just looking for some more experienced insights into these issues and what the general mindset around this stuff is.
Thanks in advance!
does zig have any way to label functions as "legacy" or "deprecated"?