 Chromium Code Reviews
 Chromium Code Reviews Issue 60733027:
  Rewrited build script for instrumented libraries from bash to python  (Closed) 
  Base URL: https://src.chromium.org/chrome/trunk/src/
    
  
    Issue 60733027:
  Rewrited build script for instrumented libraries from bash to python  (Closed) 
  Base URL: https://src.chromium.org/chrome/trunk/src/| Index: third_party/instrumented_libraries/download_build_install.py | 
| =================================================================== | 
| --- third_party/instrumented_libraries/download_build_install.py (revision 0) | 
| +++ third_party/instrumented_libraries/download_build_install.py (revision 0) | 
| @@ -0,0 +1,131 @@ | 
| +#!/usr/bin/python | 
| +# Copyright 2013 The Chromium Authors. All rights reserved. | 
| +# Use of this source code is governed by a BSD-style license that can be | 
| +# found in the LICENSE file. | 
| + | 
| +# Downloads, builds (with instrumentation) and installs shared libraries. | 
| + | 
| +import argparse | 
| +import os | 
| +import shutil | 
| +import subprocess | 
| +import sys | 
| + | 
| +# Should be a dict from 'sanitizer type' to 'compiler flag'. | 
| +SUPPORTED_SANITIZERS = {'asan': 'address'} | 
| + | 
| + | 
| +class ScopedChangeDirectory(object): | 
| + """Changes current working directory and restores it back automatically.""" | 
| + def __init__(self, path): | 
| + self.path = path | 
| + self.old_path = '' | 
| + | 
| + def __enter__(self): | 
| + self.old_path = os.getcwd() | 
| + os.chdir(self.path) | 
| + | 
| + def __exit__(self, exc_type, exc_value, traceback): | 
| + os.chdir(self.old_path) | 
| + | 
| + | 
| +def get_script_absolute_path(): | 
| + return os.path.dirname(os.path.abspath(__file__)) | 
| + | 
| + | 
| +def get_library_build_dependencies(library): | 
| + command = 'apt-get -s build-dep %s | grep Inst | cut -d " " -f 2' % library | 
| + command_result = subprocess.Popen(command, stdout=subprocess.PIPE, | 
| + shell=True) | 
| + build_dependencies = [l.strip() for l in command_result.stdout] | 
| + return build_dependencies | 
| + | 
| + | 
| +def download_build_install(parsed_arguments): | 
| + sanitizer_flag = SUPPORTED_SANITIZERS[parsed_arguments.sanitizer_type] | 
| + | 
| + environment = os.environ.copy() | 
| + environment['CFLAGS'] = '-fsanitize=%s -g -fPIC -w' % sanitizer_flag | 
| + environment['CXXFLAGS'] = '-fsanitize=%s -g -fPIC -w' % sanitizer_flag | 
| + # We use XORIGIN as RPATH and after building library replace it to $ORIGIN | 
| + # The reason: this flag goes through configure script and makefiles | 
| + # differently for different libraries. So the dollar sign '$' should be | 
| + # differently escaped. Instead of having problems with that it just | 
| + # uses XORIGIN to build library and after that replaces it to $ORIGIN | 
| + # directly in .so file. | 
| + environment['LDFLAGS'] = '-Wl,-z,origin -Wl,-R,XORIGIN/.' | 
| + | 
| + library_directory = '%s/%s' % (parsed_arguments.intermediate_directory, | 
| + parsed_arguments.library) | 
| + | 
| + install_prefix = '%s/%s/instrumented_libraries/%s' % ( | 
| + get_script_absolute_path(), | 
| + parsed_arguments.product_directory, | 
| + parsed_arguments.sanitizer_type) | 
| + | 
| + if not os.path.exists(library_directory): | 
| + os.makedirs(library_directory) | 
| + | 
| + with ScopedChangeDirectory(library_directory), \ | 
| + open(os.devnull, 'w') as dev_null: | 
| + if subprocess.call('apt-get source %s' % parsed_arguments.library, | 
| + stdout=dev_null, stderr=dev_null, shell=True): | 
| + raise Exception('Failed to download package %s' % parsed_arguments.library) | 
| 
Alexander Potapenko
2013/11/15 12:57:50
Please mind the 80-char limit.
 | 
