~paparazzi-uav/paparazzi/v5.0-manual

« back to all changes in this revision

Viewing changes to sw/ext/opencv_bebop/opencv/modules/ts/misc/run_utils.py

  • Committer: Paparazzi buildbot
  • Date: 2016-05-18 15:00:29 UTC
  • Revision ID: felix.ruess+docbot@gmail.com-20160518150029-e8lgzi5kvb4p7un9
Manual import commit 4b8bbb730080dac23cf816b98908dacfabe2a8ec from v5.0 branch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/bin/env python
 
2
 
 
3
import sys, os, platform, re, tempfile, glob, getpass, logging
 
4
from subprocess import check_call, check_output, CalledProcessError, STDOUT
 
5
 
 
6
hostos = os.name # 'nt', 'posix'
 
7
hostmachine = platform.machine() # 'x86', 'AMD64', 'x86_64'
 
8
 
 
9
def initLogger():
 
10
    l = logging.getLogger("run.py")
 
11
    l.setLevel(logging.DEBUG)
 
12
    ch = logging.StreamHandler(sys.stderr)
 
13
    ch.setFormatter(logging.Formatter("%(message)s"))
 
14
    l.addHandler(ch)
 
15
    return l
 
16
 
 
17
log = initLogger()
 
18
 
 
19
#===================================================================================================
 
20
 
 
21
class Err(Exception):
 
22
    def __init__(self, msg, *args):
 
23
        self.msg = msg % args
 
24
 
 
25
def execute(cmd, silent = False, cwd = "."):
 
26
    try:
 
27
        log.debug("Run: %s", cmd)
 
28
        if silent:
 
29
            return check_output(cmd, stderr = STDOUT, cwd = cwd).decode("latin-1")
 
30
        else:
 
31
            return check_call(cmd, cwd = cwd)
 
32
    except CalledProcessError as e:
 
33
        if silent:
 
34
            log.debug("Process returned: %d", e.returncode)
 
35
            return e.output.decode("latin-1")
 
36
        else:
 
37
            log.error("Process returned: %d", e.returncode)
 
38
            return e.returncode
 
39
 
 
40
def isColorEnabled(args):
 
41
    usercolor = [a for a in args if a.startswith("--gtest_color=")]
 
42
    return len(usercolor) == 0 and sys.stdout.isatty() and hostos != "nt"
 
43
 
 
44
#===================================================================================================
 
45
 
 
46
def getPlatformVersion():
 
47
    mv = platform.mac_ver()
 
48
    if mv[0]:
 
49
        return "Darwin" + mv[0]
 
50
    else:
 
51
        wv = platform.win32_ver()
 
52
        if wv[0]:
 
53
            return "Windows" + wv[0]
 
54
        else:
 
55
            lv = platform.linux_distribution()
 
56
            if lv[0]:
 
57
                return lv[0] + lv[1]
 
58
    return None
 
59
 
 
60
def readGitVersion(git, path):
 
61
    if not path or not git or not os.path.isdir(os.path.join(path, ".git")):
 
62
        return None
 
63
    try:
 
64
        output = execute([git, "-C", path, "rev-parse", "--short", "HEAD"], silent = True)
 
65
        return output.strip()
 
66
    except OSError:
 
67
        log.warning("Git version read failed")
 
68
        return None
 
69
 
 
70
SIMD_DETECTION_PROGRAM="""
 
71
#if __SSE5__
 
72
# error SSE5
 
73
#endif
 
74
#if __AVX2__
 
75
# error AVX2
 
76
#endif
 
77
#if __AVX__
 
78
# error AVX
 
79
#endif
 
80
#if __SSE4_2__
 
81
# error SSE4.2
 
82
#endif
 
83
#if __SSE4_1__
 
84
# error SSE4.1
 
85
#endif
 
86
#if __SSSE3__
 
87
# error SSSE3
 
88
#endif
 
89
#if __SSE3__
 
90
# error SSE3
 
91
#endif
 
92
#if __AES__
 
93
# error AES
 
94
#endif
 
95
#if __SSE2__
 
96
# error SSE2
 
97
#endif
 
98
#if __SSE__
 
99
# error SSE
 
100
#endif
 
101
#if __3dNOW__
 
102
# error 3dNOW
 
103
#endif
 
104
#if __MMX__
 
105
# error MMX
 
106
#endif
 
107
#if __ARM_NEON__
 
108
# error NEON
 
109
#endif
 
110
#error NOSIMD
 
111
"""
 
