From ce57da2b64f12c83a0bef9eb96957b3551d3a0af Mon Sep 17 00:00:00 2001 From: Junrou Nishida Date: Sun, 25 Aug 2024 13:38:30 +0900 Subject: [PATCH] build: OpenCV 4 for iOS --- WORKSPACE | 10 +- third_party/mediapipe_workaround.diff | 13 +++ third_party/opencv.BUILD | 11 ++ third_party/opencv_ios_source.BUILD | 146 ++++++++++++++++++++++++++ 4 files changed, 175 insertions(+), 5 deletions(-) create mode 100644 third_party/opencv_ios_source.BUILD diff --git a/WORKSPACE b/WORKSPACE index ca922b696..c757e8075 100644 --- a/WORKSPACE +++ b/WORKSPACE @@ -435,20 +435,20 @@ http_archive( url = "https://github.com/opencv/opencv/releases/download/3.2.0/opencv-3.2.0-ios-framework.zip", ) -# Building an opencv.xcframework from the OpenCV 4.5.3 sources is necessary for +# Building an opencv.xcframework from the OpenCV 4.5.5 sources is necessary for # MediaPipe iOS Task Libraries to be supported on arm64(M1) Macs. An # `opencv.xcframework` archive has not been released and it is recommended to # build the same from source using a script provided in OpenCV 4.5.0 upwards. -# OpenCV is fixed to version to 4.5.3 since swift support can only be disabled +# OpenCV is fixed to version to 4.5.5 since swift support can only be disabled # from 4.5.3 upwards. This is needed to avoid errors when the library is linked # in Xcode. Swift support will be added in when the final binary MediaPipe iOS # Task libraries are built. http_archive( name = "ios_opencv_source", - sha256 = "a61e7a4618d353140c857f25843f39b2abe5f451b018aab1604ef0bc34cd23d5", - build_file = "@mediapipe//third_party:opencv_ios_source.BUILD", + # sha256 = "a61e7a4618d353140c857f25843f39b2abe5f451b018aab1604ef0bc34cd23d5", + build_file = "@//third_party:opencv_ios_source.BUILD", type = "zip", - url = "https://github.com/opencv/opencv/archive/refs/tags/4.5.3.zip", + url = "https://github.com/opencv/opencv/archive/refs/tags/4.5.5.zip", ) http_archive( diff --git a/third_party/mediapipe_workaround.diff b/third_party/mediapipe_workaround.diff index bd2c0481a..598fc7c25 100644 --- a/third_party/mediapipe_workaround.diff +++ b/third_party/mediapipe_workaround.diff @@ -34,3 +34,16 @@ index a11a23fc..dbb5fe6c 100644 core::TaskRunner::Create( std::move(graph_config), std::move(resolver), std::move(packets_callback), std::move(default_executor), +diff --git a/third_party/opencv_ios_source.bzl b/third_party/opencv_ios_source.bzl +index 54bb4d5e..9632afd8 100644 +--- a/third_party/opencv_ios_source.bzl ++++ b/third_party/opencv_ios_source.bzl +@@ -15,7 +15,7 @@ + """Custom rules for building iOS OpenCV xcframework from sources.""" + + load( +- "@//third_party:opencv_ios_xcframework_files.bzl", ++ "@mediapipe//third_party:opencv_ios_xcframework_files.bzl", + "OPENCV_XCFRAMEWORK_INFO_PLIST_PATH", + "OPENCV_XCFRAMEWORK_IOS_DEVICE_FILE_PATHS", + "OPENCV_XCFRAMEWORK_IOS_SIMULATOR_FILE_PATHS", diff --git a/third_party/opencv.BUILD b/third_party/opencv.BUILD index dcb88bfab..aac4b2b61 100644 --- a/third_party/opencv.BUILD +++ b/third_party/opencv.BUILD @@ -38,6 +38,16 @@ config_setting( }, ) +config_setting( + name = "opencv_ios_source_build", + flag_values = { + ":switch": "cmake", + }, + values = { + "apple_platform_type": "ios", + }, +) + selects.config_setting_group( name = "cmake_static_win", match_all = ["@bazel_tools//src/conditions:windows", ":cmake_static"], @@ -62,6 +72,7 @@ alias( name = "opencv", actual = select({ ":cmake_static": ":opencv_cmake", + ":opencv_ios_source_build": "@ios_opencv_source//:opencv", "//conditions:default": ":opencv_binary", }), ) diff --git a/third_party/opencv_ios_source.BUILD b/third_party/opencv_ios_source.BUILD new file mode 100644 index 000000000..05b3bd47b --- /dev/null +++ b/third_party/opencv_ios_source.BUILD @@ -0,0 +1,146 @@ +# Copyright 2023 The MediaPipe Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# CHANGES: +# - OpenCV 4.5.3 -> 4.5.5 + +# Description: +# OpenCV xcframework for video/image processing on iOS. + +load( + "@mediapipe//third_party:opencv_ios_source.bzl", + "select_headers", + "unzip_opencv_xcframework", +) +load( + "@build_bazel_rules_apple//apple:apple.bzl", + "apple_static_xcframework_import", +) + +licenses(["notice"]) # BSD license + +exports_files(["LICENSE"]) + +# Build opencv2.xcframework from source using a convenience script provided in +# OPENCV sources and zip the xcframework. We only build the modules required by MediaPipe by specifying +# the modules to be ignored as command line arguments. +# We also specify the simulator and device architectures we are building for. +# Currently we only support iOS arm64 (M1 Macs) and x86_64(Intel Macs) simulators +# and arm64 iOS devices. +# Bitcode and Swift support. Swift support will be added in when the final binary +# for MediaPipe iOS Task libraries are built. Shipping with OPENCV built with +# Swift support throws linker errors when the MediaPipe framework is used from +# an iOS project. +# When building on M1 Macs, cmake version cannot be higher than 3.24.0. This is +# is mentioned in an open issue in the opencv github repo. +genrule( + name = "build_opencv_xcframework", + srcs = glob(["opencv-4.5.5/**"]), + outs = ["opencv2.xcframework.zip"], + cmd = "&&".join([ + "$(location opencv-4.5.5/platforms/apple/build_xcframework.py) \ + --iphonesimulator_archs arm64,x86_64 \ + --iphoneos_archs arm64 \ + --without dnn \ + --without ml \ + --without stitching \ + --without photo \ + --without objdetect \ + --without gapi \ + --without flann \ + --without highgui \ + --without videoio \ + --disable PROTOBUF \ + --disable-bitcode \ + --disable-swift \ + --build_only_specified_archs \ + --out $(@D)", + "cd $(@D)", + "zip --symlinks -r opencv2.xcframework.zip opencv2.xcframework", + ]), +) + +# Unzips `opencv2.xcframework.zip` built from source by `build_opencv_xcframework` +# genrule and returns an exhaustive list of all its files including symlinks. +unzip_opencv_xcframework( + name = "opencv2_unzipped_xcframework_files", + zip_file = "opencv2.xcframework.zip", +) + +# Imports the files of the unzipped `opencv2.xcframework` as an apple static +# framework which can be linked to iOS targets. +apple_static_xcframework_import( + name = "opencv_xcframework", + visibility = ["//visibility:public"], + xcframework_imports = [":opencv2_unzipped_xcframework_files"], +) + +# Filters the headers for each platform in `opencv2.xcframework` which will be +# used as headers in a `cc_library` that can be linked to C++ targets. +select_headers( + name = "opencv_xcframework_device_headers", + srcs = [":opencv_xcframework"], + platform = "ios-arm64", +) + +select_headers( + name = "opencv_xcframework_simulator_headers", + srcs = [":opencv_xcframework"], + platform = "ios-arm64_x86_64-simulator", +) + +# `cc_library` that can be linked to C++ targets to import opencv headers. +cc_library( + name = "opencv", + hdrs = select({ + "@//mediapipe:ios_x86_64": [ + ":opencv_xcframework_simulator_headers", + ], + "@//mediapipe:ios_sim_arm64": [ + ":opencv_xcframework_simulator_headers", + ], + "@//mediapipe:ios_arm64": [ + ":opencv_xcframework_device_headers", + ], + # A value from above is chosen arbitarily. + "//conditions:default": [ + ":opencv_xcframework_simulator_headers", + ], + }), + copts = [ + "-std=c++11", + "-x objective-c++", + ], + include_prefix = "opencv2", + linkopts = [ + "-framework AssetsLibrary", + "-framework CoreFoundation", + "-framework CoreGraphics", + "-framework CoreMedia", + "-framework Accelerate", + "-framework CoreImage", + "-framework AVFoundation", + "-framework CoreVideo", + "-framework QuartzCore", + ], + strip_include_prefix = select({ + "@//mediapipe:ios_x86_64": "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers", + "@//mediapipe:ios_sim_arm64": "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers", + "@//mediapipe:ios_arm64": "opencv2.xcframework/ios-arm64/opencv2.framework/Versions/A/Headers", + # Random value is selected for default cases. + "//conditions:default": "opencv2.xcframework/ios-arm64_x86_64-simulator/opencv2.framework/Versions/A/Headers", + }), + visibility = ["//visibility:public"], + deps = [":opencv_xcframework"], +)