diff --git a/docs/guide/external_zig_modules.md b/docs/guide/external_zig_modules.md new file mode 100644 index 00000000..a7a1ac6d --- /dev/null +++ b/docs/guide/external_zig_modules.md @@ -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! diff --git a/mkdocs.yml b/mkdocs.yml index 0491ae53..0a872222 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -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: diff --git a/pydust/src/pydust.build.zig b/pydust/src/pydust.build.zig index f43e4d5e..65af48f1 100644 --- a/pydust/src/pydust.build.zig +++ b/pydust/src/pydust.build.zig @@ -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| { @@ -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( @@ -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(