From 2df60064afb5cb53076764d39badfd64939833b1 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Tue, 4 Jul 2006 23:48:51 +0000 Subject: Added script, source file, and makefile to calculate PJSIP/PJMEDIA footprint git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@585 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip-apps/build/get-footprint.py | 292 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 292 insertions(+) create mode 100644 pjsip-apps/build/get-footprint.py (limited to 'pjsip-apps/build/get-footprint.py') diff --git a/pjsip-apps/build/get-footprint.py b/pjsip-apps/build/get-footprint.py new file mode 100644 index 00000000..d3ba4300 --- /dev/null +++ b/pjsip-apps/build/get-footprint.py @@ -0,0 +1,292 @@ +# $Id$ +# +# This file is used to generate PJSIP/PJMEDIA footprint report. +# To use this file, just run it in pjsip-apps/build directory, to +# produce footprint.txt and footprint.htm report files. +# +import os +import sys +import string +import time + +compile_flags1 = [ + # Base + ['BASE', 'Minimum PJLIB only'], + + # Subtotal + ['', 'Subtotal'], + + # PJLIB-UTIL + ['HAS_PJLIB_STUN', 'STUN client'], + ['HAS_PJLIB_GETOPT', 'getopt() functionality'], + + # Subtotal + ['', 'TOTAL'] +] + +compile_flags = [ + # Base + ['BASE', 'PJLIB (pool, data structures, hash tables, ioqueue, timer heap)'], + ['', 'Subtotal: Minimum PJLIB application size (linked with OS libraries)'], + + # PJLIB-UTIL + ['HAS_PJLIB_STUN', 'PJLIB-UTIL STUN client'], + ['HAS_PJLIB_GETOPT', 'PJLIB-UTIL getopt() functionality'], + ['HAS_PJLIB_XML', 'PJLIB-UTIL XML parsing and API'], + + # PJSIP + ['HAS_PJSIP_CORE', 'PJSIP Core (endpoint, transport manager, parser, message elements, etc.)'], + ['HAS_PJSIP_UDP_TRANSPORT', 'PJSIP UDP transport'], + ['', 'Subtotal: A very minimum SIP application (parsing, UDP transport+STUN, no transaction)'], + + ['HAS_PJSIP_TCP_TRANSPORT', 'PJSIP TCP transport'], + ['HAS_PJSIP_INFO', 'PJSIP INFO support (RFC 2976) (no special treatment, thus the zero size)'], + ['HAS_PJSIP_TRANSACTION', 'PJSIP transaction and stateful API'], + ['HAS_PJSIP_UA_LAYER', 'PJSIP User agent layer and base dialog and usage management (draft-ietf-sipping-dialogusage-01)'], + ['HAS_PJMEDIA_SDP', 'PJMEDIA SDP API (RFC 2327), needed by SDP negotiator'], + ['HAS_PJMEDIA_SDP_NEGOTIATOR','PJMEDIA SDP negotiator (RFC 3264), needed by INVITE session'], + ['HAS_PJSIP_INV_SESSION', 'PJSIP INVITE session API'], + ['HAS_PJSIP_REGC', 'PJSIP client registration API'], + ['', 'Subtotal: Minimal SIP application with registration (including digest authentication)'], + + ['HAS_PJSIP_EVENT_FRAMEWORK','PJSIP Event/SUBSCRIBE framework, RFC 3265 (needed by call transfer, and presence)'], + ['HAS_PJSIP_CALL_TRANSFER', 'PJSIP Call Transfer/REFER support (RFC 3515)'], + ['', 'Subtotal: Minimal SIP application with call transfer'], + + + ['HAS_PJSIP_PRESENCE', 'PJSIP Presence subscription, including PIDF/X-PIDF support (RFC 3856, RFC 3863, etc) (needs XML)'], + ['HAS_PJSIP_MESSAGE', 'PJSIP Instant Messaging/MESSAGE support (RFC 3428) (no special treatment, thus the zero size)'], + ['HAS_PJSIP_IS_COMPOSING', 'PJSIP Message Composition indication (RFC 3994)'], + + # Subtotal + ['', 'Subtotal: Complete PJSIP package (call, registration, presence, IM) +STUN +GETOPT (+PJLIB), no media'], + + # PJMEDIA + ['HAS_PJMEDIA_SND_DEV', 'PJMEDIA sound device backend (platform specific)'], + ['HAS_PJMEDIA_SILENCE_DET', 'PJMEDIA Adaptive silence detector'], + ['HAS_PJMEDIA', 'PJMEDIA endpoint'], + ['HAS_PJMEDIA_PLC', 'PJMEDIA Packet Lost Concealment implementation (needed by G.711, GSM, and sound device port)'], + ['HAS_PJMEDIA_SND_PORT', 'PJMEDIA sound device media port'], + ['HAS_PJMEDIA_RESAMPLE', 'PJMEDIA high quality resampling implementation (can be fine tuned with PJMEDIA_HAS_LARGE_FILTER and PJMEDIA_HAS_SMALL_FILTER)'], + ['HAS_PJMEDIA_G711_CODEC', 'PJMEDIA G.711 codec (PCMA/PCMU, including PLC) (may have already been linked by other module)'], + ['HAS_PJMEDIA_CONFERENCE', 'PJMEDIA conference bridge (needs resampling and silence detector)'], + ['HAS_PJMEDIA_MASTER_PORT', 'PJMEDIA master port'], + ['HAS_PJMEDIA_RTP', 'PJMEDIA stand-alone RTP'], + ['HAS_PJMEDIA_RTCP', 'PJMEDIA stand-alone RTCP and media quality calculation'], + ['HAS_PJMEDIA_JBUF', 'PJMEDIA stand-alone adaptive jitter buffer'], + ['HAS_PJMEDIA_STREAM', 'PJMEDIA stream for remote media communication (needs RTP, RTCP, and jitter buffer)'], + ['HAS_PJMEDIA_UDP_TRANSPORT','PJMEDIA UDP media transport'], + ['HAS_PJMEDIA_FILE_PLAYER', 'PJMEDIA WAV file player'], + ['HAS_PJMEDIA_FILE_CAPTURE', 'PJMEDIA WAV file writer'], + ['HAS_PJMEDIA_MEM_PLAYER', 'PJMEDIA fixed buffer player'], + ['HAS_PJMEDIA_MEM_CAPTURE', 'PJMEDIA fixed buffer writer'], + + # Subtotal + ['', 'Subtotal: Complete SIP and all PJMEDIA features (G.711 codec only)'], + + # Codecs + ['HAS_PJMEDIA_GSM_CODEC', 'PJMEDIA GSM codec (including PLC)'], + ['HAS_PJMEDIA_SPEEX_CODEC', 'PJMEDIA Speex codec (narrowband, wideband, ultra-wideband)'], + + # Total + ['', 'TOTAL: complete libraries (+all codecs)'], +] + +# Executable size report, tuple of: +# , , , , , +exe_size = [] + +# +# Write the report to text file +# +def print_text_report(filename): + output = open(filename, 'w') + + output.write('PJSIP and PJMEDIA footprint report\n') + output.write('Auto-generated by pjsip-apps/build/get-footprint.py\n') + output.write('\n') + + # Write Revision info. + f = os.popen('svn info | grep Revision') + output.write(f.readline()) + + output.write('Date: ') + output.write(time.asctime()) + output.write('\n') + output.write('\n') + + # Write individual module size + output.write('Footprint (in bytes):\n') + output.write(' .text .data .bss Module Description\n') + output.write('==========================================================\n') + + for i in range(1, len(exe_size)): + e = exe_size[i] + prev = exe_size[i-1] + + if e[1]<>'': + output.write(' ') + output.write( string.rjust(`string.atoi(e[2]) - string.atoi(prev[2])`, 8) ) + output.write( string.rjust(`string.atoi(e[3]) - string.atoi(prev[3])`, 8) ) + output.write( string.rjust(`string.atoi(e[4]) - string.atoi(prev[4])`, 8) ) + output.write(' ' + e[5] + '\n') + else: + output.write(' ------------------------\n') + output.write(' ') + output.write( string.rjust(e[2], 8) ) + output.write( string.rjust(e[3], 8) ) + output.write( string.rjust(e[4], 8) ) + output.write(' ' + e[5] + '\n') + output.write('\n') + + + # Done + output.close() + + +# +# Write the report to HTML file +# +def print_html_report(filename): + output = open(filename, 'w') + + # Get Revision info. + f = os.popen('svn info | grep Revision') + revision = f.readline() + + output.write('\n'); + output.write(' PJSIP and PJMEDIA footprint report (' + revision + ')\n') + output.write(' \n') + output.write('\n'); + output.write('\n'); + output.write('') + + output.write('

