compile_java.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. import argparse
  2. import contextlib
  3. from distutils import dir_util
  4. import os
  5. import shutil
  6. import subprocess as sp
  7. import tarfile
  8. import zipfile
  9. import sys
  10. def parse_args(args):
  11. parser = argparse.ArgumentParser(description='Wrapper to invoke Java compilation from ya make build')
  12. parser.add_argument('--javac-bin', help='path to javac')
  13. parser.add_argument('--jar-bin', help='path to jar tool')
  14. parser.add_argument('--java-bin', help='path to java binary')
  15. parser.add_argument('--kotlin-compiler', help='path to kotlin compiler jar file')
  16. parser.add_argument('--vcs-mf', help='path to VCS info manifest snippet')
  17. parser.add_argument('--package-prefix', help='package prefix for resource files')
  18. parser.add_argument('--jar-output', help='jar file with compiled classes destination path')
  19. parser.add_argument('--srcs-jar-output', help='jar file with sources destination path')
  20. parser.add_argument('srcs', nargs="*")
  21. args = parser.parse_args(args)
  22. return args, args.srcs
  23. def mkdir_p(directory):
  24. if not os.path.exists(directory):
  25. os.makedirs(directory)
  26. def split_cmd_by_delim(cmd, delim='DELIM'):
  27. result = [[]]
  28. for arg in cmd:
  29. if arg == delim:
  30. result.append([])
  31. else:
  32. result[-1].append(arg)
  33. return result
  34. def main():
  35. cmd_parts = split_cmd_by_delim(sys.argv[1:])
  36. assert len(cmd_parts) == 4
  37. args, javac_opts, peers, ktc_opts = cmd_parts
  38. opts, jsrcs = parse_args(args)
  39. jsrcs += list(filter(lambda x: x.endswith('.jsrc'), peers))
  40. peers = list(filter(lambda x: not x.endswith('.jsrc'), peers))
  41. sources_dir = 'src'
  42. mkdir_p(sources_dir)
  43. for s in jsrcs:
  44. if s.endswith('.jsrc'):
  45. with contextlib.closing(tarfile.open(s, 'r')) as tf:
  46. tf.extractall(sources_dir)
  47. srcs = []
  48. for r, _, files in os.walk(sources_dir):
  49. for f in files:
  50. srcs.append(os.path.join(r, f))
  51. srcs += jsrcs
  52. ktsrcs = list(filter(lambda x: x.endswith('.kt'), srcs))
  53. srcs = list(filter(lambda x: x.endswith('.java'), srcs))
  54. classes_dir = 'cls'
  55. mkdir_p(classes_dir)
  56. classpath = os.pathsep.join(peers)
  57. if srcs:
  58. temp_sources_file = 'temp.sources.list'
  59. with open(temp_sources_file, 'w') as ts:
  60. ts.write(' '.join(srcs))
  61. if ktsrcs:
  62. temp_kt_sources_file = 'temp.kt.sources.list'
  63. with open(temp_kt_sources_file, 'w') as ts:
  64. ts.write(' '.join(ktsrcs + srcs))
  65. kt_classes_dir = 'kt_cls'
  66. mkdir_p(kt_classes_dir)
  67. sp.check_call([opts.java_bin, '-Didea.max.content.load.filesize=30720', '-jar', opts.kotlin_compiler, '-classpath', classpath, '-d', kt_classes_dir] + ktc_opts + ['@' + temp_kt_sources_file])
  68. classpath = os.pathsep.join([kt_classes_dir, classpath])
  69. if srcs:
  70. sp.check_call([opts.javac_bin, '-nowarn', '-g', '-classpath', classpath, '-encoding', 'UTF-8', '-d', classes_dir] + javac_opts + ['@' + temp_sources_file])
  71. for s in jsrcs:
  72. if s.endswith('-sources.jar'):
  73. with zipfile.ZipFile(s) as zf:
  74. zf.extractall(sources_dir)
  75. elif s.endswith('.jar'):
  76. with zipfile.ZipFile(s) as zf:
  77. zf.extractall(classes_dir)
  78. if ktsrcs:
  79. dir_util.copy_tree(kt_classes_dir, classes_dir)
  80. if opts.vcs_mf:
  81. sp.check_call([opts.jar_bin, 'cfm', opts.jar_output, opts.vcs_mf, os.curdir], cwd=classes_dir)
  82. else:
  83. sp.check_call([opts.jar_bin, 'cfM', opts.jar_output, os.curdir], cwd=classes_dir)
  84. if opts.srcs_jar_output:
  85. for s in jsrcs:
  86. if s.endswith('.java'):
  87. if opts.package_prefix:
  88. d = os.path.join(sources_dir, *(opts.package_prefix.split('.') + [os.path.basename(s)]))
  89. else:
  90. d = os.path.join(sources_dir, os.path.basename(s))
  91. shutil.copyfile(s, d)
  92. if opts.vcs_mf:
  93. sp.check_call([opts.jar_bin, 'cfm', opts.srcs_jar_output, opts.vcs_mf, os.curdir], cwd=sources_dir)
  94. else:
  95. sp.check_call([opts.jar_bin, 'cfM', opts.srcs_jar_output, os.curdir], cwd=sources_dir)
  96. if __name__ == '__main__':
  97. main()