Send a crash report when a hung process is detected.
[chromium-blink-merge.git] / native_client_sdk / src / build_tools / build_app.py
blob3bf34cd136dc6acade0caf3e5dc2f8eb0381ef06
1 #!/usr/bin/env python
2 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
6 import argparse
7 import json
8 import os
9 import re
10 import sys
12 if sys.version_info < (2, 7, 0):
13 sys.stderr.write("python 2.7 or later is required run this script\n")
14 sys.exit(1)
16 import buildbot_common
17 import build_projects
18 import build_version
19 import easy_template
20 import parse_dsc
22 from build_paths import SDK_SRC_DIR, OUT_DIR, SDK_RESOURCE_DIR
24 sys.path.append(os.path.join(SDK_SRC_DIR, 'tools'))
25 import getos
26 import oshelpers
29 def RemoveBuildCruft(outdir):
30 for root, _, files in os.walk(outdir):
31 for f in files:
32 path = os.path.join(root, f)
33 ext = os.path.splitext(path)[1]
34 # Remove unwanted files from the package. Also remove manifest.json files
35 # (which we usually want). These ones are the manifests of the invidual
36 # examples, though, which CWS complains about. The master manifest.json
37 # is generated after we call RemoveBuildCruft.
38 if (ext in ('.d', '.o') or
39 f == 'dir.stamp' or
40 f == 'manifest.json' or
41 re.search(r'_unstripped_.*?\.nexe', f)):
42 buildbot_common.RemoveFile(path)
45 def StripNexes(outdir, platform, pepperdir):
46 for root, _, files in os.walk(outdir):
47 for f in files:
48 path = os.path.join(root, f)
49 m = re.search(r'lib(32|64).*\.so', path)
50 arch = None
51 if m:
52 # System .so file. Must be x86, because ARM doesn't support glibc yet.
53 arch = 'x86_' + m.group(1)
54 else:
55 basename, ext = os.path.splitext(f)
56 if ext in ('.nexe', '.so'):
57 # We can get the arch from the filename...
58 valid_arches = ('x86_64', 'x86_32', 'arm')
59 for a in valid_arches:
60 if basename.endswith(a):
61 arch = a
62 break
63 if not arch:
64 continue
66 strip = GetStrip(pepperdir, platform, arch, 'newlib')
67 buildbot_common.Run([strip, path])
70 def GetStrip(pepperdir, platform, arch, toolchain):
71 base_arch = {'x86_32': 'x86', 'x86_64': 'x86', 'arm': 'arm'}[arch]
72 bin_dir = os.path.join(pepperdir, 'toolchain',
73 '%s_%s_%s' % (platform, base_arch, toolchain), 'bin')
74 strip_prefix = {'x86_32': 'i686', 'x86_64': 'x86_64', 'arm': 'arm'}[arch]
75 strip_name = '%s-nacl-strip' % strip_prefix
76 return os.path.join(bin_dir, strip_name)
79 def main(args):
80 parser = argparse.ArgumentParser()
81 parser.add_argument('-c', '--channel',
82 help='Channel to display in the name of the package.')
84 # To setup bash completion for this command first install optcomplete
85 # and then add this line to your .bashrc:
86 # complete -F _optcomplete build_app.py
87 try:
88 import optcomplete
89 optcomplete.autocomplete(parser)
90 except ImportError:
91 pass
93 options = parser.parse_args(args)
95 if options.channel:
96 if options.channel not in ('Dev', 'Beta'):
97 parser.error('Unknown channel: %s' % options.channel)
99 toolchains = ['newlib', 'glibc']
101 pepper_ver = str(int(build_version.ChromeMajorVersion()))
102 pepperdir = os.path.join(OUT_DIR, 'pepper_' + pepper_ver)
103 app_dir = os.path.join(OUT_DIR, 'naclsdk_app')
104 app_examples_dir = os.path.join(app_dir, 'examples')
105 sdk_resources_dir = SDK_RESOURCE_DIR
106 platform = getos.GetPlatform()
108 buildbot_common.RemoveDir(app_dir)
109 buildbot_common.MakeDir(app_dir)
111 # Add some dummy directories so build_projects doesn't complain...
112 buildbot_common.MakeDir(os.path.join(app_dir, 'tools'))
113 buildbot_common.MakeDir(os.path.join(app_dir, 'toolchain'))
115 config = 'Release'
117 filters = {}
118 filters['DISABLE_PACKAGE'] = False
119 filters['EXPERIMENTAL'] = False
120 filters['TOOLS'] = toolchains
121 filters['DEST'] = ['examples/api', 'examples/getting_started',
122 'examples/demo', 'examples/tutorial']
123 tree = parse_dsc.LoadProjectTree(SDK_SRC_DIR, include=filters)
124 build_projects.UpdateHelpers(app_dir, clobber=True)
125 build_projects.UpdateProjects(app_dir, tree, clobber=False,
126 toolchains=toolchains, configs=[config],
127 first_toolchain=True)
129 # Collect permissions from each example, and aggregate them.
130 def MergeLists(list1, list2):
131 return list1 + [x for x in list2 if x not in list1]
132 all_permissions = []
133 all_socket_permissions = []
134 all_filesystem_permissions = []
135 for _, project in parse_dsc.GenerateProjects(tree):
136 permissions = project.get('PERMISSIONS', [])
137 all_permissions = MergeLists(all_permissions, permissions)
138 socket_permissions = project.get('SOCKET_PERMISSIONS', [])
139 all_socket_permissions = MergeLists(all_socket_permissions,
140 socket_permissions)
141 filesystem_permissions = project.get('FILESYSTEM_PERMISSIONS', [])
142 all_filesystem_permissions = MergeLists(all_filesystem_permissions,
143 filesystem_permissions)
144 if all_socket_permissions:
145 all_permissions.append({'socket': all_socket_permissions})
146 if all_filesystem_permissions:
147 all_permissions.append({'fileSystem': all_filesystem_permissions})
148 pretty_permissions = json.dumps(all_permissions, sort_keys=True, indent=4)
150 for filename in ['background.js', 'icon128.png']:
151 buildbot_common.CopyFile(os.path.join(sdk_resources_dir, filename),
152 os.path.join(app_examples_dir, filename))
154 os.environ['NACL_SDK_ROOT'] = pepperdir
156 build_projects.BuildProjects(app_dir, tree, deps=False, clean=False,
157 config=config)
159 RemoveBuildCruft(app_dir)
160 StripNexes(app_dir, platform, pepperdir)
162 # Add manifest.json after RemoveBuildCruft... that function removes the
163 # manifest.json files for the individual examples.
164 name = 'Native Client SDK'
165 if options.channel:
166 name += ' (%s)' % options.channel
167 template_dict = {
168 'name': name,
169 'channel': options.channel,
170 'description':
171 'Native Client SDK examples, showing API use and key concepts.',
172 'key': False, # manifests with "key" are rejected when uploading to CWS.
173 'permissions': pretty_permissions,
174 'version': build_version.ChromeVersionNoTrunk()
176 easy_template.RunTemplateFile(
177 os.path.join(sdk_resources_dir, 'manifest.json.template'),
178 os.path.join(app_examples_dir, 'manifest.json'),
179 template_dict)
181 app_zip = os.path.join(app_dir, 'examples.zip')
182 os.chdir(app_examples_dir)
183 oshelpers.Zip([app_zip, '-r', '*'])
185 return 0
188 if __name__ == '__main__':
189 sys.exit(main(sys.argv[1:]))