common.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. #!/usr/bin/env python
  2. # Copyright (C) 2011 Igalia S.L.
  3. #
  4. # This library is free software; you can redistribute it and/or
  5. # modify it under the terms of the GNU Lesser General Public
  6. # License as published by the Free Software Foundation; either
  7. # version 2 of the License, or (at your option) any later version.
  8. #
  9. # This library is distributed in the hope that it will be useful,
  10. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. # Lesser General Public License for more details.
  13. #
  14. # You should have received a copy of the GNU Lesser General Public
  15. # License along with this library; if not, write to the Free Software
  16. # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. import errno
  18. import os
  19. import select
  20. import subprocess
  21. import sys
  22. script_dir = None
  23. build_dir = None
  24. def script_path(*args):
  25. global script_dir
  26. if not script_dir:
  27. script_dir = os.path.join(os.path.dirname(__file__), '..', 'Scripts')
  28. return os.path.join(*(script_dir,) + args)
  29. def top_level_path(*args):
  30. return os.path.join(*((script_path('..', '..'),) + args))
  31. def get_build_path(build_types=('Release', 'Debug')):
  32. global build_dir
  33. if build_dir:
  34. return build_dir
  35. def is_valid_build_directory(path):
  36. return os.path.exists(os.path.join(path, 'GNUmakefile')) or \
  37. os.path.exists(os.path.join(path, 'Programs', 'DumpRenderTree'))
  38. if len(sys.argv[1:]) > 1 and os.path.exists(sys.argv[-1]) and is_valid_build_directory(sys.argv[-1]):
  39. return sys.argv[-1]
  40. # Debian and Ubuntu build both flavours of the library (with gtk2
  41. # and with gtk3); they use directories build-2.0 and build-3.0 for
  42. # that, which is not handled by the above cases; we check that the
  43. # directory where we are called from is a valid build directory,
  44. # which should handle pretty much all other non-standard cases.
  45. build_dir = os.getcwd()
  46. if is_valid_build_directory(build_dir):
  47. return build_dir
  48. for build_type in build_types:
  49. build_dir = top_level_path('WebKitBuild', build_type)
  50. if is_valid_build_directory(build_dir):
  51. return build_dir
  52. # distcheck builds in a directory named _build in the top-level path.
  53. build_dir = top_level_path("_build")
  54. if is_valid_build_directory(build_dir):
  55. return build_dir
  56. build_dir = top_level_path()
  57. if is_valid_build_directory(build_dir):
  58. return build_dir
  59. build_dir = top_level_path("WebKitBuild")
  60. if is_valid_build_directory(build_dir):
  61. return build_dir
  62. print('Could not determine build directory.')
  63. sys.exit(1)
  64. def build_path_for_build_types(build_types, *args):
  65. return os.path.join(*(get_build_path(build_types),) + args)
  66. def build_path(*args):
  67. return build_path_for_build_types(('Release', 'Debug'), *args)
  68. def pkg_config_file_variable(package, variable):
  69. process = subprocess.Popen(['pkg-config', '--variable=%s' % variable, package],
  70. stdout=subprocess.PIPE)
  71. stdout = process.communicate()[0].decode("utf-8")
  72. if process.returncode:
  73. return None
  74. return stdout.strip()
  75. def prefix_of_pkg_config_file(package):
  76. return pkg_config_file_variable(package, 'prefix')
  77. def gtk_version_of_pkg_config_file(pkg_config_path):
  78. process = subprocess.Popen(['pkg-config', pkg_config_path, '--print-requires'],
  79. stdout=subprocess.PIPE)
  80. stdout = process.communicate()[0].decode("utf-8")
  81. if 'gtk+-3.0' in stdout:
  82. return 3
  83. return 2
  84. def parse_output_lines(fd, parse_line_callback):
  85. output = ''
  86. read_set = [fd]
  87. while read_set:
  88. try:
  89. rlist, wlist, xlist = select.select(read_set, [], [])
  90. except select.error as e:
  91. parse_line_callback("WARNING: error while waiting for fd %d to become readable\n" % fd)
  92. parse_line_callback(" error code: %d, error message: %s\n" % (e[0], e[1]))
  93. continue
  94. if fd in rlist:
  95. try:
  96. chunk = os.read(fd, 1024)
  97. except OSError as e:
  98. if e.errno == errno.EIO:
  99. # Child process finished.
  100. chunk = ''
  101. else:
  102. raise e
  103. if not chunk:
  104. read_set.remove(fd)
  105. output += chunk
  106. while '\n' in output:
  107. pos = output.find('\n')
  108. parse_line_callback(output[:pos + 1])
  109. output = output[pos + 1:]
  110. if not chunk and output:
  111. parse_line_callback(output)
  112. output = ''