From 92ead5fab38aec7715766683b023f96c15ca6f34 Mon Sep 17 00:00:00 2001 From: Ievgen Khvedchenia Date: Tue, 1 Jul 2014 22:31:57 +0300 Subject: [PATCH] Fix cmake to build OpenCV framework on OSX --- 3rdparty/libjpeg/CMakeLists.txt | 2 +- cmake/OpenCVGenInfoPlist.cmake | 3 + modules/world/CMakeLists.txt | 4 +- platforms/osx/Info.plist.in | 18 ++++++ platforms/osx/build_framework.py | 124 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 148 insertions(+), 3 deletions(-) create mode 100644 platforms/osx/Info.plist.in create mode 100755 platforms/osx/build_framework.py diff --git a/3rdparty/libjpeg/CMakeLists.txt b/3rdparty/libjpeg/CMakeLists.txt index 028a583..65a9d1c 100644 --- a/3rdparty/libjpeg/CMakeLists.txt +++ b/3rdparty/libjpeg/CMakeLists.txt @@ -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) diff --git a/cmake/OpenCVGenInfoPlist.cmake b/cmake/OpenCVGenInfoPlist.cmake index 97c674c..db418d1 100644 --- a/cmake/OpenCVGenInfoPlist.cmake +++ b/cmake/OpenCVGenInfoPlist.cmake @@ -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() diff --git a/modules/world/CMakeLists.txt b/modules/world/CMakeLists.txt index 6a84c1b..33a9304 100644 --- a/modules/world/CMakeLists.txt +++ b/modules/world/CMakeLists.txt @@ -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 index 0000000..b2a3baf --- /dev/null +++ b/platforms/osx/Info.plist.in @@ -0,0 +1,18 @@ + + + + + CFBundleName + OpenCV + CFBundleIdentifier + org.opencv + CFBundleVersion + ${OPENCV_LIBVERSION} + CFBundleShortVersionString + ${OPENCV_LIBVERSION} + CFBundleSignature + ???? + CFBundlePackageType + FMWK + + diff --git a/platforms/osx/build_framework.py b/platforms/osx/build_framework.py new file mode 100755 index 0000000..456ea95 --- /dev/null +++ b/platforms/osx/build_framework.py @@ -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 + +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 , if it's missing, and a few its subdirectories: + + + 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 \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])) -- 2.7.4