PJSIP and PJMEDIA footprint report (' + revision + ')

\n') + output.write('Auto-generated by pjsip-apps/build/get-footprint.py\n') + output.write('

Date: ' + time.asctime() + '
\n') + output.write(revision + '

\n\n') + output.write('
\n') + output.write('\n') + + # Info + output.write('

Build Configuration

\n') + + # build.mak + output.write('\n

build.mak

\n') + output.write('\n') + f = open('../../build.mak', 'r') + s = f.readlines() + for l in s: + output.write(l + '
\n') + output.write('
\n') + + # user.mak + output.write('\n

user.mak

\n') + output.write('\n') + f = open('../../user.mak', 'r') + s = f.readlines() + for l in s: + output.write(l + '
\n') + output.write('
\n') + + # config_site.h + output.write('\n

<pj/config.site.h>

\n') + output.write('\n') + f = os.popen('cpp -dM ../../pjlib/include/pj/config_site.h | grep PJ') + s = f.readlines() + for l in s: + output.write(l + '
\n') + output.write('
\n') + + + + # Write individual module size + output.write('

Footprint Report

\n') + output.write('

The table below shows the footprint of individual feature, in bytes.

') + output.write('\n' + + '\n' + + ' \n' + + ' \n' + + ' \n' + + ' \n' + + '\n') + + + for i in range(1, len(exe_size)): + e = exe_size[i] + prev = exe_size[i-1] + + output.write('\n') + if e[1]<>'': + output.write( ' \n') + output.write( ' \n') + output.write( ' \n' ) + output.write( ' \n') + else: + output.write('\n') + output.write( ' \n') + output.write( ' \n') + output.write( ' \n') + output.write( ' \n') + + output.write('\n') + + output.write('
.text.data.bssFeatures/Module Description
' + `string.atoi(e[2]) - string.atoi(prev[2])` + '' + `string.atoi(e[3]) - string.atoi(prev[3])` + '' + `string.atoi(e[4]) - string.atoi(prev[4])` + '' + e[5] + '
   ' + e[5] + ': .text=' + e[2]+ ', .data=' + e[3] + ', .bss=' + e[4] + '
