build_package.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579
  1. #!/usr/bin/env python
  2. import os, sys
  3. import argparse
  4. import glob
  5. import re
  6. import shutil
  7. import subprocess
  8. import time
  9. import logging as log
  10. if sys.version_info[0] == 2:
  11. sys.exit("FATAL: Python 2.x is not supported")
  12. from pathlib import Path
  13. SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
  14. class Fail(Exception):
  15. def __init__(self, text=None):
  16. self.t = text
  17. def __str__(self):
  18. return "ERROR" if self.t is None else self.t
  19. def execute(cmd, cwd=None, shell=False):
  20. try:
  21. log.debug("Executing: %s" % cmd)
  22. log.info('Executing: ' + ' '.join(cmd))
  23. if cwd:
  24. log.info(" in: %s" % cwd)
  25. retcode = subprocess.call(cmd, shell=shell, cwd=str(cwd) if cwd else None)
  26. if retcode < 0:
  27. raise Fail("Child was terminated by signal: %s" % -retcode)
  28. elif retcode > 0:
  29. raise Fail("Child returned: %s" % retcode)
  30. except OSError as e:
  31. raise Fail("Execution failed: %d / %s" % (e.errno, e.strerror))
  32. def check_executable(cmd):
  33. try:
  34. log.debug("Executing: %s" % cmd)
  35. result = subprocess.check_output(cmd, stderr=subprocess.STDOUT)
  36. if not isinstance(result, str):
  37. result = result.decode("utf-8")
  38. log.debug("Result: %s" % (result + '\n').split('\n')[0])
  39. return True
  40. except OSError as e:
  41. log.debug('Failed: %s' % e)
  42. return False
  43. def rm_one(d):
  44. d = str(d) # Python 3.5 may not handle Path
  45. d = os.path.abspath(d)
  46. if os.path.exists(d):
  47. if os.path.isdir(d):
  48. log.info("Removing dir: %s", d)
  49. shutil.rmtree(d)
  50. elif os.path.isfile(d):
  51. log.info("Removing file: %s", d)
  52. os.remove(d)
  53. def prepare_dir(d, clean=False):
  54. d = str(d) # Python 3.5 may not handle Path
  55. d = os.path.abspath(d)
  56. log.info("Preparing directory: '%s' (clean: %r)", d, clean)
  57. if os.path.exists(d):
  58. if not os.path.isdir(d):
  59. raise Fail("Not a directory: %s" % d)
  60. if clean:
  61. for item in os.listdir(d):
  62. rm_one(os.path.join(d, item))
  63. else:
  64. os.makedirs(d)
  65. return Path(d)
  66. def check_dir(d):
  67. d = str(d) # Python 3.5 may not handle Path
  68. d = os.path.abspath(d)
  69. log.info("Check directory: '%s'", d)
  70. if os.path.exists(d):
  71. if not os.path.isdir(d):
  72. raise Fail("Not a directory: %s" % d)
  73. else:
  74. raise Fail("The directory is missing: %s" % d)
  75. return Path(d)
  76. # shutil.copytree fails if dst exists
  77. def copytree(src, dst, exclude=None):
  78. log.debug('copytree(%s, %s)', src, dst)
  79. src = str(src) # Python 3.5 may not handle Path
  80. dst = str(dst) # Python 3.5 may not handle Path
  81. if os.path.isfile(src):
  82. shutil.copy2(src, dst)
  83. return
  84. def copy_recurse(subdir):
  85. if exclude and subdir in exclude:
  86. log.debug(' skip: %s', subdir)
  87. return
  88. s = os.path.join(src, subdir)
  89. d = os.path.join(dst, subdir)
  90. if os.path.exists(d) or exclude:
  91. if os.path.isfile(s):
  92. shutil.copy2(s, d)
  93. elif os.path.isdir(s):
  94. if not os.path.isdir(d):
  95. os.makedirs(d)
  96. for item in os.listdir(s):
  97. copy_recurse(os.path.join(subdir, item))
  98. else:
  99. assert False, s + " => " + d
  100. else:
  101. if os.path.isfile(s):
  102. shutil.copy2(s, d)
  103. elif os.path.isdir(s):
  104. shutil.copytree(s, d)
  105. else:
  106. assert False, s + " => " + d
  107. copy_recurse('')
  108. def git_checkout(dst, url, branch, revision, clone_extra_args, noFetch=False):
  109. assert isinstance(dst, Path)
  110. log.info("Git checkout: '%s' (%s @ %s)", dst, url, revision)
  111. if noFetch:
  112. pass
  113. elif not os.path.exists(str(dst / '.git')):
  114. execute(cmd=['git', 'clone'] +
  115. (['-b', branch] if branch else []) +
  116. clone_extra_args + [url, '.'], cwd=dst)
  117. else:
  118. execute(cmd=['git', 'fetch', 'origin'] + ([branch + ':' + branch] if branch else []), cwd=dst)
  119. execute(cmd=['git', 'reset', '--hard'], cwd=dst)
  120. execute(cmd=['git', 'clean', '-f', '-d'], cwd=dst)
  121. execute(cmd=['git', 'checkout', '--force', '-B', 'winpack_dldt', revision], cwd=dst)
  122. execute(cmd=['git', 'clean', '-f', '-d'], cwd=dst)
  123. execute(cmd=['git', 'submodule', 'init'], cwd=dst)
  124. execute(cmd=['git', 'submodule', 'update', '--force', '--depth=1000'], cwd=dst)
  125. log.info("Git checkout: DONE")
  126. execute(cmd=['git', 'status'], cwd=dst)
  127. execute(cmd=['git', 'log', '--max-count=1', 'HEAD'], cwd=dst)
  128. def git_apply_patch(src_dir, patch_file):
  129. src_dir = str(src_dir) # Python 3.5 may not handle Path
  130. patch_file = str(patch_file) # Python 3.5 may not handle Path
  131. assert os.path.exists(patch_file), patch_file
  132. execute(cmd=['git', 'apply', '--3way', '-v', '--ignore-space-change', str(patch_file)], cwd=src_dir)
  133. execute(cmd=['git', '--no-pager', 'diff', 'HEAD'], cwd=src_dir)
  134. os.environ['GIT_AUTHOR_NAME'] = os.environ['GIT_COMMITTER_NAME']='build'
  135. os.environ['GIT_AUTHOR_EMAIL'] = os.environ['GIT_COMMITTER_EMAIL']='build@opencv.org'
  136. execute(cmd=['git', 'commit', '-am', 'apply opencv patch'], cwd=src_dir)
  137. #===================================================================================================
  138. class BuilderDLDT:
  139. def __init__(self, config):
  140. self.config = config
  141. cpath = self.config.dldt_config
  142. log.info('DLDT build configuration: %s', cpath)
  143. if not os.path.exists(cpath):
  144. cpath = os.path.join(SCRIPT_DIR, cpath)
  145. if not os.path.exists(cpath):
  146. raise Fail('Config "%s" is missing' % cpath)
  147. self.cpath = Path(cpath)
  148. clean_src_dir = self.config.clean_dldt
  149. if self.config.dldt_src_dir:
  150. assert os.path.exists(self.config.dldt_src_dir), self.config.dldt_src_dir
  151. dldt_dir_name = 'dldt-custom'
  152. self.srcdir = self.config.dldt_src_dir
  153. clean_src_dir = False
  154. else:
  155. assert not self.config.dldt_src_dir
  156. self.init_patchset()
  157. dldt_dir_name = 'dldt-' + self.config.dldt_src_commit + \
  158. ('/patch-' + self.patch_hashsum if self.patch_hashsum else '')
  159. if self.config.build_debug:
  160. dldt_dir_name += '-debug'
  161. self.srcdir = None # updated below
  162. log.info('DLDT directory: %s', dldt_dir_name)
  163. self.outdir = prepare_dir(os.path.join(self.config.build_cache_dir, dldt_dir_name))
  164. if self.srcdir is None:
  165. self.srcdir = prepare_dir(self.outdir / 'sources', clean=clean_src_dir)
  166. self.build_dir = prepare_dir(self.outdir / 'build', clean=self.config.clean_dldt)
  167. self.sysrootdir = prepare_dir(self.outdir / 'sysroot', clean=self.config.clean_dldt or self.config.clean_dldt_sysroot)
  168. if not (self.config.clean_dldt or self.config.clean_dldt_sysroot):
  169. _ = prepare_dir(self.sysrootdir / 'bin', clean=True) # always clean sysroot/bin (package files)
  170. _ = prepare_dir(self.sysrootdir / 'etc', clean=True) # always clean sysroot/etc (package files)
  171. if self.config.build_subst_drive:
  172. if os.path.exists(self.config.build_subst_drive + ':\\'):
  173. execute(['subst', self.config.build_subst_drive + ':', '/D'])
  174. execute(['subst', self.config.build_subst_drive + ':', str(self.outdir)])
  175. def fix_path(p):
  176. return str(p).replace(str(self.outdir), self.config.build_subst_drive + ':')
  177. self.srcdir = Path(fix_path(self.srcdir))
  178. self.build_dir = Path(fix_path(self.build_dir))
  179. self.sysrootdir = Path(fix_path(self.sysrootdir))
  180. def init_patchset(self):
  181. cpath = self.cpath
  182. self.patch_file = str(cpath / 'patch.config.py') # Python 3.5 may not handle Path
  183. with open(self.patch_file, 'r') as f:
  184. self.patch_file_contents = f.read()
  185. patch_hashsum = None
  186. try:
  187. import hashlib
  188. patch_hashsum = hashlib.md5(self.patch_file_contents.encode('utf-8')).hexdigest()
  189. except:
  190. log.warn("Can't compute hashsum of patches: %s", self.patch_file)
  191. self.patch_hashsum = self.config.override_patch_hashsum if self.config.override_patch_hashsum else patch_hashsum
  192. def prepare_sources(self):
  193. if self.config.dldt_src_dir:
  194. log.info('Using DLDT custom repository: %s', self.srcdir)
  195. return
  196. def do_clone(srcdir, noFetch):
  197. git_checkout(srcdir, self.config.dldt_src_url, self.config.dldt_src_branch, self.config.dldt_src_commit,
  198. ['-n', '--depth=100', '--no-single-branch', '--recurse-submodules'] +
  199. (self.config.dldt_src_git_clone_extra or []),
  200. noFetch=noFetch
  201. )
  202. if not os.path.exists(str(self.srcdir / '.git')):
  203. log.info('DLDT git checkout through "reference" copy.')
  204. reference_dir = self.config.dldt_reference_dir
  205. if reference_dir is None:
  206. reference_dir = prepare_dir(os.path.join(self.config.build_cache_dir, 'dldt-git-reference-repository'))
  207. do_clone(reference_dir, False)
  208. log.info('DLDT reference git checkout completed. Copying...')
  209. else:
  210. log.info('Using DLDT reference repository. Copying...')
  211. copytree(reference_dir, self.srcdir)
  212. do_clone(self.srcdir, True)
  213. else:
  214. do_clone(self.srcdir, False)
  215. log.info('DLDT git checkout completed. Patching...')
  216. def applyPatch(patch_file, subdir = None):
  217. if subdir:
  218. log.info('Patching "%s": %s' % (subdir, patch_file))
  219. else:
  220. log.info('Patching: %s' % (patch_file))
  221. git_apply_patch(self.srcdir / subdir if subdir else self.srcdir, self.cpath / patch_file)
  222. exec(compile(self.patch_file_contents, self.patch_file, 'exec'))
  223. log.info('DLDT patches applied')
  224. def build(self):
  225. self.cmake_path = 'cmake'
  226. build_config = 'Release' if not self.config.build_debug else 'Debug'
  227. cmd = [self.cmake_path, '-G', 'Visual Studio 16 2019', '-A', 'x64']
  228. cmake_vars = dict(
  229. CMAKE_BUILD_TYPE=build_config,
  230. TREAT_WARNING_AS_ERROR='OFF',
  231. ENABLE_SAMPLES='OFF',
  232. ENABLE_TESTS='OFF',
  233. BUILD_TESTS='OFF',
  234. ENABLE_OPENCV='OFF',
  235. ENABLE_GNA='OFF',
  236. ENABLE_SPEECH_DEMO='OFF', # 2020.4+
  237. NGRAPH_DOC_BUILD_ENABLE='OFF',
  238. NGRAPH_UNIT_TEST_ENABLE='OFF',
  239. NGRAPH_UNIT_TEST_OPENVINO_ENABLE='OFF',
  240. NGRAPH_TEST_UTIL_ENABLE='OFF',
  241. NGRAPH_ONNX_IMPORT_ENABLE='OFF',
  242. CMAKE_INSTALL_PREFIX=str(self.build_dir / 'install'),
  243. OUTPUT_ROOT=str(self.build_dir), # 2020.4+
  244. )
  245. self.build_config_file = str(self.cpath / 'build.config.py') # Python 3.5 may not handle Path
  246. if os.path.exists(str(self.build_config_file)):
  247. with open(self.build_config_file, 'r') as f:
  248. cfg = f.read()
  249. exec(compile(cfg, str(self.build_config_file), 'exec'))
  250. log.info('DLDT processed build configuration script')
  251. cmd += [ '-D%s=%s' % (k, v) for (k, v) in cmake_vars.items() if v is not None]
  252. if self.config.cmake_option_dldt:
  253. cmd += self.config.cmake_option_dldt
  254. cmd.append(str(self.srcdir))
  255. build_dir = self.build_dir
  256. try:
  257. execute(cmd, cwd=build_dir)
  258. # build
  259. cmd = [self.cmake_path, '--build', '.', '--config', build_config, # '--target', 'install',
  260. '--',
  261. # '/m:2' is removed, not properly supported by 2021.3
  262. '/v:n', '/consoleloggerparameters:NoSummary',
  263. ]
  264. execute(cmd, cwd=build_dir)
  265. # install ngraph only
  266. cmd = [self.cmake_path, '-DBUILD_TYPE=' + build_config, '-P', 'cmake_install.cmake']
  267. execute(cmd, cwd=build_dir / 'ngraph')
  268. except:
  269. raise
  270. log.info('DLDT build completed')
  271. def make_sysroot(self):
  272. cfg_file = str(self.cpath / 'sysroot.config.py') # Python 3.5 may not handle Path
  273. with open(cfg_file, 'r') as f:
  274. cfg = f.read()
  275. exec(compile(cfg, cfg_file, 'exec'))
  276. log.info('DLDT sysroot preparation completed')
  277. def cleanup(self):
  278. if self.config.build_subst_drive:
  279. execute(['subst', self.config.build_subst_drive + ':', '/D'])
  280. #===================================================================================================
  281. class Builder:
  282. def __init__(self, config):
  283. self.config = config
  284. build_dir_name = 'opencv_build' if not self.config.build_debug else 'opencv_build_debug'
  285. self.build_dir = prepare_dir(Path(self.config.output_dir) / build_dir_name, clean=self.config.clean_opencv)
  286. self.package_dir = prepare_dir(Path(self.config.output_dir) / 'package/opencv', clean=True)
  287. self.install_dir = prepare_dir(self.package_dir / 'build')
  288. self.src_dir = check_dir(self.config.opencv_dir)
  289. def build(self, builderDLDT):
  290. self.cmake_path = 'cmake'
  291. build_config = 'Release' if not self.config.build_debug else 'Debug'
  292. cmd = [self.cmake_path, '-G', 'Visual Studio 16 2019', '-A', 'x64']
  293. cmake_vars = dict(
  294. CMAKE_BUILD_TYPE=build_config,
  295. INSTALL_CREATE_DISTRIB='ON',
  296. BUILD_opencv_world='OFF',
  297. BUILD_TESTS='OFF',
  298. BUILD_PERF_TESTS='OFF',
  299. ENABLE_CXX11='ON',
  300. WITH_INF_ENGINE='ON',
  301. WITH_TBB='ON',
  302. CPU_BASELINE='AVX2',
  303. CMAKE_INSTALL_PREFIX=str(self.install_dir),
  304. INSTALL_PDB='ON',
  305. INSTALL_PDB_COMPONENT_EXCLUDE_FROM_ALL='OFF',
  306. VIDEOIO_PLUGIN_LIST='all',
  307. OPENCV_SKIP_CMAKE_ROOT_CONFIG='ON',
  308. OPENCV_BIN_INSTALL_PATH='bin',
  309. OPENCV_INCLUDE_INSTALL_PATH='include',
  310. OPENCV_LIB_INSTALL_PATH='lib',
  311. OPENCV_CONFIG_INSTALL_PATH='cmake',
  312. OPENCV_3P_LIB_INSTALL_PATH='3rdparty',
  313. OPENCV_SAMPLES_SRC_INSTALL_PATH='samples',
  314. OPENCV_DOC_INSTALL_PATH='doc',
  315. OPENCV_OTHER_INSTALL_PATH='etc',
  316. OPENCV_LICENSES_INSTALL_PATH='etc/licenses',
  317. OPENCV_INSTALL_DATA_DIR_RELATIVE='../../src/opencv',
  318. BUILD_opencv_python2='OFF',
  319. BUILD_opencv_python3='ON',
  320. PYTHON3_LIMITED_API='ON',
  321. OPENCV_PYTHON_INSTALL_PATH='python',
  322. )
  323. if self.config.dldt_release:
  324. cmake_vars['INF_ENGINE_RELEASE'] = str(self.config.dldt_release)
  325. cmake_vars['INF_ENGINE_LIB_DIRS:PATH'] = str(builderDLDT.sysrootdir / 'deployment_tools/inference_engine/lib/intel64')
  326. assert os.path.exists(cmake_vars['INF_ENGINE_LIB_DIRS:PATH']), cmake_vars['INF_ENGINE_LIB_DIRS:PATH']
  327. cmake_vars['INF_ENGINE_INCLUDE_DIRS:PATH'] = str(builderDLDT.sysrootdir / 'deployment_tools/inference_engine/include')
  328. assert os.path.exists(cmake_vars['INF_ENGINE_INCLUDE_DIRS:PATH']), cmake_vars['INF_ENGINE_INCLUDE_DIRS:PATH']
  329. ngraph_DIR = str(builderDLDT.sysrootdir / 'ngraph/cmake')
  330. if not os.path.exists(ngraph_DIR):
  331. ngraph_DIR = str(builderDLDT.sysrootdir / 'ngraph/deployment_tools/ngraph/cmake')
  332. assert os.path.exists(ngraph_DIR), ngraph_DIR
  333. cmake_vars['ngraph_DIR:PATH'] = ngraph_DIR
  334. cmake_vars['TBB_DIR:PATH'] = str(builderDLDT.sysrootdir / 'tbb/cmake')
  335. assert os.path.exists(cmake_vars['TBB_DIR:PATH']), cmake_vars['TBB_DIR:PATH']
  336. if self.config.build_debug:
  337. cmake_vars['CMAKE_BUILD_TYPE'] = 'Debug'
  338. cmake_vars['BUILD_opencv_python3'] ='OFF' # python3x_d.lib is missing
  339. cmake_vars['OPENCV_INSTALL_APPS_LIST'] = 'all'
  340. if self.config.build_tests:
  341. cmake_vars['BUILD_TESTS'] = 'ON'
  342. cmake_vars['BUILD_PERF_TESTS'] = 'ON'
  343. cmake_vars['BUILD_opencv_ts'] = 'ON'
  344. cmake_vars['INSTALL_TESTS']='ON'
  345. if self.config.build_tests_dnn:
  346. cmake_vars['BUILD_TESTS'] = 'ON'
  347. cmake_vars['BUILD_PERF_TESTS'] = 'ON'
  348. cmake_vars['BUILD_opencv_ts'] = 'ON'
  349. cmake_vars['OPENCV_BUILD_TEST_MODULES_LIST'] = 'dnn'
  350. cmake_vars['OPENCV_BUILD_PERF_TEST_MODULES_LIST'] = 'dnn'
  351. cmake_vars['INSTALL_TESTS']='ON'
  352. cmd += [ "-D%s=%s" % (k, v) for (k, v) in cmake_vars.items() if v is not None]
  353. if self.config.cmake_option:
  354. cmd += self.config.cmake_option
  355. cmd.append(str(self.src_dir))
  356. log.info('Configuring OpenCV...')
  357. execute(cmd, cwd=self.build_dir)
  358. log.info('Building OpenCV...')
  359. # build
  360. cmd = [self.cmake_path, '--build', '.', '--config', build_config, '--target', 'install',
  361. '--', '/v:n', '/m:2', '/consoleloggerparameters:NoSummary'
  362. ]
  363. execute(cmd, cwd=self.build_dir)
  364. log.info('OpenCV build/install completed')
  365. def copy_sysroot(self, builderDLDT):
  366. log.info('Copy sysroot files')
  367. copytree(builderDLDT.sysrootdir / 'bin', self.install_dir / 'bin')
  368. copytree(builderDLDT.sysrootdir / 'etc', self.install_dir / 'etc')
  369. log.info('Copy sysroot files - DONE')
  370. def package_sources(self):
  371. package_opencv = prepare_dir(self.package_dir / 'src/opencv', clean=True)
  372. package_opencv = str(package_opencv) # Python 3.5 may not handle Path
  373. execute(cmd=['git', 'clone', '-s', str(self.src_dir), '.'], cwd=str(package_opencv))
  374. for item in os.listdir(package_opencv):
  375. if str(item).startswith('.git'):
  376. rm_one(os.path.join(package_opencv, item))
  377. with open(str(self.package_dir / 'README.md'), 'w') as f:
  378. f.write('See licensing/copying statements in "build/etc/licenses"\n')
  379. f.write('Wiki page: https://github.com/opencv/opencv/wiki/Intel%27s-Deep-Learning-Inference-Engine-backend\n')
  380. log.info('Package OpenCV sources - DONE')
  381. #===================================================================================================
  382. def main():
  383. dldt_src_url = 'https://github.com/openvinotoolkit/openvino'
  384. dldt_src_commit = '2021.4.2'
  385. dldt_config = None
  386. dldt_release = None
  387. build_cache_dir_default = os.environ.get('BUILD_CACHE_DIR', '.build_cache')
  388. build_subst_drive = os.environ.get('BUILD_SUBST_DRIVE', None)
  389. parser = argparse.ArgumentParser(
  390. description='Build OpenCV Windows package with Inference Engine (DLDT)',
  391. )
  392. parser.add_argument('output_dir', nargs='?', default='.', help='Output directory')
  393. parser.add_argument('opencv_dir', nargs='?', default=os.path.join(SCRIPT_DIR, '../..'), help='Path to OpenCV source dir')
  394. parser.add_argument('--build_cache_dir', default=build_cache_dir_default, help='Build cache directory (sources and binaries cache of build dependencies, default = "%s")' % build_cache_dir_default)
  395. parser.add_argument('--build_subst_drive', default=build_subst_drive, help='Drive letter to workaround Windows limit for 260 symbols in path (error MSB3491)')
  396. parser.add_argument('--cmake_option', action='append', help='Append OpenCV CMake option')
  397. parser.add_argument('--cmake_option_dldt', action='append', help='Append CMake option for DLDT project')
  398. parser.add_argument('--clean_dldt', action='store_true', help='Clean DLDT build and sysroot directories')
  399. parser.add_argument('--clean_dldt_sysroot', action='store_true', help='Clean DLDT sysroot directories')
  400. parser.add_argument('--clean_opencv', action='store_true', help='Clean OpenCV build directory')
  401. parser.add_argument('--build_debug', action='store_true', help='Build debug binaries')
  402. parser.add_argument('--build_tests', action='store_true', help='Build OpenCV tests')
  403. parser.add_argument('--build_tests_dnn', action='store_true', help='Build OpenCV DNN accuracy and performance tests only')
  404. parser.add_argument('--dldt_src_url', default=dldt_src_url, help='DLDT source URL (tag / commit, default: %s)' % dldt_src_url)
  405. parser.add_argument('--dldt_src_branch', help='DLDT checkout branch')
  406. parser.add_argument('--dldt_src_commit', default=dldt_src_commit, help='DLDT source commit / tag (default: %s)' % dldt_src_commit)
  407. parser.add_argument('--dldt_src_git_clone_extra', action='append', help='DLDT git clone extra args')
  408. parser.add_argument('--dldt_release', default=dldt_release, help='DLDT release code for INF_ENGINE_RELEASE, e.g 2021030000 (default: %s)' % dldt_release)
  409. parser.add_argument('--dldt_reference_dir', help='DLDT reference git repository (optional)')
  410. parser.add_argument('--dldt_src_dir', help='DLDT custom source repository (skip git checkout and patching, use for TESTING only)')
  411. parser.add_argument('--dldt_config', default=dldt_config, help='Specify DLDT build configuration (defaults to evaluate from DLDT commit/branch)')
  412. parser.add_argument('--override_patch_hashsum', default='', help='(script debug mode)')
  413. args = parser.parse_args()
  414. log.basicConfig(
  415. format='%(asctime)s %(levelname)-8s %(message)s',
  416. level=os.environ.get('LOGLEVEL', 'INFO'),
  417. datefmt='%Y-%m-%d %H:%M:%S'
  418. )
  419. log.debug('Args: %s', args)
  420. if not check_executable(['git', '--version']):
  421. sys.exit("FATAL: 'git' is not available")
  422. if not check_executable(['cmake', '--version']):
  423. sys.exit("FATAL: 'cmake' is not available")
  424. if os.path.realpath(args.output_dir) == os.path.realpath(SCRIPT_DIR):
  425. raise Fail("Specify output_dir (building from script directory is not supported)")
  426. if os.path.realpath(args.output_dir) == os.path.realpath(args.opencv_dir):
  427. raise Fail("Specify output_dir (building from OpenCV source directory is not supported)")
  428. # Relative paths become invalid in sub-directories
  429. if args.opencv_dir is not None and not os.path.isabs(args.opencv_dir):
  430. args.opencv_dir = os.path.abspath(args.opencv_dir)
  431. if not args.dldt_config:
  432. if str(args.dldt_src_commit).startswith('releases/20'): # releases/2020/4
  433. args.dldt_config = str(args.dldt_src_commit)[len('releases/'):].replace('/', '.')
  434. if not args.dldt_src_branch:
  435. args.dldt_src_branch = args.dldt_src_commit
  436. elif str(args.dldt_src_branch).startswith('releases/20'): # releases/2020/4
  437. args.dldt_config = str(args.dldt_src_branch)[len('releases/'):].replace('/', '.')
  438. else:
  439. args.dldt_config = args.dldt_src_commit
  440. _opencv_dir = check_dir(args.opencv_dir)
  441. _outdir = prepare_dir(args.output_dir)
  442. _cachedir = prepare_dir(args.build_cache_dir)
  443. ocv_hooks_dir = os.environ.get('OPENCV_CMAKE_HOOKS_DIR', None)
  444. hooks_dir = os.path.join(SCRIPT_DIR, 'cmake-opencv-checks')
  445. os.environ['OPENCV_CMAKE_HOOKS_DIR'] = hooks_dir if ocv_hooks_dir is None else (hooks_dir + ';' + ocv_hooks_dir)
  446. builder_dldt = BuilderDLDT(args)
  447. try:
  448. builder_dldt.prepare_sources()
  449. builder_dldt.build()
  450. builder_dldt.make_sysroot()
  451. builder_opencv = Builder(args)
  452. builder_opencv.build(builder_dldt)
  453. builder_opencv.copy_sysroot(builder_dldt)
  454. builder_opencv.package_sources()
  455. except:
  456. builder_dldt.cleanup()
  457. raise
  458. log.info("=====")
  459. log.info("===== Build finished")
  460. log.info("=====")
  461. if __name__ == "__main__":
  462. try:
  463. main()
  464. except:
  465. log.info('FATAL: Error occurred. To investigate problem try to change logging level using LOGLEVEL=DEBUG environment variable.')
  466. raise