112
 
 
113
def testSIMD(compiler, cxx_flags, compiler_arg = None):
 
114
    if not compiler:
 
115
        return None
 
116
    compiler_output = ""
 
117
    try:
 
118
        _, tmpfile = tempfile.mkstemp(suffix=".cpp", text = True)
 
119
        with open(tmpfile, "w+") as fd:
 
120
            fd.write(SIMD_DETECTION_PROGRAM)
 
121
        options = [compiler]
 
122
        if compiler_arg:
 
123
            options.append(compiler_arg)
 
124
 
 
125
        prev_option = None
 
126
        for opt in " ".join(cxx_flags).split():
 
127
            if opt.count('\"') % 2 == 1:
 
128
                if prev_option is None:
 
129
                     prev_option = opt
 
130
                else:
 
131
                     options.append(prev_option + " " + opt)
 
132
                     prev_option = None
 
133
            elif prev_option is None:
 
134
                options.append(opt)
 
135
            else:
 
136
                prev_option = prev_option + " " + opt
 
137
        options.append(tmpfile)
 
138
        compiler_output = execute(options, silent = True)
 
139
        os.remove(tmpfile)
 
140
        m = re.search("#error\W+(\w+)", compiler_output)
 
141
        if m:
 
142
            return m.group(1)
 
143
    except OSError:
 
144
        pass
 
145
    log.debug("SIMD detection failed")
 
146
    return None
 
147
 
 
148
#==============================================================================
 
149
 
 
150
parse_patterns = (
 
151
    {'name': "cmake_home",               'default': None,       'pattern': re.compile(r"^CMAKE_HOME_DIRECTORY:INTERNAL=(.+)$")},
 
152
    {'name': "opencv_home",              'default': None,       'pattern': re.compile(r"^OpenCV_SOURCE_DIR:STATIC=(.+)$")},
 
153
    {'name': "opencv_build",             'default': None,       'pattern': re.compile(r"^OpenCV_BINARY_DIR:STATIC=(.+)$")},
 
154
    {'name': "tests_dir",                'default': None,       'pattern': re.compile(r"^EXECUTABLE_OUTPUT_PATH:PATH=(.+)$")},
 
155
    {'name': "build_type",               'default': "Release",  'pattern': re.compile(r"^CMAKE_BUILD_TYPE:\w+=(.*)$")},
 
156
    {'name': "git_executable",           'default': None,       'pattern': re.compile(r"^GIT_EXECUTABLE:FILEPATH=(.*)$")},
 
157
    {'name': "cxx_flags",                'default': "",         'pattern': re.compile(r"^CMAKE_CXX_FLAGS:STRING=(.*)$")},
 
158
    {'name': "cxx_flags_debug",          'default': "",         'pattern': re.compile(r"^CMAKE_CXX_FLAGS_DEBUG:STRING=(.*)$")},
 
159
    {'name': "cxx_flags_release",        'default': "",         'pattern': re.compile(r"^CMAKE_CXX_FLAGS_RELEASE:STRING=(.*)$")},
 
160
    {'name': "opencv_cxx_flags",         'default': "",         'pattern': re.compile(r"^OPENCV_EXTRA_C_FLAGS:INTERNAL=(.*)$")},
 
161
    {'name': "cxx_flags_android",        'default': None,       'pattern': re.compile(r"^ANDROID_CXX_FLAGS:INTERNAL=(.*)$")},
 
162
    {'name': "android_abi",              'default': None,       'pattern': re.compile(r"^ANDROID_ABI:STRING=(.*)$")},
 
163
    {'name': "android_executable",       'default': None,       'pattern': re.compile(r"^ANDROID_EXECUTABLE:FILEPATH=(.*android.*)$")},
 
164
    {'name': "ant_executable",           'default': None,       'pattern': re.compile(r"^ANT_EXECUTABLE:FILEPATH=(.*ant.*)$")},
 
165
    {'name': "java_test_binary_dir",     'default': None,       'pattern': re.compile(r"^opencv_test_java_BINARY_DIR:STATIC=(.*)$")},
 
166
    {'name': "is_x64",                   'default': "OFF",      'pattern': re.compile(r"^CUDA_64_BIT_DEVICE_CODE:BOOL=(ON)$")},#ugly(
 
167
    {'name': "cmake_generator",          'default': None,       'pattern': re.compile(r"^CMAKE_GENERATOR:INTERNAL=(.+)$")},
 
168
    {'name': "cxx_compiler",             'default': None,       'pattern': re.compile(r"^CMAKE_CXX_COMPILER:\w*PATH=(.+)$")},
 
169
    {'name': "cxx_compiler_arg1",        'default': None,       'pattern': re.compile(r"^CMAKE_CXX_COMPILER_ARG1:[A-Z]+=(.+)$")},
 
170
    {'name': "with_cuda",                'default': "OFF",      'pattern': re.compile(r"^WITH_CUDA:BOOL=(ON)$")},
 
171
    {'name': "cuda_library",             'default': None,       'pattern': re.compile(r"^CUDA_CUDA_LIBRARY:FILEPATH=(.+)$")},
 
172
    {'name': "cuda_version",             'default': None,       'pattern': re.compile(r"^CUDA_VERSION:STRING=(.+)$")},
 
173
    {'name': "core_dependencies",        'default': None,       'pattern': re.compile(r"^opencv_core_LIB_DEPENDS:STATIC=(.+)$")},
 
174
)
 
