added script to build the universal opencv2.framework for iOS device and simulator...
authorVadim Pisarevsky <no@email>
Sat, 9 Jun 2012 16:18:39 +0000 (16:18 +0000)
committerVadim Pisarevsky <no@email>
Sat, 9 Jun 2012 16:18:39 +0000 (16:18 +0000)
ios/Info.plist.in [new file with mode: 0644]
ios/build_framework.py [new file with mode: 0755]
modules/core/src/persistence.cpp
modules/world/CMakeLists.txt

diff --git a/ios/Info.plist.in b/ios/Info.plist.in
new file mode 100644 (file)
index 0000000..9b3d882
--- /dev/null
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
+<plist version="1.0">
+<dict>
+       <key>CFBundleName</key>
+       <string>OpenCV</string>
+       <key>CFBundleIdentifier</key>
+    <string>com.itseez.opencv</string>
+       <key>CFBundleVersion</key>
+       <string>${VERSION}</string>
+       <key>CFBundleShortVersionString</key>
+       <string>${VERSION}</string>
+       <key>CFBundleSignature</key>
+       <string>????</string>
+       <key>CFBundlePackageType</key>
+       <string>FMWK</string>
+</dict>
+</plist>
diff --git a/ios/build_framework.py b/ios/build_framework.py
new file mode 100755 (executable)
index 0000000..f6a6970
--- /dev/null
@@ -0,0 +1,120 @@
+#!/usr/bin/env python
+"""
+The script builds OpenCV.framework for iOS.
+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 SVN 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]
+        OpenCV.framework/
+            [the framework content]
+
+The script should handle minor OpenCV updates efficiently
+- it does not recompile the library from scratch each time.
+However, OpenCV.framework directory is erased and recreated on each run.
+"""
+
+import glob, re, os, os.path, shutil, string, sys
+
+def build_opencv(srcroot, buildroot, target):
+    "builds OpenCV for device or simulator"
+    
+    builddir = os.path.join(buildroot, target)
+    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 " +
+                "-DCMAKE_TOOLCHAIN_FILE=%s/ios/cmake/Toolchains/Toolchain-%s_Xcode.cmake " +
+                "-DBUILD_opencv_world=ON " +
+                "-DCMAKE_INSTALL_PREFIX=install") % (srcroot, target)
+    # 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))
+    os.system("xcodebuild -parallelizeTargets -jobs 8 -sdk %s -configuration Release -target ALL_BUILD" % target.lower())
+    os.system("xcodebuild -sdk %s -configuration Release -target install install" % target.lower())
+    os.chdir(currdir)
+    
+def put_framework_together(srcroot, dstroot):
+    "constructs the framework directory after all the targets are built"
+    
+    # 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)
+    
+    # determine OpenCV version (without subminor part)
+    tdir0 = "../build/" + targetlist[0]
+    cfg = open(tdir0 + "/cvconfig.h", "rt")
+    for l in cfg.readlines():
+        if l.startswith("#define  VERSION"):
+            opencv_version = l[l.find("\"")+1:l.rfind(".")]
+            break
+    cfg.close()
+    
+    # form the directory tree
+    dstdir = "Versions/A"
+    os.makedirs(dstdir + "/Resources")
+
+    # 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")
+    
+    # form Info.plist
+    srcfile = open(srcroot + "/ios/Info.plist.in", "rt")
+    dstfile = open(dstdir + "/Resources/Info.plist", "wt")
+    for l in srcfile.readlines():
+        dstfile.write(l.replace("${VERSION}", opencv_version))
+    srcfile.close()
+    dstfile.close()
+    
+    # copy cascades
+    # TODO ...
+    
+    # make symbolic links
+    os.symlink(dstdir + "/Headers", "Headers")
+    os.symlink(dstdir + "/Resources", "Resources")
+    os.symlink(dstdir + "/opencv2", "opencv2")
+    os.symlink("A", "Versions/Current")
+        
+        
+def build_framework(srcroot, dstroot):
+    "main function to do all the work"
+    
+    for target in ["iPhoneOS", "iPhoneSimulator"]:
+        build_opencv(srcroot, os.path.join(dstroot, "build"), target)
+    
+    put_framework_together(srcroot, dstroot)
+    
+
+if __name__ == "__main__":
+    if len(sys.argv) != 2:
+        print "Usage:\n\t./build_framework.py <outputdir>\n\n"
+        sys.exit(0)
+    
+    build_framework(os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "..")), os.path.abspath(sys.argv[1]))
index 2c1432b..3f605f3 100644 (file)
 #include <deque>
 #include <iterator>
 #include <wchar.h>
+
+#define USE_ZLIB 1
+
+#ifdef __APPLE__
+#include "TargetConditionals.h"
+#if defined TARGET_OS_IPHONE || defined TARGET_IPHONE_SIMULATOR
+#undef USE_ZLIB
+#define USE_ZLIB 0
+typedef void* gzFile;
+#endif
+#endif
+
+#if USE_ZLIB
 #include <zlib.h>
