zig-zon 0.2.4__tar.gz → 0.2.5__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.4 → zig-zon-0.2.5}/PKG-INFO +1 -1
- zig-zon-0.2.5/build.zig +118 -0
- {zig-zon-0.2.4 → zig-zon-0.2.5}/build.zig.zon +3 -5
- {zig-zon-0.2.4 → zig-zon-0.2.5}/setup.py +10 -7
- zig-zon-0.2.5/setup.zig.json +1 -0
- zig-zon-0.2.5/src/zig_zon.pyi +5 -0
- {zig-zon-0.2.4 → zig-zon-0.2.5}/src/zig_zon.zig +39 -13
- {zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3 → zig-zon-0.2.5/zig-pkg/zig_python_sdist-0.0.4}/README.md +7 -0
- {zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3 → zig-zon-0.2.5/zig-pkg/zig_python_sdist-0.0.4}/build.zig +45 -2
- {zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3 → zig-zon-0.2.5/zig-pkg/zig_python_sdist-0.0.4}/build.zig.zon +1 -1
- {zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3 → zig-zon-0.2.5/zig-pkg/zig_python_sdist-0.0.4}/src/build/CPython.zig +21 -5
- zig-zon-0.2.5/zig-pkg/zig_python_sdist-0.0.4/src/build/Compression.zig +33 -0
- {zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3 → zig-zon-0.2.5/zig-pkg/zig_python_sdist-0.0.4}/src/build/SDistStep.zig +13 -16
- {zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3 → zig-zon-0.2.5/zig-pkg/zig_python_sdist-0.0.4}/src/build/VenvInstallTest.zig +1 -1
- {zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3 → zig-zon-0.2.5/zig-pkg/zig_python_sdist-0.0.4}/src/build/extract_link_info.py +4 -12
- zig-zon-0.2.5/zig-pkg/zig_python_sdist-0.0.4/src/build/python-translatec.h +6 -0
- {zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3 → zig-zon-0.2.5/zig-pkg/zig_python_sdist-0.0.4}/src/build/python.zig +95 -25
- zig-zon-0.2.5/zig-pkg/zig_python_sdist-0.0.4/src/build/python_allocator.zig +201 -0
- {zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3 → zig-zon-0.2.5/zig-pkg/zig_python_sdist-0.0.4}/src/build/setup_json.zig +13 -5
- zig-zon-0.2.4/build.zig +0 -75
- zig-zon-0.2.4/setup.zig.json +0 -1
- {zig-zon-0.2.4 → zig-zon-0.2.5}/pkg-info.zon +0 -0
- {zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3 → zig-zon-0.2.5/zig-pkg/zig_python_sdist-0.0.4}/LICENSE +0 -0
- {zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3 → zig-zon-0.2.5/zig-pkg/zig_python_sdist-0.0.4}/pkg-info.zon +0 -0
- {zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3 → zig-zon-0.2.5/zig-pkg/zig_python_sdist-0.0.4}/src/build/LowerDashString.zig +0 -0
- {zig-zon-0.2.4/zig-pkg/zig_python_sdist-0.0.3 → zig-zon-0.2.5/zig-pkg/zig_python_sdist-0.0.4}/src/build/pkg_info.zig +0 -0
zig-zon-0.2.5/build.zig
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
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
|
+
|
|
6
|
+
pub fn build(b: *Build) void {
|
|
7
|
+
const target = b.standardTargetOptions(.{});
|
|
8
|
+
const optimize = b.standardOptimizeOption(.{});
|
|
9
|
+
|
|
10
|
+
// this target and section of our build is used at pip install time
|
|
11
|
+
const ext_install_step = b.step("bdist-wheel", "build python extension module");
|
|
12
|
+
ext_install_step.dependOn(
|
|
13
|
+
&b.addInstallFile(b.path("src/zig_zon.pyi"), "lib/zig_zon.pyi").step,
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
// this generates a python sdist archive
|
|
17
|
+
const sdist = zig_python_sdist.createSdistStep(b, .{
|
|
18
|
+
.name = "zig-zon",
|
|
19
|
+
.version = zon.version,
|
|
20
|
+
.description = b.path("README.md"),
|
|
21
|
+
.build = .{
|
|
22
|
+
.args = &.{
|
|
23
|
+
ext_install_step.name,
|
|
24
|
+
b.fmt("-Doptimize={s}", .{@tagName(optimize)}),
|
|
25
|
+
},
|
|
26
|
+
},
|
|
27
|
+
.extra_pkg_info = @import("pkg-info.zon"),
|
|
28
|
+
.files = &.{
|
|
29
|
+
.{ .src = b.path("pkg-info.zon"), .dest = "pkg-info.zon" },
|
|
30
|
+
.{ .src = b.path("build.zig.zon"), .dest = "build.zig.zon" },
|
|
31
|
+
.{ .src = b.path("build.zig"), .dest = "build.zig" },
|
|
32
|
+
.{ .src = b.path("src/zig_zon.zig"), .dest = "src/zig_zon.zig" },
|
|
33
|
+
.{ .src = b.path("src/zig_zon.pyi"), .dest = "src/zig_zon.pyi" },
|
|
34
|
+
},
|
|
35
|
+
.compression = .best,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
const sdistfile = b.addInstallFileWithDir(
|
|
39
|
+
sdist.getEmittedArchive(),
|
|
40
|
+
.{ .custom = "src" },
|
|
41
|
+
sdist.basename,
|
|
42
|
+
);
|
|
43
|
+
b.getInstallStep().dependOn(&sdistfile.step);
|
|
44
|
+
|
|
45
|
+
// we can use a python virtual environment inside
|
|
46
|
+
// the zig cache to test pip installation
|
|
47
|
+
const test_pip_install = zig_python_sdist.createVenvInstallTest(
|
|
48
|
+
b,
|
|
49
|
+
.{
|
|
50
|
+
.sdist = sdist.getEmittedArchive(),
|
|
51
|
+
.unittest_py = &.{b.path("src/test_zig_zon.py")},
|
|
52
|
+
.twine_check = true,
|
|
53
|
+
.no_clean = b.option(bool, "pip-no-clean", "dont cleanup pip temp dirs") orelse false,
|
|
54
|
+
},
|
|
55
|
+
);
|
|
56
|
+
b.step("test-pip-install", "").dependOn(test_pip_install.step);
|
|
57
|
+
|
|
58
|
+
const cpython = zig_python_sdist.createCPythonModule(b, .{
|
|
59
|
+
.target = target,
|
|
60
|
+
.version = zon.version,
|
|
61
|
+
.optimize = .ReleaseSmall,
|
|
62
|
+
});
|
|
63
|
+
const lib = b.addLibrary(.{
|
|
64
|
+
.name = "zig_zon",
|
|
65
|
+
.root_module = b.addModule("zig_zon", .{
|
|
66
|
+
.root_source_file = b.path("src/zig_zon.zig"),
|
|
67
|
+
.target = target,
|
|
68
|
+
.optimize = optimize,
|
|
69
|
+
.imports = &.{
|
|
70
|
+
.{ .name = "cpython", .module = cpython },
|
|
71
|
+
},
|
|
72
|
+
}),
|
|
73
|
+
.linkage = .dynamic,
|
|
74
|
+
});
|
|
75
|
+
const ext_install = zig_python_sdist.installExtLib(b, lib);
|
|
76
|
+
ext_install_step.dependOn(&ext_install.step);
|
|
77
|
+
|
|
78
|
+
ext_install_step.dependOn(&ext_install.step);
|
|
79
|
+
|
|
80
|
+
const ext_path = zig_python_sdist.CPython.renameExtLib(b, lib);
|
|
81
|
+
|
|
82
|
+
{
|
|
83
|
+
const ext_tests = ext_path.wf.addCopyFile(b.path("src/test_zig_zon.py"), "test_zig_zon.py");
|
|
84
|
+
_ = ext_path.wf.addCopyFile(b.path("build.zig.zon"), "build.zig.zon");
|
|
85
|
+
const test_run = Build.Step.Run.create(b, "unittest");
|
|
86
|
+
test_run.setCwd(ext_path.wf.getDirectory());
|
|
87
|
+
test_run.setEnvironmentVariable("PYTHONPATH", ".");
|
|
88
|
+
test_run.addFileArg(zig_python_sdist.CPython.find(b));
|
|
89
|
+
if (b.option(bool, "tracetest", "run unittest with tracing") orelse false) {
|
|
90
|
+
test_run.addArgs(&.{ "-m", "trace", "--trace" });
|
|
91
|
+
} else {
|
|
92
|
+
test_run.addArgs(&.{ "-m", "unittest" });
|
|
93
|
+
}
|
|
94
|
+
test_run.addDirectoryArg(ext_tests);
|
|
95
|
+
b.step("test-bdist", "run unittests against the extension").dependOn(&test_run.step);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const usf = b.addUpdateSourceFiles();
|
|
99
|
+
b.step("update-src", "updates the pyi file. needs 'mypy' installed").dependOn(&usf.step);
|
|
100
|
+
|
|
101
|
+
{
|
|
102
|
+
const stubgen_run = Build.Step.Run.create(b, "stubgen");
|
|
103
|
+
stubgen_run.setCwd(ext_path.wf.getDirectory());
|
|
104
|
+
stubgen_run.addArgs(&.{
|
|
105
|
+
"stubgen",
|
|
106
|
+
"-m",
|
|
107
|
+
lib.name,
|
|
108
|
+
"-o",
|
|
109
|
+
});
|
|
110
|
+
const stub_dir = stubgen_run.addOutputDirectoryArg("stubgen");
|
|
111
|
+
stubgen_run.addArg("--search-path");
|
|
112
|
+
stubgen_run.addDirectoryArg(ext_path.wf.getDirectory());
|
|
113
|
+
usf.addCopyFileToSource(
|
|
114
|
+
stub_dir.path(b, b.fmt("{s}.pyi", .{lib.name})),
|
|
115
|
+
b.fmt("src/{s}.pyi", .{lib.name}),
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
.{
|
|
2
2
|
.name = .python_zig_zon,
|
|
3
3
|
.fingerprint = 0x3d332656a3644fc9,
|
|
4
|
-
.version = "0.2.
|
|
4
|
+
.version = "0.2.5",
|
|
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.4#79469a3698fe6c11ad0420282e71ff858642a4ac",
|
|
9
|
+
.hash = "zig_python_sdist-0.0.4-wjgdOukkAQBzC1YymFsy5h5_nZTUlWKUFI9oseCgGkKP",
|
|
10
10
|
},
|
|
11
11
|
},
|
|
12
12
|
.paths = .{
|
|
@@ -16,7 +16,5 @@
|
|
|
16
16
|
"pkg-info.zon",
|
|
17
17
|
"LICENSE",
|
|
18
18
|
"README.md",
|
|
19
|
-
"setup.py",
|
|
20
|
-
"pyproject.toml",
|
|
21
19
|
},
|
|
22
20
|
}
|
|
@@ -14,6 +14,7 @@ with open("setup.zig.json") as fd:
|
|
|
14
14
|
|
|
15
15
|
|
|
16
16
|
def mkversion(v, need_release=False):
|
|
17
|
+
'''assembles a dict of semantic version to string'''
|
|
17
18
|
if need_release:
|
|
18
19
|
assert v['pre'] == None, "cannot use version with pre: " + str(v)
|
|
19
20
|
assert v['build'] == None, "cannot use version with build: " + str(v)
|
|
@@ -40,14 +41,15 @@ class ZigBuildWheel(bdist_wheel):
|
|
|
40
41
|
|
|
41
42
|
os.makedirs(self.bdist_dir, exist_ok=True)
|
|
42
43
|
copy_pattern = setup_json['build']['copy_pattern']
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
for pattern in copy_pattern:
|
|
45
|
+
artifacts = glob.glob(pattern)
|
|
46
|
+
if len(artifacts) == 0:
|
|
47
|
+
raise Exception(
|
|
48
|
+
'no zig artifacts found in {}/{}'.format(cwd, pattern))
|
|
47
49
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
50
|
+
for it in artifacts:
|
|
51
|
+
shutil.copyfile(it, os.path.join(
|
|
52
|
+
self.bdist_dir, os.path.basename(it)))
|
|
51
53
|
|
|
52
54
|
return super().run(*args, **kwargs)
|
|
53
55
|
|
|
@@ -58,6 +60,7 @@ setup(
|
|
|
58
60
|
cmdclass={'bdist_wheel': ZigBuildWheel},
|
|
59
61
|
install_requires=setup_json['install_requires'],
|
|
60
62
|
entry_points=setup_json['entry_points'],
|
|
63
|
+
packages=setup_json['build']['packages'],
|
|
61
64
|
setup_requires=[
|
|
62
65
|
"setuptools",
|
|
63
66
|
"wheel",
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"name":"zig_zon","version":{"major":0,"minor":2,"patch":5,"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.4","bdist-wheel","-Doptimize=ReleaseSmall"],"requires":[],"packages":[],"copy_pattern":["zig-out/lib/*"]},"install_requires":[],"entry_points":{"console_scripts":[],"gui_scripts":[]}}
|
|
@@ -8,28 +8,54 @@ const cpython = @import("cpython");
|
|
|
8
8
|
const c = cpython.c;
|
|
9
9
|
const PyObject = c.PyObject;
|
|
10
10
|
|
|
11
|
-
pub var
|
|
12
|
-
c.PyMethodDef{
|
|
13
|
-
.ml_name = "parse",
|
|
14
|
-
.ml_meth = @ptrCast(@alignCast(&parse)),
|
|
15
|
-
.ml_flags = @as(c_int, 1),
|
|
16
|
-
.ml_doc = "parse a zon literal to a python object",
|
|
17
|
-
},
|
|
18
|
-
c.PyMethodDef{},
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
pub var zigmodule = c.PyModuleDef{
|
|
11
|
+
pub var zigmodule: c.PyModuleDef = .{
|
|
22
12
|
.m_name = "zig_zon",
|
|
23
|
-
.m_methods = &
|
|
13
|
+
.m_methods = @constCast(&[_]c.PyMethodDef{
|
|
14
|
+
.{
|
|
15
|
+
.ml_name = "parse",
|
|
16
|
+
.ml_meth = @ptrCast(@alignCast(&parse)),
|
|
17
|
+
.ml_flags = 1,
|
|
18
|
+
.ml_doc = "parse a zon literal to a python object",
|
|
19
|
+
},
|
|
20
|
+
.{},
|
|
21
|
+
}),
|
|
24
22
|
};
|
|
25
23
|
|
|
26
24
|
pub export fn PyInit_zig_zon() [*c]c.PyObject {
|
|
27
25
|
const mod = c.PyModule_Create(&zigmodule);
|
|
26
|
+
|
|
27
|
+
{
|
|
28
|
+
// const annotations = c.PyDict_New();
|
|
29
|
+
// defer c.Py_DecRef(annotations);
|
|
30
|
+
// const builtins = c.PyImport_ImportModule("builtins");
|
|
31
|
+
// defer c.Py_DecRef(builtins);
|
|
32
|
+
|
|
33
|
+
// const str_type = c.PyObject_GetAttrString(builtins, "str") orelse PyErrPanic();
|
|
34
|
+
// defer c.Py_DecRef(str_type);
|
|
35
|
+
|
|
36
|
+
// assert(0 <= c.PyDict_SetItemString(annotations, "value", str_type));
|
|
37
|
+
|
|
38
|
+
// const parse_ref = c.PyObject_GetAttrString(mod, "parse") orelse PyErrPanic();
|
|
39
|
+
// defer c.Py_DecRef(parse_ref);
|
|
40
|
+
|
|
41
|
+
//TODO: find another way to set annotations, since a builtin function is immutable.
|
|
42
|
+
|
|
43
|
+
// if (0 > c.PyObject_SetAttrString(parse_ref, "__annotations__", annotations)) {
|
|
44
|
+
// c.PyErr_Print();
|
|
45
|
+
// @panic("WTF");
|
|
46
|
+
// }
|
|
47
|
+
}
|
|
48
|
+
|
|
28
49
|
cpython.addVersion(mod);
|
|
29
50
|
cpython.addZigBuiltin(mod);
|
|
30
51
|
return mod;
|
|
31
52
|
}
|
|
32
53
|
|
|
54
|
+
pub fn PyErrPanic() noreturn {
|
|
55
|
+
c.PyErr_Print();
|
|
56
|
+
@panic("Unexpected PyErr!");
|
|
57
|
+
}
|
|
58
|
+
|
|
33
59
|
pub fn parse(self: [*]PyObject, args: [*]PyObject) callconv(.c) [*c]PyObject {
|
|
34
60
|
_ = self;
|
|
35
61
|
const zon_slice: [:0]u8 = zon_slice: {
|
|
@@ -38,7 +64,7 @@ pub fn parse(self: [*]PyObject, args: [*]PyObject) callconv(.c) [*c]PyObject {
|
|
|
38
64
|
break :zon_slice std.mem.sliceTo(zon_txt, 0);
|
|
39
65
|
};
|
|
40
66
|
|
|
41
|
-
var arena_instance = std.heap.ArenaAllocator.init(
|
|
67
|
+
var arena_instance = std.heap.ArenaAllocator.init(cpython.py_allocator);
|
|
42
68
|
defer arena_instance.deinit();
|
|
43
69
|
const arena = arena_instance.allocator();
|
|
44
70
|
|
|
@@ -112,3 +112,10 @@ that will:
|
|
|
112
112
|
- compile and install your package
|
|
113
113
|
- run python unittest files against the installed package
|
|
114
114
|
- run entrypoints from the installed package to test them
|
|
115
|
+
|
|
116
|
+
## References
|
|
117
|
+
|
|
118
|
+
- [Deinventing the Wheel - Loris Cro](https://www.youtube.com/watch?v=HPmefnqirHk)
|
|
119
|
+
- <https://pypi.org/project/setuptools-zig/>
|
|
120
|
+
- <https://pypi.org/project/zig-zon>
|
|
121
|
+
- <https://codeberg.org/dasimmet/python-zig-zon>
|
|
@@ -12,6 +12,7 @@ pub const createSdistStep = createSdist;
|
|
|
12
12
|
pub const createVenvInstallTest = VenvInstallTest.create;
|
|
13
13
|
pub const createCPythonModule = createModule;
|
|
14
14
|
pub const installExtLib = CPython.installExtLib;
|
|
15
|
+
pub const renameExtLib = CPython.renameExtLib;
|
|
15
16
|
|
|
16
17
|
pub fn build(b: *Build) void {
|
|
17
18
|
const target = b.standardTargetOptions(.{});
|
|
@@ -54,12 +55,52 @@ pub fn build(b: *Build) void {
|
|
|
54
55
|
const build_ext_step = b.step("bdist-wheel", "build the sdist dummy python module");
|
|
55
56
|
build_ext_step.dependOn(&install_ext.step);
|
|
56
57
|
|
|
58
|
+
{
|
|
59
|
+
const ext_path = CPython.renameExtLib(b, sdist_dummy);
|
|
60
|
+
const ext_tests = ext_path.wf.addCopyFile(b.path("example/test_ext.py"), "test_ext.py");
|
|
61
|
+
const test_run = Build.Step.Run.create(b, "unittest");
|
|
62
|
+
test_run.setCwd(ext_path.wf.getDirectory());
|
|
63
|
+
test_run.setEnvironmentVariable("PYTHONPATH", ".");
|
|
64
|
+
test_run.addFileArg(CPython.find(b));
|
|
65
|
+
test_run.addArgs(&.{ "-m", "unittest" });
|
|
66
|
+
test_run.addDirectoryArg(ext_tests);
|
|
67
|
+
b.step("test-bdist", "test the extension against the local python version").dependOn(&test_run.step);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
{
|
|
71
|
+
const ext_path = CPython.renameExtLib(b, sdist_dummy);
|
|
72
|
+
const stubgen_run = Build.Step.Run.create(b, "stubgen");
|
|
73
|
+
stubgen_run.setCwd(ext_path.wf.getDirectory());
|
|
74
|
+
stubgen_run.addArgs(&.{
|
|
75
|
+
"stubgen",
|
|
76
|
+
"-m",
|
|
77
|
+
sdist_dummy.name,
|
|
78
|
+
"-o",
|
|
79
|
+
});
|
|
80
|
+
const stub_dir = stubgen_run.addOutputDirectoryArg("stubgen");
|
|
81
|
+
stubgen_run.addArg("--search-path");
|
|
82
|
+
stubgen_run.addDirectoryArg(ext_path.wf.getDirectory());
|
|
83
|
+
const usf = b.addUpdateSourceFiles();
|
|
84
|
+
usf.addCopyFileToSource(
|
|
85
|
+
stub_dir.path(b, b.fmt("{s}.pyi", .{sdist_dummy.name})),
|
|
86
|
+
b.fmt("example/{s}.pyi", .{sdist_dummy.name}),
|
|
87
|
+
);
|
|
88
|
+
b.step("stubgen", "generate .pyi from module with mypy stubgen").dependOn(&usf.step);
|
|
89
|
+
}
|
|
90
|
+
|
|
57
91
|
const sdist = SDistStep.createInternal(b, exe, .{
|
|
58
92
|
.name = "sdist-dummy",
|
|
59
93
|
.version = zon.version,
|
|
60
94
|
.description = b.path("README.md"),
|
|
61
95
|
.build = .{
|
|
62
|
-
.args = &.{
|
|
96
|
+
.args = &.{
|
|
97
|
+
b.fmt("-Doptimize={s}", .{@tagName(optimize)}),
|
|
98
|
+
build_ext_step.name,
|
|
99
|
+
},
|
|
100
|
+
.copy_pattern = &.{
|
|
101
|
+
"zig-out/lib/*",
|
|
102
|
+
"example/sdist_dummy.pyi",
|
|
103
|
+
},
|
|
63
104
|
},
|
|
64
105
|
.extra_pkg_info = @import("pkg-info.zon"),
|
|
65
106
|
.files = &.{
|
|
@@ -67,6 +108,7 @@ pub fn build(b: *Build) void {
|
|
|
67
108
|
.{ .src = b.path("build.zig"), .dest = "build.zig" },
|
|
68
109
|
.{ .src = b.path("pkg-info.zon"), .dest = "pkg-info.zon" },
|
|
69
110
|
.{ .src = b.path("example/sdist_dummy.zig"), .dest = "example/sdist_dummy.zig" },
|
|
111
|
+
.{ .src = b.path("example/sdist_dummy.pyi"), .dest = "example/sdist_dummy.pyi" },
|
|
70
112
|
},
|
|
71
113
|
.directories = &.{
|
|
72
114
|
.{ .src = b.path("src/build"), .dest = "src/build" },
|
|
@@ -78,6 +120,7 @@ pub fn build(b: *Build) void {
|
|
|
78
120
|
},
|
|
79
121
|
.install_requires = &.{"ruamel.yaml.clibz"},
|
|
80
122
|
.zig_version = std.SemanticVersion.parse("0.16.0") catch unreachable,
|
|
123
|
+
.compression = .best,
|
|
81
124
|
});
|
|
82
125
|
const sdist_install = sdist.install();
|
|
83
126
|
b.getInstallStep().dependOn(&sdist_install.step);
|
|
@@ -96,7 +139,7 @@ pub fn build(b: *Build) void {
|
|
|
96
139
|
.no_clean = b.option(bool, "pip-no-clean", "cleanup pip temp dirs") orelse false,
|
|
97
140
|
},
|
|
98
141
|
);
|
|
99
|
-
b.step("test-pip-install", "").dependOn(test_pip_install.step);
|
|
142
|
+
b.step("test-pip-install", "test build and install sdist with pip").dependOn(test_pip_install.step);
|
|
100
143
|
}
|
|
101
144
|
|
|
102
145
|
fn createModule(b: *Build, options: CPython.LinkOptions) *Build.Module {
|
|
@@ -13,6 +13,7 @@ pub const LinkOptions = struct {
|
|
|
13
13
|
target: Build.ResolvedTarget,
|
|
14
14
|
optimize: std.builtin.OptimizeMode,
|
|
15
15
|
version: ?[]const u8 = null,
|
|
16
|
+
header_file: ?LazyPath = null,
|
|
16
17
|
// pass in the python executable for finding headers. use "python" from PATH if omitted.
|
|
17
18
|
python_exe: ?LazyPath = null,
|
|
18
19
|
macros: []const [2][]const u8 = &default_macros,
|
|
@@ -29,10 +30,10 @@ pub fn createModuleInternal(b: *Build, sdist_build: *Build, options: LinkOptions
|
|
|
29
30
|
else
|
|
30
31
|
CPython.find(b);
|
|
31
32
|
|
|
32
|
-
const python_inc = generateIncludeDir(b, python);
|
|
33
|
+
const python_inc = generateIncludeDir(b, sdist_build, python);
|
|
33
34
|
|
|
34
35
|
const cpython = b.addTranslateC(.{
|
|
35
|
-
.root_source_file =
|
|
36
|
+
.root_source_file = options.header_file orelse sdist_build.path("src/build/python-translatec.h"),
|
|
36
37
|
.optimize = options.optimize,
|
|
37
38
|
.target = options.target,
|
|
38
39
|
});
|
|
@@ -64,18 +65,33 @@ pub fn createModuleInternal(b: *Build, sdist_build: *Build, options: LinkOptions
|
|
|
64
65
|
.imports = &.{
|
|
65
66
|
.{ .name = "c", .module = cpy_mod },
|
|
66
67
|
.{ .name = "version", .module = version },
|
|
68
|
+
.{ .name = "pyhexver", .module = b.createModule(.{
|
|
69
|
+
.root_source_file = python_inc.path(b, "pyhexver.zig"),
|
|
70
|
+
}) },
|
|
67
71
|
},
|
|
68
72
|
});
|
|
69
73
|
}
|
|
70
74
|
|
|
71
|
-
pub fn generateIncludeDir(b: *Build, python: LazyPath) LazyPath {
|
|
75
|
+
pub fn generateIncludeDir(b: *Build, sdist_build: *Build, python: LazyPath) LazyPath {
|
|
72
76
|
const extract_link_info = Build.Step.Run.create(b, "python header extraction run");
|
|
73
77
|
extract_link_info.addFileArg(python);
|
|
74
|
-
|
|
75
|
-
extract_link_info.addFileArg(wf.add("extract_link_info.py", @embedFile("extract_link_info.py")));
|
|
78
|
+
extract_link_info.addFileArg(sdist_build.path("src/build/extract_link_info.py"));
|
|
76
79
|
return extract_link_info.addOutputDirectoryArg("pyinclude");
|
|
77
80
|
}
|
|
78
81
|
|
|
82
|
+
pub fn renameExtLib(b: *Build, lib: *Build.Step.Compile) struct {
|
|
83
|
+
wf: *Build.Step.WriteFile,
|
|
84
|
+
ext: LazyPath,
|
|
85
|
+
} {
|
|
86
|
+
const ext_lib_name = lib_ext_name(b, lib);
|
|
87
|
+
const wf = b.addWriteFiles();
|
|
88
|
+
const ext = wf.addCopyFile(lib.getEmittedBin(), ext_lib_name);
|
|
89
|
+
return .{
|
|
90
|
+
.wf = wf,
|
|
91
|
+
.ext = ext,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
79
95
|
pub fn installExtLib(b: *Build, lib: *Build.Step.Compile) *Build.Step.InstallFile {
|
|
80
96
|
const ext_lib_name = lib_ext_name(b, lib);
|
|
81
97
|
return b.addInstallLibFile(lib.getEmittedBin(), ext_lib_name);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
|
|
3
|
+
pub const Compression = enum {
|
|
4
|
+
fastest,
|
|
5
|
+
default,
|
|
6
|
+
best,
|
|
7
|
+
level_1,
|
|
8
|
+
level_2,
|
|
9
|
+
level_3,
|
|
10
|
+
level_4,
|
|
11
|
+
level_5,
|
|
12
|
+
level_6,
|
|
13
|
+
level_7,
|
|
14
|
+
level_8,
|
|
15
|
+
level_9,
|
|
16
|
+
|
|
17
|
+
pub fn toGzipOptions(self: @This()) std.compress.flate.Compress.Options {
|
|
18
|
+
return switch (self) {
|
|
19
|
+
.fastest => .fastest,
|
|
20
|
+
.default => .default,
|
|
21
|
+
.best => .best,
|
|
22
|
+
.level_1 => .level_1,
|
|
23
|
+
.level_2 => .level_2,
|
|
24
|
+
.level_3 => .level_3,
|
|
25
|
+
.level_4 => .level_4,
|
|
26
|
+
.level_5 => .level_5,
|
|
27
|
+
.level_6 => .level_6,
|
|
28
|
+
.level_7 => .level_7,
|
|
29
|
+
.level_8 => .level_8,
|
|
30
|
+
.level_9 => .level_9,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
};
|
|
@@ -6,6 +6,7 @@ const LazyPath = Build.LazyPath;
|
|
|
6
6
|
const LowerDashString = @import("LowerDashString.zig");
|
|
7
7
|
const PkgInfo = @import("pkg_info.zig");
|
|
8
8
|
const SetupJson = @import("setup_json.zig");
|
|
9
|
+
const Compression = @import("Compression.zig").Compression;
|
|
9
10
|
|
|
10
11
|
const SDistStep = @This();
|
|
11
12
|
|
|
@@ -29,14 +30,7 @@ pub const Options = struct {
|
|
|
29
30
|
description: ?LazyPath = null,
|
|
30
31
|
|
|
31
32
|
/// extra configuration for building th python wheel
|
|
32
|
-
build:
|
|
33
|
-
/// extra arguments for `zig build` at wheel build time
|
|
34
|
-
args: []const []const u8 = &.{},
|
|
35
|
-
/// additional build dependencies for wheel build
|
|
36
|
-
requires: []const []const u8 = &.{},
|
|
37
|
-
/// files to copy from zig build to wheel directory. passed glob.glob() after build
|
|
38
|
-
copy_pattern: ?[]const u8 = null,
|
|
39
|
-
} = .{},
|
|
33
|
+
build: SetupJson.Build,
|
|
40
34
|
|
|
41
35
|
///additional python packages to depend on at runtime
|
|
42
36
|
install_requires: []const []const u8 = &.{},
|
|
@@ -56,6 +50,9 @@ pub const Options = struct {
|
|
|
56
50
|
|
|
57
51
|
/// entry points pip should create on install
|
|
58
52
|
entry_points: SetupJson.EntryPoints = .{},
|
|
53
|
+
|
|
54
|
+
/// gzip compression level
|
|
55
|
+
compression: ?Compression = null,
|
|
59
56
|
};
|
|
60
57
|
|
|
61
58
|
pub fn createInternal(b: *Build, builder: *Build.Step.Compile, options: Options) *SDistStep {
|
|
@@ -95,17 +92,17 @@ pub fn createInternal(b: *Build, builder: *Build.Step.Compile, options: Options)
|
|
|
95
92
|
for (options.directories) |content| {
|
|
96
93
|
self.addDirectory(content);
|
|
97
94
|
}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
}
|
|
95
|
+
|
|
96
|
+
run.addArg(b.fmt("--build={f}", .{
|
|
97
|
+
std.json.fmt(options.build, .{ .whitespace = .minified }),
|
|
98
|
+
}));
|
|
99
|
+
|
|
104
100
|
for (options.install_requires) |br| {
|
|
105
101
|
run.addArg(b.fmt("--install-requires={s}", .{br}));
|
|
106
102
|
}
|
|
107
|
-
|
|
108
|
-
|
|
103
|
+
|
|
104
|
+
if (options.compression) |compression| {
|
|
105
|
+
run.addArg(b.fmt("--compression={s}", .{@tagName(compression)}));
|
|
109
106
|
}
|
|
110
107
|
if (options.extra_pkg_info.len > 0) {
|
|
111
108
|
const extra_info = std.fmt.allocPrint(b.allocator, "--extra-pkg-info={f}", .{
|
|
@@ -46,7 +46,7 @@ pub fn create(b: *Build, options: Options) *VenvInstallTest {
|
|
|
46
46
|
venv_run.addDirectoryArg(venv.getDirectory());
|
|
47
47
|
|
|
48
48
|
self.python = if (builtin.target.os.tag == .windows)
|
|
49
|
-
venv.getDirectory().path(b, "Scripts/python")
|
|
49
|
+
venv.getDirectory().path(b, "Scripts/python.exe")
|
|
50
50
|
else
|
|
51
51
|
venv.getDirectory().path(b, "bin/python");
|
|
52
52
|
|
|
@@ -11,7 +11,7 @@ def main():
|
|
|
11
11
|
syspath = sysconfig.get_paths()
|
|
12
12
|
|
|
13
13
|
python_h = os.path.join(output_dir, 'Python.h')
|
|
14
|
-
output_header = os.path.join(output_dir, '
|
|
14
|
+
output_header = os.path.join(output_dir, 'pyhexver.zig')
|
|
15
15
|
|
|
16
16
|
os.makedirs(output_dir, exist_ok=True)
|
|
17
17
|
shutil.copytree(syspath['include'], output_dir, dirs_exist_ok=True)
|
|
@@ -26,18 +26,10 @@ def main():
|
|
|
26
26
|
syspath['include'], output_dir))
|
|
27
27
|
|
|
28
28
|
output_h_str = '''
|
|
29
|
-
//
|
|
29
|
+
// pyhexver.zig generated by extract_link_info.py
|
|
30
30
|
// sources: {}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
#endif
|
|
34
|
-
|
|
35
|
-
#ifndef PYHEXVER
|
|
36
|
-
#define PYHEXVER {}
|
|
37
|
-
#endif
|
|
38
|
-
|
|
39
|
-
#include "Python.h"
|
|
40
|
-
'''.format(sources, sys.hexversion)
|
|
31
|
+
pub const PYHEXVER={};
|
|
32
|
+
'''.format(sources, hex(sys.hexversion))
|
|
41
33
|
|
|
42
34
|
with open(output_header, 'w') as fd:
|
|
43
35
|
fd.write(output_h_str)
|
|
@@ -3,9 +3,21 @@ const builtin = @import("builtin");
|
|
|
3
3
|
const assert = std.debug.assert;
|
|
4
4
|
pub const c = @import("c");
|
|
5
5
|
pub const version = @embedFile("version");
|
|
6
|
+
pub const PYHEXVER = @import("pyhexver").PYHEXVER;
|
|
7
|
+
|
|
8
|
+
pub const py_allocator = @import("python_allocator.zig").py_allocator;
|
|
9
|
+
|
|
10
|
+
/// get the type of 'type'. in the c header this is an opaque type not acessible
|
|
11
|
+
/// by zig
|
|
12
|
+
pub fn getPyType() [*]c.PyObject {
|
|
13
|
+
const builtins = c.PyImport_ImportModule("builtins");
|
|
14
|
+
defer c.Py_DecRef(builtins);
|
|
15
|
+
return c.PyObject.GetAttrString(builtins, "type");
|
|
16
|
+
}
|
|
6
17
|
|
|
7
18
|
pub const WrapMainOptions = struct {};
|
|
8
19
|
|
|
20
|
+
/// wraps a zig "Juicy Main" function with a std.process.Init based on pythons args, allocator and environment
|
|
9
21
|
pub fn wrapMain(wrap_main: anytype, comptime options: WrapMainOptions) fn ([*]c.PyObject, [*]c.PyObject) callconv(.c) [*c]c.PyObject {
|
|
10
22
|
_ = options;
|
|
11
23
|
|
|
@@ -52,16 +64,24 @@ pub fn wrapMain(wrap_main: anytype, comptime options: WrapMainOptions) fn ([*]c.
|
|
|
52
64
|
pub fn main_fn(fn_self: [*]c.PyObject, fn_args: [*]c.PyObject) callconv(.c) [*c]c.PyObject {
|
|
53
65
|
_ = fn_self;
|
|
54
66
|
_ = fn_args;
|
|
55
|
-
var
|
|
56
|
-
defer
|
|
57
|
-
const
|
|
67
|
+
var arena_impl: std.heap.ArenaAllocator = .init(py_allocator);
|
|
68
|
+
defer arena_impl.deinit();
|
|
69
|
+
const arena = arena_impl.allocator();
|
|
70
|
+
|
|
71
|
+
var gpa_impl: std.heap.DebugAllocator(.{}) = .{
|
|
72
|
+
.backing_allocator = py_allocator,
|
|
73
|
+
};
|
|
74
|
+
defer _ = gpa_impl.deinit();
|
|
75
|
+
const gpa = gpa_impl.allocator();
|
|
58
76
|
|
|
59
|
-
var threaded: std.Io.Threaded = .init(
|
|
77
|
+
var threaded: std.Io.Threaded = .init(gpa, .{});
|
|
60
78
|
defer threaded.deinit();
|
|
61
79
|
|
|
62
80
|
const args = args: {
|
|
63
81
|
const sys = c.PyImport_ImportModule("sys");
|
|
82
|
+
defer c.Py_DecRef(sys);
|
|
64
83
|
const argv = c.PyObject_GetAttrString(sys, "argv");
|
|
84
|
+
defer c.Py_DecRef(argv);
|
|
65
85
|
const arglen = c.PySequence_Length(argv);
|
|
66
86
|
|
|
67
87
|
switch (builtin.os.tag) {
|
|
@@ -70,54 +90,64 @@ pub fn wrapMain(wrap_main: anytype, comptime options: WrapMainOptions) fn ([*]c.
|
|
|
70
90
|
|
|
71
91
|
for (0..@intCast(arglen)) |arg_i| {
|
|
72
92
|
const arg_str = c.PySequence_GetItem(argv, @intCast(arg_i));
|
|
93
|
+
defer c.Py_DecRef(arg_str);
|
|
73
94
|
const arg_bytes = c.PyUnicode_AsEncodedString(arg_str, "UTF-8", "strict");
|
|
95
|
+
defer c.Py_DecRef(arg_bytes);
|
|
74
96
|
var arg_ptr: [*c]u8 = undefined;
|
|
75
97
|
var arg_len: isize = undefined;
|
|
76
98
|
assert(0 <= c.PyBytes_AsStringAndSize(arg_bytes, &arg_ptr, &arg_len));
|
|
77
99
|
const arg = arg_ptr[0..@intCast(arg_len) :0];
|
|
78
|
-
const arg16 = std.unicode.wtf8ToWtf16LeAllocZ(
|
|
100
|
+
const arg16 = std.unicode.wtf8ToWtf16LeAllocZ(gpa, arg) catch @panic("OOM");
|
|
101
|
+
defer gpa.free(arg16);
|
|
79
102
|
|
|
80
103
|
// check if we need add quoting for windows characters
|
|
81
104
|
if (std.mem.findAny(u16, arg16, &.{ ' ', '\t' }) != null) {
|
|
82
|
-
args_list.append(
|
|
105
|
+
args_list.append(arena, '"') catch @panic("OOM");
|
|
83
106
|
for (arg16) |a| {
|
|
84
107
|
switch (a) {
|
|
85
|
-
'"' => args_list.appendSlice(
|
|
86
|
-
|
|
108
|
+
'"' => args_list.appendSlice(arena, &.{ '\\', '"' }) catch @panic("OOM"),
|
|
109
|
+
'\\' => args_list.appendSlice(arena, &.{ '\\', '\\' }) catch @panic("OOM"),
|
|
110
|
+
else => args_list.append(arena, a) catch @panic("OOM"),
|
|
87
111
|
}
|
|
88
112
|
}
|
|
89
|
-
args_list.appendSlice(
|
|
113
|
+
args_list.appendSlice(arena, &.{ '"', ' ' }) catch @panic("OOM");
|
|
90
114
|
} else {
|
|
91
|
-
args_list.appendSlice(
|
|
92
|
-
args_list.append(
|
|
115
|
+
args_list.appendSlice(arena, arg16) catch @panic("OOM");
|
|
116
|
+
args_list.append(arena, ' ') catch @panic("OOM");
|
|
93
117
|
}
|
|
94
118
|
}
|
|
95
119
|
|
|
96
|
-
break :args args_list.toOwnedSlice(
|
|
120
|
+
break :args args_list.toOwnedSlice(arena) catch @panic("OOM");
|
|
97
121
|
},
|
|
98
122
|
else => {
|
|
99
123
|
var args_list: std.ArrayList([*:0]u8) = .empty;
|
|
100
124
|
|
|
101
125
|
for (0..@intCast(arglen)) |arg_i| {
|
|
102
126
|
const arg_str = c.PySequence_GetItem(argv, @intCast(arg_i));
|
|
127
|
+
defer c.Py_DecRef(arg_str);
|
|
103
128
|
const arg_bytes = c.PyUnicode_AsEncodedString(arg_str, "UTF-8", "strict");
|
|
129
|
+
defer c.Py_DecRef(arg_bytes);
|
|
104
130
|
var arg_ptr: [*c]u8 = undefined;
|
|
105
131
|
var arg_len: isize = undefined;
|
|
106
132
|
assert(0 <= c.PyBytes_AsStringAndSize(arg_bytes, &arg_ptr, &arg_len));
|
|
107
133
|
const arg = arg_ptr[0..@intCast(arg_len) :0];
|
|
108
|
-
args_list.append(
|
|
134
|
+
args_list.append(arena, arg) catch @panic("OOM");
|
|
109
135
|
}
|
|
110
|
-
break :args args_list.toOwnedSlice(
|
|
136
|
+
break :args args_list.toOwnedSlice(arena) catch @panic("OOM");
|
|
111
137
|
},
|
|
112
138
|
}
|
|
113
139
|
};
|
|
114
140
|
|
|
115
|
-
var env: std.process.Environ.Map = .init(
|
|
141
|
+
var env: std.process.Environ.Map = .init(gpa);
|
|
116
142
|
defer env.deinit();
|
|
117
143
|
{
|
|
118
144
|
const os = c.PyImport_ImportModule("os");
|
|
145
|
+
defer c.Py_DecRef(os);
|
|
119
146
|
const os_environ = c.PyObject_GetAttrString(os, "environ");
|
|
147
|
+
defer c.Py_DecRef(os_environ);
|
|
120
148
|
const env_dict = c.PyDict_New();
|
|
149
|
+
defer c.Py_DecRef(env_dict);
|
|
150
|
+
|
|
121
151
|
assert(0 <= c.PyDict_Merge(env_dict, os_environ, 1));
|
|
122
152
|
|
|
123
153
|
var dict_key: [*c]c.PyObject = undefined;
|
|
@@ -125,12 +155,14 @@ pub fn wrapMain(wrap_main: anytype, comptime options: WrapMainOptions) fn ([*]c.
|
|
|
125
155
|
var dict_pos: c.Py_ssize_t = 0;
|
|
126
156
|
while (c.PyDict_Next(env_dict, &dict_pos, &dict_key, &dict_value) != 0) {
|
|
127
157
|
const key_bytes = c.PyUnicode_AsEncodedString(dict_key, "UTF-8", "strict");
|
|
158
|
+
defer c.Py_DecRef(key_bytes);
|
|
128
159
|
var key_ptr: [*c]u8 = undefined;
|
|
129
160
|
var key_len: isize = undefined;
|
|
130
161
|
assert(0 <= c.PyBytes_AsStringAndSize(key_bytes, &key_ptr, &key_len));
|
|
131
162
|
const key_str = key_ptr[0..@intCast(key_len) :0];
|
|
132
163
|
|
|
133
164
|
const val_bytes = c.PyUnicode_AsEncodedString(dict_value, "UTF-8", "strict");
|
|
165
|
+
defer c.Py_DecRef(val_bytes);
|
|
134
166
|
var val_ptr: [*c]u8 = undefined;
|
|
135
167
|
var val_len: isize = undefined;
|
|
136
168
|
assert(0 <= c.PyBytes_AsStringAndSize(val_bytes, &val_ptr, &val_len));
|
|
@@ -141,8 +173,8 @@ pub fn wrapMain(wrap_main: anytype, comptime options: WrapMainOptions) fn ([*]c.
|
|
|
141
173
|
}
|
|
142
174
|
|
|
143
175
|
const init: std.process.Init = .{
|
|
144
|
-
.arena = &
|
|
145
|
-
.gpa =
|
|
176
|
+
.arena = &arena_impl,
|
|
177
|
+
.gpa = gpa,
|
|
146
178
|
.io = threaded.io(),
|
|
147
179
|
.environ_map = &env,
|
|
148
180
|
.minimal = .{
|
|
@@ -175,12 +207,14 @@ pub fn wrapMain(wrap_main: anytype, comptime options: WrapMainOptions) fn ([*]c.
|
|
|
175
207
|
}
|
|
176
208
|
}
|
|
177
209
|
|
|
210
|
+
/// adds a __version__ and __version_str__ to the object
|
|
178
211
|
pub fn addVersion(mod: [*c]c.PyObject) void {
|
|
179
212
|
const semver = comptime std.SemanticVersion.parse(version) catch {
|
|
180
213
|
@compileLog("could not parse version:");
|
|
181
214
|
@compileError(version);
|
|
182
215
|
};
|
|
183
216
|
const version_dict = c.PyDict_New();
|
|
217
|
+
defer c.Py_DecRef(version_dict);
|
|
184
218
|
const None = c.Py_BuildValue("");
|
|
185
219
|
|
|
186
220
|
assert(0 <= c.PyDict_SetItemString(version_dict, "major", c.Py_BuildValue("n", semver.major)));
|
|
@@ -188,12 +222,16 @@ pub fn addVersion(mod: [*c]c.PyObject) void {
|
|
|
188
222
|
assert(0 <= c.PyDict_SetItemString(version_dict, "patch", c.Py_BuildValue("n", semver.patch)));
|
|
189
223
|
|
|
190
224
|
if (semver.pre) |pre| {
|
|
191
|
-
|
|
225
|
+
const pre_str = c.Py_BuildValue("s#", pre.ptr, pre.len);
|
|
226
|
+
defer c.Py_DecRef(pre_str);
|
|
227
|
+
assert(0 <= c.PyDict_SetItemString(version_dict, "pre", pre_str));
|
|
192
228
|
} else {
|
|
193
229
|
assert(0 <= c.PyDict_SetItemString(version_dict, "pre", None));
|
|
194
230
|
}
|
|
195
231
|
if (semver.build) |build| {
|
|
196
|
-
|
|
232
|
+
const build_str = c.Py_BuildValue("s#", build.ptr, build.len);
|
|
233
|
+
defer c.Py_DecRef(build_str);
|
|
234
|
+
assert(0 <= c.PyDict_SetItemString(version_dict, "build", build_str));
|
|
197
235
|
} else {
|
|
198
236
|
assert(0 <= c.PyDict_SetItemString(version_dict, "build", None));
|
|
199
237
|
}
|
|
@@ -211,8 +249,10 @@ pub fn addVersion(mod: [*c]c.PyObject) void {
|
|
|
211
249
|
));
|
|
212
250
|
}
|
|
213
251
|
|
|
252
|
+
/// adds a dict of zigs builtin module info to the object
|
|
214
253
|
pub fn addZigBuiltin(mod: [*c]c.PyObject) void {
|
|
215
254
|
const zig_dict = getZigBuitin();
|
|
255
|
+
defer c.Py_DecRef(zig_dict);
|
|
216
256
|
assert(0 <= c.PyObject_SetAttrString(
|
|
217
257
|
mod,
|
|
218
258
|
"__zig_builtin__",
|
|
@@ -221,7 +261,7 @@ pub fn addZigBuiltin(mod: [*c]c.PyObject) void {
|
|
|
221
261
|
}
|
|
222
262
|
|
|
223
263
|
pub fn getZigBuitin() *c.PyObject {
|
|
224
|
-
var arena_instance = std.heap.ArenaAllocator.init(
|
|
264
|
+
var arena_instance = std.heap.ArenaAllocator.init(py_allocator);
|
|
225
265
|
defer arena_instance.deinit();
|
|
226
266
|
const arena = arena_instance.allocator();
|
|
227
267
|
const None = c.Py_BuildValue("");
|
|
@@ -229,6 +269,7 @@ pub fn getZigBuitin() *c.PyObject {
|
|
|
229
269
|
const zig_dict = c.PyDict_New();
|
|
230
270
|
{
|
|
231
271
|
const version_str = c.Py_BuildValue("s#", builtin.zig_version_string.ptr, builtin.zig_version_string.len);
|
|
272
|
+
defer c.Py_DecRef(version_str);
|
|
232
273
|
assert(0 <= c.PyDict_SetItemString(
|
|
233
274
|
zig_dict,
|
|
234
275
|
"zig_version",
|
|
@@ -243,6 +284,7 @@ pub fn getZigBuitin() *c.PyObject {
|
|
|
243
284
|
.{@tagName(builtin.mode)},
|
|
244
285
|
) catch @panic("OOM");
|
|
245
286
|
const optmode_str = c.Py_BuildValue("s#", optmode.ptr, optmode.len);
|
|
287
|
+
defer c.Py_DecRef(optmode_str);
|
|
246
288
|
assert(0 <= c.PyDict_SetItemString(
|
|
247
289
|
zig_dict,
|
|
248
290
|
"optimize",
|
|
@@ -257,6 +299,7 @@ pub fn getZigBuitin() *c.PyObject {
|
|
|
257
299
|
.{@tagName(builtin.zig_backend)},
|
|
258
300
|
) catch @panic("OOM");
|
|
259
301
|
const backend_str = c.Py_BuildValue("s#", backend.ptr, backend.len);
|
|
302
|
+
defer c.Py_DecRef(backend_str);
|
|
260
303
|
assert(0 <= c.PyDict_SetItemString(
|
|
261
304
|
zig_dict,
|
|
262
305
|
"backend",
|
|
@@ -266,6 +309,7 @@ pub fn getZigBuitin() *c.PyObject {
|
|
|
266
309
|
|
|
267
310
|
{
|
|
268
311
|
const target_dict = c.PyDict_New();
|
|
312
|
+
defer c.Py_DecRef(target_dict);
|
|
269
313
|
assert(0 <= c.PyDict_SetItemString(
|
|
270
314
|
zig_dict,
|
|
271
315
|
"target",
|
|
@@ -275,6 +319,7 @@ pub fn getZigBuitin() *c.PyObject {
|
|
|
275
319
|
{
|
|
276
320
|
const target_triple = builtin.target.zigTriple(arena) catch @panic("OOM");
|
|
277
321
|
const target_triple_str = c.Py_BuildValue("s#", target_triple.ptr, target_triple.len);
|
|
322
|
+
defer c.Py_DecRef(target_triple_str);
|
|
278
323
|
assert(0 <= c.PyDict_SetItemString(
|
|
279
324
|
target_dict,
|
|
280
325
|
"triple",
|
|
@@ -284,31 +329,44 @@ pub fn getZigBuitin() *c.PyObject {
|
|
|
284
329
|
|
|
285
330
|
{
|
|
286
331
|
const cpu_dict = c.PyDict_New();
|
|
332
|
+
defer c.Py_DecRef(cpu_dict);
|
|
287
333
|
assert(0 <= c.PyDict_SetItemString(target_dict, "cpu", cpu_dict));
|
|
334
|
+
|
|
288
335
|
const arch_tag = @tagName(builtin.cpu.arch);
|
|
289
336
|
const arch_str = c.Py_BuildValue("s#", arch_tag.ptr, arch_tag.len);
|
|
337
|
+
defer c.Py_DecRef(arch_str);
|
|
290
338
|
assert(0 <= c.PyDict_SetItemString(cpu_dict, "arch", arch_str));
|
|
339
|
+
|
|
291
340
|
const model_str = c.Py_BuildValue("s#", builtin.cpu.model.name.ptr, builtin.cpu.model.name.len);
|
|
341
|
+
defer c.Py_DecRef(model_str);
|
|
292
342
|
assert(0 <= c.PyDict_SetItemString(cpu_dict, "model", model_str));
|
|
343
|
+
|
|
293
344
|
const features = c.PyList_New(0);
|
|
345
|
+
defer c.Py_DecRef(features);
|
|
294
346
|
assert(0 <= c.PyDict_SetItemString(cpu_dict, "features", features));
|
|
295
347
|
|
|
296
348
|
inline for (comptime builtin.target.cpu.arch.allFeaturesList()) |feature| {
|
|
297
349
|
if (builtin.target.cpu.has(builtin.target.cpu.arch.family(), @enumFromInt(feature.index))) {
|
|
298
350
|
const feature_str = c.Py_BuildValue("s#", feature.name.ptr, feature.name.len);
|
|
351
|
+
defer c.Py_DecRef(feature_str);
|
|
299
352
|
assert(c.PyList_Append(features, feature_str) >= 0);
|
|
300
353
|
}
|
|
301
354
|
}
|
|
302
355
|
}
|
|
303
356
|
{
|
|
304
357
|
const os_dict = c.PyDict_New();
|
|
358
|
+
defer c.Py_DecRef(os_dict);
|
|
305
359
|
assert(0 <= c.PyDict_SetItemString(target_dict, "os", os_dict));
|
|
360
|
+
|
|
306
361
|
const os_tag = @tagName(builtin.os.tag);
|
|
307
362
|
const os_str = c.Py_BuildValue("s#", os_tag.ptr, os_tag.len);
|
|
363
|
+
defer c.Py_DecRef(os_str);
|
|
308
364
|
assert(0 <= c.PyDict_SetItemString(os_dict, "tag", os_str));
|
|
365
|
+
|
|
309
366
|
switch (builtin.target.os.versionRange()) {
|
|
310
367
|
.linux => |vrange| {
|
|
311
|
-
const android = c.Py_BuildValue("
|
|
368
|
+
const android = c.Py_BuildValue("I", vrange.android);
|
|
369
|
+
defer c.Py_DecRef(android);
|
|
312
370
|
assert(0 <= c.PyDict_SetItemString(os_dict, "android", android));
|
|
313
371
|
|
|
314
372
|
const glibc = std.fmt.allocPrint(
|
|
@@ -317,6 +375,7 @@ pub fn getZigBuitin() *c.PyObject {
|
|
|
317
375
|
.{vrange.glibc},
|
|
318
376
|
) catch @panic("OOM");
|
|
319
377
|
const glibc_str = c.Py_BuildValue("s#", glibc.ptr, glibc.len);
|
|
378
|
+
defer c.Py_DecRef(glibc_str);
|
|
320
379
|
assert(0 <= c.PyDict_SetItemString(os_dict, "glibc_version", glibc_str));
|
|
321
380
|
|
|
322
381
|
const min = std.fmt.allocPrint(
|
|
@@ -325,6 +384,7 @@ pub fn getZigBuitin() *c.PyObject {
|
|
|
325
384
|
.{vrange.range.min},
|
|
326
385
|
) catch @panic("OOM");
|
|
327
386
|
const min_str = c.Py_BuildValue("s#", min.ptr, min.len);
|
|
387
|
+
defer c.Py_DecRef(min_str);
|
|
328
388
|
assert(0 <= c.PyDict_SetItemString(os_dict, "min_version", min_str));
|
|
329
389
|
|
|
330
390
|
const max = std.fmt.allocPrint(
|
|
@@ -333,23 +393,26 @@ pub fn getZigBuitin() *c.PyObject {
|
|
|
333
393
|
.{vrange.range.max},
|
|
334
394
|
) catch @panic("OOM");
|
|
335
395
|
const max_str = c.Py_BuildValue("s#", max.ptr, max.len);
|
|
396
|
+
defer c.Py_DecRef(max_str);
|
|
336
397
|
assert(0 <= c.PyDict_SetItemString(os_dict, "max_version", max_str));
|
|
337
398
|
},
|
|
338
399
|
.windows => |vrange| {
|
|
339
400
|
const min = std.fmt.allocPrint(
|
|
340
401
|
arena,
|
|
341
|
-
"{
|
|
342
|
-
.{vrange.min},
|
|
402
|
+
"{s}",
|
|
403
|
+
.{@tagName(vrange.min)},
|
|
343
404
|
) catch @panic("OOM");
|
|
344
405
|
const min_str = c.Py_BuildValue("s#", min.ptr, min.len);
|
|
406
|
+
defer c.Py_DecRef(min_str);
|
|
345
407
|
assert(0 <= c.PyDict_SetItemString(os_dict, "min_version", min_str));
|
|
346
408
|
|
|
347
409
|
const max = std.fmt.allocPrint(
|
|
348
410
|
arena,
|
|
349
|
-
"{
|
|
350
|
-
.{vrange.max},
|
|
411
|
+
"{s}",
|
|
412
|
+
.{@tagName(vrange.max)},
|
|
351
413
|
) catch @panic("OOM");
|
|
352
414
|
const max_str = c.Py_BuildValue("s#", max.ptr, max.len);
|
|
415
|
+
defer c.Py_DecRef(max_str);
|
|
353
416
|
assert(0 <= c.PyDict_SetItemString(os_dict, "max_version", max_str));
|
|
354
417
|
},
|
|
355
418
|
.semver => |vrange| {
|
|
@@ -359,6 +422,7 @@ pub fn getZigBuitin() *c.PyObject {
|
|
|
359
422
|
.{vrange.min},
|
|
360
423
|
) catch @panic("OOM");
|
|
361
424
|
const min_str = c.Py_BuildValue("s#", min.ptr, min.len);
|
|
425
|
+
defer c.Py_DecRef(min_str);
|
|
362
426
|
assert(0 <= c.PyDict_SetItemString(os_dict, "min_version", min_str));
|
|
363
427
|
|
|
364
428
|
const max = std.fmt.allocPrint(
|
|
@@ -367,6 +431,7 @@ pub fn getZigBuitin() *c.PyObject {
|
|
|
367
431
|
.{vrange.max},
|
|
368
432
|
) catch @panic("OOM");
|
|
369
433
|
const max_str = c.Py_BuildValue("s#", max.ptr, max.len);
|
|
434
|
+
defer c.Py_DecRef(max_str);
|
|
370
435
|
assert(0 <= c.PyDict_SetItemString(os_dict, "max_version", max_str));
|
|
371
436
|
},
|
|
372
437
|
.hurd => |vrange| {
|
|
@@ -376,6 +441,7 @@ pub fn getZigBuitin() *c.PyObject {
|
|
|
376
441
|
.{vrange.glibc},
|
|
377
442
|
) catch @panic("OOM");
|
|
378
443
|
const glibc_str = c.Py_BuildValue("s#", glibc.ptr, glibc.len);
|
|
444
|
+
defer c.Py_DecRef(glibc_str);
|
|
379
445
|
assert(0 <= c.PyDict_SetItemString(os_dict, "glibc_version", glibc_str));
|
|
380
446
|
|
|
381
447
|
const min = std.fmt.allocPrint(
|
|
@@ -384,6 +450,7 @@ pub fn getZigBuitin() *c.PyObject {
|
|
|
384
450
|
.{vrange.range.min},
|
|
385
451
|
) catch @panic("OOM");
|
|
386
452
|
const min_str = c.Py_BuildValue("s#", min.ptr, min.len);
|
|
453
|
+
defer c.Py_DecRef(min_str);
|
|
387
454
|
assert(0 <= c.PyDict_SetItemString(os_dict, "min_version", min_str));
|
|
388
455
|
|
|
389
456
|
const max = std.fmt.allocPrint(
|
|
@@ -392,6 +459,7 @@ pub fn getZigBuitin() *c.PyObject {
|
|
|
392
459
|
.{vrange.range.max},
|
|
393
460
|
) catch @panic("OOM");
|
|
394
461
|
const max_str = c.Py_BuildValue("s#", max.ptr, max.len);
|
|
462
|
+
defer c.Py_DecRef(max_str);
|
|
395
463
|
assert(0 <= c.PyDict_SetItemString(os_dict, "max_version", max_str));
|
|
396
464
|
},
|
|
397
465
|
.none => {},
|
|
@@ -401,11 +469,13 @@ pub fn getZigBuitin() *c.PyObject {
|
|
|
401
469
|
{
|
|
402
470
|
const abi_tag = @tagName(builtin.target.abi);
|
|
403
471
|
const abi_str = c.Py_BuildValue("s#", abi_tag.ptr, abi_tag.len);
|
|
472
|
+
defer c.Py_DecRef(abi_str);
|
|
404
473
|
assert(0 <= c.PyDict_SetItemString(target_dict, "abi", abi_str));
|
|
405
474
|
}
|
|
406
475
|
|
|
407
476
|
if (builtin.target.dynamic_linker.get()) |linker| {
|
|
408
477
|
const dynamic_linker = c.Py_BuildValue("s#", linker.ptr, linker.len);
|
|
478
|
+
defer c.Py_DecRef(dynamic_linker);
|
|
409
479
|
assert(0 <= c.PyDict_SetItemString(target_dict, "dynamic_linker", dynamic_linker));
|
|
410
480
|
} else {
|
|
411
481
|
assert(0 <= c.PyDict_SetItemString(target_dict, "dynamic_linker", None));
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
const std = @import("std");
|
|
2
|
+
const Alignment = std.mem.Alignment;
|
|
3
|
+
const Allocator = std.mem.Allocator;
|
|
4
|
+
const builtin = @import("builtin");
|
|
5
|
+
const assert = std.debug.assert;
|
|
6
|
+
pub const c = @import("c");
|
|
7
|
+
|
|
8
|
+
comptime {
|
|
9
|
+
if (!builtin.link_libc) {
|
|
10
|
+
@compileError("C allocator is only available when linking against libc");
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
pub const py_allocator: std.mem.Allocator = .{
|
|
15
|
+
.ptr = undefined,
|
|
16
|
+
.vtable = &vtable,
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const vtable: Allocator.VTable = .{
|
|
20
|
+
.alloc = alloc,
|
|
21
|
+
.resize = std.mem.Allocator.noResize,
|
|
22
|
+
.remap = std.mem.Allocator.noRemap,
|
|
23
|
+
.free = free,
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
const have_posix_memalign = switch (builtin.os.tag) {
|
|
27
|
+
.dragonfly,
|
|
28
|
+
.netbsd,
|
|
29
|
+
.freebsd,
|
|
30
|
+
.illumos,
|
|
31
|
+
.openbsd,
|
|
32
|
+
.linux,
|
|
33
|
+
.driverkit,
|
|
34
|
+
.ios,
|
|
35
|
+
.maccatalyst,
|
|
36
|
+
.macos,
|
|
37
|
+
.tvos,
|
|
38
|
+
.visionos,
|
|
39
|
+
.watchos,
|
|
40
|
+
.serenity,
|
|
41
|
+
=> true,
|
|
42
|
+
else => false,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
fn allocStrat(need_align: Alignment) union(enum) {
|
|
46
|
+
raw,
|
|
47
|
+
posix_memalign: if (have_posix_memalign) void else noreturn,
|
|
48
|
+
manual_align: if (have_posix_memalign) noreturn else void,
|
|
49
|
+
} {
|
|
50
|
+
// If `malloc` guarantees `need_align`, always prefer a raw allocation.
|
|
51
|
+
if (Alignment.compare(need_align, .lte, .of(c.max_align_t))) {
|
|
52
|
+
return .raw;
|
|
53
|
+
}
|
|
54
|
+
// Use `posix_memalign` if available. Otherwise, we must manually align the allocation.
|
|
55
|
+
return if (have_posix_memalign) .posix_memalign else .manual_align;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/// If `allocStrat(a) == .manual_align`, an allocation looks like this:
|
|
59
|
+
///
|
|
60
|
+
/// unaligned_ptr hdr_ptr aligned_ptr
|
|
61
|
+
/// v v v
|
|
62
|
+
/// +---------------+--------+--------------+
|
|
63
|
+
/// | padding | header | usable bytes |
|
|
64
|
+
/// +---------------+--------+--------------+
|
|
65
|
+
///
|
|
66
|
+
/// * `unaligned_ptr` is the raw return value of `malloc`.
|
|
67
|
+
/// * `aligned_ptr` is computed by aligning `unaligned_ptr` forward; it is what `alloc` returns.
|
|
68
|
+
/// * `hdr_ptr` points to a pointer-sized header directly before the usable space. This header
|
|
69
|
+
/// contains the value `unaligned_ptr`, so that we can pass it to `free` later. This is
|
|
70
|
+
/// necessary because the width of the padding is unknown.
|
|
71
|
+
///
|
|
72
|
+
/// This function accepts `aligned_ptr` and offsets it backwards to return `hdr_ptr`.
|
|
73
|
+
fn manualAlignHeader(aligned_ptr: [*]u8) *[*]u8 {
|
|
74
|
+
return @ptrCast(@alignCast(aligned_ptr - @sizeOf(usize)));
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
fn alloc(
|
|
78
|
+
_: *anyopaque,
|
|
79
|
+
len: usize,
|
|
80
|
+
alignment: Alignment,
|
|
81
|
+
return_address: usize,
|
|
82
|
+
) ?[*]u8 {
|
|
83
|
+
_ = return_address;
|
|
84
|
+
assert(len > 0);
|
|
85
|
+
switch (allocStrat(alignment)) {
|
|
86
|
+
.raw => {
|
|
87
|
+
// `std.c.max_align_t` isn't the whole story, because if `len` is smaller than
|
|
88
|
+
// every C type with alignment `max_align_t`, the allocation can be less-aligned.
|
|
89
|
+
// The implementation need only guarantee that any type of length `len` would be
|
|
90
|
+
// suitably aligned.
|
|
91
|
+
//
|
|
92
|
+
// For instance, if `len == 8` and `alignment == .@"16"`, then `malloc` may not
|
|
93
|
+
// fulfil this request, because there is necessarily no C type with 8-byte size
|
|
94
|
+
// but 16-byte alignment.
|
|
95
|
+
//
|
|
96
|
+
// In theory, the resulting rule here would be target-specific, but in practice,
|
|
97
|
+
// the smallest type with an alignment of `max_align_t` has the same size (it's
|
|
98
|
+
// usually `c_longdouble`), so we can just extend the allocation size up to the
|
|
99
|
+
// alignment of `max_align_t` if necessary.
|
|
100
|
+
const actual_len = @max(len, @alignOf(std.c.max_align_t));
|
|
101
|
+
const ptr = c.PyMem_Malloc(actual_len) orelse return null;
|
|
102
|
+
assert(alignment.check(@intFromPtr(ptr)));
|
|
103
|
+
return @ptrCast(ptr);
|
|
104
|
+
},
|
|
105
|
+
.posix_memalign => {
|
|
106
|
+
// The posix_memalign only accepts alignment values that are a
|
|
107
|
+
// multiple of the pointer size
|
|
108
|
+
const effective_alignment = @max(alignment.toByteUnits(), @sizeOf(usize));
|
|
109
|
+
var aligned_ptr: ?*anyopaque = undefined;
|
|
110
|
+
if (c.posix_memalign(&aligned_ptr, effective_alignment, len) != 0) {
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
113
|
+
assert(alignment.check(@intFromPtr(aligned_ptr)));
|
|
114
|
+
return @ptrCast(aligned_ptr);
|
|
115
|
+
},
|
|
116
|
+
.manual_align => {
|
|
117
|
+
// Overallocate to account for alignment padding and store the original pointer
|
|
118
|
+
// returned by `malloc` before the aligned address.
|
|
119
|
+
const padded_len = len + @sizeOf(usize) + alignment.toByteUnits() - 1;
|
|
120
|
+
const unaligned_ptr: [*]u8 = @ptrCast(c.PyMem_Malloc(padded_len) orelse return null);
|
|
121
|
+
const unaligned_addr = @intFromPtr(unaligned_ptr);
|
|
122
|
+
const aligned_addr = alignment.forward(unaligned_addr + @sizeOf(usize));
|
|
123
|
+
const aligned_ptr = unaligned_ptr + (aligned_addr - unaligned_addr);
|
|
124
|
+
manualAlignHeader(aligned_ptr).* = unaligned_ptr;
|
|
125
|
+
return aligned_ptr;
|
|
126
|
+
},
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
fn resize(
|
|
131
|
+
_: *anyopaque,
|
|
132
|
+
memory: []u8,
|
|
133
|
+
alignment: Alignment,
|
|
134
|
+
new_len: usize,
|
|
135
|
+
return_address: usize,
|
|
136
|
+
) bool {
|
|
137
|
+
_ = return_address;
|
|
138
|
+
assert(new_len > 0);
|
|
139
|
+
if (new_len <= memory.len) {
|
|
140
|
+
return true; // in-place shrink always works
|
|
141
|
+
}
|
|
142
|
+
const mallocSize = func: {
|
|
143
|
+
if (@TypeOf(std.c.malloc_size) != void) break :func std.c.malloc_size;
|
|
144
|
+
if (@TypeOf(std.c.malloc_usable_size) != void) break :func std.c.malloc_usable_size;
|
|
145
|
+
if (@TypeOf(std.c._msize) != void) break :func std.c._msize;
|
|
146
|
+
return false; // we don't know how much space is actually available
|
|
147
|
+
};
|
|
148
|
+
const usable_len: usize = switch (allocStrat(alignment)) {
|
|
149
|
+
.raw, .posix_memalign => mallocSize(memory.ptr),
|
|
150
|
+
.manual_align => usable_len: {
|
|
151
|
+
const unaligned_ptr = manualAlignHeader(memory.ptr).*;
|
|
152
|
+
const full_len = mallocSize(unaligned_ptr);
|
|
153
|
+
const padding = @intFromPtr(memory.ptr) - @intFromPtr(unaligned_ptr);
|
|
154
|
+
break :usable_len full_len - padding;
|
|
155
|
+
},
|
|
156
|
+
};
|
|
157
|
+
return new_len <= usable_len;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
fn remap(
|
|
161
|
+
ctx: *anyopaque,
|
|
162
|
+
memory: []u8,
|
|
163
|
+
alignment: Alignment,
|
|
164
|
+
new_len: usize,
|
|
165
|
+
return_address: usize,
|
|
166
|
+
) ?[*]u8 {
|
|
167
|
+
assert(new_len > 0);
|
|
168
|
+
// Prefer resizing in-place if possible, since `realloc` could be expensive even if legal.
|
|
169
|
+
if (resize(ctx, memory, alignment, new_len, return_address)) {
|
|
170
|
+
return memory.ptr;
|
|
171
|
+
}
|
|
172
|
+
switch (allocStrat(alignment)) {
|
|
173
|
+
.raw => {
|
|
174
|
+
// `malloc` and friends guarantee the required alignment, so we can try `realloc`.
|
|
175
|
+
// C only needs to respect `max_align_t` up to the allocation size due to object
|
|
176
|
+
// alignment rules. If necessary, extend the allocation size.
|
|
177
|
+
const actual_len = @max(new_len, @alignOf(std.c.max_align_t));
|
|
178
|
+
const new_ptr = c.PyMem_Realloc(memory.ptr, actual_len) orelse return null;
|
|
179
|
+
assert(alignment.check(@intFromPtr(new_ptr)));
|
|
180
|
+
return @ptrCast(new_ptr);
|
|
181
|
+
},
|
|
182
|
+
.posix_memalign, .manual_align => {
|
|
183
|
+
// `realloc` would potentially return a new allocation which does not respect
|
|
184
|
+
// the original alignment, so we can't do anything more.
|
|
185
|
+
return null;
|
|
186
|
+
},
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
fn free(
|
|
191
|
+
_: *anyopaque,
|
|
192
|
+
memory: []u8,
|
|
193
|
+
alignment: Alignment,
|
|
194
|
+
return_address: usize,
|
|
195
|
+
) void {
|
|
196
|
+
_ = return_address;
|
|
197
|
+
switch (allocStrat(alignment)) {
|
|
198
|
+
.raw, .posix_memalign => c.PyMem_Free(memory.ptr),
|
|
199
|
+
.manual_align => c.PyMem_Free(manualAlignHeader(memory.ptr).*),
|
|
200
|
+
}
|
|
201
|
+
}
|
|
@@ -3,14 +3,22 @@ const std = @import("std");
|
|
|
3
3
|
name: []const u8,
|
|
4
4
|
version: std.SemanticVersion,
|
|
5
5
|
zig_version: std.SemanticVersion,
|
|
6
|
-
build:
|
|
6
|
+
build: Build = .{},
|
|
7
|
+
install_requires: []const []const u8 = &.{},
|
|
8
|
+
entry_points: EntryPoints = .{},
|
|
9
|
+
|
|
10
|
+
pub const Build = struct {
|
|
7
11
|
args: []const []const u8 = &.{},
|
|
12
|
+
// extra build dependencies
|
|
8
13
|
requires: []const []const u8 = &.{},
|
|
14
|
+
// python packages to include
|
|
15
|
+
packages: []const []const u8 = &.{},
|
|
9
16
|
// pattern of files to copy to bdist after zig build
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
17
|
+
// defaults to "zig-out/lib/*"
|
|
18
|
+
copy_pattern: []const []const u8 = &.{
|
|
19
|
+
"zig-out/lib/*",
|
|
20
|
+
},
|
|
21
|
+
};
|
|
14
22
|
|
|
15
23
|
pub const EntryPoints = struct {
|
|
16
24
|
console_scripts: []const []const u8 = &.{},
|
zig-zon-0.2.4/build.zig
DELETED
|
@@ -1,75 +0,0 @@
|
|
|
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
|
-
|
|
6
|
-
pub fn build(b: *Build) void {
|
|
7
|
-
const target = b.standardTargetOptions(.{});
|
|
8
|
-
const optimize = b.standardOptimizeOption(.{});
|
|
9
|
-
|
|
10
|
-
// this target and section of our build is used at pip install time
|
|
11
|
-
const ext_install_step = b.step("bdist-wheel", "build python extension module");
|
|
12
|
-
|
|
13
|
-
// this generates a python sdist archive
|
|
14
|
-
const sdist = zig_python_sdist.createSdistStep(b, .{
|
|
15
|
-
.name = "zig-zon",
|
|
16
|
-
.version = zon.version,
|
|
17
|
-
.description = b.path("README.md"),
|
|
18
|
-
.build = .{
|
|
19
|
-
.args = &.{
|
|
20
|
-
ext_install_step.name,
|
|
21
|
-
b.fmt("-Doptimize={s}", .{@tagName(optimize)}),
|
|
22
|
-
},
|
|
23
|
-
},
|
|
24
|
-
.extra_pkg_info = @import("pkg-info.zon"),
|
|
25
|
-
.files = &.{
|
|
26
|
-
.{ .src = b.path("pkg-info.zon"), .dest = "pkg-info.zon" },
|
|
27
|
-
.{ .src = b.path("build.zig.zon"), .dest = "build.zig.zon" },
|
|
28
|
-
.{ .src = b.path("build.zig"), .dest = "build.zig" },
|
|
29
|
-
.{ .src = b.path("src/zig_zon.zig"), .dest = "src/zig_zon.zig" },
|
|
30
|
-
},
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
const sdistfile = b.addInstallFileWithDir(
|
|
34
|
-
sdist.getEmittedArchive(),
|
|
35
|
-
.{ .custom = "src" },
|
|
36
|
-
sdist.basename,
|
|
37
|
-
);
|
|
38
|
-
b.getInstallStep().dependOn(&sdistfile.step);
|
|
39
|
-
|
|
40
|
-
// we can use a python virtual environment inside
|
|
41
|
-
// the zig cache to test pip installation
|
|
42
|
-
const test_pip_install = zig_python_sdist.createVenvInstallTest(
|
|
43
|
-
b,
|
|
44
|
-
.{
|
|
45
|
-
.sdist = sdist.getEmittedArchive(),
|
|
46
|
-
.unittest_py = &.{b.path("src/test_zig_zon.py")},
|
|
47
|
-
.twine_check = true,
|
|
48
|
-
.no_clean = b.option(bool, "pip-no-clean", "dont cleanup pip temp dirs") orelse false,
|
|
49
|
-
},
|
|
50
|
-
);
|
|
51
|
-
b.step("test-pip-install", "").dependOn(test_pip_install.step);
|
|
52
|
-
|
|
53
|
-
{
|
|
54
|
-
const cpython = zig_python_sdist.createCPythonModule(b, .{
|
|
55
|
-
.target = target,
|
|
56
|
-
.version = zon.version,
|
|
57
|
-
.optimize = .ReleaseSmall,
|
|
58
|
-
});
|
|
59
|
-
const lib = b.addLibrary(.{
|
|
60
|
-
.name = "zig_zon",
|
|
61
|
-
.root_module = b.addModule("zig_zon", .{
|
|
62
|
-
.root_source_file = b.path("src/zig_zon.zig"),
|
|
63
|
-
.target = target,
|
|
64
|
-
.optimize = optimize,
|
|
65
|
-
.imports = &.{
|
|
66
|
-
.{ .name = "cpython", .module = cpython },
|
|
67
|
-
},
|
|
68
|
-
}),
|
|
69
|
-
.linkage = .dynamic,
|
|
70
|
-
});
|
|
71
|
-
const ext_install = zig_python_sdist.installExtLib(b, lib);
|
|
72
|
-
|
|
73
|
-
ext_install_step.dependOn(&ext_install.step);
|
|
74
|
-
}
|
|
75
|
-
}
|
zig-zon-0.2.4/setup.zig.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
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":[]}}
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|