Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 23 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@ Steps:
uninstall Remove build artifacts from prefix path
c_app Run a C application built with Zig's build system.
zig_app Run a Zig application linked to C source code.
c_app_with_static_lib Run a C app linked to a c static lib all built with zig build.
c_app_with_shared_lib Run a C app linked to a c dynamic lib all built with zig build.
zmath_static Create a static library from C source code.
zmath_shared Create a shared library from C source code.
zig_app_shared Run a Zig application that is linked to a shared library.
Expand Down Expand Up @@ -205,16 +207,16 @@ const std = @import("std");
const zmath = @cImport(@cInclude("zmath.h"));

pub fn main() !void {
const stdio = std.io.getStdOut().writer();
const stdio = std.fs.File.stdout.writerStreaming(.{});

const a = 10;
const b = 5;

const resultAdd = zmath.add(a, b);
try stdio.print("{} + {} = {}\n", .{ a, b, resultAdd });
try stdio.interface.print("{} + {} = {}\n", .{ a, b, resultAdd });

const resultSub = zmath.sub(a, b);
try stdio.print("{} - {} = {}\n", .{ a, b, resultSub });
try stdio.interface.print("{} - {} = {}\n", .{ a, b, resultSub });
}
```

Expand Down Expand Up @@ -281,10 +283,12 @@ pub fn build(b: *std.Build) *std.Build.Step.Compile {

lib.addIncludePath(b.path("include"));
lib.addCSourceFiles(.{ .files = &[_][]const u8{"src/zmath.c"} });

lib.linkLibC();

b.installArtifact(lib);
// return the lib to the caller so it can be passed in to the fn that builds apps
return lib;
}
```

Expand Down Expand Up @@ -354,16 +358,16 @@ const std = @import("std");
const zmath = @import("zmath.zig");

pub fn main() !void {
const stdio = std.io.getStdOut().writer();
const stdio = std.fs.File.stdout.writerStreaming(.{});

const a = 10;
const b = 5;

const resultAdd = try zmath.add(a, b);
try stdio.print("{d} + {d} = {d}\n", .{ a, b, resultAdd });
try stdio.interface.print("{d} + {d} = {d}\n", .{ a, b, resultAdd });

const resultSub = try zmath.sub(a, b);
try stdio.print("{d} - {d} = {d}\n", .{ a, b, resultSub });
try stdio.interface.print("{d} - {d} = {d}\n", .{ a, b, resultSub });
}
```

Expand All @@ -376,16 +380,18 @@ to link our application to our library.
```c
const std = @import("std");

pub fn build(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) *std.Build.Step.Compile {
pub fn build(b: *std.Build,
target: std.Build.ResolvedTarget,
optimize: std.builtin.OptimizeMode,
lib: *std.Build.Step.Compile) *std.Build.Step.Compile {
const exe = b.addExecutable(.{
.name = "zig_app_shared",
.root_source_file = b.path("src/zig_c_wrapper.zig"),
.target = target,
.optimize = optimize,
});

exe.addObjectFile(b.path("zig-out/lib/zmath-shared.lib"));

// this avoids having to name the library file. Libraries are named very differently on Linux, Osx and Windows
exe.linkLibrary(lib)
return exe;
}
```
Expand Down Expand Up @@ -452,7 +458,13 @@ pub fn build(b: *std.Build) void {
b.installArtifact(tests_exe);
}
```
## Two more pure 'C' examples
Two additional 'C' examples have been provided to demonstrate how to use `zig build` to
compile and link a 'C' program to a 'C' static or shared library. They are:

- `build_c_app_with_shared_lib` which builds an executable `c_app_with_shared_lib`, and
- `build_c_app_with_static_lib` which builds an executable `c_app_with_static_lib`

## Resources
- https://mtlynch.io/notes/zig-call-c-simple/
What initially made me want to tackle this subject, this article is a great
Expand Down
79 changes: 43 additions & 36 deletions build.zig
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
const std = @import("std");

const module_c_app = @import("build_c_app.zig");
const module_zig_app = @import("build_zig_app.zig");
const module_c_app_with_static_lib = @import("build_c_app_with_static_lib.zig");
const module_c_app_with_shared_lib = @import("build_c_app_with_shared_lib.zig");

const module_zig_call_c_app = @import("build_zig_call_c_app.zig");
const module_lib_static = @import("build_c_static_lib.zig");
const module_lib_shared = @import("build_c_shared_lib.zig");
const module_zig_app_static = @import("build_zig_app_static.zig");
Expand All @@ -12,68 +15,72 @@ pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});

