mumble/scripts/mkflags.py
Mikkel Krautz 54dd7e71eb Split mumble_flags.qrc into seperate files to reduce .cpp size for older compilers.
With the current setup, OpenBSD 6.0's g++4 on a VM with 4GB ram can't even
build Mumble, because the generated .cpp file from mumble_flags.qrc is
32MB.

This commit attempts to work around that by splitting our SVG flags into
separate resource files.

To make it easier to work with from the qmake build, we now also generate
a mumble_flags.pri file that will automatically add all necessary .qrc
files to RESOURCES.
2016-11-27 13:49:26 +01:00

112 lines
3.1 KiB
Python

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright 2005-2016 The Mumble Developers. All rights reserved.
# Use of this source code is governed by a BSD-style license
# that can be found in the LICENSE file at the root of the
# Mumble source tree or at <https://www.mumble.info/LICENSE>.
# mkflags.py generates .pri and .qrc files from Mumble's
# flag SVGs, such that the flags can be included as Qt
# resources.
#
# The script splits the flags into multiple .qrc files once
# a single .qrc file exceeds a given threshold.
#
# This is because older compilers (and old hardware, too!)
# can have problems with large source files. When Qt embeds
# a .qrc file, it generates a .cpp file and compiles it. Some
# of our flag SVGs can be quite large, and if we only use a
# single .qrc file, it is (as of this writing) 32MB+ large.
from __future__ import (unicode_literals, print_function, division)
import os
import shutil
import codecs
import collections
# Container for an on-disk flag SVG. Contains size and filename.
OnDiskFlag = collections.namedtuple('OnDiskFlag', ['size', 'filename'])
# Once a .qrc file's content exceeds this size, the
# file will be considered full.
MAX_SIZE = 1024*1024
def main():
# Get a list of all flag SVGs, and sort them by size.
flags = []
flagsDir = os.path.join('icons', 'flags')
flagFns = os.listdir(flagsDir)
for fn in flagFns:
if not fn.lower().endswith('svg'):
continue
with open(os.path.join(flagsDir, fn), 'r') as f:
buf = f.read()
sz = len(buf)
flags.append(OnDiskFlag(size=sz, filename=fn))
flags = sorted(flags) # Sort by first tuple index (size).
# Figure out the .qrc target of the individual
# SVG files. Once a .qrc target exceeds MAX_SIZE,
# we add a new file.
flagsOut = []
curFileContent = []
curFileSz = 0
for flag in flags:
sz = flag.size
fn = flag.filename
curFileSz += sz
curFileContent.append(fn)
if curFileSz > MAX_SIZE:
flagsOut.append(curFileContent)
curFileContent = []
curFileSz = 0
if len(curFileContent) > 0:
flagsOut.append(curFileContent)
# Remove old flags qrc file.
oldFlagsQrc = os.path.join('src', 'mumble', 'mumble_flags.qrc')
if os.path.exists(oldFlagsQrc):
os.remove(oldFlagsQrc)
# Remove existing flags dir in src/mumble.
flagsOutDir = os.path.join('src', 'mumble', 'flags')
if os.path.exists(flagsOutDir):
shutil.rmtree(flagsOutDir)
os.mkdir(flagsOutDir)
# Generate output files.
for idx, content in enumerate(flagsOut):
fn = 'mumble_flags_{0}.qrc'.format(idx)
with codecs.open(os.path.join(flagsOutDir, fn), "w", "utf-8") as f:
f.write('<!DOCTYPE RCC>\n')
f.write('<RCC version="1.0">\n')
f.write('<qresource>\n')
for fn in content:
f.write('<file alias="{0}">{1}</file>\n'.format('flags/' + fn, '../../../icons/flags/' + fn))
f.write('</qresource>\n')
f.write('</RCC>\n')
# Generate .pri file for flags.
with codecs.open(os.path.join(flagsOutDir, 'mumble_flags.pri'), "w", "utf-8") as f:
for idx, _ in enumerate(flagsOut):
fn = 'mumble_flags_{0}.qrc'.format(idx)
f.write('RESOURCES *= flags/{0}\n'.format(fn))
if __name__ == '__main__':
main()