| + # There should be only one subdirectory after downloading a package. | 
| + subdirectories = [d for d in os.listdir('.') if os.path.isdir(d)] | 
| + if len(subdirectories) > 1: | 
| 
Alexander Potapenko
2013/11/15 12:57:50
Please reinstate the '!= 1' condition per the offl
 | 
| + raise Exception('There was not one directory after downloading ' \ | 
| + 'a package %s' % parsed_arguments.library) | 
| + with ScopedChangeDirectory(subdirectories[0]): | 
| + # Now we are in the package directory. | 
| + configure_command = './configure %s --prefix=%s' % ( | 
| + parsed_arguments.custom_configure_flags, install_prefix) | 
| + if subprocess.call(configure_command, stdout=dev_null, stderr=dev_null, | 
| + env=environment, shell=True): | 
| + raise Exception("Failed to configure %s" % parsed_arguments.library) | 
| + if subprocess.call('make -j%s' % parsed_arguments.jobs, | 
| + stdout=dev_null, stderr=dev_null, shell=True): | 
| + raise Exception("Failed to make %s" % parsed_arguments.library) | 
| + if subprocess.call('make -j%s install' % parsed_arguments.jobs, | 
| + stdout=dev_null, stderr=dev_null, shell=True): | 
| + raise Exception("Failed to install %s" % parsed_arguments.library) | 
| + | 
| + # Touch a txt file to indicate library is installed. | 
| + open('%s/%s.txt' % (install_prefix, parsed_arguments.library), 'w').close() | 
| + | 
| + # Remove downloaded package and generated temporary build files. | 
| + shutil.rmtree(library_directory) | 
| + | 
| + | 
| +def main(): | 
| + argument_parser = argparse.ArgumentParser( | 
| + description = 'Download, build and install instrumented library') | 
| + | 
| + argument_parser.add_argument('-j', '--jobs', type=int, default=1) | 
| + argument_parser.add_argument('-l', '--library', required=True) | 
| + argument_parser.add_argument('-i', '--product-directory', default='.', | 
| + help='Relative path to the directory with chrome binaries') | 
| + argument_parser.add_argument('-m', '--intermediate-directory', default='.', | 
| + help='Relative path to the directory for temporary build files') | 
| + argument_parser.add_argument('-c', '--custom-configure-flags', default='') | 
| + argument_parser.add_argument('-s', '--sanitizer-type', required=True, | 
| + choices=SUPPORTED_SANITIZERS.keys()) | 
| + | 
| + parsed_arguments = argument_parser.parse_args() | 
| + # Ensure current working directory is this script directory | 
| + os.chdir(get_script_absolute_path()) | 
| + # Ensure all build dependencies are installed | 
| + build_dependencies = get_library_build_dependencies(parsed_arguments.library) | 
| + if len(build_dependencies): | 
| + print >> sys.stderr, 'Please, install build-dependencies for %s' % \ | 
| + parsed_arguments.library | 
| + print >> sys.stderr, 'One-liner for APT:' | 
| + print >> sys.stderr, 'sudo apt-get -y --no-remove build-dep %s' % \ | 
| + parsed_arguments.library | 
| + sys.exit(1) | 
| + | 
| + download_build_install(parsed_arguments) | 
| + | 
| + | 
| +if __name__ == '__main__': | 
| + main() | 
| Property changes on: third_party/instrumented_libraries/download_build_install.py | 
| ___________________________________________________________________ | 
| Added: svn:eol-style | 
| + LF | 
| Added: svn:executable | 
| + * |