mirror of
https://github.com/capnproto/pycapnp.git
synced 2025-03-04 00:14:45 +01:00
Add custom build backend to support build args (#328)
This implements a custom build backend, inspired by the [solution used by Pillow.](https://github.com/python-pillow/Pillow/pull/7171) install-option is deprecated and was removed with pip 23.1. The comonly accepted solution seems to be to define a custom build backend for now https://github.com/pypa/setuptools/issues/2491#issuecomment-1589764230 This commit changes the usage from `--install-option` to `--config-settings`.
This commit is contained in:
parent
db26d60283
commit
d48ffea939
7 changed files with 77 additions and 50 deletions
37
README.md
37
README.md
|
@ -38,25 +38,27 @@ cd pycapnp
|
|||
pip install .
|
||||
```
|
||||
|
||||
By default, the setup script will automatically use the locally installed Cap'n Proto.
|
||||
If Cap'n Proto is not installed, it will bundle and build the matching Cap'n Proto library.
|
||||
|
||||
To enforce bundling, the Cap'n Proto library:
|
||||
|
||||
```bash
|
||||
pip install . -C force-bundled-libcapnp=True
|
||||
```
|
||||
|
||||
If you wish to install using the latest upstream C++ Cap'n Proto:
|
||||
|
||||
```bash
|
||||
pip install \
|
||||
--install-option "--libcapnp-url" \
|
||||
--install-option "https://github.com/capnproto/capnproto/archive/master.tar.gz" \
|
||||
--install-option "--force-bundled-libcapnp" .
|
||||
pip install . \
|
||||
-C force-bundled-libcapnp=True \
|
||||
-C libcapnp-url="https://github.com/capnproto/capnproto/archive/master.tar.gz"
|
||||
```
|
||||
|
||||
To force bundled python:
|
||||
To enforce using the installed Cap'n Proto from the system:
|
||||
|
||||
```bash
|
||||
pip install --install-option "--force-bundled-libcapnp" .
|
||||
```
|
||||
|
||||
Slightly more prompt error messages using distutils rather than pip.
|
||||
|
||||
```bash
|
||||
python setup.py install --force-bundled-libcapnp
|
||||
pip install . -C force-system-libcapnp=True
|
||||
```
|
||||
|
||||
The bundling system isn't that smart so it might be necessary to clean up the bundled build when changing versions:
|
||||
|
@ -92,19 +94,12 @@ pipenv run pytest
|
|||
|
||||
### Binary Packages
|
||||
|
||||
Building a dumb binary distribution:
|
||||
Building a Python wheel distributiion
|
||||
|
||||
```bash
|
||||
python setup.py bdist_dumb
|
||||
pip wheel .
|
||||
```
|
||||
|
||||
Building a Python wheel distributiion:
|
||||
|
||||
```bash
|
||||
python setup.py bdist_wheel
|
||||
```
|
||||
|
||||
|
||||
## Documentation/Example
|
||||
|
||||
There is some basic documentation [here](http://capnproto.github.io/pycapnp/).
|
||||
|
|
31
_custom_build/backend.py
Normal file
31
_custom_build/backend.py
Normal file
|
@ -0,0 +1,31 @@
|
|||
import sys
|
||||
|
||||
from setuptools.build_meta import * # noqa: F401, F403
|
||||
from setuptools.build_meta import build_wheel
|
||||
|
||||
backend_class = build_wheel.__self__.__class__
|
||||
|
||||
|
||||
class _CustomBuildMetaBackend(backend_class):
|
||||
def run_setup(self, setup_script="setup.py"):
|
||||
if self.config_settings:
|
||||
flags = []
|
||||
if self.config_settings.get("force-bundled-libcapnp"):
|
||||
flags.append("--force-bundled-libcapnp")
|
||||
if self.config_settings.get("force-system-libcapnp"):
|
||||
flags.append("--force-system-libcapnp")
|
||||
if self.config_settings.get("libcapnp-url"):
|
||||
flags.append("--libcapnp-url")
|
||||
flags.append(self.config_settings["libcapnp-url"])
|
||||
if flags:
|
||||
sys.argv = sys.argv[:1] + ["build_ext"] + flags + sys.argv[1:]
|
||||
return super().run_setup(setup_script)
|
||||
|
||||
def build_wheel(
|
||||
self, wheel_directory, config_settings=None, metadata_directory=None
|
||||
):
|
||||
self.config_settings = config_settings
|
||||
return super().build_wheel(wheel_directory, config_settings, metadata_directory)
|
||||
|
||||
|
||||
build_wheel = _CustomBuildMetaBackend().build_wheel
|
|
@ -15,8 +15,8 @@ To force rebuilding the pip package from source (you'll need requirments.txt or
|
|||
|
||||
To force bundling libcapnp (or force system libcapnp), just in case setup.py isn't doing the right thing::
|
||||
|
||||
pip install --no-binary :all: --install-option "--force-bundled-libcapnp"
|
||||
pip install --no-binary :all: --install-option "--force-system-libcapnp"
|
||||
pip install --no-binary :all: -C force-bundled-libcapnp=True
|
||||
pip install --no-binary :all: -C force-system-libcapnp=True
|
||||
|
||||
If you're using an older Linux distro (e.g. CentOS 6) you many need to set `LDFLAGS="-Wl,--no-as-needed -lrt"`::
|
||||
|
||||
|
@ -24,7 +24,7 @@ If you're using an older Linux distro (e.g. CentOS 6) you many need to set `LDFL
|
|||
|
||||
It's also possible to specify the libcapnp url when bundling (this may not work, there be dragons)::
|
||||
|
||||
pip install --no-binary :all: --install-option "--force-bundled-libcapnp" --install-option "--libcapnp-url" --install-option "https://github.com/capnproto/capnproto/archive/master.tar.gz"
|
||||
pip install --no-binary :all: -C force-bundled-libcapnp=True -C libcapnp-url="https://github.com/capnproto/capnproto/archive/master.tar.gz"
|
||||
|
||||
From Source
|
||||
-----------
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
[build-system]
|
||||
requires = ["setuptools", "wheel", "pkgconfig", "cython<3"]
|
||||
build-backend = "backend"
|
||||
backend-path = ["_custom_build"]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
asyncio_mode = "auto"
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
[metadata]
|
||||
description-file = README.md
|
||||
description_file = README.md
|
||||
license_files = LICENSE.md
|
||||
|
|
46
setup.py
46
setup.py
|
@ -15,10 +15,12 @@ from distutils.command.clean import clean as _clean
|
|||
|
||||
from setuptools import setup, Extension
|
||||
|
||||
_this_dir = os.path.dirname(__file__)
|
||||
sys.path.insert(1, _this_dir)
|
||||
|
||||
from buildutils.build import build_libcapnp
|
||||
from buildutils.bundle import fetch_libcapnp
|
||||
|
||||
_this_dir = os.path.dirname(__file__)
|
||||
|
||||
MAJOR = 1
|
||||
MINOR = 3
|
||||
|
@ -85,26 +87,6 @@ class clean(_clean):
|
|||
shutil.rmtree(x, ignore_errors=True)
|
||||
|
||||
|
||||
# hack to parse commandline arguments
|
||||
force_bundled_libcapnp = "--force-bundled-libcapnp" in sys.argv
|
||||
if force_bundled_libcapnp:
|
||||
sys.argv.remove("--force-bundled-libcapnp")
|
||||
force_system_libcapnp = "--force-system-libcapnp" in sys.argv
|
||||
if force_system_libcapnp:
|
||||
sys.argv.remove("--force-system-libcapnp")
|
||||
force_cython = "--force-cython" in sys.argv
|
||||
if force_cython:
|
||||
sys.argv.remove("--force-cython")
|
||||
# Always use cython, ignoring option
|
||||
libcapnp_url = None
|
||||
try:
|
||||
libcapnp_url_index = sys.argv.index("--libcapnp-url")
|
||||
libcapnp_url = sys.argv[libcapnp_url_index + 1]
|
||||
sys.argv.remove("--libcapnp-url")
|
||||
sys.argv.remove(libcapnp_url)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
from Cython.Distutils import build_ext as build_ext_c # noqa: E402
|
||||
|
||||
|
||||
|
@ -113,13 +95,29 @@ class build_libcapnp_ext(build_ext_c):
|
|||
Build capnproto library
|
||||
"""
|
||||
|
||||
user_options = build_ext_c.user_options + [
|
||||
("force-bundled-libcapnp", None, "Bundle capnp library into the installer"),
|
||||
("force-system-libcapnp", None, "Use system capnp library"),
|
||||
("libcapnp-url=", "u", "URL to download libcapnp from (only if bundled)"),
|
||||
]
|
||||
|
||||
def initialize_options(self):
|
||||
build_ext_c.initialize_options(self)
|
||||
self.force_bundled_libcapnp = None
|
||||
self.force_system_libcapnp = None
|
||||
self.libcapnp_url = None
|
||||
|
||||
def finalize_options(self):
|
||||
# print('The custom option for install is ', self.custom_option)
|
||||
build_ext_c.finalize_options(self)
|
||||
|
||||
def build_extension(self, ext):
|
||||
build_ext_c.build_extension(self, ext)
|
||||
|
||||
def run(self): # noqa: C901
|
||||
if force_bundled_libcapnp:
|
||||
if self.force_bundled_libcapnp:
|
||||
need_build = True
|
||||
elif force_system_libcapnp:
|
||||
elif self.force_system_libcapnp:
|
||||
need_build = False
|
||||
else:
|
||||
# Try to use capnp executable to find include and lib path
|
||||
|
@ -167,7 +165,7 @@ class build_libcapnp_ext(build_ext_c):
|
|||
|
||||
if not os.path.exists(capnp_bin):
|
||||
# Not built, fetch and build
|
||||
fetch_libcapnp(bundle_dir, libcapnp_url)
|
||||
fetch_libcapnp(bundle_dir, self.libcapnp_url)
|
||||
build_libcapnp(bundle_dir, build_dir)
|
||||
else:
|
||||
print("capnproto already built at {}".format(build_dir))
|
||||
|
|
3
tox.ini
3
tox.ini
|
@ -7,10 +7,11 @@ deps=
|
|||
pkgconfig
|
||||
Jinja2
|
||||
pytest
|
||||
pytest-asyncio
|
||||
cython<3
|
||||
|
||||
commands =
|
||||
python setup.py install
|
||||
pip install .
|
||||
py.test {posargs}
|
||||
|
||||
setenv =
|
||||
|
|
Loading…
Add table
Reference in a new issue