Build OpenCV Contrib as a .xcframework, for iOS, on a M1

We needed an OpenCV Contrib module in an iOS app, using Swift Package Manager. I thought the hardest part would be using OpenCV. How wrong I was.

Build OpenCV Contrib as a .xcframework, for iOS, on a M1
Photo by Andrea De Santis / Unsplash


We needed an OpenCV Contrib module in an iOS app. When reviewing options, it was decided we would expose a Swift package, wrapping an Objective-C wrapper, that would itself be the one importing OpenCV.

This meant exposing OpenCV as a Swift Package Manager binary target. Which requires us to build a .xcframework.


Build a .xcframework that we can run on both OS devices and Intel & Apple M1 Mac iPhone / iPad Simulators. Why a .xcframework and not simply a .framework? Because while Swift Package Manager can import binaries, it can only import .xcframework ones, not .framework ones.


  • cmake (installable using brew)
  • python3  (because python2.7 is obsolete)  (installable using brew)
  • opencv source  (via git clone
  • opencv_contrib source (via git clone


Build OpenCV using the proper flags (outfile, contrib, iphoneos arch, iphonesimulator archs):

python3 opencv/platforms/apple/ \
--out ./opencv-build \
--contrib opencv_contrib \
--iphoneos_archs armv7,armv7s,arm64 \
--iphonesimulator_archs arm64 \

Where the --contrib parameter's value is the local path to the opencv_contrib source.

I tried building it for both `x86_64` and `arm64` simulators, but it simply wouldn't build, probably because my M1 Mac has an `arm64` CPU architecture. An Intel Mac (or an M1 one running Rosetta) may not be able to build for the `arm64` simulator. I will look into that in the future.

Go make yourself a nice and warm cup of tea 🫖 (because I currently am writing this in the UK 🇬🇧 )

With a dash of whisky in it 🥃, because I'm more specifically in Scotland 🏴󠁧󠁢󠁳󠁣󠁴󠁿 at the moment


... Wait

... Wait some more

Your tea should be ready now, more or less


... ... Wait


Wait some more


You can now carefully sip your tea

cd /Users/path/opencv-build/iphonesimulator/build/build-arm64-iphonesimulator/modules/objc_bindings_generator/ios/gen
    export LANG\=en_US.US-ASCII
    /Applications/ -x objective-c++ -target arm64-apple-ios9.0-simulator -fmessage-length\=122 -fdiagnostics-show-note-include-stack -fmacro-backtrace-limit\=0 -fcolor-diagnostics -Wno-trigraphs -fpascal-strings -O1 -Wno-missing-field-initializers -Wno-missing-prototypes -Wno-return-type -Wno-implicit-atomic-properties -Wno-objc-interface-ivars -Wno-arc-repeated-use-of-weak -Wno-non-virtual-dtor -Wno-overloaded-virtual -Wno-exit-time-destructors -Wno-missing-braces -Wparentheses -Wswitch -Wno-unused-function -Wno-unused-label -Wno-unused-parameter -Wno-unused-variable -Wunused-value -Wno-emp

Sip some tea.


Did you know there are over 3000 varieties of tea out there? I certainly didn't. Until I looked it up to give you some random, vaguely appropriate, fun fact.

A girl gathering leaves
Photo by 蔡 嘉宇 / Unsplash

Go buy yourself some nice biscuits to go with your tea

-o /Users/path/opencv-build/iphonesimulator/build/build-arm64-iphonesimulator/modules/objc/framework_build/

CompileC /Users/path/opencv-build/iphonesimulator/build/build-arm64-iphonesimulator/modules/objc/framework_build/ /Users/path/opencv-build/build-arm64-iphonesimulator/modules/objc_bindings_generator/ios/gen/objc/ximgproc/ normal arm64 objective-c++ (in target 'opencv2' from project 'opencv2')
    cd /Users/path/opencv-build/iphonesimulator/build/build-arm64-iphonesimulator/modules/objc_bindings_generator/ios/gen
    export LANG\=en_US.US-ASCII
    /Applications/ -x objective-c++ -target arm64-apple-ios9.0-simulator

Sip your tea some more, now with biscuits


... Wait

Put the cup of tea down...

Executing: ['cmake', '-DBUILD_TYPE=Release', '-DCMAKE_INSTALL_PREFIX=/Users/username/path/opencv-build/iphonesimulator/build/build-arm64-iphonesimulator/install', '-P', 'cmake_install.cmake'] in /Users/path/opencv-build/iphonesimulator/build/build-arm64-iphonesimulator/modules/objc/framework_build
Executing: cmake -DBUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=/Users/path/opencv-build/iphonesimulator/build/build-arm64-iphonesimulator/install -P cmake_install.cmake
-- Install configuration: "Release"

... lay back in your chair...

... and do a 360!

Turn around some more!


Oh. That got creepy.

Oh, it's done building! Congrats!

Finished building ./opencv-build/opencv2.xcframework

That wasn't so hard now, was it? Now you can use OpenCV contrib modules in your app! Isn't that nice! Next, how to import it into our projects as a binary target using Swift Package Manager!