identify_failing_build_options.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. #!/usr/bin/env python3
  2. # This file is Copyright 2010 by the GPSD project
  3. # SPDX-License-Identifier: BSD-2-Clause
  4. # This code runs compatibly under Python 2 and 3.x for x >= 2.
  5. # Preserve this property!
  6. """Build option tester."""
  7. from __future__ import absolute_import, print_function, division
  8. import os
  9. always_on = [
  10. 'minimal',
  11. ]
  12. always_off = [
  13. 'leapfetch',
  14. ]
  15. other = [
  16. 'debug',
  17. 'chrpath',
  18. 'ipv6',
  19. 'manbuild',
  20. 'nostrip',
  21. 'slow',
  22. 'profiling',
  23. 'libQgpsmm',
  24. ]
  25. knobs = [
  26. 'aivdm',
  27. 'ashtech',
  28. 'bluez',
  29. 'clientdebug',
  30. 'control_socket',
  31. 'controlsend',
  32. 'coveraging',
  33. 'dbus_export',
  34. 'earthmate',
  35. 'evermore',
  36. 'force_global',
  37. 'fury',
  38. 'fv18',
  39. 'garmin',
  40. 'garmintxt',
  41. 'geostar',
  42. 'gpsclock',
  43. 'gpsd',
  44. 'gpsdclients',
  45. 'itrax',
  46. 'libgpsmm',
  47. 'mtk3301',
  48. 'navcom',
  49. 'ncurses',
  50. 'netfeed',
  51. 'nmea2000',
  52. 'nofloats',
  53. 'ntp',
  54. 'ntpshm',
  55. 'ntrip',
  56. 'oceanserver',
  57. 'oncore',
  58. 'passthrough',
  59. 'pps',
  60. 'python',
  61. 'qt',
  62. 'reconfigure',
  63. 'rtcm104v2',
  64. 'rtcm104v3',
  65. 'shared',
  66. 'shm_export',
  67. 'sirf',
  68. 'socket_export',
  69. 'squelch',
  70. 'superstar2',
  71. 'systemd',
  72. 'timing',
  73. 'tnt',
  74. 'tripmate',
  75. 'tsip',
  76. 'ublox',
  77. 'usb',
  78. 'xgps',
  79. ]
  80. def main(starting_number_of_options=0):
  81. """Main program."""
  82. import itertools
  83. import multiprocessing
  84. import shutil
  85. import subprocess
  86. num_cpus = multiprocessing.cpu_count()
  87. job_arg = '-j%d' % num_cpus
  88. failed_configurations = []
  89. dev_null = open('/dev/null', 'w')
  90. def _run(command, phase):
  91. """Run subproceses."""
  92. if subprocess.call(command, stdout=dev_null) == 0:
  93. return True
  94. failed_configurations.append(command)
  95. print(command)
  96. with open('failed_%s_configs.txt' % phase, 'a') as failed_configs:
  97. failed_configs.write(' '.join(command) + '\n')
  98. return False
  99. static_params = [key + '=on' for key in always_on]
  100. static_params += [key + '=off' for key in always_off]
  101. for i in range(starting_number_of_options, len(knobs)):
  102. print('Testing at length {}'.format(i))
  103. for thisrow in itertools.combinations(knobs, i):
  104. print(thisrow)
  105. params = static_params + [key + '=on' for key in thisrow]
  106. # print {'on_params': thisrow, 'scons_params': params}
  107. # Clean before clearing cached options, in case options
  108. # affect what's cleaned.
  109. subprocess.call(['scons', '-c'], stdout=dev_null)
  110. # Now remove all the scons temporaries
  111. try:
  112. shutil.rmtree('.sconf_temp')
  113. except OSError:
  114. pass
  115. for f in ['.sconsign.dblite', '.scons-option-cache']:
  116. try:
  117. os.remove(f)
  118. except OSError:
  119. pass
  120. if _run(['scons', job_arg, 'build-all'] + params, 'build'):
  121. _run(['scons', job_arg, 'check'] + params, 'check')
  122. return failed_configurations
  123. if __name__ == '__main__':
  124. failed = main(0)
  125. for row in failed:
  126. print(' '.join(row))