// c_app
const c_app = module_c_app.build(b, target, optimize);
const run_c_app = b.addRunArtifact(c_app);

b.installArtifact(c_app);

const run_c_app_step = b.step("c_app", "Run a C application built with Zig's build system.");
run_c_app_step.dependOn(&run_c_app.step);

// zig_app
const zig_app = module_zig_app.build(b, target, optimize);
const run_zig_app = b.addRunArtifact(zig_app);

b.installArtifact(zig_app);

const run_zig_app_step = b.step("zig_app", "Run a Zig application linked to C source code.");
run_zig_app_step.dependOn(&run_zig_app.step);

// zmath_static
// zmath lib static
const lib_static = module_lib_static.build(b, target, optimize);
const install_lib_static = b.addInstallArtifact(lib_static, .{});

b.installArtifact(lib_static);

const install_lib_static_step = b.step("zmath_static", "Create a static library from C source code.");
install_lib_static_step.dependOn(&install_lib_static.step);

// zmath_shared
// zmath lib shared
const lib_shared = module_lib_shared.build(b, target, optimize);
const install_lib_shared = b.addInstallArtifact(lib_shared, .{});

b.installArtifact(lib_shared);

const install_lib_shared_step = b.step("zmath_shared", "Create a shared library from C source code.");
install_lib_shared_step.dependOn(&install_lib_shared.step);

// zig_app_shared
const zig_app_shared = module_zig_app_shared.build(b, target, optimize);
const run_zig_app_shared = b.addInstallArtifact(zig_app_shared, .{});
// c_app - a c program linked with c object by compiling c_app.c and zmath.c
const c_app = module_c_app.build(b, target, optimize);
const run_c_app = b.addRunArtifact(c_app);
b.installArtifact(c_app);
const run_c_app_step = b.step("c_app", "Run a C application likned to otehr c objects.");
run_c_app_step.dependOn(&run_c_app.step);

b.installArtifact(zig_app_shared);
// c_app_with_static_lib - a c program linked against zmath static lib
const c_app_with_static_lib = module_c_app_with_static_lib.build(b, target, optimize, lib_static);
const run_c_app_with_static_lib = b.addRunArtifact(c_app_with_static_lib);
b.installArtifact(c_app_with_static_lib);
const run_c_app_with_static_lib_step = b.step("c_app_with_static_lib", "Run a C application linked to a c static lib all built with zig build.");
run_c_app_with_static_lib_step.dependOn(&run_c_app_with_static_lib.step);

// c_app_with_shared_lib - a c program compiled andlinked against zmath shared lib
const c_app_with_shared_lib = module_c_app_with_shared_lib.build(b, target, optimize, lib_shared);
const run_c_app_with_shared_lib = b.addRunArtifact(c_app_with_shared_lib);
b.installArtifact(c_app_with_shared_lib);
const run_c_app_with_shared_lib_step = b.step("c_app_with_shared_lib", "Run a C application linked to a c dynamic lib all built with zig build.");
run_c_app_with_shared_lib_step.dependOn(&run_c_app_with_shared_lib.step);

// zig_call_c_app - zig_call_c_app.zig is compiled with zmath.c and the 2 objects linked together
// zig_call_c_app explicitly imports zmath.c as a c module
const zig_call_c_app = module_zig_call_c_app.build(b, target, optimize);
const run_zig_call_c_app = b.addRunArtifact(zig_call_c_app);
b.installArtifact(zig_call_c_app);
const run_zig_app_step = b.step("zig_app", "Run a Zig application linked to C source code.");
run_zig_app_step.dependOn(&run_zig_call_c_app.step);

