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

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

Issue 723033006: Instrumented libraries: overhaul RPATH handling. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month 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 | « no previous file | third_party/instrumented_libraries/fix_rpaths.sh » ('j') | 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 os 9 import os
10 import platform 10 import platform
11 import re 11 import re
12 import shlex 12 import shlex
13 import shutil 13 import shutil
14 import subprocess 14 import subprocess
15 import sys 15 import sys
16 16
17 SCRIPT_ABSOLUTE_PATH = os.path.dirname(os.path.abspath(__file__))
18
17 class ScopedChangeDirectory(object): 19 class ScopedChangeDirectory(object):
18 """Changes current working directory and restores it back automatically.""" 20 """Changes current working directory and restores it back automatically."""
19 21
20 def __init__(self, path): 22 def __init__(self, path):
21 self.path = path 23 self.path = path
22 self.old_path = '' 24 self.old_path = ''
23 25
24 def __enter__(self): 26 def __enter__(self):
25 self.old_path = os.getcwd() 27 self.old_path = os.getcwd()
26 os.chdir(self.path) 28 os.chdir(self.path)
27 return self 29 return self
28 30
29 def __exit__(self, exc_type, exc_value, traceback): 31 def __exit__(self, exc_type, exc_value, traceback):
30 os.chdir(self.old_path) 32 os.chdir(self.old_path)
31 33
32
33 def get_script_absolute_path():
34 return os.path.dirname(os.path.abspath(__file__))
35
36
37 def get_package_build_dependencies(package): 34 def get_package_build_dependencies(package):
38 command = 'apt-get -s build-dep %s | grep Inst | cut -d " " -f 2' % package 35 command = 'apt-get -s build-dep %s | grep Inst | cut -d " " -f 2' % package
39 command_result = subprocess.Popen(command, stdout=subprocess.PIPE, 36 command_result = subprocess.Popen(command, stdout=subprocess.PIPE,
40 shell=True) 37 shell=True)
41 if command_result.wait(): 38 if command_result.wait():
42 raise Exception('Failed to determine build dependencies for %s' % package) 39 raise Exception('Failed to determine build dependencies for %s' % package)
43 build_dependencies = [l.strip() for l in command_result.stdout] 40 build_dependencies = [l.strip() for l in command_result.stdout]
44 return build_dependencies 41 return build_dependencies
45 42
46 43
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
79 print stdout 76 print stdout
80 if child.returncode: 77 if child.returncode:
81 raise Exception('Failed to run: %s' % command) 78 raise Exception('Failed to run: %s' % command)
82 79
83 80
84 def run_shell_commands(commands, verbose=False, environment=None): 81 def run_shell_commands(commands, verbose=False, environment=None):
85 for command in commands: 82 for command in commands:
86 shell_call(command, verbose, environment) 83 shell_call(command, verbose, environment)
87 84
88 85
86 def fix_rpaths(destdir):
87 # TODO(earthdok): reimplement fix_rpaths.sh in Python.
88 shell_call("%s/fix_rpaths.sh %s/lib" % (SCRIPT_ABSOLUTE_PATH, destdir))
89
90
89 def destdir_configure_make_install(parsed_arguments, environment, 91 def destdir_configure_make_install(parsed_arguments, environment,
90 install_prefix): 92 install_prefix):
91 configure_command = './configure %s' % parsed_arguments.extra_configure_flags 93 configure_command = './configure %s' % parsed_arguments.extra_configure_flags
92 configure_command += ' --libdir=/lib/' 94 configure_command += ' --libdir=/lib/'
93 # Installing to a temporary directory allows us to safely clean up the .la 95 # Installing to a temporary directory allows us to safely clean up the .la
94 # files below. 96 # files below.
95 destdir = '%s/debian/instrumented_build' % os.getcwd() 97 destdir = '%s/debian/instrumented_build' % os.getcwd()
96 # Some makefiles use BUILDROOT instead of DESTDIR. 98 # Some makefiles use BUILDROOT instead of DESTDIR.
97 make_command = 'make DESTDIR=%s BUILDROOT=%s' % (destdir, destdir) 99 make_command = 'make DESTDIR=%s BUILDROOT=%s' % (destdir, destdir)
98 run_shell_commands([ 100 build_and_install_in_destdir = [
99 configure_command, 101 configure_command,
100 '%s -j%s' % (make_command, parsed_arguments.jobs), 102 '%s -j%s' % (make_command, parsed_arguments.jobs),
101 # Parallel install is flaky for some packages. 103 # Parallel install is flaky for some packages.
102 '%s install -j1' % make_command, 104 '%s install -j1' % make_command,
103 # Kill the .la files. They contain absolute paths, and will cause build 105 # Kill the .la files. They contain absolute paths, and will cause build
104 # errors in dependent libraries. 106 # errors in dependent libraries.
105 'rm %s/lib/*.la -f' % destdir, 107 'rm %s/lib/*.la -f' % destdir
108 ]
109 run_shell_commands(build_and_install_in_destdir,
110 parsed_arguments.verbose, environment)
111 fix_rpaths(destdir)
112 shell_call(
106 # Now move the contents of the temporary destdir to their final place. 113 # Now move the contents of the temporary destdir to their final place.
107 'cp %s/* %s/ -rdf' % (destdir, install_prefix)], 114 'cp %s/* %s/ -rdf' % (destdir, install_prefix),
108 parsed_arguments.verbose, environment) 115 parsed_arguments.verbose, environment)
109 116
110 117
111 def nss_make_and_copy(parsed_arguments, environment, install_prefix): 118 def nss_make_and_copy(parsed_arguments, environment, install_prefix):
112 # NSS uses a build system that's different from configure/make/install. All 119 # NSS uses a build system that's different from configure/make/install. All
113 # flags must be passed as arguments to make. 120 # flags must be passed as arguments to make.
114 make_args = [] 121 make_args = []
115 # Do an optimized build. 122 # Do an optimized build.
116 make_args.append('BUILD_OPT=1') 123 make_args.append('BUILD_OPT=1')
117 # Set USE_64=1 on x86_64 systems. 124 # Set USE_64=1 on x86_64 systems.
118 if platform.architecture()[0] == '64bit': 125 if platform.architecture()[0] == '64bit':
(...skipping 10 matching lines...) Expand all
129 make_args.append('NSPR_INCLUDE_DIR=/usr/include/nspr') 136 make_args.append('NSPR_INCLUDE_DIR=/usr/include/nspr')
130 make_args.append('NSPR_LIB_DIR=%s/lib' % install_prefix) 137 make_args.append('NSPR_LIB_DIR=%s/lib' % install_prefix)
131 make_args.append('NSS_ENABLE_ECC=1') 138 make_args.append('NSS_ENABLE_ECC=1')
132 # Make sure we don't override the default flags. 139 # Make sure we don't override the default flags.
133 for variable in ['CFLAGS', 'CXXFLAGS', 'LDFLAGS']: 140 for variable in ['CFLAGS', 'CXXFLAGS', 'LDFLAGS']:
134 del environment[variable] 141 del environment[variable]
135 with ScopedChangeDirectory('nss') as cd_nss: 142 with ScopedChangeDirectory('nss') as cd_nss:
136 # -j is not supported 143 # -j is not supported
137 shell_call('make %s' % ' '.join(make_args), parsed_arguments.verbose, 144 shell_call('make %s' % ' '.join(make_args), parsed_arguments.verbose,
138 environment) 145 environment)
146 fix_rpaths(os.getcwd())
139 # 'make install' is not supported. Copy the DSOs manually. 147 # 'make install' is not supported. Copy the DSOs manually.
140 install_dir = '%s/lib/' % install_prefix 148 install_dir = '%s/lib/' % install_prefix
141 for (dirpath, dirnames, filenames) in os.walk('./lib/'): 149 for (dirpath, dirnames, filenames) in os.walk('./lib/'):
142 for filename in filenames: 150 for filename in filenames:
143 if filename.endswith('.so'): 151 if filename.endswith('.so'):
144 full_path = os.path.join(dirpath, filename) 152 full_path = os.path.join(dirpath, filename)
145 if parsed_arguments.verbose: 153 if parsed_arguments.verbose:
146 print 'download_build_install.py: installing %s' % full_path 154 print 'download_build_install.py: installing %s' % full_path
147 shutil.copy(full_path, install_dir) 155 shutil.copy(full_path, install_dir)
148 156
149 157
150 def libcap2_make_install(parsed_arguments, environment, install_prefix): 158 def libcap2_make_install(parsed_arguments, environment, install_prefix):
151 # libcap2 doesn't come with a configure script 159 # libcap2 doesn't come with a configure script
152 make_args = [ 160 make_args = [
153 '%s="%s"' % (name, environment[name]) 161 '%s="%s"' % (name, environment[name])
154 for name in['CC', 'CXX', 'CFLAGS', 'CXXFLAGS', 'LDFLAGS']] 162 for name in['CC', 'CXX', 'CFLAGS', 'CXXFLAGS', 'LDFLAGS']]
155 shell_call('make -j%s %s' % (parsed_arguments.jobs, ' '.join(make_args)), 163 shell_call('make -j%s %s' % (parsed_arguments.jobs, ' '.join(make_args)),
156 parsed_arguments.verbose, environment) 164 parsed_arguments.verbose, environment)
165 destdir = '%s/debian/instrumented_build' % os.getcwd()
157 install_args = [ 166 install_args = [
158 'DESTDIR=%s' % install_prefix, 167 'DESTDIR=%s' % destdir,
159 # Do not install in lib64/. 168 # Do not install in lib64/.
160 'lib=lib', 169 'lib=lib',
161 # Skip a step that requires sudo. 170 # Skip a step that requires sudo.
162 'RAISE_SETFCAP=no' 171 'RAISE_SETFCAP=no'
163 ] 172 ]
164 shell_call('make -j%s install %s' % 173 shell_call('make -j%s install %s' %
165 (parsed_arguments.jobs, ' '.join(install_args)), 174 (parsed_arguments.jobs, ' '.join(install_args)),
166 parsed_arguments.verbose, environment) 175 parsed_arguments.verbose, environment)
176 fix_rpaths(destdir)
177 shell_call([
178 # Now move the contents of the temporary destdir to their final place.
179 'cp %s/* %s/ -rdf' % (destdir, install_prefix)],
180 parsed_arguments.verbose, environment)
167 181
168 182
169 def libpci3_make_install(parsed_arguments, environment, install_prefix): 183 def libpci3_make_install(parsed_arguments, environment, install_prefix):
170 # pciutils doesn't have a configure script 184 # pciutils doesn't have a configure script
171 # This build script follows debian/rules. 185 # This build script follows debian/rules.
172 186
173 # Find out the package version. We'll use this when creating symlinks. 187 # Find out the package version. We'll use this when creating symlinks.
174 dir_name = os.path.split(os.getcwd())[-1] 188 dir_name = os.path.split(os.getcwd())[-1]
175 match = re.match('pciutils-(\d+\.\d+\.\d+)', dir_name) 189 match = re.match('pciutils-(\d+\.\d+\.\d+)', dir_name)
176 if match is None: 190 if match is None:
(...skipping 19 matching lines...) Expand all
196 'IDSDIR=/usr/share/misc', 210 'IDSDIR=/usr/share/misc',
197 ] 211 ]
198 install_args = ['DESTDIR=%s' % destdir] 212 install_args = ['DESTDIR=%s' % destdir]
199 run_shell_commands([ 213 run_shell_commands([
200 'mkdir -p %s-udeb/usr/bin' % destdir, 214 'mkdir -p %s-udeb/usr/bin' % destdir,
201 'make -j%s %s' % (parsed_arguments.jobs, ' '.join(make_args + paths)), 215 'make -j%s %s' % (parsed_arguments.jobs, ' '.join(make_args + paths)),
202 'make -j%s %s install' % ( 216 'make -j%s %s install' % (
203 parsed_arguments.jobs, 217 parsed_arguments.jobs,
204 ' '.join(install_args + paths))], 218 ' '.join(install_args + paths))],
205 parsed_arguments.verbose, environment) 219 parsed_arguments.verbose, environment)
220 fix_rpaths(destdir)
206 # Now move the contents of the temporary destdir to their final place. 221 # Now move the contents of the temporary destdir to their final place.
207 run_shell_commands([ 222 run_shell_commands([
208 'cp %s/* %s/ -rd' % (destdir, install_prefix), 223 'cp %s/* %s/ -rd' % (destdir, install_prefix),
209 'install -m 644 lib/libpci.so* %s/lib/' % install_prefix, 224 'install -m 644 lib/libpci.so* %s/lib/' % install_prefix,
210 'ln -sf libpci.so.%s %s/lib/libpci.so.3' % (version, install_prefix)], 225 'ln -sf libpci.so.%s %s/lib/libpci.so.3' % (version, install_prefix)],
211 parsed_arguments.verbose, environment) 226 parsed_arguments.verbose, environment)
212 227
213 228
214 def build_and_install(parsed_arguments, environment, install_prefix): 229 def build_and_install(parsed_arguments, environment, install_prefix):
215 if parsed_arguments.build_method == 'destdir': 230 if parsed_arguments.build_method == 'destdir':
(...skipping 22 matching lines...) Expand all
238 # The CC/CXX environment variables take precedence over the command line 253 # The CC/CXX environment variables take precedence over the command line
239 # flags. 254 # flags.
240 if 'CC' not in environment and parsed_arguments.cc: 255 if 'CC' not in environment and parsed_arguments.cc:
241 environment['CC'] = parsed_arguments.cc 256 environment['CC'] = parsed_arguments.cc
242 if 'CXX' not in environment and parsed_arguments.cxx: 257 if 'CXX' not in environment and parsed_arguments.cxx:
243 environment['CXX'] = parsed_arguments.cxx 258 environment['CXX'] = parsed_arguments.cxx
244 259
245 cflags = unescape_flags(parsed_arguments.cflags) 260 cflags = unescape_flags(parsed_arguments.cflags)
246 if parsed_arguments.sanitizer_blacklist: 261 if parsed_arguments.sanitizer_blacklist:
247 cflags += ' -fsanitize-blacklist=%s/%s' % ( 262 cflags += ' -fsanitize-blacklist=%s/%s' % (
248 get_script_absolute_path(), 263 SCRIPT_ABSOLUTE_PATH,
249 parsed_arguments.sanitizer_blacklist) 264 parsed_arguments.sanitizer_blacklist)
250 environment['CFLAGS'] = cflags 265 environment['CFLAGS'] = cflags
251 environment['CXXFLAGS'] = cflags 266 environment['CXXFLAGS'] = cflags
252 267
253 ldflags = unescape_flags(parsed_arguments.ldflags) 268 ldflags = unescape_flags(parsed_arguments.ldflags)
254 # Make sure the linker searches the instrumented libraries dir for 269 # Make sure the linker searches the instrumented libraries dir for
255 # library dependencies. 270 # library dependencies.
256 environment['LDFLAGS'] = '%s -L%s/lib' % (ldflags, install_prefix) 271 environment['LDFLAGS'] = '%s -L%s/lib' % (ldflags, install_prefix)
257 272
258 if parsed_arguments.sanitizer_type == 'asan': 273 if parsed_arguments.sanitizer_type == 'asan':
259 # Do not report leaks during the build process. 274 # Do not report leaks during the build process.
260 environment['ASAN_OPTIONS'] = '%s:detect_leaks=0' % \ 275 environment['ASAN_OPTIONS'] = '%s:detect_leaks=0' % \
261 environment.get('ASAN_OPTIONS', '') 276 environment.get('ASAN_OPTIONS', '')
262 277
263 # libappindicator1 needs this. 278 # libappindicator1 needs this.
264 environment['CSC'] = '/usr/bin/mono-csc' 279 environment['CSC'] = '/usr/bin/mono-csc'
265 return environment 280 return environment
266 281
267 282
268 283
269 def download_build_install(parsed_arguments): 284 def download_build_install(parsed_arguments):
270 product_directory = os.path.normpath('%s/%s' % ( 285 product_directory = os.path.normpath('%s/%s' % (
271 get_script_absolute_path(), 286 SCRIPT_ABSOLUTE_PATH,
272 parsed_arguments.product_directory)) 287 parsed_arguments.product_directory))
273 288
274 install_prefix = '%s/instrumented_libraries/%s' % ( 289 install_prefix = '%s/instrumented_libraries/%s' % (
275 product_directory, 290 product_directory,
276 parsed_arguments.sanitizer_type) 291 parsed_arguments.sanitizer_type)
277 292
278 environment = build_environment(parsed_arguments, product_directory, 293 environment = build_environment(parsed_arguments, product_directory,
279 install_prefix) 294 install_prefix)
280 295
281 package_directory = '%s/%s' % (parsed_arguments.intermediate_directory, 296 package_directory = '%s/%s' % (parsed_arguments.intermediate_directory,
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
364 argument_parser.add_argument('--run-before-build', default='') 379 argument_parser.add_argument('--run-before-build', default='')
365 argument_parser.add_argument('--build-method', default='destdir') 380 argument_parser.add_argument('--build-method', default='destdir')
366 argument_parser.add_argument('--sanitizer-blacklist', default='') 381 argument_parser.add_argument('--sanitizer-blacklist', default='')
367 382
368 # Ignore all empty arguments because in several cases gyp passes them to the 383 # Ignore all empty arguments because in several cases gyp passes them to the
369 # script, but ArgumentParser treats them as positional arguments instead of 384 # script, but ArgumentParser treats them as positional arguments instead of
370 # ignoring (and doesn't have such options). 385 # ignoring (and doesn't have such options).
371 parsed_arguments = argument_parser.parse_args( 386 parsed_arguments = argument_parser.parse_args(
372 [arg for arg in sys.argv[1:] if len(arg) != 0]) 387 [arg for arg in sys.argv[1:] if len(arg) != 0])
373 # Ensure current working directory is this script directory. 388 # Ensure current working directory is this script directory.
374 os.chdir(get_script_absolute_path()) 389 os.chdir(SCRIPT_ABSOLUTE_PATH)
375 # Ensure all build dependencies are installed. 390 # Ensure all build dependencies are installed.
376 if parsed_arguments.check_build_deps: 391 if parsed_arguments.check_build_deps:
377 check_package_build_dependencies(parsed_arguments.package) 392 check_package_build_dependencies(parsed_arguments.package)
378 393
379 download_build_install(parsed_arguments) 394 download_build_install(parsed_arguments)
380 395
381 396
382 if __name__ == '__main__': 397 if __name__ == '__main__':
383 main() 398 main()
OLDNEW
« no previous file with comments | « no previous file | third_party/instrumented_libraries/fix_rpaths.sh » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698