zig-zon 0.2.2__tar.gz → 0.2.4__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.2 → zig-zon-0.2.4}/PKG-INFO +10 -5
- {zig-zon-0.2.2 → zig-zon-0.2.4}/build.zig +17 -14
- {zig-zon-0.2.2 → zig-zon-0.2.4}/build.zig.zon +3 -3
- {zig-zon-0.2.2 → zig-zon-0.2.4}/pkg-info.zon +4 -0
- {zig-zon-0.2.2 → zig-zon-0.2.4}/setup.py +5 -2
- zig-zon-0.2.4/setup.zig.json +1 -0
- {zig-zon-0.2.2 → zig-zon-0.2.4}/src/zig_zon.zig +26 -21
- zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3/README.md +114 -0
- {zig-zon-0.2.2/zig-pkg/zig_python_sdist → zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3}/build.zig +51 -32
- {zig-zon-0.2.2/zig-pkg/zig_python_sdist → zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3}/build.zig.zon +2 -2
- zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3/src/build/CPython.zig +112 -0
- zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3/src/build/LowerDashString.zig +20 -0
- zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3/src/build/SDistStep.zig +147 -0
- zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3/src/build/VenvInstallTest.zig +138 -0
- {zig-zon-0.2.2/zig-pkg/zig_python_sdist → zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3}/src/build/pkg_info.zig +0 -19
- zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3/src/build/python.zig +416 -0
- zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3/src/build/setup_json.zig +20 -0
- zig-zon-0.2.2/setup.zig.json +0 -1
- zig-zon-0.2.2/zig-pkg/zig_python_sdist/README.md +0 -7
- zig-zon-0.2.2/zig-pkg/zig_python_sdist/src/build/CPython.zig +0 -133
- zig-zon-0.2.2/zig-pkg/zig_python_sdist/src/build/LowerDashStringFormatter.zig +0 -12
- zig-zon-0.2.2/zig-pkg/zig_python_sdist/src/build/SDistStep.zig +0 -93
- zig-zon-0.2.2/zig-pkg/zig_python_sdist/src/build/VenvInstallTest.zig +0 -101
- zig-zon-0.2.2/zig-pkg/zig_python_sdist/src/build/python.zig +0 -50
- {zig-zon-0.2.2/zig-pkg/zig_python_sdist → zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3}/LICENSE +0 -0
- {zig-zon-0.2.2/zig-pkg/zig_python_sdist → zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3}/pkg-info.zon +0 -0
- {zig-zon-0.2.2/zig-pkg/zig_python_sdist → zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3}/src/build/extract_link_info.py +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.4
|
|
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
|
|
@@ -34,9 +38,10 @@ pip install zig-zon
|
|
|
34
38
|
running:
|
|
35
39
|
|
|
36
40
|
```python
|
|
37
|
-
import zig_zon
|
|
38
|
-
parsed = zig_zon.parse('.{.allyourcode = .are_belong_to_us, .asd = 123}')
|
|
39
|
-
print(parsed)
|
|
41
|
+
>>> import zig_zon
|
|
42
|
+
>>> parsed = zig_zon.parse('.{.allyourcode = .are_belong_to_us, .asd = 123}')
|
|
43
|
+
>>> print(parsed)
|
|
44
|
+
{'allyourcode': 'are_belong_to_us', 'asd': 123}
|
|
40
45
|
```
|
|
41
46
|
|
|
42
47
|
or, look at the [test file](https://codeberg.org/dasimmet/python-zig-zon/src/branch/main/src/test_zig_zon.py)
|
|
@@ -2,22 +2,24 @@ 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("
|
|
11
|
+
const ext_install_step = b.step("bdist-wheel", "build python extension module");
|
|
13
12
|
|
|
14
13
|
// this generates a python sdist archive
|
|
15
|
-
const sdist = zig_python_sdist.
|
|
14
|
+
const sdist = zig_python_sdist.createSdistStep(b, .{
|
|
16
15
|
.name = "zig-zon",
|
|
17
16
|
.version = zon.version,
|
|
18
17
|
.description = b.path("README.md"),
|
|
19
18
|
.build = .{
|
|
20
|
-
.args = &.{
|
|
19
|
+
.args = &.{
|
|
20
|
+
ext_install_step.name,
|
|
21
|
+
b.fmt("-Doptimize={s}", .{@tagName(optimize)}),
|
|
22
|
+
},
|
|
21
23
|
},
|
|
22
24
|
.extra_pkg_info = @import("pkg-info.zon"),
|
|
23
25
|
.files = &.{
|
|
@@ -37,11 +39,11 @@ pub fn build(b: *Build) void {
|
|
|
37
39
|
|
|
38
40
|
// we can use a python virtual environment inside
|
|
39
41
|
// the zig cache to test pip installation
|
|
40
|
-
const test_pip_install = zig_python_sdist.
|
|
42
|
+
const test_pip_install = zig_python_sdist.createVenvInstallTest(
|
|
41
43
|
b,
|
|
42
44
|
.{
|
|
43
45
|
.sdist = sdist.getEmittedArchive(),
|
|
44
|
-
.
|
|
46
|
+
.unittest_py = &.{b.path("src/test_zig_zon.py")},
|
|
45
47
|
.twine_check = true,
|
|
46
48
|
.no_clean = b.option(bool, "pip-no-clean", "dont cleanup pip temp dirs") orelse false,
|
|
47
49
|
},
|
|
@@ -49,23 +51,24 @@ pub fn build(b: *Build) void {
|
|
|
49
51
|
b.step("test-pip-install", "").dependOn(test_pip_install.step);
|
|
50
52
|
|
|
51
53
|
{
|
|
52
|
-
const cpython = zig_python_sdist.
|
|
53
|
-
|
|
54
|
+
const cpython = zig_python_sdist.createCPythonModule(b, .{
|
|
55
|
+
.target = target,
|
|
56
|
+
.version = zon.version,
|
|
57
|
+
.optimize = .ReleaseSmall,
|
|
58
|
+
});
|
|
54
59
|
const lib = b.addLibrary(.{
|
|
55
60
|
.name = "zig_zon",
|
|
56
61
|
.root_module = b.addModule("zig_zon", .{
|
|
57
62
|
.root_source_file = b.path("src/zig_zon.zig"),
|
|
58
63
|
.target = target,
|
|
59
64
|
.optimize = optimize,
|
|
65
|
+
.imports = &.{
|
|
66
|
+
.{ .name = "cpython", .module = cpython },
|
|
67
|
+
},
|
|
60
68
|
}),
|
|
61
69
|
.linkage = .dynamic,
|
|
62
70
|
});
|
|
63
|
-
|
|
64
|
-
.lib = lib,
|
|
65
|
-
.version = zon.version,
|
|
66
|
-
.optimize = .ReleaseSmall,
|
|
67
|
-
});
|
|
68
|
-
const ext_install = zig_python_sdist.CPython.installExtLib(b, lib);
|
|
71
|
+
const ext_install = zig_python_sdist.installExtLib(b, lib);
|
|
69
72
|
|
|
70
73
|
ext_install_step.dependOn(&ext_install.step);
|
|
71
74
|
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
.{
|
|
2
2
|
.name = .python_zig_zon,
|
|
3
3
|
.fingerprint = 0x3d332656a3644fc9,
|
|
4
|
-
.version = "0.2.
|
|
4
|
+
.version = "0.2.4",
|
|
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#b09744edafe683ae6000a96498cc68e86173dbe7",
|
|
9
|
+
.hash = "zig_python_sdist-0.0.3-wjgdOlzvAADTtFV1n4xTLUwlgCsiLDcmhebfZ7kWM05z",
|
|
10
10
|
},
|
|
11
11
|
},
|
|
12
12
|
.paths = .{
|
|
@@ -8,4 +8,8 @@
|
|
|
8
8
|
.{ .key = "Project-URL", .value = "Homepage, https://codeberg.org/dasimmet/python-zig-zon" },
|
|
9
9
|
.{ .key = "Project-URL", .value = "Issues, https://codeberg.org/dasimmet/python-zig-zon/issues" },
|
|
10
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" },
|
|
11
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 = 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,8 @@ 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'],
|
|
60
|
+
entry_points=setup_json['entry_points'],
|
|
58
61
|
setup_requires=[
|
|
59
62
|
"setuptools",
|
|
60
63
|
"wheel",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"name":"zig_zon","version":{"major":0,"minor":2,"patch":4,"pre":null,"build":null},"zig_version":{"major":0,"minor":16,"patch":0,"pre":null,"build":null},"build":{"args":["--fork=zig-pkg/zig_python_sdist-0.0.3","bdist-wheel","-Doptimize=ReleaseSmall"],"requires":[],"copy_pattern":"zig-out/lib/*"},"install_requires":[],"entry_points":{"console_scripts":[],"gui_scripts":[]}}
|
|
@@ -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,19 +53,21 @@ 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
|
|
|
@@ -115,8 +120,8 @@ fn parseZonAst(arena: Allocator, tree: Ast, node: Ast.Node.Index) ZonError!*c.Py
|
|
|
115
120
|
const name_token = tree.firstToken(node);
|
|
116
121
|
const enum_name = tree.tokenSlice(name_token + 1);
|
|
117
122
|
if (std.mem.startsWith(u8, enum_name, "@")) {
|
|
118
|
-
|
|
119
|
-
|
|
123
|
+
assert(std.mem.startsWith(u8, enum_name, "@\""));
|
|
124
|
+
assert(std.mem.endsWith(u8, enum_name, "\""));
|
|
120
125
|
const enum_parsed_name = try std.zig.string_literal.parseAlloc(
|
|
121
126
|
arena,
|
|
122
127
|
enum_name[1..enum_name.len],
|
|
@@ -242,10 +247,10 @@ fn parseZonArray(arena: Allocator, tree: Ast, node: Ast.Node.Index) !*c.PyObject
|
|
|
242
247
|
const IdentifierError = error{OutOfMemory} || StringLiteralError;
|
|
243
248
|
|
|
244
249
|
fn identifierTokenString(arena: Allocator, ast: Ast, token: Ast.TokenIndex) IdentifierError![:0]const u8 {
|
|
245
|
-
|
|
250
|
+
assert(ast.tokenTag(token) == .identifier);
|
|
246
251
|
const ident_name = ast.tokenSlice(token);
|
|
247
252
|
if (!std.mem.startsWith(u8, ident_name, "@")) {
|
|
248
|
-
return try arena.
|
|
253
|
+
return try arena.dupeSentinel(u8, ident_name, 0);
|
|
249
254
|
}
|
|
250
255
|
|
|
251
256
|
var buf = std.ArrayListUnmanaged(u8).empty;
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# Zig Python Sdist
|
|
2
|
+
|
|
3
|
+
this is a toolset to build python source distributions for pypi directly
|
|
4
|
+
using `zig build`. It's inspired by Loris Cro's talk
|
|
5
|
+
[Deinventing the Wheel](https://www.youtube.com/watch?v=HPmefnqirHk).
|
|
6
|
+
|
|
7
|
+
It allows to add a python distribution to zig packages
|
|
8
|
+
without dealing with python package metadata the traditional way.
|
|
9
|
+
|
|
10
|
+
You find a full usage example in the [example/](example/) directory.
|
|
11
|
+
|
|
12
|
+
## `build.zig` api
|
|
13
|
+
|
|
14
|
+
to generate a python `sdist` archive,
|
|
15
|
+
add the zig package to the `build.zig.zon` file of your existing
|
|
16
|
+
zig >= 0.16.0 project by running:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
zig fetch --save git+https://codeberg.org/dasimmet/zig-python-sdist
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
then, import the dependency and create a source distribution.
|
|
23
|
+
You will have to specify all files or directories (subdirectories are not added
|
|
24
|
+
recursively) necessary to build the extension to add to the sdist archive.
|
|
25
|
+
the `zig-python-sdist` dependency is added automatically for you as well as a `--fork`
|
|
26
|
+
command line argument to `zig build` at wheel build time.
|
|
27
|
+
|
|
28
|
+
```zig
|
|
29
|
+
const zig_python_sdist = @import("zig_python_sdist");
|
|
30
|
+
|
|
31
|
+
pub fn build(b: *std.Build) void {
|
|
32
|
+
const build_ext_step = b.step("bdist-wheel", "build the extension module");
|
|
33
|
+
{
|
|
34
|
+
// generate a module from cpython headers
|
|
35
|
+
const cpython = zig_python_sdist.createCPythonModule(b, .{
|
|
36
|
+
.target = target,
|
|
37
|
+
.version = zon.version,
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// create a shared library, linked against cpython
|
|
41
|
+
const sdist_dummy = b.addLibrary(.{
|
|
42
|
+
.name = "sdist_dummy",
|
|
43
|
+
.linkage = .dynamic,
|
|
44
|
+
.root_module = b.createModule(.{
|
|
45
|
+
.root_source_file = b.path("sdist_dummy.zig"),
|
|
46
|
+
.target = target,
|
|
47
|
+
.optimize = optimize,
|
|
48
|
+
.imports = &.{
|
|
49
|
+
.{ .name = "cpython", .module = cpython },
|
|
50
|
+
},
|
|
51
|
+
}),
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// install the extension on the "bdist-wheel" top level step
|
|
55
|
+
const sdist_dummy_install = zig_python_sdist.installExtLib(b, sdist_dummy);
|
|
56
|
+
build_ext_step.dependOn(&sdist_dummy_install.step);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const sdist = zig_python_sdist.createSdistStep(b, .{
|
|
60
|
+
.name = "python-package-name",
|
|
61
|
+
.version = @import("build.zig.zon).version,
|
|
62
|
+
.description = b.path("README.md"),
|
|
63
|
+
|
|
64
|
+
.build = .{
|
|
65
|
+
// the source distribution will build the "bdist-wheel" step on wheel build
|
|
66
|
+
.args = &.{
|
|
67
|
+
b.fmt("-Doptimize={s}", .{@tagName(optimize)}),
|
|
68
|
+
build_ext_step.name,
|
|
69
|
+
},
|
|
70
|
+
},
|
|
71
|
+
|
|
72
|
+
// add all files and directories necessary to build to the source distribution
|
|
73
|
+
.files = &.{
|
|
74
|
+
.{ .src = b.path("build.zig.zon"), .dest = "build.zig.zon" },
|
|
75
|
+
.{ .src = b.path("build.zig"), .dest = "build.zig" },
|
|
76
|
+
.{ .src = b.path("README.md"), .dest = "README.md" },
|
|
77
|
+
.{ .src = b.path("LICENSE"), .dest = "LICENSE" },
|
|
78
|
+
},
|
|
79
|
+
.directories = &.{
|
|
80
|
+
.{ .src = b.path("src"), .dest = "src" },
|
|
81
|
+
},
|
|
82
|
+
|
|
83
|
+
// tip: when adding dependency directories, pass a `--fork=<path inside sdist>` to
|
|
84
|
+
// the build arguments.
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// the install step only builds the source distribution
|
|
88
|
+
const sdist_install = sdist.install();
|
|
89
|
+
b.getInstallStep().dependOn(&sdist_install.step);
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
## `cpython` zig module
|
|
94
|
+
|
|
95
|
+
the generated `cpython` module provides a `c` member holding the translated cpython
|
|
96
|
+
headers as well as some utility functions to:
|
|
97
|
+
|
|
98
|
+
- `addVersion` adds `__version__` and `__version_str__` symbols to your module.
|
|
99
|
+
- `addZigBuiltin` adds a `__zig_builtin__` symbol to your module populated by zig's
|
|
100
|
+
build information.
|
|
101
|
+
- `wrapMain` wraps a Zig "JuicyMain" function (`fn (std.process.Init) !void`) to be used as an entrypoint for your
|
|
102
|
+
python module, by populating the `std.process.init` from python's builtin `os` and `sys` modules.
|
|
103
|
+
|
|
104
|
+
take a look at [example/sdist_dummy.zig](example/sdist_dummy.zig)
|
|
105
|
+
|
|
106
|
+
## Testing the distribution installation
|
|
107
|
+
|
|
108
|
+
to test the built source distribution, you can create a `VenvInstallTest` step
|
|
109
|
+
that will:
|
|
110
|
+
|
|
111
|
+
- create a python virtual environment
|
|
112
|
+
- compile and install your package
|
|
113
|
+
- run python unittest files against the installed package
|
|
114
|
+
- run entrypoints from the installed package to test them
|
{zig-zon-0.2.2/zig-pkg/zig_python_sdist → zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3}/build.zig
RENAMED
|
@@ -3,9 +3,15 @@ const Build = std.Build;
|
|
|
3
3
|
const LazyPath = Build.LazyPath;
|
|
4
4
|
const zon = @import("build.zig.zon");
|
|
5
5
|
|
|
6
|
+
// access to the types of the public interface
|
|
6
7
|
pub const CPython = @import("src/build/CPython.zig");
|
|
7
|
-
pub const VenvInstallTest = @import("src/build/VenvInstallTest.zig");
|
|
8
8
|
pub const SDistStep = @import("src/build/SDistStep.zig");
|
|
9
|
+
pub const VenvInstallTest = @import("src/build/VenvInstallTest.zig");
|
|
10
|
+
// public zig build interface
|
|
11
|
+
pub const createSdistStep = createSdist;
|
|
12
|
+
pub const createVenvInstallTest = VenvInstallTest.create;
|
|
13
|
+
pub const createCPythonModule = createModule;
|
|
14
|
+
pub const installExtLib = CPython.installExtLib;
|
|
9
15
|
|
|
10
16
|
pub fn build(b: *Build) void {
|
|
11
17
|
const target = b.standardTargetOptions(.{});
|
|
@@ -24,7 +30,11 @@ pub fn build(b: *Build) void {
|
|
|
24
30
|
|
|
25
31
|
b.installArtifact(exe);
|
|
26
32
|
|
|
27
|
-
const cpython = CPython.
|
|
33
|
+
const cpython = CPython.createModuleInternal(b, b, .{
|
|
34
|
+
.target = target,
|
|
35
|
+
.version = zon.version,
|
|
36
|
+
.optimize = .Debug,
|
|
37
|
+
});
|
|
28
38
|
|
|
29
39
|
const sdist_dummy = b.addLibrary(.{
|
|
30
40
|
.name = "sdist_dummy",
|
|
@@ -32,25 +42,24 @@ pub fn build(b: *Build) void {
|
|
|
32
42
|
.root_source_file = b.path("example/sdist_dummy.zig"),
|
|
33
43
|
.target = target,
|
|
34
44
|
.optimize = optimize,
|
|
45
|
+
.imports = &.{
|
|
46
|
+
.{ .name = "cpython", .module = cpython },
|
|
47
|
+
},
|
|
35
48
|
}),
|
|
36
49
|
.linkage = .dynamic,
|
|
37
50
|
});
|
|
38
|
-
cpython.link(b, .{
|
|
39
|
-
.lib = sdist_dummy,
|
|
40
|
-
.version = zon.version,
|
|
41
|
-
});
|
|
42
|
-
const install_ext = CPython.installExtLib(b, sdist_dummy);
|
|
43
51
|
|
|
44
|
-
const
|
|
52
|
+
const install_ext = installExtLib(b, sdist_dummy);
|
|
53
|
+
|
|
54
|
+
const build_ext_step = b.step("bdist-wheel", "build the sdist dummy python module");
|
|
45
55
|
build_ext_step.dependOn(&install_ext.step);
|
|
46
56
|
|
|
47
|
-
const sdist = SDistStep.createInternal(b, .{
|
|
48
|
-
.
|
|
49
|
-
.name = "zig-python-sdist-dummy",
|
|
57
|
+
const sdist = SDistStep.createInternal(b, exe, .{
|
|
58
|
+
.name = "sdist-dummy",
|
|
50
59
|
.version = zon.version,
|
|
51
60
|
.description = b.path("README.md"),
|
|
52
61
|
.build = .{
|
|
53
|
-
.args = &.{build_ext_step.name},
|
|
62
|
+
.args = &.{ b.fmt("-Doptimize={s}", .{@tagName(optimize)}), build_ext_step.name },
|
|
54
63
|
},
|
|
55
64
|
.extra_pkg_info = @import("pkg-info.zon"),
|
|
56
65
|
.files = &.{
|
|
@@ -60,47 +69,57 @@ pub fn build(b: *Build) void {
|
|
|
60
69
|
.{ .src = b.path("example/sdist_dummy.zig"), .dest = "example/sdist_dummy.zig" },
|
|
61
70
|
},
|
|
62
71
|
.directories = &.{
|
|
63
|
-
.{ .src = b.path("src"), .dest = "src" },
|
|
64
72
|
.{ .src = b.path("src/build"), .dest = "src/build" },
|
|
65
73
|
},
|
|
74
|
+
.entry_points = .{
|
|
75
|
+
.console_scripts = &.{
|
|
76
|
+
"sdist-dummy = sdist_dummy:__main__",
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
.install_requires = &.{"ruamel.yaml.clibz"},
|
|
66
80
|
.zig_version = std.SemanticVersion.parse("0.16.0") catch unreachable,
|
|
67
81
|
});
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
.{ .custom = "src" },
|
|
72
|
-
sdist.basename,
|
|
73
|
-
);
|
|
74
|
-
b.getInstallStep().dependOn(&sdistfile.step);
|
|
82
|
+
const sdist_install = sdist.install();
|
|
83
|
+
b.getInstallStep().dependOn(&sdist_install.step);
|
|
84
|
+
b.step("sdist", "only build and install sdist").dependOn(&sdist_install.step);
|
|
75
85
|
|
|
76
86
|
const test_pip_install = VenvInstallTest.create(
|
|
77
87
|
b,
|
|
78
88
|
.{
|
|
79
89
|
.sdist = sdist.getEmittedArchive(),
|
|
80
|
-
.
|
|
90
|
+
.unittest_py = &.{b.path("example/test_ext.py")},
|
|
81
91
|
.twine_check = true,
|
|
92
|
+
.entry_points = &.{
|
|
93
|
+
// TODO: make "some more" one argument on windows
|
|
94
|
+
&.{ "sdist-dummy", "with", "some more", "args" },
|
|
95
|
+
},
|
|
82
96
|
.no_clean = b.option(bool, "pip-no-clean", "cleanup pip temp dirs") orelse false,
|
|
83
97
|
},
|
|
84
98
|
);
|
|
85
99
|
b.step("test-pip-install", "").dependOn(test_pip_install.step);
|
|
86
100
|
}
|
|
87
101
|
|
|
88
|
-
|
|
102
|
+
fn createModule(b: *Build, options: CPython.LinkOptions) *Build.Module {
|
|
103
|
+
const this_dep = b.dependencyFromBuildZig(@This(), .{});
|
|
104
|
+
return CPython.createModuleInternal(b, this_dep.builder, options);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
fn createSdist(b: *Build, options: SDistStep.Options) *SDistStep {
|
|
89
108
|
var opt = options;
|
|
90
|
-
const
|
|
109
|
+
const this_dep = b.dependencyFromBuildZig(@This(), .{
|
|
91
110
|
.target = b.graph.host,
|
|
92
111
|
.optimize = .Debug,
|
|
93
112
|
});
|
|
94
|
-
|
|
113
|
+
const builder = this_dep.artifact("sdist-builder");
|
|
95
114
|
|
|
96
115
|
{
|
|
97
116
|
var files: std.ArrayList(SDistStep.Content) = .empty;
|
|
98
117
|
const extra_files: []const SDistStep.Content = &.{
|
|
99
|
-
.{ .src =
|
|
100
|
-
.{ .src =
|
|
101
|
-
.{ .src =
|
|
102
|
-
.{ .src =
|
|
103
|
-
.{ .src =
|
|
118
|
+
.{ .src = this_dep.path("build.zig.zon"), .dest = "zig-pkg/zig_python_sdist-" ++ zon.version ++ "/build.zig.zon" },
|
|
119
|
+
.{ .src = this_dep.path("build.zig"), .dest = "zig-pkg/zig_python_sdist-" ++ zon.version ++ "/build.zig" },
|
|
120
|
+
.{ .src = this_dep.path("pkg-info.zon"), .dest = "zig-pkg/zig_python_sdist-" ++ zon.version ++ "/pkg-info.zon" },
|
|
121
|
+
.{ .src = this_dep.path("README.md"), .dest = "zig-pkg/zig_python_sdist-" ++ zon.version ++ "/README.md" },
|
|
122
|
+
.{ .src = this_dep.path("LICENSE"), .dest = "zig-pkg/zig_python_sdist-" ++ zon.version ++ "/LICENSE" },
|
|
104
123
|
};
|
|
105
124
|
files.ensureTotalCapacity(
|
|
106
125
|
b.allocator,
|
|
@@ -114,7 +133,7 @@ pub fn create(b: *Build, options: SDistStep.Options) *SDistStep {
|
|
|
114
133
|
{
|
|
115
134
|
var dirs: std.ArrayList(SDistStep.Content) = .empty;
|
|
116
135
|
const extra_dirs: []const SDistStep.Content = &.{
|
|
117
|
-
.{ .src =
|
|
136
|
+
.{ .src = this_dep.path("src/build"), .dest = "zig-pkg/zig_python_sdist-" ++ zon.version ++ "/src/build" },
|
|
118
137
|
};
|
|
119
138
|
dirs.ensureTotalCapacity(
|
|
120
139
|
b.allocator,
|
|
@@ -131,10 +150,10 @@ pub fn create(b: *Build, options: SDistStep.Options) *SDistStep {
|
|
|
131
150
|
b.allocator,
|
|
132
151
|
opt.build.args.len + 1,
|
|
133
152
|
) catch @panic("OOM");
|
|
153
|
+
args.appendAssumeCapacity("--fork=zig-pkg/zig_python_sdist-" ++ zon.version);
|
|
134
154
|
args.appendSliceAssumeCapacity(opt.build.args);
|
|
135
|
-
args.appendAssumeCapacity("--fork=zig-pkg/zig_python_sdist");
|
|
136
155
|
opt.build.args = args.toOwnedSlice(b.allocator) catch @panic("OOM");
|
|
137
156
|
}
|
|
138
157
|
|
|
139
|
-
return SDistStep.createInternal(b, opt);
|
|
158
|
+
return SDistStep.createInternal(b, builder, opt);
|
|
140
159
|
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
//! a module for building cpython extension libraries,
|
|
2
|
+
//! linking them with system python headers and libs
|
|
3
|
+
|
|
4
|
+
const std = @import("std");
|
|
5
|
+
const builtin = @import("builtin");
|
|
6
|
+
const Build = std.Build;
|
|
7
|
+
const LazyPath = Build.LazyPath;
|
|
8
|
+
const mem = std.mem;
|
|
9
|
+
|
|
10
|
+
pub const CPython = @This();
|
|
11
|
+
|
|
12
|
+
pub const LinkOptions = struct {
|
|
13
|
+
target: Build.ResolvedTarget,
|
|
14
|
+
optimize: std.builtin.OptimizeMode,
|
|
15
|
+
version: ?[]const u8 = null,
|
|
16
|
+
// pass in the python executable for finding headers. use "python" from PATH if omitted.
|
|
17
|
+
python_exe: ?LazyPath = null,
|
|
18
|
+
macros: []const [2][]const u8 = &default_macros,
|
|
19
|
+
pub const default_macros = .{
|
|
20
|
+
.{ "Py_LIMITED_API", "0x03060500" }, // use the limited api from 3.6.5
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// generate a module linked against the python library headers found using
|
|
25
|
+
// a cpython runtime
|
|
26
|
+
pub fn createModuleInternal(b: *Build, sdist_build: *Build, options: LinkOptions) *Build.Module {
|
|
27
|
+
const python = if (options.python_exe) |python_exe|
|
|
28
|
+
python_exe
|
|
29
|
+
else
|
|
30
|
+
CPython.find(b);
|
|
31
|
+
|
|
32
|
+
const python_inc = generateIncludeDir(b, python);
|
|
33
|
+
|
|
34
|
+
const cpython = b.addTranslateC(.{
|
|
35
|
+
.root_source_file = python_inc.path(b, "zig_python_include.h"),
|
|
36
|
+
.optimize = options.optimize,
|
|
37
|
+
.target = options.target,
|
|
38
|
+
});
|
|
39
|
+
cpython.addIncludePath(python_inc);
|
|
40
|
+
|
|
41
|
+
for (options.macros) |macro| {
|
|
42
|
+
cpython.defineCMacro(macro[0], macro[1]);
|
|
43
|
+
}
|
|
44
|
+
const cpy_mod = cpython.createModule();
|
|
45
|
+
|
|
46
|
+
const wf = b.addWriteFiles();
|
|
47
|
+
|
|
48
|
+
const version = if (options.version) |version|
|
|
49
|
+
b.createModule(.{
|
|
50
|
+
.root_source_file = wf.add("version.txt", version),
|
|
51
|
+
})
|
|
52
|
+
else
|
|
53
|
+
b.createModule(.{
|
|
54
|
+
.root_source_file = wf.add("version.txt", "version not provided at configure time!"),
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
if (options.target.result.os.tag == .windows) {
|
|
58
|
+
cpy_mod.addLibraryPath(python_inc);
|
|
59
|
+
cpy_mod.linkSystemLibrary("python", .{});
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return b.createModule(.{
|
|
63
|
+
.root_source_file = sdist_build.path("src/build/python.zig"),
|
|
64
|
+
.imports = &.{
|
|
65
|
+
.{ .name = "c", .module = cpy_mod },
|
|
66
|
+
.{ .name = "version", .module = version },
|
|
67
|
+
},
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
pub fn generateIncludeDir(b: *Build, python: LazyPath) LazyPath {
|
|
72
|
+
const extract_link_info = Build.Step.Run.create(b, "python header extraction run");
|
|
73
|
+
extract_link_info.addFileArg(python);
|
|
74
|
+
const wf = b.addWriteFiles();
|
|
75
|
+
extract_link_info.addFileArg(wf.add("extract_link_info.py", @embedFile("extract_link_info.py")));
|
|
76
|
+
return extract_link_info.addOutputDirectoryArg("pyinclude");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
pub fn installExtLib(b: *Build, lib: *Build.Step.Compile) *Build.Step.InstallFile {
|
|
80
|
+
const ext_lib_name = lib_ext_name(b, lib);
|
|
81
|
+
return b.addInstallLibFile(lib.getEmittedBin(), ext_lib_name);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
pub fn lib_ext_name(b: *Build, lib: *Build.Step.Compile) []const u8 {
|
|
85
|
+
const target = lib.rootModuleTarget();
|
|
86
|
+
return if (target.os.tag == .windows)
|
|
87
|
+
b.fmt("{s}.pyd", .{lib.name})
|
|
88
|
+
else
|
|
89
|
+
b.fmt("{s}.so", .{lib.name});
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
pub fn find(b: *Build) LazyPath {
|
|
93
|
+
return findProgramCompat(b, &.{
|
|
94
|
+
"python",
|
|
95
|
+
"python3",
|
|
96
|
+
}) orelse {
|
|
97
|
+
const err_wf = b.addWriteFiles();
|
|
98
|
+
const err_step = b.addFail("finding python failed. please provide a path to the exe using -Dpython=");
|
|
99
|
+
err_wf.step.dependOn(&err_step.step);
|
|
100
|
+
return err_wf.getDirectory();
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// compat for 0.16.0 and 0.17.0
|
|
105
|
+
pub fn findProgramCompat(b: *std.Build, names: []const []const u8) ?LazyPath {
|
|
106
|
+
if (comptime (@import("builtin").zig_version.order(std.SemanticVersion.parse("0.16.0") catch unreachable) == .gt)) {
|
|
107
|
+
return b.findProgramLazy(.{ .names = names });
|
|
108
|
+
}
|
|
109
|
+
return .{
|
|
110
|
+
.cwd_relative = b.findProgram(names, &.{}) catch return null,
|
|
111
|
+
};
|
|
112
|
+
}
|