The repository is on sourceforge (sorry, I am a Mercurial user and don’t want to go back to git, although I might move to jujutsu): ruamel.yaml.clibz / Code / [a472ef]
The setup.py for that bunch of C files is below and should be useable as a template, at least for any stand-alone extension for Python written in C. The conditional setup_requires was necessary because otherwise these are downloaded/installed when just creating the source tarball as well.
There were no really big challenges, just a bunch of gruntwork, testing and adapting, and then having the guts to make the change and upload. I have had several Zig based Python extensions made for non-open source projects since 2020 that used setuptools-zig, and its readme has included examples for C, C+Zig and Zig only code for a long time. The ruamel.yaml.clib C code required adding a few parameters to zig build-lib:
zig build-lib -dynamic -fallow-shlib-undefined -femit-bin=/absolute/path/to/build/lib.linux-x86_64-cpython-314/_ruamel_yaml_ziglib.
cpython-314-x86_64-linux-gnu.so -lc -I /opt/util/tmp_yamlziglib/include -I /opt/python/3.14.0/include/python3.14 -O R
eleaseFast _ruamel_yaml_ziglib.c api.c writer.c dumper.c loader.c reader.c scanner.c parser.c emitter.c
and e.g. building on Linux alpine aarch64 (on my unifi firewall) I found out that installing ziglang gets you a zig file with 666 permission (if installed as build-requirement) wheras if you do a “normal” pip/uv install you get the execute permissions set (I easily wasted half a day on figuring that one out).
Testing is still a challenge as this is a vector with multiple dimensions: Python (6 versions); free-threaded (2, fortunately not for all Python versions supported (yet)); processor (2 that I tested, there are more); platforms (3 that I tested: Windows, macOS, Linux); architecture bit width (2: 32 and 64bit), libc/musl compatiblity (2). I did not test all the possible combinations, in that space but I covered each variant in each dimension at least once. And Linux & macOS (both 64bit) almost complete.
This is C compiling with zig, so Zig being at pre-1.0 was never a problem ( I had to make minor adjustments to the zig examples for setuptools-zig overtime of course, because of that).
import sys
from setuptools import Extension
from setuptools import setup
base = 'https://sourceforge.net/p/ruamel-yaml-clibz/'
setup(
name='ruamel.yaml.clibz',
version='0.3.4',
python_requires='>=3.9',
build_zig=True,
author='Anthon van der Neut',
author_email='a.van.der.neut@ruamel.eu',
description='C version of reader, parser and emitter for ruamel.yaml, compiled with Zig,'
' derived from libyaml',
long_description=open("README.md").read(),
long_description_content_type="text/markdown",
project_urls=dict(
Home=base,
Source=f'{base}code/ci/default/tree/',
Tracker=f'{base}tickets/',
Documentation='https://yaml.dev/doc/ruamel.yaml.clibz',
),
license='MIT',
ext_modules=[Extension(
name='_ruamel_yaml_clibz',
sources=[
'_ruamel_yaml_clibz.c',
'api.c',
'writer.c',
'dumper.c',
'loader.c',
'reader.c',
'scanner.c',
'parser.c',
'emitter.c',
],
extra_compile_args=[
# '-O', 'Debug',
],
)],
setup_requires=[] if 'egg_info' in sys.argv else ['setuptools-zig>=0.5.1', 'ziglang<0.16'],
)