aboutsummaryrefslogtreecommitdiffstats
path: root/build/scripts/custom_link_green_mysql.py
blob: 81d57b1f1183ad79931a7f5748f4d3be7dc357d7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import os 
import shutil 
import subprocess 
import sys 
import tempfile 
 
 
SYMBOLS_TO_PATCH = ( 
    'connect', 
    'poll', 
    'recv', 
    'recvfrom', 
    'send', 
    'sendto', 
) 
 
class Error(Exception): 
    pass 
 
 
def find_compiler(args): 
    for arg in args: 
        if os.path.basename(arg) in ('clang', 'clang++'): 
            return arg 
    raise Error('No known compiler found in the command line') 
 
 
def find_libraries(project, args): 
    if not project.endswith('/'): 
        project = project + '/' 
 
    for arg in args: 
        if arg.startswith(project): 
            yield arg 
 
 
def rename_symbol(symbol): 
    return 'green_{}'.format(symbol) 
 
 
def patch_object(object_path, objcopy): 
    args = [objcopy] 
    for symbol in SYMBOLS_TO_PATCH: 
        args.extend(('--redefine-sym', '{}={}'.format(symbol, rename_symbol(symbol)))) 
    args.append(object_path) 
    subprocess.check_call(args) 
 
 
def patch_library(library_path, ar, objcopy): 
    tmpdir = tempfile.mkdtemp(dir=os.path.dirname(library_path)) 
    try: 
        subprocess.check_call((ar, 'x', library_path), cwd=tmpdir) 
        names = os.listdir(tmpdir) 
        for name in names: 
            patch_object(os.path.join(tmpdir, name), objcopy=objcopy) 
 
        new_library_path = os.path.join(tmpdir, 'library.a') 
        subprocess.check_call([ar, 'rcs', new_library_path] + names, cwd=tmpdir) 
 
        os.rename(new_library_path, library_path) 
 
    finally: 
        shutil.rmtree(tmpdir) 
 
 
def main(): 
    try: 
        args = sys.argv[1:] 
        compiler = find_compiler(args) 
        compiler_dir = os.path.dirname(compiler) 
 
        def get_tool(name): 
            path = os.path.join(compiler_dir, name) 
            if not os.path.exists(path): 
                raise Error('No {} found alongside the compiler'.format(name)) 
            return path 
 
        ar = get_tool('llvm-ar') 
        objcopy = get_tool('llvm-objcopy') 
 
        libraries = tuple(find_libraries('contrib/libs/libmysql_r', args)) 
        for library in libraries: 
            library_path = os.path.abspath(library) 
            if not os.path.exists(library_path): 
                raise Error('No {} file exists'.format(library)) 
 
            patch_library(library_path, ar=ar, objcopy=objcopy) 
 
    except Exception as error: 
        name = os.path.basename(sys.argv[0]) 
        command = ' '.join(args) 
        message = '{name} failed: {error}\nCommand line: {command}' 
        print >> sys.stderr, message.format(**locals()) 
 
 
if __name__ == '__main__': 
    main()