build_visionos_framework.py 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. #!/usr/bin/env python
  2. """
  3. The script builds OpenCV.framework for visionOS.
  4. """
  5. from __future__ import print_function
  6. import os, os.path, sys, argparse, traceback, multiprocessing
  7. # import common code
  8. # sys.path.insert(0, os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../ios'))
  9. from build_framework import Builder
  10. sys.path.insert(0, os.path.abspath(os.path.abspath(os.path.dirname(__file__))+'/../apple'))
  11. from cv_build_utils import print_error, get_cmake_version
  12. XROS_DEPLOYMENT_TARGET='1.0' # default, can be changed via command line options or environment variable
  13. class visionOSBuilder(Builder):
  14. def checkCMakeVersion(self):
  15. assert get_cmake_version() >= (3, 17), "CMake 3.17 or later is required. Current version is {}".format(get_cmake_version())
  16. def getObjcTarget(self, target):
  17. return 'visionos'
  18. def getToolchain(self, arch, target):
  19. toolchain = os.path.join(self.opencv, "platforms", "ios", "cmake", "Toolchains", "Toolchain-%s_Xcode.cmake" % target)
  20. return toolchain
  21. def getCMakeArgs(self, arch, target):
  22. args = Builder.getCMakeArgs(self, arch, target)
  23. args = args + [
  24. '-DVISIONOS_ARCH=%s' % arch
  25. ]
  26. return args
  27. def getBuildCommand(self, arch, target):
  28. buildcmd = [
  29. "xcodebuild",
  30. "XROS_DEPLOYMENT_TARGET=" + os.environ['XROS_DEPLOYMENT_TARGET'],
  31. "ARCHS=%s" % arch,
  32. "-sdk", target.lower(),
  33. "-configuration", "Debug" if self.debug else "Release",
  34. "-parallelizeTargets",
  35. "-jobs", str(multiprocessing.cpu_count())
  36. ]
  37. return buildcmd
  38. def getInfoPlist(self, builddirs):
  39. return os.path.join(builddirs[0], "visionos", "Info.plist")
  40. if __name__ == "__main__":
  41. folder = os.path.abspath(os.path.join(os.path.dirname(sys.argv[0]), "../.."))
  42. parser = argparse.ArgumentParser(description='The script builds OpenCV.framework for visionOS.')
  43. # TODO: When we can make breaking changes, we should make the out argument explicit and required like in build_xcframework.py.
  44. parser.add_argument('out', metavar='OUTDIR', help='folder to put built framework')
  45. parser.add_argument('--opencv', metavar='DIR', default=folder, help='folder with opencv repository (default is "../.." relative to script location)')
  46. parser.add_argument('--contrib', metavar='DIR', default=None, help='folder with opencv_contrib repository (default is "None" - build only main framework)')
  47. 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"')
  48. 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"')
  49. parser.add_argument('--dynamic', default=False, action='store_true', help='build dynamic framework (default is "False" - builds static framework)')
  50. parser.add_argument('--enable_nonfree', default=False, dest='enablenonfree', action='store_true', help='enable non-free modules (disabled by default)')
  51. parser.add_argument('--visionos_deployment_target', default=os.environ.get('XROS_DEPLOYMENT_TARGET', XROS_DEPLOYMENT_TARGET), help='specify XROS_DEPLOYMENT_TARGET')
  52. parser.add_argument('--visionos_archs', default=None, help='select visionOS target ARCHS. Default is none')
  53. parser.add_argument('--visionsimulator_archs', default=None, help='select visionSimulator target ARCHS. Default is none')
  54. parser.add_argument('--debug', action='store_true', help='Build "Debug" binaries (CMAKE_BUILD_TYPE=Debug)')
  55. parser.add_argument('--debug_info', action='store_true', help='Build with debug information (useful for Release mode: BUILD_WITH_DEBUG_INFO=ON)')
  56. parser.add_argument('--framework_name', default='opencv2', dest='framework_name', help='Name of OpenCV framework (default: opencv2, will change to OpenCV in future version)')
  57. 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")')
  58. parser.add_argument('--run_tests', default=False, dest='run_tests', action='store_true', help='Run tests')
  59. parser.add_argument('--build_docs', default=False, dest='build_docs', action='store_true', help='Build docs')
  60. parser.add_argument('--disable-swift', default=False, dest='swiftdisabled', action='store_true', help='Disable building of Swift extensions')
  61. args, unknown_args = parser.parse_known_args()
  62. if unknown_args:
  63. print("The following args are not recognized and will not be used: %s" % unknown_args)
  64. os.environ['XROS_DEPLOYMENT_TARGET'] = args.visionos_deployment_target
  65. print('Using XROS_DEPLOYMENT_TARGET=' + os.environ['XROS_DEPLOYMENT_TARGET'])
  66. visionos_archs = None
  67. if args.visionos_archs:
  68. visionos_archs = args.visionos_archs.split(',')
  69. print('Using visionOS ARCHS=' + str(visionos_archs))
  70. visionsimulator_archs = None
  71. if args.visionsimulator_archs:
  72. visionsimulator_archs = args.visionsimulator_archs.split(',')
  73. print('Using visionOS ARCHS=' + str(visionsimulator_archs))
  74. # Prevent the build from happening if the same architecture is specified for multiple platforms.
  75. # When `lipo` is run to stitch the frameworks together into a fat framework, it'll fail, so it's
  76. # better to stop here while we're ahead.
  77. if visionos_archs and visionsimulator_archs:
  78. duplicate_archs = set(visionos_archs).intersection(visionsimulator_archs)
  79. if duplicate_archs:
  80. 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)
  81. exit(1)
  82. if args.legacy_build:
  83. args.framework_name = "opencv2"
  84. if not "objc" in args.without:
  85. args.without.append("objc")
  86. targets = []
  87. if not visionos_archs and not visionsimulator_archs:
  88. print_error("--visionos_archs and --visionsimulator_archs are undefined; nothing will be built.")
  89. sys.exit(1)
  90. if visionos_archs:
  91. targets.append((visionos_archs, "XROS"))
  92. if visionsimulator_archs:
  93. targets.append((visionsimulator_archs, "XRSimulator")),
  94. 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)
  95. b.build(args.out)