mirror of
https://github.com/opencv/opencv.git
synced 2024-11-24 03:00:14 +08:00
Merge pull request #18805 from alalek:cmake_objc_generator
This commit is contained in:
commit
3da1e8b2f8
@ -1,6 +1,19 @@
|
||||
if(OPENCV_INITIAL_PASS AND APPLE_FRAMEWORK AND NOT (BUILD_opencv_objc STREQUAL "OFF"))
|
||||
if(OPENCV_INITIAL_PASS)
|
||||
# generator for Objective-C source code and documentation signatures
|
||||
add_subdirectory(generator)
|
||||
endif()
|
||||
|
||||
if(NOT APPLE_FRAMEWORK)
|
||||
return()
|
||||
endif()
|
||||
|
||||
set(the_description "The Objective-C bindings")
|
||||
ocv_add_module(objc BINDINGS opencv_core opencv_imgproc PRIVATE_REQUIRED opencv_objc_bindings_generator)
|
||||
|
||||
add_custom_target(${the_module}
|
||||
ALL
|
||||
COMMENT "Objective-C framework"
|
||||
)
|
||||
add_dependencies(${the_module} gen_opencv_objc_source)
|
||||
|
||||
#include(${CMAKE_CURRENT_SOURCE_DIR}/common.cmake)
|
||||
|
@ -1,16 +1,18 @@
|
||||
set(MODULE_NAME "objc")
|
||||
set(MODULE_NAME "objc_bindings_generator")
|
||||
set(OPENCV_MODULE_IS_PART_OF_WORLD FALSE)
|
||||
ocv_add_module(${MODULE_NAME} INTERNAL opencv_core opencv_imgproc)
|
||||
|
||||
set(OPENCV_OBJC_SIGNATURES_FILE "${CMAKE_CURRENT_BINARY_DIR}/opencv_objc_signatures.json" CACHE INTERNAL "")
|
||||
#set(OPENCV_OBJC_SIGNATURES_FILE "${CMAKE_CURRENT_BINARY_DIR}/opencv_objc_signatures.json" CACHE INTERNAL "")
|
||||
set(OPENCV_OBJC_BINDINGS_DIR "${CMAKE_CURRENT_BINARY_DIR}" CACHE INTERNAL "")
|
||||
|
||||
file(REMOVE_RECURSE "${OPENCV_OBJC_BINDINGS_DIR}/gen")
|
||||
file(REMOVE "${OPENCV_DEPHELPER}/gen_opencv_objc_source") # force re-run after CMake
|
||||
file(REMOVE_RECURSE "${OPENCV_OBJC_BINDINGS_DIR}/osx")
|
||||
file(REMOVE "${OPENCV_DEPHELPER}/gen_opencv_objc_source_osx") # force re-run after CMake
|
||||
file(REMOVE_RECURSE "${OPENCV_OBJC_BINDINGS_DIR}/ios")
|
||||
file(REMOVE "${OPENCV_DEPHELPER}/gen_opencv_objc_source_ios") # force re-run after CMake
|
||||
|
||||
# This file is included from a subdirectory
|
||||
set(OBJC_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
|
||||
include(${OBJC_SOURCE_DIR}/common.cmake)
|
||||
include(${OBJC_SOURCE_DIR}/common.cmake) # fill OPENCV_OBJC_MODULES
|
||||
|
||||
# common files
|
||||
file(GLOB_RECURSE deps "${CMAKE_CURRENT_SOURCE_DIR}/templates/*")
|
||||
@ -30,15 +32,21 @@ foreach(m ${OPENCV_OBJC_MODULES})
|
||||
set(__modules_config "${__modules_config} { \"name\": \"${m_}\", \"location\": \"${rel_path}\" }")
|
||||
endforeach(m)
|
||||
|
||||
if(HAVE_opencv_objc)
|
||||
set(__objc_build_dir "\"objc_build_dir\": \"${CMAKE_CURRENT_BINARY_DIR}/../objc\",")
|
||||
endif()
|
||||
|
||||
set(CONFIG_FILE "${CMAKE_CURRENT_BINARY_DIR}/gen_objc.json")
|
||||
set(__config_str
|
||||
"{
|
||||
\"rootdir\": \"${OpenCV_SOURCE_DIR}\",
|
||||
${__objc_build_dir}
|
||||
\"modules\": [
|
||||
${__modules_config}
|
||||
]
|
||||
}
|
||||
")
|
||||
#TODO: ocv_update_file("${CONFIG_FILE}" "${__config_str}" ON_CHANGE_REMOVE "${OPENCV_DEPHELPER}/gen_opencv_objc_source")
|
||||
if(EXISTS "${CONFIG_FILE}")
|
||||
file(READ "${CONFIG_FILE}" __content)
|
||||
else()
|
||||
@ -52,33 +60,66 @@ unset(__config_str)
|
||||
|
||||
set(objc_generated_files
|
||||
# "${OPENCV_OBJC_SIGNATURES_FILE}"
|
||||
"${OPENCV_DEPHELPER}/gen_opencv_objc_source"
|
||||
)
|
||||
|
||||
string(REPLACE "opencv_" "" MODULES "${OPENCV_OBJC_MODULES}")
|
||||
|
||||
if(IOS)
|
||||
set(TARGET "ios")
|
||||
else()
|
||||
set(TARGET "osx")
|
||||
if(NOT DEFINED OPENCV_OBJC_TARGET AND APPLE_FRAMEWORK)
|
||||
if(IOS)
|
||||
set(OPENCV_OBJC_TARGET "ios")
|
||||
else()
|
||||
set(OPENCV_OBJC_TARGET "osx")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_custom_command(
|
||||
OUTPUT ${objc_generated_files}
|
||||
COMMAND ${PYTHON_DEFAULT_EXECUTABLE} "${OBJC_SOURCE_DIR}/generator/gen_objc.py" -p "${OBJC_SOURCE_DIR}/../python/src2/gen2.py" -c "${CONFIG_FILE}" -t "${TARGET}" -f "${FRAMEWORK_NAME}"
|
||||
COMMAND ${CMAKE_COMMAND} -E touch "${OPENCV_DEPHELPER}/gen_opencv_objc_source"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
|
||||
DEPENDS "${OBJC_SOURCE_DIR}/generator/gen_objc.py"
|
||||
"${OBJC_SOURCE_DIR}/../python/src2/gen2.py"
|
||||
"${OBJC_SOURCE_DIR}/../python/src2/hdr_parser.py"
|
||||
# don't, result of file(WRITE): "${CMAKE_CURRENT_BINARY_DIR}/gen_objc.json"
|
||||
${deps}
|
||||
# not allowed (file(WRITE) result): "${CONFIG_FILE}"
|
||||
COMMENT "Generate files for Objective-C bindings"
|
||||
)
|
||||
if(NOT DEFINED OPENCV_OBJC_FRAMEWORK_NAME)
|
||||
if(DEFINED FRAMEWORK_NAME)
|
||||
set(OPENCV_OBJC_FRAMEWORK_NAME "${FRAMEWORK_NAME}")
|
||||
else()
|
||||
set(OPENCV_OBJC_FRAMEWORK_NAME "opencv2")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
add_custom_target(gen_opencv_objc_source ALL DEPENDS ${objc_generated_files}
|
||||
SOURCES "${OBJC_SOURCE_DIR}/generator/gen_objc.py"
|
||||
"${OBJC_SOURCE_DIR}/generator/templates/cmakelists.template"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/gen_objc.json"
|
||||
set(objc_generated_targets "")
|
||||
|
||||
macro(ocv_add_objc_generated_target TARGET)
|
||||
set(objc_${TARGET}_generated_output_dependecy "${OPENCV_DEPHELPER}/gen_opencv_objc_source_${TARGET}")
|
||||
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}")
|
||||
add_custom_command(
|
||||
OUTPUT ${objc_generated_files} "${objc_${TARGET}_generated_output_dependecy}"
|
||||
COMMAND ${PYTHON_DEFAULT_EXECUTABLE} "${OBJC_SOURCE_DIR}/generator/gen_objc.py"
|
||||
-p "${OBJC_SOURCE_DIR}/../python/src2/gen2.py"
|
||||
-c "${CONFIG_FILE}"
|
||||
-t "${TARGET}"
|
||||
-f "${OPENCV_OBJC_FRAMEWORK_NAME}"
|
||||
COMMAND ${CMAKE_COMMAND} -E touch "${objc_${TARGET}_generated_output_dependecy}"
|
||||
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${TARGET}"
|
||||
DEPENDS "${OpenCV_SOURCE_DIR}/modules/objc/generator/gen_objc.py"
|
||||
"${OpenCV_SOURCE_DIR}/modules/python/src2/gen2.py"
|
||||
"${OpenCV_SOURCE_DIR}/modules/python/src2/hdr_parser.py"
|
||||
# don't, result of file(WRITE): "${CMAKE_CURRENT_BINARY_DIR}/gen_objc.json"
|
||||
${deps}
|
||||
# not allowed (file(WRITE) result): "${CONFIG_FILE}"
|
||||
COMMENT "Generate files for Objective-C bindings (${TARGET})"
|
||||
)
|
||||
add_custom_target(gen_opencv_objc_source_${TARGET}
|
||||
# excluded from all: ALL
|
||||
DEPENDS ${objc_generated_files} ${objc_${TARGET}_generated_output_dependecy}
|
||||
SOURCES "${OBJC_SOURCE_DIR}/generator/gen_objc.py"
|
||||
"${OBJC_SOURCE_DIR}/generator/templates/cmakelists.template"
|
||||
"${CMAKE_CURRENT_BINARY_DIR}/gen_objc.json"
|
||||
)
|
||||
list(APPEND objc_generated_targets gen_opencv_objc_source_${TARGET})
|
||||
endmacro()
|
||||
|
||||
if(OPENCV_OBJC_TARGET)
|
||||
ocv_add_objc_generated_target(${OPENCV_OBJC_TARGET})
|
||||
else()
|
||||
ocv_add_objc_generated_target(osx)
|
||||
ocv_add_objc_generated_target(ios)
|
||||
endif()
|
||||
|
||||
add_custom_target(gen_opencv_objc_source
|
||||
# excluded from all: ALL
|
||||
DEPENDS ${objc_generated_targets}
|
||||
)
|
||||
|
@ -1345,7 +1345,7 @@ typedef NS_ENUM(int, {1}) {{
|
||||
return "Ptr<" + fullname + ">"
|
||||
return fullname
|
||||
|
||||
def finalize(self, output_objc_path):
|
||||
def finalize(self, objc_target, output_objc_path, output_objc_build_path):
|
||||
opencv_header_file = os.path.join(output_objc_path, framework_name + ".h")
|
||||
opencv_header = "#import <Foundation/Foundation.h>\n\n"
|
||||
opencv_header += "// ! Project version number\nFOUNDATION_EXPORT double " + framework_name + "VersionNumber;\n\n"
|
||||
@ -1359,15 +1359,15 @@ typedef NS_ENUM(int, {1}) {{
|
||||
opencv_modulemap += "\n export *\n module * {export *}\n}\n"
|
||||
self.save(opencv_modulemap_file, opencv_modulemap)
|
||||
cmakelist_template = read_contents(os.path.join(SCRIPT_DIR, 'templates/cmakelists.template'))
|
||||
cmakelist = Template(cmakelist_template).substitute(modules = ";".join(modules), framework = framework_name)
|
||||
cmakelist = Template(cmakelist_template).substitute(modules = ";".join(modules), framework = framework_name, objc_target=objc_target)
|
||||
self.save(os.path.join(dstdir, "CMakeLists.txt"), cmakelist)
|
||||
mkdir_p("./framework_build")
|
||||
mkdir_p("./test_build")
|
||||
mkdir_p("./doc_build")
|
||||
mkdir_p(os.path.join(output_objc_build_path, "framework_build"))
|
||||
mkdir_p(os.path.join(output_objc_build_path, "test_build"))
|
||||
mkdir_p(os.path.join(output_objc_build_path, "doc_build"))
|
||||
with open(os.path.join(SCRIPT_DIR, '../doc/README.md')) as readme_in:
|
||||
readme_body = readme_in.read()
|
||||
readme_body += "\n\n\n##Modules\n\n" + ", ".join(["`" + m.capitalize() + "`" for m in modules])
|
||||
with open("./doc_build/README.md", "w") as readme_out:
|
||||
with open(os.path.join(output_objc_build_path, "doc_build/README.md"), "w") as readme_out:
|
||||
readme_out.write(readme_body)
|
||||
if framework_name != "OpenCV":
|
||||
for dirname, dirs, files in os.walk(os.path.join(testdir, "test")):
|
||||
@ -1518,6 +1518,11 @@ if __name__ == "__main__":
|
||||
config = json.load(f)
|
||||
|
||||
ROOT_DIR = config['rootdir']; assert os.path.exists(ROOT_DIR)
|
||||
if 'objc_build_dir' in config:
|
||||
objc_build_dir = config['objc_build_dir']
|
||||
assert os.path.exists(objc_build_dir), objc_build_dir
|
||||
else:
|
||||
objc_build_dir = os.getcwd()
|
||||
|
||||
dstdir = "./gen"
|
||||
testdir = "./test"
|
||||
@ -1613,6 +1618,6 @@ if __name__ == "__main__":
|
||||
generator.gen(srcfiles, module, dstdir, objc_base_path, common_headers, manual_classes)
|
||||
else:
|
||||
logging.info("No generated code for module: %s", module)
|
||||
generator.finalize(objc_base_path)
|
||||
generator.finalize(args.target, objc_base_path, objc_build_dir)
|
||||
|
||||
print('Generated files: %d (updated %d)' % (total_files, updated_files))
|
||||
|
@ -24,7 +24,7 @@ target_include_directories($framework PRIVATE "$${BUILD_ROOT}")
|
||||
target_include_directories($framework PRIVATE "$${BUILD_ROOT}/install/include")
|
||||
target_include_directories($framework PRIVATE "$${BUILD_ROOT}/install/include/opencv2")
|
||||
foreach(m $${MODULES})
|
||||
target_include_directories($framework PRIVATE "$${BUILD_ROOT}/modules/objc/gen/objc/$${m}")
|
||||
target_include_directories($framework PRIVATE "$${BUILD_ROOT}/modules/objc_bindings_generator/$objc_target/gen/objc/$${m}")
|
||||
endforeach()
|
||||
|
||||
install(TARGETS $framework LIBRARY DESTINATION lib)
|
||||
|
@ -128,10 +128,10 @@ class Builder:
|
||||
self.makeFramework(outdir, dirs)
|
||||
if self.build_objc_wrapper:
|
||||
if self.run_tests:
|
||||
check_call([sys.argv[0].replace("build_framework", "run_tests"), "--framework_dir=" + outdir, "--framework_name=" + self.framework_name, dirs[0] + "/modules/objc/test"])
|
||||
check_call([sys.argv[0].replace("build_framework", "run_tests"), "--framework_dir=" + outdir, "--framework_name=" + self.framework_name, dirs[0] + "/modules/objc_bindings_generator/{}/test".format(self.getObjcTarget())])
|
||||
else:
|
||||
print("To run tests call:")
|
||||
print(sys.argv[0].replace("build_framework", "run_tests") + " --framework_dir=" + outdir + " --framework_name=" + self.framework_name + " " + dirs[0] + "/modules/objc/test")
|
||||
print(sys.argv[0].replace("build_framework", "run_tests") + " --framework_dir=" + outdir + " --framework_name=" + self.framework_name + " " + dirs[0] + "/modules/objc_bindings_generator/{}/test".format(self.getObjcTarget()))
|
||||
if self.build_docs:
|
||||
check_call([sys.argv[0].replace("build_framework", "build_docs"), dirs[0] + "/modules/objc/framework_build"])
|
||||
doc_path = os.path.join(dirs[0], "modules", "objc", "doc_build", "docs")
|
||||
@ -216,6 +216,10 @@ class Builder:
|
||||
def getInfoPlist(self, builddirs):
|
||||
return os.path.join(builddirs[0], "ios", "Info.plist")
|
||||
|
||||
def getObjcTarget(self):
|
||||
# Obj-C generation target
|
||||
return 'ios'
|
||||
|
||||
def makeCMakeCmd(self, arch, target, dir, cmakeargs = []):
|
||||
toolchain = self.getToolchain(arch, target)
|
||||
cmakecmd = self.getCMakeArgs(arch, target) + \
|
||||
@ -255,7 +259,7 @@ class Builder:
|
||||
execute(buildcmd + ["-target", "ALL_BUILD", "build"], cwd = builddir)
|
||||
execute(["cmake", "-DBUILD_TYPE=%s" % self.getConfiguration(), "-P", "cmake_install.cmake"], cwd = builddir)
|
||||
if self.build_objc_wrapper:
|
||||
cmakecmd = self.makeCMakeCmd(arch, target, builddir + "/modules/objc/gen", cmakeargs)
|
||||
cmakecmd = self.makeCMakeCmd(arch, target, builddir + "/modules/objc_bindings_generator/{}/gen".format(self.getObjcTarget()), cmakeargs)
|
||||
cmakecmd.append("-DBUILD_ROOT=%s" % builddir)
|
||||
cmakecmd.append("-DCMAKE_INSTALL_NAME_TOOL=install_name_tool")
|
||||
cmakecmd.append("--no-warn-unused-cli")
|
||||
|
@ -14,6 +14,10 @@ MACOSX_DEPLOYMENT_TARGET='10.12' # default, can be changed via command line opt
|
||||
|
||||
class OSXBuilder(Builder):
|
||||
|
||||
def getObjcTarget(self):
|
||||
# Obj-C generation target
|
||||
return 'osx'
|
||||
|
||||
def getToolchain(self, arch, target):
|
||||
return None
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user