WIP: build accepting static, dynamic and executables.

This commit is contained in:
Philippe Pittoli 2025-10-19 02:21:54 +02:00
parent 5f756f722f
commit 6743fc66a0

View file

@ -41,33 +41,43 @@ pub fn build(b: *std.Build) void {
.target = target, .target = target,
}); });
// Here we define an executable. An executable needs to have a root module // Compile libipc as a static library with C bindings.
// which needs to expose a `main` function. While we could add a main function const lib_static_c = b.addLibrary(.{
// to the module defined above, it's sometimes preferable to split business .name = "ipc", // name of the library
// business logic and the CLI into two separate modules. .linkage = .static,
// .root_module = b.createModule(.{
// If your goal is to create a Zig library for others to use, consider if .root_source_file = b.path("src/root.zig"),
// it might benefit from also exposing a CLI tool. A parser library for a .target = target,
// data serialization format could also bundle a CLI syntax checker, for example. .optimize = optimize,
// }),
// If instead your goal is to create an executable, consider if users might });
// be interested in also being able to embed the core functionality of your // Tell the compiler we need libc.
// program in their own executable in order to avoid the overhead involved in lib_static_c.root_module.link_libc = true;
// subprocessing your CLI tool. b.installArtifact(lib_static_c);
//
// If neither case applies to you, feel free to delete the declaration you // Compile libipc as a dynamic library with C bindings.
// don't need and to put everything under a single module. const lib_dynamic_c = b.addLibrary(.{
const exe = b.addExecutable(.{ .name = "ipc", // name of the library
.linkage = .dynamic,
.version = .{ .major = 0, .minor = 2, .patch = 3 },
.root_module = b.createModule(.{
.root_source_file = b.path("src/root.zig"),
.target = target,
.optimize = optimize,
}),
});
// Tell the compiler we need libc.
lib_dynamic_c.root_module.link_libc = true;
b.installArtifact(lib_dynamic_c);
// pong service using the c client.
const c_pong = b.addExecutable(.{
.name = "ping", // name of the executable .name = "ping", // name of the executable
.root_module = b.createModule(.{ .root_module = b.createModule(.{
// b.createModule defines a new module just like b.addModule but, // b.createModule defines a new module just like b.addModule but,
// unlike b.addModule, it does not expose the module to consumers of // unlike b.addModule, it does not expose the module to consumers of
// this package, which is why in this case we don't have to give it a name. // this package, which is why in this case we don't have to give it a name.
.root_source_file = b.path("src/main.zig"), .root_source_file = b.path("src/examples/c_pong.zig"),
// Target and optimization levels must be explicitly wired in when
// defining an executable or library (in the root module), and you
// can also hardcode a specific target for an executable or library
// definition if desireable (e.g. firmware for embedded devices).
.target = target, .target = target,
.optimize = optimize, .optimize = optimize,
// List of modules available for import in source files part of the // List of modules available for import in source files part of the
@ -87,20 +97,10 @@ pub fn build(b: *std.Build) void {
// install prefix when running `zig build` (i.e. when executing the default // install prefix when running `zig build` (i.e. when executing the default
// step). By default the install prefix is `zig-out/` but can be overridden // step). By default the install prefix is `zig-out/` but can be overridden
// by passing `--prefix` or `-p`. // by passing `--prefix` or `-p`.
b.installArtifact(exe); b.installArtifact(c_pong);
// Here we define a library. // Link the executable to the library.
const lib = b.addLibrary(.{ c_pong.linkLibrary(lib_static_c);
.name = "ipc", // name of the library
.root_module = b.createModule(.{
.root_source_file = b.path("src/root.zig"),
.target = target,
.optimize = optimize,
}),
});
// Tell the compiler we need libc.
lib.root_module.link_libc = true;
b.installArtifact(lib);
// This creates a top level step. Top level steps have a name and can be // This creates a top level step. Top level steps have a name and can be
// invoked by name when running `zig build` (e.g. `zig build run`). // invoked by name when running `zig build` (e.g. `zig build run`).
@ -115,7 +115,7 @@ pub fn build(b: *std.Build) void {
// or if another step depends on it, so it's up to you to define when and // or if another step depends on it, so it's up to you to define when and
// how this Run step will be executed. In our case we want to run it when // how this Run step will be executed. In our case we want to run it when
// the user runs `zig build run`, so we create a dependency link. // the user runs `zig build run`, so we create a dependency link.
const run_cmd = b.addRunArtifact(exe); const run_cmd = b.addRunArtifact(c_pong);
run_step.dependOn(&run_cmd.step); run_step.dependOn(&run_cmd.step);
// By making the run step depend on the default step, it will be run from the // By making the run step depend on the default step, it will be run from the
@ -142,7 +142,7 @@ pub fn build(b: *std.Build) void {
// root module. Note that test executables only test one module at a time, // root module. Note that test executables only test one module at a time,
// hence why we have to create two separate ones. // hence why we have to create two separate ones.
const exe_tests = b.addTest(.{ const exe_tests = b.addTest(.{
.root_module = exe.root_module, .root_module = c_pong.root_module,
}); });
// A run step that will run the second test executable. // A run step that will run the second test executable.