diff options
author | alexv-smirnov <alex@ydb.tech> | 2023-06-13 11:05:01 +0300 |
---|---|---|
committer | alexv-smirnov <alex@ydb.tech> | 2023-06-13 11:05:01 +0300 |
commit | bf0f13dd39ee3e65092ba3572bb5b1fcd125dcd0 (patch) | |
tree | 1d1df72c0541a59a81439842f46d95396d3e7189 /build/scripts/link_lib.py | |
parent | 8bfdfa9a9bd19bddbc58d888e180fbd1218681be (diff) | |
download | ydb-bf0f13dd39ee3e65092ba3572bb5b1fcd125dcd0.tar.gz |
add ymake export to ydb
Diffstat (limited to 'build/scripts/link_lib.py')
-rw-r--r-- | build/scripts/link_lib.py | 101 |
1 files changed, 101 insertions, 0 deletions
diff --git a/build/scripts/link_lib.py b/build/scripts/link_lib.py new file mode 100644 index 0000000000..e73c02027a --- /dev/null +++ b/build/scripts/link_lib.py @@ -0,0 +1,101 @@ +import sys +import subprocess +import tempfile +import os +import shutil + + +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:] + + self.need_modify = False + self.extra_args = [] + + if self.arch_type.endswith('_AR'): + 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'] + self.need_modify = any(item.endswith('.a') for item in auto_input) + if self.need_modify: + self.objs = list( filter(lambda x: x.endswith('.o'), auto_input) ) + self.libs = list( filter(lambda x: x.endswith('.a'), auto_input) ) + else: + self.objs = auto_input + self.libs = [] + self.output_opts = [self.output] + elif self.arch_type == 'LIBTOOL': + self.create_flags = ['-static'] + self.objs = auto_input + self.libs = [] + self.output_opts = ['-o', self.output] + elif self.arch_type == 'LIB': + self.create_flags = [] + self.extra_args = list( filter(lambda x: x.startswith('/'), auto_input) ) + self.objs = list( filter(lambda x: not x.startswith('/'), auto_input) ) + self.libs = [] + self.output_opts = ['/OUT:' + self.output] + + 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.need_modify: + cmd = [opts.archiver] + opts.create_flags + opts.plugin_flags + opts.extra_args + opts.output_opts + opts.objs + stdin = None + exit_code = call() + elif len(opts.objs) == 0 and len(opts.libs) == 1: + shutil.copy(opts.libs[0], opts.output) + exit_code = 0 + 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)) |