Home | History | Annotate | Download | only in gyp
      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 
      9 The native libraries should have previously been pushed to the device (in
     10 options.target_dir). This script then creates links in an apk's lib/ folder to
     11 those native libraries.
     12 """
     13 
     14 import json
     15 import optparse
     16 import os
     17 import sys
     18 
     19 from util import build_device
     20 from util import build_utils
     21 from util import md5_check
     22 
     23 BUILD_ANDROID_DIR = os.path.join(os.path.dirname(__file__), '..')
     24 sys.path.append(BUILD_ANDROID_DIR)
     25 
     26 from pylib.utils import apk_helper
     27 
     28 def RunShellCommand(device, cmd):
     29   output = device.RunShellCommand(cmd)
     30 
     31   if output:
     32     raise Exception(
     33         'Unexpected output running command: ' + cmd + '\n' +
     34         '\n'.join(output))
     35 
     36 
     37 def CreateSymlinkScript(options):
     38   libraries = build_utils.ReadJson(options.libraries_json)
     39 
     40   link_cmd = (
     41       'rm $APK_LIBRARIES_DIR/%(lib_basename)s > /dev/null 2>&1 \n'
     42       'ln -s $STRIPPED_LIBRARIES_DIR/%(lib_basename)s '
     43         '$APK_LIBRARIES_DIR/%(lib_basename)s \n'
     44       )
     45 
     46   script = '#!/bin/sh \n'
     47 
     48   for lib in libraries:
     49     script += link_cmd % { 'lib_basename': lib }
     50 
     51   with open(options.script_host_path, 'w') as scriptfile:
     52     scriptfile.write(script)
     53 
     54 
     55 def TriggerSymlinkScript(options):
     56   device = build_device.GetBuildDeviceFromPath(
     57       options.build_device_configuration)
     58   if not device:
     59     return
     60 
     61   apk_package = apk_helper.GetPackageName(options.apk)
     62   apk_libraries_dir = '/data/data/%s/lib' % apk_package
     63 
     64   device_dir = os.path.dirname(options.script_device_path)
     65   mkdir_cmd = ('if [ ! -e %(dir)s ]; then mkdir -p %(dir)s; fi ' %
     66       { 'dir': device_dir })
     67   RunShellCommand(device, mkdir_cmd)
     68   device.PushIfNeeded(options.script_host_path, options.script_device_path)
     69 
     70   trigger_cmd = (
     71       'APK_LIBRARIES_DIR=%(apk_libraries_dir)s; '
     72       'STRIPPED_LIBRARIES_DIR=%(target_dir)s; '
     73       '. %(script_device_path)s'
     74       ) % {
     75           'apk_libraries_dir': apk_libraries_dir,
     76           'target_dir': options.target_dir,
     77           'script_device_path': options.script_device_path
     78           }
     79   RunShellCommand(device, trigger_cmd)
     80 
     81 
     82 def main(argv):
     83   parser = optparse.OptionParser()
     84   parser.add_option('--apk', help='Path to the apk.')
     85   parser.add_option('--script-host-path',
     86       help='Path on the host for the symlink script.')
     87   parser.add_option('--script-device-path',
     88       help='Path on the device to push the created symlink script.')
     89   parser.add_option('--libraries-json',
     90       help='Path to the json list of native libraries.')
     91   parser.add_option('--target-dir',
     92       help='Device directory that contains the target libraries for symlinks.')
     93   parser.add_option('--stamp', help='Path to touch on success.')
     94   parser.add_option('--build-device-configuration',
     95       help='Path to build device configuration.')
     96   options, _ = parser.parse_args()
     97 
     98   required_options = ['apk', 'libraries_json', 'script_host_path',
     99       'script_device_path', 'target_dir']
    100   build_utils.CheckOptions(options, parser, required=required_options)
    101 
    102   CreateSymlinkScript(options)
    103   TriggerSymlinkScript(options)
    104 
    105   if options.stamp:
    106     build_utils.Touch(options.stamp)
    107 
    108 
    109 if __name__ == '__main__':
    110   sys.exit(main(sys.argv))
    111