1#!/usr/bin/env python 2# -*- coding: utf-8 -*- 3# Copyright 2015 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"""Runs a linking command and optionally a strip command. 7 8This script exists to avoid using complex shell commands in 9gcc_toolchain.gni's tool("link"), in case the host running the compiler 10does not have a POSIX-like shell (e.g. Windows). 11""" 12 13import argparse 14import os 15import subprocess 16import sys 17 18import wrapper_utils 19 20# When running on a Windows host and using a toolchain whose tools are 21# actually wrapper scripts (i.e. .bat files on Windows) rather than binary 22# executables, the "command" to run has to be prefixed with this magic. 23# The GN toolchain definitions take care of that for when GN/Ninja is 24# running the tool directly. When that command is passed in to this 25# script, it appears as a unitary string but needs to be split up so that 26# just 'cmd' is the actual command given to Python's subprocess module. 27BAT_PREFIX = 'cmd /c call ' 28 29 30def command_to_run(command): 31 if command[0].startswith(BAT_PREFIX): 32 command = command[0].split(None, 3) + command[1:] 33 return command 34 35 36def is_static_link(command): 37 if "-static" in command: 38 return True 39 else: 40 return False 41 42 43""" since static link and dynamic link have different CRT files on ohos, 44and we use dynamic link CRT files as default, so when link statically, 45we need change the CRT files 46""" 47 48 49def update_crt(command): 50 for item in command: 51 if str(item).find("crtbegin_dynamic.o") >= 0: 52 index = command.index(item) 53 new_crtbegin = str(item).replace("crtbegin_dynamic.o", 54 "crtbegin_static.o") 55 command[index] = new_crtbegin 56 return command 57 58 59def main(): 60 parser = argparse.ArgumentParser(description=__doc__) 61 parser.add_argument('--strip', 62 help='The strip binary to run', 63 metavar='PATH') 64 parser.add_argument('--unstripped-file', 65 help='Executable file produced by linking command', 66 metavar='FILE') 67 parser.add_argument('--map-file', 68 help=('Use --Wl,-Map to generate a map file. Will be ' 69 'gzipped if extension ends with .gz'), 70 metavar='FILE') 71 parser.add_argument('--output', 72 required=True, 73 help='Final output executable file', 74 metavar='FILE') 75 parser.add_argument('--clang_rt_dso_path', 76 help=('Clang asan runtime shared library')) 77 parser.add_argument('command', nargs='+', help='Linking command') 78 parser.add_argument('--mini-debug', 79 action='store_true', 80 default=False, 81 help='Add .gnu_debugdata section for stripped sofile') 82 parser.add_argument('--clang-base-dir', help='') 83 args = parser.parse_args() 84 85 # Work-around for gold being slow-by-default. http://crbug.com/632230 86 fast_env = dict(os.environ) 87 fast_env['LC_ALL'] = 'C' 88 if is_static_link(args.command): 89 command = update_crt(args.command) 90 if args.clang_rt_dso_path is not None: 91 return 0 92 else: 93 command = args.command 94 result = wrapper_utils.run_link_with_optional_map_file( 95 command, env=fast_env, map_file=args.map_file) 96 if result != 0: 97 return result 98 99 # Finally, strip the linked executable (if desired). 100 if args.strip: 101 result = subprocess.call( 102 command_to_run( 103 [args.strip, '-o', args.output, args.unstripped_file])) 104 105 if args.mini_debug and not args.unstripped_file.endswith(".exe") and not args.unstripped_file.endswith(".dll"): 106 unstripped_libfile = os.path.abspath(args.unstripped_file) 107 script_path = os.path.join( 108 os.path.dirname(__file__), 'mini_debug_info.py') 109 ohos_root_path = os.path.join(os.path.dirname(__file__), '../..') 110 result = subprocess.call( 111 wrapper_utils.command_to_run( 112 ['python3', script_path, '--unstripped-path', unstripped_libfile, '--stripped-path', args.output, 113 '--root-path', ohos_root_path, '--clang-base-dir', args.clang_base_dir])) 114 115 return result 116 117 118if __name__ == "__main__": 119 sys.exit(main()) 120