From 081a2877b827f44801aa93ee491e4a313c278f43 Mon Sep 17 00:00:00 2001 From: Fantix King Date: Sat, 25 Jun 2022 14:44:02 -0400 Subject: [PATCH] Fix setup.py build and clean --- Makefile | 16 +++-- README.md | 3 +- README.zh.md | 3 +- setup.py | 166 +++++++++++++++++++++++++++++++++++---------------- 4 files changed, 130 insertions(+), 58 deletions(-) diff --git a/Makefile b/Makefile index f516bf4..49e323c 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,23 @@ -.PHONY: build dev clean +.PHONY: dist dev build clean .DEFAULT_GOAL := dev -build: +# Make distribution tarballs +dist: pip install -U build python -m build +# Incrementally build for development dev: - pip install -Ue . + KLOOP_DEBUG=1 python setup.py develop +# Always build for development +build: + KLOOP_FORCE=1 KLOOP_DEBUG=1 python setup.py develop + + +# Clean up everything including the Rust build cache clean: - git clean -Xfd -e "!/*.code-workspace" -e "!/*.vscode" -e "!/*.idea" -e "!/*.python-version" + python setup.py clean --all diff --git a/README.md b/README.md index 1cc842b..8c561f5 100644 --- a/README.md +++ b/README.md @@ -68,5 +68,6 @@ sudo apt install gcc libssl-dev python3-dev python3.10-venv curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh python3 -m venv path/to/env source path/to/env/bin/activate -pip install -e path/to/kloop +pip install cython +KLOOP_DEBUG=1 python setup.py develop # or just run `make` ``` diff --git a/README.zh.md b/README.zh.md index 837ce76..2a2572f 100644 --- a/README.zh.md +++ b/README.zh.md @@ -62,5 +62,6 @@ sudo apt install gcc libssl-dev python3-dev python3.10-venv curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh python3 -m venv path/to/env source path/to/env/bin/activate -pip install -e path/to/kloop +pip install cython +KLOOP_DEBUG=1 python setup.py develop # 或者直接执行 `make` ``` diff --git a/setup.py b/setup.py index 8e3bd58..8a73436 100644 --- a/setup.py +++ b/setup.py @@ -9,74 +9,136 @@ # See the Mulan PSL v2 for more details. +import os import subprocess import sysconfig from setuptools import setup + from Cython.Build import cythonize -from Cython.Distutils import Extension from Cython.Distutils import build_ext - - -DEBUG = True -RESOLVER_LIB = ( - f"resolver/target/{'debug' if DEBUG else 'release'}/libkloop_resolver.a" -) +from Cython.Distutils import Extension +from distutils import dir_util +from distutils import log +from distutils.command.clean import clean class build_ext_with_resolver(build_ext): - def run(self): - subprocess.check_call( - ["cargo", "build"] + [] if DEBUG else ["-r"], - cwd="resolver", + def finalize_options(self): + self.set_undefined_options( + "build", + ("debug", "debug"), + ("force", "force"), ) + if self.debug is None: + self.debug = os.getenv("KLOOP_DEBUG", "0") == "1" + if self.force is None: + self.force = os.getenv("KLOOP_FORCE", "0") == "1" + + for ext in self.distribution.ext_modules: + if self.debug: + if "-O0" not in ext.extra_compile_args: + ext.extra_compile_args.append("-O0") + if ext.name == "kloop.loop": + resolver = ( + f"resolver/target/{'debug' if self.debug else 'release'}" + f"/libkloop_resolver.a" + ) + if resolver not in ext.extra_link_args: + ext.extra_link_args.append(resolver) + if resolver not in ext.depends: + ext.depends.append(resolver) + + self.distribution.ext_modules = cythonize( + self.distribution.ext_modules, language_level="3", + ) + + super().finalize_options() + + def run(self): + if self.force: + cmd = ["cargo", "clean", "-p", "resolver"] + if not self.debug: + cmd.append("-r") + self.announce(f"Running: {cmd}", log.INFO) + subprocess.check_call(cmd, cwd="resolver") + + cmd = ["cargo", "build"] + if not self.debug: + cmd.append("-r") + self.announce(f"Running: {cmd}", log.INFO) + subprocess.check_call(cmd, cwd="resolver") super().run() +class clean_with_resolver(clean): + def run(self): + super().run() + for d in self.distribution.package_dir.values(): + self._clean_dir(d) + cmd = ["cargo", "clean"] + if not self.all: + cmd.extend(["-p", "resolver"]) + self.announce(f"Running: {cmd}", log.INFO) + if not self.dry_run: + subprocess.check_call(cmd, cwd="resolver") + + def _clean_dir(self, path): + for f in os.listdir(path): + name, ext = os.path.splitext(f) + real_f = os.path.join(path, f) + is_dir = os.path.isdir(real_f) and not os.path.islink(real_f) + if name == "__pycache__" or ext in {".egg-info", ".so", ".c"}: + if is_dir: + dir_util.remove_tree(real_f, dry_run=self.dry_run) + else: + self.announce(f"removing {real_f!r}", log.INFO) + if not self.dry_run: + os.remove(real_f) + elif is_dir: + self._clean_dir(real_f) + + setup( cmdclass={ "build_ext": build_ext_with_resolver, + "clean": clean_with_resolver, }, - ext_modules=cythonize( - [ - Extension( - "kloop.loop", - ["src/kloop/loop.pyx"], - extra_link_args=[RESOLVER_LIB], - depends=[RESOLVER_LIB], + ext_modules=[ + Extension( + "kloop.loop", + ["src/kloop/loop.pyx"], + ), + Extension( + "kloop.tls", + ["src/kloop/tls.pyx"], + libraries=[ + lib.strip().removeprefix("-l") + for lib in sysconfig.get_config_var("OPENSSL_LIBS").split() + ], + include_dirs=[ + d.strip().removeprefix("-I") + for d in sysconfig.get_config_var( + "OPENSSL_INCLUDES" + ).split() + ], + library_dirs=[ + d.strip().removeprefix("-L") + for d in sysconfig.get_config_var( + "OPENSSL_LDFLAGS" + ).split() + if d.strip().startswith("-L") + ], + extra_link_args=[ + d.strip() + for d in sysconfig.get_config_var( + "OPENSSL_LDFLAGS" + ).split() + if not d.strip().startswith("-L") + ], + runtime_library_dirs=(lambda x: [x] if x else [])( + sysconfig.get_config_var("OPENSSL_RPATH") ), - Extension( - "kloop.tls", - ["src/kloop/tls.pyx"], - libraries=[ - lib.strip().removeprefix("-l") - for lib in sysconfig.get_config_var("OPENSSL_LIBS").split() - ], - include_dirs=[ - d.strip().removeprefix("-I") - for d in sysconfig.get_config_var( - "OPENSSL_INCLUDES" - ).split() - ], - library_dirs=[ - d.strip().removeprefix("-L") - for d in sysconfig.get_config_var( - "OPENSSL_LDFLAGS" - ).split() - if d.strip().startswith("-L") - ], - extra_link_args=[ - d.strip() - for d in sysconfig.get_config_var( - "OPENSSL_LDFLAGS" - ).split() - if not d.strip().startswith("-L") - ], - runtime_library_dirs=(lambda x: [x] if x else [])( - sysconfig.get_config_var("OPENSSL_RPATH") - ), - ), - ], - language_level="3", - ), + ), + ], )