+#endif
 
 /****************************************************************************************\
 *                            Common macros and type definitions                          *
@@ -258,8 +272,10 @@ static void icvPuts( CvFileStorage* fs, const char* str )
         std::copy(str, str + strlen(str), std::back_inserter(*fs->outbuf));
     else if( fs->file )
         fputs( str, fs->file );
+#if USE_ZLIB
     else if( fs->gzfile )
         gzputs( fs->gzfile, str );
+#endif
     else
         CV_Error( CV_StsError, "The storage is not opened" );
 }
@@ -286,8 +302,10 @@ static char* icvGets( CvFileStorage* fs, char* str, int maxCount )
     }
     if( fs->file )
         return fgets( str, maxCount, fs->file );
+#if USE_ZLIB
     if( fs->gzfile )
         return gzgets( fs->gzfile, str, maxCount );
+#endif
     CV_Error( CV_StsError, "The storage is not opened" );
     return 0;
 }
@@ -298,8 +316,10 @@ static int icvEof( CvFileStorage* fs )
         return fs->strbufpos >= fs->strbufsize;
     if( fs->file )
         return feof(fs->file);
+#if USE_ZLIB
     if( fs->gzfile )
         return gzeof(fs->gzfile);
+#endif
     return false;
 }
 
@@ -307,8 +327,10 @@ static void icvCloseFile( CvFileStorage* fs )
 {
     if( fs->file )
         fclose( fs->file );
+#if USE_ZLIB
     else if( fs->gzfile )
         gzclose( fs->gzfile );
+#endif
     fs->file = 0;
     fs->gzfile = 0;
     fs->strbuf = 0;
@@ -320,8 +342,10 @@ static void icvRewind( CvFileStorage* fs )
 {
     if( fs->file )
         rewind(fs->file);
+#if USE_ZLIB
     else if( fs->gzfile )
         gzrewind(fs->gzfile);
+#endif
     fs->strbufpos = 0;
 }
 
@@ -2713,10 +2737,14 @@ cvOpenFileStorage( const char* filename, CvMemStorage* dststorage, int flags, co
         }
         else
         {
+            #if USE_ZLIB
             char mode[] = { fs->write_mode ? 'w' : 'r', 'b', compression ? compression : '3', '\0' };
             fs->gzfile = gzopen(fs->filename, mode);
             if( !fs->gzfile )
                 goto _exit_;
+            #else
+            CV_Error(CV_StsNotImplemented, "There is no compressed file storage support in this configuration");
+            #endif
         }
     }
     
index 9d626e8..1530cc8 100644 (file)
@@ -1,7 +1,13 @@
 set(the_description "All the selected OpenCV modules in a single binary")
 set(OPENCV_MODULE_IS_PART_OF_WORLD FALSE)
 set(BUILD_opencv_world_INIT OFF)
+if(IOS)
+set(BUILD_WORLD_AS_STATIC 1)
+endif()
+
+if(NOT BUILD_WORLD_AS_STATIC)
 set(OPENCV_MODULE_TYPE SHARED)
+endif()
 
 ocv_add_module(world opencv_core)
 
@@ -79,14 +85,25 @@ string(REPLACE ";" " " objlist "${objlist}")
 if(have_cfg)
   string(REGEX REPLACE "<CONFIGURATION>" "Debug" objlist_dbg "${objlist}")
   string(REGEX REPLACE "<CONFIGURATION>" "Release" objlist_rls "${objlist}")
-  set_target_properties(${the_module} PROPERTIES
-    LINK_FLAGS_DEBUG ${objlist_dbg}
-    LINK_FLAGS_RELEASE ${objlist_rls})
+  if(BUILD_WORLD_AS_STATIC)
+      set_target_properties(${the_module} PROPERTIES
+        STATIC_LIBRARY_FLAGS_DEBUG ${objlist_dbg}
+        STATIC_LIBRARY_FLAGS_RELEASE ${objlist_rls})
+  else()
+      set_target_properties(${the_module} PROPERTIES
+        LINK_FLAGS_DEBUG ${objlist_dbg}
+        LINK_FLAGS_RELEASE ${objlist_rls})
+  endif()
 else()
   file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/world_objects.list" "${objlist}")
   execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CMAKE_CURRENT_BINARY_DIR}/world_objects.list" "${CMAKE_CURRENT_BINARY_DIR}/world_objects.rsp" OUTPUT_QUIET)
-  set_target_properties(${the_module} PROPERTIES
-    LINK_FLAGS "@${CMAKE_CURRENT_BINARY_DIR}/world_objects.rsp")
+  if(BUILD_WORLD_AS_STATIC)
+    set_target_properties(${the_module} PROPERTIES
+      STATIC_LIBRARY_FLAGS "@${CMAKE_CURRENT_BINARY_DIR}/world_objects.rsp")
+  else()
+    set_target_properties(${the_module} PROPERTIES
+      LINK_FLAGS "@${CMAKE_CURRENT_BINARY_DIR}/world_objects.rsp")
+  endif()
 endif()
 
 ocv_add_precompiled_headers(${the_module})