-
-
Notifications
You must be signed in to change notification settings - Fork 11.6k
/
Copy pathlinker-wrapper.py
executable file
·93 lines (75 loc) · 3.21 KB
/
linker-wrapper.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
from __future__ import absolute_import, print_function, unicode_literals
import os
import shutil
import subprocess
import sys
rustcc = os.environ['RUST_ANDROID_GRADLE_CC']
if sys.platform == 'msys' or sys.platform == 'cygwin':
import ctypes
cygdll = 'cygwin1.dll' if sys.platform == 'cygwin' else 'msys-2.0.dll'
cygwin = ctypes.cdll.LoadLibrary(cygdll)
def win2posix(path):
CCP_WIN_W_TO_POSIX = 3
size = cygwin.cygwin_conv_path(CCP_WIN_W_TO_POSIX, path, 0, 0)
retval = ctypes.create_string_buffer(size)
cygwin.cygwin_conv_path(CCP_WIN_W_TO_POSIX, path, retval, size)
return retval.value.decode()
rustcc = win2posix(rustcc)
args = [rustcc, os.environ['RUST_ANDROID_GRADLE_CC_LINK_ARG']] + sys.argv[1:]
def cmd_quote(string):
import sys
if int(sys.version[2]) < 3:
import pipes
return pipes.quote(string)
else:
import shlex
return shlex.quote(string)
def update_in_place(arglist):
# The `gcc` library is not included starting from NDK version 23.
# Work around by using `unwind` replacement.
ndk_major_version = os.environ["CARGO_NDK_MAJOR_VERSION"]
if ndk_major_version.isdigit():
if 23 <= int(ndk_major_version):
for i, arg in enumerate(arglist):
if arg.startswith("-lgcc"):
# This is one way to preserve line endings.
arglist[i] = "-lunwind" + arg[len("-lgcc") :]
update_in_place(args)
for arg in args:
if arg.startswith("@"):
fileargs = open(arg[1:], "r").read().splitlines(keepends=True)
update_in_place(fileargs)
open(arg[1:], "w").write("".join(fileargs))
linkargfileName = ''
if (sys.platform == 'msys' or sys.platform == 'cygwin') and len(''.join(args)) > 8191:
import codecs
import tempfile
def posix2win(path):
CCP_POSIX_TO_WIN_W = 1
size = cygwin.cygwin_conv_path(CCP_POSIX_TO_WIN_W, str(path).encode(), 0, 0)
retval = ctypes.create_unicode_buffer(size)
cygwin.cygwin_conv_path(CCP_POSIX_TO_WIN_W, str(path).encode(), retval, size)
return retval.value
# response file should be use UTF-16 with BOM
linkargfile = tempfile.NamedTemporaryFile(delete=False)
linkargfile.write(codecs.BOM_UTF16_LE)
linkargfile.write('\n'.join(sys.argv[1:]).encode('utf-16-le'))
linkargfile.close()
linkargfileName = linkargfile.name
linkargfileNameW = posix2win(linkargfileName)
args = [rustcc, os.environ['RUST_ANDROID_GRADLE_CC_LINK_ARG'], '@' + linkargfileNameW]
# This only appears when the subprocess call fails, but it's helpful then.
printable_cmd = " ".join(cmd_quote(arg) for arg in args)
print(printable_cmd)
code = subprocess.call(args)
if code == 0:
sys_argv = sys.argv
if sys.platform == 'msys' or sys.platform == 'cygwin' or sys.platform == 'win32':
linkargs = list(filter(lambda s: s.startswith('@') and s.find('linker-arguments') != -1, sys.argv[1:]))
if linkargs != []:
with open(linkargs[0][1:]) as f:
sys_argv = f.read().splitlines()
shutil.copyfile(sys_argv[sys_argv.index('-o') + 1], os.environ['RUST_ANDROID_GRADLE_TARGET'])
if linkargfileName != '':
os.unlink(linkargfileName)
sys.exit(code)