// zig_app_shared - zig_c_wrapped.zig calls zmath.zig which calls zmath_ext.zig which transforms the calls to c and then all
// that is liked with the static c library
const zig_app_shared = module_zig_app_shared.build(b, target, optimize, lib_shared);
const run_zig_app_shared = b.addInstallArtifact(zig_app_shared, .{});
b.installArtifact(zig_app_shared);
const run_zig_app_shared_step = b.step("zig_app_shared", "Run a Zig application that is linked to a shared library.");
run_zig_app_shared_step.dependOn(&install_lib_shared.step); // create and install shared library
run_zig_app_shared_step.dependOn(&run_zig_app_shared.step);

// zig_app_static
const zig_app_static = module_zig_app_static.build(b, target, optimize);
// zig_app_static - zig_c_wrapped.zig calls zmath.zig which calls zmath_ext.zig which transforms the calls to c
// then all that is linked against the c shared library
const zig_app_static = module_zig_app_static.build(b, target, optimize, lib_static);
const run_zig_app_static = b.addInstallArtifact(zig_app_static, .{});

b.installArtifact(zig_app_static);

const run_zig_app_static_step = b.step("zig_app_static", "Run a Zig application that is linked to a static library.");
run_zig_app_static_step.dependOn(&install_lib_static.step); // create and install static library
run_zig_app_static_step.dependOn(&run_zig_app_static.step);

// tests
// // tests
const tests = module_tests.build(b, target, optimize);
const run_tests = b.addRunArtifact(tests);

b.installArtifact(tests);

const run_tests_step = b.step("tests", "Run a Zig tests of C source code.");
run_tests_step.dependOn(&run_tests.step);
}
//
6 changes: 2 additions & 4 deletions build_c_app.zig
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
const std = @import("std");

