3
"""Construct a GNU ld or Debian dpkg version-script from a set of
4
RFC822-style symbol lists.
7
make-version-script.py [--symbols SYMBOLS] [--unreleased-version VER]
8
[--dpkg "LIBRARY.so.0 LIBRARY0 #MINVER#"]
9
[--dpkg-build-depends-package LIBRARY-dev]
12
Each FILE starts with RFC822-style headers "Version:" (the name of the
13
symbol version, e.g. FOO_1.2.3) and "Extends:" (either the previous
14
version, or "-" if this is the first version). Next there is a blank
15
line, then a list of C symbols one per line.
17
Comments (lines starting with whitespace + "#") are allowed and ignored.
19
If --symbols is given, SYMBOLS lists the symbols actually exported by
20
the library (one per line). If --unreleased-version is given, any symbols
21
in SYMBOLS but not in FILES are assigned to that version; otherwise, any
22
such symbols cause an error.
24
If --dpkg is given, produce a Debian dpkg-gensymbols file instead of a
25
GNU ld version-script. The argument to --dpkg is the first line of the
26
resulting symbols file, and --dpkg-build-depends-package can optionally
27
be used to set the Build-Depends-Package field.
29
This script originates in telepathy-glib <http://telepathy.freedesktop.org/> -
30
please send us any changes that are needed.
33
# Copyright (C) 2008-2010 Collabora Ltd. <http://www.collabora.co.uk/>
34
# Copyright (C) 2008 Nokia Corporation
36
# Copying and distribution of this file, with or without modification,
37
# are permitted in any medium without royalty provided the copyright
38
# notice and this notice are preserved.
41
from getopt import gnu_getopt
45
sys.stderr.write((format + '\n') % args)
48
def main(abifiles, symbols=None, unreleased_version=None,
49
dpkg=False, dpkg_first_line=None, dpkg_build_depends_package=None):
54
if symbols is not None:
55
symbol_set = open(symbols, 'r').readlines()
56
symbol_set = map(str.strip, symbol_set)
57
symbol_set = set(symbol_set)
59
versioned_symbols = set()
65
assert dpkg_first_line is not None
67
if dpkg_build_depends_package is not None:
68
print "* Build-Depends-Package: %s" % dpkg_build_depends_package
70
for filename in abifiles:
71
lines = open(filename, 'r').readlines()
77
for i, line in enumerate(lines):
80
if line.startswith('#'):
83
# the transition betwen headers and symbols
86
elif line.lower().startswith('version:'):
87
line = line[8:].strip()
90
elif line.lower().startswith('extends:'):
91
line = line[8:].strip()
94
elif line.lower().startswith('release:'):
95
release = line[8:].strip()
98
e('Could not understand line in %s header: %s', filename, line)
102
e('No symbols in %s', filename)
106
e('No Versions: header in %s', filename)
110
e('No Extends: header in %s', filename)
113
if release is None and dpkg:
114
e('No Release: header in %s', filename)
118
dpkg_versions.append('%s@%s %s' % (version, version, release))
123
print "%s {" % version
127
symbol = symbol.strip()
129
if symbol.startswith('#'):
133
print " %s;" % symbol
135
dpkg_symbols.append('%s@%s %s' % (symbol, version, release))
137
if symbol in versioned_symbols:
138
raise AssertionError('Symbol %s is in version %s and an '
139
'earlier version' % (symbol, version))
141
versioned_symbols.add(symbol)
149
print "} %s;" % extends
156
for x in dpkg_versions:
159
for x in dpkg_symbols:
162
if symbol_set is not None:
163
missing = versioned_symbols - symbol_set
166
e('These symbols have disappeared:')
168
for symbol in missing:
173
unreleased = symbol_set - versioned_symbols
176
if unreleased_version is None:
177
e('Unversioned symbols are not allowed in releases:')
179
for symbol in unreleased:
185
print "%s {" % unreleased_version
188
for symbol in unreleased:
189
print " %s;" % symbol
191
print "} %s;" % version
194
if __name__ == '__main__':
195
options, argv = gnu_getopt (sys.argv[1:], '',
196
['symbols=', 'unreleased-version=',
197
'dpkg=', 'dpkg-build-depends-package='])
199
opts = {'dpkg': False}
201
for option, value in options:
202
if option == '--dpkg':
204
opts['dpkg_first_line'] = value
206
opts[option.lstrip('-').replace('-', '_')] = value