gn_to_bp.py 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. #!/usr/bin/env python
  2. #
  3. # Copyright 2016 Google Inc.
  4. #
  5. # Use of this source code is governed by a BSD-style license that can be
  6. # found in the LICENSE file.
  7. # Generate Android.bp for Skia from GN configuration.
  8. import argparse
  9. import json
  10. import os
  11. import pprint
  12. import string
  13. import subprocess
  14. import sys
  15. import tempfile
  16. root_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)),
  17. os.pardir, os.pardir)
  18. skia_gn_dir = os.path.join(root_dir, 'gn')
  19. sys.path.insert(0, skia_gn_dir)
  20. import gn_to_bp_utils
  21. from skqp_gn_args import SkqpGnArgs
  22. # First we start off with a template for Android.bp,
  23. # with holes for source lists and include directories.
  24. bp = string.Template('''// This file is autogenerated by tools/skqp/gn_to_bp.py.
  25. cc_library_shared {
  26. name: "libskqp_app",
  27. sdk_version: "26",
  28. stl: "libc++_static",
  29. compile_multilib: "both",
  30. cflags: [
  31. $cflags
  32. "-Wno-unused-parameter",
  33. "-Wno-unused-variable",
  34. ],
  35. cppflags:[
  36. $cflags_cc
  37. ],
  38. local_include_dirs: [
  39. $local_includes
  40. ],
  41. srcs: [
  42. "third_party/vulkanmemoryallocator/GrVulkanMemoryAllocator.cpp",
  43. $srcs
  44. ],
  45. arch: {
  46. arm: {
  47. srcs: [
  48. $arm_srcs
  49. ],
  50. neon: {
  51. srcs: [
  52. $arm_neon_srcs
  53. ],
  54. },
  55. },
  56. arm64: {
  57. srcs: [
  58. $arm64_srcs
  59. ],
  60. },
  61. mips: {
  62. srcs: [
  63. $none_srcs
  64. ],
  65. },
  66. mips64: {
  67. srcs: [
  68. $none_srcs
  69. ],
  70. },
  71. x86: {
  72. srcs: [
  73. $x86_srcs
  74. ],
  75. },
  76. x86_64: {
  77. srcs: [
  78. $x86_srcs
  79. ],
  80. },
  81. },
  82. shared_libs: [
  83. "libandroid",
  84. "libEGL",
  85. "libGLESv2",
  86. "liblog",
  87. "libvulkan",
  88. "libz",
  89. ],
  90. static_libs: [
  91. "libexpat",
  92. "libjpeg_static_ndk",
  93. "libpng_ndk",
  94. "libwebp-decode",
  95. "libwebp-encode",
  96. ]
  97. }''')
  98. # We'll run GN to get the main source lists and include directories for Skia.
  99. gn_args = {
  100. 'target_cpu': '"none"',
  101. 'target_os': '"android"',
  102. # setup skqp
  103. 'is_debug': 'false',
  104. 'ndk_api': '26',
  105. # specify that the Android.bp will supply the necessary components
  106. 'skia_use_system_expat': 'true', # removed this when gn is fixed
  107. 'skia_use_system_libpng': 'true',
  108. 'skia_use_system_libwebp': 'true',
  109. 'skia_use_system_libjpeg_turbo': 'true',
  110. 'skia_use_system_zlib': 'true',
  111. }
  112. for k, v in SkqpGnArgs.iteritems():
  113. gn_args[k] = v
  114. js = gn_to_bp_utils.GenerateJSONFromGN(gn_args)
  115. def strip_slashes(lst):
  116. return {str(p.lstrip('/')) for p in lst}
  117. srcs = strip_slashes(js['targets']['//:libskqp_app']['sources'])
  118. cflags = strip_slashes(js['targets']['//:libskqp_app']['cflags'])
  119. cflags_cc = strip_slashes(js['targets']['//:libskqp_app']['cflags_cc'])
  120. local_includes = strip_slashes(js['targets']['//:libskqp_app']['include_dirs'])
  121. defines = {str(d) for d in js['targets']['//:libskqp_app']['defines']}
  122. defines.update(["SK_ENABLE_DUMP_GPU", "SK_BUILD_FOR_SKQP"])
  123. cflags_cc.update(['-Wno-extra-semi-stmt'])
  124. gn_to_bp_utils.GrabDependentValues(js, '//:libskqp_app', 'sources', srcs, None)
  125. gn_to_bp_utils.GrabDependentValues(js, '//:libskqp_app', 'include_dirs',
  126. local_includes, 'freetype')
  127. gn_to_bp_utils.GrabDependentValues(js, '//:libskqp_app', 'defines',
  128. defines, None)
  129. # No need to list headers or other extra flags.
  130. srcs = {s for s in srcs if not s.endswith('.h')}
  131. cflags = gn_to_bp_utils.CleanupCFlags(cflags)
  132. cflags_cc = gn_to_bp_utils.CleanupCCFlags(cflags_cc)
  133. # We need to add the include path to the vulkan defines and header file set in
  134. # then skia_vulkan_header gn arg that is used for framework builds.
  135. local_includes.add("platform_tools/android/vulkan")
  136. # Get architecture specific source files
  137. defs = gn_to_bp_utils.GetArchSources(os.path.join(skia_gn_dir, 'opts.gni'))
  138. # Add source file until fix lands in
  139. # https://skia-review.googlesource.com/c/skia/+/101820
  140. srcs.add("src/ports/SkFontMgr_empty_factory.cpp")
  141. # Turn a list of strings into the style bpfmt outputs.
  142. def bpfmt(indent, lst, sort=True):
  143. if sort:
  144. lst = sorted(lst)
  145. return ('\n' + ' '*indent).join('"%s",' % v for v in lst)
  146. # Most defines go into SkUserConfig.h, where they're seen by Skia and its users.
  147. gn_to_bp_utils.WriteUserConfig('include/config/SkUserConfig.h', defines)
  148. # OK! We have everything to fill in Android.bp...
  149. with open('Android.bp', 'w') as f:
  150. print >>f, bp.substitute({
  151. 'local_includes': bpfmt(8, local_includes),
  152. 'srcs': bpfmt(8, srcs),
  153. 'cflags': bpfmt(8, cflags, False),
  154. 'cflags_cc': bpfmt(8, cflags_cc),
  155. 'arm_srcs': bpfmt(16, defs['armv7']),
  156. 'arm_neon_srcs': bpfmt(20, defs['neon']),
  157. 'arm64_srcs': bpfmt(16, defs['arm64'] +
  158. defs['crc32']),
  159. 'none_srcs': bpfmt(16, defs['none']),
  160. 'x86_srcs': bpfmt(16, defs['sse2'] +
  161. defs['ssse3'] +
  162. defs['sse41'] +
  163. defs['sse42'] +
  164. defs['avx'] +
  165. defs['hsw']),
  166. })