Merge pull request #24136 from komakai:visionos_support

Add experimental support for Apple VisionOS platform #24136

### Pull Request Readiness Checklist

See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request

- [x] I agree to contribute to the project under Apache 2 License.
- [x] To the best of my knowledge, the proposed patch is not based on a code under GPL or another license that is incompatible with OpenCV
- [x] The PR is proposed to the proper branch

This is dependent on cmake support for VisionOs which is currently in progress.
Creating PR now to test that there are no regressions in iOS and macOS builds
This commit is contained in:
Giles Payne 2023-12-20 21:35:10 +09:00 committed by GitHub
parent abbd878eb5
commit 3d9cb5329c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
19 changed files with 325 additions and 100 deletions

View File

@ -238,9 +238,9 @@ OCV_OPTION(BUILD_ITT "Build Intel ITT from source"
# Optional 3rd party components # Optional 3rd party components
# =================================================== # ===================================================
OCV_OPTION(WITH_1394 "Include IEEE1394 support" ON OCV_OPTION(WITH_1394 "Include IEEE1394 support" ON
VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT WINRT VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT XROS AND NOT WINRT
VERIFY HAVE_DC1394_2) VERIFY HAVE_DC1394_2)
OCV_OPTION(WITH_AVFOUNDATION "Use AVFoundation for Video I/O (iOS/Mac)" ON OCV_OPTION(WITH_AVFOUNDATION "Use AVFoundation for Video I/O (iOS/visionOS/Mac)" ON
VISIBLE_IF APPLE VISIBLE_IF APPLE
VERIFY HAVE_AVFOUNDATION) VERIFY HAVE_AVFOUNDATION)
OCV_OPTION(WITH_AVIF "Enable AVIF support" OFF OCV_OPTION(WITH_AVIF "Enable AVIF support" OFF
@ -249,15 +249,15 @@ OCV_OPTION(WITH_CAP_IOS "Enable iOS video capture" ON
VISIBLE_IF IOS VISIBLE_IF IOS
VERIFY HAVE_CAP_IOS) VERIFY HAVE_CAP_IOS)
OCV_OPTION(WITH_CAROTENE "Use NVidia carotene acceleration library for ARM platform" (NOT CV_DISABLE_OPTIMIZATION) OCV_OPTION(WITH_CAROTENE "Use NVidia carotene acceleration library for ARM platform" (NOT CV_DISABLE_OPTIMIZATION)
VISIBLE_IF (ARM OR AARCH64) AND NOT IOS) VISIBLE_IF (ARM OR AARCH64) AND NOT IOS AND NOT XROS)
OCV_OPTION(WITH_CPUFEATURES "Use cpufeatures Android library" ON OCV_OPTION(WITH_CPUFEATURES "Use cpufeatures Android library" ON
VISIBLE_IF ANDROID VISIBLE_IF ANDROID
VERIFY HAVE_CPUFEATURES) VERIFY HAVE_CPUFEATURES)
OCV_OPTION(WITH_VTK "Include VTK library support (and build opencv_viz module eiher)" ON OCV_OPTION(WITH_VTK "Include VTK library support (and build opencv_viz module eiher)" ON
VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT WINRT AND NOT CMAKE_CROSSCOMPILING VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT XROS AND NOT WINRT AND NOT CMAKE_CROSSCOMPILING
VERIFY HAVE_VTK) VERIFY HAVE_VTK)
OCV_OPTION(WITH_CUDA "Include NVidia Cuda Runtime support" OFF OCV_OPTION(WITH_CUDA "Include NVidia Cuda Runtime support" OFF
VISIBLE_IF NOT IOS AND NOT WINRT VISIBLE_IF NOT IOS AND NOT XROS AND NOT WINRT
VERIFY HAVE_CUDA) VERIFY HAVE_CUDA)
OCV_OPTION(WITH_CUFFT "Include NVidia Cuda Fast Fourier Transform (FFT) library support" WITH_CUDA OCV_OPTION(WITH_CUFFT "Include NVidia Cuda Fast Fourier Transform (FFT) library support" WITH_CUDA
VISIBLE_IF WITH_CUDA VISIBLE_IF WITH_CUDA
@ -278,10 +278,10 @@ OCV_OPTION(WITH_EIGEN "Include Eigen2/Eigen3 support" (NOT CV_DISABLE_OPTIMIZATI
VISIBLE_IF NOT WINRT VISIBLE_IF NOT WINRT
VERIFY HAVE_EIGEN) VERIFY HAVE_EIGEN)
OCV_OPTION(WITH_FFMPEG "Include FFMPEG support" (NOT ANDROID) OCV_OPTION(WITH_FFMPEG "Include FFMPEG support" (NOT ANDROID)
VISIBLE_IF NOT IOS AND NOT WINRT VISIBLE_IF NOT IOS AND NOT XROS AND NOT WINRT
VERIFY HAVE_FFMPEG) VERIFY HAVE_FFMPEG)
OCV_OPTION(WITH_GSTREAMER "Include Gstreamer support" ON OCV_OPTION(WITH_GSTREAMER "Include Gstreamer support" ON
VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT WINRT VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT XROS AND NOT WINRT
VERIFY HAVE_GSTREAMER AND GSTREAMER_VERSION VERSION_GREATER "0.99") VERIFY HAVE_GSTREAMER AND GSTREAMER_VERSION VERSION_GREATER "0.99")
OCV_OPTION(WITH_GTK "Include GTK support" ON OCV_OPTION(WITH_GTK "Include GTK support" ON
VISIBLE_IF UNIX AND NOT APPLE AND NOT ANDROID VISIBLE_IF UNIX AND NOT APPLE AND NOT ANDROID
@ -293,7 +293,7 @@ OCV_OPTION(WITH_WAYLAND "Include Wayland support" OFF
VISIBLE_IF UNIX AND NOT APPLE AND NOT ANDROID VISIBLE_IF UNIX AND NOT APPLE AND NOT ANDROID
VERIFY HAVE_WAYLAND) VERIFY HAVE_WAYLAND)
OCV_OPTION(WITH_IPP "Include Intel IPP support" (NOT MINGW AND NOT CV_DISABLE_OPTIMIZATION) OCV_OPTION(WITH_IPP "Include Intel IPP support" (NOT MINGW AND NOT CV_DISABLE_OPTIMIZATION)
VISIBLE_IF (X86_64 OR X86) AND NOT WINRT AND NOT IOS VISIBLE_IF (X86_64 OR X86) AND NOT WINRT AND NOT IOS AND NOT XROS
VERIFY HAVE_IPP) VERIFY HAVE_IPP)
OCV_OPTION(WITH_HALIDE "Include Halide support" OFF OCV_OPTION(WITH_HALIDE "Include Halide support" OFF
VISIBLE_IF TRUE VISIBLE_IF TRUE
@ -309,10 +309,10 @@ OCV_OPTION(WITH_WEBNN "Include WebNN support" OFF
VISIBLE_IF TRUE VISIBLE_IF TRUE
VERIFY HAVE_WEBNN) VERIFY HAVE_WEBNN)
OCV_OPTION(WITH_JASPER "Include JPEG2K support (Jasper)" ON OCV_OPTION(WITH_JASPER "Include JPEG2K support (Jasper)" ON
VISIBLE_IF NOT IOS VISIBLE_IF NOT IOS AND NOT XROS
VERIFY HAVE_JASPER) VERIFY HAVE_JASPER)
OCV_OPTION(WITH_OPENJPEG "Include JPEG2K support (OpenJPEG)" ON OCV_OPTION(WITH_OPENJPEG "Include JPEG2K support (OpenJPEG)" ON
VISIBLE_IF NOT IOS VISIBLE_IF NOT IOS AND NOT XROS
VERIFY HAVE_OPENJPEG) VERIFY HAVE_OPENJPEG)
OCV_OPTION(WITH_JPEG "Include JPEG support" ON OCV_OPTION(WITH_JPEG "Include JPEG support" ON
VISIBLE_IF TRUE VISIBLE_IF TRUE
@ -330,10 +330,10 @@ OCV_OPTION(WITH_OPENVX "Include OpenVX support" OFF
VISIBLE_IF TRUE VISIBLE_IF TRUE
VERIFY HAVE_OPENVX) VERIFY HAVE_OPENVX)
OCV_OPTION(WITH_OPENNI "Include OpenNI support" OFF OCV_OPTION(WITH_OPENNI "Include OpenNI support" OFF
VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT WINRT VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT XROS AND NOT WINRT
VERIFY HAVE_OPENNI) VERIFY HAVE_OPENNI)
OCV_OPTION(WITH_OPENNI2 "Include OpenNI2 support" OFF OCV_OPTION(WITH_OPENNI2 "Include OpenNI2 support" OFF
VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT WINRT VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT XROS AND NOT WINRT
VERIFY HAVE_OPENNI2) VERIFY HAVE_OPENNI2)
OCV_OPTION(WITH_PNG "Include PNG support" ON OCV_OPTION(WITH_PNG "Include PNG support" ON
VISIBLE_IF TRUE VISIBLE_IF TRUE
@ -345,19 +345,19 @@ OCV_OPTION(WITH_GDCM "Include DICOM support" OFF
VISIBLE_IF TRUE VISIBLE_IF TRUE
VERIFY HAVE_GDCM) VERIFY HAVE_GDCM)
OCV_OPTION(WITH_PVAPI "Include Prosilica GigE support" OFF OCV_OPTION(WITH_PVAPI "Include Prosilica GigE support" OFF
VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT WINRT VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT XROS AND NOT WINRT
VERIFY HAVE_PVAPI) VERIFY HAVE_PVAPI)
OCV_OPTION(WITH_ARAVIS "Include Aravis GigE support" OFF OCV_OPTION(WITH_ARAVIS "Include Aravis GigE support" OFF
VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT WINRT AND NOT WIN32 VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT XROS AND NOT WINRT AND NOT WIN32
VERIFY HAVE_ARAVIS_API) VERIFY HAVE_ARAVIS_API)
OCV_OPTION(WITH_QT "Build with Qt Backend support" OFF OCV_OPTION(WITH_QT "Build with Qt Backend support" OFF
VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT WINRT VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT XROS AND NOT WINRT
VERIFY HAVE_QT) VERIFY HAVE_QT)
OCV_OPTION(WITH_WIN32UI "Build with Win32 UI Backend support" ON OCV_OPTION(WITH_WIN32UI "Build with Win32 UI Backend support" ON
VISIBLE_IF WIN32 AND NOT WINRT VISIBLE_IF WIN32 AND NOT WINRT
VERIFY HAVE_WIN32UI) VERIFY HAVE_WIN32UI)
OCV_OPTION(WITH_TBB "Include Intel TBB support" OFF OCV_OPTION(WITH_TBB "Include Intel TBB support" OFF
VISIBLE_IF NOT IOS AND NOT WINRT VISIBLE_IF NOT IOS AND NOT XROS AND NOT WINRT
VERIFY HAVE_TBB) VERIFY HAVE_TBB)
OCV_OPTION(WITH_HPX "Include Ste||ar Group HPX support" OFF OCV_OPTION(WITH_HPX "Include Ste||ar Group HPX support" OFF
VISIBLE_IF TRUE VISIBLE_IF TRUE
@ -369,7 +369,7 @@ OCV_OPTION(WITH_PTHREADS_PF "Use pthreads-based parallel_for" ON
VISIBLE_IF NOT WIN32 OR MINGW VISIBLE_IF NOT WIN32 OR MINGW
VERIFY HAVE_PTHREADS_PF) VERIFY HAVE_PTHREADS_PF)
OCV_OPTION(WITH_TIFF "Include TIFF support" ON OCV_OPTION(WITH_TIFF "Include TIFF support" ON
VISIBLE_IF NOT IOS VISIBLE_IF NOT IOS AND NOT XROS
VERIFY HAVE_TIFF) VERIFY HAVE_TIFF)
OCV_OPTION(WITH_V4L "Include Video 4 Linux support" ON OCV_OPTION(WITH_V4L "Include Video 4 Linux support" ON
VISIBLE_IF UNIX AND NOT ANDROID AND NOT APPLE VISIBLE_IF UNIX AND NOT ANDROID AND NOT APPLE
@ -396,16 +396,16 @@ OCV_OPTION(WITH_CLP "Include Clp support (EPL)" OFF
VISIBLE_IF TRUE VISIBLE_IF TRUE
VERIFY HAVE_CLP) VERIFY HAVE_CLP)
OCV_OPTION(WITH_OPENCL "Include OpenCL Runtime support" (NOT ANDROID AND NOT CV_DISABLE_OPTIMIZATION) OCV_OPTION(WITH_OPENCL "Include OpenCL Runtime support" (NOT ANDROID AND NOT CV_DISABLE_OPTIMIZATION)
VISIBLE_IF NOT IOS AND NOT WINRT VISIBLE_IF NOT IOS AND NOT XROS AND NOT WINRT
VERIFY HAVE_OPENCL) VERIFY HAVE_OPENCL)
OCV_OPTION(WITH_OPENCL_SVM "Include OpenCL Shared Virtual Memory support" OFF OCV_OPTION(WITH_OPENCL_SVM "Include OpenCL Shared Virtual Memory support" OFF
VISIBLE_IF TRUE VISIBLE_IF TRUE
VERIFY HAVE_OPENCL_SVM) # experimental VERIFY HAVE_OPENCL_SVM) # experimental
OCV_OPTION(WITH_OPENCLAMDFFT "Include AMD OpenCL FFT library support" ON OCV_OPTION(WITH_OPENCLAMDFFT "Include AMD OpenCL FFT library support" ON
VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT WINRT VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT XROS AND NOT WINRT
VERIFY HAVE_CLAMDFFT) VERIFY HAVE_CLAMDFFT)
OCV_OPTION(WITH_OPENCLAMDBLAS "Include AMD OpenCL BLAS library support" ON OCV_OPTION(WITH_OPENCLAMDBLAS "Include AMD OpenCL BLAS library support" ON
VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT WINRT VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT XROS AND NOT WINRT
VERIFY HAVE_CLAMDBLAS) VERIFY HAVE_CLAMDBLAS)
OCV_OPTION(WITH_DIRECTX "Include DirectX support" ON OCV_OPTION(WITH_DIRECTX "Include DirectX support" ON
VISIBLE_IF WIN32 AND NOT WINRT VISIBLE_IF WIN32 AND NOT WINRT
@ -429,13 +429,13 @@ OCV_OPTION(WITH_MFX "Include Intel Media SDK support" OFF
VISIBLE_IF (UNIX AND NOT ANDROID) OR (WIN32 AND NOT WINRT AND NOT MINGW) VISIBLE_IF (UNIX AND NOT ANDROID) OR (WIN32 AND NOT WINRT AND NOT MINGW)
VERIFY HAVE_MFX) VERIFY HAVE_MFX)
OCV_OPTION(WITH_GDAL "Include GDAL Support" OFF OCV_OPTION(WITH_GDAL "Include GDAL Support" OFF
VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT WINRT VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT XROS AND NOT WINRT
VERIFY HAVE_GDAL) VERIFY HAVE_GDAL)
OCV_OPTION(WITH_GPHOTO2 "Include gPhoto2 library support" OFF OCV_OPTION(WITH_GPHOTO2 "Include gPhoto2 library support" OFF
VISIBLE_IF UNIX AND NOT ANDROID AND NOT IOS VISIBLE_IF UNIX AND NOT ANDROID AND NOT IOS AND NOT XROS
VERIFY HAVE_GPHOTO2) VERIFY HAVE_GPHOTO2)
OCV_OPTION(WITH_LAPACK "Include Lapack library support" (NOT CV_DISABLE_OPTIMIZATION) OCV_OPTION(WITH_LAPACK "Include Lapack library support" (NOT CV_DISABLE_OPTIMIZATION)
VISIBLE_IF NOT ANDROID AND NOT IOS VISIBLE_IF NOT ANDROID AND NOT IOS AND NOT XROS
VERIFY HAVE_LAPACK) VERIFY HAVE_LAPACK)
OCV_OPTION(WITH_ITT "Include Intel ITT support" ON OCV_OPTION(WITH_ITT "Include Intel ITT support" ON
VISIBLE_IF NOT APPLE_FRAMEWORK VISIBLE_IF NOT APPLE_FRAMEWORK
@ -516,7 +516,7 @@ OCV_OPTION(INSTALL_TESTS "Install accuracy and performance test binar
# OpenCV build options # OpenCV build options
# =================================================== # ===================================================
OCV_OPTION(ENABLE_CCACHE "Use ccache" (UNIX AND (CMAKE_GENERATOR MATCHES "Makefile" OR CMAKE_GENERATOR MATCHES "Ninja" OR CMAKE_GENERATOR MATCHES "Xcode")) ) OCV_OPTION(ENABLE_CCACHE "Use ccache" (UNIX AND (CMAKE_GENERATOR MATCHES "Makefile" OR CMAKE_GENERATOR MATCHES "Ninja" OR CMAKE_GENERATOR MATCHES "Xcode")) )
OCV_OPTION(ENABLE_PRECOMPILED_HEADERS "Use precompiled headers" MSVC IF (MSVC OR (NOT IOS AND NOT CMAKE_CROSSCOMPILING) ) ) OCV_OPTION(ENABLE_PRECOMPILED_HEADERS "Use precompiled headers" MSVC IF (MSVC OR (NOT IOS AND NOT XROS AND NOT CMAKE_CROSSCOMPILING) ) )
OCV_OPTION(ENABLE_DELAYLOAD "Enable delayed loading of OpenCV DLLs" OFF VISIBLE_IF MSVC AND BUILD_SHARED_LIBS) OCV_OPTION(ENABLE_DELAYLOAD "Enable delayed loading of OpenCV DLLs" OFF VISIBLE_IF MSVC AND BUILD_SHARED_LIBS)
OCV_OPTION(ENABLE_SOLUTION_FOLDERS "Solution folder in Visual Studio or in other IDEs" (MSVC_IDE OR CMAKE_GENERATOR MATCHES Xcode) ) OCV_OPTION(ENABLE_SOLUTION_FOLDERS "Solution folder in Visual Studio or in other IDEs" (MSVC_IDE OR CMAKE_GENERATOR MATCHES Xcode) )
OCV_OPTION(ENABLE_PROFILING "Enable profiling in the GCC compiler (Add flags: -g -pg)" OFF IF CV_GCC ) OCV_OPTION(ENABLE_PROFILING "Enable profiling in the GCC compiler (Add flags: -g -pg)" OFF IF CV_GCC )
@ -526,8 +526,8 @@ OCV_OPTION(ENABLE_OMIT_FRAME_POINTER "Enable -fomit-frame-pointer for GCC"
OCV_OPTION(ENABLE_POWERPC "Enable PowerPC for GCC" ON IF (CV_GCC AND CMAKE_SYSTEM_PROCESSOR MATCHES powerpc.*) ) OCV_OPTION(ENABLE_POWERPC "Enable PowerPC for GCC" ON IF (CV_GCC AND CMAKE_SYSTEM_PROCESSOR MATCHES powerpc.*) )
OCV_OPTION(ENABLE_FAST_MATH "Enable compiler options for fast math optimizations on FP computations (not recommended)" OFF) OCV_OPTION(ENABLE_FAST_MATH "Enable compiler options for fast math optimizations on FP computations (not recommended)" OFF)
if(NOT IOS AND (NOT ANDROID OR OPENCV_ANDROID_USE_LEGACY_FLAGS) AND CMAKE_CROSSCOMPILING) # Use CPU_BASELINE instead if(NOT IOS AND (NOT ANDROID OR OPENCV_ANDROID_USE_LEGACY_FLAGS) AND CMAKE_CROSSCOMPILING) # Use CPU_BASELINE instead
OCV_OPTION(ENABLE_NEON "Enable NEON instructions" (NEON OR ANDROID_ARM_NEON OR AARCH64) IF (CV_GCC OR CV_CLANG) AND (ARM OR AARCH64 OR IOS) ) OCV_OPTION(ENABLE_NEON "Enable NEON instructions" (NEON OR ANDROID_ARM_NEON OR AARCH64) IF (CV_GCC OR CV_CLANG) AND (ARM OR AARCH64 OR IOS OR XROS) )
OCV_OPTION(ENABLE_VFPV3 "Enable VFPv3-D32 instructions" OFF IF (CV_GCC OR CV_CLANG) AND (ARM OR AARCH64 OR IOS) ) OCV_OPTION(ENABLE_VFPV3 "Enable VFPv3-D32 instructions" OFF IF (CV_GCC OR CV_CLANG) AND (ARM OR AARCH64 OR IOS OR XROS) )
endif() endif()
OCV_OPTION(ENABLE_NOISY_WARNINGS "Show all warnings even if they are too noisy" OFF ) OCV_OPTION(ENABLE_NOISY_WARNINGS "Show all warnings even if they are too noisy" OFF )
OCV_OPTION(OPENCV_WARNINGS_ARE_ERRORS "Treat warnings as errors" OFF ) OCV_OPTION(OPENCV_WARNINGS_ARE_ERRORS "Treat warnings as errors" OFF )
@ -649,7 +649,7 @@ endif()
ocv_cmake_hook(POST_CMAKE_BUILD_OPTIONS) ocv_cmake_hook(POST_CMAKE_BUILD_OPTIONS)
# --- Python Support --- # --- Python Support ---
if(NOT IOS) if(NOT IOS AND NOT XROS)
include(cmake/OpenCVDetectPython.cmake) include(cmake/OpenCVDetectPython.cmake)
endif() endif()
@ -734,7 +734,7 @@ include(cmake/OpenCVModule.cmake)
# Detect endianness of build platform # Detect endianness of build platform
# ---------------------------------------------------------------------------- # ----------------------------------------------------------------------------
if(IOS) if(IOS OR XROS)
# test_big_endian needs try_compile, which doesn't work for iOS # test_big_endian needs try_compile, which doesn't work for iOS
# http://public.kitware.com/Bug/view.php?id=12288 # http://public.kitware.com/Bug/view.php?id=12288
set(WORDS_BIGENDIAN 0) set(WORDS_BIGENDIAN 0)
@ -1007,7 +1007,7 @@ include(cmake/OpenCVGenAndroidMK.cmake)
# Generate OpenCVConfig.cmake and OpenCVConfig-version.cmake for cmake projects # Generate OpenCVConfig.cmake and OpenCVConfig-version.cmake for cmake projects
include(cmake/OpenCVGenConfig.cmake) include(cmake/OpenCVGenConfig.cmake)
# Generate Info.plist for the IOS framework # Generate Info.plist for the iOS/visionOS framework
if(APPLE_FRAMEWORK) if(APPLE_FRAMEWORK)
include(cmake/OpenCVGenInfoPlist.cmake) include(cmake/OpenCVGenInfoPlist.cmake)
endif() endif()

View File

@ -175,7 +175,7 @@ if(NOT ${found})
endif() endif()
endif() endif()
if(NOT ANDROID AND NOT IOS) if(NOT ANDROID AND NOT IOS AND NOT XROS)
if(CMAKE_HOST_UNIX) if(CMAKE_HOST_UNIX)
execute_process(COMMAND ${_executable} -c "from sysconfig import *; print(get_path('purelib'))" execute_process(COMMAND ${_executable} -c "from sysconfig import *; print(get_path('purelib'))"
RESULT_VARIABLE _cvpy_process RESULT_VARIABLE _cvpy_process
@ -240,7 +240,7 @@ if(NOT ${found})
OUTPUT_STRIP_TRAILING_WHITESPACE) OUTPUT_STRIP_TRAILING_WHITESPACE)
endif() endif()
endif() endif()
endif(NOT ANDROID AND NOT IOS) endif(NOT ANDROID AND NOT IOS AND NOT XROS)
endif() endif()
# Export return values # Export return values

View File

@ -77,7 +77,7 @@ endif(WITH_OPENGL)
# --- Cocoa --- # --- Cocoa ---
if(APPLE) if(APPLE)
if(NOT IOS AND CV_CLANG) if(NOT IOS AND NOT XROS AND CV_CLANG)
set(HAVE_COCOA YES) set(HAVE_COCOA YES)
endif() endif()
endif() endif()

View File

@ -13,6 +13,14 @@ if(IOS)
configure_file("${OpenCV_SOURCE_DIR}/platforms/ios/Info.plist.in" configure_file("${OpenCV_SOURCE_DIR}/platforms/ios/Info.plist.in"
"${CMAKE_BINARY_DIR}/ios/Info.plist") "${CMAKE_BINARY_DIR}/ios/Info.plist")
endif() endif()
elseif(XROS)
if(APPLE_FRAMEWORK AND DYNAMIC_PLIST)
configure_file("${OpenCV_SOURCE_DIR}/platforms/ios/Info.Dynamic.plist.in"
"${CMAKE_BINARY_DIR}/visionos/Info.plist")
else()
configure_file("${OpenCV_SOURCE_DIR}/platforms/ios/Info.plist.in"
"${CMAKE_BINARY_DIR}/visionos/Info.plist")
endif()
elseif(APPLE) elseif(APPLE)
configure_file("${OpenCV_SOURCE_DIR}/platforms/osx/Info.plist.in" configure_file("${OpenCV_SOURCE_DIR}/platforms/osx/Info.plist.in"
"${CMAKE_BINARY_DIR}/osx/Info.plist") "${CMAKE_BINARY_DIR}/osx/Info.plist")

View File

@ -1,4 +1,4 @@
if(MSVC OR IOS) if(MSVC OR IOS OR XROS)
return() return()
endif() endif()

View File

@ -1564,7 +1564,7 @@ function(ocv_add_library target)
set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG 1) set(CMAKE_SHARED_LIBRARY_RUNTIME_C_FLAG 1)
if(IOS AND NOT MAC_CATALYST) if((IOS OR XROS) AND NOT MAC_CATALYST)
set(OPENCV_APPLE_INFO_PLIST "${CMAKE_BINARY_DIR}/ios/Info.plist") set(OPENCV_APPLE_INFO_PLIST "${CMAKE_BINARY_DIR}/ios/Info.plist")
else() else()
set(OPENCV_APPLE_INFO_PLIST "${CMAKE_BINARY_DIR}/osx/Info.plist") set(OPENCV_APPLE_INFO_PLIST "${CMAKE_BINARY_DIR}/osx/Info.plist")

View File

@ -20,7 +20,7 @@ ocv_add_dispatched_file_force_all(test_intrin512 TEST AVX512_SKX)
set(PARALLEL_ENABLE_PLUGINS_DEFAULT ON) set(PARALLEL_ENABLE_PLUGINS_DEFAULT ON)
if(EMSCRIPTEN OR IOS OR WINRT) if(EMSCRIPTEN OR IOS OR XROS OR WINRT)
set(PARALLEL_ENABLE_PLUGINS_DEFAULT OFF) set(PARALLEL_ENABLE_PLUGINS_DEFAULT OFF)
endif() endif()
# parallel backends configuration # parallel backends configuration

View File

@ -137,11 +137,11 @@ if(APPLE OR APPLE_FRAMEWORK)
list(APPEND imgcodecs_srcs ${CMAKE_CURRENT_LIST_DIR}/src/apple_conversions.h) list(APPEND imgcodecs_srcs ${CMAKE_CURRENT_LIST_DIR}/src/apple_conversions.h)
list(APPEND imgcodecs_srcs ${CMAKE_CURRENT_LIST_DIR}/src/apple_conversions.mm) list(APPEND imgcodecs_srcs ${CMAKE_CURRENT_LIST_DIR}/src/apple_conversions.mm)
endif() endif()
if(IOS) if(IOS OR XROS)
list(APPEND imgcodecs_srcs ${CMAKE_CURRENT_LIST_DIR}/src/ios_conversions.mm) list(APPEND imgcodecs_srcs ${CMAKE_CURRENT_LIST_DIR}/src/ios_conversions.mm)
list(APPEND IMGCODECS_LIBRARIES "-framework UIKit") list(APPEND IMGCODECS_LIBRARIES "-framework UIKit")
endif() endif()
if(APPLE AND (NOT IOS)) if(APPLE AND (NOT IOS) AND (NOT XROS))
list(APPEND imgcodecs_srcs ${CMAKE_CURRENT_LIST_DIR}/src/macosx_conversions.mm) list(APPEND imgcodecs_srcs ${CMAKE_CURRENT_LIST_DIR}/src/macosx_conversions.mm)
list(APPEND IMGCODECS_LIBRARIES "-framework AppKit") list(APPEND IMGCODECS_LIBRARIES "-framework AppKit")
endif() endif()

View File

@ -0,0 +1,5 @@
{
"SourceMap" : {
"visionos" : "ios"
}
}

View File

@ -9,6 +9,8 @@ file(REMOVE_RECURSE "${OPENCV_OBJC_BINDINGS_DIR}/osx")
file(REMOVE "${OPENCV_DEPHELPER}/gen_opencv_objc_source_osx") # force re-run after CMake file(REMOVE "${OPENCV_DEPHELPER}/gen_opencv_objc_source_osx") # force re-run after CMake
file(REMOVE_RECURSE "${OPENCV_OBJC_BINDINGS_DIR}/ios") file(REMOVE_RECURSE "${OPENCV_OBJC_BINDINGS_DIR}/ios")
file(REMOVE "${OPENCV_DEPHELPER}/gen_opencv_objc_source_ios") # force re-run after CMake file(REMOVE "${OPENCV_DEPHELPER}/gen_opencv_objc_source_ios") # force re-run after CMake
file(REMOVE_RECURSE "${OPENCV_OBJC_BINDINGS_DIR}/visionos")
file(REMOVE "${OPENCV_DEPHELPER}/gen_opencv_objc_source_visionos") # force re-run after CMake
# This file is included from a subdirectory # This file is included from a subdirectory
set(OBJC_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..") set(OBJC_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/..")
@ -67,6 +69,8 @@ string(REPLACE "opencv_" "" MODULES "${OPENCV_OBJC_MODULES}")
if(NOT DEFINED OPENCV_OBJC_TARGET AND APPLE_FRAMEWORK) if(NOT DEFINED OPENCV_OBJC_TARGET AND APPLE_FRAMEWORK)
if(IOS) if(IOS)
set(OPENCV_OBJC_TARGET "ios") set(OPENCV_OBJC_TARGET "ios")
elseif(XROS)
set(OPENCV_OBJC_TARGET "visionos")
else() else()
set(OPENCV_OBJC_TARGET "osx") set(OPENCV_OBJC_TARGET "osx")
endif() endif()
@ -117,6 +121,7 @@ if(OPENCV_OBJC_TARGET)
else() else()
ocv_add_objc_generated_target(osx) ocv_add_objc_generated_target(osx)
ocv_add_objc_generated_target(ios) ocv_add_objc_generated_target(ios)
ocv_add_objc_generated_target(visionos)
endif() endif()
add_custom_target(gen_opencv_objc_source add_custom_target(gen_opencv_objc_source

View File

@ -1600,7 +1600,7 @@ if __name__ == "__main__":
arg_parser = argparse.ArgumentParser(description='OpenCV Objective-C Wrapper Generator') arg_parser = argparse.ArgumentParser(description='OpenCV Objective-C Wrapper Generator')
arg_parser.add_argument('-p', '--parser', required=True, help='OpenCV header parser') arg_parser.add_argument('-p', '--parser', required=True, help='OpenCV header parser')
arg_parser.add_argument('-c', '--config', required=True, help='OpenCV modules config') arg_parser.add_argument('-c', '--config', required=True, help='OpenCV modules config')
arg_parser.add_argument('-t', '--target', required=True, help='Target (either ios or osx)') arg_parser.add_argument('-t', '--target', required=True, help='Target (either ios or osx or visionos)')
arg_parser.add_argument('-f', '--framework', required=True, help='Framework name') arg_parser.add_argument('-f', '--framework', required=True, help='Framework name')
args=arg_parser.parse_args() args=arg_parser.parse_args()
@ -1671,6 +1671,7 @@ if __name__ == "__main__":
logging.info("\nCommon headers (%d):\n%s", len(common_headers), pformat(common_headers)) logging.info("\nCommon headers (%d):\n%s", len(common_headers), pformat(common_headers))
gendict_fname = os.path.join(misc_location, 'gen_dict.json') gendict_fname = os.path.join(misc_location, 'gen_dict.json')
module_source_map = {}
if os.path.exists(gendict_fname): if os.path.exists(gendict_fname):
with open(gendict_fname) as f: with open(gendict_fname) as f:
gen_type_dict = json.load(f) gen_type_dict = json.load(f)
@ -1687,6 +1688,7 @@ if __name__ == "__main__":
header_fix.update(gen_type_dict.get("header_fix", {})) header_fix.update(gen_type_dict.get("header_fix", {}))
enum_fix.update(gen_type_dict.get("enum_fix", {})) enum_fix.update(gen_type_dict.get("enum_fix", {}))
const_fix.update(gen_type_dict.get("const_fix", {})) const_fix.update(gen_type_dict.get("const_fix", {}))
module_source_map = gen_type_dict.get("SourceMap", {})
namespaces_dict.update(gen_type_dict.get("namespaces_dict", {})) namespaces_dict.update(gen_type_dict.get("namespaces_dict", {}))
module_imports += gen_type_dict.get("module_imports", []) module_imports += gen_type_dict.get("module_imports", [])
@ -1695,15 +1697,10 @@ if __name__ == "__main__":
if os.path.exists(objc_files_dir): if os.path.exists(objc_files_dir):
copied_files += copy_objc_files(objc_files_dir, objc_base_path, module, True) copied_files += copy_objc_files(objc_files_dir, objc_base_path, module, True)
if args.target == 'ios': target_path = 'macosx' if args.target == 'osx' else module_source_map.get(args.target, args.target)
ios_files_dir = os.path.join(misc_location, 'ios') target_files_dir = os.path.join(misc_location, target_path)
if os.path.exists(ios_files_dir): if os.path.exists(target_files_dir):
copied_files += copy_objc_files(ios_files_dir, objc_base_path, module, True) copied_files += copy_objc_files(target_files_dir, objc_base_path, module, True)
if args.target == 'osx':
osx_files_dir = os.path.join(misc_location, 'macosx')
if os.path.exists(osx_files_dir):
copied_files += copy_objc_files(osx_files_dir, objc_base_path, module, True)
objc_test_files_dir = os.path.join(misc_location, 'test') objc_test_files_dir = os.path.join(misc_location, 'test')
if os.path.exists(objc_test_files_dir): if os.path.exists(objc_test_files_dir):

View File

@ -1,5 +1,5 @@
set(VIDEOIO_ENABLE_PLUGINS_DEFAULT ON) set(VIDEOIO_ENABLE_PLUGINS_DEFAULT ON)
if(EMSCRIPTEN OR IOS OR WINRT) if(EMSCRIPTEN OR IOS OR XROS OR WINRT)
set(VIDEOIO_ENABLE_PLUGINS_DEFAULT OFF) set(VIDEOIO_ENABLE_PLUGINS_DEFAULT OFF)
endif() endif()
@ -197,7 +197,7 @@ if(TARGET ocv.3rdparty.aravis)
endif() endif()
if(TARGET ocv.3rdparty.avfoundation) if(TARGET ocv.3rdparty.avfoundation)
if(IOS) if(IOS OR XROS)
list(APPEND videoio_srcs ${CMAKE_CURRENT_LIST_DIR}/src/cap_avfoundation.mm) list(APPEND videoio_srcs ${CMAKE_CURRENT_LIST_DIR}/src/cap_avfoundation.mm)
else() else()
list(APPEND videoio_srcs ${CMAKE_CURRENT_LIST_DIR}/src/cap_avfoundation_mac.mm) list(APPEND videoio_srcs ${CMAKE_CURRENT_LIST_DIR}/src/cap_avfoundation_mac.mm)

View File

@ -61,6 +61,8 @@
#define DISABLE_AUTO_RESTART 999 #define DISABLE_AUTO_RESTART 999
#if !TARGET_OS_VISION
@interface CaptureDelegate : NSObject <AVCaptureVideoDataOutputSampleBufferDelegate> @interface CaptureDelegate : NSObject <AVCaptureVideoDataOutputSampleBufferDelegate>
{ {
int newFrame; int newFrame;
@ -125,6 +127,7 @@ class CvCaptureCAM : public CvCapture {
int disableAutoRestart; int disableAutoRestart;
}; };
#endif
/***************************************************************************** /*****************************************************************************
* *
@ -160,6 +163,7 @@ private:
uint32_t mMode; uint32_t mMode;
int mFormat; int mFormat;
void handleTracks(NSArray<AVAssetTrack *>* tracks, const char* filename);
bool setupReadingAt(CMTime position); bool setupReadingAt(CMTime position);
IplImage* retrieveFramePixelBuffer(); IplImage* retrieveFramePixelBuffer();
int getPreferredOrientationDegrees() const; int getPreferredOrientationDegrees() const;
@ -217,6 +221,8 @@ cv::Ptr<cv::IVideoCapture> cv::create_AVFoundation_capture_file(const std::strin
} }
#if !TARGET_OS_VISION
cv::Ptr<cv::IVideoCapture> cv::create_AVFoundation_capture_cam(int index) cv::Ptr<cv::IVideoCapture> cv::create_AVFoundation_capture_cam(int index)
{ {
CvCaptureCAM* retval = new CvCaptureCAM(index); CvCaptureCAM* retval = new CvCaptureCAM(index);
@ -226,6 +232,8 @@ cv::Ptr<cv::IVideoCapture> cv::create_AVFoundation_capture_cam(int index)
return 0; return 0;
} }
#endif
cv::Ptr<cv::IVideoWriter> cv::create_AVFoundation_writer(const std::string& filename, int fourcc, cv::Ptr<cv::IVideoWriter> cv::create_AVFoundation_writer(const std::string& filename, int fourcc,
double fps, const cv::Size &frameSize, double fps, const cv::Size &frameSize,
const cv::VideoWriterParameters& params) const cv::VideoWriterParameters& params)
@ -245,6 +253,8 @@ cv::Ptr<cv::IVideoWriter> cv::create_AVFoundation_writer(const std::string& file
* *
*****************************************************************************/ *****************************************************************************/
#if !TARGET_OS_VISION
CvCaptureCAM::CvCaptureCAM(int cameraNum) { CvCaptureCAM::CvCaptureCAM(int cameraNum) {
mCaptureSession = nil; mCaptureSession = nil;
mCaptureDeviceInput = nil; mCaptureDeviceInput = nil;
@ -773,6 +783,7 @@ fromConnection:(AVCaptureConnection *)connection{
@end @end
#endif
/***************************************************************************** /*****************************************************************************
* *
@ -811,24 +822,26 @@ CvCaptureFile::CvCaptureFile(const char* filename) {
return; return;
} }
// Available since iOS 15
#if TARGET_OS_VISION || (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 150000)
if (@available(iOS 15, visionOS 1, *)) {
[mAsset loadTracksWithMediaType:AVMediaTypeVideo completionHandler:^(NSArray<AVAssetTrack *>* tracks, NSError* err) {
if (err != nil) {
handleTracks(tracks, filename);
}
[localpool drain];
}];
return;
} else {
#if !TARGET_OS_VISION
NSArray *tracks = [mAsset tracksWithMediaType:AVMediaTypeVideo];
handleTracks(tracks, filename);
#endif
}
#else
NSArray *tracks = [mAsset tracksWithMediaType:AVMediaTypeVideo]; NSArray *tracks = [mAsset tracksWithMediaType:AVMediaTypeVideo];
if ([tracks count] == 0) { handleTracks(tracks, filename);
fprintf(stderr, "OpenCV: Couldn't read video stream from file \"%s\"\n", filename); #endif
[localpool drain];
started = 0;
return;
}
mAssetTrack = [tracks[0] retain];
if ( ! setupReadingAt(kCMTimeZero) ) {
fprintf(stderr, "OpenCV: Couldn't read movie file \"%s\"\n", filename);
[localpool drain];
started = 0;
return;
}
started = 1;
[localpool drain]; [localpool drain];
} }
@ -850,6 +863,24 @@ CvCaptureFile::~CvCaptureFile() {
[localpool drain]; [localpool drain];
} }
void CvCaptureFile::handleTracks(NSArray<AVAssetTrack *>* tracks, const char* filename) {
if ([tracks count] == 0) {
fprintf(stderr, "OpenCV: Couldn't read video stream from file \"%s\"\n", filename);
started = 0;
return;
}
mAssetTrack = [tracks[0] retain];
if ( ! setupReadingAt(kCMTimeZero) ) {
fprintf(stderr, "OpenCV: Couldn't read movie file \"%s\"\n", filename);
started = 0;
return;
}
started = 1;
}
bool CvCaptureFile::setupReadingAt(CMTime position) { bool CvCaptureFile::setupReadingAt(CMTime position) {
if (mAssetReader) { if (mAssetReader) {
if (mAssetReader.status == AVAssetReaderStatusReading) { if (mAssetReader.status == AVAssetReaderStatusReading) {
@ -1269,25 +1300,25 @@ CvVideoWriter_AVFoundation::CvVideoWriter_AVFoundation(const char* filename, int
//exception; //exception;
} }
// Three codec supported AVVideoCodecH264 AVVideoCodecJPEG AVVideoCodecTypeHEVC // Three codec supported AVVideoCodecTypeH264 AVVideoCodecTypeJPEG AVVideoCodecTypeHEVC
// On iPhone 3G H264 is not supported. // On iPhone 3G H264 is not supported.
if (fourcc == CV_FOURCC('J','P','E','G') || fourcc == CV_FOURCC('j','p','e','g') || if (fourcc == CV_FOURCC('J','P','E','G') || fourcc == CV_FOURCC('j','p','e','g') ||
fourcc == CV_FOURCC('M','J','P','G') || fourcc == CV_FOURCC('m','j','p','g')){ fourcc == CV_FOURCC('M','J','P','G') || fourcc == CV_FOURCC('m','j','p','g')){
codec = [AVVideoCodecJPEG copy]; // Use JPEG codec if specified, otherwise H264 codec = [AVVideoCodecTypeJPEG copy]; // Use JPEG codec if specified, otherwise H264
}else if(fourcc == CV_FOURCC('H','2','6','4') || fourcc == CV_FOURCC('a','v','c','1')){ }else if(fourcc == CV_FOURCC('H','2','6','4') || fourcc == CV_FOURCC('a','v','c','1')){
codec = [AVVideoCodecH264 copy]; codec = [AVVideoCodecTypeH264 copy];
// Available since iOS 11 // Available since iOS 11
#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000 #if TARGET_OS_VISION || (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 110000)
}else if(fourcc == CV_FOURCC('H','2','6','5') || fourcc == CV_FOURCC('h','v','c','1') || }else if(fourcc == CV_FOURCC('H','2','6','5') || fourcc == CV_FOURCC('h','v','c','1') ||
fourcc == CV_FOURCC('H','E','V','C') || fourcc == CV_FOURCC('h','e','v','c')){ fourcc == CV_FOURCC('H','E','V','C') || fourcc == CV_FOURCC('h','e','v','c')){
if (@available(iOS 11, *)) { if (@available(iOS 11, visionOS 1, *)) {
codec = [AVVideoCodecTypeHEVC copy]; codec = [AVVideoCodecTypeHEVC copy];
} else { } else {
codec = [AVVideoCodecH264 copy]; codec = [AVVideoCodecTypeH264 copy];
} }
#endif #endif
}else{ }else{
codec = [AVVideoCodecH264 copy]; // default canonical H264. codec = [AVVideoCodecTypeH264 copy]; // default canonical H264.
} }
//NSLog(@"Path: %@", path); //NSLog(@"Path: %@", path);
@ -1349,17 +1380,17 @@ CvVideoWriter_AVFoundation::~CvVideoWriter_AVFoundation() {
NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init];
[mMovieWriterInput markAsFinished]; [mMovieWriterInput markAsFinished];
[mMovieWriter finishWriting]; [mMovieWriter finishWritingWithCompletionHandler:^() {
[mMovieWriter release]; [mMovieWriter release];
[mMovieWriterInput release]; [mMovieWriterInput release];
[mMovieWriterAdaptor release]; [mMovieWriterAdaptor release];
[path release]; [path release];
[codec release]; [codec release];
[fileType release]; [fileType release];
cvReleaseImage(&argbimage); cvReleaseImage(&argbimage);
[localpool drain];
[localpool drain];
}];
} }
bool CvVideoWriter_AVFoundation::writeFrame(const IplImage* iplimage) { bool CvVideoWriter_AVFoundation::writeFrame(const IplImage* iplimage) {

View File

@ -31,6 +31,8 @@ if __name__ == "__main__":
parser.add_argument('--framework_name', default='opencv2', help='Name of OpenCV xcframework (default: opencv2, will change to OpenCV in future version)') parser.add_argument('--framework_name', default='opencv2', help='Name of OpenCV xcframework (default: opencv2, will change to OpenCV in future version)')
parser.add_argument('--iphoneos_archs', default=None, help='select iPhoneOS target ARCHS. Default is "armv7,arm64"') parser.add_argument('--iphoneos_archs', default=None, help='select iPhoneOS target ARCHS. Default is "armv7,arm64"')
parser.add_argument('--iphonesimulator_archs', default=None, help='select iPhoneSimulator target ARCHS. Default is "x86_64,arm64"') parser.add_argument('--iphonesimulator_archs', default=None, help='select iPhoneSimulator target ARCHS. Default is "x86_64,arm64"')
parser.add_argument('--visionos_archs', default=None, help='select visionOS target ARCHS. Default is "arm64"')
parser.add_argument('--visionsimulator_archs', default=None, help='select visionSimulator target ARCHS. Default is "arm64"')
parser.add_argument('--macos_archs', default=None, help='Select MacOS ARCHS. Default is "x86_64,arm64"') parser.add_argument('--macos_archs', default=None, help='Select MacOS ARCHS. Default is "x86_64,arm64"')
parser.add_argument('--catalyst_archs', default=None, help='Select Catalyst ARCHS. Default is "x86_64,arm64"') parser.add_argument('--catalyst_archs', default=None, help='Select Catalyst ARCHS. Default is "x86_64,arm64"')
parser.add_argument('--build_only_specified_archs', default=False, action='store_true', help='if enabled, only directly specified archs are built and defaults are ignored') parser.add_argument('--build_only_specified_archs', default=False, action='store_true', help='if enabled, only directly specified archs are built and defaults are ignored')
@ -52,6 +54,13 @@ if __name__ == "__main__":
iphonesimulator_archs = "x86_64,arm64" iphonesimulator_archs = "x86_64,arm64"
print('Using iPhoneSimulator ARCHS={}'.format(iphonesimulator_archs)) print('Using iPhoneSimulator ARCHS={}'.format(iphonesimulator_archs))
# Parse architectures from args
visionos_archs = args.visionos_archs
print('Using visionOS ARCHS={}'.format(visionos_archs))
visionsimulator_archs = args.visionsimulator_archs
print('Using visionSimulator ARCHS={}'.format(visionsimulator_archs))
macos_archs = args.macos_archs macos_archs = args.macos_archs
if not macos_archs and not args.build_only_specified_archs: if not macos_archs and not args.build_only_specified_archs:
# Supply defaults # Supply defaults
@ -70,6 +79,7 @@ if __name__ == "__main__":
# Phase 1: build .frameworks for each platform # Phase 1: build .frameworks for each platform
osx_script_path = os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../osx/build_framework.py') osx_script_path = os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../osx/build_framework.py')
ios_script_path = os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../ios/build_framework.py') ios_script_path = os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../ios/build_framework.py')
visionos_script_path = os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../ios/build_visionos_framework.py')
build_folders = [] build_folders = []
@ -91,6 +101,19 @@ if __name__ == "__main__":
command = ["python3", ios_script_path, build_folder, "--iphonesimulator_archs", iphonesimulator_archs, "--framework_name", args.framework_name, "--build_only_specified_archs"] + unknown_args command = ["python3", ios_script_path, build_folder, "--iphonesimulator_archs", iphonesimulator_archs, "--framework_name", args.framework_name, "--build_only_specified_archs"] + unknown_args
print_header("Building iPhoneSimulator frameworks") print_header("Building iPhoneSimulator frameworks")
execute(command, cwd=os.getcwd()) execute(command, cwd=os.getcwd())
if visionos_archs:
build_folder = get_or_create_build_folder(args.out, "visionos")
build_folders.append(build_folder)
command = ["python3", visionos_script_path, build_folder, "--visionos_archs", visionos_archs, "--framework_name", args.framework_name, "--build_only_specified_archs"] + unknown_args
print_header("Building visionOS frameworks")
print(command)
execute(command, cwd=os.getcwd())
if visionsimulator_archs:
build_folder = get_or_create_build_folder(args.out, "visionsimulator")
build_folders.append(build_folder)
command = ["python3", visionos_script_path, build_folder, "--visionsimulator_archs", visionsimulator_archs, "--framework_name", args.framework_name, "--build_only_specified_archs"] + unknown_args
print_header("Building visionSimulator frameworks")
execute(command, cwd=os.getcwd())
if macos_archs: if macos_archs:
build_folder = get_or_create_build_folder(args.out, "macos") build_folder = get_or_create_build_folder(args.out, "macos")
build_folders.append(build_folder) build_folders.append(build_folder)

View File

@ -254,9 +254,9 @@ class Builder:
toolchain = self.getToolchain(arch, target) toolchain = self.getToolchain(arch, target)
cmakecmd = self.getCMakeArgs(arch, target) + \ cmakecmd = self.getCMakeArgs(arch, target) + \
(["-DCMAKE_TOOLCHAIN_FILE=%s" % toolchain] if toolchain is not None else []) (["-DCMAKE_TOOLCHAIN_FILE=%s" % toolchain] if toolchain is not None else [])
if target.lower().startswith("iphoneos"): if target.lower().startswith("iphoneos") or target.lower().startswith("xros"):
cmakecmd.append("-DCPU_BASELINE=DETECT") cmakecmd.append("-DCPU_BASELINE=DETECT")
if target.lower().startswith("iphonesimulator"): if target.lower().startswith("iphonesimulator") or target.lower().startswith("xrsimulator"):
build_arch = check_output(["uname", "-m"]).decode('utf-8').rstrip() build_arch = check_output(["uname", "-m"]).decode('utf-8').rstrip()
if build_arch != arch: if build_arch != arch:
print("build_arch (%s) != arch (%s)" % (build_arch, arch)) print("build_arch (%s) != arch (%s)" % (build_arch, arch))
@ -341,7 +341,7 @@ class Builder:
def makeDynamicLib(self, builddir): def makeDynamicLib(self, builddir):
target = builddir[(builddir.rfind("build-") + 6):] target = builddir[(builddir.rfind("build-") + 6):]
target_platform = target[(target.rfind("-") + 1):] target_platform = target[(target.rfind("-") + 1):]
is_device = target_platform == "iphoneos" or target_platform == "catalyst" is_device = target_platform == "iphoneos" or target_platform == "visionos" or target_platform == "catalyst"
framework_dir = os.path.join(builddir, "install", "lib", self.framework_name + ".framework") framework_dir = os.path.join(builddir, "install", "lib", self.framework_name + ".framework")
if not os.path.exists(framework_dir): if not os.path.exists(framework_dir):
os.makedirs(framework_dir) os.makedirs(framework_dir)
@ -379,7 +379,7 @@ class Builder:
"-framework", "CoreImage", "-framework", "CoreMedia", "-framework", "QuartzCore", "-framework", "CoreImage", "-framework", "CoreMedia", "-framework", "QuartzCore",
"-framework", "Accelerate", "-framework", "OpenCL", "-framework", "Accelerate", "-framework", "OpenCL",
] ]
elif target_platform == "iphoneos" or target_platform == "iphonesimulator": elif target_platform == "iphoneos" or target_platform == "iphonesimulator" or target_platform == "xros" or target_platform == "xrsimulator":
framework_options = [ framework_options = [
"-iframework", "%s/System/iOSSupport/System/Library/Frameworks" % sdk_dir, "-iframework", "%s/System/iOSSupport/System/Library/Frameworks" % sdk_dir,
"-framework", "AVFoundation", "-framework", "CoreGraphics", "-framework", "AVFoundation", "-framework", "CoreGraphics",

View File

@ -0,0 +1,116 @@
#!/usr/bin/env python
"""
The script builds OpenCV.framework for visionOS.
"""
from __future__ import print_function
import os, os.path, sys, argparse, traceback, multiprocessing
# import common code
# sys.path.insert(0, os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../ios'))
from build_framework import Builder
sys.path.insert(0, os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../apple'))
from cv_build_utils import print_error, get_cmake_version
XROS_DEPLOYMENT_TARGET='1.0' # default, can be changed via command line options or environment variable
class visionOSBuilder(Builder):
def checkCMakeVersion(self):
assert get_cmake_version() >= (3, 17), "CMake 3.17 or later is required. Current version is {}".format(get_cmake_version())
def getObjcTarget(self, target):
return 'visionos'
def getToolchain(self, arch, target):
toolchain = os.path.join(self.opencv, "platforms", "ios", "cmake", "Toolchains", "Toolchain-%s_Xcode.cmake" % target)
return toolchain
def getCMakeArgs(self, arch, target):
args = Builder.getCMakeArgs(self, arch, target)
args = args + [
'-DVISIONOS_ARCH=%s' % arch
]
return args
def getBuildCommand(self, arch, target):
buildcmd = [
"xcodebuild",
"XROS_DEPLOYMENT_TARGET=" + os.environ['XROS_DEPLOYMENT_TARGET'],
"ARCHS=%s" % arch,
"-sdk", target.lower(),
"-configuration", "Debug" if self.debug else "Release",
"-parallelizeTargets",
"-jobs", str(multiprocessing.cpu_count())
]
return buildcmd
def getInfoPlist(self, builddirs):
return os.path.join(builddirs[0], "visionos", "Info.plist")
if __name__ == "__main__":
folder = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "../.."))
parser = argparse.ArgumentParser(description='The script builds OpenCV.framework for visionOS.')
# TODO: When we can make breaking changes, we should make the out argument explicit and required like in build_xcframework.py.
parser.add_argument('out', metavar='OUTDIR', help='folder to put built framework')
parser.add_argument('--opencv', metavar='DIR', default=folder, help='folder with opencv repository (default is "../.." relative to script location)')
parser.add_argument('--contrib', metavar='DIR', default=None, help='folder with opencv_contrib repository (default is "None" - build only main framework)')
parser.add_argument('--without', metavar='MODULE', default=[], action='append', help='OpenCV modules to exclude from the framework. To exclude multiple, specify this flag again, e.g. "--without video --without objc"')
parser.add_argument('--disable', metavar='FEATURE', default=[], action='append', help='OpenCV features to disable (add WITH_*=OFF). To disable multiple, specify this flag again, e.g. "--disable tbb --disable openmp"')
parser.add_argument('--dynamic', default=False, action='store_true', help='build dynamic framework (default is "False" - builds static framework)')
parser.add_argument('--enable_nonfree', default=False, dest='enablenonfree', action='store_true', help='enable non-free modules (disabled by default)')
parser.add_argument('--visionos_deployment_target', default=os.environ.get('XROS_DEPLOYMENT_TARGET', XROS_DEPLOYMENT_TARGET), help='specify XROS_DEPLOYMENT_TARGET')
parser.add_argument('--visionos_archs', default=None, help='select visionOS target ARCHS. Default is none')
parser.add_argument('--visionsimulator_archs', default=None, help='select visionSimulator target ARCHS. Default is none')
parser.add_argument('--debug', action='store_true', help='Build "Debug" binaries (CMAKE_BUILD_TYPE=Debug)')
parser.add_argument('--debug_info', action='store_true', help='Build with debug information (useful for Release mode: BUILD_WITH_DEBUG_INFO=ON)')
parser.add_argument('--framework_name', default='opencv2', dest='framework_name', help='Name of OpenCV framework (default: opencv2, will change to OpenCV in future version)')
parser.add_argument('--legacy_build', default=False, dest='legacy_build', action='store_true', help='Build legacy framework (default: False, equivalent to "--framework_name=opencv2 --without=objc")')
parser.add_argument('--run_tests', default=False, dest='run_tests', action='store_true', help='Run tests')
parser.add_argument('--build_docs', default=False, dest='build_docs', action='store_true', help='Build docs')
parser.add_argument('--disable-swift', default=False, dest='swiftdisabled', action='store_true', help='Disable building of Swift extensions')
args, unknown_args = parser.parse_known_args()
if unknown_args:
print("The following args are not recognized and will not be used: %s" % unknown_args)
os.environ['XROS_DEPLOYMENT_TARGET'] = args.visionos_deployment_target
print('Using XROS_DEPLOYMENT_TARGET=' + os.environ['XROS_DEPLOYMENT_TARGET'])
visionos_archs = None
if args.visionos_archs:
visionos_archs = args.visionos_archs.split(',')
print('Using visionOS ARCHS=' + str(visionos_archs))
visionsimulator_archs = None
if args.visionsimulator_archs:
visionsimulator_archs = args.visionsimulator_archs.split(',')
print('Using visionOS ARCHS=' + str(visionsimulator_archs))
# Prevent the build from happening if the same architecture is specified for multiple platforms.
# When `lipo` is run to stitch the frameworks together into a fat framework, it'll fail, so it's
# better to stop here while we're ahead.
if visionos_archs and visionsimulator_archs:
duplicate_archs = set(visionos_archs).intersection(visionsimulator_archs)
if duplicate_archs:
print_error("Cannot have the same architecture for multiple platforms in a fat framework! Consider using build_xcframework.py in the apple platform folder instead. Duplicate archs are %s" % duplicate_archs)
exit(1)
if args.legacy_build:
args.framework_name = "opencv2"
if not "objc" in args.without:
args.without.append("objc")
targets = []
if not visionos_archs and not visionsimulator_archs:
print_error("--visionos_archs and --visionsimulator_archs are undefined; nothing will be built.")
sys.exit(1)
if visionos_archs:
targets.append((visionos_archs, "XROS"))
if visionsimulator_archs:
targets.append((visionsimulator_archs, "XRSimulator")),
b = visionOSBuilder(args.opencv, args.contrib, args.dynamic, True, args.without, args.disable, args.enablenonfree, targets, args.debug, args.debug_info, args.framework_name, args.run_tests, args.build_docs, args.swiftdisabled)
b.build(args.out)

View File

@ -0,0 +1,5 @@
message(STATUS "Setting up visionOS toolchain for VISIONOS_ARCH='${VISIONOS_ARCH}'")
set(VISIONOS TRUE)
set(XROS 1)
include(${CMAKE_CURRENT_LIST_DIR}/common-ios-toolchain.cmake)
message(STATUS "visionOS toolchain loaded")

View File

@ -0,0 +1,5 @@
message(STATUS "Setting up visionSimulator toolchain for VISIONOS_ARCH='${VISIONOS_ARCH}'")
set(VISIONSIMULATOR TRUE)
set(XROS 1)
include(${CMAKE_CURRENT_LIST_DIR}/common-ios-toolchain.cmake)
message(STATUS "visionSimulator toolchain loaded")

View File

@ -61,26 +61,45 @@ else()
endmacro() endmacro()
endif() # IN_TRY_COMPILE endif() # IN_TRY_COMPILE
if(NOT DEFINED IOS_ARCH) if((IPHONEOS OR IPHONESIMULATOR) AND NOT DEFINED IOS_ARCH)
message(FATAL_ERROR "iOS toolchain requires ARCH option for proper configuration of compiler flags") message(FATAL_ERROR "iOS toolchain requires ARCH option for proper configuration of compiler flags")
endif() endif()
if(IOS_ARCH MATCHES "^arm64") if((VISIONOS OR VISIONSIMULATOR) AND NOT DEFINED VISIONOS_ARCH)
message(FATAL_ERROR "visionOS toolchain requires ARCH option for proper configuration of compiler flags")
endif()
if((IOS_ARCH MATCHES "^arm64") OR (VISIONOS_ARCH MATCHES "^arm64"))
set(AARCH64 1) set(AARCH64 1)
elseif(IOS_ARCH MATCHES "^armv") elseif(IOS_ARCH MATCHES "^armv")
set(ARM 1) set(ARM 1)
elseif(IOS_ARCH MATCHES "^x86_64") elseif((IOS_ARCH MATCHES "^x86_64") OR (VISIONOS_ARCH MATCHES "^x86_64"))
set(X86_64 1) set(X86_64 1)
elseif(IOS_ARCH MATCHES "^i386") elseif(IOS_ARCH MATCHES "^i386")
set(X86 1) set(X86 1)
else() else()
message(FATAL_ERROR "iOS toolchain doesn't recognize ARCH='${IOS_ARCH}' value") if(IPHONEOS OR IPHONESIMULATOR)
message(FATAL_ERROR "invalid value of IOS_ARCH='${IOS_ARCH}'")
elseif(VISIONOS OR VISIONSIMULATOR)
message(FATAL_ERROR "invalid value of VISIONOS_ARCH='${VISIONOS_ARCH}'")
endif()
endif() endif()
if(NOT DEFINED CMAKE_OSX_SYSROOT) if(NOT DEFINED CMAKE_OSX_SYSROOT)
if(IPHONEOS) if(IPHONEOS)
set(CMAKE_OSX_SYSROOT "iphoneos") set(CMAKE_OSX_SYSROOT "iphoneos")
set(SYSTEM "iOS")
set(ARCH "${IOS_ARCH}")
elseif(IPHONESIMULATOR) elseif(IPHONESIMULATOR)
set(CMAKE_OSX_SYSROOT "iphonesimulator") set(CMAKE_OSX_SYSROOT "iphonesimulator")
set(SYSTEM "iOS")
set(ARCH "${IOS_ARCH}")
elseif(VISIONOS)
set(CMAKE_OSX_SYSROOT "xros")
set(SYSTEM "visionOS")
set(ARCH "${VISIONOS_ARCH}")
elseif(VISIONSIMULATOR)
set(CMAKE_OSX_SYSROOT "xrsimulator")
set(SYSTEM "visionOS")
set(ARCH "${VISIONOS_ARCH}")
elseif(MAC_CATALYST) elseif(MAC_CATALYST)
# Use MacOS SDK for Catalyst builds # Use MacOS SDK for Catalyst builds
set(CMAKE_OSX_SYSROOT "macosx") set(CMAKE_OSX_SYSROOT "macosx")
@ -90,14 +109,25 @@ set(CMAKE_MACOSX_BUNDLE YES)
set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO")
if(APPLE_FRAMEWORK AND NOT BUILD_SHARED_LIBS) if(APPLE_FRAMEWORK AND NOT BUILD_SHARED_LIBS)
set(CMAKE_OSX_ARCHITECTURES "${IOS_ARCH}" CACHE INTERNAL "Build architecture for iOS" FORCE) set(CMAKE_OSX_ARCHITECTURES "${ARCH}" CACHE INTERNAL "Build architecture for iOS/visionOS" FORCE)
endif() endif()
if(NOT DEFINED IPHONEOS_DEPLOYMENT_TARGET AND NOT MAC_CATALYST) if((IPHONEOS OR IPHONESIMULATOR) AND NOT DEFINED IPHONEOS_DEPLOYMENT_TARGET)
if(NOT DEFINED ENV{IPHONEOS_DEPLOYMENT_TARGET}) if(NOT DEFINED ENV{IPHONEOS_DEPLOYMENT_TARGET})
message(FATAL_ERROR "IPHONEOS_DEPLOYMENT_TARGET is not specified") message(FATAL_ERROR "IPHONEOS_DEPLOYMENT_TARGET is not specified")
endif() endif()
set(IPHONEOS_DEPLOYMENT_TARGET "$ENV{IPHONEOS_DEPLOYMENT_TARGET}") set(IPHONEOS_DEPLOYMENT_TARGET "$ENV{IPHONEOS_DEPLOYMENT_TARGET}")
set(DEPLOYMENT_TARGET "${IPHONEOS_DEPLOYMENT_TARGET}")
set(DEPLOYMENT_TARGET_CMDLINE "IPHONEOS_DEPLOYMENT_TARGET=${IPHONEOS_DEPLOYMENT_TARGET}")
endif()
if((VISIONOS OR VISIONSIMULATOR) AND NOT DEFINED XROS_DEPLOYMENT_TARGET)
if(NOT DEFINED ENV{XROS_DEPLOYMENT_TARGET})
message(FATAL_ERROR "XROS_DEPLOYMENT_TARGET is not specified")
endif()
set(XROS_DEPLOYMENT_TARGET "$ENV{XROS_DEPLOYMENT_TARGET}")
set(DEPLOYMENT_TARGET "${XROS_DEPLOYMENT_TARGET}")
set(DEPLOYMENT_TARGET_CMDLINE "XROS_DEPLOYMENT_TARGET=${XROS_DEPLOYMENT_TARGET}")
endif() endif()
if(NOT __IN_TRY_COMPILE) if(NOT __IN_TRY_COMPILE)
@ -124,9 +154,9 @@ if(NOT __IN_TRY_COMPILE)
message(FATAL_ERROR "Can't prepare xcodebuild_wrapper") message(FATAL_ERROR "Can't prepare xcodebuild_wrapper")
endif() endif()
if(APPLE_FRAMEWORK AND BUILD_SHARED_LIBS) if(APPLE_FRAMEWORK AND BUILD_SHARED_LIBS)
set(XCODEBUILD_EXTRA_ARGS "${XCODEBUILD_EXTRA_ARGS} IPHONEOS_DEPLOYMENT_TARGET=${IPHONEOS_DEPLOYMENT_TARGET} CODE_SIGN_IDENTITY='' CODE_SIGNING_REQUIRED=NO -sdk ${CMAKE_OSX_SYSROOT}") set(XCODEBUILD_EXTRA_ARGS "${XCODEBUILD_EXTRA_ARGS} ${DEPLOYMENT_TARGET_CMDLINE} CODE_SIGN_IDENTITY='' CODE_SIGNING_REQUIRED=NO -sdk ${CMAKE_OSX_SYSROOT}")
else() else()
set(XCODEBUILD_EXTRA_ARGS "${XCODEBUILD_EXTRA_ARGS} IPHONEOS_DEPLOYMENT_TARGET=${IPHONEOS_DEPLOYMENT_TARGET} CODE_SIGN_IDENTITY='' CODE_SIGNING_REQUIRED=NO ARCHS=${IOS_ARCH} -sdk ${CMAKE_OSX_SYSROOT}") set(XCODEBUILD_EXTRA_ARGS "${XCODEBUILD_EXTRA_ARGS} ${DEPLOYMENT_TARGET_CMDLINE} CODE_SIGN_IDENTITY='' CODE_SIGNING_REQUIRED=NO ARCHS=${ARCH} -sdk ${CMAKE_OSX_SYSROOT}")
endif() endif()
configure_file("${CMAKE_CURRENT_LIST_DIR}/xcodebuild_wrapper.in" "${_xcodebuild_wrapper_tmp}" @ONLY) configure_file("${CMAKE_CURRENT_LIST_DIR}/xcodebuild_wrapper.in" "${_xcodebuild_wrapper_tmp}" @ONLY)
file(COPY "${_xcodebuild_wrapper_tmp}" DESTINATION ${CMAKE_BINARY_DIR} FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE) file(COPY "${_xcodebuild_wrapper_tmp}" DESTINATION ${CMAKE_BINARY_DIR} FILE_PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
@ -137,16 +167,16 @@ if(NOT __IN_TRY_COMPILE)
endif() endif()
# Standard settings # Standard settings
set(CMAKE_SYSTEM_NAME iOS) set(CMAKE_SYSTEM_NAME "${SYSTEM}")
# Apple Framework settings # Apple Framework settings
if(APPLE_FRAMEWORK AND BUILD_SHARED_LIBS) if(APPLE_FRAMEWORK AND BUILD_SHARED_LIBS)
set(CMAKE_SYSTEM_VERSION "${IPHONEOS_DEPLOYMENT_TARGET}") set(CMAKE_SYSTEM_VERSION "${DEPLOYMENT_TARGET}")
set(CMAKE_C_SIZEOF_DATA_PTR 4) set(CMAKE_C_SIZEOF_DATA_PTR 4)
set(CMAKE_CXX_SIZEOF_DATA_PTR 4) set(CMAKE_CXX_SIZEOF_DATA_PTR 4)
else() else()
set(CMAKE_SYSTEM_VERSION "${IPHONEOS_DEPLOYMENT_TARGET}") set(CMAKE_SYSTEM_VERSION "${DEPLOYMENT_TARGET}")
set(CMAKE_SYSTEM_PROCESSOR "${IOS_ARCH}") set(CMAKE_SYSTEM_PROCESSOR "${ARCH}")
if(AARCH64 OR X86_64) if(AARCH64 OR X86_64)
set(CMAKE_C_SIZEOF_DATA_PTR 8) set(CMAKE_C_SIZEOF_DATA_PTR 8)
@ -190,4 +220,4 @@ if(NOT CMAKE_FIND_ROOT_PATH_MODE_PROGRAM)
set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER) set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
endif() endif()
toolchain_save_config(IOS_ARCH IPHONEOS_DEPLOYMENT_TARGET) toolchain_save_config(IOS_ARCH VISIONOS_ARCH ARCH DEPLOYMENT_TARGET)