diff options
author | Devtools Arcadia <arcadia-devtools@yandex-team.ru> | 2022-02-07 18:08:42 +0300 |
---|---|---|
committer | Devtools Arcadia <arcadia-devtools@mous.vla.yp-c.yandex.net> | 2022-02-07 18:08:42 +0300 |
commit | 1110808a9d39d4b808aef724c861a2e1a38d2a69 (patch) | |
tree | e26c9fed0de5d9873cce7e00bc214573dc2195b7 /build/scripts/link_lib.py | |
download | ydb-1110808a9d39d4b808aef724c861a2e1a38d2a69.tar.gz |
intermediate changes
ref:cde9a383711a11544ce7e107a78147fb96cc4029
Diffstat (limited to 'build/scripts/link_lib.py')
-rw-r--r-- | build/scripts/link_lib.py | 85 |
1 files changed, 85 insertions, 0 deletions
diff --git a/build/scripts/link_lib.py b/build/scripts/link_lib.py new file mode 100644 index 00000000000..344d50d4ebb --- /dev/null +++ b/build/scripts/link_lib.py @@ -0,0 +1,85 @@ +import sys +import subprocess +import tempfile +import os + + +class Opts(object): + def __init__(self, args): + self.archiver = args[0] + self.arch_type = args[1] + self.llvm_ar_format = args[2] + self.build_root = args[3] + self.plugin = args[4] + self.output = args[5] + auto_input = args[6:] + + if self.arch_type == 'GNU_AR': + self.create_flags = ['rcs'] + self.modify_flags = ['-M'] + elif self.arch_type == 'LLVM_AR': + self.create_flags = ['rcs', '-format=%s' % self.llvm_ar_format] + self.modify_flags = ['-M'] + elif self.arch_type == 'LIBTOOL': + self.create_flags = ['-static', '-o'] + self.modify_flags = [] + + need_modify = self.arch_type != 'LIBTOOL' and any(item.endswith('.a') for item in auto_input) + if need_modify: + self.objs = filter(lambda x: x.endswith('.o'), auto_input) + self.libs = filter(lambda x: x.endswith('.a'), auto_input) + else: + self.objs = auto_input + self.libs = [] + + self.plugin_flags = ['--plugin', self.plugin] if self.plugin != 'None' else [] + + +def get_opts(args): + return Opts(args) + + +if __name__ == "__main__": + opts = get_opts(sys.argv[1:]) + + # There is a bug in llvm-ar. Some files with size slightly greater 2^32 + # still have GNU format instead of GNU64 and cause link problems. + # Workaround just lowers llvm-ar's GNU64 threshold to 2^31. + if opts.arch_type == 'LLVM_AR': + os.environ['SYM64_THRESHOLD'] = '31' + + def call(): + try: + p = subprocess.Popen(cmd, stdin=stdin, cwd=opts.build_root) + rc = p.wait() + return rc + except OSError as e: + raise Exception('while running %s: %s' % (' '.join(cmd), e)) + + try: + os.unlink(opts.output) + except OSError: + pass + + if not opts.libs: + cmd = [opts.archiver] + opts.create_flags + opts.plugin_flags + [opts.output] + opts.objs + stdin = None + exit_code = call() + else: + temp = tempfile.NamedTemporaryFile(dir=os.path.dirname(opts.output), delete=False) + + with open(temp.name, 'w') as tmp: + tmp.write('CREATE {0}\n'.format(opts.output)) + for lib in opts.libs: + tmp.write('ADDLIB {0}\n'.format(lib)) + for obj in opts.objs: + tmp.write('ADDMOD {0}\n'.format(obj)) + tmp.write('SAVE\n') + tmp.write('END\n') + cmd = [opts.archiver] + opts.modify_flags + opts.plugin_flags + stdin = open(temp.name) + exit_code = call() + os.remove(temp.name) + + if exit_code != 0: + raise Exception('{0} returned non-zero exit code {1}. Stop.'.format(' '.join(cmd), exit_code)) |