zig-zon 0.1.2__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. zig-zon-0.2.0/PKG-INFO +60 -0
  2. zig-zon-0.2.0/build.zig +66 -0
  3. zig-zon-0.2.0/build.zig.zon +21 -0
  4. zig-zon-0.2.0/setup.py +63 -0
  5. zig-zon-0.2.0/setup.zig.json +1 -0
  6. {zig_zon-0.1.2 → zig-zon-0.2.0}/src/zig_zon.zig +8 -7
  7. zig-zon-0.2.0/zig-pkg/zig_python_sdist/README.md +7 -0
  8. zig-zon-0.2.0/zig-pkg/zig_python_sdist/build.zig +135 -0
  9. zig-zon-0.2.0/zig-pkg/zig_python_sdist/build.zig.zon +13 -0
  10. {zig_zon-0.1.2/.zig-dependencies/setuptools_zig_build-0.2.2-Ep6e3PA_AAD4M-tp4oSHJ1CvFBVqj3N87O67Z498MQwS/src → zig-zon-0.2.0/zig-pkg/zig_python_sdist/src/build}/CPython.zig +38 -108
  11. zig-zon-0.2.0/zig-pkg/zig_python_sdist/src/build/LowerDashStringFormatter.zig +12 -0
  12. zig-zon-0.2.0/zig-pkg/zig_python_sdist/src/build/SDistStep.zig +77 -0
  13. zig-zon-0.2.0/zig-pkg/zig_python_sdist/src/build/VenvInstallTest.zig +76 -0
  14. {zig_zon-0.1.2/.zig-dependencies/setuptools_zig_build-0.2.2-Ep6e3PA_AAD4M-tp4oSHJ1CvFBVqj3N87O67Z498MQwS/src → zig-zon-0.2.0/zig-pkg/zig_python_sdist/src/build}/extract_link_info.py +17 -9
  15. zig-zon-0.2.0/zig-pkg/zig_python_sdist/src/build/python.zig +50 -0
  16. zig_zon-0.1.2/.zig-dependencies/setuptools_zig_build-0.2.2-Ep6e3PA_AAD4M-tp4oSHJ1CvFBVqj3N87O67Z498MQwS/README.md +0 -46
  17. zig_zon-0.1.2/.zig-dependencies/setuptools_zig_build-0.2.2-Ep6e3PA_AAD4M-tp4oSHJ1CvFBVqj3N87O67Z498MQwS/build.zig +0 -6
  18. zig_zon-0.1.2/.zig-dependencies/setuptools_zig_build-0.2.2-Ep6e3PA_AAD4M-tp4oSHJ1CvFBVqj3N87O67Z498MQwS/build.zig.zon +0 -13
  19. zig_zon-0.1.2/.zig-dependencies/setuptools_zig_build-0.2.2-Ep6e3PA_AAD4M-tp4oSHJ1CvFBVqj3N87O67Z498MQwS/src/python-runner.zig +0 -49
  20. zig_zon-0.1.2/.zig-dependencies/setuptools_zig_build-0.2.2-Ep6e3PA_AAD4M-tp4oSHJ1CvFBVqj3N87O67Z498MQwS/src/runtime.zig +0 -33
  21. zig_zon-0.1.2/LICENSE +0 -21
  22. zig_zon-0.1.2/MANIFEST.in +0 -2
  23. zig_zon-0.1.2/PKG-INFO +0 -67
  24. zig_zon-0.1.2/README.md +0 -48
  25. zig_zon-0.1.2/build.zig +0 -36
  26. zig_zon-0.1.2/build.zig.zon +0 -21
  27. zig_zon-0.1.2/pyproject.toml +0 -32
  28. zig_zon-0.1.2/sdistlist.json +0 -1
  29. zig_zon-0.1.2/setup.cfg +0 -4
  30. zig_zon-0.1.2/setup.py +0 -23
  31. zig_zon-0.1.2/src/test_zig_zon.py +0 -41
  32. zig_zon-0.1.2/zig_zon.egg-info/PKG-INFO +0 -67
  33. zig_zon-0.1.2/zig_zon.egg-info/SOURCES.txt +0 -13
  34. zig_zon-0.1.2/zig_zon.egg-info/dependency_links.txt +0 -1
  35. zig_zon-0.1.2/zig_zon.egg-info/top_level.txt +0 -1
  36. {zig_zon-0.1.2/.zig-dependencies/setuptools_zig_build-0.2.2-Ep6e3PA_AAD4M-tp4oSHJ1CvFBVqj3N87O67Z498MQwS → zig-zon-0.2.0/zig-pkg/zig_python_sdist}/LICENSE +0 -0