pub fn build(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) *std.Build.Step.Compile {
const exe = b.addExecutable(.{
.name = "c_app",
const exe = b.addExecutable(.{ .name = "c_app", .root_module = b.createModule(.{
.target = target,
.optimize = optimize,
});
}) });

exe.addIncludePath(b.path("include"));
exe.addCSourceFiles(.{ .files = &[_][]const u8{ "src/c_app.c", "src/zmath.c" } });

exe.linkLibC();

return exe;
Expand Down
15 changes: 15 additions & 0 deletions build_c_app_with_shared_lib.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const std = @import("std");

pub fn build(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, lib: *std.Build.Step.Compile) *std.Build.Step.Compile {
const exe = b.addExecutable(.{ .name = "c_app_with_shared_lib", .root_module = b.createModule(.{
.target = target,
.optimize = optimize,
}) });

exe.addIncludePath(b.path("include"));
exe.addCSourceFiles(.{ .files = &[_][]const u8{"src/c_app.c"} }); //, "src/zmath.c" } });
exe.linkLibrary(lib);
exe.linkLibC();

return exe;
}
15 changes: 15 additions & 0 deletions build_c_app_with_static_lib.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
const std = @import("std");

pub fn build(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, lib: *std.Build.Step.Compile) *std.Build.Step.Compile {
const exe = b.addExecutable(.{ .name = "c_app_with_static_lib", .root_module = b.createModule(.{
.target = target,
.optimize = optimize,
}) });

exe.addIncludePath(b.path("include"));
exe.addCSourceFiles(.{ .files = &[_][]const u8{"src/c_app.c"} }); //, "src/zmath.c" } });
exe.linkLibrary(lib);
exe.linkLibC();

return exe;
}
5 changes: 2 additions & 3 deletions build_c_shared_lib.zig
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
const std = @import("std");

pub fn build(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) *std.Build.Step.Compile {
const lib = b.addSharedLibrary(.{
.name = "zmath-shared",
const lib = b.addLibrary(.{ .linkage = .dynamic, .name = "zmath-shared", .root_module = b.createModule(.{
.target = target,
.optimize = optimize,
});
}) });

lib.addIncludePath(b.path("include"));
lib.addCSourceFiles(.{ .files = &[_][]const u8{"src/zmath.c"} });
Expand Down
7 changes: 4 additions & 3 deletions build_c_static_lib.zig
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
const std = @import("std");

pub fn build(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) *std.Build.Step.Compile {
const lib = b.addStaticLibrary(.{
.name = "zmath-static",
const lib = b.addLibrary(.{ .linkage = .static, .name = "zmath-static", .root_module = b.createModule(.{
.target = target,
.optimize = optimize,
});
}) });

lib.addIncludePath(b.path("include"));
lib.addCSourceFiles(.{ .files = &[_][]const u8{"src/zmath.c"} });

lib.linkLibC();
var stdio = std.fs.File.stdout().writerStreaming(&.{});

stdio.interface.print("\nXXBuild static library name {s}. \n", .{lib.out_lib_filename}) catch {};
return lib;
}
5 changes: 2 additions & 3 deletions build_test_zmath.zig
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
const std = @import("std");

pub fn build(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) *std.Build.Step.Compile {
const exe = b.addTest(.{
.name = "test_zmath",
const exe = b.addTest(.{ .name = "test_zmath", .root_module = b.createModule(.{
.root_source_file = b.path("tests/test_zmath.zig"),
.target = target,
.optimize = optimize,
});
}) });

exe.addIncludePath(b.path("include"));
exe.addCSourceFile(.{
Expand Down
11 changes: 6 additions & 5 deletions build_zig_app_shared.zig
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
const std = @import("std");

pub fn build(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) *std.Build.Step.Compile {
const exe = b.addExecutable(.{
.name = "zig_app_shared",
pub fn build(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, lib: *std.Build.Step.Compile) *std.Build.Step.Compile {
const exe = b.addExecutable(.{ .name = "zig_app_shared", .root_module = b.createModule(.{
.root_source_file = b.path("src/zig_c_wrapper.zig"),
.target = target,
.optimize = optimize,
});
}) });

exe.addObjectFile(b.path("zig-out/lib/zmath-shared.lib"));
// exe.addObjectFile(b.path("zig-out/lib/libzmath-shared.dylib"));
exe.linkLibrary(lib);
// exe.addRPath(b.path("zig-out/lib"));

return exe;
}
11 changes: 5 additions & 6 deletions build_zig_app_static.zig
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
const std = @import("std");

pub fn build(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) *std.Build.Step.Compile {
const exe = b.addExecutable(.{
.name = "zig_app_static",
pub fn build(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode, lib: *std.Build.Step.Compile) *std.Build.Step.Compile {
const exe = b.addExecutable(.{ .name = "zig_app_static", .root_module = b.createModule(.{
.root_source_file = b.path("src/zig_c_wrapper.zig"),
.target = target,
.optimize = optimize,
});

exe.addObjectFile(b.path("zig-out/lib/zmath-static.lib"));
}) });

// exe.addObjectFile(b.path("zig-out/lib/libzmath-static.a"));
exe.linkLibrary(lib);
return exe;
}
18 changes: 18 additions & 0 deletions build_zig_call_c_app.zig
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const std = @import("std");

pub fn build(b: *std.Build, target: std.Build.ResolvedTarget, optimize: std.builtin.OptimizeMode) *std.Build.Step.Compile {
const exe = b.addExecutable(.{ .name = "zig_call_c_app", .root_module = b.createModule(.{
.root_source_file = b.path("src/zig_call_c_app.zig"),
.target = target,
.optimize = optimize,
}) });

exe.addIncludePath(b.path("include"));
exe.addCSourceFile(.{
.file = b.path("src/zmath.c"),
});

exe.linkLibC();

return exe;
}
15 changes: 0 additions & 15 deletions src/zig_app.zig

This file was deleted.

Loading