\n') + output.write('') + output.write('\n') + output.write('\n') + + # Done + output.close() + + + + +# +# Get the size of individual feature +# +def get_size(all_flags, flags, desc): + file = 'footprint.exe' + # Remove file + rc = os.system("make -f Footprint.mak FCFLAGS='" + all_flags + "' clean") + # Make the executable + cmd = "make -f Footprint.mak FCFLAGS='" + all_flags + "' all" + #print cmd + rc = os.system(cmd) + if rc <> 0: + sys.exit(1) + + # Run 'size' against the executable + f = os.popen('size ' + file) + # Skip header of the 'size' output + f.readline() + # Get the sizes + size = f.readline() + f.close() + # Split into tokens + tokens = size.split() + # Build the size tuple and add to exe_size + elem = all_flags, flags, tokens[0], tokens[1], tokens[2], desc + exe_size.append(elem) + # Remove file + rc = os.system("make -f Footprint.mak FCFLAGS='" + all_flags + "' clean") + +# Main +elem = '', '', '0', '0', '0', '' +exe_size.append(elem) + +all_flags = '' +for elem in compile_flags: + if elem[0] <> '': + flags = '-D' + elem[0] + all_flags += flags + ' ' + get_size(all_flags, elem[0], elem[1]) + else: + e = exe_size[len(exe_size)-1] + n = all_flags, '', e[2], e[3], e[4], elem[1] + exe_size.append(n) + + +print_text_report('footprint.txt') +print_html_report('footprint.htm') + -- cgit v1.2.3