shader_to_header.py 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #!/usr/bin/env python
  2. # Copyright 2016 The Chromium Authors. All rights reserved.
  3. # Use of this source code is governed by a BSD-style license that can be
  4. # found in the LICENSE file.
  5. """Helper script to inline files as const char[] into a C header file.
  6. Example:
  7. Input file in_a.vert:
  8. 1"
  9. 2
  10. 3\
  11. Input file in_b.frag:
  12. 4
  13. 5
  14. 6
  15. shader_to_header.py "output.h" "in_a.vert" "in_b.frag" will generate this:
  16. #ifndef OUTPUT_H_BSGN3bbEMBDD0ucC
  17. #define OUTPUT_H_BSGN3bbEMBDD0ucC
  18. const char kInAVert[] = "1\"\n2\n3\\\n";
  19. const char kInBFrag[] = "4\n5\n6\n";
  20. #endif // OUTPUT_H_BSGN3bbEMBDD0ucC
  21. """
  22. import os.path
  23. import random
  24. import string
  25. import sys
  26. RANDOM_STRING_LENGTH = 16
  27. STRING_CHARACTERS = (string.ascii_uppercase +
  28. string.ascii_lowercase +
  29. string.digits)
  30. def random_str():
  31. return ''.join(random.choice(STRING_CHARACTERS)
  32. for _ in range(RANDOM_STRING_LENGTH))
  33. def escape_text(line):
  34. # encode('string-escape') doesn't escape double quote so you need to manually
  35. # escape it.
  36. return line.encode('string-escape').replace('"', '\\"')
  37. def main():
  38. if len(sys.argv) < 3:
  39. print 'Usage: shader_to_header.py <output-file> <input-files...>'
  40. return 1
  41. output_path = sys.argv[1]
  42. include_guard = (os.path.basename(output_path).upper().replace('.', '_') +
  43. '_' + random_str())
  44. with open(output_path, 'w') as output_file:
  45. output_file.write('#ifndef ' + include_guard + '\n' +
  46. '#define ' + include_guard + '\n\n')
  47. existing_names = set()
  48. argc = len(sys.argv)
  49. for i in xrange(2, argc):
  50. input_path = sys.argv[i]
  51. with open(input_path, 'r') as input_file:
  52. # hello_world.vert -> kHelloWorldVert
  53. const_name = ('k' + os.path.basename(input_path).title()
  54. .replace('_', '').replace('.', ''))
  55. if const_name in existing_names:
  56. print >> sys.stderr, ('Error: Constant name ' + const_name +
  57. ' is already used by a previous file. Files with the same' +
  58. ' name can\'t be inlined into the same header.')
  59. return 1
  60. existing_names.add(const_name)
  61. text = input_file.read()
  62. inlined = ('const char ' + const_name + '[] = "' + escape_text(text) +
  63. '";\n\n');
  64. output_file.write(inlined)
  65. output_file.write('#endif // ' + include_guard + '\n')
  66. return 0
  67. if __name__ == '__main__':
  68. sys.exit(main())