tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

generate_mozbuild.py (13607B)


      1 #!/usr/bin/env python3
      2 
      3 import locale
      4 import subprocess
      5 from collections import defaultdict
      6 locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
      7 
      8 header = """
      9 #
     10 #   #####   #######           #     #     #     #     #     #
     11 # ##     #  #     #          # #    #  #  #    # #     #   #
     12 # ##        #     #         #   #   #  #  #   #   #     # #
     13 # ##  ####  #     #        #     #  #  #  #  #     #     #
     14 # ##     #  #     #        #######  #  #  #  #######     #      ###
     15 # ##     #  #     #        #     #  #  #  #  #     #     #      ###
     16 # # #####   #######        #     #   ## ##   #     #     #      ###
     17 #
     18 # Seriously. You shouldn't even be looking at this file unless you're
     19 # debugging generate_mozbuild.py.
     20 #
     21 # DO NOT MODIFY THIS FILE IT IS AUTOGENERATED.
     22 #
     23 
     24 skia_opt_flags = []
     25 
     26 if CONFIG['MOZ_OPTIMIZE']:
     27    if CONFIG['CC_TYPE'] == 'clang-cl':
     28        skia_opt_flags += ['-O2']
     29    elif CONFIG['CC_TYPE'] in ('clang', 'gcc'):
     30        skia_opt_flags += ['-O3']
     31 
     32 """
     33 
     34 footer = """
     35 
     36 # We allow warnings for third-party code that can be updated from upstream.
     37 AllowCompilerWarnings()
     38 
     39 FINAL_LIBRARY = 'xul'
     40 LOCAL_INCLUDES += [
     41    'skia',
     42 ]
     43 
     44 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
     45    DEFINES['UNICODE'] = True
     46    DEFINES['_UNICODE'] = True
     47 
     48 # We should autogenerate these SSE related flags.
     49 
     50 if CONFIG['INTEL_ARCHITECTURE']:
     51    SOURCES['skia/modules/skcms/skcms.cc'].flags += ['-DSKCMS_DISABLE_SKX']
     52    skia_ssse3_flags = ['-Dskvx=skvx_ssse3', '-mssse3']
     53    skia_avx_flags = ['-Dskvx=skvx_avx', '-mavx']
     54    skia_hsw_flags = ['-Dskvx=skvx_hsw', '-mavx2', '-mf16c', '-mfma']
     55    SOURCES['skia/src/core/SkBitmapProcState_opts_ssse3.cpp'].flags += skia_ssse3_flags
     56    SOURCES['skia/src/core/SkBlitMask_opts_ssse3.cpp'].flags += skia_ssse3_flags
     57    SOURCES['skia/src/core/SkSwizzler_opts_ssse3.cpp'].flags += ['-Dskvx=skvx_ssse3']
     58    SOURCES['skia/src/core/SkMemset_opts_avx.cpp'].flags += skia_avx_flags
     59    SOURCES['skia/src/core/SkBlitRow_opts_hsw.cpp'].flags += skia_hsw_flags
     60    SOURCES['skia/src/core/SkSwizzler_opts_hsw.cpp'].flags += ['-Dskvx=skvx_hsw']
     61    SOURCES['skia/src/opts/SkOpts_hsw.cpp'].flags += skia_hsw_flags
     62    SOURCES['skia/modules/skcms/src/skcms_TransformHsw.cc'].flags += skia_hsw_flags
     63 
     64 DEFINES['MOZ_SKIA'] = True
     65 
     66 DEFINES['SKIA_IMPLEMENTATION'] = 1
     67 
     68 DEFINES['SK_PDF_USE_HARFBUZZ_SUBSETTING'] = 1
     69 
     70 if CONFIG['MOZ_TREE_FREETYPE']:
     71    DEFINES['SK_CAN_USE_DLOPEN'] = 0
     72 
     73 # Suppress warnings in third-party code.
     74 CXXFLAGS += [
     75    '-Wno-deprecated-declarations',
     76    '-Wno-overloaded-virtual',
     77    '-Wno-sign-compare',
     78    '-Wno-unreachable-code',
     79    '-Wno-unused-function',
     80 ]
     81 if CONFIG['CC_TYPE'] == 'gcc':
     82    CXXFLAGS += [
     83        '-Wno-logical-op',
     84        '-Wno-maybe-uninitialized',
     85    ]
     86 if CONFIG['CC_TYPE'] in ('clang', 'clang-cl'):
     87    CXXFLAGS += [
     88        '-Wno-implicit-fallthrough',
     89        '-Wno-inconsistent-missing-override',
     90        '-Wno-macro-redefined',
     91        '-Wno-unused-private-field',
     92    ]
     93 
     94 if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('gtk', 'android'):
     95    LOCAL_INCLUDES += [
     96        "/gfx/cairo/cairo/src",
     97    ]
     98    CXXFLAGS += CONFIG['CAIRO_FT_CFLAGS']
     99 
    100 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk':
    101    CXXFLAGS += CONFIG['MOZ_PANGO_CFLAGS']
    102 
    103 if CONFIG['TARGET_CPU'] in ('mips32', 'mips64'):
    104    # The skia code uses `mips` as a variable, but it's a builtin preprocessor
    105    # macro on mips that expands to `1`.
    106    DEFINES['mips'] = False
    107 
    108 # Work around bug 1841199.
    109 if CONFIG['TARGET_CPU'] in ('mips32', 'mips64', 'ppc64'):
    110    DEFINES['musttail'] = 'nomusttail'
    111 
    112 if CONFIG['TARGET_CPU'] == 'loongarch64':
    113    # In ABI1.0, the compilers disable 128bit SIMD defautly; in ABI2.0, it
    114    # enable defaultly. The below flags can maintain compatibility.
    115    CXXFLAGS += ['-mlsx']
    116    if (
    117        CONFIG['CC_TYPE'] == 'clang'
    118        and int(CONFIG["CC_VERSION"].split(".")[0]) >= 18
    119    ):
    120        CXXFLAGS += ['-flax-vector-conversions=all']
    121    else:
    122        # gcc, clang8 for loongarch64.
    123        CXXFLAGS += ['-flax-vector-conversions']
    124 
    125    SOURCES += ['skia/src/opts/SkOpts_lasx.cpp']
    126    SOURCES['skia/src/opts/SkOpts_lasx.cpp'].flags += skia_opt_flags
    127    SOURCES['skia/src/core/SkBitmapProcState_opts_lasx.cpp'].flags += ['-mlasx']
    128    SOURCES['skia/src/core/SkBlitRow_opts_lasx.cpp'].flags += ['-mlasx']
    129    SOURCES['skia/src/core/SkSwizzler_opts_lasx.cpp'].flags += ['-mlasx']
    130    SOURCES['skia/src/opts/SkOpts_lasx.cpp'].flags += ['-mlasx']
    131 """
    132 
    133 import json
    134 
    135 platforms = ['linux', 'mac', 'android', 'win']
    136 
    137 def parse_sources(output):
    138  return set(v.replace('//', 'skia/') for v in output.decode('utf-8').split() if v.endswith('.cpp') or v.endswith('.S'))
    139 
    140 def generate_opt_sources():
    141  cpus = [('intel', 'x86', [':hsw'])]
    142 
    143  opt_sources = {}
    144  for key, cpu, deps in cpus:
    145    subprocess.check_output('cd skia && bin/gn gen out/{0} --args=\'target_cpu="{1}"\''.format(key, cpu), shell=True)
    146    opt_sources[key] = set()
    147    for dep in deps:
    148        try:
    149            output = subprocess.check_output('cd skia && bin/gn desc out/{0} {1} sources'.format(key, dep), shell=True)
    150            if output:
    151                opt_sources[key].update(parse_sources(output))
    152        except subprocess.CalledProcessError as e:
    153            if e.output.find(b'source_set') < 0:
    154                raise
    155 
    156  return opt_sources
    157 
    158 def generate_platform_sources():
    159  sources = {}
    160  platform_args = {
    161    'win' : 'win_vc="C:/" win_sdk_version="00.0.00000.0" win_toolchain_version="00.00.00000"'
    162  }
    163  source_sets = [':core', ':skia', ':clipstack_utils', ':pathops']
    164  for plat in platforms:
    165    args = platform_args.get(plat, '')
    166    subprocess.check_output('cd skia && bin/gn gen out/{0} --args=\'target_os="{0}" {1}\' > /dev/null'.format(plat, args), shell=True)
    167    output = b''
    168    for source_set in source_sets:
    169      set_output = subprocess.check_output('cd skia && bin/gn desc out/{0} {1} sources'.format(plat, source_set), shell=True)
    170      if set_output:
    171        output += set_output
    172    sources[plat] = parse_sources(output)
    173 
    174  plat_deps = {
    175    ':fontmgr_win' : 'win',
    176    ':fontmgr_win_gdi' : 'win',
    177    ':fontmgr_mac_ct' : 'mac',
    178  }
    179  for dep, key in plat_deps.items():
    180    output = subprocess.check_output('cd skia && bin/gn desc out/{1} {0} sources'.format(dep, key), shell=True)
    181    if output:
    182      sources[key].update(parse_sources(output))
    183 
    184  deps = {':pdf' : 'pdf'}
    185  for dep, key in deps.items():
    186    output = subprocess.check_output('cd skia && bin/gn desc out/linux {} sources'.format(dep), shell=True)
    187    if output:
    188      sources[key] = parse_sources(output)
    189 
    190  sources.update(generate_opt_sources())
    191  return sources
    192 
    193 
    194 def generate_separated_sources(platform_sources):
    195  ignorelist = [
    196    'skia/src/android/',
    197    'skia/src/effects/Sk',
    198    'skia/src/effects/imagefilters/',
    199    'skia/src/fonts/',
    200    'skia/src/ports/SkImageEncoder',
    201    'skia/src/ports/SkImageGenerator',
    202    'SkLight',
    203    'codec',
    204    'SkWGL',
    205    'SkMemory_malloc',
    206    'third_party',
    207    'SkAnimCodecPlayer',
    208    'SkCamera',
    209    'SkCapture',
    210    'SkCanvasStack',
    211    'SkCanvasStateUtils',
    212    'SkMultiPictureDocument',
    213    'SkNullCanvas',
    214    'SkNWayCanvas',
    215    'SkOverdrawCanvas',
    216    'SkPaintFilterCanvas',
    217    'SkParseColor',
    218    'SkXPS',
    219    'SkCreateCGImageRef',
    220    'skia/src/ports/SkGlobalInitialization',
    221    'skia/src/utils/SkJSON',
    222  ]
    223 
    224  def isignorelisted(value):
    225    for item in ignorelist:
    226      if value.find(item) >= 0:
    227        return True
    228 
    229    return False
    230 
    231  separated = defaultdict(set, {
    232    'common': {
    233      'skia/src/codec/SkCodec.cpp',
    234      'skia/src/codec/SkCodecImageGenerator.cpp',
    235      'skia/src/codec/SkColorPalette.cpp',
    236      'skia/src/codec/SkImageGenerator_FromEncoded.cpp',
    237      'skia/src/codec/SkPixmapUtils.cpp',
    238      'skia/src/codec/SkSampler.cpp',
    239      'skia/src/effects/imagefilters/SkBlendImageFilter.cpp',
    240      'skia/src/effects/imagefilters/SkBlurImageFilter.cpp',
    241      'skia/src/effects/imagefilters/SkComposeImageFilter.cpp',
    242      'skia/src/effects/imagefilters/SkCropImageFilter.cpp',
    243      'skia/src/effects/SkBlenders.cpp',
    244      'skia/src/effects/SkDashPathEffect.cpp',
    245      'skia/src/encode/SkJpegEncoder_none.cpp',
    246      'skia/src/encode/SkPngEncoder_none.cpp',
    247      'skia/src/encode/SkWebpEncoder_none.cpp',
    248      'skia/src/ports/SkDiscardableMemory_none.cpp',
    249      'skia/src/ports/SkGlobalInitialization_default.cpp',
    250      'skia/src/ports/SkMemory_mozalloc.cpp',
    251      'skia/src/ports/SkImageGenerator_none.cpp',
    252      'skia/modules/skcms/skcms.cc',
    253      'skia/modules/skcms/src/skcms_TransformBaseline.cc',
    254      'skia/src/core/SkImageFilterTypes.cpp',
    255    },
    256    'android': {
    257      # 'skia/src/ports/SkDebug_android.cpp',
    258      'skia/src/ports/SkFontHost_cairo.cpp',
    259      # 'skia/src/ports/SkFontHost_FreeType.cpp',
    260      'skia/src/ports/SkFontHost_FreeType_common.cpp',
    261      # 'skia/src/ports/SkTime_Unix.cpp',
    262      # 'skia/src/utils/SkThreadUtils_pthread.cpp',
    263    },
    264    'linux': {
    265      'skia/src/ports/SkFontHost_cairo.cpp',
    266      'skia/src/ports/SkFontHost_FreeType_common.cpp',
    267    },
    268    'win': set (),
    269    'intel': {
    270      'skia/modules/skcms/src/skcms_TransformHsw.cc',
    271    },
    272    'arm': set(),
    273    'arm64': set(),
    274    'none': set(),
    275    'pdf': set()
    276  })
    277 
    278  for plat in platform_sources.keys():
    279    for value in platform_sources[plat]:
    280      if isignorelisted(value):
    281        continue
    282 
    283      if value in separated['common']:
    284        continue
    285 
    286      key = plat
    287 
    288      if all(value in platform_sources.get(p, {})
    289             for p in platforms if p != plat):
    290        key = 'common'
    291 
    292      separated[key].add(value)
    293 
    294  return separated
    295 
    296 def uniq(seq):
    297  seen = set()
    298  seen_add = seen.add
    299  return [ x for x in seq if x not in seen and not seen_add(x)]
    300 
    301 def write_cflags(f, values, subsearch, cflag, indent):
    302  def write_indent(indent):
    303    for _ in range(indent):
    304        f.write(' ')
    305 
    306  if isinstance(subsearch, str):
    307    subsearch = [ subsearch ]
    308 
    309  def isallowlisted(value):
    310    for item in subsearch:
    311      if value.find(item) >= 0:
    312        return True
    313 
    314    return False
    315 
    316  val_list = uniq(sorted(values, key=lambda x: x.lower()))
    317 
    318  if len(val_list) == 0:
    319    return
    320 
    321  for val in val_list:
    322    if isallowlisted(val):
    323      write_indent(indent)
    324      f.write("SOURCES[\'" + val + "\'].flags += " + cflag + "\n")
    325 
    326 opt_allowlist = [
    327  'SkOpts',
    328  'SkBitmapProcState',
    329  'SkBlitRow',
    330  'SkBlitter',
    331  'SkMemset',
    332  'SkSpriteBlitter',
    333  'SkSwizzler',
    334  'SkMatrix.cpp',
    335  'skcms',
    336  '_opts',
    337 ]
    338 
    339 # Unfortunately for now the gpu and pathops directories are
    340 # non-unifiable. Keep track of this and fix it.
    341 unified_ignorelist = [
    342  'FontHost',
    343  'SkBitmapProcState_matrixProcs.cpp',
    344  'SkBlitter_A8.cpp',
    345  'SkBlitter_ARGB32.cpp',
    346  'SkBlitter_Sprite.cpp',
    347  'SkCpu.cpp',
    348  'SkScan_Antihair.cpp',
    349  'SkScan_AntiPath.cpp',
    350  'SkParse.cpp',
    351  'SkPDFFont.cpp',
    352  'SkPDFDevice.cpp',
    353  'SkPDFType1Font.cpp',
    354  'SkPictureData.cpp',
    355  'SkColorSpace',
    356  'SkPath.cpp',
    357  'SkPathOpsDebug.cpp',
    358  'SkParsePath.cpp',
    359  'SkRecorder.cpp',
    360  'SkRTree.cpp',
    361  'SkVertices.cpp',
    362  'SkSLLexer.cpp',
    363  'SkTypeface_mac_ct.cpp',
    364 ] + opt_allowlist
    365 
    366 def write_sources(f, values, indent):
    367  def isignorelisted(value):
    368    for item in unified_ignorelist:
    369      if value.find(item) >= 0:
    370        return True
    371 
    372    return False
    373 
    374  sources = {}
    375  sources['nonunified'] = set()
    376  sources['unified'] = set()
    377 
    378  for item in values:
    379    if isignorelisted(item):
    380      sources['nonunified'].add(item)
    381    else:
    382      sources['unified'].add(item)
    383 
    384  write_list(f, "UNIFIED_SOURCES", sources['unified'], indent)
    385  write_list(f, "SOURCES", sources['nonunified'], indent)
    386 
    387 def write_list(f, name, values, indent):
    388  def write_indent(indent):
    389    for _ in range(indent):
    390        f.write(' ')
    391 
    392  val_list = uniq(sorted(values, key=lambda x: x.lower()))
    393 
    394  if len(val_list) == 0:
    395    return
    396 
    397  write_indent(indent)
    398  f.write(name + ' += [\n')
    399  for val in val_list:
    400    write_indent(indent + 4)
    401    f.write('\'' + val + '\',\n')
    402 
    403  write_indent(indent)
    404  f.write(']\n')
    405 
    406 def write_mozbuild(sources):
    407  filename = 'moz.build'
    408  f = open(filename, 'w')
    409 
    410  f.write(header)
    411 
    412  write_sources(f, sources['common'], 0)
    413  write_cflags(f, sources['common'], opt_allowlist, 'skia_opt_flags', 0)
    414 
    415  f.write("if CONFIG['MOZ_ENABLE_SKIA_PDF']:\n")
    416  write_sources(f, sources['pdf'], 4)
    417 
    418  f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':\n")
    419  write_sources(f, sources['android'], 4)
    420 
    421  f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('cocoa', 'uikit'):\n")
    422  write_sources(f, sources['mac'], 4)
    423 
    424  f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'gtk':\n")
    425  write_sources(f, sources['linux'], 4)
    426 
    427  f.write("if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':\n")
    428  write_list(f, "SOURCES", sources['win'], 4)
    429 
    430  f.write("if CONFIG['INTEL_ARCHITECTURE']:\n")
    431  write_sources(f, sources['intel'], 4)
    432  write_cflags(f, sources['intel'], opt_allowlist, 'skia_opt_flags', 4)
    433 
    434  if sources['arm']:
    435    f.write("elif CONFIG['TARGET_CPU'] == 'arm' and CONFIG['CC_TYPE'] in ('clang', 'gcc'):\n")
    436    write_sources(f, sources['arm'], 4)
    437    write_cflags(f, sources['arm'], opt_allowlist, 'skia_opt_flags', 4)
    438 
    439  if sources['arm64']:
    440    f.write("elif CONFIG['TARGET_CPU'] == 'aarch64':\n")
    441    write_sources(f, sources['arm64'], 4)
    442    write_cflags(f, sources['arm64'], opt_allowlist, 'skia_opt_flags', 4)
    443 
    444  if sources['none']:
    445    f.write("else:\n")
    446    write_sources(f, sources['none'], 4)
    447 
    448  f.write(footer)
    449 
    450  f.close()
    451 
    452  print('Wrote ' + filename)
    453 
    454 def main():
    455  platform_sources = generate_platform_sources()
    456  separated_sources = generate_separated_sources(platform_sources)
    457  write_mozbuild(separated_sources)
    458 
    459 
    460 if __name__ == '__main__':
    461  main()