diff --git a/core/src/main/rust/linker-wrapper.py b/core/src/main/rust/linker-wrapper.py index 80dc1888b9..2bb0217f8d 100755 --- a/core/src/main/rust/linker-wrapper.py +++ b/core/src/main/rust/linker-wrapper.py @@ -6,7 +6,46 @@ import subprocess import sys -args = [os.environ['RUST_ANDROID_GRADLE_CC'], os.environ['RUST_ANDROID_GRADLE_CC_LINK_ARG']] + sys.argv[1:] +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:] + +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(pipes.quote(arg) for arg in args) @@ -14,5 +53,13 @@ code = subprocess.call(args) if code == 0: - shutil.copyfile(sys.argv[sys.argv.index('-o') + 1], os.environ['RUST_ANDROID_GRADLE_TARGET']) + 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)