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 |