Added build file for ios opencv from sources
This commit is contained in:
Vendored
+151
@@ -0,0 +1,151 @@
|
||||
# Copyright 2023 The MediaPipe Authors. All rights reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""Custom rules for building iOS OpenCV xcframework from sources."""
|
||||
|
||||
load(
|
||||
"@//third_party:opencv_ios_xcframework_files.bzl",
|
||||
"OPENCV_XCFRAMEWORK_IOS_SIMULATOR_FILE_PATHS",
|
||||
"OPENCV_XCFRAMEWORK_IOS_DEVICE_FILE_PATHS",
|
||||
"OPENCV_XCFRAMEWORK_INFO_PLIST_PATH"
|
||||
)
|
||||
|
||||
_OPENCV_XCFRAMEWORK_DIR_NAME = "opencv2.xcframework"
|
||||
_OPENCV_FRAMEWORK_DIR_NAME = "opencv2.framework"
|
||||
_OPENCV_SIMULATOR_PLATFORM_DIR_NAME = "ios-arm64_x86_64-simulator"
|
||||
_OPENCV_DEVICE_PLATFORM_DIR_NAME = "ios-arm64"
|
||||
_OPENCV_PLATFORM_DIR_NAMES = [_OPENCV_SIMULATOR_PLATFORM_DIR_NAME, _OPENCV_DEVICE_PLATFORM_DIR_NAME]
|
||||
|
||||
def _select_headers_impl(ctx):
|
||||
_files = [f for f in ctx.files.srcs
|
||||
if (f.basename.endswith(".h") or f.basename.endswith(".hpp"))
|
||||
and f.dirname.find(ctx.attr.platform) != -1]
|
||||
return [DefaultInfo(files = depset(_files))]
|
||||
|
||||
# This rule selects only the headers from an apple static xcframework filtered by
|
||||
# an input platform string.
|
||||
select_headers = rule(
|
||||
implementation = _select_headers_impl,
|
||||
attrs = {
|
||||
"srcs": attr.label_list(mandatory = True, allow_files=True),
|
||||
"platform": attr.string(mandatory = True),
|
||||
},
|
||||
)
|
||||
|
||||
# This function declares and returns symlinks to the directories within each platform
|
||||
# in `opencv2.xcframework` expected to be present.
|
||||
# The symlinks are created according to the structure stipulated by apple xcframeworks
|
||||
# do that they can be correctly consumed by `apple_static_xcframework_import` rule.
|
||||
def _opencv2_directory_symlinks(ctx, platforms):
|
||||
basenames = ['Resources', 'Headers', 'Modules', 'Versions/Current']
|
||||
symlinks = []
|
||||
|
||||
for platform in platforms:
|
||||
symlinks = symlinks + [
|
||||
ctx.actions.declare_symlink(
|
||||
_OPENCV_XCFRAMEWORK_DIR_NAME + "/{}/{}/{}".format(platform, _OPENCV_FRAMEWORK_DIR_NAME, name)
|
||||
) for name in basenames]
|
||||
|
||||
return symlinks
|
||||
|
||||
# This function declares and returns all the files for each platform expected
|
||||
# to be present in `opencv2.xcframework` after the unzipping action is run.
|
||||
def _opencv2_file_list(ctx, platform_filepath_lists):
|
||||
binary_name = "opencv2"
|
||||
output_files = []
|
||||
binaries_to_symlink = []
|
||||
|
||||
for (platform, filepaths) in platform_filepath_lists:
|
||||
for path in filepaths:
|
||||
file = ctx.actions.declare_file(path)
|
||||
output_files.append(file)
|
||||
if path.endswith(binary_name):
|
||||
symlink_output = ctx.actions.declare_file(
|
||||
_OPENCV_XCFRAMEWORK_DIR_NAME + "/{}/{}/{}".format(
|
||||
platform, _OPENCV_FRAMEWORK_DIR_NAME ,binary_name))
|
||||
binaries_to_symlink.append((symlink_output, file))
|
||||
|
||||
return output_files, binaries_to_symlink
|
||||
|
||||
def _unzip_opencv_xcframework_impl(ctx):
|
||||
|
||||
# Array to iterate over the various platforms to declare output files and
|
||||
# symlinks.
|
||||
platform_filepath_lists = [
|
||||
(_OPENCV_SIMULATOR_PLATFORM_DIR_NAME, OPENCV_XCFRAMEWORK_IOS_SIMULATOR_FILE_PATHS),
|
||||
(_OPENCV_DEVICE_PLATFORM_DIR_NAME, OPENCV_XCFRAMEWORK_IOS_DEVICE_FILE_PATHS)
|
||||
]
|
||||
|
||||
# Gets an exhaustive list of output files which are present in the xcframework.
|
||||
# Also gets array of `(binary simlink, binary)` pairs which are to be symlinked
|
||||
# using `ctx.actions.symlink()`.
|
||||
output_files, binaries_to_symlink = _opencv2_file_list(ctx, platform_filepath_lists)
|
||||
output_files.append(ctx.actions.declare_file(OPENCV_XCFRAMEWORK_INFO_PLIST_PATH))
|
||||
|
||||
# xcframeworks have a directory structure in which the `opencv2.framework` folders for each
|
||||
# platform contain directories which are symlinked to the respective folders of the version
|
||||
# in use. Simply unzipping the zip of the framework will not make Bazel treat these
|
||||
# as symlinks. They have to be explicity declared as symlinks using `ctx.actions.declare_symlink()`.
|
||||
directory_symlinks = _opencv2_directory_symlinks(
|
||||
ctx, [_OPENCV_SIMULATOR_PLATFORM_DIR_NAME, _OPENCV_DEVICE_PLATFORM_DIR_NAME])
|
||||
|
||||
output_files = output_files + directory_symlinks
|
||||
|
||||
args = ctx.actions.args()
|
||||
|
||||
# Add the path of the zip file to be unzipped as an argument to be passed to
|
||||
# `run_shell` action.
|
||||
args.add(ctx.file.zip_file.path)
|
||||
|
||||
# Add the path to the directory in which the framework is to be unzipped to.
|
||||
args.add(ctx.file.zip_file.dirname)
|
||||
|
||||
ctx.actions.run_shell(
|
||||
inputs = [ctx.file.zip_file],
|
||||
outputs = output_files,
|
||||
arguments = [args],
|
||||
progress_message = "Unzipping %s" % ctx.file.zip_file.short_path,
|
||||
command = "unzip -qq $1 -d $2",
|
||||
)
|
||||
|
||||
# The symlinks of the opencv2 binaries for each platform in the xcframework
|
||||
# have to be symlinked using the `ctx.actions.symlink` unlike the directory
|
||||
# symlinks which can be expected to be valid when unzipping is completed.
|
||||
# Otherwise, when tests are run, the linker complaints that the binary is
|
||||
# not found.
|
||||
binary_symlink_files = []
|
||||
for (symlink_output, binary_file) in binaries_to_symlink:
|
||||
ctx.actions.symlink(output = symlink_output, target_file = binary_file)
|
||||
binary_symlink_files.append(symlink_output)
|
||||
|
||||
# Return all the declared output files and symlinks as the output of this
|
||||
# rule.
|
||||
return [ DefaultInfo(files=depset(output_files + binary_symlink_files)) ]
|
||||
|
||||
|
||||
# This rule unzips an `opencv2.xcframework.zip` created by a genrule that
|
||||
# invokes a python script in the opencv 4.5.1 github archive.
|
||||
# It returns all the contents of opencv2.xcframework as a list of files in the
|
||||
# output. This rule works by explicitly declaring files at hardcoded
|
||||
# paths in the opencv2 xcframework bundle which are expected to be present when
|
||||
# the zip file is unzipped. This is a prerequisite since the outputs of this rule
|
||||
# will be consumed by apple_static_xcframework_import which can only take a list
|
||||
# of files as inputs.
|
||||
unzip_opencv_xcframework = rule(
|
||||
implementation = _unzip_opencv_xcframework_impl,
|
||||
attrs = {
|
||||
"zip_file": attr.label(mandatory = True, allow_single_file=True),
|
||||
},
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user