meson_exe.py 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103
  1. # Copyright 2013-2016 The Meson development team
  2. # Licensed under the Apache License, Version 2.0 (the "License");
  3. # you may not use this file except in compliance with the License.
  4. # You may obtain a copy of the License at
  5. # http://www.apache.org/licenses/LICENSE-2.0
  6. # Unless required by applicable law or agreed to in writing, software
  7. # distributed under the License is distributed on an "AS IS" BASIS,
  8. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  9. # See the License for the specific language governing permissions and
  10. # limitations under the License.
  11. import os
  12. import sys
  13. import argparse
  14. import pickle
  15. import platform
  16. import subprocess
  17. from .. import mesonlib
  18. options = None
  19. def buildparser():
  20. parser = argparse.ArgumentParser()
  21. parser.add_argument('args', nargs='+')
  22. return parser
  23. def is_windows():
  24. platname = platform.system().lower()
  25. return platname == 'windows' or 'mingw' in platname
  26. def is_cygwin():
  27. platname = platform.system().lower()
  28. return 'cygwin' in platname
  29. def run_with_mono(fname):
  30. if fname.endswith('.exe') and not (is_windows() or is_cygwin()):
  31. return True
  32. return False
  33. def run_exe(exe):
  34. if exe.fname[0].endswith('.jar'):
  35. cmd = ['java', '-jar'] + exe.fname
  36. elif not exe.is_cross and run_with_mono(exe.fname[0]):
  37. cmd = ['mono'] + exe.fname
  38. else:
  39. if exe.is_cross:
  40. if exe.exe_runner is None:
  41. raise AssertionError('BUG: Can\'t run cross-compiled exe {!r}'
  42. 'with no wrapper'.format(exe.name))
  43. elif not exe.exe_runner.found():
  44. raise AssertionError('BUG: Can\'t run cross-compiled exe {!r} with not-found'
  45. 'wrapper {!r}'.format(exe.name, exe.exe_runner.get_path()))
  46. else:
  47. cmd = exe.exe_runner.get_command() + exe.fname
  48. else:
  49. cmd = exe.fname
  50. child_env = os.environ.copy()
  51. child_env.update(exe.env)
  52. if len(exe.extra_paths) > 0:
  53. child_env['PATH'] = (os.pathsep.join(exe.extra_paths + ['']) +
  54. child_env['PATH'])
  55. if exe.exe_runner and mesonlib.substring_is_in_list('wine', exe.exe_runner.get_command()):
  56. wine_paths = ['Z:' + p for p in exe.extra_paths]
  57. wine_path = ';'.join(wine_paths)
  58. # Don't accidentally end with an `;` because that will add the
  59. # current directory and might cause unexpected behaviour
  60. if 'WINEPATH' in child_env:
  61. child_env['WINEPATH'] = wine_path + ';' + child_env['WINEPATH']
  62. else:
  63. child_env['WINEPATH'] = wine_path
  64. p = subprocess.Popen(cmd + exe.cmd_args, env=child_env, cwd=exe.workdir,
  65. close_fds=False,
  66. stdout=subprocess.PIPE,
  67. stderr=subprocess.PIPE)
  68. stdout, stderr = p.communicate()
  69. if exe.capture and p.returncode == 0:
  70. with open(exe.capture, 'wb') as output:
  71. output.write(stdout)
  72. else:
  73. sys.stdout.buffer.write(stdout)
  74. if stderr:
  75. sys.stderr.buffer.write(stderr)
  76. return p.returncode
  77. def run(args):
  78. global options
  79. options = buildparser().parse_args(args)
  80. if len(options.args) != 1:
  81. print('Test runner for Meson. Do not run on your own, mmm\'kay?')
  82. print(sys.argv[0] + ' [data file]')
  83. exe_data_file = options.args[0]
  84. with open(exe_data_file, 'rb') as f:
  85. exe = pickle.load(f)
  86. return run_exe(exe)
  87. if __name__ == '__main__':
  88. sys.exit(run(sys.argv[1:]))