forked from isagalaev/ijson
-
Notifications
You must be signed in to change notification settings - Fork 51
/
setup.py
130 lines (115 loc) · 4.59 KB
/
setup.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
try:
from distutils import ccompiler
from distutils import sysconfig
except ImportError:
from setuptools._distutils import ccompiler
from setuptools._distutils import sysconfig
import glob
import os
import platform
import shutil
import tempfile
from setuptools import setup, find_packages, Extension
def get_ijson_version():
"""Get version from code without fully importing it"""
_globals = {}
with open(os.path.join('src', 'ijson', 'version.py')) as f:
code = f.read()
exec(code, _globals)
return _globals['__version__']
setupArgs = dict(
name = 'ijson',
version = get_ijson_version(),
author = 'Rodrigo Tobar, Ivan Sagalaev',
author_email = 'rtobar@icrar.org, maniac@softwaremaniacs.org',
url = 'https://github.com/ICRAR/ijson',
license = 'BSD',
description = 'Iterative JSON parser with standard Python iterator interfaces',
long_description = open('README.rst').read(),
long_description_content_type = 'text/x-rst',
classifiers = [
'Development Status :: 5 - Production/Stable',
'License :: OSI Approved :: BSD License',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
'Programming Language :: Python :: 3.11',
'Programming Language :: Python :: 3.12',
'Programming Language :: Python :: 3.13',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Topic :: Software Development :: Libraries :: Python Modules',
],
packages = find_packages(where="src"),
package_dir={"": "src"},
)
# Check if the yajl library + headers are present
# We don't use compiler.has_function because it leaves a lot of files behind
# without properly cleaning up
def yajl_present():
compiler = ccompiler.new_compiler(verbose=1)
sysconfig.customize_compiler(compiler) # CC, CFLAGS, LDFLAGS, etc
yajl_version_test_file = tempfile.NamedTemporaryFile(suffix=".c", prefix="yajl_version", delete=False)
try:
yajl_version_test_file.write(b'''
#include <yajl/yajl_version.h>
int main(int args, char **argv)
{
#if YAJL_MAJOR != 2
fail to compile
#else
yajl_version();
#endif
return 0;
}
''')
yajl_version_test_file.close()
try:
objs = compiler.compile([yajl_version_test_file.name])
compiler.link_shared_lib(objs, 'a', libraries=["yajl"])
return True
finally:
os.remove(compiler.library_filename('a', lib_type='shared'))
for obj in objs:
os.remove(obj)
except:
return False
finally:
os.remove(yajl_version_test_file.name)
def patch_yajl_sources():
"""Make yajl sources ready for direct compilation against them"""
# cp cextern/yajl -R $yajl_sources_copy
# mkdir $yajl_sources_copy/yajl
# cp $yajl_sources_copy/src/api/*.h $yajl_sources_copy/yajl
patched_sources = os.path.join(tempfile.mkdtemp(), 'yajl')
shutil.copytree(os.path.join('cextern', 'yajl'), patched_sources)
headers_original = os.path.join(patched_sources, 'src', 'api')
headers_copy = os.path.join(patched_sources, 'yajl')
shutil.copytree(headers_original, headers_copy)
return patched_sources
extra_sources = []
extra_include_dirs = []
libs = ['yajl']
embed_yajl = os.environ.get('IJSON_EMBED_YAJL', None) == '1'
if not embed_yajl:
have_yajl = yajl_present()
else:
yajl_sources = patch_yajl_sources()
extra_sources = sorted(glob.glob(os.path.join(yajl_sources, 'src', '*.c')))
extra_sources.remove(os.path.join(yajl_sources, 'src', 'yajl_version.c'))
extra_include_dirs = [yajl_sources, os.path.join(yajl_sources, 'src')]
libs = []
build_yajl_default = '1' if embed_yajl or have_yajl else '0'
build_yajl = os.environ.get('IJSON_BUILD_YAJL2C', build_yajl_default) == '1'
if build_yajl:
yajl_ext = Extension('ijson.backends._yajl2',
language='c',
sources=sorted(glob.glob('src/ijson/backends/ext/_yajl2/*.c')) + extra_sources,
include_dirs=['src/ijson/backends/ext/_yajl2'] + extra_include_dirs,
libraries=libs,
depends=glob.glob('src/ijson/backends/ext/_yajl2/*.h'))
setupArgs['ext_modules'] = [yajl_ext]
setup(**setupArgs)