Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / third_party / chromite / lib / unittest_lib.py
1 # Copyright 2014 The Chromium OS Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file.
4
5 """Unittest-only utility functions library."""
6
7 from __future__ import print_function
8
9 import os
10
11 from chromite.lib import cros_build_lib
12 from chromite.lib import osutils
13
14
15 class BuildELFError(Exception):
16   """Generic error building an ELF file."""
17
18
19 def BuildELF(filename, defined_symbols=None, undefined_symbols=None,
20              used_libs=None, executable=False, static=False):
21   """Builds a dynamic ELF with the provided import and exports.
22
23   Compiles and links a dynamic program that exports some functions, as libraries
24   do, and requires some symbols from other libraries. Dependencies shoud live
25   in the same directory as the result. This function
26
27   Args:
28     filename: The output filename where the ELF is created.
29     defined_symbols: The list of symbols this ELF exports.
30     undefined_symbols: The list of symbols this ELF requires from other ELFs.
31     used_libs: The list of libraries this ELF loads dynamically, including only
32         the name of the library. For example, 'bz2' rather than 'libbz2.so.1.0'.
33     executable: Whether the file has a main() function.
34     static: Whether the file is statically linked (implies executable=True).
35   """
36   if defined_symbols is None:
37     defined_symbols = []
38   if undefined_symbols is None:
39     undefined_symbols = []
40   if used_libs is None:
41     used_libs = []
42   if static and not executable:
43     raise ValueError('static requires executable to be True.')
44
45   source = ''.join('void %s();\n' % sym for sym in undefined_symbols)
46   source += """
47 void __defined_symbols(const char*) __attribute__ ((visibility ("hidden")));
48 void __defined_symbols(const char* sym) {
49   %s
50 }
51 """ % ('\n  '.join('%s();' % sym for sym in undefined_symbols))
52
53   source += ''.join("""
54 void %s() __attribute__ ((visibility ("default")));
55 void %s() { __defined_symbols("%s"); }
56 """ % (sym, sym, sym) for sym in defined_symbols)
57
58   if executable:
59     source += """
60 int main() {
61   __defined_symbols("main");
62   return 42;
63 }
64 """
65   source_fn = filename + '_tmp.c'
66   osutils.WriteFile(source_fn, source)
67
68   outdir = os.path.dirname(filename)
69   cmd = ['gcc', '-o', filename, source_fn]
70   if not executable:
71     cmd += ['-shared', '-fPIC']
72   if static:
73     cmd += ['-static']
74   cmd += ['-L.', '-Wl,-rpath=./']
75   cmd += ['-l%s' % lib for lib in used_libs]
76   try:
77     cros_build_lib.RunCommand(
78         cmd, cwd=outdir, redirect_stdout=True, redirect_stderr=True,
79         print_cmd=False)
80   except cros_build_lib.RunCommandError, e:
81     raise BuildELFError('%s\n%s' % (e.message, e.result.error))
82   finally:
83     os.unlink(source_fn)