zig-zon 0.2.1__tar.gz → 0.2.3__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.
- {zig-zon-0.2.1 → zig-zon-0.2.3}/PKG-INFO +23 -2
- {zig-zon-0.2.1 → zig-zon-0.2.3}/build.zig +28 -36
- {zig-zon-0.2.1 → zig-zon-0.2.3}/build.zig.zon +4 -3
- zig-zon-0.2.3/pkg-info.zon +15 -0
- {zig-zon-0.2.1 → zig-zon-0.2.3}/setup.py +4 -2
- zig-zon-0.2.3/setup.zig.json +1 -0
- {zig-zon-0.2.1 → zig-zon-0.2.3}/src/zig_zon.zig +38 -27
- {zig-zon-0.2.1 → zig-zon-0.2.3}/zig-pkg/zig_python_sdist/build.zig +17 -26
- {zig-zon-0.2.1 → zig-zon-0.2.3}/zig-pkg/zig_python_sdist/build.zig.zon +2 -1
- zig-zon-0.2.3/zig-pkg/zig_python_sdist/pkg-info.zon +11 -0
- zig-zon-0.2.3/zig-pkg/zig_python_sdist/src/build/CPython.zig +125 -0
- {zig-zon-0.2.1 → zig-zon-0.2.3}/zig-pkg/zig_python_sdist/src/build/SDistStep.zig +26 -2
- {zig-zon-0.2.1 → zig-zon-0.2.3}/zig-pkg/zig_python_sdist/src/build/VenvInstallTest.zig +29 -4
- zig-zon-0.2.3/zig-pkg/zig_python_sdist/src/build/extract_link_info.py +84 -0
- {zig-zon-0.2.1 → zig-zon-0.2.3}/zig-pkg/zig_python_sdist/src/build/pkg_info.zig +0 -19
- zig-zon-0.2.3/zig-pkg/zig_python_sdist/src/build/python.zig +217 -0
- zig-zon-0.2.1/setup.zig.json +0 -1
- zig-zon-0.2.1/zig-pkg/zig_python_sdist/src/build/CPython.zig +0 -198
- zig-zon-0.2.1/zig-pkg/zig_python_sdist/src/build/extract_link_info.py +0 -72
- zig-zon-0.2.1/zig-pkg/zig_python_sdist/src/build/python.zig +0 -50
- {zig-zon-0.2.1 → zig-zon-0.2.3}/zig-pkg/zig_python_sdist/LICENSE +0 -0
- {zig-zon-0.2.1 → zig-zon-0.2.3}/zig-pkg/zig_python_sdist/README.md +0 -0
- {zig-zon-0.2.1 → zig-zon-0.2.3}/zig-pkg/zig_python_sdist/src/build/LowerDashStringFormatter.zig +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: zig-zon
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: a native cpython extension to parse zig object notation strings
|
|
5
5
|
Author-email: Tobias Simetsreiter <dasimmet@gmail.com>
|
|
6
6
|
Maintainer-email: Tobias Simetsreiter <dasimmet@gmail.com>
|
|
@@ -10,6 +10,10 @@ Requires-Python: >=3.8
|
|
|
10
10
|
Project-URL: Homepage, https://codeberg.org/dasimmet/python-zig-zon
|
|
11
11
|
Project-URL: Issues, https://codeberg.org/dasimmet/python-zig-zon/issues
|
|
12
12
|
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Programming Language :: Python :: 3
|
|
14
|
+
Classifier: Programming Language :: Zig
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: Topic :: Software Development :: Libraries
|
|
13
17
|
Description-Content-Type: text/markdown
|
|
14
18
|
|
|
15
19
|
# Python Zig Zon Parser
|
|
@@ -25,7 +29,7 @@ Depending on your OS, you may need the python development headers
|
|
|
25
29
|
|
|
26
30
|
## Usage
|
|
27
31
|
|
|
28
|
-
install from source on pypi
|
|
32
|
+
install from source on <https://pypi.org/project/zig-zon>:
|
|
29
33
|
|
|
30
34
|
```bash
|
|
31
35
|
pip install zig-zon
|
|
@@ -41,6 +45,23 @@ print(parsed)
|
|
|
41
45
|
|
|
42
46
|
or, look at the [test file](https://codeberg.org/dasimmet/python-zig-zon/src/branch/main/src/test_zig_zon.py)
|
|
43
47
|
|
|
48
|
+
## Supported values and their python type
|
|
49
|
+
|
|
50
|
+
- `structs` -> `dict`
|
|
51
|
+
- `tuples` -> `list`
|
|
52
|
+
- `integer literals` -> `int`
|
|
53
|
+
- `hex literals` -> `int`
|
|
54
|
+
- `float literals` -> `float`
|
|
55
|
+
- `booleans` -> `bool`
|
|
56
|
+
- `null` -> `None`
|
|
57
|
+
- `string literals` -> `str`
|
|
58
|
+
- `bare enum literals` -> `str`
|
|
59
|
+
- `quoted enum literals` -> `str`
|
|
60
|
+
|
|
61
|
+
## Not supported values
|
|
62
|
+
|
|
63
|
+
- `bigint`
|
|
64
|
+
|
|
44
65
|
## How it works
|
|
45
66
|
|
|
46
67
|
The `zig build` commands produces a python source distribution archive ready
|
|
@@ -2,35 +2,13 @@ const std = @import("std");
|
|
|
2
2
|
const Build = std.Build;
|
|
3
3
|
const zig_python_sdist = @import("zig_python_sdist");
|
|
4
4
|
const zon = @import("build.zig.zon");
|
|
5
|
-
const CPython = @import("setuptools_zig_build").CPython;
|
|
6
5
|
|
|
7
6
|
pub fn build(b: *Build) void {
|
|
8
7
|
const target = b.standardTargetOptions(.{});
|
|
9
8
|
const optimize = b.standardOptimizeOption(.{});
|
|
10
9
|
|
|
11
10
|
// this target and section of our build is used at pip install time
|
|
12
|
-
const ext_install_step = b.step("
|
|
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
|
-
}
|
|
11
|
+
const ext_install_step = b.step("bdist-wheel", "build python extension module");
|
|
34
12
|
|
|
35
13
|
// this generates a python sdist archive
|
|
36
14
|
const sdist = zig_python_sdist.create(b, .{
|
|
@@ -38,21 +16,14 @@ pub fn build(b: *Build) void {
|
|
|
38
16
|
.version = zon.version,
|
|
39
17
|
.description = b.path("README.md"),
|
|
40
18
|
.build = .{
|
|
41
|
-
.args = &.{
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
.{ .key = "Author-email", .value = "Tobias Simetsreiter <dasimmet@gmail.com>" },
|
|
46
|
-
.{ .key = "Maintainer-email", .value = "Tobias Simetsreiter <dasimmet@gmail.com>" },
|
|
47
|
-
.{ .key = "License-Expression", .value = "MIT" },
|
|
48
|
-
.{ .key = "Keywords", .value = "zig,ziglang,cpython,native,sdist,zon" },
|
|
49
|
-
.{ .key = "Requires-Python", .value = ">=3.8" },
|
|
50
|
-
.{ .key = "Project-URL", .value = "Homepage, https://codeberg.org/dasimmet/python-zig-zon" },
|
|
51
|
-
.{ .key = "Project-URL", .value = "Issues, https://codeberg.org/dasimmet/python-zig-zon/issues" },
|
|
52
|
-
// .{ .key = "Requires-Python", .value = ">=3.8" },
|
|
53
|
-
.{ .key = "Classifier", .value = "Development Status :: 4 - Beta" },
|
|
19
|
+
.args = &.{
|
|
20
|
+
ext_install_step.name,
|
|
21
|
+
b.fmt("-Doptimize={s}", .{@tagName(optimize)}),
|
|
22
|
+
},
|
|
54
23
|
},
|
|
24
|
+
.extra_pkg_info = @import("pkg-info.zon"),
|
|
55
25
|
.files = &.{
|
|
26
|
+
.{ .src = b.path("pkg-info.zon"), .dest = "pkg-info.zon" },
|
|
56
27
|
.{ .src = b.path("build.zig.zon"), .dest = "build.zig.zon" },
|
|
57
28
|
.{ .src = b.path("build.zig"), .dest = "build.zig" },
|
|
58
29
|
.{ .src = b.path("src/zig_zon.zig"), .dest = "src/zig_zon.zig" },
|
|
@@ -73,8 +44,29 @@ pub fn build(b: *Build) void {
|
|
|
73
44
|
.{
|
|
74
45
|
.sdist = sdist.getEmittedArchive(),
|
|
75
46
|
.test_py = b.path("src/test_zig_zon.py"),
|
|
47
|
+
.twine_check = true,
|
|
76
48
|
.no_clean = b.option(bool, "pip-no-clean", "dont cleanup pip temp dirs") orelse false,
|
|
77
49
|
},
|
|
78
50
|
);
|
|
79
51
|
b.step("test-pip-install", "").dependOn(test_pip_install.step);
|
|
52
|
+
|
|
53
|
+
{
|
|
54
|
+
const lib = b.addLibrary(.{
|
|
55
|
+
.name = "zig_zon",
|
|
56
|
+
.root_module = b.addModule("zig_zon", .{
|
|
57
|
+
.root_source_file = b.path("src/zig_zon.zig"),
|
|
58
|
+
.target = target,
|
|
59
|
+
.optimize = optimize,
|
|
60
|
+
}),
|
|
61
|
+
.linkage = .dynamic,
|
|
62
|
+
});
|
|
63
|
+
zig_python_sdist.linkCPython(b, .{
|
|
64
|
+
.lib = lib,
|
|
65
|
+
.version = zon.version,
|
|
66
|
+
.optimize = .ReleaseSmall,
|
|
67
|
+
});
|
|
68
|
+
const ext_install = zig_python_sdist.installExtLib(b, lib);
|
|
69
|
+
|
|
70
|
+
ext_install_step.dependOn(&ext_install.step);
|
|
71
|
+
}
|
|
80
72
|
}
|
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
.{
|
|
2
2
|
.name = .python_zig_zon,
|
|
3
3
|
.fingerprint = 0x3d332656a3644fc9,
|
|
4
|
-
.version = "0.2.
|
|
4
|
+
.version = "0.2.3",
|
|
5
5
|
.minimum_zig_version = "0.16.0",
|
|
6
6
|
.dependencies = .{
|
|
7
7
|
.zig_python_sdist = .{
|
|
8
|
-
.url = "git+https://codeberg.org/dasimmet/zig-python-sdist.git#
|
|
9
|
-
.hash = "zig_python_sdist-0.0.
|
|
8
|
+
.url = "git+https://codeberg.org/dasimmet/zig-python-sdist.git?ref=0.0.2#3dd2c2eaf62a7007d6c257c357ded7911537621a",
|
|
9
|
+
.hash = "zig_python_sdist-0.0.2-wjgdOpyrAADPCiUfh4LoKFNZkHstj4a1bIyEuwnNKkcc",
|
|
10
10
|
},
|
|
11
11
|
},
|
|
12
12
|
.paths = .{
|
|
13
13
|
"src",
|
|
14
14
|
"build.zig",
|
|
15
15
|
"build.zig.zon",
|
|
16
|
+
"pkg-info.zon",
|
|
16
17
|
"LICENSE",
|
|
17
18
|
"README.md",
|
|
18
19
|
"setup.py",
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
.{
|
|
2
|
+
.{ .key = "Summary", .value = "a native cpython extension to parse zig object notation strings" },
|
|
3
|
+
.{ .key = "Author-email", .value = "Tobias Simetsreiter <dasimmet@gmail.com>" },
|
|
4
|
+
.{ .key = "Maintainer-email", .value = "Tobias Simetsreiter <dasimmet@gmail.com>" },
|
|
5
|
+
.{ .key = "License-Expression", .value = "MIT" },
|
|
6
|
+
.{ .key = "Keywords", .value = "zig,ziglang,cpython,native,sdist,zon" },
|
|
7
|
+
.{ .key = "Requires-Python", .value = ">=3.8" },
|
|
8
|
+
.{ .key = "Project-URL", .value = "Homepage, https://codeberg.org/dasimmet/python-zig-zon" },
|
|
9
|
+
.{ .key = "Project-URL", .value = "Issues, https://codeberg.org/dasimmet/python-zig-zon/issues" },
|
|
10
|
+
.{ .key = "Classifier", .value = "Development Status :: 4 - Beta" },
|
|
11
|
+
.{ .key = "Classifier", .value = "Programming Language :: Python :: 3" },
|
|
12
|
+
.{ .key = "Classifier", .value = "Programming Language :: Zig" },
|
|
13
|
+
.{ .key = "Classifier", .value = "Intended Audience :: Developers" },
|
|
14
|
+
.{ .key = "Classifier", .value = "Topic :: Software Development :: Libraries" },
|
|
15
|
+
}
|
|
@@ -39,10 +39,11 @@ class ZigBuildWheel(bdist_wheel):
|
|
|
39
39
|
subprocess.check_call(build_cmd)
|
|
40
40
|
|
|
41
41
|
os.makedirs(self.bdist_dir, exist_ok=True)
|
|
42
|
-
|
|
42
|
+
copy_pattern = "zig-out/{}".format(setup_json['build']['copy_pattern'])
|
|
43
|
+
artifacts = glob.glob(copy_pattern)
|
|
43
44
|
if len(artifacts) == 0:
|
|
44
45
|
raise Exception(
|
|
45
|
-
'no zig artifacts found in {}/
|
|
46
|
+
'no zig artifacts found in {}/{}'.format(cwd, copy_pattern))
|
|
46
47
|
|
|
47
48
|
for it in artifacts:
|
|
48
49
|
shutil.copyfile(it, os.path.join(
|
|
@@ -55,6 +56,7 @@ setup(
|
|
|
55
56
|
name=setup_json['name'],
|
|
56
57
|
version=mkversion(setup_json['version']),
|
|
57
58
|
cmdclass={'bdist_wheel': ZigBuildWheel},
|
|
59
|
+
install_requires=setup_json['install_requires'],
|
|
58
60
|
setup_requires=[
|
|
59
61
|
"setuptools",
|
|
60
62
|
"wheel",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"name":"zig_zon","version":{"major":0,"minor":2,"patch":3,"pre":null,"build":null},"zig_version":{"major":0,"minor":16,"patch":0,"pre":null,"build":null},"build":{"args":["bdist-wheel","-Doptimize=Debug","--fork=zig-pkg/zig_python_sdist"],"requires":[],"copy_pattern":"lib/*"},"install_requires":[]}
|
|
@@ -26,20 +26,23 @@ pub var zigmodule = c.PyModuleDef{
|
|
|
26
26
|
pub export fn PyInit_zig_zon() [*c]c.PyObject {
|
|
27
27
|
const mod = c.PyModule_Create(&zigmodule);
|
|
28
28
|
cpython.addVersion(mod);
|
|
29
|
-
cpython.
|
|
29
|
+
cpython.addZigBuiltin(mod);
|
|
30
30
|
return mod;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
pub fn parse(self: [*]PyObject, args: [*]PyObject) callconv(.c) [*c]PyObject {
|
|
34
34
|
_ = self;
|
|
35
|
-
|
|
36
|
-
|
|
35
|
+
const zon_slice: [:0]u8 = zon_slice: {
|
|
36
|
+
var zon_txt: [*c]u8 = undefined;
|
|
37
|
+
if (!(c.PyArg_ParseTuple(args, "s", &zon_txt) != 0)) return null;
|
|
38
|
+
break :zon_slice std.mem.sliceTo(zon_txt, 0);
|
|
39
|
+
};
|
|
37
40
|
|
|
38
41
|
var arena_instance = std.heap.ArenaAllocator.init(std.heap.c_allocator);
|
|
39
42
|
defer arena_instance.deinit();
|
|
40
43
|
const arena = arena_instance.allocator();
|
|
41
44
|
|
|
42
|
-
const ast = Ast.parse(arena,
|
|
45
|
+
const ast = Ast.parse(arena, zon_slice, .zon) catch |err| {
|
|
43
46
|
const errstr = std.fmt.allocPrintSentinel(
|
|
44
47
|
arena,
|
|
45
48
|
"zig-zon ast error: {s}",
|
|
@@ -50,23 +53,25 @@ pub fn parse(self: [*]PyObject, args: [*]PyObject) callconv(.c) [*c]PyObject {
|
|
|
50
53
|
return null;
|
|
51
54
|
};
|
|
52
55
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
56
|
+
{
|
|
57
|
+
// TODO: use zoir instead of AST maybe?
|
|
58
|
+
// this is unused for now and instead i walk the AST myself, but i keep it in as a sanity check.
|
|
59
|
+
var zoir = ZonGen.generate(arena, ast, .{ .parse_str_lits = false }) catch |err| {
|
|
60
|
+
const errstr = std.fmt.allocPrintSentinel(
|
|
61
|
+
arena,
|
|
62
|
+
"zig-zon zoir error: {s}",
|
|
63
|
+
.{@errorName(err)},
|
|
64
|
+
0,
|
|
65
|
+
) catch "";
|
|
66
|
+
c.PyErr_SetString(c.PyExc_Exception, errstr.ptr);
|
|
67
|
+
return null;
|
|
68
|
+
};
|
|
69
|
+
defer zoir.deinit(arena);
|
|
70
|
+
}
|
|
66
71
|
|
|
67
72
|
const main_node_index = ast.nodeData(.root).node;
|
|
68
73
|
|
|
69
|
-
return
|
|
74
|
+
return parseZonAst(arena, ast, main_node_index) catch |err| {
|
|
70
75
|
const errstr = std.fmt.allocPrintSentinel(
|
|
71
76
|
arena,
|
|
72
77
|
"zig-zon parse error: {s}",
|
|
@@ -86,10 +91,11 @@ const ZonError = error{
|
|
|
86
91
|
StructExpected,
|
|
87
92
|
StructIdentifierExpected,
|
|
88
93
|
NotImplemented,
|
|
89
|
-
|
|
94
|
+
ZonArrayInitFailed,
|
|
95
|
+
InvalidLiteral, // from quoted enum literal parse function
|
|
90
96
|
} || IdentifierError || NumberLiteralError;
|
|
91
97
|
|
|
92
|
-
fn
|
|
98
|
+
fn parseZonAst(arena: Allocator, tree: Ast, node: Ast.Node.Index) ZonError!*c.PyObject {
|
|
93
99
|
const node_tag = tree.nodeTag(node);
|
|
94
100
|
switch (node_tag) {
|
|
95
101
|
.struct_init_comma,
|
|
@@ -114,8 +120,13 @@ fn parseZon(arena: Allocator, tree: Ast, node: Ast.Node.Index) ZonError!*c.PyObj
|
|
|
114
120
|
const name_token = tree.firstToken(node);
|
|
115
121
|
const enum_name = tree.tokenSlice(name_token + 1);
|
|
116
122
|
if (std.mem.startsWith(u8, enum_name, "@")) {
|
|
117
|
-
std.
|
|
118
|
-
|
|
123
|
+
assert(std.mem.startsWith(u8, enum_name, "@\""));
|
|
124
|
+
assert(std.mem.endsWith(u8, enum_name, "\""));
|
|
125
|
+
const enum_parsed_name = try std.zig.string_literal.parseAlloc(
|
|
126
|
+
arena,
|
|
127
|
+
enum_name[1..enum_name.len],
|
|
128
|
+
);
|
|
129
|
+
return c.Py_BuildValue("s#", enum_parsed_name.ptr, enum_parsed_name.len);
|
|
119
130
|
}
|
|
120
131
|
|
|
121
132
|
return c.Py_BuildValue("s#", enum_name.ptr, enum_name.len);
|
|
@@ -208,7 +219,7 @@ fn parseZonStruct(arena: Allocator, tree: Ast, node: Ast.Node.Index) ZonError!*c
|
|
|
208
219
|
for (struct_init.ast.fields) |field_init| {
|
|
209
220
|
const name_token = tree.firstToken(field_init) - 2;
|
|
210
221
|
const field_name = try identifierTokenString(arena, tree, name_token);
|
|
211
|
-
const field_obj = try
|
|
222
|
+
const field_obj = try parseZonAst(arena, tree, field_init);
|
|
212
223
|
const set_result = c.PyDict_SetItemString(ret, field_name, field_obj);
|
|
213
224
|
assert(set_result >= 0);
|
|
214
225
|
}
|
|
@@ -221,13 +232,13 @@ fn parseZonArray(arena: Allocator, tree: Ast, node: Ast.Node.Index) !*c.PyObject
|
|
|
221
232
|
const array_init = tree.fullArrayInit(&buf, node) orelse {
|
|
222
233
|
const tok = tree.nodeMainToken(node);
|
|
223
234
|
std.log.err("expected paths expression to be a list of strings, got: {d}", .{tok});
|
|
224
|
-
return error.
|
|
235
|
+
return error.ZonArrayInitFailed;
|
|
225
236
|
};
|
|
226
237
|
|
|
227
238
|
const ret = c.PyList_New(0);
|
|
228
239
|
|
|
229
240
|
for (array_init.ast.elements) |elem_node| {
|
|
230
|
-
const field_ret = try
|
|
241
|
+
const field_ret = try parseZonAst(arena, tree, elem_node);
|
|
231
242
|
assert(c.PyList_Append(ret, field_ret) >= 0);
|
|
232
243
|
}
|
|
233
244
|
return ret;
|
|
@@ -236,10 +247,10 @@ fn parseZonArray(arena: Allocator, tree: Ast, node: Ast.Node.Index) !*c.PyObject
|
|
|
236
247
|
const IdentifierError = error{OutOfMemory} || StringLiteralError;
|
|
237
248
|
|
|
238
249
|
fn identifierTokenString(arena: Allocator, ast: Ast, token: Ast.TokenIndex) IdentifierError![:0]const u8 {
|
|
239
|
-
|
|
250
|
+
assert(ast.tokenTag(token) == .identifier);
|
|
240
251
|
const ident_name = ast.tokenSlice(token);
|
|
241
252
|
if (!std.mem.startsWith(u8, ident_name, "@")) {
|
|
242
|
-
return try arena.
|
|
253
|
+
return try arena.dupeSentinel(u8, ident_name, 0);
|
|
243
254
|
}
|
|
244
255
|
|
|
245
256
|
var buf = std.ArrayListUnmanaged(u8).empty;
|
|
@@ -24,8 +24,6 @@ pub fn build(b: *Build) void {
|
|
|
24
24
|
|
|
25
25
|
b.installArtifact(exe);
|
|
26
26
|
|
|
27
|
-
const cpython = CPython.find(b);
|
|
28
|
-
|
|
29
27
|
const sdist_dummy = b.addLibrary(.{
|
|
30
28
|
.name = "sdist_dummy",
|
|
31
29
|
.root_module = b.createModule(.{
|
|
@@ -35,13 +33,14 @@ pub fn build(b: *Build) void {
|
|
|
35
33
|
}),
|
|
36
34
|
.linkage = .dynamic,
|
|
37
35
|
});
|
|
38
|
-
|
|
36
|
+
|
|
37
|
+
linkCPython(b, .{
|
|
39
38
|
.lib = sdist_dummy,
|
|
40
39
|
.version = zon.version,
|
|
41
40
|
});
|
|
42
|
-
const install_ext =
|
|
41
|
+
const install_ext = installExtLib(b, sdist_dummy);
|
|
43
42
|
|
|
44
|
-
const build_ext_step = b.step("
|
|
43
|
+
const build_ext_step = b.step("bdist-wheel", "build the sdist dummy python module");
|
|
45
44
|
build_ext_step.dependOn(&install_ext.step);
|
|
46
45
|
|
|
47
46
|
const sdist = SDistStep.createInternal(b, .{
|
|
@@ -50,54 +49,46 @@ pub fn build(b: *Build) void {
|
|
|
50
49
|
.version = zon.version,
|
|
51
50
|
.description = b.path("README.md"),
|
|
52
51
|
.build = .{
|
|
53
|
-
.args = &.{build_ext_step.name},
|
|
54
|
-
},
|
|
55
|
-
.extra_pkg_info = &.{
|
|
56
|
-
.{ .key = "Summary", .value = "Just a Test" },
|
|
57
|
-
.{ .key = "Author-email", .value = "Tobias Simetsreiter <dasimmet@gmail.com>" },
|
|
58
|
-
.{ .key = "Maintainer-email", .value = "Tobias Simetsreiter <dasimmet@gmail.com>" },
|
|
59
|
-
.{ .key = "License-Expression", .value = "MIT" },
|
|
60
|
-
.{ .key = "Keywords", .value = "zig,ziglang,cpython,native,sdist" },
|
|
61
|
-
.{ .key = "Requires-Python", .value = ">=3.8" },
|
|
62
|
-
.{ .key = "Project-URL", .value = "Homepage, https://codeberg.org/dasimmet/zig-python-sdist" },
|
|
63
|
-
.{ .key = "Project-URL", .value = "Issues, https://codeberg.org/dasimmet/zig-python-sdist/issues" },
|
|
64
|
-
.{ .key = "Classifier", .value = "Development Status :: 4 - Beta" },
|
|
52
|
+
.args = &.{ build_ext_step.name, b.fmt("-Doptimize={s}", .{@tagName(optimize)}) },
|
|
65
53
|
},
|
|
54
|
+
.extra_pkg_info = @import("pkg-info.zon"),
|
|
66
55
|
.files = &.{
|
|
67
56
|
.{ .src = b.path("build.zig.zon"), .dest = "build.zig.zon" },
|
|
68
57
|
.{ .src = b.path("build.zig"), .dest = "build.zig" },
|
|
58
|
+
.{ .src = b.path("pkg-info.zon"), .dest = "pkg-info.zon" },
|
|
69
59
|
.{ .src = b.path("example/sdist_dummy.zig"), .dest = "example/sdist_dummy.zig" },
|
|
70
60
|
},
|
|
71
61
|
.directories = &.{
|
|
72
62
|
.{ .src = b.path("src"), .dest = "src" },
|
|
73
63
|
.{ .src = b.path("src/build"), .dest = "src/build" },
|
|
74
64
|
},
|
|
65
|
+
.install_requires = &.{"ruamel.yaml.clibz"},
|
|
75
66
|
.zig_version = std.SemanticVersion.parse("0.16.0") catch unreachable,
|
|
76
67
|
});
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
.{ .custom = "src" },
|
|
81
|
-
sdist.basename,
|
|
82
|
-
);
|
|
83
|
-
b.getInstallStep().dependOn(&sdistfile.step);
|
|
68
|
+
const sdist_install = sdist.install();
|
|
69
|
+
b.getInstallStep().dependOn(&sdist_install.step);
|
|
70
|
+
b.step("sdist", "only build and install sdist").dependOn(&sdist_install.step);
|
|
84
71
|
|
|
85
72
|
const test_pip_install = VenvInstallTest.create(
|
|
86
73
|
b,
|
|
87
74
|
.{
|
|
88
75
|
.sdist = sdist.getEmittedArchive(),
|
|
89
76
|
.test_py = b.path("example/test_ext.py"),
|
|
77
|
+
.twine_check = true,
|
|
90
78
|
.no_clean = b.option(bool, "pip-no-clean", "cleanup pip temp dirs") orelse false,
|
|
91
79
|
},
|
|
92
80
|
);
|
|
93
81
|
b.step("test-pip-install", "").dependOn(test_pip_install.step);
|
|
94
82
|
}
|
|
95
83
|
|
|
84
|
+
pub const linkCPython = CPython.link;
|
|
85
|
+
pub const installExtLib = CPython.installExtLib;
|
|
86
|
+
|
|
96
87
|
pub fn create(b: *Build, options: SDistStep.Options) *SDistStep {
|
|
97
88
|
var opt = options;
|
|
98
89
|
const sdist = b.dependencyFromBuildZig(@This(), .{
|
|
99
90
|
.target = b.graph.host,
|
|
100
|
-
.optimize = .
|
|
91
|
+
.optimize = .ReleaseFast,
|
|
101
92
|
});
|
|
102
93
|
opt.sdist_builder = opt.sdist_builder orelse sdist.artifact("sdist-builder");
|
|
103
94
|
|
|
@@ -106,6 +97,7 @@ pub fn create(b: *Build, options: SDistStep.Options) *SDistStep {
|
|
|
106
97
|
const extra_files: []const SDistStep.Content = &.{
|
|
107
98
|
.{ .src = sdist.path("build.zig.zon"), .dest = "zig-pkg/zig_python_sdist/build.zig.zon" },
|
|
108
99
|
.{ .src = sdist.path("build.zig"), .dest = "zig-pkg/zig_python_sdist/build.zig" },
|
|
100
|
+
.{ .src = sdist.path("pkg-info.zon"), .dest = "zig-pkg/zig_python_sdist/pkg-info.zon" },
|
|
109
101
|
.{ .src = sdist.path("README.md"), .dest = "zig-pkg/zig_python_sdist/README.md" },
|
|
110
102
|
.{ .src = sdist.path("LICENSE"), .dest = "zig-pkg/zig_python_sdist/LICENSE" },
|
|
111
103
|
};
|
|
@@ -121,7 +113,6 @@ pub fn create(b: *Build, options: SDistStep.Options) *SDistStep {
|
|
|
121
113
|
{
|
|
122
114
|
var dirs: std.ArrayList(SDistStep.Content) = .empty;
|
|
123
115
|
const extra_dirs: []const SDistStep.Content = &.{
|
|
124
|
-
// .{ .src = sdist.path("src"), .dest = "zig-pkg/zig_python_sdist/src" },
|
|
125
116
|
.{ .src = sdist.path("src/build"), .dest = "zig-pkg/zig_python_sdist/src/build" },
|
|
126
117
|
};
|
|
127
118
|
dirs.ensureTotalCapacity(
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
.{
|
|
2
|
+
.{ .key = "Summary", .value = "Just a Test" },
|
|
3
|
+
.{ .key = "Author-email", .value = "Tobias Simetsreiter <dasimmet@gmail.com>" },
|
|
4
|
+
.{ .key = "Maintainer-email", .value = "Tobias Simetsreiter <dasimmet@gmail.com>" },
|
|
5
|
+
.{ .key = "License-Expression", .value = "MIT" },
|
|
6
|
+
.{ .key = "Keywords", .value = "zig,ziglang,cpython,native,sdist" },
|
|
7
|
+
.{ .key = "Requires-Python", .value = ">=3.8" },
|
|
8
|
+
.{ .key = "Project-URL", .value = "Homepage, https://codeberg.org/dasimmet/zig-python-sdist" },
|
|
9
|
+
.{ .key = "Project-URL", .value = "Issues, https://codeberg.org/dasimmet/zig-python-sdist/issues" },
|
|
10
|
+
.{ .key = "Classifier", .value = "Development Status :: 4 - Beta" },
|
|
11
|
+
}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
const builtin = @import("builtin");
|
|
3
|
+
const Build = std.Build;
|
|
4
|
+
const LazyPath = Build.LazyPath;
|
|
5
|
+
const mem = std.mem;
|
|
6
|
+
|
|
7
|
+
/// a module for building cpython extension libraries,
|
|
8
|
+
/// linking them with system python headers and libs
|
|
9
|
+
pub const CPython = @This();
|
|
10
|
+
|
|
11
|
+
exe: LazyPath,
|
|
12
|
+
|
|
13
|
+
pub fn find(b: *Build) *CPython {
|
|
14
|
+
const self = b.allocator.create(CPython) catch @panic("OOM");
|
|
15
|
+
self.* = .{
|
|
16
|
+
.exe = findProgramCompat(b, &.{
|
|
17
|
+
"python",
|
|
18
|
+
"python3",
|
|
19
|
+
}) orelse {
|
|
20
|
+
const err_wf = b.addWriteFiles();
|
|
21
|
+
const err_step = b.addFail("finding python failed. please provide a path to the exe using -Dpython=");
|
|
22
|
+
err_wf.step.dependOn(&err_step.step);
|
|
23
|
+
self.* = .{ .exe = err_wf.getDirectory() };
|
|
24
|
+
return self;
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
return self;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
pub const LinkOptions = struct {
|
|
31
|
+
/// library to link against libpython
|
|
32
|
+
lib: *std.Build.Step.Compile,
|
|
33
|
+
version: ?[]const u8 = null,
|
|
34
|
+
python_exe: ?LazyPath = null,
|
|
35
|
+
/// optimize mode for the c module. will fall back to lib's optimize mode.
|
|
36
|
+
optimize: ?std.builtin.OptimizeMode = null,
|
|
37
|
+
macros: []const [2][]const u8 = &default_macros,
|
|
38
|
+
pub const default_macros = .{
|
|
39
|
+
.{ "Py_LIMITED_API", "0x03060500" }, // use the limited api from 3.6.5
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
pub fn link(b: *Build, options: LinkOptions) void {
|
|
44
|
+
const self: *const CPython = if (options.python_exe) |python_exe|
|
|
45
|
+
&.{ .exe = python_exe }
|
|
46
|
+
else
|
|
47
|
+
CPython.find(b);
|
|
48
|
+
|
|
49
|
+
const target = Build.ResolvedTarget{
|
|
50
|
+
.query = .{},
|
|
51
|
+
.result = options.lib.rootModuleTarget(),
|
|
52
|
+
};
|
|
53
|
+
|
|
54
|
+
const python_inc = self.generateIncludeDir(b);
|
|
55
|
+
|
|
56
|
+
const cpython = b.addTranslateC(.{
|
|
57
|
+
.root_source_file = python_inc.path(b, "zig_python_include.h"),
|
|
58
|
+
.optimize = options.optimize orelse options.lib.root_module.optimize orelse .ReleaseSafe,
|
|
59
|
+
.target = target,
|
|
60
|
+
});
|
|
61
|
+
cpython.addIncludePath(python_inc);
|
|
62
|
+
|
|
63
|
+
const wf = b.addWriteFiles();
|
|
64
|
+
|
|
65
|
+
const pymod = b.createModule(.{
|
|
66
|
+
.root_source_file = wf.add("python.zig", @embedFile("python.zig")),
|
|
67
|
+
.imports = &.{
|
|
68
|
+
.{ .name = "c", .module = cpython.createModule() },
|
|
69
|
+
},
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
if (options.version) |version| {
|
|
73
|
+
pymod.addImport("version", b.createModule(.{
|
|
74
|
+
.root_source_file = wf.add("version.txt", version),
|
|
75
|
+
}));
|
|
76
|
+
} else {
|
|
77
|
+
pymod.addImport("version", b.createModule(.{
|
|
78
|
+
.root_source_file = wf.add("version.txt", "version not provided at configure time!"),
|
|
79
|
+
}));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
for (options.macros) |macro| {
|
|
83
|
+
cpython.defineCMacro(macro[0], macro[1]);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
if (target.result.os.tag == .windows) {
|
|
87
|
+
options.lib.root_module.addLibraryPath(python_inc);
|
|
88
|
+
options.lib.root_module.linkSystemLibrary("python", .{});
|
|
89
|
+
}
|
|
90
|
+
options.lib.root_module.addImport(
|
|
91
|
+
"cpython",
|
|
92
|
+
pymod,
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
pub fn generateIncludeDir(self: CPython, b: *Build) LazyPath {
|
|
97
|
+
const extract_link_info = Build.Step.Run.create(b, "python header extraction run");
|
|
98
|
+
extract_link_info.addFileArg(self.exe);
|
|
99
|
+
const wf = b.addWriteFiles();
|
|
100
|
+
extract_link_info.addFileArg(wf.add("extract_link_info.py", @embedFile("extract_link_info.py")));
|
|
101
|
+
return extract_link_info.addOutputDirectoryArg("pyinclude");
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
pub fn installExtLib(b: *Build, lib: *Build.Step.Compile) *Build.Step.InstallFile {
|
|
105
|
+
const ext_lib_name = lib_ext_name(b, lib);
|
|
106
|
+
return b.addInstallLibFile(lib.getEmittedBin(), ext_lib_name);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
pub fn lib_ext_name(b: *Build, lib: *Build.Step.Compile) []const u8 {
|
|
110
|
+
const target = lib.rootModuleTarget();
|
|
111
|
+
return if (target.os.tag == .windows)
|
|
112
|
+
b.fmt("{s}.pyd", .{lib.name})
|
|
113
|
+
else
|
|
114
|
+
b.fmt("{s}.so", .{lib.name});
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// compat for 0.16.0 and 0.17.0
|
|
118
|
+
pub fn findProgramCompat(b: *std.Build, names: []const []const u8) ?LazyPath {
|
|
119
|
+
if (comptime (@import("builtin").zig_version.order(std.SemanticVersion.parse("0.16.0") catch unreachable) == .gt)) {
|
|
120
|
+
return b.findProgramLazy(.{ .names = names });
|
|
121
|
+
}
|
|
122
|
+
return .{
|
|
123
|
+
.cwd_relative = b.findProgram(names, &.{}) catch return null,
|
|
124
|
+
};
|
|
125
|
+
}
|