Home | History | Annotate | Download | only in skqp
      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 
      8 # Generate Android.bp for Skia from GN configuration.
      9 
     10 import argparse
     11 import json
     12 import os
     13 import pprint
     14 import string
     15 import subprocess
     16 import sys
     17 import tempfile
     18 
     19 root_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)),
     20                         os.pardir, os.pardir)
     21 skia_gn_dir = os.path.join(root_dir, 'gn')
     22 sys.path.insert(0, skia_gn_dir)
     23 
     24 import gn_to_bp_utils
     25 
     26 # First we start off with a template for Android.bp,
     27 # with holes for source lists and include directories.
     28 bp = string.Template('''// This file is autogenerated by tools/skqp/gn_to_bp.py.
     29 
     30 cc_library_shared {
     31     name: "libskqp_app",
     32     sdk_version: "26",
     33     stl: "libc++_static",
     34     tags: ["tests", "optional"],
     35 
     36     cflags: [
     37         $cflags
     38         "-Wno-unused-parameter",
     39         "-Wno-unused-variable",
     40     ],
     41 
     42     cppflags:[
     43         $cflags_cc
     44     ],
     45 
     46     local_include_dirs: [
     47         $local_includes
     48     ],
     49 
     50     srcs: [
     51         $srcs
     52     ],
     53 
     54     arch: {
     55         arm: {
     56             srcs: [
     57                 $arm_srcs
     58             ],
     59 
     60             neon: {
     61                 srcs: [
     62                     $arm_neon_srcs
     63                 ],
     64             },
     65         },
     66 
     67         arm64: {
     68             srcs: [
     69                 $arm64_srcs
     70             ],
     71         },
     72 
     73         mips: {
     74             srcs: [
     75                 $none_srcs
     76             ],
     77         },
     78 
     79         mips64: {
     80             srcs: [
     81                 $none_srcs
     82             ],
     83         },
     84 
     85         x86: {
     86             srcs: [
     87                 $x86_srcs
     88             ],
     89             cflags: [
     90                 // Clang seems to think new/malloc will only be 4-byte aligned
     91                 // on x86 Android. We're pretty sure it's actually 8-byte
     92                 // alignment. tests/OverAlignedTest.cpp has more information,
     93                 // and should fail if we're wrong.
     94                 "-Wno-over-aligned"
     95             ],
     96         },
     97 
     98         x86_64: {
     99             srcs: [
    100                 $x86_srcs
    101             ],
    102         },
    103     },
    104 
    105     shared_libs: [
    106           "libandroid",
    107           "libEGL",
    108           "libGLESv2",
    109           "liblog",
    110           "libvulkan",
    111           "libz",
    112     ],
    113     static_libs: [
    114           "libjpeg_static_ndk",
    115           "libjsoncpp",
    116           "libpng_ndk",
    117           "libwebp-decode",
    118           "libwebp-encode",
    119     ]
    120 }''')
    121 
    122 # We'll run GN to get the main source lists and include directories for Skia.
    123 gn_args = {
    124   'target_cpu': '"none"',
    125   'target_os':  '"android"',
    126 
    127   # setup skqp
    128   'is_debug':   'false',
    129   'ndk_api':    '26',
    130   'skia_skqp_global_error_tolerance': '4',
    131 
    132   # setup vulkan
    133   'skia_use_vulkan':    'true',
    134   'skia_vulkan_header': '"Skia_Vulkan_Android.h"',
    135 
    136   # enable/disable skia subsystems
    137   'skia_enable_fontmgr_empty': 'true',
    138   'skia_enable_pdf':           'false',
    139   'skia_use_expat':            'false',
    140   'skia_use_dng_sdk':          'false',
    141   'skia_use_icu':              'false',
    142   'skia_use_lua':              'false',
    143   'skia_use_piex':             'false',
    144   'skia_use_skcms':            'false',
    145 
    146   # specify that the Android.bp will supply the necessary components
    147   'skia_use_system_expat':         'true', # removed this when gn is fixed
    148   'skia_use_system_libpng':        'true',
    149   'skia_use_system_jsoncpp':       'true',
    150   'skia_use_system_libwebp':       'true',
    151   'skia_use_system_libjpeg_turbo': 'true',
    152   'skia_use_system_zlib':          'true',
    153 }
    154 
    155 js = gn_to_bp_utils.GenerateJSONFromGN(gn_args)
    156 
    157 def strip_slashes(lst):
    158   return {str(p.lstrip('/')) for p in lst}
    159 
    160 srcs            = strip_slashes(js['targets']['//:libskqp_app']['sources'])
    161 cflags          = strip_slashes(js['targets']['//:libskqp_app']['cflags'])
    162 cflags_cc       = strip_slashes(js['targets']['//:libskqp_app']['cflags_cc'])
    163 local_includes  = strip_slashes(js['targets']['//:libskqp_app']['include_dirs'])
    164 defines      = {str(d) for d in js['targets']['//:libskqp_app']['defines']}
    165 
    166 gn_to_bp_utils.GrabDependentValues(js, '//:libskqp_app', 'sources', srcs, None)
    167 gn_to_bp_utils.GrabDependentValues(js, '//:libskqp_app', 'include_dirs',
    168                                    local_includes, 'freetype')
    169 gn_to_bp_utils.GrabDependentValues(js, '//:libskqp_app', 'defines',
    170                                    defines, None)
    171 
    172 # No need to list headers or other extra flags.
    173 srcs = {s for s in srcs           if not s.endswith('.h')}
    174 cflags = gn_to_bp_utils.CleanupCFlags(cflags)
    175 cflags_cc = gn_to_bp_utils.CleanupCCFlags(cflags_cc)
    176 
    177 # We need to add the include path to the vulkan defines and header file set in
    178 # then skia_vulkan_header gn arg that is used for framework builds.
    179 local_includes.add("platform_tools/android/vulkan")
    180 
    181 # Get architecture specific source files
    182 defs = gn_to_bp_utils.GetArchSources(os.path.join(skia_gn_dir, 'opts.gni'))
    183 
    184 # Add source file until fix lands in
    185 # https://skia-review.googlesource.com/c/skia/+/101820
    186 srcs.add("src/ports/SkFontMgr_empty_factory.cpp")
    187 
    188 # Turn a list of strings into the style bpfmt outputs.
    189 def bpfmt(indent, lst, sort=True):
    190   if sort:
    191     lst = sorted(lst)
    192   return ('\n' + ' '*indent).join('"%s",' % v for v in lst)
    193 
    194 # Most defines go into SkUserConfig.h, where they're seen by Skia and its users.
    195 gn_to_bp_utils.WriteUserConfig('include/config/SkUserConfig.h', defines)
    196 
    197 # OK!  We have everything to fill in Android.bp...
    198 with open('Android.bp', 'w') as f:
    199   print >>f, bp.substitute({
    200     'local_includes': bpfmt(8, local_includes),
    201     'srcs':           bpfmt(8, srcs),
    202     'cflags':         bpfmt(8, cflags, False),
    203     'cflags_cc':      bpfmt(8, cflags_cc),
    204 
    205     'arm_srcs':       bpfmt(16, defs['armv7']),
    206     'arm_neon_srcs':  bpfmt(20, defs['neon']),
    207     'arm64_srcs':     bpfmt(16, defs['arm64'] +
    208                                 defs['crc32']),
    209     'none_srcs':      bpfmt(16, defs['none']),
    210     'x86_srcs':       bpfmt(16, defs['sse2'] +
    211                                 defs['ssse3'] +
    212                                 defs['sse41'] +
    213                                 defs['sse42'] +
    214                                 defs['avx'  ]),
    215   })
    216 
    217