• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python
2#
3# Copyright 2013 The Chromium Authors. All rights reserved.
4# Use of this source code is governed by a BSD-style license that can be
5# found in the LICENSE file.
6
7"""Creates symlinks to native libraries for an APK.
8
9The native libraries should have previously been pushed to the device (in
10options.target_dir). This script then creates links in an apk's lib/ folder to
11those native libraries.
12"""
13
14import optparse
15import os
16import sys
17
18from util import build_device
19from util import build_utils
20
21BUILD_ANDROID_DIR = os.path.abspath(
22    os.path.join(os.path.dirname(__file__), '..'))
23sys.path.append(BUILD_ANDROID_DIR)
24
25import devil_chromium
26from devil.android import apk_helper
27from pylib import constants
28
29def RunShellCommand(device, cmd):
30  output = device.RunShellCommand(cmd, check_return=True)
31
32  if output:
33    raise Exception(
34        'Unexpected output running command: ' + cmd + '\n' +
35        '\n'.join(output))
36
37
38def CreateSymlinkScript(options):
39  libraries = build_utils.ParseGypList(options.libraries)
40
41  link_cmd = (
42      'rm $APK_LIBRARIES_DIR/%(lib_basename)s > /dev/null 2>&1 \n'
43      'ln -s $STRIPPED_LIBRARIES_DIR/%(lib_basename)s '
44        '$APK_LIBRARIES_DIR/%(lib_basename)s \n'
45      )
46
47  script = '#!/bin/sh \n'
48
49  for lib in libraries:
50    script += link_cmd % { 'lib_basename': lib }
51
52  with open(options.script_host_path, 'w') as scriptfile:
53    scriptfile.write(script)
54
55
56def TriggerSymlinkScript(options):
57  device = build_device.GetBuildDeviceFromPath(
58      options.build_device_configuration)
59  if not device:
60    return
61
62  apk_package = apk_helper.GetPackageName(options.apk)
63  apk_libraries_dir = '/data/data/%s/lib' % apk_package
64
65  device_dir = os.path.dirname(options.script_device_path)
66  mkdir_cmd = ('if [ ! -e %(dir)s ]; then mkdir -p %(dir)s; fi ' %
67      { 'dir': device_dir })
68  RunShellCommand(device, mkdir_cmd)
69  device.PushChangedFiles([(os.path.abspath(options.script_host_path),
70                            options.script_device_path)])
71
72  trigger_cmd = (
73      'APK_LIBRARIES_DIR=%(apk_libraries_dir)s; '
74      'STRIPPED_LIBRARIES_DIR=%(target_dir)s; '
75      '. %(script_device_path)s'
76      ) % {
77          'apk_libraries_dir': apk_libraries_dir,
78          'target_dir': options.target_dir,
79          'script_device_path': options.script_device_path
80          }
81  RunShellCommand(device, trigger_cmd)
82
83
84def main(args):
85  args = build_utils.ExpandFileArgs(args)
86  parser = optparse.OptionParser()
87  parser.add_option('--apk', help='Path to the apk.')
88  parser.add_option('--script-host-path',
89      help='Path on the host for the symlink script.')
90  parser.add_option('--script-device-path',
91      help='Path on the device to push the created symlink script.')
92  parser.add_option('--libraries',
93      help='List of native libraries.')
94  parser.add_option('--target-dir',
95      help='Device directory that contains the target libraries for symlinks.')
96  parser.add_option('--stamp', help='Path to touch on success.')
97  parser.add_option('--build-device-configuration',
98      help='Path to build device configuration.')
99  parser.add_option('--configuration-name',
100      help='The build CONFIGURATION_NAME')
101  parser.add_option('--output-directory',
102      help='The output directory')
103  options, _ = parser.parse_args(args)
104
105  required_options = ['apk', 'libraries', 'script_host_path',
106      'script_device_path', 'target_dir', 'configuration_name']
107  build_utils.CheckOptions(options, parser, required=required_options)
108  constants.SetBuildType(options.configuration_name)
109
110  devil_chromium.Initialize(
111      output_directory=os.path.abspath(options.output_directory))
112
113  CreateSymlinkScript(options)
114  TriggerSymlinkScript(options)
115
116  if options.stamp:
117    build_utils.Touch(options.stamp)
118
119
120if __name__ == '__main__':
121  sys.exit(main(sys.argv[1:]))
122