mirror of
https://git.proxmox.com/git/fwupd
synced 2025-05-15 22:52:20 +00:00

Also, we now verify the version script is correct each time we run the tests; the consequences of getting the version script wrong are terribly bad. Note, we can't actually use generated .map file for two reasons: 1. We don't hard depend on GObject Introspection 2. The map file is required to build the lib that the GIR is built from To avoid the circular dep, and to ensure we don't change exported API accidentaly actually check in a version of the version script to git.
120 lines
4.1 KiB
Python
Executable File
120 lines
4.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# pylint: disable=invalid-name,missing-docstring
|
|
#
|
|
# Copyright (C) 2017 Richard Hughes <richard@hughsie.com>
|
|
#
|
|
# Licensed under the GNU General Public License Version 2
|
|
#
|
|
# This program is free software; you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation; either version 2 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import sys
|
|
import xml.etree.ElementTree as ET
|
|
|
|
XMLNS = '{http://www.gtk.org/introspection/core/1.0}'
|
|
XMLNS_C = '{http://www.gtk.org/introspection/c/1.0}'
|
|
|
|
def usage(return_code):
|
|
""" print usage and exit with the supplied return code """
|
|
if return_code == 0:
|
|
out = sys.stdout
|
|
else:
|
|
out = sys.stderr
|
|
out.write("usage: %s <NAME> <INPUT> <OUTPUT>\n" % sys.argv[0])
|
|
sys.exit(return_code)
|
|
|
|
class LdVersionScript:
|
|
""" Rasterize some text """
|
|
|
|
def __init__(self, library_name):
|
|
self.library_name = library_name
|
|
self.releases = {}
|
|
|
|
def _add_node(self, node):
|
|
identifier = node.attrib[XMLNS_C + 'identifier']
|
|
if 'version' not in node.attrib:
|
|
print('No version for', identifier)
|
|
sys.exit(1)
|
|
return
|
|
version = node.attrib['version']
|
|
if version not in self.releases:
|
|
self.releases[version] = []
|
|
release = self.releases[version]
|
|
release.append(identifier)
|
|
return version
|
|
|
|
def import_gir(self, filename):
|
|
tree = ET.parse(filename)
|
|
root = tree.getroot()
|
|
for ns in root.findall(XMLNS + 'namespace'):
|
|
for node in ns.findall(XMLNS + 'function'):
|
|
self._add_node(node)
|
|
for cls in ns.findall(XMLNS + 'class'):
|
|
|
|
# add all class functions
|
|
for node in cls.findall(XMLNS + 'function'):
|
|
self._add_node(node)
|
|
|
|
# add the constructor
|
|
for node in cls.findall(XMLNS + 'constructor'):
|
|
self._add_node(node)
|
|
|
|
# choose the lowest version method for the _get_type symbol
|
|
version_lowest = None
|
|
type_name = cls.attrib['{http://www.gtk.org/introspection/glib/1.0}get-type']
|
|
|
|
# add all class methods
|
|
for node in cls.findall(XMLNS + 'method'):
|
|
version_tmp = self._add_node(node)
|
|
if version_tmp:
|
|
if not version_lowest or version_tmp < version_lowest:
|
|
version_lowest = version_tmp
|
|
|
|
# finally add the get_type symbol
|
|
if version_lowest:
|
|
self.releases[version_lowest].append(type_name)
|
|
|
|
def render(self):
|
|
|
|
# get a sorted list of all the versions
|
|
versions = []
|
|
for version in self.releases:
|
|
versions.append(version)
|
|
|
|
# output the version data to a file
|
|
verout = '# generated automatically, do not edit!\n'
|
|
oldversion = None
|
|
for version in sorted(versions):
|
|
symbols = sorted(self.releases[version])
|
|
verout += '\n%s_%s {\n' % (self.library_name, version)
|
|
verout += ' global:\n'
|
|
for symbol in symbols:
|
|
verout += ' %s;\n' % symbol
|
|
verout += ' local: *;\n'
|
|
if oldversion:
|
|
verout += '} %s_%s;\n' % (self.library_name, oldversion)
|
|
else:
|
|
verout += '};\n'
|
|
oldversion = version
|
|
return verout
|
|
|
|
if __name__ == '__main__':
|
|
if {'-?', '--help', '--usage'}.intersection(set(sys.argv)):
|
|
usage(0)
|
|
if len(sys.argv) != 4:
|
|
usage(1)
|
|
|
|
ld = LdVersionScript(library_name=sys.argv[1])
|
|
ld.import_gir(sys.argv[2])
|
|
open(sys.argv[3], 'w').write(ld.render())
|