Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(88)

Side by Side Diff: third_party/instrumented_libraries/scripts/download_build_install.py

Issue 2103683002: Add GN rules for building instrumented libraries. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « third_party/instrumented_libraries/scripts/build_and_package.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 ast
9 import os 10 import os
10 import platform 11 import platform
11 import re 12 import re
12 import shlex 13 import shlex
13 import shutil 14 import shutil
14 import subprocess 15 import subprocess
15 import sys 16 import sys
16 17
17 SCRIPT_ABSOLUTE_PATH = os.path.dirname(os.path.abspath(__file__)) 18 SCRIPT_ABSOLUTE_PATH = os.path.dirname(os.path.abspath(__file__))
18 19
19 def unescape_flags(s): 20 def unescape_flags(s):
20 """Un-escapes build flags received from GYP. 21 """Un-escapes build flags received from GYP.
21 22
22 GYP escapes build flags as if they are to be inserted directly into a command 23 GYP escapes build flags as if they are to be inserted directly into a command
23 line, wrapping each flag in double quotes. When flags are passed via 24 line, wrapping each flag in double quotes. When flags are passed via
24 CFLAGS/LDFLAGS instead, double quotes must be dropped. 25 CFLAGS/LDFLAGS instead, double quotes must be dropped.
25 """ 26 """
26 return ' '.join(shlex.split(s)) 27 if not s:
28 return ''
29 try:
30 return ' '.join(ast.literal_eval(s))
31 except (SyntaxError, ValueError):
32 return ' '.join(shlex.split(s))
27 33
28 34
29 def real_path(path_relative_to_gyp): 35 def real_path(path_relative_to_gyp):
30 """Returns the absolute path to a file. 36 """Returns the absolute path to a file.
31 37
32 GYP generates paths relative to the location of the .gyp file, which is one 38 GYP generates paths relative to the location of the .gyp file, which is one
33 level above the location of this script. This function converts them to 39 level above the location of this script. This function converts them to
34 absolute paths. 40 absolute paths.
35 """ 41 """
36 return os.path.realpath(os.path.join(SCRIPT_ABSOLUTE_PATH, '..', 42 return os.path.realpath(os.path.join(SCRIPT_ABSOLUTE_PATH, '..',
37 path_relative_to_gyp)) 43 path_relative_to_gyp))
38 44
39 45
40 class InstrumentedPackageBuilder(object): 46 class InstrumentedPackageBuilder(object):
41 """Checks out and builds a single instrumented package.""" 47 """Checks out and builds a single instrumented package."""
42 def __init__(self, args, clobber): 48 def __init__(self, args, clobber):
43 self._cc = args.cc 49 self._cc = args.cc
44 self._cxx = args.cxx 50 self._cxx = args.cxx
45 self._extra_configure_flags = args.extra_configure_flags 51 self._extra_configure_flags = unescape_flags(args.extra_configure_flags)
46 self._jobs = args.jobs 52 self._jobs = args.jobs
47 self._libdir = args.libdir 53 self._libdir = args.libdir
48 self._package = args.package 54 self._package = args.package
49 self._patch = real_path(args.patch) if args.patch else None 55 self._patch = real_path(args.patch) if args.patch else None
50 self._pre_build = \ 56 self._pre_build = \
51 real_path(args.pre_build) if args.pre_build else None 57 real_path(args.pre_build) if args.pre_build else None
52 self._sanitizer = args.sanitizer 58 self._sanitizer = args.sanitizer
53 self._verbose = args.verbose 59 self._verbose = args.verbose
54 self._clobber = clobber 60 self._clobber = clobber
55 self._working_dir = os.path.join( 61 self._working_dir = os.path.join(
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 raise Exception('Failed to run: %s' % command) 114 raise Exception('Failed to run: %s' % command)
109 115
110 def maybe_download_source(self): 116 def maybe_download_source(self):
111 """Checks out the source code (if needed). 117 """Checks out the source code (if needed).
112 118
113 Checks out the source code for the package, if required (i.e. unless running 119 Checks out the source code for the package, if required (i.e. unless running
114 in no-clobber mode). Initializes self._source_dir and self._source_archives. 120 in no-clobber mode). Initializes self._source_dir and self._source_archives.
115 """ 121 """
116 get_fresh_source = self._clobber or not os.path.exists(self._working_dir) 122 get_fresh_source = self._clobber or not os.path.exists(self._working_dir)
117 if get_fresh_source: 123 if get_fresh_source:
118 self.shell_call('rm -rf %s' % self._working_dir) 124 shutil.rmtree(self._working_dir, ignore_errors=True)
119 os.makedirs(self._working_dir) 125 os.makedirs(self._working_dir)
120 self.shell_call('apt-get source %s' % self._package, 126 self.shell_call('apt-get source %s' % self._package,
121 cwd=self._working_dir) 127 cwd=self._working_dir)
122 128
123 (dirpath, dirnames, filenames) = os.walk(self._working_dir).next() 129 (dirpath, dirnames, filenames) = os.walk(self._working_dir).next()
124 130
125 if len(dirnames) != 1: 131 if len(dirnames) != 1:
126 raise Exception( 132 raise Exception(
127 '`apt-get source %s\' must create exactly one subdirectory.' 133 '`apt-get source %s\' must create exactly one subdirectory.'
128 % self._package) 134 % self._package)
(...skipping 12 matching lines...) Expand all
141 self.shell_call('patch -p1 -i %s' % self._patch, cwd=self._source_dir) 147 self.shell_call('patch -p1 -i %s' % self._patch, cwd=self._source_dir)
142 if self._pre_build: 148 if self._pre_build:
143 self.shell_call(self._pre_build, cwd=self._source_dir) 149 self.shell_call(self._pre_build, cwd=self._source_dir)
144 150
145 def copy_source_archives(self): 151 def copy_source_archives(self):
146 """Copies the downloaded source archives to the output dir. 152 """Copies the downloaded source archives to the output dir.
147 153
148 For license compliance purposes, every Chromium build that includes 154 For license compliance purposes, every Chromium build that includes
149 instrumented libraries must include their full source code. 155 instrumented libraries must include their full source code.
150 """ 156 """
151 self.shell_call('rm -rf %s' % self._source_archives_dir) 157 shutil.rmtree(self._source_archives_dir, ignore_errors=True)
152 os.makedirs(self._source_archives_dir) 158 os.makedirs(self._source_archives_dir)
153 for filename in self._source_archives: 159 for filename in self._source_archives:
154 shutil.copy(filename, self._source_archives_dir) 160 shutil.copy(filename, self._source_archives_dir)
155 if self._patch: 161 if self._patch:
156 shutil.copy(self._patch, self._source_archives_dir) 162 shutil.copy(self._patch, self._source_archives_dir)
157 163
158 def download_build_install(self): 164 def download_build_install(self):
159 got_fresh_source = self.maybe_download_source() 165 got_fresh_source = self.maybe_download_source()
160 if got_fresh_source: 166 if got_fresh_source:
161 self.patch_source() 167 self.patch_source()
162 self.copy_source_archives() 168 self.copy_source_archives()
163 169
164 self.shell_call('mkdir -p %s' % self.dest_libdir()) 170 if not os.path.exists(self.dest_libdir()):
171 os.makedirs(self.dest_libdir())
165 172
166 try: 173 try:
167 self.build_and_install() 174 self.build_and_install()
168 except Exception as exception: 175 except Exception as exception:
169 print 'ERROR: Failed to build package %s. Have you run ' \ 176 print 'ERROR: Failed to build package %s. Have you run ' \
170 'src/third_party/instrumented_libraries/scripts/' \ 177 'src/third_party/instrumented_libraries/scripts/' \
171 'install-build-deps.sh?' % \ 178 'install-build-deps.sh?' % \
172 self._package 179 self._package
173 print 180 print
174 raise 181 raise
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
359 # Make sure we don't override the default flags in the makefile. 366 # Make sure we don't override the default flags in the makefile.
360 for variable in ['CFLAGS', 'CXXFLAGS', 'LDFLAGS']: 367 for variable in ['CFLAGS', 'CXXFLAGS', 'LDFLAGS']:
361 del self._build_env[variable] 368 del self._build_env[variable]
362 369
363 # Hardcoded paths. 370 # Hardcoded paths.
364 temp_dir = os.path.join(self._source_dir, 'nss') 371 temp_dir = os.path.join(self._source_dir, 'nss')
365 temp_libdir = os.path.join(temp_dir, 'lib') 372 temp_libdir = os.path.join(temp_dir, 'lib')
366 373
367 # Parallel build is not supported. Also, the build happens in 374 # Parallel build is not supported. Also, the build happens in
368 # <source_dir>/nss. 375 # <source_dir>/nss.
369 self.make(make_args, jobs=1, cwd=temp_dir) 376 try:
377 self.make(make_args, jobs=1, cwd=temp_dir)
378 except Exception:
379 # Building fails after all the required DSOs have been built, so ignore
380 # the error.
381 pass
370 382
371 self.fix_rpaths(temp_libdir) 383 self.fix_rpaths(temp_libdir)
372 384
373 # 'make install' is not supported. Copy the DSOs manually. 385 # 'make install' is not supported. Copy the DSOs manually.
374 for (dirpath, dirnames, filenames) in os.walk(temp_libdir): 386 for (dirpath, dirnames, filenames) in os.walk(temp_libdir):
375 for filename in filenames: 387 for filename in filenames:
376 if filename.endswith('.so'): 388 if filename.endswith('.so'):
377 full_path = os.path.join(dirpath, filename) 389 full_path = os.path.join(dirpath, filename)
378 if self._verbose: 390 if self._verbose:
379 print 'download_build_install.py: installing %s' % full_path 391 print 'download_build_install.py: installing %s' % full_path
380 shutil.copy(full_path, self.dest_libdir()) 392 shutil.copy(full_path, self.dest_libdir())
381 393
382 394
395 class StubBuilder(InstrumentedPackageBuilder):
396 def download_build_install(self):
397 self._touch(os.path.join(self._destdir, '%s.txt' % self._package))
398 self._touch(os.path.join(self.dest_libdir(), '%s.so.0' % self._package))
399
400 def _touch(self, path):
401 with open(path, 'w'):
402 pass
403
404
383 def main(): 405 def main():
384 parser = argparse.ArgumentParser( 406 parser = argparse.ArgumentParser(
385 description='Download, build and install an instrumented package.') 407 description='Download, build and install an instrumented package.')
386 408
387 parser.add_argument('-j', '--jobs', type=int, default=1) 409 parser.add_argument('-j', '--jobs', type=int, default=1)
388 parser.add_argument('-p', '--package', required=True) 410 parser.add_argument('-p', '--package', required=True)
389 parser.add_argument( 411 parser.add_argument(
390 '-i', '--product-dir', default='.', 412 '-i', '--product-dir', default='.',
391 help='Relative path to the directory with chrome binaries') 413 help='Relative path to the directory with chrome binaries')
392 parser.add_argument( 414 parser.add_argument(
(...skipping 27 matching lines...) Expand all
420 (os.environ.get('INSTRUMENTED_LIBRARIES_NO_CLOBBER', '') != '1') 442 (os.environ.get('INSTRUMENTED_LIBRARIES_NO_CLOBBER', '') != '1')
421 443
422 if args.build_method == 'destdir': 444 if args.build_method == 'destdir':
423 builder = InstrumentedPackageBuilder(args, clobber) 445 builder = InstrumentedPackageBuilder(args, clobber)
424 elif args.build_method == 'custom_nss': 446 elif args.build_method == 'custom_nss':
425 builder = NSSBuilder(args, clobber) 447 builder = NSSBuilder(args, clobber)
426 elif args.build_method == 'custom_libcap': 448 elif args.build_method == 'custom_libcap':
427 builder = LibcapBuilder(args, clobber) 449 builder = LibcapBuilder(args, clobber)
428 elif args.build_method == 'custom_libpci3': 450 elif args.build_method == 'custom_libpci3':
429 builder = Libpci3Builder(args, clobber) 451 builder = Libpci3Builder(args, clobber)
452 elif args.build_method == 'stub':
453 builder = StubBuilder(args, clobber)
430 else: 454 else:
431 raise Exception('Unrecognized build method: %s' % args.build_method) 455 raise Exception('Unrecognized build method: %s' % args.build_method)
432 456
433 builder.download_build_install() 457 builder.download_build_install()
434 458
435 if __name__ == '__main__': 459 if __name__ == '__main__':
436 main() 460 main()
OLDNEW
« no previous file with comments | « third_party/instrumented_libraries/scripts/build_and_package.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698