| #!/usr/bin/env python |
| # Copyright (c) 2013 The Chromium Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| import argparse |
| import json |
| import os |
| import re |
| import sys |
| |
| if sys.version_info < (2, 7, 0): |
| sys.stderr.write("python 2.7 or later is required run this script\n") |
| sys.exit(1) |
| |
| import buildbot_common |
| import build_projects |
| import build_version |
| import easy_template |
| import parse_dsc |
| |
| from build_paths import SDK_SRC_DIR, OUT_DIR, SDK_RESOURCE_DIR |
| |
| sys.path.append(os.path.join(SDK_SRC_DIR, 'tools')) |
| import getos |
| import oshelpers |
| |
| |
| def RemoveBuildCruft(outdir): |
| for root, _, files in os.walk(outdir): |
| for f in files: |
| path = os.path.join(root, f) |
| ext = os.path.splitext(path)[1] |
| # Remove unwanted files from the package. Also remove manifest.json files |
| # (which we usually want). These ones are the manifests of the invidual |
| # examples, though, which CWS complains about. The master manifest.json |
| # is generated after we call RemoveBuildCruft. |
| if (ext in ('.d', '.o') or |
| f == 'dir.stamp' or |
| f == 'manifest.json' or |
| re.search(r'_unstripped_.*?\.nexe', f)): |
| buildbot_common.RemoveFile(path) |
| |
| |
| def StripNexes(outdir, platform, pepperdir): |
| for root, _, files in os.walk(outdir): |
| for f in files: |
| path = os.path.join(root, f) |
| m = re.search(r'lib(32|64).*\.so', path) |
| arch = None |
| if m: |
| # System .so file. Must be x86, because ARM doesn't support glibc yet. |
| arch = 'x86_' + m.group(1) |
| else: |
| basename, ext = os.path.splitext(f) |
| if ext in ('.nexe', '.so'): |
| # We can get the arch from the filename... |
| valid_arches = ('x86_64', 'x86_32', 'arm') |
| for a in valid_arches: |
| if basename.endswith(a): |
| arch = a |
| break |
| if not arch: |
| continue |
| |
| strip = GetStrip(pepperdir, platform, arch, 'newlib') |
| buildbot_common.Run([strip, path]) |
| |
| |
| def GetStrip(pepperdir, platform, arch, toolchain): |
| base_arch = {'x86_32': 'x86', 'x86_64': 'x86', 'arm': 'arm'}[arch] |
| bin_dir = os.path.join(pepperdir, 'toolchain', |
| '%s_%s_%s' % (platform, base_arch, toolchain), 'bin') |
| strip_prefix = {'x86_32': 'i686', 'x86_64': 'x86_64', 'arm': 'arm'}[arch] |
| strip_name = '%s-nacl-strip' % strip_prefix |
| return os.path.join(bin_dir, strip_name) |
| |
| |
| def main(args): |
| parser = argparse.ArgumentParser() |
| parser.add_argument('-c', '--channel', |
| help='Channel to display in the name of the package.') |
| |
| # To setup bash completion for this command first install optcomplete |
| # and then add this line to your .bashrc: |
| # complete -F _optcomplete build_app.py |
| try: |
| import optcomplete |
| optcomplete.autocomplete(parser) |
| except ImportError: |
| pass |
| |
| options = parser.parse_args(args) |
| |
| if options.channel: |
| if options.channel not in ('Dev', 'Beta'): |
| parser.error('Unknown channel: %s' % options.channel) |
| |
| toolchains = ['newlib', 'glibc'] |
| |
| pepper_ver = str(int(build_version.ChromeMajorVersion())) |
| pepperdir = os.path.join(OUT_DIR, 'pepper_' + pepper_ver) |
| app_dir = os.path.join(OUT_DIR, 'naclsdk_app') |
| app_examples_dir = os.path.join(app_dir, 'examples') |
| sdk_resources_dir = SDK_RESOURCE_DIR |
| platform = getos.GetPlatform() |
| |
| buildbot_common.RemoveDir(app_dir) |
| buildbot_common.MakeDir(app_dir) |
| |
| # Add some dummy directories so build_projects doesn't complain... |
| buildbot_common.MakeDir(os.path.join(app_dir, 'tools')) |
| buildbot_common.MakeDir(os.path.join(app_dir, 'toolchain')) |
| |
| config = 'Release' |
| |
| filters = {} |
| filters['DISABLE_PACKAGE'] = False |
| filters['EXPERIMENTAL'] = False |
| filters['TOOLS'] = toolchains |
| filters['DEST'] = ['examples/api', 'examples/getting_started', |
| 'examples/demo', 'examples/tutorial'] |
| tree = parse_dsc.LoadProjectTree(SDK_SRC_DIR, include=filters) |
| build_projects.UpdateHelpers(app_dir, clobber=True) |
| build_projects.UpdateProjects(app_dir, tree, clobber=False, |
| toolchains=toolchains, configs=[config], |
| first_toolchain=True) |
| |
| # Collect permissions from each example, and aggregate them. |
| def MergeLists(list1, list2): |
| return list1 + [x for x in list2 if x not in list1] |
| all_permissions = [] |
| all_socket_permissions = [] |
| all_filesystem_permissions = [] |
| for _, project in parse_dsc.GenerateProjects(tree): |
| permissions = project.get('PERMISSIONS', []) |
| all_permissions = MergeLists(all_permissions, permissions) |
| socket_permissions = project.get('SOCKET_PERMISSIONS', []) |
| all_socket_permissions = MergeLists(all_socket_permissions, |
| socket_permissions) |
| filesystem_permissions = project.get('FILESYSTEM_PERMISSIONS', []) |
| all_filesystem_permissions = MergeLists(all_filesystem_permissions, |
| filesystem_permissions) |
| if all_socket_permissions: |
| all_permissions.append({'socket': all_socket_permissions}) |
| if all_filesystem_permissions: |
| all_permissions.append({'fileSystem': all_filesystem_permissions}) |
| pretty_permissions = json.dumps(all_permissions, sort_keys=True, indent=4) |
| |
| for filename in ['background.js', 'icon128.png']: |
| buildbot_common.CopyFile(os.path.join(sdk_resources_dir, filename), |
| os.path.join(app_examples_dir, filename)) |
| |
| os.environ['NACL_SDK_ROOT'] = pepperdir |
| |
| build_projects.BuildProjects(app_dir, tree, deps=False, clean=False, |
| config=config) |
| |
| RemoveBuildCruft(app_dir) |
| StripNexes(app_dir, platform, pepperdir) |
| |
| # Add manifest.json after RemoveBuildCruft... that function removes the |
| # manifest.json files for the individual examples. |
| name = 'Native Client SDK' |
| if options.channel: |
| name += ' (%s)' % options.channel |
| template_dict = { |
| 'name': name, |
| 'channel': options.channel, |
| 'description': |
| 'Native Client SDK examples, showing API use and key concepts.', |
| 'key': False, # manifests with "key" are rejected when uploading to CWS. |
| 'permissions': pretty_permissions, |
| 'version': build_version.ChromeVersionNoTrunk() |
| } |
| easy_template.RunTemplateFile( |
| os.path.join(sdk_resources_dir, 'manifest.json.template'), |
| os.path.join(app_examples_dir, 'manifest.json'), |
| template_dict) |
| |
| app_zip = os.path.join(app_dir, 'examples.zip') |
| os.chdir(app_examples_dir) |
| oshelpers.Zip([app_zip, '-r', '*']) |
| |
| return 0 |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main(sys.argv[1:])) |