update osx and ios build_framework.py

This commit is contained in:
Alexander Alekhin 2015-12-16 17:28:03 +03:00
parent 3c6aa650a1
commit be23846c4e
12 changed files with 131 additions and 206 deletions

View File

@ -214,20 +214,20 @@ OCV_OPTION(WITH_GPHOTO2 "Include gPhoto2 library support" ON
# OpenCV build components # OpenCV build components
# =================================================== # ===================================================
OCV_OPTION(BUILD_SHARED_LIBS "Build shared libraries (.dll/.so) instead of static ones (.lib/.a)" NOT (ANDROID OR IOS) ) OCV_OPTION(BUILD_SHARED_LIBS "Build shared libraries (.dll/.so) instead of static ones (.lib/.a)" NOT (ANDROID OR APPLE_FRAMEWORK) )
OCV_OPTION(BUILD_opencv_apps "Build utility applications (used for example to train classifiers)" (NOT ANDROID AND NOT WINRT) IF (NOT IOS) ) OCV_OPTION(BUILD_opencv_apps "Build utility applications (used for example to train classifiers)" (NOT ANDROID AND NOT WINRT) IF (NOT APPLE_FRAMEWORK) )
OCV_OPTION(BUILD_ANDROID_EXAMPLES "Build examples for Android platform" ON IF ANDROID ) OCV_OPTION(BUILD_ANDROID_EXAMPLES "Build examples for Android platform" ON IF ANDROID )
OCV_OPTION(BUILD_DOCS "Create build rules for OpenCV Documentation" ON IF NOT WINRT) OCV_OPTION(BUILD_DOCS "Create build rules for OpenCV Documentation" ON IF (NOT WINRT OR APPLE_FRAMEWORK))
OCV_OPTION(BUILD_EXAMPLES "Build all examples" OFF ) OCV_OPTION(BUILD_EXAMPLES "Build all examples" OFF )
OCV_OPTION(BUILD_PACKAGE "Enables 'make package_source' command" ON IF NOT WINRT) OCV_OPTION(BUILD_PACKAGE "Enables 'make package_source' command" ON IF NOT WINRT)
OCV_OPTION(BUILD_PERF_TESTS "Build performance tests" ON IF (NOT IOS) ) OCV_OPTION(BUILD_PERF_TESTS "Build performance tests" ON IF (NOT APPLE_FRAMEWORK) )
OCV_OPTION(BUILD_TESTS "Build accuracy & regression tests" ON IF (NOT IOS) ) OCV_OPTION(BUILD_TESTS "Build accuracy & regression tests" ON IF (NOT APPLE_FRAMEWORK) )
OCV_OPTION(BUILD_WITH_DEBUG_INFO "Include debug info into debug libs (not MSCV only)" ON ) OCV_OPTION(BUILD_WITH_DEBUG_INFO "Include debug info into debug libs (not MSCV only)" ON )
OCV_OPTION(BUILD_WITH_STATIC_CRT "Enables use of staticaly linked CRT for staticaly linked OpenCV" ON IF MSVC ) OCV_OPTION(BUILD_WITH_STATIC_CRT "Enables use of staticaly linked CRT for staticaly linked OpenCV" ON IF MSVC )
OCV_OPTION(BUILD_WITH_DYNAMIC_IPP "Enables dynamic linking of IPP (only for standalone IPP)" OFF ) OCV_OPTION(BUILD_WITH_DYNAMIC_IPP "Enables dynamic linking of IPP (only for standalone IPP)" OFF )
OCV_OPTION(BUILD_FAT_JAVA_LIB "Create fat java wrapper containing the whole OpenCV library" ON IF NOT BUILD_SHARED_LIBS AND CMAKE_COMPILER_IS_GNUCXX ) OCV_OPTION(BUILD_FAT_JAVA_LIB "Create fat java wrapper containing the whole OpenCV library" ON IF NOT BUILD_SHARED_LIBS AND CMAKE_COMPILER_IS_GNUCXX )
OCV_OPTION(BUILD_ANDROID_SERVICE "Build OpenCV Manager for Google Play" OFF IF ANDROID ) OCV_OPTION(BUILD_ANDROID_SERVICE "Build OpenCV Manager for Google Play" OFF IF ANDROID )
OCV_OPTION(BUILD_CUDA_STUBS "Build CUDA modules stubs when no CUDA SDK" OFF IF (NOT IOS) ) OCV_OPTION(BUILD_CUDA_STUBS "Build CUDA modules stubs when no CUDA SDK" OFF IF (NOT APPLE_FRAMEWORK) )
# 3rd party libs # 3rd party libs
OCV_OPTION(BUILD_ZLIB "Build zlib from source" WIN32 OR APPLE ) OCV_OPTION(BUILD_ZLIB "Build zlib from source" WIN32 OR APPLE )
@ -244,7 +244,7 @@ OCV_OPTION(INSTALL_CREATE_DISTRIB "Change install rules to build the distribut
OCV_OPTION(INSTALL_C_EXAMPLES "Install C examples" OFF ) OCV_OPTION(INSTALL_C_EXAMPLES "Install C examples" OFF )
OCV_OPTION(INSTALL_PYTHON_EXAMPLES "Install Python examples" OFF ) OCV_OPTION(INSTALL_PYTHON_EXAMPLES "Install Python examples" OFF )
OCV_OPTION(INSTALL_ANDROID_EXAMPLES "Install Android examples" OFF IF ANDROID ) OCV_OPTION(INSTALL_ANDROID_EXAMPLES "Install Android examples" OFF IF ANDROID )
OCV_OPTION(INSTALL_TO_MANGLED_PATHS "Enables mangled install paths, that help with side by side installs." OFF IF (UNIX AND NOT ANDROID AND NOT IOS AND BUILD_SHARED_LIBS) ) OCV_OPTION(INSTALL_TO_MANGLED_PATHS "Enables mangled install paths, that help with side by side installs." OFF IF (UNIX AND NOT ANDROID AND NOT APPLE_FRAMEWORK AND BUILD_SHARED_LIBS) )
OCV_OPTION(INSTALL_TESTS "Install accuracy and performance test binaries and test data" OFF) OCV_OPTION(INSTALL_TESTS "Install accuracy and performance test binaries and test data" OFF)
# OpenCV build options # OpenCV build options
@ -422,7 +422,7 @@ if(DEFINED CMAKE_DEBUG_POSTFIX)
set(OPENCV_DEBUG_POSTFIX "${CMAKE_DEBUG_POSTFIX}") set(OPENCV_DEBUG_POSTFIX "${CMAKE_DEBUG_POSTFIX}")
endif() endif()
if(INSTALL_CREATE_DISTRIB AND BUILD_SHARED_LIBS AND NOT DEFINED BUILD_opencv_world) if((INSTALL_CREATE_DISTRIB AND BUILD_SHARED_LIBS AND NOT DEFINED BUILD_opencv_world) OR APPLE_FRAMEWORK)
set(BUILD_opencv_world ON CACHE INTERNAL "") set(BUILD_opencv_world ON CACHE INTERNAL "")
endif() endif()
@ -669,7 +669,9 @@ include(cmake/OpenCVGenAndroidMK.cmake)
include(cmake/OpenCVGenConfig.cmake) include(cmake/OpenCVGenConfig.cmake)
# Generate Info.plist for the IOS framework # Generate Info.plist for the IOS framework
include(cmake/OpenCVGenInfoPlist.cmake) if(APPLE_FRAMEWORK)
include(cmake/OpenCVGenInfoPlist.cmake)
endif()
# Generate ABI descriptor # Generate ABI descriptor
include(cmake/OpenCVGenABI.cmake) include(cmake/OpenCVGenABI.cmake)

View File

@ -73,7 +73,7 @@ function(find_python preferred_version min_version library_env include_dir_env
if(_found) if(_found)
set(_version_major_minor "${_version_major}.${_version_minor}") set(_version_major_minor "${_version_major}.${_version_minor}")
if(NOT ANDROID AND NOT IOS) if(NOT ANDROID AND NOT APPLE_FRAMEWORK)
ocv_check_environment_variables(${library_env} ${include_dir_env}) ocv_check_environment_variables(${library_env} ${include_dir_env})
if(NOT ${${library_env}} EQUAL "") if(NOT ${${library_env}} EQUAL "")
set(PYTHON_LIBRARY "${${library_env}}") set(PYTHON_LIBRARY "${${library_env}}")

View File

@ -1,10 +1,5 @@
if(OPENCV_EXTRA_WORLD) set(OPENCV_APPLE_BUNDLE_NAME "OpenCV")
set(OPENCV_APPLE_BUNDLE_NAME "OpenCV_contrib") set(OPENCV_APPLE_BUNDLE_ID "org.opencv")
set(OPENCV_APPLE_BUNDLE_ID "org.opencv_contrib")
else()
set(OPENCV_APPLE_BUNDLE_NAME "OpenCV")
set(OPENCV_APPLE_BUNDLE_ID "org.opencv")
endif()
if(IOS) if(IOS)
configure_file("${OpenCV_SOURCE_DIR}/platforms/ios/Info.plist.in" configure_file("${OpenCV_SOURCE_DIR}/platforms/ios/Info.plist.in"

View File

@ -352,6 +352,7 @@ function(__ocv_sort_modules_by_deps __lst)
ocv_list_sort(${__lst}) ocv_list_sort(${__lst})
set(input ${${__lst}}) set(input ${${__lst}})
set(result "") set(result "")
set(result_extra "")
while(input) while(input)
list(LENGTH input length_before) list(LENGTH input length_before)
foreach (m ${input}) foreach (m ${input})
@ -376,16 +377,27 @@ function(__ocv_sort_modules_by_deps __lst)
list(LENGTH input length_after) list(LENGTH input length_after)
# check for infinite loop or unresolved dependencies # check for infinite loop or unresolved dependencies
if (NOT length_after LESS length_before) if (NOT length_after LESS length_before)
message(WARNING "Unresolved dependencies or loop in dependency graph (${length_after})\n" if(NOT BUILD_SHARED_LIBS)
"Processed ${__lst}: ${${__lst}}\n" if (";${input};" MATCHES ";opencv_world;")
"Good modules: ${result}\n" list(REMOVE_ITEM input "opencv_world")
"Bad modules: ${input}" list(APPEND result_extra "opencv_world")
) else()
list(APPEND result ${input}) # We can't do here something
break() list(APPEND result ${input})
break()
endif()
else()
message(FATAL_ERROR WARNING "Unresolved dependencies or loop in dependency graph (${length_after})\n"
"Processed ${__lst}: ${${__lst}}\n"
"Good modules: ${result}\n"
"Bad modules: ${input}"
)
list(APPEND result ${input})
break()
endif()
endif() endif()
endwhile() endwhile()
set(${__lst} "${result}" PARENT_SCOPE) set(${__lst} "${result};${result_extra}" PARENT_SCOPE)
endfunction() endfunction()
# resolve dependensies # resolve dependensies

View File

@ -725,6 +725,9 @@ function(ocv_target_link_libraries target)
endif() endif()
endforeach() endforeach()
endif() endif()
if(";${LINK_DEPS};" MATCHES ";${target};")
list(REMOVE_ITEM LINK_DEPS "${target}") # prevent "link to itself" warning (world problem)
endif()
target_link_libraries(${target} ${LINK_DEPS}) target_link_libraries(${target} ${LINK_DEPS})
endfunction() endfunction()

View File

@ -83,7 +83,6 @@ file(GLOB imgcodecs_ext_hdrs
) )
if(IOS) if(IOS)
add_definitions(-DHAVE_IOS=1)
list(APPEND imgcodecs_srcs ${CMAKE_CURRENT_LIST_DIR}/src/ios_conversions.mm) list(APPEND imgcodecs_srcs ${CMAKE_CURRENT_LIST_DIR}/src/ios_conversions.mm)
list(APPEND IMGCODECS_LIBRARIES "-framework Accelerate" "-framework CoreGraphics" "-framework CoreImage" "-framework QuartzCore" "-framework AssetsLibrary") list(APPEND IMGCODECS_LIBRARIES "-framework Accelerate" "-framework CoreGraphics" "-framework CoreImage" "-framework QuartzCore" "-framework AssetsLibrary")
endif() endif()

View File

@ -1,7 +1,8 @@
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
# CMake file for java support # CMake file for java support
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
if(IOS OR WINRT OR NOT PYTHON_DEFAULT_AVAILABLE OR NOT ANT_EXECUTABLE OR NOT (JNI_FOUND OR (ANDROID AND ANDROID_NATIVE_API_LEVEL GREATER 7)) if(APPLE_FRAMEWORK OR WINRT OR NOT PYTHON_DEFAULT_AVAILABLE OR NOT ANT_EXECUTABLE
OR NOT (JNI_FOUND OR (ANDROID AND ANDROID_NATIVE_API_LEVEL GREATER 7))
OR BUILD_opencv_world OR BUILD_opencv_world
) )
ocv_module_disable(java) ocv_module_disable(java)

View File

@ -9,7 +9,7 @@ if((WIN32 AND CMAKE_BUILD_TYPE STREQUAL "Debug")
ocv_module_disable(python3) ocv_module_disable(python3)
endif() endif()
if(ANDROID OR IOS OR WINRT) if(ANDROID OR APPLE_FRAMEWORK OR WINRT)
ocv_module_disable(python2) ocv_module_disable(python2)
ocv_module_disable(python3) ocv_module_disable(python3)
endif() endif()

View File

@ -189,7 +189,6 @@ if(HAVE_GPHOTO2)
endif(HAVE_GPHOTO2) endif(HAVE_GPHOTO2)
if(IOS) if(IOS)
add_definitions(-DHAVE_IOS=1)
list(APPEND videoio_srcs list(APPEND videoio_srcs
${CMAKE_CURRENT_LIST_DIR}/src/cap_ios_abstract_camera.mm ${CMAKE_CURRENT_LIST_DIR}/src/cap_ios_abstract_camera.mm
${CMAKE_CURRENT_LIST_DIR}/src/cap_ios_photo_camera.mm ${CMAKE_CURRENT_LIST_DIR}/src/cap_ios_photo_camera.mm

View File

@ -2,7 +2,7 @@ set(the_description "All the selected OpenCV modules in a single binary")
set(OPENCV_MODULE_IS_PART_OF_WORLD FALSE) set(OPENCV_MODULE_IS_PART_OF_WORLD FALSE)
set(BUILD_opencv_world_INIT OFF) set(BUILD_opencv_world_INIT OFF)
if(IOS OR NOT BUILD_SHARED_LIBS) if(APPLE_FRAMEWORK OR NOT BUILD_SHARED_LIBS)
set(OPENCV_MODULE_TYPE STATIC) set(OPENCV_MODULE_TYPE STATIC)
set(OPENCV_WORLD_FLAGS_PROPERTY STATIC_LIBRARY_FLAGS) set(OPENCV_WORLD_FLAGS_PROPERTY STATIC_LIBRARY_FLAGS)
else() else()
@ -59,26 +59,3 @@ endif()
if(BUILD_opencv_highgui AND OPENCV_MODULE_opencv_highgui_IS_PART_OF_WORLD) if(BUILD_opencv_highgui AND OPENCV_MODULE_opencv_highgui_IS_PART_OF_WORLD)
ocv_highgui_configure_target() ocv_highgui_configure_target()
endif() endif()
if(IOS OR APPLE)
set(merge_libs "")
macro(ios_include_3party_libs)
foreach(l ${ARGN})
add_dependencies(${the_module} ${l})
list(APPEND merge_libs "$<TARGET_LINKER_FILE:${l}>")
endforeach()
endmacro()
if(WITH_PNG)
ios_include_3party_libs(zlib libpng)
endif()
if(WITH_JPEG)
ios_include_3party_libs(libjpeg)
endif()
add_custom_command(TARGET ${the_module} POST_BUILD
COMMAND /usr/bin/libtool -static -o ${CMAKE_CURRENT_BINARY_DIR}/${the_module}_fat.a $<TARGET_LINKER_FILE:${the_module}> ${merge_libs}
COMMAND mv ${CMAKE_CURRENT_BINARY_DIR}/${the_module}_fat.a $<TARGET_LINKER_FILE:${the_module}>
)
endif()

100
platforms/ios/build_framework.py Executable file → Normal file
View File

@ -43,7 +43,7 @@ def getXCodeMajor():
return 0 return 0
class Builder: class Builder:
def __init__(self, opencv, contrib): def __init__(self, opencv, contrib, targets):
self.opencv = os.path.abspath(opencv) self.opencv = os.path.abspath(opencv)
self.contrib = None self.contrib = None
if contrib: if contrib:
@ -52,13 +52,7 @@ class Builder:
self.contrib = os.path.abspath(modpath) self.contrib = os.path.abspath(modpath)
else: else:
print("Note: contrib repository is bad - modules subfolder not found", file=sys.stderr) print("Note: contrib repository is bad - modules subfolder not found", file=sys.stderr)
self.targets = [ self.targets = targets
("armv7", "iPhoneOS"),
("armv7s", "iPhoneOS"),
("arm64", "iPhoneOS"),
("i386", "iPhoneSimulator"),
("x86_64", "iPhoneSimulator")
]
def getBD(self, parent, t): def getBD(self, parent, t):
res = os.path.join(parent, '%s-%s' % t) res = os.path.join(parent, '%s-%s' % t)
@ -66,7 +60,7 @@ class Builder:
os.makedirs(res) os.makedirs(res)
return os.path.abspath(res) return os.path.abspath(res)
def build(self, outdir): def _build(self, outdir):
outdir = os.path.abspath(outdir) outdir = os.path.abspath(outdir)
if not os.path.isdir(outdir): if not os.path.isdir(outdir):
os.makedirs(outdir) os.makedirs(outdir)
@ -81,36 +75,38 @@ class Builder:
cmake_flags = [] cmake_flags = []
if self.contrib: if self.contrib:
cmake_flags.append("-DOPENCV_EXTRA_MODULES_PATH=%s" % self.contrib) cmake_flags.append("-DOPENCV_EXTRA_MODULES_PATH=%s" % self.contrib)
if xcode_ver >= 7 and not "Simulator" in t[1]: if xcode_ver >= 7 and t[1] == 'iPhoneOS':
cmake_flags.append("-DCMAKE_C_FLAGS=-fembed-bitcode") cmake_flags.append("-DCMAKE_C_FLAGS=-fembed-bitcode")
cmake_flags.append("-DCMAKE_CXX_FLAGS=-fembed-bitcode") cmake_flags.append("-DCMAKE_CXX_FLAGS=-fembed-bitcode")
self.buildOne(t[0], t[1], mainBD, cmake_flags) self.buildOne(t[0], t[1], mainBD, cmake_flags)
self.mergeLibs(mainBD) self.mergeLibs(mainBD)
self.makeFramework(outdir, dirs) self.makeFramework(outdir, dirs)
def buildOne(self, arch, target, builddir, cmakeargs = []): def build(self, outdir):
# Run cmake try:
self._build(outdir)
except Exception as e:
print("="*60, file=sys.stderr)
print("ERROR: %s" % e, file=sys.stderr)
print("="*60, file=sys.stderr)
traceback.print_exc(file=sys.stderr)
sys.exit(1)
def getToolchain(self, arch, target):
toolchain = os.path.join(self.opencv, "platforms", "ios", "cmake", "Toolchains", "Toolchain-%s_Xcode.cmake" % target) toolchain = os.path.join(self.opencv, "platforms", "ios", "cmake", "Toolchains", "Toolchain-%s_Xcode.cmake" % target)
cmakecmd = [ return toolchain
def getCMakeArgs(self, arch, target):
args = [
"cmake", "cmake",
"-GXcode", "-GXcode",
"-DCMAKE_BUILD_TYPE=Release", "-DAPPLE_FRAMEWORK=ON",
"-DCMAKE_TOOLCHAIN_FILE=%s" % toolchain,
"-DCMAKE_INSTALL_PREFIX=install", "-DCMAKE_INSTALL_PREFIX=install",
"-DCMAKE_BUILD_TYPE=Release",
] ]
if arch.startswith("armv"): return args
cmakecmd.append("-DENABLE_NEON=ON")
cmakecmd.append(self.opencv) def getBuildCommand(self, arch, target):
cmakecmd.extend(cmakeargs)
execute(cmakecmd, cwd = builddir)
# Clean and build
cleanlist = []
cleanlist.extend(glob.glob(os.path.join(builddir, "lib", "Release", "*.a")))
cleanlist.extend(glob.glob(os.path.join(builddir, "modules", "*", "UninstalledProducts", "*.a")))
print("Cleaning files:\n\t%s" % "\n\t".join(cleanlist), file=sys.stderr)
for f in cleanlist:
if os.path.isfile(f):
os.remove(f)
buildcmd = [ buildcmd = [
"xcodebuild", "xcodebuild",
"IPHONEOS_DEPLOYMENT_TARGET=6.0", "IPHONEOS_DEPLOYMENT_TARGET=6.0",
@ -118,15 +114,35 @@ class Builder:
"-sdk", target.lower(), "-sdk", target.lower(),
"-configuration", "Release", "-configuration", "Release",
"-parallelizeTargets", "-parallelizeTargets",
"-jobs", "8", "-jobs", "4"
] ]
return buildcmd
def getInfoPlist(self, builddirs):
return os.path.join(builddirs[0], "ios", "Info.plist")
def buildOne(self, arch, target, builddir, cmakeargs = []):
# Run cmake
toolchain = self.getToolchain(arch, target)
cmakecmd = self.getCMakeArgs(arch, target) + \
(["-DCMAKE_TOOLCHAIN_FILE=%s" % toolchain] if toolchain is not None else [])
if arch.startswith("armv"):
cmakecmd.append("-DENABLE_NEON=ON")
cmakecmd.append(self.opencv)
cmakecmd.extend(cmakeargs)
execute(cmakecmd, cwd = builddir)
# Clean and build
clean_dir = os.path.join(builddir, "install")
if os.path.isdir(clean_dir):
shutil.rmtree(clean_dir)
buildcmd = self.getBuildCommand(arch, target)
execute(buildcmd + ["-target", "ALL_BUILD", "build"], cwd = builddir) execute(buildcmd + ["-target", "ALL_BUILD", "build"], cwd = builddir)
execute(buildcmd + ["-target", "install", "install"], cwd = builddir) execute(["cmake", "-P", "cmake_install.cmake"], cwd = builddir)
def mergeLibs(self, builddir): def mergeLibs(self, builddir):
res = os.path.join(builddir, "lib", "Release", "libopencv_merged.a") res = os.path.join(builddir, "lib", "Release", "libopencv_merged.a")
libs = glob.glob(os.path.join(builddir, "lib", "Release", "*.a")) libs = glob.glob(os.path.join(builddir, "install", "lib", "*.a"))
libs3 = glob.glob(os.path.join(builddir, "3rdparty", "lib", "Release", "*.a")) libs3 = glob.glob(os.path.join(builddir, "install", "share", "OpenCV", "3rdparty", "lib", "*.a"))
print("Merging libraries:\n\t%s" % "\n\t".join(libs + libs3), file=sys.stderr) print("Merging libraries:\n\t%s" % "\n\t".join(libs + libs3), file=sys.stderr)
execute(["libtool", "-static", "-o", res] + libs + libs3) execute(["libtool", "-static", "-o", res] + libs + libs3)
@ -156,7 +172,7 @@ class Builder:
# copy Info.plist # copy Info.plist
resdir = os.path.join(dstdir, "Resources") resdir = os.path.join(dstdir, "Resources")
os.makedirs(resdir) os.makedirs(resdir)
shutil.copyfile(os.path.join(builddirs[0], "ios", "Info.plist"), os.path.join(resdir, "Info.plist")) shutil.copyfile(self.getInfoPlist(builddirs), os.path.join(resdir, "Info.plist"))
# make symbolic links # make symbolic links
links = [ links = [
@ -178,12 +194,12 @@ if __name__ == "__main__":
parser.add_argument('--contrib', metavar='DIR', default=None, help='folder with opencv_contrib repository (default is "None" - build only main framework)') parser.add_argument('--contrib', metavar='DIR', default=None, help='folder with opencv_contrib repository (default is "None" - build only main framework)')
args = parser.parse_args() args = parser.parse_args()
b = Builder(args.opencv, args.contrib) b = Builder(args.opencv, args.contrib,
try: [
b.build(args.out) ("armv7", "iPhoneOS"),
except Exception as e: ("armv7s", "iPhoneOS"),
print("="*60, file=sys.stderr) ("arm64", "iPhoneOS"),
print("ERROR: %s" % e, file=sys.stderr) ("i386", "iPhoneSimulator"),
print("="*60, file=sys.stderr) ("x86_64", "iPhoneSimulator"),
traceback.print_exc(file=sys.stderr) ])
sys.exit(1) b.build(args.out)

143
platforms/osx/build_framework.py Executable file → Normal file
View File

@ -1,124 +1,45 @@
#!/usr/bin/env python #!/usr/bin/env python
""" """
The script builds OpenCV.framework for iOS. The script builds OpenCV.framework for OSX.
The built framework is universal, it can be used to build app and run it on either iOS simulator or real device.
Usage:
./build_framework.py <outputdir>
By cmake conventions (and especially if you work with OpenCV repository),
the output dir should not be a subdirectory of OpenCV source tree.
Script will create <outputdir>, if it's missing, and a few its subdirectories:
<outputdir>
build/
iPhoneOS-*/
[cmake-generated build tree for an iOS device target]
iPhoneSimulator/
[cmake-generated build tree for iOS simulator]
opencv2.framework/
[the framework content]
The script should handle minor OpenCV updates efficiently
- it does not recompile the library from scratch each time.
However, opencv2.framework directory is erased and recreated on each run.
""" """
import glob, re, os, os.path, shutil, string, sys from __future__ import print_function
import os, os.path, sys, argparse, traceback
def build_opencv(srcroot, buildroot, target, arch): # import common code
"builds OpenCV for device or simulator" sys.path.insert(0, os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../ios'))
from build_framework import Builder
builddir = os.path.join(buildroot, target + '-' + arch) class OSXBuilder(Builder):
if not os.path.isdir(builddir):
os.makedirs(builddir)
currdir = os.getcwd()
os.chdir(builddir)
# for some reason, if you do not specify CMAKE_BUILD_TYPE, it puts libs to "RELEASE" rather than "Release"
cmakeargs = ("-GXcode " +
"-DCMAKE_BUILD_TYPE=Release " +
"-DBUILD_SHARED_LIBS=OFF " +
"-DBUILD_DOCS=OFF " +
"-DBUILD_EXAMPLES=OFF " +
"-DBUILD_TESTS=OFF " +
"-DBUILD_PERF_TESTS=OFF " +
"-DBUILD_opencv_apps=OFF " +
"-DBUILD_opencv_world=ON " +
"-DBUILD_opencv_matlab=OFF " +
"-DWITH_TIFF=OFF -DBUILD_TIFF=OFF " +
"-DWITH_JASPER=OFF -DBUILD_JASPER=OFF " +
"-DWITH_WEBP=OFF -DBUILD_WEBP=OFF " +
"-DWITH_OPENEXR=OFF -DBUILD_OPENEXR=OFF " +
"-DWITH_IPP=OFF -DWITH_IPP_A=OFF " +
"-DCMAKE_C_FLAGS=\"-Wno-implicit-function-declaration\" " +
"-DCMAKE_INSTALL_PREFIX=install")
# if cmake cache exists, just rerun cmake to update OpenCV.xproj if necessary
if os.path.isfile(os.path.join(builddir, "CMakeCache.txt")):
os.system("cmake %s ." % (cmakeargs,))
else:
os.system("cmake %s %s" % (cmakeargs, srcroot))
for wlib in [builddir + "/modules/world/UninstalledProducts/libopencv_world.a", def getToolchain(self, arch, target):
builddir + "/lib/Release/libopencv_world.a"]: return None
if os.path.isfile(wlib):
os.remove(wlib)
os.system("xcodebuild -parallelizeTargets ARCHS=%s -jobs 2 -sdk %s -configuration Release -target ALL_BUILD" % (arch, target.lower())) def getBuildCommand(self, arch, target):
os.system("xcodebuild ARCHS=%s -sdk %s -configuration Release -target install install" % (arch, target.lower())) buildcmd = [
os.chdir(currdir) "xcodebuild",
"ARCHS=%s" % arch,
"-sdk", target.lower(),
"-configuration", "Release",
"-parallelizeTargets",
"-jobs", "4"
]
return buildcmd
def put_framework_together(srcroot, dstroot): def getInfoPlist(self, builddirs):
"constructs the framework directory after all the targets are built" return os.path.join(builddirs[0], "osx", "Info.plist")
# find the list of targets (basically, ["iPhoneOS", "iPhoneSimulator"])
targetlist = glob.glob(os.path.join(dstroot, "build", "*"))
targetlist = [os.path.basename(t) for t in targetlist]
# set the current dir to the dst root
currdir = os.getcwd()
framework_dir = dstroot + "/opencv2.framework"
if os.path.isdir(framework_dir):
shutil.rmtree(framework_dir)
os.makedirs(framework_dir)
os.chdir(framework_dir)
# form the directory tree
dstdir = "Versions/A"
os.makedirs(dstdir + "/Resources")
tdir0 = "../build/" + targetlist[0]
# copy headers
shutil.copytree(tdir0 + "/install/include/opencv2", dstdir + "/Headers")
# make universal static lib
wlist = " ".join(["../build/" + t + "/lib/Release/libopencv_world.a" for t in targetlist])
os.system("lipo -create " + wlist + " -o " + dstdir + "/opencv2")
# copy Info.plist
shutil.copyfile(tdir0 + "/osx/Info.plist", dstdir + "/Resources/Info.plist")
# make symbolic links
os.symlink("A", "Versions/Current")
os.symlink("Versions/Current/Headers", "Headers")
os.symlink("Versions/Current/Resources", "Resources")
os.symlink("Versions/Current/opencv2", "opencv2")
def build_framework(srcroot, dstroot):
"main function to do all the work"
targets = ["MacOSX", "MacOSX" ]
archs = ["x86_64", "i386" ]
for i in range(len(targets)):
build_opencv(srcroot, os.path.join(dstroot, "build"), targets[i], archs[i])
put_framework_together(srcroot, dstroot)
if __name__ == "__main__": if __name__ == "__main__":
if len(sys.argv) != 2: folder = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "../.."))
print "Usage:\n\t./build_framework.py <outputdir>\n\n" parser = argparse.ArgumentParser(description='The script builds OpenCV.framework for OSX.')
sys.exit(0) parser.add_argument('out', metavar='OUTDIR', help='folder to put built framework')
parser.add_argument('--opencv', metavar='DIR', default=folder, help='folder with opencv repository (default is "../.." relative to script location)')
parser.add_argument('--contrib', metavar='DIR', default=None, help='folder with opencv_contrib repository (default is "None" - build only main framework)')
args = parser.parse_args()
build_framework(os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "../..")), os.path.abspath(sys.argv[1])) b = OSXBuilder(args.opencv, args.contrib,
[
("x86_64", "MacOSX")
])
b.build(args.out)