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