custom_link_green_mysql.py 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. from __future__ import print_function
  2. import os
  3. import shutil
  4. import subprocess
  5. import sys
  6. import tempfile
  7. SYMBOLS_TO_PATCH = (
  8. 'connect',
  9. 'poll',
  10. 'recv',
  11. 'recvfrom',
  12. 'send',
  13. 'sendto',
  14. )
  15. class Error(Exception):
  16. pass
  17. def find_compiler(args):
  18. for arg in args:
  19. if os.path.basename(arg) in ('clang', 'clang++'):
  20. return arg
  21. raise Error('No known compiler found in the command line')
  22. def find_libraries(project, args):
  23. if not project.endswith('/'):
  24. project = project + '/'
  25. for arg in args:
  26. if arg.startswith(project):
  27. yield arg
  28. def rename_symbol(symbol):
  29. return 'green_{}'.format(symbol)
  30. def patch_object(object_path, objcopy):
  31. args = [objcopy]
  32. for symbol in SYMBOLS_TO_PATCH:
  33. args.extend(('--redefine-sym', '{}={}'.format(symbol, rename_symbol(symbol))))
  34. args.append(object_path)
  35. subprocess.check_call(args)
  36. def patch_library(library_path, ar, objcopy):
  37. tmpdir = tempfile.mkdtemp(dir=os.path.dirname(library_path))
  38. try:
  39. subprocess.check_call((ar, 'x', library_path), cwd=tmpdir)
  40. names = os.listdir(tmpdir)
  41. for name in names:
  42. patch_object(os.path.join(tmpdir, name), objcopy=objcopy)
  43. new_library_path = os.path.join(tmpdir, 'library.a')
  44. subprocess.check_call([ar, 'rcs', new_library_path] + names, cwd=tmpdir)
  45. os.rename(new_library_path, library_path)
  46. finally:
  47. shutil.rmtree(tmpdir)
  48. def main():
  49. try:
  50. args = sys.argv[1:]
  51. compiler = find_compiler(args)
  52. compiler_dir = os.path.dirname(compiler)
  53. def get_tool(name):
  54. path = os.path.join(compiler_dir, name)
  55. if not os.path.exists(path):
  56. raise Error('No {} found alongside the compiler'.format(name))
  57. return path
  58. ar = get_tool('llvm-ar')
  59. objcopy = get_tool('llvm-objcopy')
  60. libraries = tuple(find_libraries('contrib/libs/libmysql_r', args))
  61. for library in libraries:
  62. library_path = os.path.abspath(library)
  63. if not os.path.exists(library_path):
  64. raise Error('No {} file exists'.format(library))
  65. patch_library(library_path, ar=ar, objcopy=objcopy)
  66. except Exception as error:
  67. name = os.path.basename(sys.argv[0])
  68. command = ' '.join(args)
  69. message = '{name} failed: {error}\nCommand line: {command}'
  70. print(message.format(**locals()), file=sys.stderr)
  71. if __name__ == '__main__':
  72. main()