175
 
 
176
class CMakeCache:
 
177
    def __init__(self, cfg = None):
 
178
        self.setDefaultAttrs()
 
179
        self.cmake_home_vcver = None
 
180
        self.opencv_home_vcver = None
 
181
        self.featuresSIMD = None
 
182
        self.main_modules = []
 
183
        if cfg:
 
184
            self.build_type = cfg
 
185
 
 
186
    def setDummy(self, path):
 
187
        self.tests_dir = os.path.normpath(path)
 
188
 
 
189
    def read(self, path, fname):
 
190
        rx = re.compile(r'^opencv_(\w+)_SOURCE_DIR:STATIC=(.*)$')
 
191
        module_paths = {} # name -> path
 
192
        with open(fname, "rt") as cachefile:
 
193
            for l in cachefile.readlines():
 
194
                ll = l.strip()
 
195
                if not ll or ll.startswith("#"):
 
196
                    continue
 
197
                for p in parse_patterns:
 
198
                    match = p["pattern"].match(ll)
 
199
                    if match:
 
200
                        value = match.groups()[0]
 
201
                        if value and not value.endswith("-NOTFOUND"):
 
202
                            setattr(self, p["name"], value)
 
203
                            # log.debug("cache value: %s = %s", p["name"], value)
 
204
 
 
205
                match = rx.search(ll)
 
206
                if match:
 
207
                    module_paths[match.group(1)] = match.group(2)
 
208
 
 
209
        if not self.tests_dir:
 
210
            self.tests_dir = path
 
211
        else:
 
212
            rel = os.path.relpath(self.tests_dir, self.opencv_build)
 
213
            self.tests_dir = os.path.join(path, rel)
 
214
        self.tests_dir = os.path.normpath(self.tests_dir)
 
215
 
 
216
        # fix VS test binary path (add Debug or Release)
 
217
        if "Visual Studio" in self.cmake_generator:
 
218
            self.tests_dir = os.path.join(self.tests_dir, self.build_type)
 
219
 
 
220
        self.cmake_home_vcver = readGitVersion(self.git_executable, self.cmake_home)
 
221
        if self.opencv_home == self.cmake_home:
 
222
            self.opencv_home_vcver = self.cmake_home_vcver
 
223
        else:
 
224
            self.opencv_home_vcver = readGitVersion(self.git_executable, self.opencv_home)
 
225
 
 
226
        for module,path in module_paths.items():
 
227
            rel = os.path.relpath(path, self.opencv_home)
 
228
            if not ".." in rel:
 
229
                self.main_modules.append(module)
 
230
 
 
231
        self.flags = [
 
232
            self.cxx_flags_android,
 
233
            self.cxx_flags,
 
234
            self.cxx_flags_release,
 
235
            self.opencv_cxx_flags,
 
236
            self.cxx_flags_release]
 
237
        self.flags = [f for f in self.flags if f]
 
238
        self.featuresSIMD = testSIMD(self.cxx_compiler, self.flags, self.cxx_compiler_arg1)
 
239
 
 
240
    def setDefaultAttrs(self):
 
241
        for p in parse_patterns:
 
242
            setattr(self, p["name"], p["default"])
 
243
 
 
244
    def gatherTests(self, mask, isGood = None):
 
245
        if self.tests_dir and os.path.isdir(self.tests_dir):
 
246
            d = os.path.abspath(self.tests_dir)
 
247
            files = glob.glob(os.path.join(d, mask))
 
248
            if not self.getOS() == "android" and self.withJava():
 
249
                files.append("java")
 
250
            return [f for f in files if isGood(f)]
 
