Output better error messages during build

The python build scripts use subprocess.check_call() for external
commands (aapt, javac, etc). On a failure, it prints the python
stacktrace, followed by the command being run (in a form that can be
copy-pasted and actually work), followed by the output from the command.

Previously, it was printing command output, then command, then
stacktrace which is much less useful.


Review URL: https://chromiumcodereview.appspot.com/12913028

git-svn-id: http://src.chromium.org/svn/trunk/src/build@191300 4ff67af0-8c30-449e-8e8b-ad334ec8d88c
This commit is contained in:
cjhopman@chromium.org 2013-03-29 05:06:32 +00:00
Родитель 7ec0ffc678
Коммит 2ddf6003dc
6 изменённых файлов: 50 добавлений и 15 удалений

Просмотреть файл

@ -7,7 +7,6 @@
import fnmatch
import optparse
import os
import subprocess
import sys
from pylib import build_utils
@ -16,7 +15,7 @@ from pylib import build_utils
def DoDex(options, paths):
dx_binary = os.path.join(options.android_sdk_root, 'platform-tools', 'dx')
dex_cmd = [dx_binary, '--dex', '--output', options.dex_path] + paths
subprocess.check_call(dex_cmd)
build_utils.CheckCallDie(dex_cmd)
def main(argv):

Просмотреть файл

@ -7,7 +7,6 @@
import fnmatch
import optparse
import os
import subprocess
import sys
from pylib import build_utils
@ -27,7 +26,7 @@ def DoJar(options):
jar_cwd = options.classes_dir
class_files = [os.path.relpath(f, jar_cwd) for f in class_files]
jar_cmd = ['jar', 'cf0', jar_path] + class_files
subprocess.check_call(jar_cmd, cwd=jar_cwd)
build_utils.CheckCallDie(jar_cmd, cwd=jar_cwd)
def main(argv):

Просмотреть файл

@ -7,7 +7,6 @@
import fnmatch
import optparse
import os
import subprocess
import sys
from pylib import build_utils
@ -41,7 +40,7 @@ def DoJavac(options):
build_utils.DeleteDirectory(output_dir)
build_utils.MakeDirectory(output_dir)
subprocess.check_call([
build_utils.CheckCallDie([
'javac',
'-g',
'-Xlint:unchecked',

Просмотреть файл

@ -9,7 +9,6 @@
import optparse
import os
import shlex
import subprocess
from pylib import build_utils
@ -80,17 +79,20 @@ def main():
package_command.append('--non-constant-id')
if options.custom_package:
package_command += ['--custom-package', options.custom_package]
subprocess.check_call(package_command)
build_utils.CheckCallDie(package_command)
# Crunch image resources. This shrinks png files and is necessary for 9-patch
# images to display correctly.
build_utils.MakeDirectory(options.crunch_output_dir)
subprocess.check_call([aapt,
'crunch',
'-S', options.crunch_input_dir,
'-C', options.crunch_output_dir])
build_utils.Touch(options.stamp)
aapt_cmd = [aapt,
'crunch',
'-S', options.crunch_input_dir,
'-C', options.crunch_output_dir]
build_utils.CheckCallDie(aapt_cmd)
if options.stamp:
build_utils.Touch(options.stamp)
if __name__ == '__main__':

Просмотреть файл

@ -4,8 +4,12 @@
import fnmatch
import os
import pipes
import shlex
import shutil
import subprocess
import sys
import traceback
def MakeDirectory(dir_path):
@ -51,3 +55,36 @@ def ParseGypList(gyp_string):
return shlex.split(gyp_string)
# This can be used in most cases like subprocess.check_call. The output,
# particularly when the command fails, better highlights the command's failure.
# This call will directly exit on a failure in the subprocess so that no python
# stacktrace is printed after the output of the failed command.
def CheckCallDie(args, cwd=None):
if not cwd:
cwd = os.getcwd()
child = subprocess.Popen(args,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, cwd=cwd)
stdout, _ = child.communicate()
if child.returncode:
stacktrace = traceback.extract_stack()
print >> sys.stderr, ''.join(traceback.format_list(stacktrace))
# A user should be able to simply copy and paste the command that failed
# into their shell.
copyable_command = ' '.join(map(pipes.quote, args))
copyable_command = ('( cd ' + os.path.abspath(cwd) + '; '
+ copyable_command + ' )')
print >> sys.stderr, 'Command failed:', copyable_command, '\n'
if stdout:
print stdout,
# Directly exit to avoid printing stacktrace.
sys.exit(child.returncode)
else:
if stdout:
print stdout,

Просмотреть файл

@ -6,7 +6,6 @@
import optparse
import os
import subprocess
import sys
from pylib import build_utils
@ -16,7 +15,7 @@ def StripLibrary(android_strip, android_strip_args, library_path, output_path):
strip_cmd = ([android_strip] +
android_strip_args +
['-o', output_path, library_path])
subprocess.check_call(strip_cmd)
build_utils.CheckCallDie(strip_cmd)
def main(argv):