From 6743fc66a0ac4c9b5b3fc7f6b766d777b39ef2a0 Mon Sep 17 00:00:00 2001 From: Philippe Pittoli Date: Sun, 19 Oct 2025 02:21:54 +0200 Subject: [PATCH] WIP: build accepting static, dynamic and executables. --- build.zig | 74 +++++++++++++++++++++++++++---------------------------- 1 file changed, 37 insertions(+), 37 deletions(-) diff --git a/build.zig b/build.zig index 13a6b52..861e19d 100644 --- a/build.zig +++ b/build.zig @@ -41,33 +41,43 @@ pub fn build(b: *std.Build) void { .target = target, }); - // Here we define an executable. An executable needs to have a root module - // which needs to expose a `main` function. While we could add a main function - // to the module defined above, it's sometimes preferable to split business - // business logic and the CLI into two separate modules. - // - // If your goal is to create a Zig library for others to use, consider if - // it might benefit from also exposing a CLI tool. A parser library for a - // data serialization format could also bundle a CLI syntax checker, for example. - // - // 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 - // program in their own executable in order to avoid the overhead involved in - // subprocessing your CLI tool. - // - // If neither case applies to you, feel free to delete the declaration you - // don't need and to put everything under a single module. - const exe = b.addExecutable(.{ + // Compile libipc as a static library with C bindings. + const lib_static_c = b.addLibrary(.{ + .name = "ipc", // name of the library + .linkage = .static, + .root_module = b.createModule(.{ + .root_source_file = b.path("src/root.zig"), + .target = target, + .optimize = optimize, + }), + }); + // Tell the compiler we need libc. + lib_static_c.root_module.link_libc = true; + b.installArtifact(lib_static_c); + + // Compile libipc as a dynamic library with C bindings. + const lib_dynamic_c = b.addLibrary(.{ + .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 .root_module = b.createModule(.{ // b.createModule defines a new module just like b.addModule but, // 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. - .root_source_file = b.path("src/main.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). + .root_source_file = b.path("src/examples/c_pong.zig"), .target = target, .optimize = optimize, // 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 // step). By default the install prefix is `zig-out/` but can be overridden // by passing `--prefix` or `-p`. - b.installArtifact(exe); + b.installArtifact(c_pong); - // Here we define a library. - const lib = b.addLibrary(.{ - .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); + // Link the executable to the library. + c_pong.linkLibrary(lib_static_c); // 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`). @@ -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 // 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. - const run_cmd = b.addRunArtifact(exe); + const run_cmd = b.addRunArtifact(c_pong); run_step.dependOn(&run_cmd.step); // 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, // hence why we have to create two separate ones. 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.