251
        return []
 
252
 
 
253
    def isMainModule(self, name):
 
254
        return name in self.main_modules
 
255
 
 
256
    def withCuda(self):
 
257
        return self.cuda_version and self.with_cuda == "ON" and self.cuda_library and not self.cuda_library.endswith("-NOTFOUND")
 
258
 
 
259
    def withJava(self):
 
260
        return self.ant_executable and self.java_test_binary_dir
 
261
 
 
262
    def getGitVersion(self):
 
263
        if self.cmake_home_vcver:
 
264
            if self.cmake_home_vcver == self.opencv_home_vcver:
 
265
                rev = self.cmake_home_vcver
 
266
            elif self.opencv_home_vcver:
 
267
                rev = self.cmake_home_vcver + "-" + self.opencv_home_vcver
 
268
            else:
 
269
                rev = self.cmake_home_vcver
 
270
        else:
 
271
            rev = None
 
272
        if rev:
 
273
            rev = rev.replace(":","to")
 
274
        else:
 
275
            rev = ""
 
276
        return rev
 
277
 
 
278
    def getTestFullName(self, shortname):
 
279
        return os.path.join(self.tests_dir, shortname)
 
280
 
 
281
    def getSIMDFeatures(self):
 
282
        return self.featuresSIMD
 
283
 
 
284
    def getOS(self):
 
285
        if self.android_executable:
 
286
            return "android"
 
287
        else:
 
288
            return hostos
 
289
 
 
290
    def getArch(self):
 
291
        arch = "unknown"
 
292
        if self.getOS() == "android":
 
293
            if "armeabi-v7a" in self.android_abi:
 
294
                arch = "armv7a"
 
295
            elif "armeabi-v6" in self.android_abi:
 
296
                arch = "armv6"
 
297
            elif "armeabi" in self.android_abi:
 
298
                arch = "armv5te"
 
299
            elif "x86" in self.android_abi:
 
300
                arch = "x86"
 
301
            elif "mips" in self.android_abi:
 
302
                arch = "mips"
 
303
            else:
 
304
                arch = "ARM"
 
305
        elif self.is_x64 and hostmachine in ["AMD64", "x86_64"]:
 
306
            arch = "x64"
 
307
        elif hostmachine in ["x86", "AMD64", "x86_64"]:
 
308
            arch = "x86"
 
309
        return arch
 
310
 
 
311
    def getDependencies(self):
 
312
        if self.core_dependencies:
 
313
            candidates = ["tbb", "ippicv", "ipp", "pthreads"]
 
314
            return [a for a in self.core_dependencies.split(";") if a and a in candidates]
 
315
        return []
 
316
 
 
317
 
 
318
#==============================================================================
 
319
 
 
320
def getRunningProcessExePathByName_win32(name):
 
321
    from ctypes import windll, POINTER, pointer, Structure, sizeof
 
322
    from ctypes import c_long , c_int , c_uint , c_char , c_ubyte , c_char_p , c_void_p
 
323
 
 
324
    class PROCESSENTRY32(Structure):
 
325
        _fields_ = [ ( 'dwSize' , c_uint ) ,
 
326
                    ( 'cntUsage' , c_uint) ,
 
327
                    ( 'th32ProcessID' , c_uint) ,
 
328
                    ( 'th32DefaultHeapID' , c_uint) ,
 
329
                    ( 'th32ModuleID' , c_uint) ,
 
330
                    ( 'cntThreads' , c_uint) ,
 
331
                    ( 'th32ParentProcessID' , c_uint) ,
 
332
                    ( 'pcPriClassBase' , c_long) ,
 
333
                    ( 'dwFlags' , c_uint) ,
 
334
                    ( 'szExeFile' , c_char * 260 ) ,
 
335
                    ( 'th32MemoryBase' , c_long) ,
 
336
                    ( 'th32AccessKey' , c_long ) ]
 
337
 
 
338
    class MODULEENTRY32(Structure):
 
339
        _fields_ = [ ( 'dwSize' , c_long ) ,
 
340
                    ( 'th32ModuleID' , c_long ),
 
341
                    ( 'th32ProcessID' , c_long ),
 
342
                    ( 'GlblcntUsage' , c_long ),
 
343
                    ( 'ProccntUsage' , c_long ) ,
 
344
                    ( 'modBaseAddr' , c_long ) ,
 
345
                    ( 'modBaseSize' , c_long ) ,
 
346
                    ( 'hModule' , c_void_p ) ,
 
347
                    ( 'szModule' , c_char * 256 ),
 
348
                    ( 'szExePath' , c_char * 260 ) ]
 
