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