| OLD | NEW |
| 1 #!/usr/bin/python | 1 #!/usr/bin/python |
| 2 # Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 3 # Use of this source code is governed by a BSD-style license that can be |
| 4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
| 5 | 5 |
| 6 """Downloads, builds (with instrumentation) and installs shared libraries.""" | 6 """Downloads, builds (with instrumentation) and installs shared libraries.""" |
| 7 | 7 |
| 8 import argparse | 8 import argparse |
| 9 import os | 9 import os |
| 10 import platform | 10 import platform |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 106 raise Exception('Failed to run: %s' % command) | 106 raise Exception('Failed to run: %s' % command) |
| 107 | 107 |
| 108 | 108 |
| 109 def run_shell_commands(commands, verbose=False, environment=None): | 109 def run_shell_commands(commands, verbose=False, environment=None): |
| 110 for command in commands: | 110 for command in commands: |
| 111 shell_call(command, verbose, environment) | 111 shell_call(command, verbose, environment) |
| 112 | 112 |
| 113 | 113 |
| 114 def destdir_configure_make_install(parsed_arguments, environment, | 114 def destdir_configure_make_install(parsed_arguments, environment, |
| 115 install_prefix): | 115 install_prefix): |
| 116 configure_command = './configure %s' % parsed_arguments.custom_configure_flags | 116 configure_command = './configure %s' % parsed_arguments.extra_configure_flags |
| 117 configure_command += ' --libdir=/lib/' | 117 configure_command += ' --libdir=/lib/' |
| 118 # Installing to a temporary directory allows us to safely clean up the .la | 118 # Installing to a temporary directory allows us to safely clean up the .la |
| 119 # files below. | 119 # files below. |
| 120 destdir = '%s/debian/instrumented_build' % os.getcwd() | 120 destdir = '%s/debian/instrumented_build' % os.getcwd() |
| 121 # Some makefiles use BUILDROOT instead of DESTDIR. | 121 # Some makefiles use BUILDROOT instead of DESTDIR. |
| 122 make_command = 'make -j%s DESTDIR=%s BUILDROOT=%s' % ( | 122 make_command = 'make -j%s DESTDIR=%s BUILDROOT=%s' % ( |
| 123 parsed_arguments.jobs, destdir, destdir), | 123 parsed_arguments.jobs, destdir, destdir), |
| 124 run_shell_commands([ | 124 run_shell_commands([ |
| 125 configure_command, | 125 configure_command, |
| 126 make_command, | 126 make_command, |
| 127 '%s install' % make_command, | 127 '%s install' % make_command, |
| 128 # Kill the .la files. They contain absolute paths, and will cause build | 128 # Kill the .la files. They contain absolute paths, and will cause build |
| 129 # errors in dependent libraries. | 129 # errors in dependent libraries. |
| 130 'rm %s/lib/*.la -f' % destdir, | 130 'rm %s/lib/*.la -f' % destdir, |
| 131 # Now move the contents of the temporary destdir to their final place. | 131 # Now move the contents of the temporary destdir to their final place. |
| 132 'cp %s/* %s/ -rdf' % (destdir, install_prefix)], | 132 'cp %s/* %s/ -rdf' % (destdir, install_prefix)], |
| 133 parsed_arguments.verbose, environment) | 133 parsed_arguments.verbose, environment) |
| 134 | 134 |
| 135 | 135 |
| 136 def prefix_configure_make_install(parsed_arguments, environment, | 136 def prefix_configure_make_install(parsed_arguments, environment, |
| 137 install_prefix): | 137 install_prefix): |
| 138 configure_command = './configure %s --prefix=%s' % ( | 138 configure_command = './configure %s --prefix=%s' % ( |
| 139 parsed_arguments.custom_configure_flags, install_prefix) | 139 parsed_arguments.extra_configure_flags, install_prefix) |
| 140 shell_call(configure_command, parsed_arguments.verbose, environment) | 140 shell_call(configure_command, parsed_arguments.verbose, environment) |
| 141 shell_call('make -j%s' % parsed_arguments.jobs, | 141 shell_call('make -j%s' % parsed_arguments.jobs, |
| 142 parsed_arguments.verbose, environment) | 142 parsed_arguments.verbose, environment) |
| 143 shell_call('make -j%s install' % parsed_arguments.jobs, | 143 shell_call('make -j%s install' % parsed_arguments.jobs, |
| 144 parsed_arguments.verbose, environment) | 144 parsed_arguments.verbose, environment) |
| 145 | 145 |
| 146 | 146 |
| 147 def nss_make_and_copy(parsed_arguments, environment, install_prefix): | 147 def nss_make_and_copy(parsed_arguments, environment, install_prefix): |
| 148 # NSS uses a build system that's different from configure/make/install. All | 148 # NSS uses a build system that's different from configure/make/install. All |
| 149 # flags must be passed as arguments to make. | 149 # flags must be passed as arguments to make. |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 if parsed_arguments.build_method == 'destdir': | 236 if parsed_arguments.build_method == 'destdir': |
| 237 destdir_configure_make_install( | 237 destdir_configure_make_install( |
| 238 parsed_arguments, environment, install_prefix) | 238 parsed_arguments, environment, install_prefix) |
| 239 elif parsed_arguments.build_method == 'prefix': | 239 elif parsed_arguments.build_method == 'prefix': |
| 240 prefix_configure_make_install(parsed_arguments, environment, install_prefix) | 240 prefix_configure_make_install(parsed_arguments, environment, install_prefix) |
| 241 elif parsed_arguments.build_method == 'custom_nss': | 241 elif parsed_arguments.build_method == 'custom_nss': |
| 242 nss_make_and_copy(parsed_arguments, environment, install_prefix) | 242 nss_make_and_copy(parsed_arguments, environment, install_prefix) |
| 243 elif parsed_arguments.build_method == 'custom_libcap': | 243 elif parsed_arguments.build_method == 'custom_libcap': |
| 244 libcap2_make_install(parsed_arguments, environment, install_prefix) | 244 libcap2_make_install(parsed_arguments, environment, install_prefix) |
| 245 elif parsed_arguments.build_method == 'custom_pango': | 245 elif parsed_arguments.build_method == 'custom_pango': |
| 246 parsed_arguments.custom_configure_flags += \ | 246 parsed_arguments.extra_configure_flags += \ |
| 247 ' --x-libraries=%s/lib' % install_prefix | 247 ' --x-libraries=%s/lib' % install_prefix |
| 248 parsed_arguments.custom_configure_flags += \ | 248 parsed_arguments.extra_configure_flags += \ |
| 249 ' --x-includes=%s/include' % install_prefix | 249 ' --x-includes=%s/include' % install_prefix |
| 250 prefix_configure_make_install(parsed_arguments, environment, install_prefix) | 250 prefix_configure_make_install(parsed_arguments, environment, install_prefix) |
| 251 elif parsed_arguments.build_method == 'custom_libpci3': | 251 elif parsed_arguments.build_method == 'custom_libpci3': |
| 252 libpci3_make_install(parsed_arguments, environment, install_prefix) | 252 libpci3_make_install(parsed_arguments, environment, install_prefix) |
| 253 else: | 253 else: |
| 254 raise Exception('Unrecognized build method: %s' % | 254 raise Exception('Unrecognized build method: %s' % |
| 255 parsed_arguments.build_method) | 255 parsed_arguments.build_method) |
| 256 | 256 |
| 257 | 257 |
| 258 def download_build_install(parsed_arguments): | 258 def download_build_install(parsed_arguments): |
| 259 sanitizer_params = SUPPORTED_SANITIZERS[parsed_arguments.sanitizer_type] | 259 sanitizer_params = SUPPORTED_SANITIZERS[parsed_arguments.sanitizer_type] |
| 260 | 260 |
| 261 environment = os.environ.copy() | 261 environment = os.environ.copy() |
| 262 # Usage of environment variables CC and CXX prefers usage flags --c-compiler | 262 # Usage of environment variables CC and CXX prefers usage flags --c-compiler |
| 263 # and --cxx-compiler | 263 # and --cxx-compiler |
| 264 if 'CC' not in environment and parsed_arguments.c_compiler: | 264 if 'CC' not in environment and parsed_arguments.cc: |
| 265 environment['CC'] = parsed_arguments.c_compiler | 265 environment['CC'] = parsed_arguments.cc |
| 266 if 'CXX' not in environment and parsed_arguments.cxx_compiler: | 266 if 'CXX' not in environment and parsed_arguments.cxx: |
| 267 environment['CXX'] = parsed_arguments.cxx_compiler | 267 environment['CXX'] = parsed_arguments.cxx |
| 268 | 268 |
| 269 product_directory = os.path.normpath('%s/%s' % ( | 269 product_directory = os.path.normpath('%s/%s' % ( |
| 270 get_script_absolute_path(), | 270 get_script_absolute_path(), |
| 271 parsed_arguments.product_directory)) | 271 parsed_arguments.product_directory)) |
| 272 | 272 |
| 273 compiler_flags = sanitizer_params['compiler_flags'] | 273 compiler_flags = sanitizer_params['compiler_flags'] |
| 274 if parsed_arguments.sanitizer_blacklist: | 274 if parsed_arguments.sanitizer_blacklist: |
| 275 compiler_flags += ' -fsanitize-blacklist=%s/%s' % ( | 275 compiler_flags += ' -fsanitize-blacklist=%s/%s' % ( |
| 276 product_directory, | 276 product_directory, |
| 277 parsed_arguments.sanitizer_blacklist) | 277 parsed_arguments.sanitizer_blacklist) |
| 278 environment['CFLAGS'] = '%s %s' % (compiler_flags, | 278 environment['CFLAGS'] = '%s %s' % (compiler_flags, |
| 279 parsed_arguments.custom_c_compiler_flags) | 279 parsed_arguments.extra_cflags) |
| 280 environment['CXXFLAGS'] = '%s %s' % ( | 280 environment['CXXFLAGS'] = '%s %s' % ( |
| 281 compiler_flags, | 281 compiler_flags, |
| 282 parsed_arguments.custom_cxx_compiler_flags) | 282 parsed_arguments.extra_cxxflags) |
| 283 | 283 |
| 284 install_prefix = '%s/instrumented_libraries/%s' % ( | 284 install_prefix = '%s/instrumented_libraries/%s' % ( |
| 285 product_directory, | 285 product_directory, |
| 286 parsed_arguments.sanitizer_type) | 286 parsed_arguments.sanitizer_type) |
| 287 | 287 |
| 288 # Make sure the linker searches the instrumented libraries dir for | 288 # Make sure the linker searches the instrumented libraries dir for |
| 289 # library dependencies. | 289 # library dependencies. |
| 290 environment['LDFLAGS'] = '%s -L%s/lib %s' % ( | 290 environment['LDFLAGS'] = '%s -L%s/lib %s' % ( |
| 291 sanitizer_params['linker_flags'], | 291 sanitizer_params['linker_flags'], |
| 292 install_prefix, parsed_arguments.custom_linker_flags) | 292 install_prefix, parsed_arguments.extra_ldflags) |
| 293 | 293 |
| 294 library_directory = '%s/%s' % (parsed_arguments.intermediate_directory, | 294 library_directory = '%s/%s' % (parsed_arguments.intermediate_directory, |
| 295 parsed_arguments.library) | 295 parsed_arguments.library) |
| 296 | 296 |
| 297 # A failed build might have left a dirty source tree behind. | 297 # A failed build might have left a dirty source tree behind. |
| 298 if os.path.exists(library_directory): | 298 if os.path.exists(library_directory): |
| 299 shutil.rmtree(library_directory) | 299 shutil.rmtree(library_directory) |
| 300 os.makedirs(library_directory) | 300 os.makedirs(library_directory) |
| 301 | 301 |
| 302 with ScopedChangeDirectory(library_directory) as cd_library: | 302 with ScopedChangeDirectory(library_directory) as cd_library: |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 338 description='Download, build and install instrumented library') | 338 description='Download, build and install instrumented library') |
| 339 | 339 |
| 340 argument_parser.add_argument('-j', '--jobs', type=int, default=1) | 340 argument_parser.add_argument('-j', '--jobs', type=int, default=1) |
| 341 argument_parser.add_argument('-l', '--library', required=True) | 341 argument_parser.add_argument('-l', '--library', required=True) |
| 342 argument_parser.add_argument( | 342 argument_parser.add_argument( |
| 343 '-i', '--product-directory', default='.', | 343 '-i', '--product-directory', default='.', |
| 344 help='Relative path to the directory with chrome binaries') | 344 help='Relative path to the directory with chrome binaries') |
| 345 argument_parser.add_argument( | 345 argument_parser.add_argument( |
| 346 '-m', '--intermediate-directory', default='.', | 346 '-m', '--intermediate-directory', default='.', |
| 347 help='Relative path to the directory for temporary build files') | 347 help='Relative path to the directory for temporary build files') |
| 348 argument_parser.add_argument('--custom-configure-flags', default='') | 348 argument_parser.add_argument('--extra-configure-flags', default='') |
| 349 argument_parser.add_argument('--custom-c-compiler-flags', default='') | 349 argument_parser.add_argument('--extra-cflags', default='') |
| 350 argument_parser.add_argument('--custom-cxx-compiler-flags', default='') | 350 argument_parser.add_argument('--extra-cxxflags', default='') |
| 351 argument_parser.add_argument('--custom-linker-flags', default='') | 351 argument_parser.add_argument('--extra-ldflags', default='') |
| 352 argument_parser.add_argument('-s', '--sanitizer-type', required=True, | 352 argument_parser.add_argument('-s', '--sanitizer-type', required=True, |
| 353 choices=SUPPORTED_SANITIZERS.keys()) | 353 choices=SUPPORTED_SANITIZERS.keys()) |
| 354 argument_parser.add_argument('-v', '--verbose', action='store_true') | 354 argument_parser.add_argument('-v', '--verbose', action='store_true') |
| 355 argument_parser.add_argument('--check-build-deps', action='store_true') | 355 argument_parser.add_argument('--check-build-deps', action='store_true') |
| 356 argument_parser.add_argument('--c-compiler') | 356 argument_parser.add_argument('--cc') |
| 357 argument_parser.add_argument('--cxx-compiler') | 357 argument_parser.add_argument('--cxx') |
| 358 # This should be a shell script to run before building specific libraries | 358 # This should be a shell script to run before building specific libraries |
| 359 # e.g. extracting archives with sources, patching makefiles, etc. | 359 # e.g. extracting archives with sources, patching makefiles, etc. |
| 360 argument_parser.add_argument('--run-before-build', default='') | 360 argument_parser.add_argument('--run-before-build', default='') |
| 361 argument_parser.add_argument('--build-method', default='destdir') | 361 argument_parser.add_argument('--build-method', default='destdir') |
| 362 argument_parser.add_argument('--sanitizer-blacklist', default='') | 362 argument_parser.add_argument('--sanitizer-blacklist', default='') |
| 363 | 363 |
| 364 # Ignore all empty arguments because in several cases gyp passes them to the | 364 # Ignore all empty arguments because in several cases gyp passes them to the |
| 365 # script, but ArgumentParser treats them as positional arguments instead of | 365 # script, but ArgumentParser treats them as positional arguments instead of |
| 366 # ignoring (and doesn't have such options). | 366 # ignoring (and doesn't have such options). |
| 367 parsed_arguments = argument_parser.parse_args( | 367 parsed_arguments = argument_parser.parse_args( |
| 368 [arg for arg in sys.argv[1:] if len(arg) != 0]) | 368 [arg for arg in sys.argv[1:] if len(arg) != 0]) |
| 369 # Ensure current working directory is this script directory. | 369 # Ensure current working directory is this script directory. |
| 370 os.chdir(get_script_absolute_path()) | 370 os.chdir(get_script_absolute_path()) |
| 371 # Ensure all build dependencies are installed. | 371 # Ensure all build dependencies are installed. |
| 372 if parsed_arguments.check_build_deps: | 372 if parsed_arguments.check_build_deps: |
| 373 check_library_build_dependencies(parsed_arguments.library) | 373 check_library_build_dependencies(parsed_arguments.library) |
| 374 | 374 |
| 375 download_build_install(parsed_arguments) | 375 download_build_install(parsed_arguments) |
| 376 | 376 |
| 377 | 377 |
| 378 if __name__ == '__main__': | 378 if __name__ == '__main__': |
| 379 main() | 379 main() |
| OLD | NEW |