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.join(os.path.dirname(__file__), '..') 22sys.path.append(BUILD_ANDROID_DIR) 23 24from pylib import constants 25from pylib.utils import apk_helper 26 27def 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 36def CreateSymlinkScript(options): 37 libraries = build_utils.ParseGypList(options.libraries) 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 54def 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.PushChangedFiles(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 81def main(args): 82 args = build_utils.ExpandFileArgs(args) 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', 90 help='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 parser.add_option('--configuration-name', 97 help='The build CONFIGURATION_NAME') 98 options, _ = parser.parse_args(args) 99 100 required_options = ['apk', 'libraries', 'script_host_path', 101 'script_device_path', 'target_dir', 'configuration_name'] 102 build_utils.CheckOptions(options, parser, required=required_options) 103 constants.SetBuildType(options.configuration_name) 104 105 CreateSymlinkScript(options) 106 TriggerSymlinkScript(options) 107 108 if options.stamp: 109 build_utils.Touch(options.stamp) 110 111 112if __name__ == '__main__': 113 sys.exit(main(sys.argv[1:])) 114