Switch to setuptools usage, instead of distutil
and many other setup improvments, this is a squashed commit from many better and smaller commits on master
This commit is contained in:
parent
0afd5aee8b
commit
a379365ae2
|
@ -1,4 +1,4 @@
|
|||
include README INSTALL COPYING COPYING.LESSER AUTHORS ChangeLog
|
||||
include README.md INSTALL COPYING COPYING.LESSER AUTHORS ChangeLog
|
||||
recursive-include efl *.c *.h *.pyx *.pxi *.pxd
|
||||
graft include
|
||||
graft tests
|
||||
|
|
19
Makefile
19
Makefile
|
@ -29,6 +29,11 @@ install:
|
|||
$(PY) setup.py install
|
||||
|
||||
|
||||
.PHONY: uninstall
|
||||
uninstall:
|
||||
$(PY) setup.py uninstall
|
||||
|
||||
|
||||
.PHONY: doc
|
||||
doc:
|
||||
$(PY) setup.py build build_doc
|
||||
|
@ -47,9 +52,17 @@ clean:
|
|||
.PHONY: maintainer-clean
|
||||
maintainer-clean:
|
||||
$(PY) setup.py clean --all clean_generated_files
|
||||
rm -rf build/
|
||||
rm -rf dist/
|
||||
rm -rf python_efl.egg-info/
|
||||
rm -f installed_files-*.txt
|
||||
|
||||
|
||||
.PHONY: dist
|
||||
dist:
|
||||
$(PY) setup.py sdist --formats=gztar,bztar
|
||||
|
||||
|
||||
$(PY) setup.py sdist --formats=gztar,xztar
|
||||
$(PY) setup.py bdist_wheel
|
||||
@cd dist/; for f in `ls *.tar.*` ; do \
|
||||
echo Generating sha256 for: $$f ; \
|
||||
sha256sum $$f > $$f.sha256; \
|
||||
done
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
# along with this Python-EFL. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# semver examples:
|
||||
# development: "1.12.99" ( 1, 12, 99 )
|
||||
# pre-release: "1.13.0-beta1" ( 1, 13, 0 )
|
||||
# release: "1.13.0" ( 1, 13, 0 )
|
||||
# development: '1.12.99' ( 1, 12, 99 )
|
||||
# pre-release: '1.13.0-beta1' ( 1, 13, 0 )
|
||||
# release: '1.13.0' ( 1, 13, 0 )
|
||||
|
||||
__version__ = "1.25.0"
|
||||
__version__ = '1.25.0'
|
||||
__version_info__ = (1, 25, 0)
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
[build-system]
|
||||
requires = ['setuptools', 'wheel']
|
||||
build-backend = 'setuptools.build_meta'
|
765
setup.py
765
setup.py
|
@ -3,164 +3,314 @@
|
|||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import platform
|
||||
import subprocess
|
||||
from distutils.core import setup, Command
|
||||
from distutils.extension import Extension
|
||||
from distutils.command.build_ext import build_ext
|
||||
from distutils.version import StrictVersion, LooseVersion
|
||||
from efl import __version__, __version_info__ as vers
|
||||
import unittest
|
||||
from distutils.version import LooseVersion
|
||||
from setuptools import setup, Extension, Command
|
||||
|
||||
script_path = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
# python-efl version (change in efl/__init__.py)
|
||||
RELEASE = __version__
|
||||
VERSION = "%d.%d" % (vers[0], vers[1] if vers[2] < 99 else vers[1] + 1)
|
||||
|
||||
# dependencies
|
||||
CYTHON_MIN_VERSION = "0.23.5"
|
||||
EFL_MIN_VER = '1.25.1'
|
||||
CYTHON_MIN_VERSION = '0.23.5'
|
||||
CYTHON_BLACKLIST = ()
|
||||
EFL_MIN_VER = RELEASE
|
||||
ELM_MIN_VER = RELEASE
|
||||
|
||||
# Add git commit count for dev builds
|
||||
if vers[2] == 99:
|
||||
try:
|
||||
call = subprocess.Popen(["git", "rev-list", "--count", "HEAD"],
|
||||
stdout=subprocess.PIPE)
|
||||
out, err = call.communicate()
|
||||
count = out.decode("utf-8").strip()
|
||||
RELEASE += "a" + count
|
||||
except Exception:
|
||||
RELEASE += "a0"
|
||||
|
||||
|
||||
# XXX: Force default visibility. See phab T504
|
||||
if os.getenv("CFLAGS") is not None and "-fvisibility=" in os.environ["CFLAGS"]:
|
||||
os.environ["CFLAGS"] += " -fvisibility=default"
|
||||
# basic utils
|
||||
def read_file(rel_path):
|
||||
with open(os.path.join(script_path, rel_path)) as fp:
|
||||
return fp.read()
|
||||
|
||||
def cmd_output(cmd):
|
||||
p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
p.wait()
|
||||
if p.returncode != 0:
|
||||
print('WARNING: An error occurred while running "%s" (code %s)' % (cmd, p.returncode))
|
||||
stderr_content = p.stderr.read().decode('utf-8').strip()
|
||||
if stderr_content:
|
||||
print(stderr_content)
|
||||
return ''
|
||||
return p.stdout.read().decode('utf-8').strip()
|
||||
|
||||
def get_version(rel_path):
|
||||
for line in read_file(rel_path).splitlines():
|
||||
if line.startswith('__version__'):
|
||||
return line.split("'")[1]
|
||||
raise SystemExit('Unable to find version string.')
|
||||
|
||||
|
||||
# === Sphinx ===
|
||||
try:
|
||||
from sphinx.setup_command import BuildDoc
|
||||
except ImportError:
|
||||
class BuildDoc(Command):
|
||||
description = "build docs using sphinx, that must be installed."
|
||||
version = ""
|
||||
release = ""
|
||||
user_options = []
|
||||
# python-efl version from sources
|
||||
RELEASE = get_version('efl/__init__.py')
|
||||
|
||||
def initialize_options(self):
|
||||
pass
|
||||
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
print("Error: sphinx not found")
|
||||
# add git commit count for dev builds
|
||||
if RELEASE.split('.')[2] == '99':
|
||||
count = cmd_output('git rev-list --count HEAD') or '0'
|
||||
RELEASE += 'a' + count
|
||||
sys.stdout.write('Python-EFL: %s\n' % RELEASE)
|
||||
|
||||
|
||||
# === pkg-config ===
|
||||
# === check python version ===
|
||||
sys.stdout.write('Checking for Python: ')
|
||||
py_ver = sys.version_info
|
||||
py_ver = '%s.%s.%s' % (py_ver[0], py_ver[1], py_ver[2])
|
||||
if sys.hexversion < 0x020700f0:
|
||||
raise SystemExit('too old. Found: %s Need at least 2.7.0' % py_ver)
|
||||
sys.stdout.write('OK, found %s\n' % py_ver)
|
||||
if sys.version_info.major == 2:
|
||||
print(
|
||||
'\n'
|
||||
'WARNING: Python 2 support is deprecated and will be removed soon.\n'
|
||||
' You should really upgrade to python 3, NOW !\n'
|
||||
' ...you have been warned, continue at your own risk.\n'
|
||||
)
|
||||
time.sleep(5) # you really need to read the above message :P
|
||||
|
||||
|
||||
# === use cython or pre-generated C files ===
|
||||
USE_CYTHON = False
|
||||
if os.getenv('DISABLE_CYTHON') is not None:
|
||||
if os.path.exists(os.path.join(script_path, 'efl/eo/efl.eo.c')):
|
||||
USE_CYTHON = False
|
||||
else:
|
||||
sys.exit(
|
||||
'You have requested to use pregenerated files with DISABLE_CYTHON\n'
|
||||
'but the files are not available!\n'
|
||||
'Unset DISABLE_CYTHON from your build environment and try again.'
|
||||
)
|
||||
elif os.getenv('ENABLE_CYTHON') is not None:
|
||||
USE_CYTHON = True
|
||||
elif not os.path.exists(os.path.join(script_path, 'efl/eo/efl.eo.c')):
|
||||
USE_CYTHON = True
|
||||
elif os.path.exists(os.path.join(script_path, 'Makefile')):
|
||||
USE_CYTHON = True
|
||||
|
||||
|
||||
# === pkg-config helper ===
|
||||
def pkg_config(name, require, min_vers=None):
|
||||
try:
|
||||
sys.stdout.write("Checking for " + name + ": ")
|
||||
sys.stdout.write('Checking for %s: ' % name)
|
||||
|
||||
call = subprocess.Popen(["pkg-config", "--modversion", require],
|
||||
stdout=subprocess.PIPE)
|
||||
out, err = call.communicate()
|
||||
if call.returncode != 0:
|
||||
raise SystemExit("Did not find " + name + " with 'pkg-config'.")
|
||||
ver = cmd_output('pkg-config --modversion %s' % require)
|
||||
if not ver:
|
||||
raise SystemExit('Cannot find %s with pkg-config.' % name)
|
||||
|
||||
ver = out.decode("utf-8").strip()
|
||||
if min_vers is not None:
|
||||
assert (LooseVersion(ver) >= LooseVersion(min_vers)) is True
|
||||
|
||||
call = subprocess.Popen(["pkg-config", "--cflags", require],
|
||||
stdout=subprocess.PIPE)
|
||||
out, err = call.communicate()
|
||||
cflags = out.decode("utf-8").split()
|
||||
|
||||
call = subprocess.Popen(["pkg-config", "--libs", require],
|
||||
stdout=subprocess.PIPE)
|
||||
out, err = call.communicate()
|
||||
libs = out.decode("utf-8").split()
|
||||
|
||||
sys.stdout.write("OK, found " + ver + "\n")
|
||||
|
||||
cflags = list(set(cflags))
|
||||
assert LooseVersion(ver) >= LooseVersion(min_vers)
|
||||
sys.stdout.write('OK, found %s\n' % ver)
|
||||
|
||||
cflags = cmd_output('pkg-config --cflags %s' % require).split()
|
||||
libs = cmd_output('pkg-config --libs %s' % require).split()
|
||||
return (cflags, libs)
|
||||
except (OSError, subprocess.CalledProcessError):
|
||||
raise SystemExit("Did not find " + name + " with 'pkg-config'.")
|
||||
except (AssertionError):
|
||||
raise SystemExit("%s version mismatch. Found: %s Needed %s" % (
|
||||
name, ver, min_vers))
|
||||
raise SystemExit('Did not find %s with pkg-config.' % name)
|
||||
except AssertionError:
|
||||
raise SystemExit('%s version mismatch. Found: %s Needed %s' % (name, ver, min_vers))
|
||||
|
||||
|
||||
# === setup.py clean_generated_files command ===
|
||||
class CleanGenerated(Command):
|
||||
description = "Clean C and html files generated by Cython"
|
||||
user_options = []
|
||||
ext_modules = []
|
||||
py_modules = []
|
||||
packages = ['efl']
|
||||
common_cflags = [
|
||||
'-fno-var-tracking-assignments', # seems to lower the mem used during build
|
||||
'-Wno-misleading-indentation', # not needed (we don't indent the C code)
|
||||
'-Wno-deprecated-declarations', # we bind deprecated functions
|
||||
'-Wno-unused-variable', # eo_instance_from_object() is unused
|
||||
'-Wno-format-security', # some cc don't like the way cython use EINA_LOG macros
|
||||
# '-Werror', '-Wfatal-errors' # use this to stop build on first warnings
|
||||
]
|
||||
# remove clang unknown flags
|
||||
if os.getenv('CC') == 'clang':
|
||||
common_cflags.remove('-fno-var-tracking-assignments')
|
||||
|
||||
def initialize_options(self):
|
||||
pass
|
||||
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
def run(self):
|
||||
for lib in ("eo", "evas", "ecore", "ecore_x", "ecore_input", "ecore_con",
|
||||
"edje", "emotion", "elementary", "ethumb", "dbus_mainloop",
|
||||
"utils"):
|
||||
lib_path = os.path.join(script_path, "efl", lib)
|
||||
for root, dirs, files in os.walk(lib_path):
|
||||
for f in files:
|
||||
if f.endswith((".c", ".html")) and f != "e_dbus.c":
|
||||
self.remove(os.path.join(root, f))
|
||||
|
||||
def remove(self, fullpath):
|
||||
print("removing %s" % fullpath.replace(script_path, "").lstrip('/'))
|
||||
os.remove(fullpath)
|
||||
# force default visibility. See phab T504
|
||||
if os.getenv('CFLAGS') is not None and '-fvisibility=' in os.environ['CFLAGS']:
|
||||
os.environ['CFLAGS'] += ' -fvisibility=default'
|
||||
|
||||
|
||||
# === setup.py uninstall command ===
|
||||
RECORD_FILE = "installed_files-%d.%d.txt" % sys.version_info[:2]
|
||||
class Uninstall(Command):
|
||||
description = 'remove all the installed files recorded at installation time'
|
||||
user_options = []
|
||||
|
||||
def initialize_options(self):
|
||||
pass
|
||||
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
def remove_entry(self, entry):
|
||||
if os.path.isfile(entry):
|
||||
if set(('build', 'build_ext', 'install', 'bdist', 'bdist_wheel', 'sdist')) & set(sys.argv):
|
||||
# === check cython version ===
|
||||
sys.stdout.write('Checking for Cython: ')
|
||||
if USE_CYTHON:
|
||||
# check if cython is installed
|
||||
try:
|
||||
print("removing file %s" % entry)
|
||||
os.unlink(entry)
|
||||
except OSError as e:
|
||||
print(e)
|
||||
return
|
||||
import Cython
|
||||
import Cython.Compiler.Options
|
||||
except ImportError:
|
||||
raise SystemExit('not found! Needed >= %s' % (CYTHON_MIN_VERSION))
|
||||
|
||||
directory = os.path.dirname(entry)
|
||||
while os.listdir(directory) == []:
|
||||
try:
|
||||
print("removing empty directory %s" % directory)
|
||||
os.rmdir(directory)
|
||||
except OSError as e:
|
||||
print(e)
|
||||
break
|
||||
directory = os.path.dirname(directory)
|
||||
# check min version
|
||||
if LooseVersion(Cython.__version__) < LooseVersion(CYTHON_MIN_VERSION):
|
||||
raise SystemExit('too old! Found %s Needed %s' % (
|
||||
Cython.__version__, CYTHON_MIN_VERSION))
|
||||
|
||||
# check black-listed releases
|
||||
if Cython.__version__.startswith(CYTHON_BLACKLIST):
|
||||
raise SystemExit('found %s, its broken! Need another release' %
|
||||
Cython.__version__)
|
||||
|
||||
sys.stdout.write('OK, found %s\n' % Cython.__version__)
|
||||
MODULES_EXT = 'pyx'
|
||||
# Stop compilation on first error
|
||||
Cython.Compiler.Options.fast_fail = True
|
||||
# Generates HTML files with annotated source
|
||||
Cython.Compiler.Options.annotate = False
|
||||
# Set to False to disable docstrings
|
||||
Cython.Compiler.Options.docstrings = True
|
||||
|
||||
def run(self):
|
||||
if not os.path.exists(RECORD_FILE):
|
||||
print('ERROR: No %s file found!' % RECORD_FILE)
|
||||
else:
|
||||
for entry in open(RECORD_FILE).read().split():
|
||||
self.remove_entry(entry)
|
||||
sys.stdout.write('not needed, using pre-generated C files\n')
|
||||
MODULES_EXT = 'c'
|
||||
|
||||
# === Eina ===
|
||||
eina_cflags, eina_libs = pkg_config('Eina', 'eina', EFL_MIN_VER)
|
||||
|
||||
# === Eo ===
|
||||
eo_cflags, eo_libs = pkg_config('Eo', 'eo', EFL_MIN_VER)
|
||||
ext_modules.append(Extension(
|
||||
'efl.eo', ['efl/eo/efl.eo.' + MODULES_EXT],
|
||||
extra_compile_args=eo_cflags + common_cflags,
|
||||
extra_link_args=eo_libs
|
||||
))
|
||||
|
||||
# === Utilities ===
|
||||
ext_modules.append(Extension(
|
||||
'efl.utils.deprecated', ['efl/utils/deprecated.' + MODULES_EXT],
|
||||
extra_compile_args=eina_cflags + common_cflags,
|
||||
extra_link_args=eina_libs
|
||||
))
|
||||
ext_modules.append(Extension(
|
||||
'efl.utils.conversions', ['efl/utils/conversions.' + MODULES_EXT],
|
||||
extra_compile_args=eo_cflags + common_cflags,
|
||||
extra_link_args=eo_libs + eina_libs
|
||||
))
|
||||
ext_modules.append(Extension(
|
||||
'efl.utils.logger', ['efl/utils/logger.' + MODULES_EXT],
|
||||
extra_compile_args=eina_cflags + common_cflags,
|
||||
extra_link_args=eina_libs
|
||||
))
|
||||
py_modules.append('efl.utils.setup')
|
||||
packages.append('efl.utils')
|
||||
|
||||
# === Evas ===
|
||||
evas_cflags, evas_libs = pkg_config('Evas', 'evas', EFL_MIN_VER)
|
||||
ext_modules.append(Extension(
|
||||
'efl.evas', ['efl/evas/efl.evas.' + MODULES_EXT],
|
||||
extra_compile_args=evas_cflags + common_cflags,
|
||||
extra_link_args=evas_libs
|
||||
))
|
||||
|
||||
# === Ecore + EcoreFile ===
|
||||
ecore_cflags, ecore_libs = pkg_config('Ecore', 'ecore', EFL_MIN_VER)
|
||||
ecore_file_cflags, ecore_file_libs = pkg_config('EcoreFile', 'ecore-file', EFL_MIN_VER)
|
||||
ext_modules.append(Extension(
|
||||
'efl.ecore', ['efl/ecore/efl.ecore.' + MODULES_EXT],
|
||||
extra_compile_args=list(set(ecore_cflags + ecore_file_cflags + common_cflags)),
|
||||
extra_link_args=ecore_libs + ecore_file_libs
|
||||
))
|
||||
|
||||
# === Ecore Input ===
|
||||
ecore_input_cflags, ecore_input_libs = pkg_config('EcoreInput', 'ecore-input', EFL_MIN_VER)
|
||||
ext_modules.append(Extension(
|
||||
'efl.ecore_input', ['efl/ecore_input/efl.ecore_input.' + MODULES_EXT],
|
||||
extra_compile_args=ecore_input_cflags + common_cflags,
|
||||
extra_link_args=ecore_input_libs
|
||||
))
|
||||
|
||||
# === Ecore Con ===
|
||||
ecore_con_cflags, ecore_con_libs = pkg_config('EcoreCon', 'ecore-con', EFL_MIN_VER)
|
||||
ext_modules.append(Extension(
|
||||
'efl.ecore_con', ['efl/ecore_con/efl.ecore_con.' + MODULES_EXT],
|
||||
extra_compile_args=ecore_con_cflags + ecore_file_cflags + common_cflags,
|
||||
extra_link_args=ecore_con_libs
|
||||
))
|
||||
|
||||
# === Ecore X ===
|
||||
try:
|
||||
ecore_x_cflags, ecore_x_libs = pkg_config('EcoreX', 'ecore-x', EFL_MIN_VER)
|
||||
except SystemExit:
|
||||
print('Not found, will not be built')
|
||||
else:
|
||||
ext_modules.append(Extension(
|
||||
'efl.ecore_x', ['efl/ecore_x/efl.ecore_x.' + MODULES_EXT],
|
||||
extra_compile_args=ecore_x_cflags + common_cflags,
|
||||
extra_link_args=ecore_x_libs
|
||||
))
|
||||
|
||||
# === Ethumb ===
|
||||
ethumb_cflags, ethumb_libs = pkg_config('Ethumb', 'ethumb', EFL_MIN_VER)
|
||||
ext_modules.append(Extension(
|
||||
'efl.ethumb', ['efl/ethumb/efl.ethumb.' + MODULES_EXT],
|
||||
extra_compile_args=ethumb_cflags + common_cflags,
|
||||
extra_link_args=ethumb_libs
|
||||
))
|
||||
|
||||
# === Ethumb Client ===
|
||||
ethumb_cl_cflags, ethumb_cl_libs = pkg_config('Ethumb_Client', 'ethumb_client', EFL_MIN_VER)
|
||||
ext_modules.append(Extension(
|
||||
'efl.ethumb_client', ['efl/ethumb/efl.ethumb_client.' + MODULES_EXT],
|
||||
extra_compile_args=ethumb_cl_cflags + common_cflags,
|
||||
extra_link_args=ethumb_cl_libs
|
||||
))
|
||||
|
||||
# === Edje ===
|
||||
edje_cflags, edje_libs = pkg_config('Edje', 'edje', EFL_MIN_VER)
|
||||
ext_modules.append(Extension(
|
||||
'efl.edje', ['efl/edje/efl.edje.' + MODULES_EXT],
|
||||
extra_compile_args=edje_cflags + common_cflags,
|
||||
extra_link_args=edje_libs
|
||||
))
|
||||
|
||||
# === Edje_Edit ===
|
||||
ext_modules.append(Extension(
|
||||
'efl.edje_edit', ['efl/edje_edit/efl.edje_edit.' + MODULES_EXT],
|
||||
define_macros=[('EDJE_EDIT_IS_UNSTABLE_AND_I_KNOW_ABOUT_IT', None)],
|
||||
extra_compile_args=edje_cflags + common_cflags,
|
||||
extra_link_args=edje_libs
|
||||
))
|
||||
|
||||
# === Emotion ===
|
||||
emotion_cflags, emotion_libs = pkg_config('Emotion', 'emotion', EFL_MIN_VER)
|
||||
ext_modules.append(Extension(
|
||||
'efl.emotion', ['efl/emotion/efl.emotion.' + MODULES_EXT],
|
||||
extra_compile_args=emotion_cflags + common_cflags,
|
||||
extra_link_args=emotion_libs
|
||||
))
|
||||
|
||||
# === dbus mainloop integration ===
|
||||
dbus_cflags, dbus_libs = pkg_config('DBus', 'dbus-python', '0.83.0')
|
||||
ext_modules.append(Extension(
|
||||
'efl.dbus_mainloop', ['efl/dbus_mainloop/efl.dbus_mainloop.' + MODULES_EXT,
|
||||
'efl/dbus_mainloop/e_dbus.c'],
|
||||
extra_compile_args=dbus_cflags + ecore_cflags + common_cflags,
|
||||
extra_link_args=dbus_libs + ecore_libs
|
||||
))
|
||||
|
||||
# === Elementary ===
|
||||
elm_cflags, elm_libs = pkg_config('Elementary', 'elementary', EFL_MIN_VER)
|
||||
ext_modules.append(Extension(
|
||||
'efl.elementary.__init__', ['efl/elementary/__init__.' + MODULES_EXT],
|
||||
extra_compile_args=elm_cflags + common_cflags,
|
||||
extra_link_args=elm_libs
|
||||
))
|
||||
packages.append('efl.elementary')
|
||||
|
||||
# Cythonize all ext_modules
|
||||
if USE_CYTHON:
|
||||
from Cython.Build import cythonize
|
||||
ext_modules = cythonize(
|
||||
ext_modules,
|
||||
include_path=['include'],
|
||||
compiler_directives={
|
||||
#'c_string_type': 'unicode',
|
||||
#'c_string_encoding': 'utf-8',
|
||||
'embedsignature': True,
|
||||
'binding': True,
|
||||
'language_level': 2,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
# === setup.py test command ===
|
||||
|
@ -175,314 +325,115 @@ class Test(Command):
|
|||
pass
|
||||
|
||||
def run(self):
|
||||
import unittest
|
||||
|
||||
sys.path.insert(0, "build/lib.%s-%s-%d.%d" % (
|
||||
sys.path.insert(0, 'build/lib.%s-%s-%d.%d' % (
|
||||
platform.system().lower(), platform.machine(),
|
||||
sys.version_info[0], sys.version_info[1]))
|
||||
if "efl" in sys.modules:
|
||||
del sys.modules["efl"]
|
||||
if 'efl' in sys.modules:
|
||||
del sys.modules['efl']
|
||||
|
||||
loader = unittest.TestLoader()
|
||||
suite = loader.discover('./tests')
|
||||
runner = unittest.TextTestRunner(verbosity=1, buffer=True)
|
||||
result = runner.run(suite)
|
||||
runner.run(suite)
|
||||
|
||||
|
||||
# === use cython or pre-generated C files ===
|
||||
USE_CYTHON = False
|
||||
if os.getenv("DISABLE_CYTHON") is not None:
|
||||
if os.path.exists(os.path.join(script_path, "efl/eo/efl.eo.c")):
|
||||
USE_CYTHON = False
|
||||
else:
|
||||
sys.exit(
|
||||
"You have requested to use pregenerated files with DISABLE_CYTHON\n"
|
||||
"but the files are not available!\n"
|
||||
"Unset DISABLE_CYTHON from your build environment and try again.")
|
||||
elif os.getenv("ENABLE_CYTHON") is not None:
|
||||
USE_CYTHON = True
|
||||
elif not os.path.exists(os.path.join(script_path, "efl/eo/efl.eo.c")):
|
||||
USE_CYTHON = True
|
||||
elif os.path.exists(os.path.join(script_path, "Makefile")):
|
||||
USE_CYTHON = True
|
||||
|
||||
|
||||
ext_modules = []
|
||||
py_modules = []
|
||||
packages = ["efl"]
|
||||
common_cflags = [
|
||||
"-fno-var-tracking-assignments", # seems to lower the mem used during build
|
||||
"-Wno-misleading-indentation", # not needed (we don't indent the C code)
|
||||
"-Wno-deprecated-declarations", # we bind deprecated functions
|
||||
"-Wno-unused-variable", # eo_instance_from_object() is unused
|
||||
"-Wno-format-security", # some cc don't like the way cython use EINA_LOG macros
|
||||
# "-Werror", "-Wfatal-errors" # use this to stop build on first warnings
|
||||
]
|
||||
# remove clang unknown flags
|
||||
if os.getenv("CC") == "clang":
|
||||
common_cflags.remove('-fno-var-tracking-assignments')
|
||||
|
||||
|
||||
if set(("build", "build_ext", "install", "bdist", "sdist")) & set(sys.argv):
|
||||
sys.stdout.write("Python-EFL: %s\n" % RELEASE)
|
||||
|
||||
# === Python ===
|
||||
sys.stdout.write("Checking for Python: ")
|
||||
py_ver = sys.version_info
|
||||
py_ver = "%s.%s.%s" % (py_ver[0], py_ver[1], py_ver[2])
|
||||
if sys.hexversion < 0x020600f0:
|
||||
raise SystemExit("too old. Found: %s Need at least 2.6.0" % py_ver)
|
||||
else:
|
||||
sys.stdout.write("OK, found %s\n" % py_ver)
|
||||
|
||||
# === Cython ===
|
||||
sys.stdout.write("Checking for Cython: ")
|
||||
if USE_CYTHON:
|
||||
# check if cython is installed
|
||||
# === setup.py build_doc command ===
|
||||
try:
|
||||
from Cython.Distutils import Extension, build_ext
|
||||
from Cython.Build import cythonize
|
||||
import Cython.Compiler.Options
|
||||
from sphinx.setup_command import BuildDoc
|
||||
except ImportError:
|
||||
raise SystemExit("not found! Needed >= %s" % (CYTHON_MIN_VERSION))
|
||||
class BuildDoc(Command):
|
||||
description = 'build docs using sphinx, that must be installed.'
|
||||
version = ''
|
||||
release = ''
|
||||
user_options = []
|
||||
|
||||
# check min version
|
||||
if LooseVersion(Cython.__version__) < LooseVersion(CYTHON_MIN_VERSION):
|
||||
raise SystemExit("too old! Found %s Needed %s" % (
|
||||
Cython.__version__, CYTHON_MIN_VERSION))
|
||||
def initialize_options(self):
|
||||
pass
|
||||
|
||||
# check black-listed releases
|
||||
if Cython.__version__.startswith(CYTHON_BLACKLIST):
|
||||
raise SystemExit("found %s, it's broken! Need another release" %
|
||||
Cython.__version__)
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
sys.stdout.write("OK, found %s\n" % Cython.__version__)
|
||||
module_suffix = ".pyx"
|
||||
# Stop compilation on first error
|
||||
Cython.Compiler.Options.fast_fail = True
|
||||
# Generates HTML files with annotated source
|
||||
Cython.Compiler.Options.annotate = False
|
||||
# Set to False to disable docstrings
|
||||
Cython.Compiler.Options.docstrings = True
|
||||
def run(self):
|
||||
print('Error: sphinx not found')
|
||||
|
||||
else:
|
||||
sys.stdout.write("not needed, using pre-generated C files\n")
|
||||
module_suffix = ".c"
|
||||
|
||||
# === Eina ===
|
||||
eina_cflags, eina_libs = pkg_config('Eina', 'eina', EFL_MIN_VER)
|
||||
# === setup.py clean_generated_files command ===
|
||||
class CleanGenerated(Command):
|
||||
description = 'Clean C and html files generated by Cython'
|
||||
user_options = []
|
||||
|
||||
# === Eo ===
|
||||
eo_cflags, eo_libs = pkg_config('Eo', 'eo', EFL_MIN_VER)
|
||||
eo_ext = Extension("efl.eo",
|
||||
["efl/eo/efl.eo" + module_suffix],
|
||||
define_macros=[
|
||||
('EFL_BETA_API_SUPPORT', 1),
|
||||
('EFL_EO_API_SUPPORT', 1)
|
||||
],
|
||||
include_dirs=['include/'],
|
||||
extra_compile_args=eo_cflags + common_cflags,
|
||||
extra_link_args=eo_libs + eina_libs
|
||||
)
|
||||
ext_modules.append(eo_ext)
|
||||
def initialize_options(self):
|
||||
pass
|
||||
|
||||
# === Utilities ===
|
||||
utils_ext = [
|
||||
Extension("efl.utils.deprecated",
|
||||
["efl/utils/deprecated" + module_suffix],
|
||||
include_dirs=['include/'],
|
||||
extra_compile_args=eina_cflags + common_cflags,
|
||||
extra_link_args=eina_libs),
|
||||
Extension("efl.utils.conversions",
|
||||
["efl/utils/conversions" + module_suffix],
|
||||
include_dirs=['include/'],
|
||||
extra_compile_args=eo_cflags + common_cflags,
|
||||
extra_link_args=eo_libs + eina_libs),
|
||||
Extension("efl.utils.logger",
|
||||
["efl/utils/logger" + module_suffix],
|
||||
include_dirs=['include/'],
|
||||
extra_compile_args=eina_cflags + common_cflags,
|
||||
extra_link_args=eina_libs),
|
||||
]
|
||||
ext_modules.extend(utils_ext)
|
||||
py_modules.append("efl.utils.setup")
|
||||
packages.append("efl.utils")
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
# === Evas ===
|
||||
evas_cflags, evas_libs = pkg_config('Evas', 'evas', EFL_MIN_VER)
|
||||
evas_ext = Extension("efl.evas",
|
||||
["efl/evas/efl.evas" + module_suffix],
|
||||
define_macros=[
|
||||
('EFL_BETA_API_SUPPORT', 1),
|
||||
('EFL_EO_API_SUPPORT', 1)
|
||||
],
|
||||
include_dirs=['include/'],
|
||||
extra_compile_args=evas_cflags + common_cflags,
|
||||
extra_link_args=evas_libs + eina_libs + eo_libs)
|
||||
ext_modules.append(evas_ext)
|
||||
def run(self):
|
||||
for lib in ('eo', 'evas', 'ecore', 'ecore_x', 'ecore_input', 'ecore_con', 'edje',
|
||||
'emotion', 'elementary', 'ethumb', 'dbus_mainloop', 'utils'):
|
||||
lib_path = os.path.join(script_path, 'efl', lib)
|
||||
for root, _dirs, files in os.walk(lib_path):
|
||||
for fname in files:
|
||||
if fname.endswith(('.c', '.html')) and fname != 'e_dbus.c':
|
||||
self.remove(os.path.join(root, fname))
|
||||
|
||||
# === Ecore ===
|
||||
ecore_cflags, ecore_libs = pkg_config('Ecore', 'ecore', EFL_MIN_VER)
|
||||
ecore_file_cflags, ecore_file_libs = pkg_config('EcoreFile', 'ecore-file',
|
||||
EFL_MIN_VER)
|
||||
ecore_ext = Extension("efl.ecore",
|
||||
["efl/ecore/efl.ecore" + module_suffix],
|
||||
include_dirs=['include/'],
|
||||
extra_compile_args=list(set(ecore_cflags +
|
||||
ecore_file_cflags +
|
||||
common_cflags)),
|
||||
extra_link_args=ecore_libs + ecore_file_libs +
|
||||
eina_libs + evas_libs)
|
||||
ext_modules.append(ecore_ext)
|
||||
def remove(self, fullpath):
|
||||
print('removing %s' % fullpath.replace(script_path, '').lstrip('/'))
|
||||
os.remove(fullpath)
|
||||
|
||||
# === Ecore Input ===
|
||||
ecore_input_cflags, ecore_input_libs = pkg_config('EcoreInput',
|
||||
'ecore-input',
|
||||
EFL_MIN_VER)
|
||||
ecore_input_ext = Extension("efl.ecore_input",
|
||||
["efl/ecore_input/efl.ecore_input" + module_suffix],
|
||||
include_dirs=['include/'],
|
||||
extra_compile_args=list(set(ecore_cflags +
|
||||
ecore_file_cflags +
|
||||
ecore_input_cflags +
|
||||
common_cflags)),
|
||||
extra_link_args=ecore_libs + ecore_file_libs +
|
||||
ecore_input_libs)
|
||||
ext_modules.append(ecore_input_ext)
|
||||
|
||||
# === Ecore Con ===
|
||||
ecore_con_cflags, ecore_con_libs = pkg_config('EcoreCon', 'ecore-con',
|
||||
EFL_MIN_VER)
|
||||
ecore_con_ext = Extension("efl.ecore_con",
|
||||
["efl/ecore_con/efl.ecore_con" + module_suffix],
|
||||
include_dirs=['include/'],
|
||||
extra_compile_args=list(set(ecore_cflags +
|
||||
ecore_file_cflags +
|
||||
ecore_con_cflags +
|
||||
common_cflags)),
|
||||
extra_link_args=ecore_libs + ecore_file_libs +
|
||||
ecore_con_libs + eina_libs)
|
||||
ext_modules.append(ecore_con_ext)
|
||||
# === setup.py uninstall command ===
|
||||
RECORD_FILE = 'installed_files-%d.%d.txt' % sys.version_info[:2]
|
||||
class Uninstall(Command):
|
||||
description = 'remove all the installed files recorded at installation time'
|
||||
user_options = []
|
||||
|
||||
# === Ecore X ===
|
||||
def initialize_options(self):
|
||||
pass
|
||||
|
||||
def finalize_options(self):
|
||||
pass
|
||||
|
||||
def remove_entry(self, entry):
|
||||
if os.path.isfile(entry):
|
||||
try:
|
||||
ecore_x_cflags, ecore_x_libs = pkg_config('EcoreX', 'ecore-x',
|
||||
EFL_MIN_VER)
|
||||
except SystemExit:
|
||||
print("Not found, will not be built")
|
||||
print('removing file %s' % entry)
|
||||
os.unlink(entry)
|
||||
except OSError as err:
|
||||
print(err)
|
||||
return
|
||||
|
||||
directory = os.path.dirname(entry)
|
||||
while os.listdir(directory) == []:
|
||||
try:
|
||||
print('removing empty directory %s' % directory)
|
||||
os.rmdir(directory)
|
||||
except OSError as err:
|
||||
print(err)
|
||||
break
|
||||
directory = os.path.dirname(directory)
|
||||
|
||||
def run(self):
|
||||
if not os.path.exists(RECORD_FILE):
|
||||
print('ERROR: No %s file found!' % RECORD_FILE)
|
||||
else:
|
||||
ecore_x_ext = Extension("efl.ecore_x",
|
||||
["efl/ecore_x/efl.ecore_x" + module_suffix],
|
||||
include_dirs=['include/'],
|
||||
extra_compile_args=list(set(ecore_cflags +
|
||||
ecore_file_cflags +
|
||||
ecore_x_cflags +
|
||||
ecore_input_cflags +
|
||||
common_cflags)),
|
||||
extra_link_args=ecore_libs + ecore_file_libs +
|
||||
ecore_x_libs + ecore_input_libs +
|
||||
eina_libs + evas_libs)
|
||||
ext_modules.append(ecore_x_ext)
|
||||
|
||||
# === Ethumb ===
|
||||
ethumb_cflags, ethumb_libs = pkg_config('Ethumb', 'ethumb', EFL_MIN_VER)
|
||||
ethumb_ext = Extension("efl.ethumb",
|
||||
["efl/ethumb/efl.ethumb" + module_suffix],
|
||||
include_dirs=['include/'],
|
||||
extra_compile_args=ethumb_cflags + common_cflags,
|
||||
extra_link_args=ethumb_libs + eina_libs)
|
||||
ext_modules.append(ethumb_ext)
|
||||
|
||||
# === Ethumb Client ===
|
||||
ethumb_client_cflags, ethumb_client_libs = pkg_config('Ethumb_Client',
|
||||
'ethumb_client', EFL_MIN_VER)
|
||||
ethumb_client_ext = Extension("efl.ethumb_client",
|
||||
["efl/ethumb/efl.ethumb_client" + module_suffix],
|
||||
include_dirs=['include/'],
|
||||
extra_compile_args=ethumb_client_cflags +
|
||||
common_cflags,
|
||||
extra_link_args=ethumb_client_libs + eina_libs)
|
||||
ext_modules.append(ethumb_client_ext)
|
||||
|
||||
# === Edje ===
|
||||
edje_cflags, edje_libs = pkg_config('Edje', 'edje', EFL_MIN_VER)
|
||||
edje_ext = Extension("efl.edje",
|
||||
["efl/edje/efl.edje" + module_suffix],
|
||||
include_dirs=['include/'],
|
||||
extra_compile_args=edje_cflags + common_cflags,
|
||||
extra_link_args=edje_libs + eina_libs + evas_libs)
|
||||
ext_modules.append(edje_ext)
|
||||
|
||||
# === Edje_Edit ===
|
||||
edje_edit_ext = Extension("efl.edje_edit",
|
||||
["efl/edje_edit/efl.edje_edit" + module_suffix],
|
||||
define_macros=[('EDJE_EDIT_IS_UNSTABLE_AND_I_KNOW_ABOUT_IT', None)],
|
||||
include_dirs=['include/'],
|
||||
extra_compile_args=edje_cflags + common_cflags,
|
||||
extra_link_args=edje_libs + eina_libs + evas_libs)
|
||||
ext_modules.append(edje_edit_ext)
|
||||
|
||||
# === Emotion ===
|
||||
emotion_cflags, emotion_libs = pkg_config('Emotion', 'emotion', EFL_MIN_VER)
|
||||
emotion_ext = Extension("efl.emotion",
|
||||
["efl/emotion/efl.emotion" + module_suffix],
|
||||
include_dirs=['include/'],
|
||||
extra_compile_args=emotion_cflags + common_cflags,
|
||||
extra_link_args=emotion_libs + eina_libs + evas_libs)
|
||||
ext_modules.append(emotion_ext)
|
||||
|
||||
# === dbus mainloop integration ===
|
||||
dbus_cflags, dbus_libs = pkg_config('DBus', 'dbus-python', "0.83.0")
|
||||
dbus_ml_ext = Extension("efl.dbus_mainloop",
|
||||
["efl/dbus_mainloop/efl.dbus_mainloop" + module_suffix,
|
||||
"efl/dbus_mainloop/e_dbus.c"],
|
||||
extra_compile_args=list(set(dbus_cflags +
|
||||
ecore_cflags +
|
||||
common_cflags)),
|
||||
extra_link_args=dbus_libs + ecore_libs)
|
||||
ext_modules.append(dbus_ml_ext)
|
||||
|
||||
# === Elementary ===
|
||||
elm_cflags, elm_libs = pkg_config('Elementary', 'elementary', ELM_MIN_VER)
|
||||
e = Extension("efl.elementary.__init__",
|
||||
["efl/elementary/__init__" + module_suffix],
|
||||
define_macros=[
|
||||
('EFL_BETA_API_SUPPORT', 1),
|
||||
('EFL_EO_API_SUPPORT', 1)
|
||||
],
|
||||
include_dirs=["include/"],
|
||||
extra_compile_args=elm_cflags + common_cflags,
|
||||
extra_link_args=elm_libs + eina_libs + eo_libs + evas_libs)
|
||||
ext_modules.append(e)
|
||||
|
||||
packages.append("efl.elementary")
|
||||
|
||||
# Cythonize all the external modules (if needed)
|
||||
if USE_CYTHON:
|
||||
ext_modules = cythonize(ext_modules,
|
||||
include_path=["include"],
|
||||
compiler_directives={
|
||||
#"c_string_type": "unicode",
|
||||
#"c_string_encoding": "utf-8",
|
||||
"embedsignature": True,
|
||||
"binding": True,
|
||||
"language_level": 2,
|
||||
})
|
||||
for entry in open(RECORD_FILE).read().split():
|
||||
self.remove_entry(entry)
|
||||
|
||||
|
||||
setup(
|
||||
name="python-efl",
|
||||
fullname="Python bindings for Enlightenment Foundation Libraries",
|
||||
description="Python bindings for Enlightenment Foundation Libraries",
|
||||
long_description=open(os.path.join(script_path, 'README.md')).read(),
|
||||
name='python-efl',
|
||||
fullname='Python bindings for Enlightenment Foundation Libraries',
|
||||
description='Python bindings for Enlightenment Foundation Libraries',
|
||||
long_description=read_file('README.md'),
|
||||
version=RELEASE,
|
||||
author='Davide Andreoli, Kai Huuhko, and others',
|
||||
author_email="dave@gurumeditation.it, kai.huuhko@gmail.com",
|
||||
contact="Enlightenment developer mailing list",
|
||||
contact_email="enlightenment-devel@lists.sourceforge.net",
|
||||
url="http://www.enlightenment.org",
|
||||
license="GNU Lesser General Public License (LGPL)",
|
||||
keywords="efl wrapper binding enlightenment eo evas ecore edje emotion elementary ethumb",
|
||||
author_email='dave@gurumeditation.it, kai.huuhko@gmail.com',
|
||||
contact='Enlightenment developer mailing list',
|
||||
contact_email='enlightenment-devel@lists.sourceforge.net',
|
||||
url='http://www.enlightenment.org',
|
||||
license='GNU Lesser General Public License (LGPL)',
|
||||
keywords='efl wrapper binding enlightenment eo evas ecore edje emotion elementary ethumb',
|
||||
classifiers=[
|
||||
'Development Status :: 5 - Production/Stable',
|
||||
'Environment :: X11 Applications',
|
||||
|
@ -503,11 +454,10 @@ setup(
|
|||
'build_doc': BuildDoc,
|
||||
'clean_generated_files': CleanGenerated,
|
||||
'uninstall': Uninstall,
|
||||
'build_ext': build_ext,
|
||||
},
|
||||
command_options={
|
||||
'build_doc': {
|
||||
'version': ('setup.py', VERSION),
|
||||
'version': ('setup.py', RELEASE),
|
||||
'release': ('setup.py', RELEASE),
|
||||
},
|
||||
'install': {
|
||||
|
@ -517,4 +467,5 @@ setup(
|
|||
packages=packages,
|
||||
ext_modules=ext_modules,
|
||||
py_modules=py_modules,
|
||||
zip_safe=False,
|
||||
)
|
||||
|
|
Loading…
Reference in New Issue