diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d6d22c204..300e17c9dd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -238,9 +238,9 @@ OCV_OPTION(BUILD_ITT "Build Intel ITT from source" # Optional 3rd party components # =================================================== 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) -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 VERIFY HAVE_AVFOUNDATION) 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 VERIFY HAVE_CAP_IOS) 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 VISIBLE_IF ANDROID VERIFY HAVE_CPUFEATURES) 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) 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) OCV_OPTION(WITH_CUFFT "Include NVidia Cuda Fast Fourier Transform (FFT) library support" 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 VERIFY HAVE_EIGEN) 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) 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") OCV_OPTION(WITH_GTK "Include GTK support" ON 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 VERIFY HAVE_WAYLAND) 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) OCV_OPTION(WITH_HALIDE "Include Halide support" OFF VISIBLE_IF TRUE @@ -309,10 +309,10 @@ OCV_OPTION(WITH_WEBNN "Include WebNN support" OFF VISIBLE_IF TRUE VERIFY HAVE_WEBNN) OCV_OPTION(WITH_JASPER "Include JPEG2K support (Jasper)" ON - VISIBLE_IF NOT IOS + VISIBLE_IF NOT IOS AND NOT XROS VERIFY HAVE_JASPER) OCV_OPTION(WITH_OPENJPEG "Include JPEG2K support (OpenJPEG)" ON - VISIBLE_IF NOT IOS + VISIBLE_IF NOT IOS AND NOT XROS VERIFY HAVE_OPENJPEG) OCV_OPTION(WITH_JPEG "Include JPEG support" ON VISIBLE_IF TRUE @@ -330,10 +330,10 @@ OCV_OPTION(WITH_OPENVX "Include OpenVX support" OFF VISIBLE_IF TRUE VERIFY HAVE_OPENVX) 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) 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) OCV_OPTION(WITH_PNG "Include PNG support" ON VISIBLE_IF TRUE @@ -345,19 +345,19 @@ OCV_OPTION(WITH_GDCM "Include DICOM support" OFF VISIBLE_IF TRUE VERIFY HAVE_GDCM) 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) 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) 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) OCV_OPTION(WITH_WIN32UI "Build with Win32 UI Backend support" ON VISIBLE_IF WIN32 AND NOT WINRT VERIFY HAVE_WIN32UI) 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) OCV_OPTION(WITH_HPX "Include Ste||ar Group HPX support" OFF VISIBLE_IF TRUE @@ -369,7 +369,7 @@ OCV_OPTION(WITH_PTHREADS_PF "Use pthreads-based parallel_for" ON VISIBLE_IF NOT WIN32 OR MINGW VERIFY HAVE_PTHREADS_PF) OCV_OPTION(WITH_TIFF "Include TIFF support" ON - VISIBLE_IF NOT IOS + VISIBLE_IF NOT IOS AND NOT XROS VERIFY HAVE_TIFF) OCV_OPTION(WITH_V4L "Include Video 4 Linux support" ON 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 VERIFY HAVE_CLP) 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) OCV_OPTION(WITH_OPENCL_SVM "Include OpenCL Shared Virtual Memory support" OFF VISIBLE_IF TRUE VERIFY HAVE_OPENCL_SVM) # experimental 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) 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) OCV_OPTION(WITH_DIRECTX "Include DirectX support" ON 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) VERIFY HAVE_MFX) 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) 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) 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) OCV_OPTION(WITH_ITT "Include Intel ITT support" ON VISIBLE_IF NOT APPLE_FRAMEWORK @@ -516,7 +516,7 @@ OCV_OPTION(INSTALL_TESTS "Install accuracy and performance test binar # 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_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_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 ) @@ -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_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 -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_VFPV3 "Enable VFPv3-D32 instructions" OFF 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 OR XROS) ) endif() 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 ) @@ -649,7 +649,7 @@ endif() ocv_cmake_hook(POST_CMAKE_BUILD_OPTIONS) # --- Python Support --- -if(NOT IOS) +if(NOT IOS AND NOT XROS) include(cmake/OpenCVDetectPython.cmake) endif() @@ -734,7 +734,7 @@ include(cmake/OpenCVModule.cmake) # Detect endianness of build platform # ---------------------------------------------------------------------------- -if(IOS) +if(IOS OR XROS) # test_big_endian needs try_compile, which doesn't work for iOS # http://public.kitware.com/Bug/view.php?id=12288 set(WORDS_BIGENDIAN 0) @@ -1007,7 +1007,7 @@ include(cmake/OpenCVGenAndroidMK.cmake) # Generate OpenCVConfig.cmake and OpenCVConfig-version.cmake for cmake projects include(cmake/OpenCVGenConfig.cmake) -# Generate Info.plist for the IOS framework +# Generate Info.plist for the iOS/visionOS framework if(APPLE_FRAMEWORK) include(cmake/OpenCVGenInfoPlist.cmake) endif() diff --git a/cmake/OpenCVDetectPython.cmake b/cmake/OpenCVDetectPython.cmake index d4098ce8e6..b18bebb674 100644 --- a/cmake/OpenCVDetectPython.cmake +++ b/cmake/OpenCVDetectPython.cmake @@ -175,7 +175,7 @@ if(NOT ${found}) endif() endif() - if(NOT ANDROID AND NOT IOS) + if(NOT ANDROID AND NOT IOS AND NOT XROS) if(CMAKE_HOST_UNIX) execute_process(COMMAND ${_executable} -c "from sysconfig import *; print(get_path('purelib'))" RESULT_VARIABLE _cvpy_process @@ -240,7 +240,7 @@ if(NOT ${found}) OUTPUT_STRIP_TRAILING_WHITESPACE) endif() endif() - endif(NOT ANDROID AND NOT IOS) + endif(NOT ANDROID AND NOT IOS AND NOT XROS) endif() # Export return values diff --git a/cmake/OpenCVFindLibsGUI.cmake b/cmake/OpenCVFindLibsGUI.cmake index 79758fa813..31c19b1da7 100644 --- a/cmake/OpenCVFindLibsGUI.cmake +++ b/cmake/OpenCVFindLibsGUI.cmake @@ -77,7 +77,7 @@ endif(WITH_OPENGL) # --- Cocoa --- if(APPLE) - if(NOT IOS AND CV_CLANG) + if(NOT IOS AND NOT XROS AND CV_CLANG) set(HAVE_COCOA YES) endif() endif() diff --git a/cmake/OpenCVGenInfoPlist.cmake b/cmake/OpenCVGenInfoPlist.cmake index 105087907f..f1a6926d07 100644 --- a/cmake/OpenCVGenInfoPlist.cmake +++ b/cmake/OpenCVGenInfoPlist.cmake @@ -13,6 +13,14 @@ if(IOS) configure_file("${OpenCV_SOURCE_DIR}/platforms/ios/Info.plist.in" "${CMAKE_BINARY_DIR}/ios/Info.plist") 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) configure_file("${OpenCV_SOURCE_DIR}/platforms/osx/Info.plist.in" "${CMAKE_BINARY_DIR}/osx/Info.plist") diff --git a/cmake/OpenCVGenPkgconfig.cmake b/cmake/OpenCVGenPkgconfig.cmake index 8d36b74f09..4fc80f5e4b 100644 --- a/cmake/OpenCVGenPkgconfig.cmake +++ b/cmake/OpenCVGenPkgconfig.cmake @@ -1,4 +1,4 @@ -if(MSVC OR IOS) +if(MSVC OR IOS OR XROS) return() endif() diff --git a/cmake/OpenCVUtils.cmake b/cmake/OpenCVUtils.cmake index a90eb5a5ab..3f82550065 100644 --- a/cmake/OpenCVUtils.cmake +++ b/cmake/OpenCVUtils.cmake @@ -1564,7 +1564,7 @@ function(ocv_add_library target) 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") else() set(OPENCV_APPLE_INFO_PLIST "${CMAKE_BINARY_DIR}/osx/Info.plist") diff --git a/modules/core/CMakeLists.txt b/modules/core/CMakeLists.txt index 4d5ebf3483..bf3a65c7c3 100644 --- a/modules/core/CMakeLists.txt +++ b/modules/core/CMakeLists.txt @@ -20,7 +20,7 @@ ocv_add_dispatched_file_force_all(test_intrin512 TEST AVX512_SKX) 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) endif() # parallel backends configuration diff --git a/modules/imgcodecs/CMakeLists.txt b/modules/imgcodecs/CMakeLists.txt index 8183837c43..1468d4d73b 100644 --- a/modules/imgcodecs/CMakeLists.txt +++ b/modules/imgcodecs/CMakeLists.txt @@ -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.mm) endif() -if(IOS) +if(IOS OR XROS) list(APPEND imgcodecs_srcs ${CMAKE_CURRENT_LIST_DIR}/src/ios_conversions.mm) list(APPEND IMGCODECS_LIBRARIES "-framework UIKit") 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_LIBRARIES "-framework AppKit") endif() diff --git a/modules/imgcodecs/misc/objc/gen_dict.json b/modules/imgcodecs/misc/objc/gen_dict.json new file mode 100644 index 0000000000..cfcd5889e7 --- /dev/null +++ b/modules/imgcodecs/misc/objc/gen_dict.json @@ -0,0 +1,5 @@ +{ + "SourceMap" : { + "visionos" : "ios" + } +} diff --git a/modules/objc/generator/CMakeLists.txt b/modules/objc/generator/CMakeLists.txt index b3cbbd3f5f..bd8f8325b3 100644 --- a/modules/objc/generator/CMakeLists.txt +++ b/modules/objc/generator/CMakeLists.txt @@ -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_RECURSE "${OPENCV_OBJC_BINDINGS_DIR}/ios") 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 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(IOS) set(OPENCV_OBJC_TARGET "ios") + elseif(XROS) + set(OPENCV_OBJC_TARGET "visionos") else() set(OPENCV_OBJC_TARGET "osx") endif() @@ -117,6 +121,7 @@ if(OPENCV_OBJC_TARGET) else() ocv_add_objc_generated_target(osx) ocv_add_objc_generated_target(ios) + ocv_add_objc_generated_target(visionos) endif() add_custom_target(gen_opencv_objc_source diff --git a/modules/objc/generator/gen_objc.py b/modules/objc/generator/gen_objc.py index 3105e7eefd..58b7dd555c 100755 --- a/modules/objc/generator/gen_objc.py +++ b/modules/objc/generator/gen_objc.py @@ -1600,7 +1600,7 @@ if __name__ == "__main__": 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('-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') 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)) gendict_fname = os.path.join(misc_location, 'gen_dict.json') + module_source_map = {} if os.path.exists(gendict_fname): with open(gendict_fname) as f: gen_type_dict = json.load(f) @@ -1687,6 +1688,7 @@ if __name__ == "__main__": header_fix.update(gen_type_dict.get("header_fix", {})) enum_fix.update(gen_type_dict.get("enum_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", {})) module_imports += gen_type_dict.get("module_imports", []) @@ -1695,15 +1697,10 @@ if __name__ == "__main__": if os.path.exists(objc_files_dir): copied_files += copy_objc_files(objc_files_dir, objc_base_path, module, True) - if args.target == 'ios': - ios_files_dir = os.path.join(misc_location, 'ios') - if os.path.exists(ios_files_dir): - copied_files += copy_objc_files(ios_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) + target_path = 'macosx' if args.target == 'osx' else module_source_map.get(args.target, args.target) + target_files_dir = os.path.join(misc_location, target_path) + if os.path.exists(target_files_dir): + copied_files += copy_objc_files(target_files_dir, objc_base_path, module, True) objc_test_files_dir = os.path.join(misc_location, 'test') if os.path.exists(objc_test_files_dir): diff --git a/modules/videoio/CMakeLists.txt b/modules/videoio/CMakeLists.txt index eee706d306..f800babdcd 100644 --- a/modules/videoio/CMakeLists.txt +++ b/modules/videoio/CMakeLists.txt @@ -1,5 +1,5 @@ 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) endif() @@ -197,7 +197,7 @@ if(TARGET ocv.3rdparty.aravis) endif() if(TARGET ocv.3rdparty.avfoundation) - if(IOS) + if(IOS OR XROS) list(APPEND videoio_srcs ${CMAKE_CURRENT_LIST_DIR}/src/cap_avfoundation.mm) else() list(APPEND videoio_srcs ${CMAKE_CURRENT_LIST_DIR}/src/cap_avfoundation_mac.mm) diff --git a/modules/videoio/src/cap_avfoundation.mm b/modules/videoio/src/cap_avfoundation.mm index 12fa42f5b5..d0f2b41c37 100644 --- a/modules/videoio/src/cap_avfoundation.mm +++ b/modules/videoio/src/cap_avfoundation.mm @@ -61,6 +61,8 @@ #define DISABLE_AUTO_RESTART 999 +#if !TARGET_OS_VISION + @interface CaptureDelegate : NSObject { int newFrame; @@ -125,6 +127,7 @@ class CvCaptureCAM : public CvCapture { int disableAutoRestart; }; +#endif /***************************************************************************** * @@ -160,6 +163,7 @@ private: uint32_t mMode; int mFormat; + void handleTracks(NSArray* tracks, const char* filename); bool setupReadingAt(CMTime position); IplImage* retrieveFramePixelBuffer(); int getPreferredOrientationDegrees() const; @@ -217,6 +221,8 @@ cv::Ptr cv::create_AVFoundation_capture_file(const std::strin } +#if !TARGET_OS_VISION + cv::Ptr cv::create_AVFoundation_capture_cam(int index) { CvCaptureCAM* retval = new CvCaptureCAM(index); @@ -226,6 +232,8 @@ cv::Ptr cv::create_AVFoundation_capture_cam(int index) return 0; } +#endif + cv::Ptr cv::create_AVFoundation_writer(const std::string& filename, int fourcc, double fps, const cv::Size &frameSize, const cv::VideoWriterParameters& params) @@ -245,6 +253,8 @@ cv::Ptr cv::create_AVFoundation_writer(const std::string& file * *****************************************************************************/ +#if !TARGET_OS_VISION + CvCaptureCAM::CvCaptureCAM(int cameraNum) { mCaptureSession = nil; mCaptureDeviceInput = nil; @@ -773,6 +783,7 @@ fromConnection:(AVCaptureConnection *)connection{ @end +#endif /***************************************************************************** * @@ -811,24 +822,26 @@ CvCaptureFile::CvCaptureFile(const char* filename) { 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* 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]; - if ([tracks count] == 0) { - fprintf(stderr, "OpenCV: Couldn't read video stream from file \"%s\"\n", filename); - [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; + handleTracks(tracks, filename); +#endif [localpool drain]; } @@ -850,6 +863,24 @@ CvCaptureFile::~CvCaptureFile() { [localpool drain]; } +void CvCaptureFile::handleTracks(NSArray* 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) { if (mAssetReader) { if (mAssetReader.status == AVAssetReaderStatusReading) { @@ -1269,25 +1300,25 @@ CvVideoWriter_AVFoundation::CvVideoWriter_AVFoundation(const char* filename, int //exception; } - // Three codec supported AVVideoCodecH264 AVVideoCodecJPEG AVVideoCodecTypeHEVC + // Three codec supported AVVideoCodecTypeH264 AVVideoCodecTypeJPEG AVVideoCodecTypeHEVC // On iPhone 3G H264 is not supported. 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')){ - 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')){ - codec = [AVVideoCodecH264 copy]; + codec = [AVVideoCodecTypeH264 copy]; // 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') || 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]; } else { - codec = [AVVideoCodecH264 copy]; + codec = [AVVideoCodecTypeH264 copy]; } #endif }else{ - codec = [AVVideoCodecH264 copy]; // default canonical H264. + codec = [AVVideoCodecTypeH264 copy]; // default canonical H264. } //NSLog(@"Path: %@", path); @@ -1349,17 +1380,17 @@ CvVideoWriter_AVFoundation::~CvVideoWriter_AVFoundation() { NSAutoreleasePool* localpool = [[NSAutoreleasePool alloc] init]; [mMovieWriterInput markAsFinished]; - [mMovieWriter finishWriting]; - [mMovieWriter release]; - [mMovieWriterInput release]; - [mMovieWriterAdaptor release]; - [path release]; - [codec release]; - [fileType release]; - cvReleaseImage(&argbimage); - - [localpool drain]; + [mMovieWriter finishWritingWithCompletionHandler:^() { + [mMovieWriter release]; + [mMovieWriterInput release]; + [mMovieWriterAdaptor release]; + [path release]; + [codec release]; + [fileType release]; + cvReleaseImage(&argbimage); + [localpool drain]; + }]; } bool CvVideoWriter_AVFoundation::writeFrame(const IplImage* iplimage) { diff --git a/platforms/apple/build_xcframework.py b/platforms/apple/build_xcframework.py index 49878435d0..3916c135f9 100755 --- a/platforms/apple/build_xcframework.py +++ b/platforms/apple/build_xcframework.py @@ -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('--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('--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('--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') @@ -52,6 +54,13 @@ if __name__ == "__main__": iphonesimulator_archs = "x86_64,arm64" 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 if not macos_archs and not args.build_only_specified_archs: # Supply defaults @@ -70,6 +79,7 @@ if __name__ == "__main__": # Phase 1: build .frameworks for each platform 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') + visionos_script_path = os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../ios/build_visionos_framework.py') 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 print_header("Building iPhoneSimulator frameworks") 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: build_folder = get_or_create_build_folder(args.out, "macos") build_folders.append(build_folder) diff --git a/platforms/ios/build_framework.py b/platforms/ios/build_framework.py index 77878280f7..b876812720 100755 --- a/platforms/ios/build_framework.py +++ b/platforms/ios/build_framework.py @@ -254,9 +254,9 @@ class Builder: toolchain = self.getToolchain(arch, target) cmakecmd = self.getCMakeArgs(arch, target) + \ (["-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") - 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() if build_arch != arch: print("build_arch (%s) != arch (%s)" % (build_arch, arch)) @@ -341,7 +341,7 @@ class Builder: def makeDynamicLib(self, builddir): target = builddir[(builddir.rfind("build-") + 6):] 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") if not os.path.exists(framework_dir): os.makedirs(framework_dir) @@ -379,7 +379,7 @@ class Builder: "-framework", "CoreImage", "-framework", "CoreMedia", "-framework", "QuartzCore", "-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 = [ "-iframework", "%s/System/iOSSupport/System/Library/Frameworks" % sdk_dir, "-framework", "AVFoundation", "-framework", "CoreGraphics", diff --git a/platforms/ios/build_visionos_framework.py b/platforms/ios/build_visionos_framework.py new file mode 100755 index 0000000000..96364c7b8b --- /dev/null +++ b/platforms/ios/build_visionos_framework.py @@ -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) diff --git a/platforms/ios/cmake/Toolchains/Toolchain-XROS_Xcode.cmake b/platforms/ios/cmake/Toolchains/Toolchain-XROS_Xcode.cmake new file mode 100644 index 0000000000..0f22bd73a9 --- /dev/null +++ b/platforms/ios/cmake/Toolchains/Toolchain-XROS_Xcode.cmake @@ -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") diff --git a/platforms/ios/cmake/Toolchains/Toolchain-XRSimulator_Xcode.cmake b/platforms/ios/cmake/Toolchains/Toolchain-XRSimulator_Xcode.cmake new file mode 100644 index 0000000000..aee12f4c5d --- /dev/null +++ b/platforms/ios/cmake/Toolchains/Toolchain-XRSimulator_Xcode.cmake @@ -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") diff --git a/platforms/ios/cmake/Toolchains/common-ios-toolchain.cmake b/platforms/ios/cmake/Toolchains/common-ios-toolchain.cmake index 9918c468b4..7a14529c2d 100644 --- a/platforms/ios/cmake/Toolchains/common-ios-toolchain.cmake +++ b/platforms/ios/cmake/Toolchains/common-ios-toolchain.cmake @@ -61,26 +61,45 @@ else() endmacro() 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") 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) elseif(IOS_ARCH MATCHES "^armv") 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) elseif(IOS_ARCH MATCHES "^i386") set(X86 1) 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() if(NOT DEFINED CMAKE_OSX_SYSROOT) if(IPHONEOS) set(CMAKE_OSX_SYSROOT "iphoneos") + set(SYSTEM "iOS") + set(ARCH "${IOS_ARCH}") elseif(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) # Use MacOS SDK for Catalyst builds set(CMAKE_OSX_SYSROOT "macosx") @@ -90,14 +109,25 @@ set(CMAKE_MACOSX_BUNDLE YES) set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_REQUIRED "NO") 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() -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}) message(FATAL_ERROR "IPHONEOS_DEPLOYMENT_TARGET is not specified") endif() 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() if(NOT __IN_TRY_COMPILE) @@ -124,9 +154,9 @@ if(NOT __IN_TRY_COMPILE) message(FATAL_ERROR "Can't prepare xcodebuild_wrapper") endif() 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() - 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() 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) @@ -137,16 +167,16 @@ if(NOT __IN_TRY_COMPILE) endif() # Standard settings -set(CMAKE_SYSTEM_NAME iOS) +set(CMAKE_SYSTEM_NAME "${SYSTEM}") # Apple Framework settings 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_CXX_SIZEOF_DATA_PTR 4) else() - set(CMAKE_SYSTEM_VERSION "${IPHONEOS_DEPLOYMENT_TARGET}") - set(CMAKE_SYSTEM_PROCESSOR "${IOS_ARCH}") + set(CMAKE_SYSTEM_VERSION "${DEPLOYMENT_TARGET}") + set(CMAKE_SYSTEM_PROCESSOR "${ARCH}") if(AARCH64 OR X86_64) 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) endif() -toolchain_save_config(IOS_ARCH IPHONEOS_DEPLOYMENT_TARGET) +toolchain_save_config(IOS_ARCH VISIONOS_ARCH ARCH DEPLOYMENT_TARGET)