/ setup.py
setup.py
1 #!/usr/bin/env python 2 3 import os 4 import shlex 5 import shutil 6 import subprocess 7 import sys 8 import sysconfig 9 import tarfile 10 11 from Cython.Build import cythonize 12 from setuptools import setup 13 from setuptools.command.build_ext import build_ext 14 from setuptools.extension import Extension 15 16 17 def _path_in_dir(relative_path): 18 return os.path.abspath(os.path.join(os.path.dirname(__file__), relative_path)) 19 20 def _dep_source_path(relative_path): 21 return os.path.join(_path_in_dir("deps"), relative_path) 22 23 def _dep_build_path(relative_path): 24 return os.path.join(_path_in_dir("_deps/build"), relative_path) 25 26 def _read(fname): 27 return open(os.path.join(os.path.dirname(__file__), fname)).read() 28 29 30 jq_lib_tarball_path = _dep_source_path("jq-1.7.1.tar.gz") 31 jq_lib_dir = _dep_build_path("jq-1.7.1") 32 33 class jq_with_deps_build_ext(build_ext): 34 def finalize_options(self): 35 build_ext.finalize_options(self) 36 if os.name == "nt": 37 self.compiler = "mingw32" 38 39 def run(self): 40 if not os.path.exists(_dep_build_path(".")): 41 os.makedirs(_dep_build_path(".")) 42 self._build_libjq() 43 build_ext.run(self) 44 45 def _build_libjq(self): 46 self._build_lib( 47 tarball_path=jq_lib_tarball_path, 48 lib_dir=jq_lib_dir, 49 commands=[ 50 ["./configure", "CFLAGS=-fPIC -pthread", "--disable-maintainer-mode", "--with-oniguruma=builtin"], 51 ["make"], 52 ]) 53 54 def _build_lib(self, tarball_path, lib_dir, commands): 55 self._extract_tarball( 56 tarball_path=tarball_path, 57 lib_dir=lib_dir, 58 ) 59 60 macosx_deployment_target = sysconfig.get_config_var("MACOSX_DEPLOYMENT_TARGET") 61 if macosx_deployment_target: 62 os.environ['MACOSX_DEPLOYMENT_TARGET'] = str(macosx_deployment_target) 63 64 def run_command(args): 65 print("Executing: %s" % ' '.join(args)) 66 67 if os.name == "nt": 68 command = ["msys2.cmd", "-c", " ".join(shlex.quote(arg) for arg in args)] 69 else: 70 command = args 71 72 subprocess.check_call(command, cwd=lib_dir) 73 74 for command in commands: 75 run_command(command) 76 77 def _extract_tarball(self, tarball_path, lib_dir): 78 if os.path.exists(lib_dir): 79 shutil.rmtree(lib_dir) 80 tarfile.open(tarball_path, "r:gz").extractall(_dep_build_path(".")) 81 82 83 use_system_libs = bool(os.environ.get("JQPY_USE_SYSTEM_LIBS")) 84 85 86 if use_system_libs: 87 jq_build_ext = build_ext 88 link_args_deps = ["-ljq", "-lonig"] 89 extra_objects = [] 90 else: 91 jq_build_ext = jq_with_deps_build_ext 92 link_args_deps = [] 93 extra_objects = [ 94 os.path.join(jq_lib_dir, ".libs/libjq.a"), 95 os.path.join(jq_lib_dir, "modules/oniguruma/src/.libs/libonig.a"), 96 ] 97 98 jq_extension = Extension( 99 "jq", 100 sources=["jq.pyx"], 101 # MS_WIN64 has to be set to successfully build when using MinGW for 64-bit 102 # Windows. See: https://github.com/cython/cython/issues/2670 103 define_macros=[("MS_WIN64" , 1)] if os.name == "nt" and sys.maxsize > 2**32 else None, 104 include_dirs=[os.path.join(jq_lib_dir, "src")], 105 extra_link_args=["-lm"] + (["-Wl,-Bstatic", "-lpthread", "-lshlwapi", "-static-libgcc"] if os.name == 'nt' else []) + link_args_deps, 106 extra_objects=extra_objects, 107 ) 108 109 setup( 110 name='jq', 111 version='1.8.0', 112 description='jq is a lightweight and flexible JSON processor.', 113 long_description=_read("README.rst"), 114 author='Michael Williamson', 115 url='https://github.com/mwilliamson/jq.py', 116 python_requires='>=3.7', 117 license='BSD 2-Clause', 118 ext_modules = cythonize([jq_extension]), 119 cmdclass={"build_ext": jq_build_ext}, 120 classifiers=[ 121 'Development Status :: 5 - Production/Stable', 122 'Intended Audience :: Developers', 123 'License :: OSI Approved :: BSD License', 124 'Programming Language :: Python', 125 'Programming Language :: Python :: 3', 126 'Programming Language :: Python :: 3.7', 127 'Programming Language :: Python :: 3.8', 128 'Programming Language :: Python :: 3.9', 129 'Programming Language :: Python :: 3.10', 130 'Programming Language :: Python :: 3.11', 131 'Programming Language :: Python :: 3.12', 132 'Programming Language :: Python :: 3.13', 133 'Programming Language :: Python :: Implementation :: PyPy', 134 'Programming Language :: Python :: Implementation :: CPython', 135 ], 136 ) 137