Fix cmake to build OpenCV framework on OSX
authorIevgen Khvedchenia <ekhvedchenya@gmail.com>
Tue, 1 Jul 2014 19:31:57 +0000 (22:31 +0300)
committerIevgen Khvedchenia <ekhvedchenya@gmail.com>
Tue, 1 Jul 2014 19:31:57 +0000 (22:31 +0300)
3rdparty/libjpeg/CMakeLists.txt
cmake/OpenCVGenInfoPlist.cmake
modules/world/CMakeLists.txt
platforms/osx/Info.plist.in [new file with mode: 0644]
platforms/osx/build_framework.py [new file with mode: 0755]

index 028a583..65a9d1c 100644 (file)
@@ -9,7 +9,7 @@ ocv_include_directories(${CMAKE_CURRENT_SOURCE_DIR})
 file(GLOB lib_srcs *.c)
 file(GLOB lib_hdrs *.h)
 
-if(ANDROID OR IOS)
+if(ANDROID OR IOS OR APPLE)
   ocv_list_filterout(lib_srcs jmemansi.c)
 else()
   ocv_list_filterout(lib_srcs jmemnobs.c)
index 97c674c..db418d1 100644 (file)
@@ -1,4 +1,7 @@
 if(IOS)
   configure_file("${OpenCV_SOURCE_DIR}/platforms/ios/Info.plist.in"
                  "${CMAKE_BINARY_DIR}/ios/Info.plist")
+elseif(APPLE)
+  configure_file("${OpenCV_SOURCE_DIR}/platforms/osx/Info.plist.in"
+                 "${CMAKE_BINARY_DIR}/osx/Info.plist")
 endif()
index 6a84c1b..33a9304 100644 (file)
@@ -106,11 +106,11 @@ macro(ios_include_3party_libs)
   ocv_list_filterout(objlist jmemansi) # <<= dirty fix
 endmacro()
 
-if(IOS AND WITH_PNG)
+if( (IOS OR APPLE) AND WITH_PNG)
   ios_include_3party_libs(zlib libpng)
 endif()
 
-if(IOS AND WITH_JPEG)
+if( (IOS OR APPLE) AND WITH_JPEG)
   ios_include_3party_libs(libjpeg)
 endif()
 
diff --git a/platforms/osx/Info.plist.in b/platforms/osx/Info.plist.in
new file mode 100644 (file)
index 0000000..b2a3baf
--- /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>org.opencv</string>
+    <key>CFBundleVersion</key>
+    <string>${OPENCV_LIBVERSION}</string>
+    <key>CFBundleShortVersionString</key>
+    <string>${OPENCV_LIBVERSION}</string>
+    <key>CFBundleSignature</key>
+    <string>????</string>
+    <key>CFBundlePackageType</key>
+    <string>FMWK</string>
+</dict>
+</plist>
diff --git a/platforms/osx/build_framework.py b/platforms/osx/build_framework.py
new file mode 100755 (executable)
index 0000000..456ea95
--- /dev/null
@@ -0,0 +1,124 @@
+#!/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 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
+
+def build_opencv(srcroot, buildroot, target, arch):
+    "builds OpenCV for device or simulator"
+
+    builddir = os.path.join(buildroot, target + '-' + arch)
+    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",
+                 builddir + "/lib/Release/libopencv_world.a"]:
+        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()))
+    os.system("xcodebuild ARCHS=%s -sdk %s -configuration Release -target install install" % (arch, 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)
+
+    # 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 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]))