setup.py (194 lines of code) (raw):
################################################################################
#
# Copyright 2022 Alibaba Group Holding Limited.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
################################################################################
import io
import os
import shutil
import sys
import sysconfig
import warnings
from setuptools.command.build_ext import build_ext as old_build_ext
from setuptools import setup, Extension
if sys.version_info < (3, 8):
print('Python versions prior to 3.7 are not supported for PemJa.',
file=sys.stderr)
sys.exit(-1)
this_directory = os.path.abspath(os.path.dirname(__file__))
version_file = os.path.join(this_directory, 'src/main/python/pemja/version.py')
try:
exec (open(version_file).read())
except IOError:
print("Failed to load PemJa version file for packaging. {0} not found!".format(version_file),
file=sys.stderr)
sys.exit(-1)
VERSION = __version__ # noqa
with io.open(os.path.join(this_directory, 'README.md'), 'r', encoding='utf-8') as f:
long_description = f.read()
_java_home = None
def get_java_home():
global _java_home
if _java_home is not None:
return _java_home
env_home = os.environ.get('JAVA_HOME')
if env_home:
if os.path.exists(env_home):
_java_home = env_home
return env_home
else:
print('Path {0} indicated by JAVA_HOME does not exist.'.format(env_home),
file=sys.stderr)
sys.exit(-1)
if is_windows():
java_path = shutil.which("java")
if java_path is None:
print('Can not determine JAVA_HOME from environment variable nor java executable path.',
file=sys.stderr)
sys.exit(-1)
exe_home = os.path.dirname(os.path.dirname(java_path))
_java_home = exe_home
return exe_home
return None
def is_osx():
return 'macosx' in sysconfig.get_platform()
def is_bsd():
return 'bsd' in sysconfig.get_platform()
def is_windows():
return 'win' in sysconfig.get_platform()
def get_python_libs():
libs = []
if not (is_bsd() or is_windows()):
libs.append('dl')
return libs
def get_java_libraries():
if is_windows():
return ['jvm']
return []
def get_java_lib_folders():
if not is_osx():
import fnmatch
if is_windows():
jre = os.path.join(get_java_home(), 'lib')
else:
jre = os.path.join(get_java_home(), 'jre', 'lib')
if not os.path.exists(jre):
jre = os.path.join(get_java_home(), 'lib')
folders = []
for root, dirnames, filenames in os.walk(jre):
if is_windows():
for filename in fnmatch.filter(filenames, '*jvm.lib'):
folders.append(os.path.dirname(os.path.join(root, filename)))
else:
for filename in fnmatch.filter(filenames, '*jvm.so'):
folders.append(os.path.dirname(os.path.join(root, filename)))
return list(set(folders))
return []
def get_files(dir, pattern):
ret = []
for root, dirs, files in os.walk(dir):
for f in files:
if f.endswith(pattern):
ret.append(os.path.join(root, f))
return ret
def is_apple_jdk():
return get_java_home() == '/System/Library/Frameworks/JavaVM.framework'
def get_java_linker_args():
if is_apple_jdk():
return ['-framework JavaVM']
return []
def get_java_include():
inc_name = 'include'
if is_apple_jdk():
inc_name = 'Headers'
inc = os.path.join(get_java_home(), inc_name)
if not os.path.exists(inc):
print("Include folder should be at '{0}' but doesn't exist. "
"Please check you've installed the JDK properly.".format(inc),
file=sys.stderr)
sys.exit(-1)
jni = os.path.join(inc, "jni.h")
if not os.path.exists(jni):
print("jni.h should be in '{0}' but doesn't exist. "
"Please check you've installed the JDK properly.".format(jni),
file=sys.stderr)
sys.exit(-1)
paths = [inc]
# Include platform specific headers if found
include_linux = os.path.join(inc, 'linux')
if os.path.exists(include_linux):
paths.append(include_linux)
include_darwin = os.path.join(inc, 'darwin')
if os.path.exists(include_darwin):
paths.append(include_darwin)
include_bsd = os.path.join(inc, 'freebsd')
if os.path.exists(include_bsd):
paths.append(include_bsd)
include_win32 = os.path.join(inc, 'win32')
if os.path.exists(include_win32):
paths.append(include_win32)
return paths
def get_src_include():
return ['src/main/c/Include']
def _is_using_gcc(obj):
is_gcc = False
if obj.compiler.compiler_type == 'unix':
cc = sysconfig.get_config_var("CC")
if not cc:
cc = ""
is_gcc = "gcc" in cc
return is_gcc
class build_ext(old_build_ext):
def build_extension(self, ext):
if _is_using_gcc(self):
if '-std=c99' not in ext.extra_compile_args:
ext.extra_compile_args.append('-std=c99')
old_build_ext.build_extension(self, ext)
extensions = ([
Extension(
name="pemja_core",
sources=get_files('src/main/c/pemja/core', '.c'),
libraries=get_java_libraries() + get_python_libs(),
library_dirs = get_java_lib_folders(),
extra_link_args=get_java_linker_args(),
include_dirs=get_java_include() + ['src/main/c/pemja/core/include'],
language="3"),
Extension(
name="pemja_utils",
sources=get_files('src/main/c/pemja/utils', '.c'),
library_dirs = get_java_lib_folders(),
extra_link_args=get_java_linker_args(),
include_dirs=get_java_include() + ['src/main/c/pemja/utils/include'],
language="3")
])
PACKAGE_DATA = {
'pemja': ['README.txt']
}
PACKAGE_DIR = {
'': 'src/main/python'
}
setup(
name='pemja',
version=VERSION,
packages=["pemja"],
include_package_data=True,
package_dir=PACKAGE_DIR,
package_data=PACKAGE_DATA,
author='Apache Software Foundation',
license='https://www.apache.org/licenses/LICENSE-2.0',
author_email='hxbks2ks@gmail.com',
python_requires='>=3.8',
install_requires=['find-libpython'],
cmdclass={'build_ext': build_ext},
description='PemJa',
long_description=long_description,
long_description_content_type='text/markdown',
zip_safe=False,
classifiers=[
'Development Status :: 5 - Production/Stable',
'License :: OSI Approved :: Apache Software License',
'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 :: Implementation :: CPython',
'Operating System :: Unix',
'Operating System :: MacOS',
'Operating System :: Microsoft :: Windows',
],
ext_modules=extensions)