]> git.0d.be Git - empathy.git/blob - tools/make-version-script.py
Updated Slovak translation
[empathy.git] / tools / make-version-script.py
1 #!/usr/bin/python
2
3 """Construct a GNU ld or Debian dpkg version-script from a set of
4 RFC822-style symbol lists.
5
6 Usage:
7     make-version-script.py [--symbols SYMBOLS] [--unreleased-version VER]
8         [--dpkg "LIBRARY.so.0 LIBRARY0 #MINVER#"]
9         [--dpkg-build-depends-package LIBRARY-dev]
10         [FILES...]
11
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.
16
17 Comments (lines starting with whitespace + "#") are allowed and ignored.
18
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.
23
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.
28
29 This script originates in telepathy-glib <http://telepathy.freedesktop.org/> -
30 please send us any changes that are needed.
31 """
32
33 # Copyright (C) 2008-2010 Collabora Ltd. <http://www.collabora.co.uk/>
34 # Copyright (C) 2008 Nokia Corporation
35 #
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.
39
40 import sys
41 from getopt import gnu_getopt
42
43
44 def e(format, *args):
45     sys.stderr.write((format + '\n') % args)
46
47
48 def main(abifiles, symbols=None, unreleased_version=None,
49          dpkg=False, dpkg_first_line=None, dpkg_build_depends_package=None):
50
51     gnuld = not dpkg
52     symbol_set = None
53
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)
58
59     versioned_symbols = set()
60
61     dpkg_symbols = []
62     dpkg_versions = []
63
64     if dpkg:
65         assert dpkg_first_line is not None
66         print(dpkg_first_line)
67         if dpkg_build_depends_package is not None:
68             print("* Build-Depends-Package: %s" % dpkg_build_depends_package)
69
70     for filename in abifiles:
71         lines = open(filename, 'r').readlines()
72
73         version = None
74         extends = None
75         release = None
76
77         for i, line in enumerate(lines):
78             line = line.strip()
79
80             if line.startswith('#'):
81                 continue
82             elif not line:
83                 # the transition betwen headers and symbols
84                 cut = i + 1
85                 break
86             elif line.lower().startswith('version:'):
87                 line = line[8:].strip()
88                 version = line
89                 continue
90             elif line.lower().startswith('extends:'):
91                 line = line[8:].strip()
92                 extends = line
93                 continue
94             elif line.lower().startswith('release:'):
95                 release = line[8:].strip()
96                 continue
97             else:
98                 e('Could not understand line in %s header: %s', filename, line)
99                 raise SystemExit(1)
100
101         else:
102             e('No symbols in %s', filename)
103             raise SystemExit(1)
104
105         if version is None:
106             e('No Versions: header in %s', filename)
107             raise SystemExit(1)
108
109         if extends is None:
110             e('No Extends: header in %s', filename)
111             raise SystemExit(1)
112
113         if release is None and dpkg:
114             e('No Release: header in %s', filename)
115             raise SystemExit(1)
116
117         if dpkg:
118             dpkg_versions.append('%s@%s %s' % (version, version, release))
119
120         lines = lines[cut:]
121
122         if gnuld:
123             print("%s {" % version)
124             print("    global:")
125
126         for symbol in lines:
127             symbol = symbol.strip()
128
129             if symbol.startswith('#'):
130                 continue
131
132             if gnuld:
133                 print("        %s;" % symbol)
134             elif dpkg:
135                 dpkg_symbols.append('%s@%s %s' % (symbol, version, release))
136
137             if symbol in versioned_symbols:
138                 raise AssertionError('Symbol %s is in version %s and an '
139                                      'earlier version' % (symbol, version))
140
141             versioned_symbols.add(symbol)
142
143         if gnuld:
144             if extends == '-':
145                 print("    local:")
146                 print("        *;")
147                 print("};")
148             else:
149                 print("} %s;" % extends)
150                 print("")
151
152     if dpkg:
153         dpkg_symbols.sort()
154         dpkg_versions.sort()
155
156         for x in dpkg_versions:
157             print(" %s" % x)
158
159         for x in dpkg_symbols:
160             print(" %s" % x)
161
162     if symbol_set is not None:
163         missing = versioned_symbols - symbol_set
164
165         if missing:
166             e('These symbols have disappeared:')
167
168             for symbol in missing:
169                 e('    %s', symbol)
170
171             raise SystemExit(1)
172
173         unreleased = symbol_set - versioned_symbols
174
175         if unreleased:
176             if unreleased_version is None:
177                 e('Unversioned symbols are not allowed in releases:')
178
179                 for symbol in unreleased:
180                     e('    %s', symbol)
181
182                 raise SystemExit(1)
183
184             if gnuld:
185                 print("%s {" % unreleased_version)
186                 print("    global:")
187
188                 for symbol in unreleased:
189                     print("        %s;" % symbol)
190
191                 print("} %s;" % version)
192
193
194 if __name__ == '__main__':
195     options, argv = gnu_getopt (sys.argv[1:], '',
196                                 ['symbols=', 'unreleased-version=',
197                                  'dpkg=', 'dpkg-build-depends-package='])
198
199     opts = {'dpkg': False}
200
201     for option, value in options:
202         if option == '--dpkg':
203             opts['dpkg'] = True
204             opts['dpkg_first_line'] = value
205         else:
206             opts[option.lstrip('-').replace('-', '_')] = value
207
208     main(argv, **opts)