link_fat_obj.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. import argparse
  2. import subprocess
  3. import sys, os
  4. # Explicitly enable local imports
  5. # Don't forget to add imported scripts to inputs of the calling command!
  6. sys.path.append(os.path.dirname(os.path.abspath(__file__)))
  7. import process_command_files as pcf
  8. from process_whole_archive_option import ProcessWholeArchiveOption
  9. YA_ARG_PREFIX = '-Ya,'
  10. def flt_args():
  11. for a in sys.argv[1:]:
  12. if a.startswith('-l'):
  13. # skip -lxxx args
  14. pass
  15. else:
  16. yield a
  17. def get_args():
  18. parser = argparse.ArgumentParser()
  19. parser.add_argument('--obj')
  20. parser.add_argument('--globals-lib')
  21. parser.add_argument('--lib', required=True)
  22. parser.add_argument('--arch', required=True)
  23. parser.add_argument('--build-root', default=None)
  24. parser.add_argument('--with-own-obj', action='store_true', default=False)
  25. parser.add_argument('--with-global-srcs', action='store_true', default=False)
  26. groups = {}
  27. args_list = groups.setdefault('default', [])
  28. for arg in pcf.iter_args(list(flt_args())):
  29. if arg == '--with-own-obj':
  30. groups['default'].append(arg)
  31. elif arg == '--globals-lib':
  32. groups['default'].append(arg)
  33. elif arg == '--with-global-srcs':
  34. groups['default'].append(arg)
  35. elif arg.startswith(YA_ARG_PREFIX):
  36. group_name = arg[len(YA_ARG_PREFIX) :]
  37. args_list = groups.setdefault(group_name, [])
  38. else:
  39. args_list.append(arg)
  40. return parser.parse_args(groups['default']), groups
  41. def strip_suppression_files(srcs):
  42. return [s for s in srcs if not s.endswith('.supp')]
  43. def strip_forceload_prefix(srcs):
  44. force_load_prefix = '-Wl,-force_load,'
  45. return list(map(lambda lib: lib[lib.startswith(force_load_prefix) and len(force_load_prefix) :], srcs))
  46. def main():
  47. args, groups = get_args()
  48. # Inputs
  49. auto_input = groups['input']
  50. # Outputs
  51. lib_output = args.lib
  52. obj_output = args.obj
  53. # Dependencies
  54. global_srcs = groups['global_srcs']
  55. global_srcs = strip_suppression_files(global_srcs)
  56. global_srcs = ProcessWholeArchiveOption(args.arch).construct_cmd(global_srcs)
  57. global_srcs = strip_forceload_prefix(global_srcs)
  58. peers = groups['peers']
  59. # Tools
  60. linker = groups['linker']
  61. archiver = groups['archiver']
  62. do_link = (
  63. linker + ['-o', obj_output, '-Wl,-r', '-nodefaultlibs', '-nostartfiles', '-Wl,-no-pie'] + global_srcs + auto_input
  64. )
  65. do_archive = archiver + [lib_output] + peers
  66. do_globals = None
  67. if args.globals_lib:
  68. do_globals = archiver + [args.globals_lib] + auto_input + global_srcs
  69. if args.with_own_obj:
  70. do_archive += auto_input
  71. if args.with_global_srcs:
  72. do_archive += global_srcs
  73. def call(c):
  74. proc = subprocess.Popen(c, shell=False, stderr=sys.stderr, stdout=sys.stdout, cwd=args.build_root)
  75. proc.communicate()
  76. return proc.returncode
  77. if obj_output:
  78. link_res = call(do_link)
  79. if link_res:
  80. sys.exit(link_res)
  81. if do_globals:
  82. glob_res = call(do_globals)
  83. if glob_res:
  84. sys.exit(glob_res)
  85. sys.exit(call(do_archive))
  86. if __name__ == '__main__':
  87. main()