mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 17:44:04 +08:00
Merge pull request #9566 from alalek:python_signatures
This commit is contained in:
commit
b8b5d83ad0
@ -48,17 +48,28 @@ set(cv2_generated_hdrs
|
|||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_funcs.h"
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_funcs.h"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_types.h"
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_types.h"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_type_reg.h"
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_type_reg.h"
|
||||||
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_ns_reg.h")
|
"${CMAKE_CURRENT_BINARY_DIR}/pyopencv_generated_ns_reg.h"
|
||||||
|
)
|
||||||
|
|
||||||
|
set(OPENCV_${PYTHON}_SIGNATURES_FILE "${CMAKE_CURRENT_BINARY_DIR}/pyopencv_signatures.json" CACHE INTERNAL "")
|
||||||
|
|
||||||
|
set(cv2_generated_files ${cv2_generated_hdrs}
|
||||||
|
"${OPENCV_${PYTHON}_SIGNATURES_FILE}"
|
||||||
|
)
|
||||||
|
|
||||||
string(REPLACE ";" "\n" opencv_hdrs_ "${opencv_hdrs}")
|
string(REPLACE ";" "\n" opencv_hdrs_ "${opencv_hdrs}")
|
||||||
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${opencv_hdrs_}")
|
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${opencv_hdrs_}")
|
||||||
add_custom_command(
|
add_custom_command(
|
||||||
OUTPUT ${cv2_generated_hdrs}
|
OUTPUT ${cv2_generated_files}
|
||||||
COMMAND ${PYTHON_DEFAULT_EXECUTABLE} "${PYTHON_SOURCE_DIR}/src2/gen2.py" ${CMAKE_CURRENT_BINARY_DIR} "${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${PYTHON}"
|
COMMAND ${PYTHON_DEFAULT_EXECUTABLE} "${PYTHON_SOURCE_DIR}/src2/gen2.py" ${CMAKE_CURRENT_BINARY_DIR} "${CMAKE_CURRENT_BINARY_DIR}/headers.txt" "${PYTHON}"
|
||||||
DEPENDS ${PYTHON_SOURCE_DIR}/src2/gen2.py
|
DEPENDS ${PYTHON_SOURCE_DIR}/src2/gen2.py
|
||||||
DEPENDS ${PYTHON_SOURCE_DIR}/src2/hdr_parser.py
|
DEPENDS ${PYTHON_SOURCE_DIR}/src2/hdr_parser.py
|
||||||
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/headers.txt
|
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/headers.txt
|
||||||
DEPENDS ${opencv_hdrs})
|
DEPENDS ${opencv_hdrs}
|
||||||
|
COMMENT "Generate files for ${the_module}"
|
||||||
|
)
|
||||||
|
|
||||||
|
add_custom_target(gen_${the_module} DEPENDS ${cv2_generated_files})
|
||||||
|
|
||||||
set(cv2_custom_hdr "${CMAKE_CURRENT_BINARY_DIR}/pyopencv_custom_headers.h")
|
set(cv2_custom_hdr "${CMAKE_CURRENT_BINARY_DIR}/pyopencv_custom_headers.h")
|
||||||
file(WRITE ${cv2_custom_hdr} "//user-defined headers\n")
|
file(WRITE ${cv2_custom_hdr} "//user-defined headers\n")
|
||||||
@ -67,6 +78,7 @@ foreach(uh ${opencv_userdef_hdrs})
|
|||||||
endforeach(uh)
|
endforeach(uh)
|
||||||
|
|
||||||
ocv_add_library(${the_module} MODULE ${PYTHON_SOURCE_DIR}/src2/cv2.cpp ${cv2_generated_hdrs} ${opencv_userdef_hdrs} ${cv2_custom_hdr})
|
ocv_add_library(${the_module} MODULE ${PYTHON_SOURCE_DIR}/src2/cv2.cpp ${cv2_generated_hdrs} ${opencv_userdef_hdrs} ${cv2_custom_hdr})
|
||||||
|
add_dependencies(${the_module} gen_${the_module})
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
set_target_properties(${the_module} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
|
set_target_properties(${the_module} PROPERTIES LINK_FLAGS "-undefined dynamic_lookup")
|
||||||
|
@ -310,7 +310,8 @@ class ClassInfo(object):
|
|||||||
if not customname and self.wname.startswith("Cv"):
|
if not customname and self.wname.startswith("Cv"):
|
||||||
self.wname = self.wname[2:]
|
self.wname = self.wname[2:]
|
||||||
|
|
||||||
def gen_map_code(self, all_classes):
|
def gen_map_code(self, codegen):
|
||||||
|
all_classes = codegen.classes
|
||||||
code = "static bool pyopencv_to(PyObject* src, %s& dst, const char* name)\n{\n PyObject* tmp;\n bool ok;\n" % (self.cname)
|
code = "static bool pyopencv_to(PyObject* src, %s& dst, const char* name)\n{\n PyObject* tmp;\n bool ok;\n" % (self.cname)
|
||||||
code += "".join([gen_template_set_prop_from_map.substitute(propname=p.name,proptype=p.tp) for p in self.props])
|
code += "".join([gen_template_set_prop_from_map.substitute(propname=p.name,proptype=p.tp) for p in self.props])
|
||||||
if self.base:
|
if self.base:
|
||||||
@ -319,9 +320,10 @@ class ClassInfo(object):
|
|||||||
code += "\n return true;\n}\n"
|
code += "\n return true;\n}\n"
|
||||||
return code
|
return code
|
||||||
|
|
||||||
def gen_code(self, all_classes):
|
def gen_code(self, codegen):
|
||||||
|
all_classes = codegen.classes
|
||||||
if self.ismap:
|
if self.ismap:
|
||||||
return self.gen_map_code(all_classes)
|
return self.gen_map_code(codegen)
|
||||||
|
|
||||||
getset_code = StringIO()
|
getset_code = StringIO()
|
||||||
getset_inits = StringIO()
|
getset_inits = StringIO()
|
||||||
@ -354,10 +356,10 @@ class ClassInfo(object):
|
|||||||
sorted_methods.sort()
|
sorted_methods.sort()
|
||||||
|
|
||||||
if self.constructor is not None:
|
if self.constructor is not None:
|
||||||
methods_code.write(self.constructor.gen_code(all_classes))
|
methods_code.write(self.constructor.gen_code(codegen))
|
||||||
|
|
||||||
for mname, m in sorted_methods:
|
for mname, m in sorted_methods:
|
||||||
methods_code.write(m.gen_code(all_classes))
|
methods_code.write(m.gen_code(codegen))
|
||||||
methods_inits.write(m.get_tab_entry())
|
methods_inits.write(m.get_tab_entry())
|
||||||
|
|
||||||
baseptr = "NULL"
|
baseptr = "NULL"
|
||||||
@ -516,6 +518,8 @@ class FuncVariant(object):
|
|||||||
else:
|
else:
|
||||||
outstr = "None"
|
outstr = "None"
|
||||||
|
|
||||||
|
self.py_arg_str = argstr
|
||||||
|
self.py_return_str = outstr
|
||||||
self.py_prototype = "%s(%s) -> %s" % (self.wname, argstr, outstr)
|
self.py_prototype = "%s(%s) -> %s" % (self.wname, argstr, outstr)
|
||||||
self.py_noptargs = noptargs
|
self.py_noptargs = noptargs
|
||||||
self.py_arglist = arglist
|
self.py_arglist = arglist
|
||||||
@ -554,11 +558,11 @@ class FuncInfo(object):
|
|||||||
|
|
||||||
return "pyopencv_" + self.namespace.replace('.','_') + '_' + classname + name
|
return "pyopencv_" + self.namespace.replace('.','_') + '_' + classname + name
|
||||||
|
|
||||||
def get_wrapper_prototype(self, all_classes):
|
def get_wrapper_prototype(self, codegen):
|
||||||
full_fname = self.get_wrapper_name()
|
full_fname = self.get_wrapper_name()
|
||||||
if self.isconstructor:
|
if self.isconstructor:
|
||||||
return "static int {fn_name}(pyopencv_{type_name}_t* self, PyObject* args, PyObject* kw)".format(
|
return "static int {fn_name}(pyopencv_{type_name}_t* self, PyObject* args, PyObject* kw)".format(
|
||||||
fn_name=full_fname, type_name=all_classes[self.classname].name)
|
fn_name=full_fname, type_name=codegen.classes[self.classname].name)
|
||||||
|
|
||||||
if self.classname:
|
if self.classname:
|
||||||
self_arg = "self"
|
self_arg = "self"
|
||||||
@ -615,8 +619,9 @@ class FuncInfo(object):
|
|||||||
).substitute(py_funcname = self.variants[0].wname, wrap_funcname=self.get_wrapper_name(),
|
).substitute(py_funcname = self.variants[0].wname, wrap_funcname=self.get_wrapper_name(),
|
||||||
flags = " | ".join(flags), py_docstring = full_docstring)
|
flags = " | ".join(flags), py_docstring = full_docstring)
|
||||||
|
|
||||||
def gen_code(self, all_classes):
|
def gen_code(self, codegen):
|
||||||
proto = self.get_wrapper_prototype(all_classes)
|
all_classes = codegen.classes
|
||||||
|
proto = self.get_wrapper_prototype(codegen)
|
||||||
code = "%s\n{\n" % (proto,)
|
code = "%s\n{\n" % (proto,)
|
||||||
code += " using namespace %s;\n\n" % self.namespace.replace('.', '::')
|
code += " using namespace %s;\n\n" % self.namespace.replace('.', '::')
|
||||||
|
|
||||||
@ -799,6 +804,20 @@ class FuncInfo(object):
|
|||||||
if self.isconstructor:
|
if self.isconstructor:
|
||||||
def_ret = "-1"
|
def_ret = "-1"
|
||||||
code += "\n return %s;\n}\n\n" % def_ret
|
code += "\n return %s;\n}\n\n" % def_ret
|
||||||
|
|
||||||
|
cname = self.cname
|
||||||
|
if self.classname:
|
||||||
|
classinfo = all_classes[self.classname]
|
||||||
|
cname = classinfo.cname + '::' + cname
|
||||||
|
py_signatures = codegen.py_signatures.setdefault(cname, [])
|
||||||
|
for v in self.variants:
|
||||||
|
s = dict(name=v.name, arg=v.py_arg_str, ret=v.py_return_str)
|
||||||
|
for old in py_signatures:
|
||||||
|
if s == old:
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
py_signatures.append(s)
|
||||||
|
|
||||||
return code
|
return code
|
||||||
|
|
||||||
|
|
||||||
@ -822,6 +841,7 @@ class PythonWrapperGenerator(object):
|
|||||||
self.code_type_reg = StringIO()
|
self.code_type_reg = StringIO()
|
||||||
self.code_ns_reg = StringIO()
|
self.code_ns_reg = StringIO()
|
||||||
self.code_type_publish = StringIO()
|
self.code_type_publish = StringIO()
|
||||||
|
self.py_signatures = dict()
|
||||||
self.class_idx = 0
|
self.class_idx = 0
|
||||||
|
|
||||||
def add_class(self, stype, name, decl):
|
def add_class(self, stype, name, decl):
|
||||||
@ -931,9 +951,13 @@ class PythonWrapperGenerator(object):
|
|||||||
|
|
||||||
|
|
||||||
def save(self, path, name, buf):
|
def save(self, path, name, buf):
|
||||||
f = open(path + "/" + name, "wt")
|
with open(path + "/" + name, "wt") as f:
|
||||||
f.write(buf.getvalue())
|
f.write(buf.getvalue())
|
||||||
f.close()
|
|
||||||
|
def save_json(self, path, name, value):
|
||||||
|
import json
|
||||||
|
with open(path + "/" + name, "wt") as f:
|
||||||
|
json.dump(value, f)
|
||||||
|
|
||||||
def gen(self, srcfiles, output_path):
|
def gen(self, srcfiles, output_path):
|
||||||
self.clear()
|
self.clear()
|
||||||
@ -996,7 +1020,7 @@ class PythonWrapperGenerator(object):
|
|||||||
classlist1.sort()
|
classlist1.sort()
|
||||||
|
|
||||||
for decl_idx, name, classinfo in classlist1:
|
for decl_idx, name, classinfo in classlist1:
|
||||||
code = classinfo.gen_code(self.classes)
|
code = classinfo.gen_code(self)
|
||||||
self.code_types.write(code)
|
self.code_types.write(code)
|
||||||
if not classinfo.ismap:
|
if not classinfo.ismap:
|
||||||
self.code_type_reg.write("MKTYPE2(%s);\n" % (classinfo.name,) )
|
self.code_type_reg.write("MKTYPE2(%s);\n" % (classinfo.name,) )
|
||||||
@ -1009,7 +1033,7 @@ class PythonWrapperGenerator(object):
|
|||||||
for name, func in sorted(ns.funcs.items()):
|
for name, func in sorted(ns.funcs.items()):
|
||||||
if func.isconstructor:
|
if func.isconstructor:
|
||||||
continue
|
continue
|
||||||
code = func.gen_code(self.classes)
|
code = func.gen_code(self)
|
||||||
self.code_funcs.write(code)
|
self.code_funcs.write(code)
|
||||||
self.gen_namespace(ns_name)
|
self.gen_namespace(ns_name)
|
||||||
self.gen_namespaces_reg()
|
self.gen_namespaces_reg()
|
||||||
@ -1027,6 +1051,7 @@ class PythonWrapperGenerator(object):
|
|||||||
self.save(output_path, "pyopencv_generated_type_reg.h", self.code_type_reg)
|
self.save(output_path, "pyopencv_generated_type_reg.h", self.code_type_reg)
|
||||||
self.save(output_path, "pyopencv_generated_ns_reg.h", self.code_ns_reg)
|
self.save(output_path, "pyopencv_generated_ns_reg.h", self.code_ns_reg)
|
||||||
self.save(output_path, "pyopencv_generated_type_publish.h", self.code_type_publish)
|
self.save(output_path, "pyopencv_generated_type_publish.h", self.code_type_publish)
|
||||||
|
self.save_json(output_path, "pyopencv_signatures.json", self.py_signatures)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
srcfiles = hdr_parser.opencv_hdr_list
|
srcfiles = hdr_parser.opencv_hdr_list
|
||||||
|
Loading…
Reference in New Issue
Block a user