Skip to content

Commit

Permalink
Fix cmake to build OpenCV framework on OSX
Browse files Browse the repository at this point in the history
  • Loading branch information
BloodAxe committed Jul 1, 2014
1 parent 3f485d5 commit 92ead5f
Show file tree
Hide file tree
Showing 5 changed files with 148 additions and 3 deletions.
2 changes: 1 addition & 1 deletion 3rdparty/libjpeg/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions cmake/OpenCVGenInfoPlist.cmake
Original file line number Diff line number Diff line change
@@ -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()
4 changes: 2 additions & 2 deletions modules/world/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()

Expand Down
18 changes: 18 additions & 0 deletions platforms/osx/Info.plist.in
Original file line number Diff line number Diff line change
@@ -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>
124 changes: 124 additions & 0 deletions platforms/osx/build_framework.py
Original file line number Diff line number Diff line change
@@ -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]))

0 comments on commit 92ead5f

Please sign in to comment.