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
59 changes: 59 additions & 0 deletions docs/guide/external_zig_modules.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# External Zig Modules

In order to use third party Zig dependencies, first, we need to set pydust `self_managed` mode to `true` in `pyproject.toml`, this way, you get to manage your own `build.zig`:

```toml linenums="0"
[tool.pydust]
self_managed = true
```

Fetch the required library with `zig fetch`. In this example we'll use [sam701/zig-toml](https://github.com/sam701/zig-toml) and [jetzig-framework/zmd](https://github.com/jetzig-framework/zmd).

Fetch the libraries with `zig fetch`:
```sh linenums="0"
zig fetch --save git+https://github.com/jetzig-framework/zmd.git
zig fetch --save git+https://github.com/sam701/zig-toml
```

Then, pass a list of modules to `pydust.addPythonModule`. This is an example of a `build.zig` file that uses an external Zig module:

```zig title="build.zig" hl_lines="14-26 34"
const std = @import("std");
const py = @import("./pydust.build.zig");

pub fn build(b: *std.Build) void {
const target = b.standardTargetOptionsQueryOnly(.{});
const optimize = b.standardOptimizeOption(.{});

const test_step = b.step("test", "Run library tests");

const pydust = py.addPydust(b, .{
.test_step = test_step,
});

const zmd = b.dependency("zmd", .{
.target = target,
.optimize = optimize,
});

const toml = b.dependency("toml", .{
.target = target,
.optimize = optimize,
});

var modules: [2]std.Build.Module.Import = undefined;
modules[0] = std.Build.Module.Import{ .name = "zmd", .module = zmd.module("zmd") };
modules[1] = std.Build.Module.Import{ .name = "toml", .module = toml.module("toml") };

_ = pydust.addPythonModule(.{
.name = "hello",
.root_source_file = b.path("src/hello.zig"),
.limited_api = true,
.target = target,
.optimize = optimize,
.imports = &modules,
});
}
```

Now you can import your modules from the Zig source files of you project!
1 change: 1 addition & 0 deletions mkdocs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ nav:
- 'Testing': "guide/_4_testing.md"
- 'Memory Management': "guide/_5_memory.md"
- 'Buffer Protocol': "guide/_6_buffers.md"
- 'External Zig Modules': "guide/external_zig_modules.md"

extra:
social:
Expand Down
7 changes: 7 additions & 0 deletions pydust/src/pydust.build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ pub const PythonModuleOptions = struct {
target: std.Target.Query,
optimize: std.builtin.Mode,
main_pkg_path: ?std.Build.LazyPath = null,
imports: []const std.Build.Module.Import = &.{},

pub fn short_name(self: *const PythonModuleOptions) [:0]const u8 {
if (std.mem.lastIndexOfScalar(u8, self.name, '.')) |short_name_idx| {
Expand Down Expand Up @@ -188,6 +189,9 @@ pub const PydustStep = struct {
lib.root_module.addImport("pydust", lib_module);
lib.linkLibC();
lib.linker_allow_shlib_undefined = true;
for (options.imports) |import| {
lib.root_module.addImport(import.name, import.module);
}

// Install the shared library within the source tree
const install = b.addInstallFileWithDir(
Expand Down Expand Up @@ -230,6 +234,9 @@ pub const PydustStep = struct {
libtest.addLibraryPath(b.path(self.python_library_dir));
// Needed to support miniconda statically linking libpython on macos
libtest.addRPath(b.path(self.python_library_dir));
for (options.imports) |import| {
libtest.root_module.addImport(import.name, import.module);
}

// Install the test binary
const install_libtest = b.addInstallBinFile(
Expand Down