From 8ed37421c6728551bfe14dd57532cc546345af00 Mon Sep 17 00:00:00 2001 From: Kai Huuhko Date: Fri, 3 Oct 2014 18:46:58 +0300 Subject: [PATCH] Eolian: WIP --- efl-eo-files | 154 +++++++++++++++ efl/ecore/con/__init__.py | 0 efl/ecore/idle/__init__.py | 0 efl/evas/efl.evas.pyx | 2 +- efl/utils/conversions.pyx | 8 +- scripts/eolian_generate.py | 379 ++++++++++++++++++------------------- setup.py | 151 ++++++++++++--- 7 files changed, 466 insertions(+), 228 deletions(-) create mode 100644 efl-eo-files create mode 100644 efl/ecore/con/__init__.py create mode 100644 efl/ecore/idle/__init__.py diff --git a/efl-eo-files b/efl-eo-files new file mode 100644 index 0000000..309b543 --- /dev/null +++ b/efl-eo-files @@ -0,0 +1,154 @@ +./ecore_audio/ecore_audio_in.eo +./ecore_audio/ecore_audio_out.eo +./ecore_audio/ecore_audio.eo +./ecore_audio/ecore_audio_out_sndfile.eo +./ecore_audio/ecore_audio_in_sndfile.eo +./ecore_audio/ecore_audio_in_tone.eo +./ecore_audio/ecore_audio_out_pulse.eo +./ecore_con/ecore_con_client.eo +./ecore_con/ecore_con_connector.eo +./ecore_con/ecore_con_base.eo +./ecore_con/ecore_con_server.eo +./ecore_con/ecore_con_url.eo +./efl/interfaces/efl_control.eo +./efl/interfaces/efl_image.eo +./efl/interfaces/efl_text.eo +./efl/interfaces/efl_text_properties.eo +./efl/interfaces/efl_player.eo +./efl/interfaces/efl_file.eo +./emotion/emotion_object.eo +./ecore/ecore_parent.eo +./ecore/ecore_mainloop.eo +./ecore/ecore_exe.eo +./ecore/ecore_poller.eo +./ecore/ecore_idle_enterer.eo +./ecore/ecore_idle_exiter.eo +./ecore/ecore_idler.eo +./ecore/ecore_timer.eo +./ecore/ecore_job.eo +./ecore/ecore_animator.eo +./eo/eo_abstract_class.eo +./eo/eo_base.eo +./evas/canvas/evas_textblock.eo +./evas/canvas/evas_line.eo +./evas/canvas/evas_3d_scene.eo +./evas/canvas/evas_text.eo +./evas/canvas/evas_draggable_interface.eo +./evas/canvas/evas_object.eo +./evas/canvas/evas_3d_light.eo +./evas/canvas/evas_3d_mesh.eo +./evas/canvas/evas_scrollable_interface.eo +./evas/canvas/evas_image.eo +./evas/canvas/evas_clickable_interface.eo +./evas/canvas/evas_rectangle.eo +./evas/canvas/evas_signal_interface.eo +./evas/canvas/evas_smart_clipped.eo +./evas/canvas/evas_3d_object.eo +./evas/canvas/evas_3d_node.eo +./evas/canvas/evas_canvas.eo +./evas/canvas/evas_3d_texture.eo +./evas/canvas/evas_common_interface.eo +./evas/canvas/evas_object_smart.eo +./evas/canvas/evas_out.eo +./evas/canvas/evas_table.eo +./evas/canvas/evas_polygon.eo +./evas/canvas/evas_3d_camera.eo +./evas/canvas/evas_box.eo +./evas/canvas/evas_3d_material.eo +./evas/canvas/evas_selectable_interface.eo +./evas/canvas/evas_grid.eo +./evas/canvas/evas_zoomable_interface.eo +./evas/canvas/evas_textgrid.eo +./edje/edje_object.eo +./edje/edje_edit.eo +./elm_multibuttonentry.eo +./elm_map.eo +./elm_genlist.eo +./elm_pan.eo +./elm_grid.eo +./elm_app_server_view.eo +./elm_popup.eo +./elm_container.eo +./elm_entry.eo +./elm_interface_atspi_value.eo +./elm_interface_atspi_editable_text.eo +./elm_actionslider.eo +./elm_plug.eo +./elm_icon.eo +./elm_interface_atspi_image.eo +./elm_diskselector.eo +./elm_slider.eo +./elm_interface_atspi_selection.eo +./elm_label.eo +./elm_prefs.eo +./elm_dayselector.eo +./elm_radio.eo +./elm_interface_atspi_accessible.eo +./elm_route.eo +./elm_list.eo +./elm_clock.eo +./elm_ctxpopup.eo +./elm_app_client_view.eo +./elm_flipselector.eo +./elm_colorselector.eo +./elm_interface_atspi_text.eo +./elm_mapbuf.eo +./elm_player.eo +./elm_index.eo +./elm_photocam_pan.eo +./elm_table.eo +./elm_interface_fileselector.eo +./elm_scroller.eo +./elm_systray.eo +./elm_hoversel.eo +./elm_fileselector.eo +./elm_widget.eo +./elm_frame.eo +./elm_panes.eo +./elm_interface_atspi_action.eo +./elm_web.eo +./elm_toolbar.eo +./elm_menu.eo +./elm_fileselector_entry.eo +./elm_datetime.eo +./elm_win.eo +./elm_separator.eo +./elm_glview.eo +./elm_panel.eo +./elm_interface_atspi_window.eo +./elm_button.eo +./elm_check.eo +./elm_interface_atspi_widget.eo +./elm_inwin.eo +./elm_gesture_layer.eo +./elm_hover.eo +./elm_photocam.eo +./elm_interface_atspi_widget_action.eo +./elm_conformant.eo +./elm_segment_control.eo +./elm_slideshow.eo +./elm_gengrid.eo +./elm_app_server.eo +./elm_progressbar.eo +./elm_atspi_app_object.eo +./elm_bg.eo +./elm_photo.eo +./elm_bubble.eo +./elm_interface_scrollable.eo +./elm_app_client.eo +./elm_notify.eo +./elm_access.eo +./elm_flip.eo +./elm_video.eo +./elm_gengrid_pan.eo +./elm_image.eo +./elm_calendar.eo +./elm_naviframe.eo +./elm_layout.eo +./elm_map_pan.eo +./elm_genlist_pan.eo +./elm_interface_atspi_component.eo +./elm_spinner.eo +./elm_thumb.eo +./elm_fileselector_button.eo +./elm_box.eo diff --git a/efl/ecore/con/__init__.py b/efl/ecore/con/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/efl/ecore/idle/__init__.py b/efl/ecore/idle/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/efl/evas/efl.evas.pyx b/efl/evas/efl.evas.pyx index 3db56fe..c3d09ae 100644 --- a/efl/evas/efl.evas.pyx +++ b/efl/evas/efl.evas.pyx @@ -25,7 +25,7 @@ from cpython cimport PyUnicode_AsUTF8String from efl.c_eo cimport eo_add_ref, Eo, Eo_Class, _eo_do_start, _eo_do_end, \ CFILE, CFUNC, CLINE, Eo_Event_Description from efl.eo cimport object_from_instance, _object_mapping_register, \ - _register_decorated_callbacks, _Eo + _register_decorated_callbacks, _Eo, instance_from_object from efl.utils.conversions cimport _ctouni from efl.eina cimport eina_hash_add, eina_hash_del, EINA_FALSE diff --git a/efl/utils/conversions.pyx b/efl/utils/conversions.pyx index 400801d..3e77ec1 100644 --- a/efl/utils/conversions.pyx +++ b/efl/utils/conversions.pyx @@ -19,8 +19,8 @@ from libc.stdlib cimport malloc from libc.string cimport strdup from cpython cimport PyUnicode_AsUTF8String -from efl.c_eo cimport Eo as cEo -from efl.eo cimport Eo, object_from_instance +from efl.c_eo cimport Eo +from efl.eo cimport _Eo, object_from_instance from efl.eina cimport eina_list_append, eina_stringshare_add cdef unicode _touni(char* s): @@ -158,7 +158,7 @@ cdef Eina_List *python_list_strings_to_eina_list(list strings): cdef list eina_list_objects_to_python_list(const Eina_List *lst): cdef list ret = list() while lst: - ret.append(object_from_instance(lst.data)) + ret.append(object_from_instance(lst.data)) lst = lst.next return ret @@ -166,7 +166,7 @@ cdef list eina_list_objects_to_python_list(const Eina_List *lst): cdef Eina_List *python_list_objects_to_eina_list(list objects): cdef: Eina_List *lst = NULL - Eo o + _Eo o if objects is None: return NULL diff --git a/scripts/eolian_generate.py b/scripts/eolian_generate.py index ce57121..b001b35 100755 --- a/scripts/eolian_generate.py +++ b/scripts/eolian_generate.py @@ -3,22 +3,8 @@ import os import textwrap from keyword import iskeyword -#from traceback import format_exc -from collections import Counter - -from argparse import ArgumentParser -parser = ArgumentParser(description="Python generator for eolian") -parser.add_argument( - '-v', '--verbose', action="count", help="max is -vvv") -parser.add_argument( - '--enable-docstrings', action="store_true") -parser.add_argument( - '--with-legacy-api', action="store_true") -parser.add_argument( - '-o', '--output', default="/tmp", help="defaults to /tmp") -parser.add_argument('paths', nargs="+") -args = parser.parse_args() +# from collections import Counter import logging handler = logging.StreamHandler() @@ -26,20 +12,15 @@ formatter = logging.Formatter("%(name)s %(levelname)s: %(message)s") handler.setFormatter(formatter) log = logging.getLogger("efl.eolian") log.addHandler(handler) - -level = logging.ERROR -if args.verbose: - level -= 10 * args.verbose -log.setLevel(level) +log_level = logging.ERROR +log.setLevel(log_level) from efl import eolian eolian.init() - from converters import convert_in_param, convert_out_param, conv_type_ret, \ conv_cls_name, EolianTypeError, event_conversion_get - PY_EFL_TOP_LEVEL_PACKAGE = "efl" generated_pxis = {} @@ -104,16 +85,9 @@ class Generator(object): #self.write(docs, wrapped=True) #self.write('"""') - def printout(self, filepath=None, append=False): + def printout(self): result = "\n".join(self.result) - if filepath: - mode = "a" if append else "w" - with open(filepath, mode) as f: - f.write(result.encode("utf-8")) - f.write("\n") - log.info(filepath + " written") - else: - print(result) + return result def clear(self): self.result = [] @@ -537,7 +511,7 @@ class Class(object): self = klass.__new__(klass) self.__init__() - class_counter[cls.name] += 1 + # class_counter[cls.name] += 1 self.c_name = cls.name self.full_c_name = cls.full_name @@ -572,7 +546,7 @@ class Class(object): cls.name, prop.name ) continue - function_counter["_".join((prefix, prop.name))] += 1 + # function_counter["_".join((prefix, prop.name))] += 1 try: o = Property(prop, prefix) except Exception: @@ -591,7 +565,7 @@ class Class(object): cls.name, method.name ) continue - function_counter["_".join((prefix, method.name))] += 1 + # function_counter["_".join((prefix, method.name))] += 1 try: o = Function(method, prefix) except Exception: @@ -601,7 +575,7 @@ class Class(object): continue self.methods.append(o) - generated_class_counter[cls.name] += 1 + # generated_class_counter[cls.name] += 1 for event in cls.events: self.events.append(Event(event)) @@ -699,8 +673,8 @@ class Class(object): log.info("Skipping %r because of unknown type", o) except Exception: log.exception("Error while generating %r", o) - else: - generated_function_counter["_".join((o.prefix, o.name))] += 1 + # else: + # generated_function_counter["_".join((o.prefix, o.name))] += 1 gen.dedent() gen.write() @@ -749,92 +723,6 @@ class Class(object): gen.write() -class File(object): - def __init__(self, filepath): - self.filepath = filepath - self.pyxgen = PyxGenerator() - self.pygen = Generator() - self.cls = eolian.Class.get_by_file(filepath) - if not self.cls: - raise RuntimeError("Could not get class from %s" % (filepath)) - if self.cls.full_name.startswith("Eo."): - raise EolianSkip("Skipping Eo class") - self.gencls = Class.parse(self.cls) - - def cdefs_generate(self): - gen = self.pyxgen - - gen.write('cdef extern from "%s":' % (self.gencls.header_path)) - gen.indent() - - for i in eolian.type_aliases_get_by_file(self.filepath): - base = i.base_type - if base.type == eolian.TypeType.REGULAR: - gen.write("ctypedef %s %s" % (base.name, i.name)) - elif base.type == eolian.TypeType.FUNCTION: - ret_type = base.return_type - if ret_type: - ret = ret_type.c_type - else: - ret = "void" - gen.write("ctypedef %s (*%s)(%s)" % ( - ret, - i.name, - ", ".join([i.c_type for i in base.arguments]))) - elif base.type == eolian.TypeType.STRUCT: - gen.write("ctypedef struct %s:" % (i.name)) - gen.indent() - for f in base.struct_fields: - gen.write("%s %s" % (f.type.c_type, f.name)) - gen.dedent() - else: - log.error("Unhandled alias! %s %s %s %s", i.name, i.full_name, i.filename, i.description) - for i in eolian.type_structs_get_by_file(self.filepath): - log.error("Type struct not handled! %s %s %s %s", i.name, i.full_name, i.filename, i.description) - for i in eolian.type_enums_get_by_file(self.filepath): - log.error("Type enum not handled! %s %s %s %s", i.name, i.full_name, i.filename, i.description) - for i in eolian.variable_constants_get_by_file(self.filepath): - log.error("Variable constant not handled! %s", i) - for i in eolian.variable_globals_get_by_file(self.filepath): - log.error("Variable global not handled! %s", i) - - self.gencls.cdefs_generate(gen) - - gen.dedent() - gen.write() - - def pyx_generate(self): - self.gencls.pyx_generate(self.pyxgen) - - path = [] - cls_name = self.cls.name.lower() - filename = "generated_" + cls_name + ".pxi" - for ns in self.cls.namespaces: - path.append(ns.lower()) - if not path: - log.warning("Class %s has no namespaces defined" % (self.cls.name)) - nstmp = cls_name.partition("_") - path.append(nstmp[0]) - filename = "generated_" + nstmp[2] + ".pxi" - # else: - # namespace = ".".join(namespaces) - # filename = ".".join((namespace, filename)) - # path.append(filename) - path = os.path.join(*path) - pxi_path = os.path.join(args.output, path, filename) - - self.pyxgen.printout(filepath=pxi_path) - - generated_pxis.setdefault(os.path.join(path), []).append((path, filename, self.cls)) - - # def py_generate(self): - # py_path = os.path.join(args.output, "__init__" + ".py") - - # self.gencls.py_generate(self.pygen) - - # self.pygen.printout(filepath=py_path, append=True) - - class Event(object): def __init__(self, event): self.event = event @@ -875,81 +763,182 @@ class Event(object): gen.write() -class_counter = Counter() -generated_class_counter = Counter() -function_counter = Counter() -generated_function_counter = Counter() +class File(object): + def __init__(self, filename): + self.filename = filename + self.pyxgen = PyxGenerator() + self.pygen = Generator() + self.cls = eolian.Class.get_by_file(filename) + if not self.cls: + raise RuntimeError("Could not get class from %s" % (filename)) + if self.cls.full_name.startswith("Eo."): + raise EolianSkip("Skipping Eo class") + self.gencls = Class.parse(self.cls) + + def cdefs_generate(self): + gen = self.pyxgen + + gen.write('cdef extern from "%s":' % (self.gencls.header_path)) + gen.indent() + + for i in eolian.type_aliases_get_by_file(self.filename): + base = i.base_type + if base.type == eolian.TypeType.REGULAR: + gen.write("ctypedef %s %s" % (base.name, i.name)) + elif base.type == eolian.TypeType.FUNCTION: + ret_type = base.return_type + if ret_type: + ret = ret_type.c_type + else: + ret = "void" + gen.write("ctypedef %s (*%s)(%s)" % ( + ret, + i.name, + ", ".join([i.c_type for i in base.arguments]))) + elif base.type == eolian.TypeType.STRUCT: + gen.write("ctypedef struct %s:" % (i.name)) + gen.indent() + for f in base.struct_fields: + gen.write("%s %s" % (f.type.c_type, f.name)) + gen.dedent() + else: + log.error("Unhandled alias! %s %s %s %s", i.name, i.full_name, i.filename, i.description) + for i in eolian.type_structs_get_by_file(self.filename): + log.error("Type struct not handled! %s %s %s %s", i.name, i.full_name, i.filename, i.description) + for i in eolian.type_enums_get_by_file(self.filename): + log.error("Type enum not handled! %s %s %s %s", i.name, i.full_name, i.filename, i.description) + for i in eolian.variable_constants_get_by_file(self.filename): + log.error("Variable constant not handled! %s", i) + for i in eolian.variable_globals_get_by_file(self.filename): + log.error("Variable global not handled! %s", i) + + self.gencls.cdefs_generate(gen) + + gen.dedent() + gen.write() + + def pyx_generate(self): + self.gencls.pyx_generate(self.pyxgen) + + def printout(self): + return self.pyxgen.printout() -for path in args.paths: - for dirpath, dirnames, filenames in os.walk(path): - eolian.directory_scan(dirpath) - - for filename in filenames: - if filename.endswith(".eo"): - f = os.path.join(dirpath, filename) - if not eolian.eo_file_parse(f): - log.warn("Errors in parsing %s" % (f)) - - try: - eolf = File(filename) - except EolianSkip: - continue - except Exception: - log.exception("Exception while creating %s" % (filename)) - continue - - try: - eolf.cdefs_generate() - except Exception: - log.exception("Exception while generating cdefs for %s" % (filename)) - continue - - try: - eolf.pyx_generate() - except Exception: - log.exception("Exception while generating pyx for %s" % (filename)) - continue - - # try: - # eolf.py_generate() - # except Exception: - # log.exception("Exception while generating py for %s" % (filename)) - # continue +# class_counter = Counter() +# generated_class_counter = Counter() +# function_counter = Counter() +# generated_function_counter = Counter() -for pxis in generated_pxis.values(): - ns, pxi_path, cls = pxis[0] - filename = os.path.join(args.output, ns, "generated_classes.pxi") - if os.path.exists(filename): - log.warn("File %s exists, removing" % (filename)) - os.remove(filename) - with open(filename, "a") as f: - # for ns, pxi_path, cls in pxis: - # line = "ctypedef Eo %s\n" % (cls.full_name.replace(".", "_")) - # f.write(line) - for ns, pxi_path, cls in pxis: - line = 'include "%s"\n' % (pxi_path) - f.write(line) - - -def report(): - print("===============================================") - print("Number of classes: %d" % (len(class_counter))) - print("Number of classes generated: %d" % (len(generated_class_counter))) - if len(class_counter) > 0: - print("Percentage of classes generated: %f" % ( - float(len(generated_class_counter)) / float(len(class_counter)) * 100.0 - )) - print("Number of functions: %d" % (len(function_counter))) - print("Number of functions generated: %d" % ( - len(generated_function_counter))) - if len(function_counter) > 0: - print("Percentage of functions generated: %f" % ( - float(len(generated_function_counter)) / float(len(function_counter)) - * 100.0 - )) - -report() eolian.shutdown() + + +if __name__ == "__main__": + from argparse import ArgumentParser + parser = ArgumentParser(description="Python bindings generator for Eolian") + parser.add_argument( + '-v', '--verbose', action="count", help="max is -vvv") + # parser.add_argument( + # '--enable-docstrings', action="store_true") + # parser.add_argument( + # '--with-legacy-api', action="store_true") + parser.add_argument( + '-o', '--output', default="/tmp", help="output directory, defaults to /tmp") + parser.add_argument( + '-I', help="include directory") + parser.add_argument('paths', nargs="+") + args = parser.parse_args() + + if args.verbose: + log_level -= 10 * args.verbose + + log.setLevel(log_level) + + for path in args.paths: + for dirpath, dirnames, filenames in os.walk(path): + eolian.directory_scan(dirpath) + + for filename in filenames: + if filename.endswith(".eo"): + f = os.path.join(dirpath, filename) + if not eolian.eo_file_parse(f): + log.warn("Errors in parsing %s" % (f)) + + try: + eolf = File(filename) + except EolianSkip: + continue + except Exception: + log.exception("Exception while creating %s" % (filename)) + continue + + try: + eolf.cdefs_generate() + except Exception: + log.exception("Exception while generating cdefs for %s" % (filename)) + continue + + try: + eolf.pyx_generate() + except Exception: + log.exception("Exception while generating pyx for %s" % (filename)) + continue + + # try: + # eolf.py_generate() + # except Exception: + # log.exception("Exception while generating py for %s" % (filename)) + # continue + + + path = [] + cls_name = self.cls.name.lower() + filename = "generated_" + cls_name + ".pxi" + for ns in self.cls.namespaces: + path.append(ns.lower()) + if not path: + log.warning("Class %s has no namespaces defined" % (self.cls.name)) + nstmp = cls_name.partition("_") + path.append(nstmp[0]) + filename = "generated_" + nstmp[2] + ".pxi" + path = os.path.join(*path) + pxi_path = os.path.join(args.output, path, filename) + + self.pyxgen.printout(filepath=pxi_path) + + generated_pxis.setdefault(os.path.join(path), []).append((path, filename, self.cls)) + + for pxis in generated_pxis.values(): + ns, pxi_path, cls = pxis[0] + filename = os.path.join(args.output, ns, "generated_classes.pxi") + if os.path.exists(filename): + log.warn("File %s exists, removing" % (filename)) + os.remove(filename) + with open(filename, "a") as f: + # for ns, pxi_path, cls in pxis: + # line = "ctypedef Eo %s\n" % (cls.full_name.replace(".", "_")) + # f.write(line) + for ns, pxi_path, cls in pxis: + line = 'include "%s"\n' % (pxi_path) + f.write(line) + + + # def report(): + # print("===============================================") + # print("Number of classes: %d" % (len(class_counter))) + # print("Number of classes generated: %d" % (len(generated_class_counter))) + # if len(class_counter) > 0: + # print("Percentage of classes generated: %f" % ( + # float(len(generated_class_counter)) / float(len(class_counter)) * 100.0 + # )) + # print("Number of functions: %d" % (len(function_counter))) + # print("Number of functions generated: %d" % ( + # len(generated_function_counter))) + # if len(function_counter) > 0: + # print("Percentage of functions generated: %f" % ( + # float(len(generated_function_counter)) / float(len(function_counter)) + # * 100.0 + # )) + + # report() diff --git a/setup.py b/setup.py index 915a79c..255a902 100755 --- a/setup.py +++ b/setup.py @@ -63,26 +63,26 @@ except ImportError: # === pkg-config === -def pkg_config(name, require, min_vers=None): +def pkg_config(lib_human_name, lib_system_name, min_vers=None): try: - sys.stdout.write("Checking for " + name + ": ") + sys.stdout.write("Checking for " + lib_human_name + ": ") call = subprocess.Popen( - ["pkg-config", "--modversion", require], stdout=subprocess.PIPE) + ["pkg-config", "--modversion", lib_system_name], stdout=subprocess.PIPE) out, err = call.communicate() ver = out.decode("utf-8").strip() if min_vers is not None: assert 0 == subprocess.call( - ["pkg-config", "--atleast-version", min_vers, require]) + ["pkg-config", "--atleast-version", min_vers, lib_system_name]) call = subprocess.Popen( - ["pkg-config", "--cflags", require], stdout=subprocess.PIPE) + ["pkg-config", "--cflags-only-I", lib_system_name], stdout=subprocess.PIPE) out, err = call.communicate() cflags = out.decode("utf-8").split() call = subprocess.Popen( - ["pkg-config", "--libs", require], stdout=subprocess.PIPE) + ["pkg-config", "--libs", lib_system_name], stdout=subprocess.PIPE) out, err = call.communicate() libs = out.decode("utf-8").split() @@ -92,10 +92,10 @@ def pkg_config(name, require, min_vers=None): return (cflags, libs) except (OSError, subprocess.CalledProcessError): - raise SystemExit("Did not find " + name + " with 'pkg-config'.") + raise SystemExit("Did not find " + lib_human_name + " with 'pkg-config'.") except (AssertionError): raise SystemExit( - name + " version mismatch. Found: " + ver + " Needed: " + min_vers + lib_human_name + " version mismatch. Found: " + ver + " Needed: " + min_vers ) @@ -182,8 +182,92 @@ class CleanGenerated(Command): os.remove(dbus_ml_path) +def get_eolian_files(prefix): + files = [] + with open("efl-eo-files", "r") as f: + for line in f.readlines(): + if line.startswith("./" + prefix + "/"): + line = line.rpartition("/")[2].strip() + files.append(line) + + return files + + +PY_EFL_TOP_LEVEL_PACKAGE = "efl" +def generate_pxis(prefix, header_name, output_path): + + import platform + d = "lib.%s-%s-%d.%d" % ( + platform.system().lower(), + platform.machine(), + sys.version_info[0], + sys.version_info[1] + ) + orig_path = sys.path + sys.path[0] = os.path.abspath("build/" + d) + + #efl = __import__("efl.eolian" % d) + from efl import eolian + + eolian.init() + + sys.path = orig_path + + eol_files = get_eolian_files(prefix) + + from eolian_generate import File, EolianSkip + + generated_pxis = [] + + for filename in eol_files: + if not eolian.eo_file_parse(filename): + log.warn("Errors in parsing %s" % (filename)) + + try: + eolf = File(filename) + except EolianSkip: + continue + except Exception: + log.exception("Exception while creating %s" % (filename)) + continue + + try: + eolf.cdefs_generate() + except Exception: + log.exception("Exception while generating cdefs for %s" % (filename)) + continue + + try: + eolf.pyx_generate() + except Exception: + log.exception("Exception while generating pyx for %s" % (filename)) + continue + + filebase, fileext = os.path.splitext(filename) + filename = "generated_" + filebase + ".pxi" + + printout = eolf.printout() + + output_file = os.path.join(output_path, filename) + with open(output_file, "w") as f: + f.write(printout) + + generated_pxis.append(filename) + + list_name = os.path.join(output_path, "generated_classes.pxi") + with open(list_name, "a") as f: + for filename in generated_pxis: + if os.path.exists(list_name): + log.warn("File %s exists, removing" % (list_name)) + os.remove(list_name) + + line = 'include "%s"\n' % (filename) + f.write(line) + + eolian.shutdown() + modules = [] -packages = ["efl"] +packages = [PY_EFL_TOP_LEVEL_PACKAGE] #package_dirs = {} # Use this if you put packages in non-root paths if set(("build", "build_ext", "install", "bdist", "sdist")) & set(sys.argv): @@ -203,16 +287,18 @@ if set(("build", "build_ext", "install", "bdist", "sdist")) & set(sys.argv): modules.append(eo_ext) # === Eolian === - eol_cflags, eol_libs = pkg_config('Eolian', 'eolian', EFL_MIN_VERSION) - eol_ext = Extension( - "eolian.__init__", ["efl/eolian/__init__" + module_suffix], + header_name = "Eolian" + library_name = "eolian" + eol_cflags, eol_libs = pkg_config(header_name, library_name, EFL_MIN_VERSION) + output_path = "/".join((PY_EFL_TOP_LEVEL_PACKAGE, library_name)) + modules.append(Extension( + ".".join((library_name, "__init__")), ["/".join((output_path, "__init__" + module_suffix))], define_macros=[('EFL_BETA_API_SUPPORT', None)], #include_dirs=['include/'], extra_compile_args=eol_cflags + eina_cflags, extra_link_args=eol_libs + eina_libs - ) - modules.append(eol_ext) - packages.append("efl.eolian") + )) + packages.append(".".join((PY_EFL_TOP_LEVEL_PACKAGE, library_name))) # === Utilities === utils_ext = [ @@ -240,23 +326,32 @@ if set(("build", "build_ext", "install", "bdist", "sdist")) & set(sys.argv): packages.append("efl.utils.enum") # === Efl (interfaces) === - eo_cflags, eo_libs = pkg_config('Efl', 'efl', EFL_MIN_VERSION) - eo_ext = Extension( - "efl.__init__", ["efl/efl/__init__" + module_suffix], + header_name = "Efl" + library_name = "efl" + efl_cflags, efl_libs = pkg_config(header_name, library_name, EFL_MIN_VERSION) + include_path = efl_cflags[0] + output_path = "/".join((PY_EFL_TOP_LEVEL_PACKAGE, library_name)) + generate_pxis(library_name, header_name, output_path) + efl_ext = Extension( + ".".join((library_name, "__init__")), ["/".join((output_path, "__init__" + module_suffix))], define_macros=[ ('EFL_BETA_API_SUPPORT', 1), ('EFL_EO_API_SUPPORT', 1), ], include_dirs=['include/'], - extra_compile_args=eo_cflags, - extra_link_args=eo_libs + eina_libs + extra_compile_args=efl_cflags, + extra_link_args=efl_libs + eina_libs ) - modules.append(eo_ext) + modules.append(efl_ext) # === Evas === evas_cflags, evas_libs = pkg_config('Evas', 'evas', EFL_MIN_VERSION) evas_ext = Extension( "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, extra_link_args=evas_libs + eina_libs, @@ -276,13 +371,13 @@ if set(("build", "build_ext", "install", "bdist", "sdist")) & set(sys.argv): # evas_libs # ), # ] - try: - ecore_input_cflags, ecore_input_libs = pkg_config( - 'EcoreInput', 'ecore-input', EFL_MIN_VERSION) - ecore_x_cflags, ecore_x_libs = pkg_config( - 'EcoreX', 'ecore-x', EFL_MIN_VERSION) - except SystemExit: # FIXME: Change pkg-config to return a value - pass + # try: + # ecore_input_cflags, ecore_input_libs = pkg_config( + # 'EcoreInput', 'ecore-input', EFL_MIN_VERSION) + # ecore_x_cflags, ecore_x_libs = pkg_config( + # 'EcoreX', 'ecore-x', EFL_MIN_VERSION) + # except SystemExit: # FIXME: Change pkg-config to return a value + # pass # else: # ecore_exts.append( # Extension(