| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 #!/usr/bin/env python |  | 
| 2 |  | 
| 3 # Copyright (c) 2016 The Dart 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 """ |  | 
| 8 This script performs the final link step for Fuchsia NDK executables. |  | 
| 9 Usage: |  | 
| 10 ./fuchsia_link {arm,arm64,ia32} {executable,library,shared_library} |  | 
| 11                {host,target} [linker args] |  | 
| 12 """ |  | 
| 13 |  | 
| 14 import os |  | 
| 15 import subprocess |  | 
| 16 import sys |  | 
| 17 |  | 
| 18 # Figure out where we are. |  | 
| 19 SCRIPT_DIR = os.path.dirname(sys.argv[0]) |  | 
| 20 DART_ROOT = os.path.realpath(os.path.join(SCRIPT_DIR, '..')) |  | 
| 21 THIRD_PARTY_ROOT = os.path.join(DART_ROOT, 'third_party') |  | 
| 22 |  | 
| 23 |  | 
| 24 def CheckDirExists(path, docstring): |  | 
| 25   if not os.path.isdir(path): |  | 
| 26     raise Exception('Could not find %s directory %s' |  | 
| 27           % (docstring, path)) |  | 
| 28 |  | 
| 29 |  | 
| 30 def execute(args): |  | 
| 31   process = subprocess.Popen(args) |  | 
| 32   process.wait() |  | 
| 33   return process.returncode |  | 
| 34 |  | 
| 35 |  | 
| 36 def main(): |  | 
| 37   if len(sys.argv) < 5: |  | 
| 38     raise Exception(sys.argv[0] + " failed: not enough arguments") |  | 
| 39 |  | 
| 40   # gyp puts -shared first in a shared_library link. Remove it. |  | 
| 41   if sys.argv[1] == '-shared': |  | 
| 42     sys.argv.remove('-shared') |  | 
| 43 |  | 
| 44   # Grab the command line arguments. |  | 
| 45   target_arch = sys.argv[1] |  | 
| 46   link_type = sys.argv[2] |  | 
| 47   link_target = sys.argv[3] |  | 
| 48   link_args = sys.argv[4:] |  | 
| 49 |  | 
| 50   # Check arguments. |  | 
| 51   if target_arch not in ['arm64', 'x64',]: |  | 
| 52     raise Exception(sys.argv[0] + |  | 
| 53         " first argument must be 'arm64', or 'x64'") |  | 
| 54   if link_type not in ['executable', 'library', 'shared_library']: |  | 
| 55     raise Exception(sys.argv[0] + |  | 
| 56       " second argument must be 'executable' or 'library' or 'shared_library'") |  | 
| 57   if link_target not in ['host', 'target']: |  | 
| 58     raise Exception(sys.argv[0] + " third argument must be 'host' or 'target'") |  | 
| 59 |  | 
| 60   # TODO(zra): Figure out how to link a shared library with the |  | 
| 61   # cross-compilers. For now, we disable it by generating empty files |  | 
| 62   # for the results. We disable it here to avoid inspecting the OS type in |  | 
| 63   # the gyp files. |  | 
| 64   if link_type == 'shared_library': |  | 
| 65     print "NOT linking shared library for Fuchsia." |  | 
| 66     o_index = link_args.index('-o') |  | 
| 67     output = os.path.join(DART_ROOT, link_args[o_index + 1]) |  | 
| 68     open(output, 'a').close() |  | 
| 69     sys.exit(0) |  | 
| 70 |  | 
| 71   # Set up path to the Fuchsia NDK. |  | 
| 72   CheckDirExists(THIRD_PARTY_ROOT, 'third party tools') |  | 
| 73   fuchsia_tools = os.path.join(THIRD_PARTY_ROOT, 'fuchsia_tools') |  | 
| 74   CheckDirExists(fuchsia_tools, 'Fuchsia tools') |  | 
| 75 |  | 
| 76   # Set up the directory of the Fuchsia NDK cross-compiler toolchain. |  | 
| 77   toolchain_arch = 'x86_64-elf-5.3.0-Linux-x86_64' |  | 
| 78   if target_arch == 'arm64': |  | 
| 79     toolchain_arch = 'aarch64-elf-5.3.0-Linux-x86_64' |  | 
| 80   fuchsia_toolchain = os.path.join( |  | 
| 81       fuchsia_tools, 'toolchains', toolchain_arch, 'bin') |  | 
| 82   CheckDirExists(fuchsia_toolchain, 'Fuchsia toolchain') |  | 
| 83 |  | 
| 84   # Set up the path to the linker executable. |  | 
| 85   fuchsia_linker = os.path.join(fuchsia_toolchain, 'x86_64-elf-g++') |  | 
| 86   if target_arch == 'arm64': |  | 
| 87     fuchsia_linker = os.path.join(fuchsia_toolchain, 'aarch64-elf-c++') |  | 
| 88 |  | 
| 89   # Grab the path to libgcc.a, which we must explicitly add to the link, |  | 
| 90   # by invoking the cross-compiler with the -print-libgcc-file-name flag. |  | 
| 91   fuchsia_gcc = os.path.join(fuchsia_toolchain, 'x86_64-elf-gcc') |  | 
| 92   if target_arch == 'arm64': |  | 
| 93     fuchsia_gcc = os.path.join(fuchsia_toolchain, 'aarch64-elf-gcc') |  | 
| 94   fuchsia_libgcc = subprocess.check_output( |  | 
| 95       [fuchsia_gcc, '-print-libgcc-file-name']).strip() |  | 
| 96 |  | 
| 97   # Set up the path to the system root directory, which is where we'll find the |  | 
| 98   # Fuchsia specific system includes and libraries. |  | 
| 99   fuchsia_sysroot = os.path.join(fuchsia_tools, 'sysroot', 'x86_64') |  | 
| 100   if target_arch == 'arm64': |  | 
| 101     fuchsia_sysroot = os.path.join(fuchsia_tools, 'sysroot', 'arm64') |  | 
| 102   CheckDirExists(fuchsia_sysroot, 'Fuchsia sysroot') |  | 
| 103   fuchsia_lib = os.path.join(fuchsia_sysroot, 'usr', 'lib') |  | 
| 104   crtn_fuchsia = os.path.join(fuchsia_lib, 'crtn.o') |  | 
| 105 |  | 
| 106   if link_target == 'target': |  | 
| 107     # Add and remove libraries as listed in configurations_fuchsia.gypi |  | 
| 108     libs_to_rm = ['-lrt', '-lpthread'] |  | 
| 109     libs_to_add = [fuchsia_libgcc, '-lc', '-ldl', '-lm'] |  | 
| 110 |  | 
| 111     # Add crtn_fuchsia to end if we are linking an executable. |  | 
| 112     if link_type == 'executable': |  | 
| 113       libs_to_add.extend([crtn_fuchsia]) |  | 
| 114 |  | 
| 115     link_args = [i for i in link_args if i not in libs_to_rm] |  | 
| 116     link_args.extend(libs_to_add) |  | 
| 117 |  | 
| 118     link_args.insert(0, fuchsia_linker) |  | 
| 119   else: |  | 
| 120     link_args.extend(['-ldl', '-lrt']) |  | 
| 121     link_args.insert(0, 'g++') |  | 
| 122 |  | 
| 123   print ' '.join(link_args) |  | 
| 124   sys.exit(execute(link_args)) |  | 
| 125 |  | 
| 126 if __name__ == '__main__': |  | 
| 127   main() |  | 
| OLD | NEW | 
|---|