pyjnius/setup.py

271 lines
7.8 KiB
Python
Raw Normal View History

2018-10-13 21:22:39 +00:00
'''
Setup.py for creating a binary distribution.
'''
from __future__ import print_function
try:
from setuptools import setup, Extension
except ImportError:
from distutils.core import setup, Extension
2017-10-24 14:33:12 +00:00
try:
import subprocess32 as subprocess
except ImportError:
import subprocess
2012-08-14 01:42:43 +00:00
from os import environ
from os.path import dirname, join, exists
2012-08-14 01:42:43 +00:00
import sys
from platform import machine
2018-10-13 21:22:39 +00:00
from setup_sdist import SETUP_KWARGS
PY2 = sys.version_info < (3, 0, 0)
2017-03-23 17:56:02 +00:00
2012-08-14 01:42:43 +00:00
2015-11-03 13:57:04 +00:00
def getenv(key):
2018-10-13 21:22:39 +00:00
'''Get value from environment and decode it.'''
2015-11-03 13:57:04 +00:00
val = environ.get(key)
if val is not None:
if not PY2:
try:
return val.decode()
except AttributeError:
return val
return val
2015-11-03 13:57:04 +00:00
2017-03-23 17:56:02 +00:00
2018-10-13 21:22:39 +00:00
FILES = [
'jni.pxi',
'jnius_compat.pxi',
'jnius_conversion.pxi',
'jnius_export_class.pxi',
'jnius_export_func.pxi',
'jnius_jvm_android.pxi',
'jnius_jvm_desktop.pxi',
2015-05-01 16:16:58 +00:00
'jnius_jvm_dlopen.pxi',
'jnius_localref.pxi',
'jnius.pyx',
'jnius_utils.pxi',
]
2018-10-13 21:22:39 +00:00
LIBRARIES = []
LIBRARY_DIRS = []
LIB_LOCATION = None
EXTRA_LINK_ARGS = []
INCLUDE_DIRS = []
INSTALL_REQUIRES = ['six>=1.7.0']
2012-08-14 01:42:43 +00:00
# detect Python for android
2018-10-13 21:22:39 +00:00
PLATFORM = sys.platform
NDKPLATFORM = getenv('NDKPLATFORM')
if NDKPLATFORM is not None and getenv('LIBLINK'):
PLATFORM = 'android'
2012-08-14 01:42:43 +00:00
# detect cython
try:
from Cython.Distutils import build_ext
2018-10-13 21:22:39 +00:00
INSTALL_REQUIRES.append('cython')
2012-08-14 01:42:43 +00:00
except ImportError:
2018-10-13 21:22:39 +00:00
# pylint: disable=ungrouped-imports
try:
from setuptools.command.build_ext import build_ext
except ImportError:
from distutils.command.build_ext import build_ext
2018-10-13 21:22:39 +00:00
if PLATFORM != 'android':
2014-08-19 12:35:20 +00:00
print('\n\nYou need Cython to compile Pyjnius.\n\n')
raise
2015-05-01 16:16:58 +00:00
# On Android we expect to see 'c' files lying about.
# and we go ahead with the 'desktop' file? Odd.
2018-10-13 21:22:39 +00:00
FILES = [fn[:-3] + 'c' for fn in FILES if fn.endswith('pyx')]
2012-08-14 01:42:43 +00:00
def find_javac(possible_homes):
2018-10-13 21:22:39 +00:00
'''Find javac in all possible locations.'''
name = "javac.exe" if sys.platform == "win32" else "javac"
for home in possible_homes:
for javac in [join(home, name), join(home, 'bin', name)]:
if exists(javac):
return javac
return name # Fall back to "hope it's on the path"
def compile_native_invocation_handler(*possible_homes):
2018-10-13 21:22:39 +00:00
'''Find javac and compile NativeInvocationHandler.java.'''
javac = find_javac(possible_homes)
subprocess.check_call([
javac, '-target', '1.6', '-source', '1.6',
join('jnius', 'src', 'org', 'jnius', 'NativeInvocationHandler.java')
])
2018-10-13 21:22:39 +00:00
if PLATFORM == 'android':
2012-08-14 01:42:43 +00:00
# for android, we use SDL...
2018-10-13 21:22:39 +00:00
LIBRARIES = ['sdl', 'log']
LIBRARY_DIRS = ['libs/' + getenv('ARCH')]
2018-10-13 21:22:39 +00:00
elif PLATFORM == 'darwin':
2018-10-13 21:22:39 +00:00
FRAMEWORK = subprocess.Popen(
2017-03-23 17:56:02 +00:00
'/usr/libexec/java_home',
stdout=subprocess.PIPE, shell=True).communicate()[0]
if not PY2:
FRAMEWORK = FRAMEWORK.decode('utf-8')
2018-10-13 21:22:39 +00:00
FRAMEWORK = FRAMEWORK.strip()
2018-10-13 21:22:39 +00:00
if not FRAMEWORK:
raise Exception('You must install Java on your Mac OS X distro')
2018-10-13 21:22:39 +00:00
if '1.6' in FRAMEWORK:
LIB_LOCATION = '../Libraries/libjvm.dylib'
INCLUDE_DIRS = [join(
FRAMEWORK, (
'System/Library/Frameworks/'
'JavaVM.framework/Versions/Current/Headers'
)
)]
2015-05-01 01:29:55 +00:00
else:
2018-10-13 21:22:39 +00:00
LIB_LOCATION = 'jre/lib/server/libjvm.dylib'
# We want to favor Java installation declaring JAVA_HOME
if getenv('JAVA_HOME'):
FRAMEWORK = getenv('JAVA_HOME')
FULL_LIB_LOCATION = join(FRAMEWORK, LIB_LOCATION)
if not exists(FULL_LIB_LOCATION):
# In that case, the Java version is very likely >=9.
# So we need to modify the `libjvm.so` path.
LIB_LOCATION = 'lib/server/libjvm.dylib'
2018-10-13 21:22:39 +00:00
INCLUDE_DIRS = [
'{0}/include'.format(FRAMEWORK),
'{0}/include/darwin'.format(FRAMEWORK)
2017-03-23 17:56:02 +00:00
]
print('JAVA_HOME: {0}\n'.format(FRAMEWORK))
2018-10-13 21:22:39 +00:00
compile_native_invocation_handler(FRAMEWORK)
2018-11-29 04:45:36 +00:00
2012-08-14 01:42:43 +00:00
else:
2018-11-29 04:45:36 +00:00
# Note: if on Windows, set ONLY JAVA_HOME
2018-10-13 21:22:39 +00:00
# not on android or osx, we need to search the JDK_HOME
2018-11-29 04:45:36 +00:00
2018-10-13 21:22:39 +00:00
JDK_HOME = getenv('JDK_HOME')
if not JDK_HOME:
2018-11-29 04:45:36 +00:00
2018-10-13 21:22:39 +00:00
if PLATFORM == 'win32':
2018-11-29 04:45:36 +00:00
TMP_JDK_HOME = getenv('JAVA_HOME')
print(TMP_JDK_HOME)
# Remove /bin if it's appended to JAVA_HOME
if TMP_JDK_HOME[-3:] == 'bin':
TMP_JDK_HOME = TMP_JDK_HOME[:-4]
# Check whether it's JDK
if exists(join(TMP_JDK_HOME, 'bin', 'javac.exe')):
JDK_HOME = TMP_JDK_HOME
else:
2018-10-13 21:22:39 +00:00
JDK_HOME = subprocess.Popen(
2017-03-23 17:56:02 +00:00
'readlink -f `which javac` | sed "s:bin/javac::"',
shell=True, stdout=subprocess.PIPE).communicate()[0].strip()
2018-11-29 04:45:36 +00:00
if JDK_HOME is not None and not PY2:
2018-11-29 04:45:36 +00:00
JDK_HOME = JDK_HOME.decode('utf-8')
2018-10-13 21:22:39 +00:00
if not JDK_HOME or not exists(JDK_HOME):
2012-08-14 01:42:43 +00:00
raise Exception('Unable to determine JDK_HOME')
2018-10-13 21:22:39 +00:00
JRE_HOME = None
if exists(join(JDK_HOME, 'jre')):
JRE_HOME = join(JDK_HOME, 'jre')
2018-11-29 04:45:36 +00:00
if PLATFORM != 'win32' and not JRE_HOME:
2018-10-13 21:22:39 +00:00
JRE_HOME = subprocess.Popen(
2017-03-23 17:56:02 +00:00
'readlink -f `which java` | sed "s:bin/java::"',
shell=True, stdout=subprocess.PIPE).communicate()[0].strip()
2017-03-23 17:38:55 +00:00
2018-10-13 21:22:39 +00:00
# This dictionary converts values from platform.machine()
# to a "cpu" string. It is needed to set the correct lib path,
# found in the JRE_HOME, e.g.: <JRE_HOME>/lib/<cpu>/.
MACHINE2CPU = {
"i686": "i386",
"x86_64": "amd64",
"armv7l": "arm"
2017-03-23 17:56:02 +00:00
}
2018-10-13 21:22:39 +00:00
if machine() in MACHINE2CPU.keys():
CPU = MACHINE2CPU[machine()]
else:
2018-10-13 21:22:39 +00:00
print(
"WARNING: Not able to assign machine()"
" = %s to a cpu value!" % machine()
)
print(" Using cpu = 'i386' instead!")
2018-10-13 21:22:39 +00:00
CPU = 'i386'
2017-03-23 17:38:55 +00:00
2018-10-13 21:22:39 +00:00
if PLATFORM == 'win32':
INCL_DIR = join(JDK_HOME, 'include', 'win32')
LIBRARIES = ['jvm']
2013-11-26 04:44:46 +00:00
else:
2018-10-13 21:22:39 +00:00
INCL_DIR = join(JDK_HOME, 'include', 'linux')
LIB_LOCATION = 'jre/lib/{}/server/libjvm.so'.format(CPU)
2013-11-26 04:44:46 +00:00
if isinstance(JRE_HOME, bytes):
JAVA_HOME = dirname(JRE_HOME.decode())
else:
JAVA_HOME = dirname(JRE_HOME)
FULL_LIB_LOCATION = join(JAVA_HOME, LIB_LOCATION)
if not exists(FULL_LIB_LOCATION):
# In that case, the Java version is very likely >=9.
# So we need to modify the `libjvm.so` path.
LIB_LOCATION = 'lib/server/libjvm.so'
2018-10-13 21:22:39 +00:00
INCLUDE_DIRS = [
join(JDK_HOME, 'include'),
INCL_DIR
2017-03-23 17:56:02 +00:00
]
2015-05-01 16:16:58 +00:00
2018-10-13 21:22:39 +00:00
if PLATFORM == 'win32':
if isinstance(JRE_HOME, bytes):
2018-11-29 04:45:36 +00:00
JRE_HOME = JRE_HOME.decode('utf-8')
2018-10-13 21:22:39 +00:00
LIBRARY_DIRS = [
join(JDK_HOME, 'lib'),
2018-11-29 04:45:36 +00:00
join(JDK_HOME, 'bin', 'server')
2017-03-23 17:56:02 +00:00
]
2012-08-14 01:42:43 +00:00
2018-11-29 04:45:36 +00:00
print('JDK_HOME: {0}\n'.format(JDK_HOME))
print('JRE_HOME: {0}\n'.format(JRE_HOME))
2018-10-13 21:22:39 +00:00
compile_native_invocation_handler(JDK_HOME, JRE_HOME)
2012-08-14 01:42:43 +00:00
# generate the config.pxi
with open(join(dirname(__file__), 'jnius', 'config.pxi'), 'w') as fd:
2018-10-13 21:22:39 +00:00
fd.write('DEF JNIUS_PLATFORM = {0!r}\n\n'.format(PLATFORM))
if not PY2:
fd.write('DEF JNIUS_PYTHON3 = True\n\n')
else:
fd.write('DEF JNIUS_PYTHON3 = False\n\n')
2018-10-13 21:22:39 +00:00
if LIB_LOCATION is not None:
fd.write('DEF JNIUS_LIB_SUFFIX = {0!r}\n\n'.format(LIB_LOCATION))
2012-08-14 01:42:43 +00:00
2018-11-27 17:53:01 +00:00
# pop setup.py from included files in the installed package
SETUP_KWARGS['py_modules'].remove('setup')
2012-08-14 01:42:43 +00:00
# create the extension
2017-03-23 17:56:02 +00:00
setup(
cmdclass={'build_ext': build_ext},
2018-10-13 21:22:39 +00:00
install_requires=INSTALL_REQUIRES,
2017-03-23 17:56:02 +00:00
ext_modules=[
Extension(
2018-10-13 21:22:39 +00:00
'jnius', [join('jnius', x) for x in FILES],
libraries=LIBRARIES,
library_dirs=LIBRARY_DIRS,
include_dirs=INCLUDE_DIRS,
extra_link_args=EXTRA_LINK_ARGS
2017-03-23 17:56:02 +00:00
)
],
**SETUP_KWARGS
2017-03-23 17:56:02 +00:00
)