Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
numba
GitHub Repository: numba/llvmlite
Path: blob/main/setup.py
1154 views
1
from setuptools import setup, Command, Extension
2
from setuptools.command.build import build
3
from setuptools.command.build_ext import build_ext
4
from setuptools.command.install import install
5
from shutil import rmtree
6
from subprocess import run
7
import logging
8
import os
9
import sys
10
11
import versioneer
12
13
logger = logging.getLogger(__name__)
14
15
16
try:
17
from wheel.bdist_wheel import bdist_wheel
18
except ImportError:
19
bdist_wheel = None
20
21
min_python_version = (3, 10)
22
23
24
def _version_info_str(int_tuple):
25
return ".".join(map(str, int_tuple))
26
27
28
def _guard_py_ver():
29
current_python_version = sys.version_info[:3]
30
min_py = _version_info_str(min_python_version)
31
cur_py = _version_info_str(current_python_version)
32
33
if not min_python_version <= current_python_version:
34
msg = ('Cannot install on Python version {}; only versions >={} '
35
'are supported.')
36
raise RuntimeError(msg.format(cur_py, min_py))
37
38
39
_guard_py_ver()
40
41
versioneer.VCS = 'git'
42
versioneer.versionfile_source = 'llvmlite/_version.py'
43
versioneer.versionfile_build = 'llvmlite/_version.py'
44
versioneer.tag_prefix = 'v' # tags are like v1.2.0
45
versioneer.parentdir_prefix = 'llvmlite-' # dirname like 'myproject-1.2.0'
46
47
48
here_dir = os.path.dirname(os.path.abspath(__file__))
49
50
cmdclass = versioneer.get_cmdclass()
51
build = cmdclass.get('build', build)
52
build_ext = cmdclass.get('build_ext', build_ext)
53
54
55
def build_library_files():
56
cmd = [sys.executable, os.path.join(here_dir, 'ffi', 'build.py')]
57
# Turn on -fPIC for building on Linux, BSD, OS X, and GNU platforms
58
plt = sys.platform
59
if 'linux' in plt or 'bsd' in plt or 'darwin' in plt or 'gnu' in plt:
60
os.environ['CXXFLAGS'] = os.environ.get('CXXFLAGS', '') + ' -fPIC'
61
62
run(cmd, check=True)
63
64
65
class LlvmliteBuild(build):
66
def finalize_options(self):
67
build.finalize_options(self)
68
# The build isn't platform-independent
69
if self.build_lib == self.build_purelib:
70
self.build_lib = self.build_platlib
71
72
def get_sub_commands(self):
73
# Force "build_ext" invocation.
74
commands = build.get_sub_commands(self)
75
for c in commands:
76
if c == 'build_ext':
77
return commands
78
return ['build_ext'] + commands
79
80
81
class LlvmliteBuildExt(build_ext):
82
83
def run(self):
84
build_ext.run(self)
85
build_library_files()
86
# HACK: this makes sure the library file (which is large) is only
87
# included in binary builds, not source builds.
88
from llvmlite.utils import get_library_files
89
self.distribution.package_data = {
90
"llvmlite.binding": get_library_files(),
91
}
92
93
94
class LlvmliteInstall(install):
95
# Ensure install see the libllvmlite shared library
96
# This seems to only be necessary on OSX.
97
def run(self):
98
from llvmlite.utils import get_library_files
99
self.distribution.package_data = {
100
"llvmlite.binding": get_library_files(),
101
}
102
install.run(self)
103
104
def finalize_options(self):
105
install.finalize_options(self)
106
# Force use of "platlib" dir for auditwheel to recognize this
107
# is a non-pure build
108
self.install_libbase = self.install_platlib
109
self.install_lib = self.install_platlib
110
111
112
class LlvmliteClean(Command):
113
"""Custom clean command to tidy up the project root."""
114
# Required to implement but there don't appear to be any relevant flags
115
# for this command, so do nothing
116
def initialize_options(self) -> None:
117
pass
118
119
# Required to implement but there don't appear to be any relevant flags
120
# for this command, so do nothing
121
def finalize_options(self) -> None:
122
pass
123
124
def run(self):
125
build_dir = os.path.join(here_dir, 'build')
126
if os.path.exists(build_dir):
127
self._rm_tree(build_dir)
128
path = os.path.join(here_dir, 'llvmlite.egg-info')
129
if os.path.isdir(path):
130
self._rm_tree(path)
131
ffi_build = os.path.join(here_dir, 'ffi', 'build')
132
if os.path.exists(ffi_build):
133
self._rm_tree(ffi_build)
134
# restrict rm_walk here to llvmlite dir to avoid touching other
135
# subdirectories; build/ and ffi/build/ are
136
# already removed above via _rm_tree.
137
self._rm_walk(os.path.join(here_dir, 'llvmlite'))
138
139
def _rm_walk(self, root):
140
for path, _, files in os.walk(root):
141
if any(p.startswith('.') for p in path.split(os.path.sep)):
142
# Skip hidden directories like the git folder right away
143
continue
144
if path.endswith('__pycache__'):
145
self._rm_tree(path)
146
else:
147
for fname in files:
148
suffixes = ('.pyc', '.o', '.so', '.dylib', '.dll')
149
if any(fname.endswith(suffix) for suffix in suffixes):
150
fpath = os.path.join(path, fname)
151
os.remove(fpath)
152
logger.info("removing '%s'", fpath)
153
154
def _rm_tree(self, path):
155
logger.info("removing '%s' (and everything underneath it)", path)
156
rmtree(path)
157
158
159
cmdclass.update({'build': LlvmliteBuild,
160
'build_ext': LlvmliteBuildExt,
161
'install': LlvmliteInstall,
162
'clean': LlvmliteClean,
163
})
164
165
if bdist_wheel is not None:
166
class LLvmliteBDistWheel(bdist_wheel):
167
def run(self):
168
# Ensure the binding file exist when running wheel build
169
from llvmlite.utils import get_library_files
170
build_library_files()
171
self.distribution.package_data.update({
172
"llvmlite.binding": get_library_files(),
173
})
174
# Run wheel build command
175
bdist_wheel.run(self)
176
177
def finalize_options(self):
178
bdist_wheel.finalize_options(self)
179
# The build isn't platform-independent
180
self.root_is_pure = False
181
182
cmdclass.update({'bdist_wheel': LLvmliteBDistWheel})
183
184
# A stub C-extension to make bdist_wheel build an arch dependent build
185
ext_stub = Extension(name="llvmlite.binding._stub",
186
sources=["llvmlite/binding/_stub.c"])
187
188
189
packages = ['llvmlite',
190
'llvmlite.binding',
191
'llvmlite.ir',
192
'llvmlite.tests',
193
]
194
195
196
with open('README.rst') as f:
197
long_description = f.read()
198
199
200
setup(name='llvmlite',
201
description="lightweight wrapper around basic LLVM functionality",
202
version=versioneer.get_version(),
203
classifiers=[
204
"Development Status :: 4 - Beta",
205
"Intended Audience :: Developers",
206
"Operating System :: OS Independent",
207
"Programming Language :: Python",
208
"Programming Language :: Python :: 3",
209
"Programming Language :: Python :: 3.10",
210
"Programming Language :: Python :: 3.11",
211
"Programming Language :: Python :: 3.12",
212
"Programming Language :: Python :: 3.13",
213
"Programming Language :: Python :: 3.14",
214
"Topic :: Software Development :: Code Generators",
215
"Topic :: Software Development :: Compilers",
216
],
217
# Include the separately-compiled shared library
218
url="http://llvmlite.readthedocs.io",
219
project_urls={
220
"Source": "https://github.com/numba/llvmlite",
221
},
222
packages=packages,
223
license_expression="BSD-2-Clause AND Apache-2.0 WITH LLVM-exception",
224
license_files=['LICENSE', 'LICENSE.thirdparty'],
225
cmdclass=cmdclass,
226
long_description=long_description,
227
python_requires=">={}".format(_version_info_str(min_python_version)),
228
)
229
230