custom_link_green_mysql.py 2.5 KB

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