zig-zon-0.2.0/PKG-INFO ADDED
@@ -0,0 +1,60 @@
1
+ Metadata-Version: 2.4
2
+ Name: zig-zon
3
+ Version: 0.2.0
4
+ Summary:
5
+ Description-Content-Type: text/markdown
6
+
7
+ # Python Zig Zon Parser
8
+
9
+ A native python extension built with zig to parse zig-object-notation strings
10
+ into python objects.
11
+
12
+ On PyPi it is only distributed in source, and built during install.
13
+ It therefore needs to download the `ziglang` python package.
14
+
15
+ Depending on your OS, you may need the python development headers
16
+ (e.g. `python3-dev`) installed.
17
+
18
+ ## Usage
19
+
20
+ install from source on pypi:
21
+
22
+ ```bash
23
+ pip install zig-zon
24
+ ```
25
+
26
+ running:
27
+
28
+ ```python
29
+ import zig_zon
30
+ parsed = zig_zon.parse('.{.allyourcode = .are_belong_to_us, .asd = 123}')
31
+ print(parsed)
32
+ ```
33
+
34
+ or, look at the [test file](https://codeberg.org/dasimmet/python-zig-zon/src/branch/main/src/test_zig_zon.py)
35
+
36
+ ## How it works
37
+
38
+ The `zig build` commands produces a python source distribution archive ready
39
+ for uploading to Pypi. It includes the sources of [zig-python-sdist](https://codeberg.org/dasimmet/zig-python-sdist)
40
+ and a custom `setup.py` that handles the build of the cpython extension.
41
+
42
+ When you run pip install, the source distribution is downloaded, and since
43
+ this source distribution depends on the `ziglang` python package at build time,
44
+ a `zig build` command is used to compile the extension.
45
+
46
+ ## Developing
47
+
48
+ as opposed to other solutions for building cpython extensions in zig,
49
+ i want to develop this using:
50
+
51
+ ```
52
+ zig build
53
+ ```
54
+
55
+ for linking against the local python installation [zig-python-sdist](https://codeberg.org/dasimmet/zig-python-sdist)
56
+ runs a python script that imports the cpython headers into zig's build cache,
57
+ run `translate-c` on the result and offers a `cpython` module to import
58
+ in our zig code.
59
+ On windows, the extension library is also linked against
60
+ the python runtime static lib and renamed to a `.pyd` file for importing.
@@ -0,0 +1,66 @@
1
+ const std = @import("std");
2
+ const Build = std.Build;
3
+ const zig_python_sdist = @import("zig_python_sdist");
4
+ const zon = @import("build.zig.zon");
5
+ const CPython = @import("setuptools_zig_build").CPython;
6
+
7
+ pub fn build(b: *Build) void {
8
+ const target = b.standardTargetOptions(.{});
9
+ const optimize = b.standardOptimizeOption(.{});
10
+
11
+ // this target and section of our build is used at pip install time
12
+ const ext_install_step = b.step("pyext", "build python extension module");
13
+ {
14
+ const cpython = zig_python_sdist.CPython.find(b);
15
+
16
+ const lib = b.addLibrary(.{
17
+ .name = "zig_zon",
18
+ .root_module = b.addModule("zig_zon", .{
19
+ .root_source_file = b.path("src/zig_zon.zig"),
20
+ .target = target,
21
+ .optimize = optimize,
22
+ }),
23
+ .linkage = .dynamic,
24
+ });
25
+ cpython.link(b, .{
26
+ .lib = lib,
27
+ .version = zon.version,
28
+ .optimize = .ReleaseSmall,
29
+ });
30
+ const ext_install = zig_python_sdist.CPython.installExtLib(b, lib);
31
+
32
+ ext_install_step.dependOn(&ext_install.step);
33
+ }
34
+
35
+ // this generates a python sdist archive
36
+ const sdist = zig_python_sdist.create(b, .{
37
+ .name = "zig-zon",
38
+ .version = zon.version,
39
+ .description = b.path("README.md"),
40
+ .build_args = &.{ ext_install_step.name, b.fmt("-Doptimize={s}", .{@tagName(optimize)}) },
41
+ .files = &.{
42
+ .{ .src = b.path("build.zig.zon"), .dest = "build.zig.zon" },
43
+ .{ .src = b.path("build.zig"), .dest = "build.zig" },
44
+ .{ .src = b.path("src/zig_zon.zig"), .dest = "src/zig_zon.zig" },
45
+ },
46
+ });
47
+
48
+ const sdistfile = b.addInstallFileWithDir(
49
+ sdist.getEmittedArchive(),
50
+ .{ .custom = "src" },
51
+ sdist.basename,
52
+ );
53
+ b.getInstallStep().dependOn(&sdistfile.step);
54
+
55
+ // we can use a python virtual environment inside
56
+ // the zig cache to test pip installation
57
+ const test_pip_install = zig_python_sdist.VenvInstallTest.create(
58
+ b,
59
+ .{
60
+ .sdist = sdist.getEmittedArchive(),
61
+ .test_py = b.path("src/test_zig_zon.py"),
62
+ .no_clean = b.option(bool, "pip-no-clean", "dont cleanup pip temp dirs") orelse false,
63
+ },
64
+ );
65
+ b.step("test-pip-install", "").dependOn(test_pip_install.step);
66
+ }
@@ -0,0 +1,21 @@
1
+ .{
2
+ .name = .python_zig_zon,
3
+ .fingerprint = 0x3d332656a3644fc9,
4
+ .version = "0.2.0",
5
+ .minimum_zig_version = "0.16.0",
6
+ .dependencies = .{
7
+ .zig_python_sdist = .{
8
+ .url = "git+https://codeberg.org/dasimmet/zig-python-sdist.git#509be1fcce025754c7bc6f0647802e79e195778b",
9
+ .hash = "zig_python_sdist-0.0.1-wjgdOo-NAAAH7qc0ulwksgbdgfrZ8bP4EhMw_ZRN1UtS",
10
+ },
11
+ },
12
+ .paths = .{
13
+ "src",
14
+ "build.zig",
15
+ "build.zig.zon",
16
+ "LICENSE",
17
+ "README.md",
18
+ "setup.py",
19
+ "pyproject.toml",
20
+ },
21
+ }
zig-zon-0.2.0/setup.py ADDED
@@ -0,0 +1,63 @@
1
+ #!/usr/bin/env python
2
+
3
+ from setuptools import setup
4
+ from setuptools.command.bdist_wheel import bdist_wheel
5
+ import subprocess
6
+ import sys
7
+ import os
8
+ import json
9
+ import glob
10
+ import shutil
11
+
12
+ with open("setup.zig.json") as fd:
13
+ setup_json = json.load(fd)
14
+
15
+
16
+ def mkversion(v, need_release=False):
17
+ if need_release:
18
+ assert v['pre'] == None, "cannot use version with pre: " + str(v)
19
+ assert v['build'] == None, "cannot use version with build: " + str(v)
20
+ return str(v['major']) + '.' + str(
21
+ v['minor']) + '.' + str(v['patch'])
22
+
23
+
24
+ class ZigBuildWheel(bdist_wheel):
25
+ def run(self, *args, **kwargs):
26
+
27
+ import ziglang
28
+ zig_exe = os.path.join(
29
+ os.path.dirname(ziglang.__file__), "zig")
30
+
31
+ cwd = os.getcwd()
32
+ print("zig build dir:", cwd, file=sys.stderr)
33
+ print("using zig exe:", zig_exe, file=sys.stderr)
34
+
35
+ extra_build_args = setup_json['build']['args']
36
+ build_cmd = [zig_exe, 'build'] + extra_build_args
37
+
38
+ print("zig build:", build_cmd, file=sys.stderr)
39
+ subprocess.check_call(build_cmd)
40
+
41
+ os.makedirs(self.bdist_dir, exist_ok=True)
42
+ artifacts = glob.glob("zig-out/lib/*")
43
+ if len(artifacts) == 0:
44
+ raise Exception(
45
+ 'no zig artifacts found in {}/zig-out/lib/*'.format(cwd))
46
+
47
+ for it in artifacts:
48
+ shutil.copyfile(it, os.path.join(
49
+ self.bdist_dir, os.path.basename(it)))
50
+
51
+ return super().run(*args, **kwargs)
52
+
53
+
54
+ setup(
55
+ name=setup_json['name'],
56
+ version=mkversion(setup_json['version']),
57
+ cmdclass={'bdist_wheel': ZigBuildWheel},
58
+ setup_requires=[
59
+ "setuptools",
60
+ "wheel",
61
+ "ziglang==" + mkversion(setup_json['zig_version'], need_release=True),
62
+ ],
63
+ )
@@ -0,0 +1 @@
1
+ {"name":"zig_zon","version":{"major":0,"minor":2,"patch":0,"pre":null,"build":null},"zig_version":{"major":0,"minor":16,"patch":0,"pre":null,"build":null},"build":{"args":["pyext","-Doptimize=Debug","--fork=zig-pkg/zig_python_sdist"]}}
@@ -4,8 +4,8 @@ const Allocator = std.mem.Allocator;
4
4
  const assert = std.debug.assert;
5
5
  const ZonGen = std.zig.ZonGen;
6
6
 
7
- const python = @import("cpython");
8
- const c = python.c;
7
+ const cpython = @import("cpython");
8
+ const c = cpython.c;
9
9
  const PyObject = c.PyObject;
10
10
 
11
11
  pub var methods = [_]c.PyMethodDef{
@@ -25,7 +25,8 @@ pub var zigmodule = c.PyModuleDef{
25
25
 
26
26
  pub export fn PyInit_zig_zon() [*c]c.PyObject {
27
27
  const mod = c.PyModule_Create(&zigmodule);
28
- python.addVersion(mod);
28
+ cpython.addVersion(mod);
29
+ cpython.addZigTargetTriple(mod);
29
30
  return mod;
30
31
  }
31
32
 
@@ -138,8 +139,8 @@ fn parseZon(arena: Allocator, tree: Ast, node: Ast.Node.Index) ZonError!*c.PyObj
138
139
  return PyNone();
139
140
  } else {
140
141
  if (@errorReturnTrace()) |et| {
141
- std.debug.dumpStackTrace(et.*);
142
- std.debug.dumpCurrentStackTrace(null);
142
+ std.debug.dumpErrorReturnTrace(et);
143
+ std.debug.dumpCurrentStackTrace(.{});
143
144
  }
144
145
  std.log.err("identifier not implemented: {any} '{s}'", .{ node_tag, token_slice });
145
146
  return error.NotImplemented;
@@ -147,8 +148,8 @@ fn parseZon(arena: Allocator, tree: Ast, node: Ast.Node.Index) ZonError!*c.PyObj
147
148
  },
148
149
  else => {
149
150
  if (@errorReturnTrace()) |et| {
150
- std.debug.dumpStackTrace(et.*);
151
- std.debug.dumpCurrentStackTrace(null);
151
+ std.debug.dumpErrorReturnTrace(et);
152
+ std.debug.dumpCurrentStackTrace(.{});
152
153
  }
153
154
  const token_slice = tree.tokenSlice(tree.firstToken(node));
154
155
  std.log.err("zon ast token not implemented: {any} '{s}'", .{ node_tag, token_slice });
@@ -0,0 +1,7 @@
1
+ # Zig Python Sdist
2
+
3
+ this is a toolset to build python source distributions for pypi directly
4
+ using `zig build`.
5
+
6
+ It allows to add a python distribution to zig packages
7
+ without dealing with python package metadata the traditional way.
@@ -0,0 +1,135 @@
1
+ const std = @import("std");
2
+ const Build = std.Build;
3
+ const LazyPath = Build.LazyPath;
4
+ const zon = @import("build.zig.zon");
5
+
6
+ pub const CPython = @import("src/build/CPython.zig");
7
+ pub const VenvInstallTest = @import("src/build/VenvInstallTest.zig");
8
+ pub const SDistStep = @import("src/build/SDistStep.zig");
9
+
10
+ pub fn build(b: *Build) void {
11
+ const target = b.standardTargetOptions(.{});
12
+ const optimize = b.standardOptimizeOption(.{});
13
+
14
+ const mod = b.addModule("sdist-builder", .{
15
+ .root_source_file = b.path("src/sdist_builder.zig"),
16
+ .target = target,
17
+ .optimize = optimize,
18
+ });
19
+
20
+ const exe = b.addExecutable(.{
21
+ .name = "sdist-builder",
22
+ .root_module = mod,
23
+ });
24
+
25
+ b.installArtifact(exe);
26
+
27
+ const cpython = CPython.find(b);
28
+
29
+ const sdist_dummy = b.addLibrary(.{
30
+ .name = "sdist_dummy",
31
+ .root_module = b.createModule(.{
32
+ .root_source_file = b.path("example/sdist_dummy.zig"),
33
+ .target = target,
34
+ .optimize = optimize,
35
+ }),
36
+ .linkage = .dynamic,
37
+ });
38
+ cpython.link(b, .{
39
+ .lib = sdist_dummy,
40
+ .version = zon.version,
41
+ });
42
+ const install_ext = CPython.installExtLib(b, sdist_dummy);
43
+
44
+ const build_ext_step = b.step("build-ext", "build the sdist dummy python module");
45
+ build_ext_step.dependOn(&install_ext.step);
46
+
47
+ const sdist = SDistStep.createInternal(b, .{
48
+ .sdist_builder = exe,
49
+ .name = "zig-python-sdist-dummy",
50
+ .version = zon.version,
51
+ .description = b.path("README.md"),
52
+ .build_args = &.{build_ext_step.name}, // target name for pip zig build command
53
+ .files = &.{
54
+ .{ .src = b.path("build.zig.zon"), .dest = "build.zig.zon" },
55
+ .{ .src = b.path("build.zig"), .dest = "build.zig" },
56
+ .{ .src = b.path("example/sdist_dummy.zig"), .dest = "example/sdist_dummy.zig" },
57
+ },
58
+ .directories = &.{
59
+ .{ .src = b.path("src"), .dest = "src" },
60
+ .{ .src = b.path("src/build"), .dest = "src/build" },
61
+ },
62
+ .zig_version = std.SemanticVersion.parse("0.16.0") catch unreachable,
63
+ });
64
+
65
+ const sdistfile = b.addInstallFileWithDir(
66
+ sdist.getEmittedArchive(),
67
+ .{ .custom = "src" },
68
+ sdist.basename,
69
+ );
70
+ b.getInstallStep().dependOn(&sdistfile.step);
71
+
72
+ const test_pip_install = VenvInstallTest.create(
73
+ b,
74
+ .{
75
+ .sdist = sdist.getEmittedArchive(),
76
+ .test_py = b.path("example/test_ext.py"),
77
+ .no_clean = b.option(bool, "pip-no-clean", "cleanup pip temp dirs") orelse false,
78
+ },
79
+ );
80
+ b.step("test-pip-install", "").dependOn(test_pip_install.step);
81
+ }
82
+
83
+ pub fn create(b: *Build, options: SDistStep.Options) *SDistStep {
84
+ var opt = options;
85
+ const sdist = b.dependencyFromBuildZig(@This(), .{
86
+ .target = b.graph.host,
87
+ .optimize = .Debug,
88
+ });
89
+ opt.sdist_builder = opt.sdist_builder orelse sdist.artifact("sdist-builder");
90
+
91
+ {
92
+ var files: std.ArrayList(SDistStep.Content) = .empty;
93
+ const extra_files: []const SDistStep.Content = &.{
94
+ .{ .src = sdist.path("build.zig.zon"), .dest = "zig-pkg/zig_python_sdist/build.zig.zon" },
95
+ .{ .src = sdist.path("build.zig"), .dest = "zig-pkg/zig_python_sdist/build.zig" },
96
+ .{ .src = sdist.path("README.md"), .dest = "zig-pkg/zig_python_sdist/README.md" },
97
+ .{ .src = sdist.path("LICENSE"), .dest = "zig-pkg/zig_python_sdist/LICENSE" },
98
+ };
99
+ files.ensureTotalCapacity(
100
+ b.allocator,
101
+ opt.files.len + extra_files.len,
102
+ ) catch @panic("OOM");
103
+ files.appendSliceAssumeCapacity(opt.files);
104
+ files.appendSliceAssumeCapacity(extra_files);
105
+ opt.files = files.toOwnedSlice(b.allocator) catch @panic("OOM");
106
+ }
107
+
108
+ {
109
+ var dirs: std.ArrayList(SDistStep.Content) = .empty;
110
+ const extra_dirs: []const SDistStep.Content = &.{
111
+ // .{ .src = sdist.path("src"), .dest = "zig-pkg/zig_python_sdist/src" },
112
+ .{ .src = sdist.path("src/build"), .dest = "zig-pkg/zig_python_sdist/src/build" },
113
+ };
114
+ dirs.ensureTotalCapacity(
115
+ b.allocator,
116
+ opt.directories.len + extra_dirs.len,
117
+ ) catch @panic("OOM");
118
+ dirs.appendSliceAssumeCapacity(opt.directories);
119
+ dirs.appendSliceAssumeCapacity(extra_dirs);
120
+ opt.directories = dirs.toOwnedSlice(b.allocator) catch @panic("OOM");
121
+ }
122
+
123
+ {
124
+ var args: std.ArrayList([]const u8) = .empty;
125
+ args.ensureTotalCapacity(
126
+ b.allocator,
127
+ opt.build_args.len + 1,
128
+ ) catch @panic("OOM");
129
+ args.appendSliceAssumeCapacity(opt.build_args);
130
+ args.appendAssumeCapacity("--fork=zig-pkg/zig_python_sdist");
131
+ opt.build_args = args.toOwnedSlice(b.allocator) catch @panic("OOM");
132
+ }
133
+
134
+ return SDistStep.createInternal(b, opt);
135
+ }
@@ -0,0 +1,13 @@
1
+ .{
2
+ .name = .zig_python_sdist,
3
+ .version = "0.0.1",
4
+ .minimum_zig_version = "0.17.0-dev.947+36069a2a7",
5
+ .paths = .{
6
+ "build.zig",
7
+ "build.zig.zon",
8
+ "README.md",
9
+ "LICENSE",
10
+ "src",
11
+ },
12
+ .fingerprint = 0xbc2496e43a1d38c2,
13
+ }
@@ -7,7 +7,6 @@ const mem = std.mem;
7
7
  pub const CPython = @This();
8
8
 
9
9
  exe: Build.LazyPath,
10
- version: ?[]const u8 = null,
11
10
 
12
11
  /// adds a `python` option to the build. if not provided, tries to find `python` in PATH
13
12
  pub fn findAddOption(b: *Build) *CPython {
@@ -26,10 +25,10 @@ pub fn findAddOption(b: *Build) *CPython {
26
25
 
27
26
  pub fn find(b: *Build) *CPython {
28
27
  const self = b.allocator.create(CPython) catch @panic("OOM");
29
- const exe_path = FindExeWindowsCompat.findProgram(b, &.{
28
+ const exe_path = findProgramCompat(b, &.{
30
29
  "python",
31
30
  "python3",
32
- }, &.{}) catch {
31
+ }) orelse {
33
32
  const err_wf = b.addWriteFiles();
34
33
  const err_step = b.addFail("finding python failed. please provide a path to the exe using -Dpython=");
35
34
  err_wf.step.dependOn(&err_step.step);
@@ -44,17 +43,12 @@ pub fn find(b: *Build) *CPython {
44
43
  return self;
45
44
  }
46
45
 
47
- pub fn addVersionOption(self: *CPython, b: *Build, fallback: []const u8) void {
48
- self.version = b.option(
49
- []const u8,
50
- "version",
51
- "set a version string",
52
- ) orelse fallback;
53
- }
54
-
55
46
  pub const LinkOptions = struct {
56
47
  /// library to link against libpython
57
48
  lib: *std.Build.Step.Compile,
49
+ version: ?[]const u8 = null,
50
+ /// optimize mode for the c module. will fall back to lib's optimize mode.
51
+ optimize: ?std.builtin.OptimizeMode = null,
58
52
  macros: []const [2][]const u8 = &default_macros,
59
53
  pub const default_macros = .{
60
54
  .{ "Py_LIMITED_API", "0x03060500" }, // use the limited api from 3.6.5
@@ -69,58 +63,54 @@ pub fn generateIncludeDir(self: CPython, b: *Build) Build.LazyPath {
69
63
  return extract_link_info.addOutputDirectoryArg("include");
70
64
  }
71
65
 
72
- pub fn installExtLib(b: *Build, lib: *Build.Step.Compile) void {
66
+ pub fn installExtLib(b: *Build, lib: *Build.Step.Compile) *Build.Step.InstallFile {
73
67
  const ext_lib_name = lib_ext_name(b, lib);
74
- const lib_install = b.addInstallLibFile(lib.getEmittedBin(), ext_lib_name);
75
- b.getInstallStep().dependOn(&lib_install.step);
68
+ return b.addInstallLibFile(lib.getEmittedBin(), ext_lib_name);
76
69
  }
77
70
 
78
- pub fn link(self: CPython, b: *Build, opt: LinkOptions) void {
71
+ pub fn link(self: CPython, b: *Build, options: LinkOptions) void {
79
72
  const target = Build.ResolvedTarget{
80
73
  .query = .{},
81
- .result = opt.lib.rootModuleTarget(),
74
+ .result = options.lib.rootModuleTarget(),
82
75
  };
83
76
 
84
77
  const python_inc = self.generateIncludeDir(b);
85
78
 
86
79
  const cpython = b.addTranslateC(.{
87
80
  .root_source_file = python_inc.path(b, "Zig_Python_With_Hexver.h"),
88
- .optimize = opt.lib.root_module.optimize orelse .ReleaseSafe,
81
+ .optimize = options.optimize orelse options.lib.root_module.optimize orelse .ReleaseSafe,
89
82
  .target = target,
90
- .link_libc = true,
91
83
  });
92
84
  cpython.addIncludePath(python_inc);
93
85
 
94
86
  const wf = b.addWriteFiles();
95
- _ = wf.add("runtime.zig", @embedFile("runtime.zig"));
96
- const pymod_lp = wf.add("python.zig", if (self.version == null)
97
- \\pub const c = @import("c");
98
- \\pub const runtime = @import("runtime.zig");
99
- else
100
- \\pub const c = @import("c");
101
- \\pub const runtime = @import("runtime.zig");
102
- \\pub const version = @embedFile("version.txt");
103
- \\pub fn addVersion(mod: [*c]c.PyObject) void {
104
- \\ runtime.addVersion(@This(), mod);
105
- \\}
106
- \\
107
- );
108
- if (self.version) |version| {
109
- _ = wf.add("version.txt", version);
110
- }
111
87
 
112
- const pymod = b.createModule(.{ .root_source_file = pymod_lp });
113
- pymod.addImport("c", cpython.createModule());
88
+ const pymod = b.createModule(.{
89
+ .root_source_file = wf.add("python.zig", @embedFile("python.zig")),
90
+ .imports = &.{
91
+ .{ .name = "c", .module = cpython.createModule() },
92
+ },
93
+ });
94
+
95
+ if (options.version) |version| {
96
+ pymod.addImport("version", b.createModule(.{
97
+ .root_source_file = wf.add("version.txt", version),
98
+ }));
99
+ } else {
100
+ pymod.addImport("version", b.createModule(.{
101
+ .root_source_file = wf.add("version.txt", "version not provided at configure time!"),
102
+ }));
103
+ }
114
104
 
115
- for (opt.macros) |macro| {
105
+ for (options.macros) |macro| {
116
106
  cpython.defineCMacro(macro[0], macro[1]);
117
107
  }
118
108
 
119
109
  if (target.result.os.tag == .windows) {
120
- opt.lib.root_module.addLibraryPath(python_inc);
121
- opt.lib.linkSystemLibrary("python");
110
+ options.lib.root_module.addLibraryPath(python_inc);
111
+ options.lib.root_module.linkSystemLibrary("python", .{});
122
112
  }
123
- opt.lib.root_module.addImport(
113
+ options.lib.root_module.addImport(
124
114
  "cpython",
125
115
  pymod,
126
116
  );
@@ -166,74 +156,6 @@ pub fn writeExtensionFile(b: *Build, lib: *Build.Step.Compile) Build.LazyPath {
166
156
  return wf.addCopyFile(lib.getEmittedBin(), ext_lib_name);
167
157
  }
168
158
 
169
- const FindExeWindowsCompat = struct {
170
- fn tryFindProgram(b: *Build, full_path: []const u8) ?[]const u8 {
171
- if (fs.realpathAlloc(b.allocator, full_path)) |p| {
172
- return p;
173
- } else |err| switch (err) {
174
- error.OutOfMemory => @panic("OOM"),
175
- else => {},
176
- }
177
-
178
- if (builtin.os.tag == .windows) {
179
- if (b.graph.env_map.get("PATHEXT")) |PATHEXT| {
180
- var it = mem.tokenizeScalar(u8, PATHEXT, fs.path.delimiter);
181
-
182
- while (it.next()) |ext| {
183
- if (!supportedWindowsProgramExtension(ext)) continue;
184
- const exe_path = mem.join(b.allocator, "", &.{ full_path, ext }) catch @panic("OOM");
185
- fs.accessAbsolute(exe_path, .{ .mode = .read_only }) catch {
186
- b.allocator.free(exe_path);
187
- continue;
188
- };
189
- return exe_path;
190
- }
191
- }
192
- }
193
-
194
- return null;
195
- }
196
-
197
- pub fn findProgram(b: *Build, names: []const []const u8, paths: []const []const u8) error{FileNotFound}![]const u8 {
198
- // TODO report error for ambiguous situations
199
- for (b.search_prefixes.items) |search_prefix| {
200
- for (names) |name| {
201
- if (fs.path.isAbsolute(name)) {
202
- return name;
203
- }
204
- return tryFindProgram(b, b.pathJoin(&.{ search_prefix, "bin", name })) orelse continue;
205
- }
206
- }
207
- if (b.graph.env_map.get("PATH")) |PATH| {
208
- for (names) |name| {
209
- if (fs.path.isAbsolute(name)) {
210
- return name;
211
- }
212
- var it = mem.tokenizeScalar(u8, PATH, fs.path.delimiter);
213
- while (it.next()) |p| {
214
- return tryFindProgram(b, b.pathJoin(&.{ p, name })) orelse continue;
215
- }
216
- }
217
- }
218
- for (names) |name| {
219
- if (fs.path.isAbsolute(name)) {
220
- return name;
221
- }
222
- for (paths) |p| {
223
- return tryFindProgram(b, b.pathJoin(&.{ p, name })) orelse continue;
224
- }
225
- }
226
- return error.FileNotFound;
227
- }
228
-
229
- fn supportedWindowsProgramExtension(ext: []const u8) bool {
230
- inline for (@typeInfo(std.process.Child.WindowsExtension).@"enum".fields) |field| {
231
- if (std.ascii.eqlIgnoreCase(ext, "." ++ field.name)) return true;
232
- }
233
- return false;
234
- }
235
- };
236
-
237
159
  pub fn addSdistList(b: *Build) void {
238
160
  const wf = b.addWriteFiles();
239
161
  var wr: std.Io.Writer.Allocating = .init(b.allocator);
@@ -266,3 +188,11 @@ fn writeDeps(b: *std.Build, w: *std.json.Stringify) !void {
266
188
  }
267
189
  }
268
190
  }
191
+
192
+ // compat for 0.16.0 and 0.17.0
193
+ pub fn findProgramCompat(b: *std.Build, names: []const []const u8) ?[]const u8 {
194
+ if (comptime (@import("builtin").zig_version.order(std.SemanticVersion.parse("0.16.0") catch unreachable) == .gt)) {
195
+ return b.findProgram(.{ .names = names });
196
+ }
197
+ return b.findProgram(names, &.{}) catch null;
198
+ }
@@ -0,0 +1,12 @@
1
+ const std = @import("std");
2
+ str: []const u8,
3
+ pub fn format(self: @This(), w: *std.Io.Writer) !void {
4
+ for (self.str) |char| {
5
+ if (char != '-') {
6
+ @branchHint(.likely);
7
+ try w.writeByte(char);
8
+ } else {
9
+ try w.writeByte('_');
10
+ }
11
+ }
12
+ }