link_exe.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. import itertools
  2. import os
  3. import os.path
  4. import sys
  5. import json
  6. import subprocess
  7. import optparse
  8. import textwrap
  9. # Explicitly enable local imports
  10. # Don't forget to add imported scripts to inputs of the calling command!
  11. sys.path.append(os.path.dirname(os.path.abspath(__file__)))
  12. import process_command_files as pcf
  13. import thinlto_cache
  14. from process_whole_archive_option import ProcessWholeArchiveOption
  15. def remove_excessive_flags(cmd):
  16. flags = []
  17. for flag in cmd:
  18. if not flag.endswith('.ios.interface') and not flag.endswith('.pkg.fake'):
  19. flags.append(flag)
  20. return flags
  21. def remove_libs(cmd, libs):
  22. excluded_flags = ['-l{}'.format(lib) for lib in libs]
  23. flags = []
  24. for flag in cmd:
  25. if flag in excluded_flags:
  26. continue
  27. flags.append(flag)
  28. return flags
  29. def parse_args(args):
  30. parser = optparse.OptionParser()
  31. parser.disable_interspersed_args()
  32. parser.add_option('--custom-step')
  33. parser.add_option('--python')
  34. parser.add_option('--source-root')
  35. parser.add_option('--build-root')
  36. parser.add_option('--clang-ver')
  37. parser.add_option('--dynamic-cuda', action='store_true')
  38. parser.add_option('--cuda-architectures',
  39. help='List of supported CUDA architectures, separated by ":" (e.g. "sm_52:compute_70:lto_90a"')
  40. parser.add_option('--nvprune-exe')
  41. parser.add_option('--objcopy-exe')
  42. parser.add_option('--arch')
  43. parser.add_option('--linker-output')
  44. parser.add_option('--whole-archive-peers', action='append')
  45. parser.add_option('--whole-archive-libs', action='append')
  46. parser.add_option('--exclude-libs', action='append')
  47. thinlto_cache.add_options(parser)
  48. return parser.parse_args(args)
  49. if __name__ == '__main__':
  50. args = sys.argv[1:]
  51. plugins = []
  52. if '--start-plugins' in args:
  53. ib = args.index('--start-plugins')
  54. ie = args.index('--end-plugins')
  55. plugins = args[ib + 1:ie]
  56. args = args[:ib] + args[ie + 1:]
  57. for p in plugins:
  58. res = subprocess.check_output([sys.executable, p, sys.argv[0]] + args).decode().strip()
  59. if res:
  60. args = json.loads(res)[1:]
  61. opts, args = parse_args(args)
  62. args = pcf.skip_markers(args)
  63. cmd = args
  64. cmd = remove_excessive_flags(cmd)
  65. if opts.exclude_libs:
  66. cmd = remove_libs(cmd, opts.exclude_libs)
  67. cmd = ProcessWholeArchiveOption(opts.arch, opts.whole_archive_peers, opts.whole_archive_libs).construct_cmd(cmd)
  68. if opts.custom_step:
  69. assert opts.python
  70. subprocess.check_call([opts.python] + [opts.custom_step] + args)
  71. if opts.linker_output:
  72. stdout = open(opts.linker_output, 'w')
  73. else:
  74. stdout = sys.stdout
  75. thinlto_cache.preprocess(opts, cmd)
  76. rc = subprocess.call(cmd, shell=False, stderr=sys.stderr, stdout=stdout)
  77. thinlto_cache.postprocess(opts)
  78. sys.exit(rc)