fix_py2_protobuf.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116
  1. import subprocess
  2. import os, sys
  3. # Explicitly enable local imports
  4. # Don't forget to add imported scripts to inputs of the calling command!
  5. sys.path.append(os.path.dirname(os.path.abspath(__file__)))
  6. import process_command_files as pcf
  7. def run(*args):
  8. # print >>sys.stderr, args
  9. return subprocess.check_output(list(args), shell=False).strip()
  10. def gen_renames_1(d):
  11. for l in d.split('\n'):
  12. l = l.strip()
  13. if ' ' in l:
  14. yield l.split(' ')[-1]
  15. def gen_renames_2(p, d):
  16. for s in gen_renames_1(d):
  17. yield s + ' ' + p + s
  18. def gen_renames(p, d):
  19. return '\n'.join(gen_renames_2(p, d)).strip() + '\n'
  20. def rename_syms(where, ret, libs):
  21. p = 'py2_'
  22. # join libs
  23. run(where + 'llvm-ar', 'qcL', ret, *libs)
  24. # find symbols to rename
  25. syms = run(where + 'llvm-nm', '--extern-only', '--defined-only', '-A', ret)
  26. # prepare rename plan
  27. renames = gen_renames(p, syms)
  28. with open('syms', 'w') as f:
  29. f.write(renames)
  30. # rename symbols
  31. run(where + 'llvm-objcopy', '--redefine-syms=syms', ret)
  32. # back-rename some symbols
  33. args = [
  34. where + 'llvm-objcopy',
  35. '--redefine-sym',
  36. p + 'init_api_implementation=init6google8protobuf8internal19_api_implementation',
  37. '--redefine-sym',
  38. p + 'init_message=init6google8protobuf5pyext8_message',
  39. '--redefine-sym',
  40. p + 'init6google8protobuf8internal19_api_implementation=init6google8protobuf8internal19_api_implementation',
  41. '--redefine-sym',
  42. p + 'init6google8protobuf5pyext8_message=init6google8protobuf5pyext8_message',
  43. '--redefine-sym',
  44. p + '_init6google8protobuf8internal19_api_implementation=_init6google8protobuf8internal19_api_implementation',
  45. '--redefine-sym',
  46. p + '_init6google8protobuf5pyext8_message=_init6google8protobuf5pyext8_message',
  47. ret,
  48. ]
  49. run(*args)
  50. return ret
  51. def fix_py2(cmd, have_comand_files=False, prefix='lib', suffix='a'):
  52. args = cmd
  53. if have_comand_files:
  54. args = pcf.get_args(cmd)
  55. if 'protobuf_old' not in str(args):
  56. return cmd
  57. py2_libs = [prefix + 'contrib-libs-protobuf_old.' + suffix, prefix + 'pypython-protobuf-py2.' + suffix]
  58. def need_rename(x):
  59. for v in py2_libs:
  60. if v in x:
  61. return True
  62. return False
  63. old = []
  64. lib = []
  65. where = os.path.dirname(cmd[0]) + '/'
  66. for x in args:
  67. if need_rename(x):
  68. lib.append(x)
  69. else:
  70. old.append(x)
  71. name = rename_syms(where, 'libprotoherobora.' + suffix, lib)
  72. if not have_comand_files:
  73. return old + [name]
  74. for file in cmd:
  75. if pcf.is_cmdfile_arg(file):
  76. cmd_file_path = pcf.cmdfile_path(file)
  77. args = pcf.read_from_command_file(cmd_file_path)
  78. if not 'protobuf_old' in str(args):
  79. continue
  80. with open(cmd_file_path, 'w') as afile:
  81. for arg in args:
  82. if not need_rename(arg):
  83. afile.write(arg + '\n')
  84. afile.write(name)
  85. return cmd