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 import constants
     27 from pylib.utils import apk_helper
     28 
     29 def RunShellCommand(device, cmd):
     30   output = device.RunShellCommand(cmd)
     31 
     32   if output:
     33     raise Exception(
     34         'Unexpected output running command: ' + cmd + '\n' +
     35         '\n'.join(output))
     36 
     37 
     38 def CreateSymlinkScript(options):
     39   libraries = build_utils.ReadJson(options.libraries_json)
     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 
     56 def 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.PushIfNeeded(options.script_host_path, options.script_device_path)
     70 
     71   trigger_cmd = (
     72       'APK_LIBRARIES_DIR=%(apk_libraries_dir)s; '
     73       'STRIPPED_LIBRARIES_DIR=%(target_dir)s; '
     74       '. %(script_device_path)s'
     75       ) % {
     76           'apk_libraries_dir': apk_libraries_dir,
     77           'target_dir': options.target_dir,
     78           'script_device_path': options.script_device_path
     79           }
     80   RunShellCommand(device, trigger_cmd)
     81 
     82 
     83 def main(argv):
     84   parser = optparse.OptionParser()
     85   parser.add_option('--apk', help='Path to the apk.')
     86   parser.add_option('--script-host-path',
     87       help='Path on the host for the symlink script.')
     88   parser.add_option('--script-device-path',
     89       help='Path on the device to push the created symlink script.')
     90   parser.add_option('--libraries-json',
     91       help='Path to the json list of native libraries.')
     92   parser.add_option('--target-dir',
     93       help='Device directory that contains the target libraries for symlinks.')
     94   parser.add_option('--stamp', help='Path to touch on success.')
     95   parser.add_option('--build-device-configuration',
     96       help='Path to build device configuration.')
     97   parser.add_option('--configuration-name',
     98       help='The build CONFIGURATION_NAME')
     99   options, _ = parser.parse_args()
    100 
    101   required_options = ['apk', 'libraries_json', 'script_host_path',
    102       'script_device_path', 'target_dir', 'configuration_name']
    103   build_utils.CheckOptions(options, parser, required=required_options)
    104   constants.SetBuildType(options.configuration_name)
    105 
    106   CreateSymlinkScript(options)
    107   TriggerSymlinkScript(options)
    108 
    109   if options.stamp:
    110     build_utils.Touch(options.stamp)
    111 
    112 
    113 if __name__ == '__main__':
    114   sys.exit(main(sys.argv))
    115