349
 
 
350
    TH32CS_SNAPPROCESS = 2
 
351
    TH32CS_SNAPMODULE = 0x00000008
 
352
 
 
353
    ## CreateToolhelp32Snapshot
 
354
    CreateToolhelp32Snapshot= windll.kernel32.CreateToolhelp32Snapshot
 
355
    CreateToolhelp32Snapshot.reltype = c_long
 
356
    CreateToolhelp32Snapshot.argtypes = [ c_int , c_int ]
 
357
    ## Process32First
 
358
    Process32First = windll.kernel32.Process32First
 
359
    Process32First.argtypes = [ c_void_p , POINTER( PROCESSENTRY32 ) ]
 
360
    Process32First.rettype = c_int
 
361
    ## Process32Next
 
362
    Process32Next = windll.kernel32.Process32Next
 
363
    Process32Next.argtypes = [ c_void_p , POINTER(PROCESSENTRY32) ]
 
364
    Process32Next.rettype = c_int
 
365
    ## CloseHandle
 
366
    CloseHandle = windll.kernel32.CloseHandle
 
367
    CloseHandle.argtypes = [ c_void_p ]
 
368
    CloseHandle.rettype = c_int
 
369
    ## Module32First
 
370
    Module32First = windll.kernel32.Module32First
 
371
    Module32First.argtypes = [ c_void_p , POINTER(MODULEENTRY32) ]
 
372
    Module32First.rettype = c_int
 
373
 
 
374
    hProcessSnap = c_void_p(0)
 
375
    hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS , 0 )
 
376
 
 
377
    pe32 = PROCESSENTRY32()
 
378
    pe32.dwSize = sizeof( PROCESSENTRY32 )
 
379
    ret = Process32First( hProcessSnap , pointer( pe32 ) )
 
380
    path = None
 
381
 
 
382
    while ret :
 
383
        if name + ".exe" == pe32.szExeFile:
 
384
            hModuleSnap = c_void_p(0)
 
385
            me32 = MODULEENTRY32()
 
386
            me32.dwSize = sizeof( MODULEENTRY32 )
 
387
            hModuleSnap = CreateToolhelp32Snapshot( TH32CS_SNAPMODULE, pe32.th32ProcessID )
 
388
 
 
389
            ret = Module32First( hModuleSnap, pointer(me32) )
 
390
            path = me32.szExePath
 
391
            CloseHandle( hModuleSnap )
 
392
            if path:
 
393
                break
 
394
        ret = Process32Next( hProcessSnap, pointer(pe32) )
 
395
    CloseHandle( hProcessSnap )
 
396
    return path
 
397
 
 
398
 
 
399
def getRunningProcessExePathByName_posix(name):
 
400
    pids= [pid for pid in os.listdir('/proc') if pid.isdigit()]
 
401
    for pid in pids:
 
402
        try:
 
403
            path = os.readlink(os.path.join('/proc', pid, 'exe'))
 
404
            if path and path.endswith(name):
 
405
                return path
 
406
        except:
 
407
            pass
 
408
 
 
409
def getRunningProcessExePathByName(name):
 
410
    try:
 
411
        if hostos == "nt":
 
412
            return getRunningProcessExePathByName_win32(name)
 
413
        elif hostos == "posix":
 
414
            return getRunningProcessExePathByName_posix(name)
 
415
        else:
 
416
            return None
 
417
    except:
 
418
        return None
 
419
 
 
420
 
 
421
class TempEnvDir:
 
422
    def __init__(self, envname, prefix):
 
423
        self.envname = envname
 
424
        self.prefix = prefix
 
425
        self.saved_name = None
 
426
        self.new_name = None
 
427
 
 
428
    def init(self):
 
429
        self.saved_name = os.environ.get(self.envname)
 
430
        self.new_name = tempfile.mkdtemp(prefix=self.prefix, dir=self.saved_name or None)
 
431
        os.environ[self.envname] = self.new_name
 
432
 
 
433
    def clean(self):
 
434
        if self.saved_name:
 
435
            os.environ[self.envname] = self.saved_name
 
436
        else:
 
437
            del os.environ[self.envname]
 
438
        try:
 
439
            shutil.rmtree(self.new_name)
 
440
        except:
 
441
            pass
 
442
 
 
443
#===================================================================================================
 
444
 
 
445
if __name__ == "__main__":
 
446
    log.error("This is utility file, please execute run.py script")