rework setup.py, need testing on windows/linux. hopefully that would be more easy to implement new extensions that require new libs now.

This commit is contained in:
Mathieu Virbel 2012-02-24 00:25:20 +01:00
parent 8d3403d3eb
commit 69bea76df9
1 changed files with 183 additions and 151 deletions

302
setup.py
View File

@ -1,20 +1,36 @@
#
# Kivy - Crossplatform NUI toolkit
# http://kivy.org/
#
import sys import sys
from fnmatch import filter as fnfilter from copy import deepcopy
from os.path import join, dirname, realpath, sep, exists from os.path import join, dirname, sep, exists
from os import walk, environ from os import walk, environ
from distutils.core import setup from distutils.core import setup
from distutils.extension import Extension from distutils.extension import Extension
# -----------------------------------------------------------------------------
# Detect options
#
c_options = {
'use_opengl_es2': True,
'use_opengl_debug': False,
'use_glew': False,
'use_mesagl': 'USE_MESAGL' in environ}
# -----------------------------------------------------------------------------
# Determine on which platform we are
platform = sys.platform platform = sys.platform
# # Detect Python for android project (http://github.com/kivy/python-for-android)
# Detect Python for android project
# FIXME: add a specific var for this project, not just guess
#
ndkplatform = environ.get('NDKPLATFORM') ndkplatform = environ.get('NDKPLATFORM')
if ndkplatform is not None and environ.get('LIBLINK'): if ndkplatform is not None and environ.get('LIBLINK'):
platform = 'android' platform = 'android'
# -----------------------------------------------------------------------------
# Cython check
try: try:
# check for cython # check for cython
from Cython.Distutils import build_ext from Cython.Distutils import build_ext
@ -27,61 +43,8 @@ except ImportError:
have_cython = False have_cython = False
from distutils.command.build_ext import build_ext from distutils.command.build_ext import build_ext
# extract version (simulate doc generation, kivy will be not imported) # -----------------------------------------------------------------------------
environ['KIVY_DOC_INCLUDE'] = '1' # Setup classes
import kivy
# extra build commands go in the cmdclass dict {'command-name': CommandClass}
# see tools.packaging.{platform}.build.py for custom build commands for
# portable packages. also e.g. we use build_ext command from cython if its
# installed for c extensions.
cmdclass = {}
try:
# add build rules for portable packages to cmdclass
if platform == 'win32':
from kivy.tools.packaging.win32.build import WindowsPortableBuild
cmdclass['build_portable'] = WindowsPortableBuild
elif platform == 'darwin':
from kivy.tools.packaging.osx.build import OSXPortableBuild
cmdclass['build_portable'] = OSXPortableBuild
except ImportError:
print 'User distribution detected, avoid portable command.'
from kivy.tools.packaging.factory import FactoryBuild
cmdclass['build_factory'] = FactoryBuild
#
# Detect options
#
c_options = {
'use_opengl_es2': True,
'use_opengl_debug': False,
'use_glew': False,
'use_mesagl': 'USE_MESAGL' in environ}
# Detect which opengl version headers to use
if platform in ('android', 'darwin'):
pass
elif platform == 'win32':
print 'Windows platform detected, force GLEW usage.'
c_options['use_glew'] = True
else:
# searching GLES headers
default_header_dirs = ['/usr/include', '/usr/local/include']
found = False
for hdir in default_header_dirs:
filename = join(hdir, 'GLES2', 'gl2.h')
if exists(filename):
found = True
print 'Found GLES 2.0 headers at', filename
break
if not found:
print 'WARNING: GLES 2.0 headers are not found'
print 'Fallback to Desktop opengl headers.'
c_options['use_opengl_es2'] = False
class KivyBuildExt(build_ext): class KivyBuildExt(build_ext):
def build_extensions(self): def build_extensions(self):
@ -104,55 +67,55 @@ class KivyBuildExt(build_ext):
build_ext.build_extensions(self) build_ext.build_extensions(self)
cmdclass['build_ext'] = KivyBuildExt
# extension modules # -----------------------------------------------------------------------------
ext_modules = [] # extract version (simulate doc generation, kivy will be not imported)
environ['KIVY_DOC_INCLUDE'] = '1'
import kivy
# list all files to compile # extra build commands go in the cmdclass dict {'command-name': CommandClass}
pyx_files = [] # see tools.packaging.{platform}.build.py for custom build commands for
pxd_files = [] # portable packages. also e.g. we use build_ext command from cython if its
kivy_libs_dir = realpath(join(kivy.kivy_base_dir, 'libs')) # installed for c extensions.
for root, dirnames, filenames in walk(join(dirname(__file__), 'kivy')): from kivy.tools.packaging.factory import FactoryBuild
# ignore lib directory cmdclass = {
if realpath(root).startswith(kivy_libs_dir): 'build_factory': FactoryBuild,
continue 'build_ext': KivyBuildExt }
for filename in fnfilter(filenames, '*.pxd'):
pxd_files.append(join(root, filename))
for filename in fnfilter(filenames, '*.pyx'):
pyx_files.append(join(root, filename))
if not have_cython: try:
pyx_files = pyx_files = ['%s.c' % x[:-4] for x in pyx_files] # add build rules for portable packages to cmdclass
pxd_files = []
# add cython core extension modules if cython is available
if True:
libraries = ['m']
include_dirs = []
extra_link_args = []
if platform == 'win32': if platform == 'win32':
libraries.append('opengl32') from kivy.tools.packaging.win32.build import WindowsPortableBuild
cmdclass['build_portable'] = WindowsPortableBuild
elif platform == 'darwin': elif platform == 'darwin':
# On OSX, it's not -lGL, but -framework OpenGL... from kivy.tools.packaging.osx.build import OSXPortableBuild
extra_link_args = ['-framework', 'OpenGL'] cmdclass['build_portable'] = OSXPortableBuild
elif platform.startswith('freebsd'): except ImportError:
include_dirs += ['/usr/local/include'] print 'User distribution detected, avoid portable command.'
extra_link_args += ['-L', '/usr/local/lib']
elif platform == 'android':
include_dirs += [join(ndkplatform, 'usr', 'include')]
extra_link_args += ['-L', join(ndkplatform, 'usr', 'lib')]
libraries.append('GLESv2')
else:
libraries.append('GL')
if c_options['use_glew']: # Detect which opengl version headers to use
if platform == 'win32': if platform in ('android', 'darwin'):
libraries.append('glew32') pass
elif platform == 'win32':
print 'Windows platform detected, force GLEW usage.'
c_options['use_glew'] = True
else: else:
libraries.append('GLEW') # searching GLES headers
default_header_dirs = ['/usr/include', '/usr/local/include']
found = False
for hdir in default_header_dirs:
filename = join(hdir, 'GLES2', 'gl2.h')
if exists(filename):
found = True
print 'Found GLES 2.0 headers at', filename
break
if not found:
print 'WARNING: GLES 2.0 headers are not found'
print 'Fallback to Desktop opengl headers.'
c_options['use_opengl_es2'] = False
# -----------------------------------------------------------------------------
# declare flags
def get_modulename_from_file(filename): def get_modulename_from_file(filename):
pyx = '.'.join(filename.split('.')[:-1]) pyx = '.'.join(filename.split('.')[:-1])
pyxl = pyx.split(sep) pyxl = pyx.split(sep)
@ -165,14 +128,6 @@ if True:
class CythonExtension(Extension): class CythonExtension(Extension):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
# Small hack to only compile for x86_64 on OSX.
# Is there a better way to do this?
if platform == 'darwin':
extra_args = ['-arch', 'x86_64']
kwargs['extra_compile_args'] = extra_args + \
kwargs.get('extra_compile_args', [])
kwargs['extra_link_args'] = extra_args + \
kwargs.get('extra_link_args', [])
Extension.__init__(self, *args, **kwargs) Extension.__init__(self, *args, **kwargs)
self.pyrex_directives = { self.pyrex_directives = {
'profile': 'USE_PROFILE' in environ, 'profile': 'USE_PROFILE' in environ,
@ -182,44 +137,122 @@ if True:
# sources # sources
self.sources = args[1] self.sources = args[1]
# simple extensions def merge(d1, *args):
for pyx in (x for x in pyx_files if not 'graphics' in x): d1 = deepcopy(d1)
pxd = [x for x in pxd_files if not 'graphics' in x] for d2 in args:
for key, value in d2.iteritems():
if key in d1:
d1[key].extend(value)
else:
d1[key] = value
return d1
def determine_gl_flags():
flags = {'libraries': []}
if platform == 'win32':
flags['libraries'] = ['opengl32']
elif platform == 'darwin':
flags['extra_link_args'] = ['-framework', 'OpenGL', '-arch', 'x86_64']
flags['extra_compile_args'] = ['-arch', 'x86_64']
elif platform.startswith('freebsd'):
flags['include_dirs'] = ['/usr/local/include']
flags['extra_link_args'] = ['-L', '/usr/local/lib']
elif platform == 'android':
flags['include_dirs'] += [join(ndkplatform, 'usr', 'include')]
flags['extra_link_args'] += ['-L', join(ndkplatform, 'usr', 'lib')]
flags['libraries'] = ['GLESv2']
else:
flags['libraries'] = ['GL']
if c_options['use_glew']:
if platform == 'win32':
flags['libraries'] += ['glew32']
else:
flags['libraries'] += ['GLEW']
return flags
def determine_graphics_pxd():
flags = {'depends': [join(dirname(__file__), 'kivy', x) for x in [
'graphics/buffer.pxd',
'graphics/c_opengl.pxd',
'graphics/c_opengl_debug.pxd',
'graphics/compiler.pxd',
'graphics/context_instructions.pxd',
'graphics/fbo.pxd',
'graphics/instructions.pxd',
'graphics/opengl_utils.pxd',
'graphics/shader.pxd',
'graphics/texture.pxd',
'graphics/transformation.pxd',
'graphics/vbo.pxd',
'graphics/vertex.pxd']]}
return flags
base_flags = {
'libraries': ['m'],
'include_dirs': [],
'extra_links_args': [],
'extra_compile_args': []}
gl_flags = determine_gl_flags()
graphics_flags = determine_graphics_pxd()
# -----------------------------------------------------------------------------
# sources to compile
sources = {
'_event.pyx': base_flags,
'properties.pyx': base_flags,
'graphics/buffer.pyx': base_flags,
'graphics/c_opengl_debug.pyx': merge(base_flags, gl_flags, graphics_flags),
'graphics/compiler.pyx': merge(base_flags, gl_flags, graphics_flags),
'graphics/context_instructions.pyx': merge(base_flags, gl_flags, graphics_flags),
'graphics/fbo.pyx': merge(base_flags, gl_flags, graphics_flags),
'graphics/instructions.pyx': merge(base_flags, gl_flags, graphics_flags),
'graphics/opengl.pyx': merge(base_flags, gl_flags, graphics_flags),
'graphics/opengl_utils.pyx': merge(base_flags, gl_flags, graphics_flags),
'graphics/shader.pyx': merge(base_flags, gl_flags, graphics_flags),
'graphics/stencil_instructions.pyx': merge(base_flags, gl_flags, graphics_flags),
'graphics/texture.pyx': merge(base_flags, gl_flags, graphics_flags),
'graphics/transformation.pyx': merge(base_flags, gl_flags, graphics_flags),
'graphics/vbo.pyx': merge(base_flags, gl_flags, graphics_flags),
'graphics/vertex.pyx': merge(base_flags, gl_flags, graphics_flags),
'graphics/vertex_instructions.pyx': merge(base_flags, gl_flags, graphics_flags),
}
# -----------------------------------------------------------------------------
# extension modules
def get_extensions_from_sources(sources):
ext_modules = []
for pyx, flags in sources.iteritems():
pyx = join(dirname(__file__), 'kivy', pyx)
if not have_cython:
pyx = '%s.c' % pyx[:-4]
module_name = get_modulename_from_file(pyx) module_name = get_modulename_from_file(pyx)
ext_modules.append(CythonExtension(module_name, [pyx] + pxd)) depends = flags.pop('depends', [])
ext_modules.append(CythonExtension(module_name,
[pyx] + depends, **flags))
return ext_modules
# opengl aware modules ext_modules = get_extensions_from_sources(sources)
for pyx in (x for x in pyx_files if 'graphics' in x):
pxd = [x for x in pxd_files if 'graphics' in x]
module_name = get_modulename_from_file(pyx)
ext_modules.append(CythonExtension(
module_name, [pyx] + pxd,
libraries=libraries,
include_dirs=include_dirs,
extra_link_args=extra_link_args))
# -----------------------------------------------------------------------------
#setup datafiles to be included in the disytibution, liek examples... # automatically detect data files
#extracts all examples files except sandbox
data_file_prefix = 'share/kivy-' data_file_prefix = 'share/kivy-'
examples = {} examples = {}
examples_allowed_ext = ('readme', 'py', 'wav', 'png', 'jpg', 'svg', 'json', examples_allowed_ext = ('readme', 'py', 'wav', 'png', 'jpg', 'svg', 'json',
'avi', 'gif', 'txt', 'ttf', 'obj', 'mtl', 'kv') 'avi', 'gif', 'txt', 'ttf', 'obj', 'mtl', 'kv')
for root, subFolders, files in walk('examples'): for root, subFolders, files in walk('examples'):
if 'sandbox' in root: for fn in files:
continue ext = fn.split('.')[-1].lower()
for file in files:
ext = file.split('.')[-1].lower()
if ext not in examples_allowed_ext: if ext not in examples_allowed_ext:
continue continue
filename = join(root, file) filename = join(root, fn)
directory = '%s%s' % (data_file_prefix, dirname(filename)) directory = '%s%s' % (data_file_prefix, dirname(filename))
if not directory in examples: if not directory in examples:
examples[directory] = [] examples[directory] = []
examples[directory].append(filename) examples[directory].append(filename)
# -----------------------------------------------------------------------------
# setup ! # setup !
setup( setup(
name='Kivy', name='Kivy',
@ -255,8 +288,7 @@ setup(
'kivy.network', 'kivy.network',
'kivy.tools', 'kivy.tools',
'kivy.tools.packaging', 'kivy.tools.packaging',
'kivy.uix', 'kivy.uix', ],
],
package_dir={'kivy': 'kivy'}, package_dir={'kivy': 'kivy'},
package_data={'kivy': [ package_data={'kivy': [
'data/*.kv', 'data/*.kv',