2014-07-05 22:49:34 +04:00
|
|
|
#!/usr/bin/env python
|
2015-12-13 13:49:17 +03:00
|
|
|
from __future__ import division, print_function
|
|
|
|
import os
|
2015-03-09 08:46:35 +03:00
|
|
|
import shutil
|
2015-12-13 13:49:17 +03:00
|
|
|
import subprocess
|
2014-07-05 22:49:34 +04:00
|
|
|
import sys
|
2015-10-13 01:31:59 +03:00
|
|
|
from distutils.command.build_ext import build_ext
|
2015-12-13 13:49:17 +03:00
|
|
|
from distutils.sysconfig import get_python_inc
|
2015-10-13 01:31:59 +03:00
|
|
|
|
2015-12-13 13:49:17 +03:00
|
|
|
try:
|
|
|
|
from setuptools import Extension, setup
|
|
|
|
except ImportError:
|
|
|
|
from distutils.core import Extension, setup
|
|
|
|
|
|
|
|
|
|
|
|
MAJOR = 0
|
|
|
|
MINOR = 100
|
|
|
|
MICRO = 0
|
|
|
|
ISRELEASED = False
|
|
|
|
VERSION = '%d.%d.%d' % (MAJOR, MINOR, MICRO)
|
|
|
|
|
|
|
|
|
|
|
|
PACKAGES = [
|
|
|
|
'spacy',
|
|
|
|
'spacy.tokens',
|
|
|
|
'spacy.en',
|
|
|
|
'spacy.serialize',
|
|
|
|
'spacy.syntax',
|
|
|
|
'spacy.munge',
|
|
|
|
'spacy.tests',
|
|
|
|
'spacy.tests.matcher',
|
|
|
|
'spacy.tests.morphology',
|
|
|
|
'spacy.tests.munge',
|
|
|
|
'spacy.tests.parser',
|
|
|
|
'spacy.tests.serialize',
|
|
|
|
'spacy.tests.spans',
|
|
|
|
'spacy.tests.tagger',
|
|
|
|
'spacy.tests.tokenizer',
|
|
|
|
'spacy.tests.tokens',
|
|
|
|
'spacy.tests.vectors',
|
|
|
|
'spacy.tests.vocab']
|
|
|
|
|
|
|
|
|
|
|
|
MOD_NAMES = [
|
|
|
|
'spacy.parts_of_speech',
|
|
|
|
'spacy.strings',
|
|
|
|
'spacy.lexeme',
|
|
|
|
'spacy.vocab',
|
|
|
|
'spacy.attrs',
|
|
|
|
'spacy.morphology',
|
|
|
|
'spacy.tagger',
|
|
|
|
'spacy.syntax.stateclass',
|
|
|
|
'spacy.tokenizer',
|
|
|
|
'spacy.syntax.parser',
|
|
|
|
'spacy.syntax.transition_system',
|
|
|
|
'spacy.syntax.arc_eager',
|
|
|
|
'spacy.syntax._parse_features',
|
|
|
|
'spacy.gold',
|
|
|
|
'spacy.orth',
|
|
|
|
'spacy.tokens.doc',
|
|
|
|
'spacy.tokens.span',
|
|
|
|
'spacy.tokens.token',
|
|
|
|
'spacy.serialize.packer',
|
|
|
|
'spacy.serialize.huffman',
|
|
|
|
'spacy.serialize.bits',
|
|
|
|
'spacy.cfile',
|
|
|
|
'spacy.matcher',
|
|
|
|
'spacy.syntax.ner',
|
|
|
|
'spacy.symbols']
|
|
|
|
|
|
|
|
|
|
|
|
if sys.version_info[:2] < (2, 7) or (3, 0) <= sys.version_info[0:2] < (3, 4):
|
|
|
|
raise RuntimeError('Python version 2.7 or >= 3.4 required.')
|
2015-11-03 09:07:43 +03:00
|
|
|
|
|
|
|
|
2015-10-13 01:46:52 +03:00
|
|
|
# By subclassing build_extensions we have the actual compiler that will be used which is really known only after finalize_options
|
2015-10-13 01:31:59 +03:00
|
|
|
# http://stackoverflow.com/questions/724664/python-distutils-how-to-get-a-compiler-that-is-going-to-be-used
|
2015-12-13 13:49:17 +03:00
|
|
|
compile_options = {'msvc' : ['/Ox', '/EHsc'],
|
|
|
|
'other' : ['-O3', '-Wno-strict-prototypes', '-Wno-unused-function']}
|
|
|
|
link_options = {'msvc' : [],
|
|
|
|
'other' : []}
|
2015-10-13 01:31:59 +03:00
|
|
|
|
2015-12-13 13:49:17 +03:00
|
|
|
if sys.platform.startswith('darwin'):
|
|
|
|
compile_options['other'].append('-mmacosx-version-min=10.8')
|
|
|
|
compile_options['other'].append('-stdlib=libc++')
|
|
|
|
link_options['other'].append('-lc++')
|
2015-01-06 04:34:55 +03:00
|
|
|
|
|
|
|
|
2015-12-13 13:49:17 +03:00
|
|
|
class build_ext_options:
|
|
|
|
def build_options(self):
|
|
|
|
for e in self.extensions:
|
|
|
|
e.extra_compile_args = compile_options.get(
|
|
|
|
self.compiler.compiler_type, compile_options['other'])
|
|
|
|
for e in self.extensions:
|
|
|
|
e.extra_link_args = link_options.get(
|
|
|
|
self.compiler.compiler_type, link_options['other'])
|
2015-01-17 08:19:54 +03:00
|
|
|
|
|
|
|
|
2015-12-13 13:49:17 +03:00
|
|
|
class build_ext_subclass(build_ext, build_ext_options):
|
|
|
|
def build_extensions(self):
|
|
|
|
build_ext_options.build_options(self)
|
|
|
|
build_ext.build_extensions(self)
|
2015-01-17 08:19:54 +03:00
|
|
|
|
|
|
|
|
2015-12-13 13:49:17 +03:00
|
|
|
# Return the git revision as a string
|
|
|
|
def git_version():
|
|
|
|
def _minimal_ext_cmd(cmd):
|
|
|
|
# construct minimal environment
|
|
|
|
env = {}
|
|
|
|
for k in ['SYSTEMROOT', 'PATH']:
|
|
|
|
v = os.environ.get(k)
|
|
|
|
if v is not None:
|
|
|
|
env[k] = v
|
|
|
|
# LANGUAGE is used on win32
|
|
|
|
env['LANGUAGE'] = 'C'
|
|
|
|
env['LANG'] = 'C'
|
|
|
|
env['LC_ALL'] = 'C'
|
|
|
|
out = subprocess.Popen(cmd, stdout = subprocess.PIPE, env=env).communicate()[0]
|
|
|
|
return out
|
|
|
|
|
|
|
|
try:
|
|
|
|
out = _minimal_ext_cmd(['git', 'rev-parse', 'HEAD'])
|
|
|
|
GIT_REVISION = out.strip().decode('ascii')
|
|
|
|
except OSError:
|
|
|
|
GIT_REVISION = 'Unknown'
|
|
|
|
|
|
|
|
return GIT_REVISION
|
|
|
|
|
|
|
|
|
|
|
|
def get_version_info():
|
|
|
|
# Adding the git rev number needs to be done inside write_version_py(),
|
|
|
|
# otherwise the import of spacy.about messes up the build under Python 3.
|
|
|
|
FULLVERSION = VERSION
|
|
|
|
if os.path.exists('.git'):
|
|
|
|
GIT_REVISION = git_version()
|
|
|
|
elif os.path.exists('spacy/about.py'):
|
|
|
|
# must be a source distribution, use existing version file
|
|
|
|
try:
|
|
|
|
from spacy.about import git_revision as GIT_REVISION
|
|
|
|
except ImportError:
|
|
|
|
raise ImportError('Unable to import git_revision. Try removing '
|
|
|
|
'spacy/about.py and the build directory '
|
|
|
|
'before building.')
|
|
|
|
else:
|
|
|
|
GIT_REVISION = 'Unknown'
|
|
|
|
|
|
|
|
if not ISRELEASED:
|
|
|
|
FULLVERSION += '.dev0+' + GIT_REVISION[:7]
|
|
|
|
|
|
|
|
return FULLVERSION, GIT_REVISION
|
|
|
|
|
|
|
|
|
|
|
|
def write_version_py(filename='spacy/about.py'):
|
|
|
|
cnt = """# THIS FILE IS GENERATED FROM SPACY SETUP.PY
|
|
|
|
short_version = '%(version)s'
|
|
|
|
version = '%(version)s'
|
|
|
|
full_version = '%(full_version)s'
|
|
|
|
git_revision = '%(git_revision)s'
|
|
|
|
release = %(isrelease)s
|
|
|
|
if not release:
|
|
|
|
version = full_version
|
|
|
|
"""
|
|
|
|
FULLVERSION, GIT_REVISION = get_version_info()
|
|
|
|
|
|
|
|
with open(filename, 'w') as f:
|
|
|
|
f.write(cnt % {'version': VERSION,
|
|
|
|
'full_version' : FULLVERSION,
|
|
|
|
'git_revision' : GIT_REVISION,
|
|
|
|
'isrelease': str(ISRELEASED)})
|
|
|
|
|
|
|
|
|
|
|
|
def generate_cython():
|
|
|
|
cwd = os.path.abspath(os.path.dirname(__file__))
|
|
|
|
print('Cythonizing sources')
|
2015-12-13 14:32:22 +03:00
|
|
|
p = subprocess.call([os.path.join(cwd, 'bin', 'cythonize.sh'),
|
2015-12-13 13:49:17 +03:00
|
|
|
'spacy'],
|
|
|
|
cwd=cwd)
|
|
|
|
if p != 0:
|
|
|
|
raise RuntimeError('Running cythonize failed')
|
|
|
|
|
|
|
|
|
|
|
|
def clean():
|
|
|
|
for name in MOD_NAMES:
|
|
|
|
name = name.replace('.', '/')
|
|
|
|
for ext in ['.so', '.html', '.cpp', '.c']:
|
|
|
|
if os.path.exists(name + ext):
|
|
|
|
os.unlink(name + ext)
|
2015-01-25 06:49:10 +03:00
|
|
|
|
|
|
|
|
2015-12-13 13:49:17 +03:00
|
|
|
def setup_package():
|
|
|
|
src_path = os.path.dirname(os.path.abspath(sys.argv[0]))
|
|
|
|
old_path = os.getcwd()
|
|
|
|
os.chdir(src_path)
|
|
|
|
sys.path.insert(0, src_path)
|
2015-11-03 09:07:43 +03:00
|
|
|
|
2015-12-13 13:49:17 +03:00
|
|
|
# Rewrite the version file everytime
|
|
|
|
write_version_py()
|
2015-11-03 09:07:43 +03:00
|
|
|
|
2015-12-13 13:49:17 +03:00
|
|
|
include_dirs = [
|
2015-12-13 14:45:30 +03:00
|
|
|
os.path.join(sys.prefix, 'include'),
|
2015-12-13 14:41:46 +03:00
|
|
|
get_python_inc(plat_specific=True)]
|
2015-03-08 08:16:32 +03:00
|
|
|
|
2015-12-13 13:49:17 +03:00
|
|
|
ext_modules = []
|
|
|
|
for mod_name in MOD_NAMES:
|
|
|
|
mod_path = mod_name.replace('.', '/') + '.cpp'
|
|
|
|
ext_modules.append(
|
|
|
|
Extension(mod_name, [mod_path],
|
|
|
|
language='c++', include_dirs=include_dirs))
|
2015-03-08 08:16:32 +03:00
|
|
|
|
2015-12-13 13:49:17 +03:00
|
|
|
metadata = dict(
|
2015-01-04 21:30:56 +03:00
|
|
|
name='spacy',
|
2015-12-13 13:49:17 +03:00
|
|
|
packages=PACKAGES,
|
|
|
|
description='Industrial-strength NLP',
|
2015-01-04 21:30:56 +03:00
|
|
|
author='Matthew Honnibal',
|
2015-12-13 13:49:17 +03:00
|
|
|
author_email='matt@spacy.io',
|
2015-06-07 20:05:28 +03:00
|
|
|
version=VERSION,
|
2015-12-13 13:49:17 +03:00
|
|
|
url='https://spacy.io',
|
|
|
|
license='MIT',
|
|
|
|
ext_modules=ext_modules,
|
2015-11-19 12:59:51 +03:00
|
|
|
install_requires=['numpy', 'murmurhash == 0.24', 'cymem == 1.30', 'preshed == 0.44',
|
2015-12-13 13:49:17 +03:00
|
|
|
'thinc == 4.0.0', 'text_unidecode', 'plac', 'six',
|
2015-11-21 21:04:57 +03:00
|
|
|
'ujson', 'cloudpickle', 'sputnik == 0.5.2'],
|
2015-12-13 13:49:17 +03:00
|
|
|
cmdclass = {
|
|
|
|
'build_ext': build_ext_subclass},
|
2015-01-04 21:30:56 +03:00
|
|
|
)
|
|
|
|
|
2015-12-13 13:49:17 +03:00
|
|
|
# Run build
|
|
|
|
cwd = os.path.abspath(os.path.dirname(__file__))
|
|
|
|
if not os.path.exists(os.path.join(cwd, 'PKG-INFO')):
|
|
|
|
# Generate Cython sources, unless building from source release
|
|
|
|
generate_cython()
|
2015-01-04 21:30:56 +03:00
|
|
|
|
2015-12-13 13:49:17 +03:00
|
|
|
# sync include dirs from native dependencies
|
|
|
|
include_dir = os.path.join(src_path, 'include')
|
|
|
|
if os.path.exists(include_dir):
|
|
|
|
shutil.rmtree(include_dir)
|
|
|
|
os.mkdir(include_dir)
|
2015-01-04 21:30:56 +03:00
|
|
|
|
2015-12-13 14:41:46 +03:00
|
|
|
# import numpy
|
|
|
|
# shutil.copytree(
|
|
|
|
# os.path.join(numpy.get_include(), 'numpy'),
|
|
|
|
# os.path.join(include_dir, 'numpy'))
|
2015-01-04 21:30:56 +03:00
|
|
|
|
2015-12-13 14:41:46 +03:00
|
|
|
# import murmurhash
|
|
|
|
# shutil.copytree(
|
|
|
|
# os.path.join(os.path.dirname(murmurhash.__file__), 'headers', 'murmurhash'),
|
|
|
|
# os.path.join(include_dir, 'murmurhash'))
|
2015-12-13 13:49:17 +03:00
|
|
|
|
|
|
|
try:
|
|
|
|
setup(**metadata)
|
|
|
|
finally:
|
|
|
|
del sys.path[0]
|
|
|
|
os.chdir(old_path)
|
2015-01-04 21:30:56 +03:00
|
|
|
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
2015-03-09 08:46:35 +03:00
|
|
|
if sys.argv[1] == 'clean':
|
2015-12-13 13:49:17 +03:00
|
|
|
clean()
|
2015-03-09 08:46:35 +03:00
|
|
|
else:
|
2015-12-13 13:49:17 +03:00
|
|
|
setup_package()
|