OLD | NEW |
---|---|
(Empty) | |
1 #!/usr/bin/env python | |
2 # Copyright 2017 The Chromium Authors. All rights reserved. | |
3 # Use of this source code is governed by a BSD-style license that can be | |
4 # found in the LICENSE file. | |
5 """A script to compile the integration tests with llvm's clang, | |
6 instrument the code with llvm's Asan, and link it to the syzyasan_rtl | |
7 runtime environment. | |
8 """ | |
9 | |
10 import optparse | |
11 import os | |
12 import re | |
13 import subprocess | |
14 import sys | |
15 | |
16 | |
17 _SCRIPT_DIR = os.path.dirname(os.path.realpath(__file__)) | |
18 _SRC_DIR = os.path.abspath(os.path.join(_SCRIPT_DIR, os.pardir, os.pardir)) | |
19 _CLANG_CL_PATH = os.path.join(_SRC_DIR, | |
20 'third_party', 'llvm-build', 'Release+Asserts', 'bin', 'clang-cl.exe') | |
21 | |
Sébastien Marchand
2017/07/06 20:28:58
Add another BL here.
njanevsk
2017/07/06 20:36:42
Done.
| |
22 def compile_with_asan(clang_path, source_files, src_dir, object_files, | |
23 target_name): | |
24 """Only compiles with clang but does not link. | |
Sébastien Marchand
2017/07/06 20:28:57
Drop the "Only", here and below (and update the se
njanevsk
2017/07/06 20:36:42
Done.
| |
25 | |
26 Only compiles the files and isntruments them with LLVM's Asan but does not | |
Sébastien Marchand
2017/07/06 20:28:57
instruments, not isntruments :)
njanevsk
2017/07/06 20:36:42
Done.
| |
27 link them. The linking is done separately in the method link. | |
28 | |
29 Args: | |
30 clang_path: Path to the clang-cl compiler. | |
31 source_files: The source files to be compiled. | |
32 src_dir: The repository where the syzgy src is located. | |
Sébastien Marchand
2017/07/06 20:28:58
s/syzgy/syzygy/
njanevsk
2017/07/06 20:36:42
Done.
| |
33 object_files: The path where each object file should be generated. | |
34 target_name: The name of the target being build. | |
35 """ | |
36 | |
37 compiler_flags = [ | |
38 '-c', | |
39 '-m32', | |
40 '-fsanitize=address', | |
41 '-mllvm', | |
42 '-asan-instrumentation-with-call-threshold=0', | |
43 '-mllvm', | |
44 '-asan-stack=0', | |
45 '-DUNICODE', | |
46 '-D_UNICODE', | |
47 '-DNOMINMAX', | |
48 '-D_CRT_SECURE_NO_WARNINGS', | |
49 '-I', | |
50 src_dir, | |
51 ] | |
52 | |
53 compile_command_base = [clang_path] | |
54 compile_command_base.extend(compiler_flags) | |
55 | |
56 for source_file, object_file in zip(source_files, object_files): | |
57 compile_command = [compile_command_base, source_file, '-o', object_files] | |
58 | |
59 ret = subprocess.call(compile_command) | |
60 if ret != 0: | |
61 print 'ERROR: Failed compiling %s using clang-cl.' % target_name | |
62 return ret | |
63 return ret | |
64 | |
Sébastien Marchand
2017/07/06 20:28:57
Add a BL
njanevsk
2017/07/06 20:36:42
Done.
| |
65 def link(clang_path, object_files, build_dir, target_name): | |
66 """ Links the object files and produces the integration_tests_clang_dll.dll. | |
67 | |
Sébastien Marchand
2017/07/06 20:28:58
Remove one of these BLs
njanevsk
2017/07/06 20:36:42
Done.
| |
68 | |
69 Links the object files and produces the dll. The object files have to be | |
70 produced by the compile method above. | |
71 | |
72 Args: | |
73 clang_path: Path to the clang-cl compiler in the syzygy project. | |
74 source_files: The source file names which are converted to obj filenames. | |
75 build_dir: The directory where to produce the linked dll. | |
76 target_name: The name of the target being build. | |
77 """ | |
78 | |
79 linker_flags = [ | |
80 '-o', | |
81 os.path.join(build_dir, target_name + '.dll'), | |
82 '/link', | |
83 '/dll', | |
84 build_dir + '\export_dll.dll.lib', | |
85 build_dir + '\syzyasan_rtl.dll.lib', | |
86 '-defaultlib:libcmt' | |
87 ] | |
88 | |
89 linker_command = [clang_path, '-m32'] | |
90 linker_command.extend(object_files) | |
91 linker_command.extend(linker_flags) | |
92 ret = subprocess.call(linker_command) | |
93 | |
94 if ret != 0: | |
95 print 'ERROR: Failed to link %s using clang-cl.' % target_name | |
96 return ret | |
97 | |
98 | |
99 def main(): | |
100 parser = optparse.OptionParser(usage='%prog [options]') | |
101 parser.add_option('--output-dir', | |
102 help='Path to the Syzygy Release directory.') | |
103 parser.add_option('--input-files', help='Files to be compiled and linked.') | |
104 parser.add_option('--target-name', help='Name of the target to be compiled.') | |
105 | |
106 options, _ = parser.parse_args() | |
107 | |
108 if not options.output_dir: | |
109 parser.error('--output-dir is required.') | |
110 if not options.input_files: | |
111 parser.error('--input-files is required.') | |
112 if not options.target_name: | |
113 parser.error('--target-name is required.') | |
114 | |
115 def get_object_file_location(source_file, | |
116 output_dir, target_name): | |
117 return os.path.join(output_dir, 'obj', | |
118 os.path.split(os.path.relpath(source_file, | |
119 _SRC_DIR))[0], | |
120 '%s.%s.obj' % (target_name, | |
121 os.path.splitext(os.path.basename(source_file))[0]) | |
122 | |
123 source_files = options.input_files.split() | |
124 object_files = [] | |
125 | |
126 for source_file in source_files: | |
127 object_files.append(get_object_file_location(source_file, | |
128 options.output_dir, | |
129 options.target_name)) | |
130 | |
131 ret = compile_with_asan(_CLANG_CL_PATH, source_files, _SRC_DIR, | |
132 object_files, options.target_name) | |
133 | |
134 if ret == 0: | |
135 ret = link(_CLANG_CL_PATH, object_files, options.output_dir, | |
136 options.target_name) | |
137 else: | |
138 print ('ERROR: Compilation of %s failed, skipping link step.' | |
139 % options.target_name) | |
140 | |
141 return ret | |
142 | |
143 | |
144 if __name__ == '__main__': | |
145 sys.exit(main()) | |
OLD | NEW |