Chromium Code Reviews| 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") | |
|
Sébastien Marchand
2017/07/06 15:41:35
Use ' rather than ". Both works but we tend to pre
| |
| 21 | |
| 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. | |
| 25 | |
| 26 Only compiles the files and isntruments them with LLVM's Asan but does not | |
| 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. | |
| 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 = [clang_path] | |
| 54 compile_command.extend(compiler_flags) | |
| 55 | |
| 56 for source_file, object_file in zip(source_files, object_files): | |
| 57 # Needed to get back the original list for each file that is being compiled. | |
| 58 command_len = len(compile_command) | |
|
Sébastien Marchand
2017/07/06 15:41:35
Add a new variable called compile_command_base (or
| |
| 59 compile_command.append(source_file) | |
| 60 compile_command.append('-o') | |
| 61 compile_command.append(object_file) | |
| 62 | |
| 63 ret = subprocess.call(compile_command) | |
| 64 if ret != 0: | |
| 65 print ("ERROR: Failed compiling %s using clang-cl" % target_name) | |
|
Sébastien Marchand
2017/07/06 15:41:34
The parenthesis aren't needed, use ' rather than "
| |
| 66 return ret | |
| 67 compile_command = compile_command[:command_len] | |
| 68 return ret | |
| 69 | |
| 70 def link(clang_path, object_files, build_dir, target_name): | |
| 71 """ Links the object files and produces the integration_tests_clang_dll.dll. | |
| 72 | |
| 73 | |
| 74 Links the object files and produces the dll. The object files have to be | |
| 75 produced by the compile method above. | |
| 76 | |
| 77 Args: | |
| 78 clang_path: Path to the clang-cl compiler in the syzygy project. | |
| 79 source_files: The source file names which are converted to obj filenames. | |
| 80 build_dir: The directory where to produce the linked dll. | |
| 81 target_name: The name of the target being build. | |
| 82 """ | |
| 83 | |
| 84 linker_flags = [ | |
| 85 '-o', | |
| 86 os.path.join(build_dir, target_name + '.dll'), | |
| 87 '/link', | |
| 88 '/dll', | |
| 89 build_dir + '\export_dll.dll.lib', | |
| 90 build_dir + '\syzyasan_rtl.dll.lib', | |
| 91 '-defaultlib:libcmt' | |
| 92 ] | |
| 93 | |
| 94 linker_command = [clang_path, '-m32'] | |
| 95 linker_command.extend(object_files) | |
| 96 linker_command.extend(linker_flags) | |
| 97 ret = subprocess.call(linker_command) | |
| 98 | |
| 99 if ret != 0: | |
| 100 print ("ERROR: Failed to link %s using clang-cl" % target_name) | |
|
Sébastien Marchand
2017/07/06 15:41:34
Ditto, no parenthesis and s/"/'/
| |
| 101 return ret | |
| 102 | |
| 103 | |
| 104 def main(): | |
| 105 parser = optparse.OptionParser(usage='%prog [options]') | |
| 106 parser.add_option('--output-dir', | |
| 107 help='Path to the Syzygy Release directory.') | |
| 108 parser.add_option('--input-files', help='files to be compiled and linked') | |
|
Sébastien Marchand
2017/07/06 15:41:34
Use full sentences here, starting with an uppercas
| |
| 109 parser.add_option('--target-name', help='name of the target to be compiled') | |
|
Sébastien Marchand
2017/07/06 15:41:34
Ditto.
| |
| 110 | |
| 111 options, _ = parser.parse_args() | |
| 112 | |
| 113 if not options.output_dir: | |
| 114 parser.error('--output-dir is required') | |
|
Sébastien Marchand
2017/07/06 15:41:34
Ditto, add a period (here and below).
| |
| 115 if not options.input_files: | |
| 116 parser.error('--input-files is required') | |
| 117 if not options.target_name: | |
| 118 parser.error('--target-name is required') | |
| 119 | |
| 120 def get_object_file_location(source_file, | |
| 121 output_dir, target_name): | |
| 122 return os.path.join(output_dir, 'obj', | |
| 123 os.path.split(os.path.relpath(source_file, | |
| 124 _SRC_DIR))[0], | |
| 125 target_name + '.%s.obj' % | |
|
Sébastien Marchand
2017/07/06 15:41:34
Don't mix + and %, you could do: "%s.%s.obj' % (ta
| |
| 126 os.path.splitext(os.path.basename(source_file))[0]) | |
| 127 | |
| 128 source_files = options.input_files.split() | |
| 129 object_files = [] | |
| 130 | |
| 131 for source_file in source_files: | |
| 132 object_files.append(get_object_file_location(source_file, | |
| 133 options.output_dir, | |
| 134 options.target_name)) | |
| 135 | |
| 136 ret = compile_with_asan(_CLANG_CL_PATH, source_files, _SRC_DIR, | |
| 137 object_files, options.target_name) | |
| 138 | |
| 139 if ret == 0: | |
| 140 ret = link(_CLANG_CL_PATH, object_files, options.output_dir, | |
| 141 options.target_name) | |
| 142 else: | |
| 143 print ("ERROR: Compilation of %s failed, skipping link step." | |
|
Sébastien Marchand
2017/07/06 15:41:35
Use ' rather than ".
| |
| 144 % options.target_name) | |
| 145 | |
| 146 return ret | |
| 147 | |
| 148 | |
| 149 if __name__ == '__main__': | |
| 150 sys.exit(main()) | |
| OLD | NEW |