Chromium Code Reviews
|
| OLD | NEW |
|---|---|
| (Empty) | |
| 1 #!/usr/bin/python | |
| 2 # Copyright 2013 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 | |
| 6 # Downloads, builds (with instrumentation) and installs shared libraries. | |
| 7 | |
| 8 import argparse | |
| 9 import os | |
| 10 import shutil | |
| 11 import subprocess | |
| 12 import sys | |
| 13 | |
| 14 # Should be a dict from 'sanitizer type' to 'compiler flag'. | |
| 15 SUPPORTED_SANITIZERS = {"asan": "address"} | |
|
Alexander Potapenko
2013/11/15 10:32:19
"Be consistent with your choice of string quote ch
alextaran1
2013/11/15 12:00:51
Done.
| |
| 16 | |
| 17 | |
| 18 class ScopedChangeDirectory(object): | |
| 19 "Changes current working directory and restores it back automatically." | |
|
Alexander Potapenko
2013/11/15 10:32:19
Doc strings should use """.
alextaran1
2013/11/15 12:00:51
Done.
| |
| 20 def __init__(self, path): | |
| 21 self.path = path | |
| 22 self.old_path = "" | |
| 23 | |
| 24 def __enter__(self): | |
| 25 self.old_path = os.getcwd() | |
| 26 os.chdir(self.path) | |
| 27 | |
| 28 def __exit__(self, exc_type, exc_value, traceback): | |
| 29 os.chdir(self.old_path) | |
| 30 | |
| 31 | |
| 32 def get_script_absolute_path(): | |
| 33 return os.path.dirname(os.path.abspath(__file__)) | |
| 34 | |
| 35 | |
| 36 def get_library_build_dependencies(library): | |
| 37 command = 'apt-get -s build-dep {0} | grep Inst | cut -d " " -f 2'.format( | |
|
Alexander Potapenko
2013/11/15 10:32:19
It's more readable to split the string somewhere i
Alexander Potapenko
2013/11/15 10:32:19
Also consider using the % operator instead of the
alextaran1
2013/11/15 12:00:51
After replacing "format" to "%" wrapping isn't nee
| |
| 38 library) | |
| 39 command_result = subprocess.Popen(command, stdout = subprocess.PIPE, | |
|
Alexander Potapenko
2013/11/15 10:32:19
"Don't use spaces around the '=' sign when used to
alextaran1
2013/11/15 12:00:51
Done.
| |
| 40 shell = True) | |
| 41 build_dependencies = [l.strip() for l in command_result.stdout] | |
| 42 return build_dependencies | |
| 43 | |
| 44 | |
| 45 def download_build_install(parsed_arguments): | |
| 46 sanitizer_flag = SUPPORTED_SANITIZERS[parsed_arguments.sanitizer_type] | |
| 47 | |
| 48 os.putenv("CFLAGS", "-fsanitize={0} -g -fPIC -w".format(sanitizer_flag)) | |
|
Alexander Potapenko
2013/11/15 10:32:19
You don't need to change the actual environment of
alextaran1
2013/11/15 12:00:51
Done.
| |
| 49 os.putenv("CXXFLAGS", "-fsanitize={0} -g -fPIC -w".format(sanitizer_flag)) | |
| 50 # We use XORIGIN as RPATH and after building library replace it to $ORIGIN | |
| 51 # The reason: this flag goes through configure script and makefiles | |
| 52 # differently for different libraries. So the dollar sign "$" should be | |
| 53 # differently escaped. Instead of having problems with that it just | |
| 54 # uses XORIGIN to build library and after that replaces it to $ORIGIN | |
| 55 # directly in .so file. | |
| 56 os.putenv("LDFLAGS", "-Wl,-z,origin -Wl,-R,XORIGIN/.") | |
| 57 | |
| 58 library_directory = "{0}/{1}".format(parsed_arguments.intermediate_directory, | |
| 59 parsed_arguments.library) | |
| 60 | |
| 61 install_prefix = "{0}/{1}/instrumented_libraries/{2}".format( | |
| 62 get_script_absolute_path(), | |
| 63 parsed_arguments.product_directory, | |
| 64 parsed_arguments.sanitizer_type) | |
| 65 | |
| 66 if not os.path.exists(library_directory): | |
| 67 os.makedirs(library_directory) | |
| 68 | |
| 69 with ScopedChangeDirectory(library_directory), open(os.devnull, "w") as dev_nu ll: | |
|
Alexander Potapenko
2013/11/15 10:32:19
Please wrap this line.
alextaran1
2013/11/15 12:00:51
Done.
| |
| 70 subprocess.call("apt-get source {0}".format(parsed_arguments.library), | |
| 71 stdout = dev_null, stderr = dev_null, shell = True) | |
| 72 # There should be only one subdirectory after downloading a package. | |
| 73 subdirectories = [d for d in os.listdir(".") if os.path.isdir(d)] | |
| 74 if len(subdirectories) != 1: | |
| 75 raise Exception("There was not one directory after downloading " \ | |
| 76 "a package {0}".format(parsed_arguments.library)) | |
| 77 with ScopedChangeDirectory(subdirectories[0]): | |
|
Alexander Potapenko
2013/11/15 10:32:19
You're assuming len(subdirectories) > 0. If this s
alextaran1
2013/11/15 12:00:51
Done.
| |
| 78 # Now we are in the package directory. | |
| 79 configure_command = "./configure {0} --prefix={1}".format( | |
| 80 parsed_arguments.custom_configure_flags, install_prefix) | |
| 81 subprocess.call(configure_command, stdout = dev_null, stderr = dev_null, | |
| 82 shell = True) | |
| 83 subprocess.call("make -j{0}".format(parsed_arguments.jobs), | |
| 84 stdout = dev_null, stderr = dev_null, shell = True) | |
| 85 subprocess.call("make -j{0} install".format(parsed_arguments.jobs), | |
| 86 stdout = dev_null, stderr = dev_null, shell = True) | |
| 87 | |
| 88 # Touch a txt file to indicate library is installed. | |
| 89 open("{0}/{1}.txt".format(install_prefix, parsed_arguments.library), "w") \ | |
| 90 .close() | |
| 91 # Remove downloaded package and generated temporary build files. | |
| 92 shutil.rmtree(library_directory) | |
| 93 | |
| 94 | |
| 95 def main(): | |
| 96 argument_parser = argparse.ArgumentParser( | |
| 97 description = "Download, build and install instrumented library") | |
| 98 | |
| 99 argument_parser.add_argument("-j", "--jobs", type = int, default = 1) | |
| 100 argument_parser.add_argument("-l", "--library", required = True) | |
| 101 argument_parser.add_argument("-i", "--product-directory", default = ".", | |
| 102 help = "Relative path to the directory with chrome binaries") | |
| 103 argument_parser.add_argument("-m", "--intermediate-directory", default = ".", | |
| 104 help = "Relative path to the directory for temporary build files") | |
| 105 argument_parser.add_argument("-c", "--custom-configure-flags", default = "") | |
| 106 argument_parser.add_argument("-s", "--sanitizer-type", required = True, | |
| 107 choices = SUPPORTED_SANITIZERS.keys()) | |
| 108 | |
| 109 parsed_arguments = argument_parser.parse_args() | |
| 110 # Ensure current working directory is this script directory | |
| 111 os.chdir(get_script_absolute_path()) | |
| 112 # Ensure all build dependencies are installed | |
| 113 build_dependencies = get_library_build_dependencies(parsed_arguments.library) | |
| 114 if len(build_dependencies) != 0: | |
|
Alexander Potapenko
2013/11/15 10:32:19
That's just 'if len(build_dependencies)'.
Overall,
alextaran1
2013/11/15 12:00:51
Done.
| |
| 115 print >> sys.stderr, "Please, install build-dependencies for {0}".format( | |
| 116 parsed_arguments.library) | |
| 117 print >> sys.stderr, "One-liner for APT:" | |
| 118 print >> sys.stderr, "sudo apt-get -y --no-remove build-dep {0}".format( | |
| 119 parsed_arguments.library) | |
| 120 sys.exit(1) | |
| 121 | |
| 122 download_build_install(parsed_arguments) | |
| 123 | |
| 124 | |
| 125 if __name__ == "__main__": | |
| 126 main() | |
| OLD | NEW |