#!/usr/bin/env python import os import locale from collections import defaultdict locale.setlocale(locale.LC_ALL, 'en_US.UTF-8') header = """ # # ##### ####### # # # # # # # ## # # # # # # # # # # # # # ## # # # # # # # # # # # # ## #### # # # # # # # # # # # ## # # # ####### # # # ####### # ### # ## # # # # # # # # # # # ### # # ##### ####### # # ## ## # # # ### # # Seriously. You shouldn't even be looking at this file unless you're # debugging generate_mozbuild.py. # # DO NOT MODIFY THIS FILE IT IS AUTOGENERATED. # skia_opt_flags = [] if CONFIG['MOZ_OPTIMIZE']: if CONFIG['_MSC_VER']: skia_opt_flags += ['-O2'] elif CONFIG['GNU_CC']: skia_opt_flags += ['-O2'] """ footer = """ # We allow warnings for third-party code that can be updated from upstream. ALLOW_COMPILER_WARNINGS = True FINAL_LIBRARY = 'gkmedias' LOCAL_INCLUDES += [ 'skia/include/c', 'skia/include/config', 'skia/include/core', 'skia/include/effects', 'skia/include/gpu', 'skia/include/images', 'skia/include/pathops', 'skia/include/ports', 'skia/include/private', 'skia/include/utils', 'skia/include/utils/mac', 'skia/include/views', 'skia/src/core', 'skia/src/gpu', 'skia/src/gpu/effects', 'skia/src/gpu/gl', 'skia/src/image', 'skia/src/lazy', 'skia/src/opts', 'skia/src/sfnt', 'skia/src/utils', 'skia/src/utils/mac', 'skia/src/utils/win', ] if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android'): DEFINES['SK_FONTHOST_CAIRO_STANDALONE'] = 0 if CONFIG['MOZ_WIDGET_TOOLKIT'] in { 'android', 'cocoa', 'gtk2', 'gtk3', 'uikit', }: DEFINES['SK_FONTHOST_DOES_NOT_USE_FONTMGR'] = 1 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows': DEFINES['UNICODE'] = True DEFINES['_UNICODE'] = True SOURCES += [ 'skia/src/fonts/SkFontMgr_indirect.cpp', 'skia/src/fonts/SkRemotableFontMgr.cpp', ] if CONFIG['GKMEDIAS_SHARED_LIBRARY']: DEFINES['SKIA_DLL'] = 1 DEFINES['GR_DLL'] = 1 # We should autogenerate these SSE related flags. if CONFIG['_MSC_VER']: # MSVC doesn't need special compiler flags, but Skia needs to be told that these files should # be built with the required SSE level or it will simply compile in stubs and cause runtime crashes SOURCES['skia/src/opts/SkBitmapFilter_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20'] SOURCES['skia/src/opts/SkBitmapProcState_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20'] SOURCES['skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=31'] SOURCES['skia/src/opts/SkBlitRow_opts_SSE2.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=20'] SOURCES['skia/src/opts/SkOpts_ssse3.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=31'] SOURCES['skia/src/opts/SkOpts_sse41.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=41'] SOURCES['skia/src/opts/SkOpts_sse42.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=42'] SOURCES['skia/src/opts/SkOpts_avx.cpp'].flags += ['-DSK_CPU_SSE_LEVEL=51'] if CONFIG['INTEL_ARCHITECTURE'] and (CONFIG['GNU_CC'] or CONFIG['CLANG_CL']): SOURCES['skia/src/opts/SkBitmapFilter_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS'] SOURCES['skia/src/opts/SkBitmapProcState_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS'] SOURCES['skia/src/opts/SkBitmapProcState_opts_SSSE3.cpp'].flags += ['-mssse3'] SOURCES['skia/src/opts/SkBlitRow_opts_SSE2.cpp'].flags += CONFIG['SSE2_FLAGS'] SOURCES['skia/src/opts/SkOpts_ssse3.cpp'].flags += ['-mssse3'] SOURCES['skia/src/opts/SkOpts_sse41.cpp'].flags += ['-msse4.1'] SOURCES['skia/src/opts/SkOpts_sse42.cpp'].flags += ['-msse4.2'] SOURCES['skia/src/opts/SkOpts_avx.cpp'].flags += ['-mavx'] elif CONFIG['CPU_ARCH'] == 'arm' and CONFIG['GNU_CC'] and CONFIG['BUILD_ARM_NEON']: DEFINES['SK_ARM_HAS_OPTIONAL_NEON'] = 1 DEFINES['SKIA_IMPLEMENTATION'] = 1 if not CONFIG['MOZ_ENABLE_SKIA_GPU']: DEFINES['SK_SUPPORT_GPU'] = 0 if CONFIG['MOZ_TREE_FREETYPE']: DEFINES['SK_CAN_USE_DLOPEN'] = 0 # Suppress warnings in third-party code. if CONFIG['GNU_CXX'] or CONFIG['CLANG_CL']: CXXFLAGS += [ '-Wno-deprecated-declarations', '-Wno-overloaded-virtual', '-Wno-shadow', '-Wno-sign-compare', '-Wno-unreachable-code', '-Wno-unused-function', ] if CONFIG['GNU_CXX'] and not CONFIG['CLANG_CXX'] and not CONFIG['CLANG_CL']: CXXFLAGS += [ '-Wno-logical-op', '-Wno-maybe-uninitialized', ] if CONFIG['CLANG_CXX'] or CONFIG['CLANG_CL']: CXXFLAGS += [ '-Wno-implicit-fallthrough', '-Wno-inconsistent-missing-override', '-Wno-macro-redefined', '-Wno-unused-private-field', ] if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3', 'android'): CXXFLAGS += CONFIG['MOZ_CAIRO_CFLAGS'] CXXFLAGS += CONFIG['CAIRO_FT_CFLAGS'] if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk2', 'gtk3'): CXXFLAGS += CONFIG['MOZ_PANGO_CFLAGS'] """ import json platforms = ['linux', 'mac', 'android', 'win'] def generate_opt_sources(): opt_sources = {'opts': {''}} for root, dirs, files in os.walk('skia/src/opts'): for name in files: if name.endswith('.cpp'): opt_sources['opts'].add(os.path.join(root, name)) return opt_sources def generate_platform_sources(): sources = {} for plat in platforms: if os.system("cd skia && GYP_GENERATORS=dump_mozbuild ./gyp_skia -D OS=%s -D host_os=linux gyp/skia_lib.gyp" % plat) != 0: print 'Failed to generate sources for ' + plat continue f = open('skia/sources.json'); sources[plat] = set(v.replace('../', 'skia/') for v in json.load(f)); f.close() return dict(sources.items() + generate_opt_sources().items()) def generate_separated_sources(platform_sources): blacklist = [ 'experimental', 'SkXML', 'GrGLCreateNativeInterface', 'GrGLCreateNullInterface', 'GrGLAssembleInterface', 'GrGLTestInterface', 'fontconfig', 'FontConfig', 'SkThreadUtils_pthread_', 'SkFontMgr_android', 'SkFontMgr_custom', 'SkFontHost_FreeType.cpp', 'Movie', 'ImageEncoder', 'skia/src/c/', 'skia/src/effects/Gr', 'skia/src/effects/Sk', 'skia/src/fonts/', 'skia/src/images/', 'skia/src/ports/SkImageGenerator', 'skia/src/sksl/', 'skia/src/gpu/vk/', 'SkBitmapRegion', 'SkLight', 'SkRadialShadow', 'SkShadow', 'SkNormal', 'SkLite', 'codec', 'SkWGL', 'SkMemory_malloc', 'SkOpts_', 'opts_check_x86', 'third_party', # unused in skia/src/utils 'SkBoundaryPatch', 'SkCamera', 'SkCanvasStack', 'SkCanvasStateUtils', 'SkCurveMeasure', 'SkDeferredCanvas', 'SkDumpCanvas', 'SkFrontBufferedStream', 'SkInterpolator', 'SkLayer', 'SkMeshUtils', 'SkMD5', 'SkMultiPictureDocument', 'SkNinePatch', 'SkNullCanvas', 'SkNWayCanvas', 'SkPaintFilterCanvas', 'SkParseColor', 'SkPatchGrid', 'SkRTConf', 'SkTextBox', 'SkWhitelistTypefaces', ] def isblacklisted(value): for item in blacklist: if value.find(item) >= 0: return True return False separated = defaultdict(set, { 'common': { 'skia/src/core/SkBlurImageFilter.cpp', 'skia/src/core/SkGpuBlurUtils.cpp', 'skia/src/effects/SkDashPathEffect.cpp', 'skia/src/effects/SkImageSource.cpp', 'skia/src/effects/SkLayerRasterizer.cpp', 'skia/src/gpu/gl/GrGLCreateNativeInterface_none.cpp', 'skia/src/ports/SkDiscardableMemory_none.cpp', 'skia/src/ports/SkMemory_mozalloc.cpp', 'skia/src/ports/SkImageEncoder_none.cpp', 'skia/src/ports/SkImageGenerator_none.cpp', }, 'android': { # 'skia/src/ports/SkDebug_android.cpp', 'skia/src/ports/SkFontHost_cairo.cpp', # 'skia/src/ports/SkFontHost_FreeType.cpp', # 'skia/src/ports/SkFontHost_FreeType_common.cpp', # 'skia/src/ports/SkTime_Unix.cpp', # 'skia/src/utils/SkThreadUtils_pthread.cpp', }, 'linux': { 'skia/src/ports/SkFontHost_cairo.cpp', }, 'intel': { # There is currently no x86-specific opt for SkTextureCompression 'skia/src/opts/opts_check_x86.cpp', 'skia/src/opts/SkOpts_ssse3.cpp', 'skia/src/opts/SkOpts_sse41.cpp', 'skia/src/opts/SkOpts_sse42.cpp', 'skia/src/opts/SkOpts_avx.cpp', 'skia/src/opts/SkOpts_hsw.cpp', }, 'arm': { 'skia/src/core/SkUtilsArm.cpp', }, 'neon': { 'skia/src/opts/SkOpts_neon.cpp', }, 'none': set(), 'pdf': set(), 'gpu': set() }) for plat in platform_sources.keys(): for value in platform_sources[plat]: if isblacklisted(value): continue if value in separated['common']: continue key = plat if '_SSE' in value or '_SSSE' in value: key = 'intel' elif '_neon' in value: key = 'neon' elif '_arm' in value: key = 'arm' elif '_none' in value: key = 'none' elif 'gpu' in value or 'Gpu' in value: key = 'gpu' elif all(value in platform_sources.get(p, {}) for p in platforms if p != plat): key = 'common' separated[key].add(value) if os.system("cd skia && GYP_GENERATORS=dump_mozbuild ./gyp_skia -D OS=linux -D host_os=linux -R pdf gyp/pdf.gyp") != 0: print 'Failed to generate sources for Skia PDF' else: f = open('skia/sources.json'); separated['pdf'].add('skia/src/core/SkMD5.cpp'); separated['pdf'].update(filter(lambda x: 'pdf' in x, set(v.replace('../', 'skia/') for v in json.load(f)))); f.close() return separated def uniq(seq): seen = set() seen_add = seen.add return [ x for x in seq if x not in seen and not seen_add(x)] def write_cflags(f, values, subsearch, cflag, indent): def write_indent(indent): for _ in range(indent): f.write(' ') if isinstance(subsearch, str): subsearch = [ subsearch ] def iswhitelisted(value): for item in subsearch: if value.find(item) >= 0: return True return False val_list = uniq(sorted(values, key=lambda x: x.lower())) if len(val_list) == 0: return for val in val_list: if iswhitelisted(val): write_indent(indent) f.write("SOURCES[\'" + val + "\'].flags += " + cflag + "\n") opt_whitelist = [ 'skia/src/opts/Sk', 'SkOpts', 'SkBitmapProcState', 'SkBlitMask', 'SkBlitRow', 'SkBlitter', 'SkSpriteBlitter', 'SkMatrix.cpp', ] # Unfortunately for now the gpu and pathops directories are # non-unifiable. Keep track of this and fix it. unified_blacklist = [ 'FontHost', 'SkAdvancedTypefaceMetrics', 'SkBitmapProcState_matrixProcs.cpp', 'SkBlitter_A8.cpp', 'SkBlitter_ARGB32.cpp', 'SkBlitter_RGB16.cpp', 'SkBlitter_Sprite.cpp', 'SkScan_Antihair.cpp', 'SkParse.cpp', 'SkPDFFont.cpp', 'SkPictureData.cpp', 'GrDrawContext', 'GrResourceCache', 'GrAA', 'GrGL', 'GrBatchAtlas.cpp', 'GrMSAAPathRenderer.cpp', 'GrNonAAFillRect', 'SkColorSpace', 'SkImage_Gpu.cpp', 'SkPathOpsDebug.cpp', 'SkParsePath.cpp', 'SkRecorder.cpp', 'SkMiniRecorder.cpp', 'SkXfermode', 'SkMatrix44.cpp', ] + opt_whitelist def write_sources(f, values, indent): def isblacklisted(value): for item in unified_blacklist: if value.find(item) >= 0: return True return False sources = {} sources['nonunified'] = set() sources['unified'] = set() for item in values: if isblacklisted(item): sources['nonunified'].add(item) else: sources['unified'].add(item) write_list(f, "SOURCES", sources['unified'], indent) write_list(f, "SOURCES", sources['nonunified'], indent) def write_list(f, name, values, indent): def write_indent(indent): for _ in range(indent): f.write(' ') val_list = uniq(sorted(values, key=lambda x: x.lower())) if len(val_list) == 0: return write_indent(indent) f.write(name + ' += [\n') for val in val_list: write_indent(indent + 4) f.write('\'' + val + '\',\n') write_indent(indent) f.write(']\n') def write_mozbuild(sources): filename = 'moz.build' f = open(filename, 'w') f.write(header) write_sources(f, sources['common'], 0) write_cflags(f, sources['common'], opt_whitelist, 'skia_opt_flags', 0) f.write("if CONFIG['MOZ_ENABLE_SKIA_PDF']:\n") write_sources(f, sources['pdf'], 4) f.write("if CONFIG['MOZ_ENABLE_SKIA_GPU']:\n") write_sources(f, sources['gpu'], 4) f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('android'):\n") write_sources(f, sources['android'], 4) f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] in {'cocoa', 'uikit'}:\n") write_sources(f, sources['mac'], 4) f.write("if 'gtk' in CONFIG['MOZ_WIDGET_TOOLKIT']:\n") write_sources(f, sources['linux'], 4) f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':\n") # Windows-specific files don't get unification because of nasty headers. # Luckily there are not many files in this. write_list(f, "SOURCES", sources['win'], 4) f.write("if CONFIG['INTEL_ARCHITECTURE']:\n") write_sources(f, sources['intel'], 4) write_cflags(f, sources['intel'], opt_whitelist, 'skia_opt_flags', 4) f.write("elif CONFIG['CPU_ARCH'] in ('arm', 'aarch64') and CONFIG['GNU_CC']:\n") write_sources(f, sources['arm'], 4) write_cflags(f, sources['arm'], opt_whitelist, 'skia_opt_flags', 4) f.write(" if CONFIG['CPU_ARCH'] == 'aarch64':\n") write_sources(f, sources['neon'], 8) f.write(" elif CONFIG['BUILD_ARM_NEON']:\n") write_list(f, 'SOURCES', sources['neon'], 8) write_cflags(f, sources['neon'], 'neon', "CONFIG['NEON_FLAGS']", 8) f.write(" if CONFIG['CPU_ARCH'] == 'aarch64' or CONFIG['BUILD_ARM_NEON']:\n") write_cflags(f, sources['neon'], opt_whitelist, 'skia_opt_flags', 8) f.write("else:\n") write_sources(f, sources['none'], 4) f.write(footer) f.close() print 'Wrote ' + filename def main(): platform_sources = generate_platform_sources() separated_sources = generate_separated_sources(platform_sources) write_mozbuild(separated_sources) if __name__ == '__main__': main()