1
# $Id: get-footprint.py 1352 2007-06-08 01:41:25Z bennylp $
3
# This file is used to generate PJSIP/PJMEDIA footprint report.
4
# To use this file, just run it in pjsip-apps/build directory, to
5
# produce footprint.txt and footprint.htm report files.
14
['BASE', 'Empty application size'],
15
['', 'Subtotal: Empty application size'],
17
['HAS_PJLIB', 'Minimum PJLIB only'],
23
['HAS_PJLIB_STUN', 'STUN client'],
24
['HAS_PJLIB_GETOPT', 'getopt() functionality'],
32
['BASE', 'Empty application size'],
33
['', 'Subtotal: empty application size on this platform'],
35
['HAS_PJLIB', 'PJLIB (pool, data structures, hash tables, ioqueue, socket, timer heap, etc.). ' +
36
'For targets that statically link application with LIBC, the size includes ' +
37
'various LIBC functions that are used by PJLIB.'],
38
['', 'Subtotal: Application linked with PJLIB'],
41
['HAS_PJLIB_STUN', 'PJLIB-UTIL STUN client'],
42
['HAS_PJLIB_GETOPT', 'PJLIB-UTIL getopt() functionality'],
43
['HAS_PJLIB_SCANNER', 'PJLIB-UTIL text scanner (needed by SIP parser)'],
44
['HAS_PJLIB_XML', 'PJLIB-UTIL tiny XML (parsing and API) (needs text scanner)'],
45
['HAS_PJLIB_DNS', 'PJLIB-UTIL DNS packet and parsing'],
46
['HAS_PJLIB_RESOLVER', 'PJLIB-UTIL Asynchronous DNS resolver/caching engine'],
47
['HAS_PJLIB_CRC32', 'PJLIB-UTIL CRC32 algorithm'],
48
['HAS_PJLIB_HMAC_MD5', 'PJLIB-UTIL HMAC-MD5 algorithm'],
49
['HAS_PJLIB_HMAC_SHA1', 'PJLIB-UTIL HMAC-SHA1 algorithm'],
52
['HAS_PJSIP_CORE_MSG_ELEM', 'PJSIP Core - Messaging Elements and Parsing (message, headers, SIP URI, TEL URI/RFC 3966, etc.)'],
53
['HAS_PJSIP_CORE', 'PJSIP Core - Endpoint (transport management, module management, event distribution, etc.)'],
54
['HAS_PJSIP_CORE_MSG_UTIL', 'PJSIP Core - Stateless operations, SIP SRV, server resolution and fail-over'],
55
['HAS_PJSIP_UDP_TRANSPORT', 'PJSIP UDP transport'],
56
['', 'Subtotal: A minimalistic SIP application (parsing, UDP transport+STUN, no transaction)'],
58
['HAS_PJSIP_TCP_TRANSPORT', 'PJSIP TCP transport'],
59
['HAS_PJSIP_TLS_TRANSPORT', 'PJSIP TLS transport'],
60
['HAS_PJSIP_INFO', 'PJSIP INFO support (RFC 2976) (no special treatment, thus the zero size)'],
61
['HAS_PJSIP_TRANSACTION', 'PJSIP transaction and stateful API'],
62
['HAS_PJSIP_AUTH_CLIENT', 'PJSIP digest authentication client'],
63
['HAS_PJSIP_UA_LAYER', 'PJSIP User agent layer and base dialog and usage management (draft-ietf-sipping-dialogusage-01)'],
64
['HAS_PJMEDIA_SDP', 'PJMEDIA SDP Parsing and API (RFC 2327), needed by SDP negotiator'],
65
['HAS_PJMEDIA_SDP_NEGOTIATOR','PJMEDIA SDP negotiator (RFC 3264), needed by INVITE session'],
66
['HAS_PJSIP_INV_SESSION', 'PJSIP INVITE session API'],
67
['HAS_PJSIP_REGC', 'PJSIP client registration API'],
68
['', 'Subtotal: Minimal SIP application with registration (including digest authentication)'],
70
['HAS_PJSIP_EVENT_FRAMEWORK','PJSIP Event/SUBSCRIBE framework, RFC 3265 (needed by call transfer, and presence)'],
71
['HAS_PJSIP_CALL_TRANSFER', 'PJSIP Call Transfer/REFER support (RFC 3515)'],
72
['', 'Subtotal: Minimal SIP application with call transfer'],
75
['HAS_PJSIP_PRESENCE', 'PJSIP Presence subscription, including PIDF/X-PIDF support (RFC 3856, RFC 3863, etc) (needs XML)'],
76
['HAS_PJSIP_MESSAGE', 'PJSIP Instant Messaging/MESSAGE support (RFC 3428) (no special treatment, thus the zero size)'],
77
['HAS_PJSIP_IS_COMPOSING', 'PJSIP Message Composition indication (RFC 3994)'],
80
['', 'Subtotal: Complete PJSIP package (call, registration, presence, IM) +STUN +GETOPT (+PJLIB), no media'],
83
['HAS_PJNATH_STUN', 'PJNATH STUN'],
84
['HAS_PJNATH_ICE', 'PJNATH ICE'],
87
['HAS_PJMEDIA_EC', 'PJMEDIA accoustic echo cancellation'],
88
['HAS_PJMEDIA_SND_DEV', 'PJMEDIA sound device backend (platform specific)'],
89
['HAS_PJMEDIA_SILENCE_DET', 'PJMEDIA Adaptive silence detector'],
90
['HAS_PJMEDIA', 'PJMEDIA endpoint'],
91
['HAS_PJMEDIA_PLC', 'PJMEDIA Packet Lost Concealment implementation (needed by G.711, GSM, and sound device port)'],
92
['HAS_PJMEDIA_SND_PORT', 'PJMEDIA sound device media port'],
93
['HAS_PJMEDIA_RESAMPLE', 'PJMEDIA resampling algorithm (large filter disabled)'],
94
['HAS_PJMEDIA_G711_CODEC', 'PJMEDIA G.711 codec (PCMA/PCMU, including PLC) (may have already been linked by other module)'],
95
['HAS_PJMEDIA_CONFERENCE', 'PJMEDIA conference bridge (needs resampling and silence detector)'],
96
['HAS_PJMEDIA_MASTER_PORT', 'PJMEDIA master port'],
97
['HAS_PJMEDIA_RTP', 'PJMEDIA stand-alone RTP'],
98
['HAS_PJMEDIA_RTCP', 'PJMEDIA stand-alone RTCP and media quality calculation'],
99
['HAS_PJMEDIA_JBUF', 'PJMEDIA stand-alone adaptive jitter buffer'],
100
['HAS_PJMEDIA_STREAM', 'PJMEDIA stream for remote media communication (needs RTP, RTCP, and jitter buffer)'],
101
['HAS_PJMEDIA_TONEGEN', 'PJMEDIA tone generator'],
102
['HAS_PJMEDIA_UDP_TRANSPORT','PJMEDIA UDP media transport'],
103
['HAS_PJMEDIA_FILE_PLAYER', 'PJMEDIA WAV file player'],
104
['HAS_PJMEDIA_FILE_CAPTURE', 'PJMEDIA WAV file writer'],
105
['HAS_PJMEDIA_MEM_PLAYER', 'PJMEDIA fixed buffer player'],
106
['HAS_PJMEDIA_MEM_CAPTURE', 'PJMEDIA fixed buffer writer'],
107
['HAS_PJMEDIA_ICE', 'PJMEDIA ICE transport'],
110
['', 'Subtotal: Complete SIP and all PJMEDIA features (G.711 codec only)'],
113
['HAS_PJMEDIA_GSM_CODEC', 'PJMEDIA GSM codec (including PLC)'],
114
['HAS_PJMEDIA_SPEEX_CODEC', 'PJMEDIA Speex codec (narrowband, wideband, ultra-wideband)'],
115
['HAS_PJMEDIA_ILBC_CODEC', 'PJMEDIA iLBC codec'],
118
['', 'TOTAL: complete libraries (+all codecs)'],
121
# Executable size report, tuple of:
122
# <all flags>, <flags added>, <text size>, <data>, <bss>, <description>
126
# Write the report to text file
128
def print_text_report(filename):
129
output = open(filename, 'w')
131
output.write('PJSIP and PJMEDIA footprint report\n')
132
output.write('Auto-generated by pjsip-apps/build/get-footprint.py\n')
135
# Write Revision info.
136
f = os.popen('svn info | grep Revision')
137
output.write(f.readline())
139
output.write('Date: ')
140
output.write(time.asctime())
144
# Write individual module size
145
output.write('Footprint (in bytes):\n')
146
output.write(' .text .data .bss Module Description\n')
147
output.write('==========================================================\n')
149
for i in range(1, len(exe_size)):
155
output.write( string.rjust(`string.atoi(e[2]) - string.atoi(prev[2])`, 8) )
156
output.write( string.rjust(`string.atoi(e[3]) - string.atoi(prev[3])`, 8) )
157
output.write( string.rjust(`string.atoi(e[4]) - string.atoi(prev[4])`, 8) )
158
output.write(' ' + e[5] + '\n')
160
output.write(' ------------------------\n')
162
output.write( string.rjust(e[2], 8) )
163
output.write( string.rjust(e[3], 8) )
164
output.write( string.rjust(e[4], 8) )
165
output.write(' ' + e[5] + '\n')
174
# Write the report to HTML file
176
def print_html_report():
179
f = os.popen('svn info | grep Revision')
180
revision = f.readline().split()[1]
182
# Get Machine, OS, and CC name
183
f = os.popen('make -f Footprint.mak print_name')
184
names = f.readline().split()
191
filename = 'footprint-' + m + '-' + o + '.htm'
192
output = open(filename, 'w')
194
title = 'PJSIP and PJMEDIA footprint report for ' + m + '-' + o + ' target'
195
output.write('<HTML><HEAD>\n');
196
output.write(' <TITLE>' + title + '</TITLE>\n')
197
output.write(' <LINK href="/style/style.css" type="text/css" rel="stylesheet">\n')
198
output.write('</HEAD>\n');
199
output.write('<BODY bgcolor="white">\n');
200
output.write('<!--#include virtual="/header.html" -->')
202
output.write(' <H1>' + title + '</H1>\n')
203
output.write('Auto-generated by pjsip-apps/build/get-footprint.py script\n')
204
output.write('<p>Date: ' + time.asctime() + '<BR>\n')
205
output.write('Revision: r' + revision + '</p>\n\n')
206
output.write('<HR>\n')
210
output.write('<H2>Build Configuration</H2>\n')
213
output.write('\n<H3>build.mak</H3>\n')
214
output.write('<tt>\n')
215
f = open('../../build.mak', 'r')
218
output.write(l + '<BR>\n')
219
output.write('</tt>\n')
220
output.write('<p>Using ' + cc + ' version ' + cc_ver +'</p>\n')
223
output.write('\n<H3>user.mak</H3>\n')
224
output.write('<tt>\n')
225
f = open('../../user.mak', 'r')
228
output.write(l + '<BR>\n')
229
output.write('</tt>\n')
232
output.write('\n<H3><pj/config.site.h></H3>\n')
233
output.write('<tt>\n')
234
f = os.popen('cpp -dM -I../../pjlib/include ../../pjlib/include/pj/config_site.h | grep PJ')
237
output.write(l + '<BR>\n')
238
output.write('</tt>\n')
242
# Write individual module size
243
output.write('<H2>Footprint Report</H2>\n')
244
output.write('<p>The table below shows the footprint of individual feature, in bytes.</p>')
245
output.write('<TABLE border="1" cellpadding="2" cellspacing="0">\n' +
246
'<TR bgcolor="#e8e8ff">\n' +
247
' <TD align="center"><strong>.text</strong></TD>\n' +
248
' <TD align="center"><strong>.data</strong></TD>\n' +
249
' <TD align="center"><strong>.bss</strong></TD>\n' +
250
' <TD align="center"><strong>Features/Module Description</strong></TD>\n' +
254
for i in range(1, len(exe_size)):
258
output.write('<TR>\n')
260
output.write( ' <TD align="right">' + `string.atoi(e[2]) - string.atoi(prev[2])` + '</TD>\n')
261
output.write( ' <TD align="right">' + `string.atoi(e[3]) - string.atoi(prev[3])` + '</TD>\n')
262
output.write( ' <TD align="right">' + `string.atoi(e[4]) - string.atoi(prev[4])` + '</TD>\n' )
263
output.write( ' <TD>' + e[5] + '</TD>\n')
265
empty_size = exe_size[1]
266
output.write('<TR bgcolor="#e8e8ff">\n')
267
output.write( ' <TD align="right"> </TD>\n')
268
output.write( ' <TD align="right"> </TD>\n')
269
output.write( ' <TD align="right"> </TD>\n')
270
output.write( ' <TD><strong>' + e[5] + ': .text=' + e[2]+ ', .data=' + e[3] + ', .bss=' + e[4] )
271
output.write( '\n </strong> <BR>(Size minus empty application size: ' + \
272
'.text=' + `string.atoi(e[2]) - string.atoi(empty_size[2])` + \
273
', .data=' + `string.atoi(e[3]) - string.atoi(empty_size[3])` + \
274
', .data=' + `string.atoi(e[4]) - string.atoi(empty_size[4])` + \
276
output.write( ' </TD>\n')
278
output.write('</TR>\n')
280
output.write('</TABLE>\n')
281
output.write('<!--#include virtual="/footer.html" -->')
282
output.write('</BODY>\n')
283
output.write('</HTML>\n')
292
# Get the size of individual feature
294
def get_size(all_flags, flags, desc):
295
file = 'footprint.exe'
297
rc = os.system("make -f Footprint.mak FCFLAGS='" + all_flags + "' clean")
298
# Make the executable
299
cmd = "make -f Footprint.mak FCFLAGS='" + all_flags + "' all"
305
# Run 'size' against the executable
306
f = os.popen('size ' + file)
307
# Skip header of the 'size' output
313
tokens = size.split()
314
# Build the size tuple and add to exe_size
315
elem = all_flags, flags, tokens[0], tokens[1], tokens[2], desc
316
exe_size.append(elem)
318
rc = os.system("make -f Footprint.mak FCFLAGS='" + all_flags + "' clean")
321
elem = '', '', '0', '0', '0', ''
322
exe_size.append(elem)
325
for elem in compile_flags:
327
flags = '-D' + elem[0]
328
all_flags += flags + ' '
329
get_size(all_flags, elem[0], elem[1])
331
e = exe_size[len(exe_size)-1]
332
n = all_flags, '', e[2], e[3], e[4], elem[1]
336
#print_text_report('footprint.txt')