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