jamesa/build_graph.py
author James Aley <jamesa@symbian.org>
Wed, 04 Nov 2009 17:40:17 +0000
changeset 5 842a773e65f2
permissions -rw-r--r--
Adding some dependency analysis scripts
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
5
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
     1
# Copyright (c) 2009 Symbian Foundation Ltd
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
     2
# This component and the accompanying materials are made available
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
     3
# under the terms of the License "Eclipse Public License v1.0"
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
     4
# which accompanies this distribution, and is available
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
     5
# at the URL "http://www.eclipse.org/legal/epl-v10.html".
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
     6
#
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
     7
# Initial Contributors:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
     8
# Symbian Foundation Ltd - initial contribution.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
     9
# 
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    10
# Contributors:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    11
#
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    12
# Description:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    13
# Generates a dependency graph of the Symbian source tree.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    14
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    15
"""Build a graph of component dependencies from Symbian OS source code.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    16
The graph is serialized to a file, which can then be used by other scripts to extract data.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    17
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    18
The script works by recursing over the directory structure from the specified root and then
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    19
analyzing all bld.inf files to locate referenced production MMP files. These are then processed
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    20
for target and dependency information.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    21
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    22
You can use the supplementary scripts to then extract useful information from the generated graph
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    23
file.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    24
"""
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    25
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    26
from optparse import OptionParser
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    27
from _common import Node
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    28
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    29
import re
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    30
import os
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    31
import sys
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    32
import pickle
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    33
import logging
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    34
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    35
__author__ = 'James Aley'
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    36
__email__ = 'jamesa@symbian.org'
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    37
__version__ = '1.0'
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    38
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    39
# Constants for various default config
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    40
_LOG_FORMAT = '%(levelname)s: %(message)s'
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    41
_MAX_PATH = 260
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    42
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    43
# Precompile regexes for better performance
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    44
# - Comment filtering
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    45
_RE_CLEAN_INLINE = '^(.*)//.*$'
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    46
_RE_MULTILINE_OPEN = '^(.*)/\\*.*$'
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    47
_RE_MULTILINE_CLOSE = '^.*\\*/(.*)$'
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    48
_p_clean_inline = re.compile(_RE_CLEAN_INLINE)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    49
_p_multiline_open = re.compile(_RE_MULTILINE_OPEN)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    50
_p_multiline_close = re.compile(_RE_MULTILINE_CLOSE)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    51
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    52
# - MMP file Parsing
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    53
_RE_TARGET = '^\\s*TARGET\\s+([^\\s]+).*$'
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    54
_RE_PLAIN_TARGET = '^\\s*([^\\s\\.]+)\\.?[^\\s]?\\s*'
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    55
_RE_COMPLEX_TARGET = '.*\\((.+),.+\\).*'
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    56
_RE_LIBRARY = '^\\s*[^\\s]*LIBRARY.*\\s+([^\\s]+.*)$'
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    57
_RE_START = '^\\s*START.*$'
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    58
_RE_END = '\\s*END.*$'
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    59
_p_target = re.compile(_RE_TARGET, re.I)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    60
_p_plain_target = re.compile(_RE_PLAIN_TARGET)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    61
_p_complex_target = re.compile(_RE_COMPLEX_TARGET)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    62
_p_library = re.compile(_RE_LIBRARY, re.I)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    63
_p_start = re.compile(_RE_START)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    64
_p_end = re.compile(_RE_END)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    65
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    66
# - BLD.INF file parsing
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    67
_RE_PRJ_MMPFILES = '^\\s*PRJ_MMPFILES\\s*$'
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    68
_RE_OTHER_SECTION = '^\\s*PRJ_[a-z]+\\s*$'
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    69
_p_prj_mmpfiles = re.compile(_RE_PRJ_MMPFILES, re.I)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    70
_p_other_section = re.compile(_RE_OTHER_SECTION, re.I)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    71
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    72
# Set up a logging instance for output
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    73
logging.basicConfig(format=_LOG_FORMAT, level=logging.WARNING, stream=sys.stdout)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    74
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    75
# Cache dictionary to marry Nodes to eachother
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    76
node_cache = {}
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    77
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    78
# Dictionary representing the dependency graph.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    79
# Each key identifies the node in the graph, where the value is the node
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    80
# object itself including the arcs to other node_path keys that it requires.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    81
graph = {}
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    82
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    83
def rstrip(string, suffix):
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    84
    """Like Python's __str__.rstrip(chars), but it treats the chars as
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    85
    a contiguous string and only strips that complete ending.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    86
    """
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    87
    if string.endswith(suffix):
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    88
        string = string[:len(string) - len(suffix)]
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    89
    return string
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    90
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    91
def clean_binary_name(binary_name):
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    92
    """Strips the extension off of binary names so that references to .lib
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    93
    are associated with the correct binaries.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    94
    """
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    95
    match_complex_target = _p_complex_target.match(binary_name)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    96
    if match_complex_target:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    97
        binary_name = match_complex_target.groups()[0].lower().strip()
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    98
    else:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
    99
        match_plain_target = _p_plain_target.match(binary_name)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   100
        if match_plain_target:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   101
            binary_name = match_plain_target.groups()[0].lower().strip()
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   102
    return binary_name
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   103
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   104
def looks_like_test(path):
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   105
    """Returns true if a path looks like it refers to test components.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   106
    The script does its best to filter test components, as many are missing
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   107
    from the source tree and they're not interesting with respect to building
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   108
    production ROM images anyway.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   109
    """
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   110
    conventions = ['tsrc', 'test']
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   111
    for convention in conventions:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   112
        # Iterate through likely test component conventions, if
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   113
        # we match one, return True now
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   114
        if os.path.sep + convention + os.path.sep in path.lower():
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   115
            return True
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   116
    # Otherwise, nothing found, so return False
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   117
    return False
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   118
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   119
def without_comments(source_file):
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   120
    """Generator function, will yield lines of the source_file object (iterable)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   121
    with commented regions removed.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   122
    """
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   123
    multiline_region = False
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   124
    for line in source_file:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   125
        match_multiline_close = _p_multiline_close.match(line)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   126
        if match_multiline_close:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   127
            # Close Comments, strip to the left of the comment
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   128
            multiline_region = False
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   129
            line = match_multiline_close.groups()[0]
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   130
        if multiline_region:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   131
            # Skip the line if we're in a commented region
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   132
            continue
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   133
        match_multiline_open = _p_multiline_open.match(line)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   134
        if match_multiline_open:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   135
            # Open comments, strip to the right of the comment
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   136
            multiline_region = True
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   137
            line = match_multiline_open.groups()[0]
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   138
        match_inline = _p_clean_inline.match(line)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   139
        if match_inline:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   140
            # Strip the line to only the left of the comment
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   141
            line = match_inline.groups()[0]
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   142
        if line:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   143
            yield line
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   144
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   145
def parse_mmp(mmp_path):
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   146
    """Read an mmp file, return a tuple of the form:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   147
        (target, required_target_list)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   148
    """
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   149
    logging.debug('parse_mmp(%s)' % (mmp_path, ))
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   150
    
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   151
    mmp_file = None
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   152
    try:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   153
        mmp_file = open(mmp_path)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   154
    except IOError, e:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   155
        logging.error('Unable to open: %s' % (mmp_path, ))
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   156
        return
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   157
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   158
    # Iterate through MMP file lines to find the TARGET and LIBRARY statements
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   159
    # Note that Symbian projects can compile to different TARGET objects depending on
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   160
    # precompiler macros, so we must index all possible target names.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   161
    targets = []
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   162
    libs = []
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   163
    resource_block = False
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   164
    for line in without_comments(mmp_file):
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   165
        match_start = _p_start.match(line)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   166
        if match_start:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   167
            resource_block = True
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   168
        match_end = _p_end.match(line)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   169
        if match_end:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   170
            resource_block = False
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   171
        if resource_block:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   172
            # need to avoid resource target sections
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   173
            continue
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   174
        match_target = _p_target.match(line)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   175
        match_library = _p_library.match(line)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   176
        if match_target:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   177
            clean_target = clean_binary_name(match_target.groups()[0])
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   178
            targets.append(clean_target)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   179
        elif match_library:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   180
            libs_on_line = match_library.groups()[0].split()
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   181
            for lib in libs_on_line:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   182
                clean_lib = clean_binary_name(lib)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   183
                libs.append(clean_lib)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   184
    mmp_file.close()
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   185
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   186
    return (targets, libs)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   187
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   188
def new_node(path, ref_mmps, ref_testmmps):
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   189
    """Construct a new node in the graph with the provided content.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   190
    """
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   191
    logging.debug('new_node(%s, ref_mmps(%d), ref_testmmps(%d))' % (path, len(ref_mmps), len(ref_testmmps)))
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   192
    node = Node(path)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   193
    
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   194
    # Iterate the MMPs, read dependency and target information
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   195
    for mmp in ref_mmps:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   196
        (targets, dependencies) = parse_mmp(mmp)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   197
        if len(targets) > 0:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   198
            for target in targets:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   199
                node.mmp_components.append(target)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   200
            node.add_deps(dependencies)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   201
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   202
    # Register the components in the cache, as later we will
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   203
    # join the graph nodes by referring to this cache
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   204
    for c in node.mmp_components:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   205
        if c in node_cache.keys():
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   206
            existing = node_cache[c]
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   207
            node_cache[c] = existing + [path]
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   208
        else:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   209
            node_cache[c] = [path]
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   210
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   211
    # Add this node to the graph
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   212
    graph[path] = node
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   213
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   214
def parse_bld_inf(path):
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   215
    """Parse a bld.inf file to check to see if references MMP files.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   216
    For those MMP files included, parse them to build the node object.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   217
    """
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   218
    logging.debug('parse_bld_inf(%s)' % (path, ))
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   219
    
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   220
    # List the files referenced from this bld.inf
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   221
    ref_mmp = []
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   222
    ref_testmmp = []
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   223
    
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   224
    bld_inf = None
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   225
    try:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   226
        bld_inf = open(path, 'r')
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   227
    except IOError, e:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   228
        logging.error('Unable to open: %s' % (path, ))
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   229
        return
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   230
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   231
    # Parse the bld_inf file, adding references MMP files to appropriate lists
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   232
    projects_flag = False
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   233
    for line in without_comments(bld_inf):
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   234
        match_projects = _p_prj_mmpfiles.match(line)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   235
        match_other_section = _p_other_section.match(line)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   236
        if match_projects:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   237
            projects_flag = True
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   238
        elif match_other_section:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   239
            projects_flag = False
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   240
        if projects_flag and len(line) <= _MAX_PATH:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   241
            rel_name = rstrip(line.lower().strip(), '.mmp')
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   242
            bld_inf_path = os.path.dirname(path)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   243
            test_path = os.path.join(bld_inf_path, rel_name + '.mmp')
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   244
            test_path = os.path.realpath(test_path)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   245
            if os.path.exists(test_path):
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   246
                ref_mmp.append(test_path)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   247
            else:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   248
                logging.warning('%s refers to %s but it does not exist!' % (path, test_path))
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   249
    bld_inf.close()
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   250
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   251
    # If we found some MMP files, then this is a new node
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   252
    if len(ref_mmp) > 0:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   253
        new_node(path, ref_mmp, ref_testmmp)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   254
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   255
def make_nodes(not_used, dir_name, file_names):
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   256
    """Call back function for os.path.walk: will analyse the file names, if
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   257
    there are any bld.inf files, it will open them to see if they identify a
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   258
    Node object and create them as appropriate
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   259
    """
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   260
    logging.debug('make_nodes(%s, %s)' % (dir_name, file_names))
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   261
    if looks_like_test(dir_name):
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   262
        return
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   263
    for file_name in file_names:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   264
        if file_name.lower().endswith('.inf'):
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   265
            abs_path = os.path.join(dir_name, file_name)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   266
            assert(os.path.exists(abs_path))
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   267
            parse_bld_inf(abs_path)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   268
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   269
def connect_nodes():
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   270
    """Walk through the graph and substute the contents of the dependency
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   271
    list members at each node with references to the node_path of that which
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   272
    builds the referenced component.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   273
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   274
    There will be instances where multiple graph nodes build overlapping
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   275
    components. This will, in practice, mean that there are many ways of
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   276
    building a suitable ROM for dependencies of one of these nodes.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   277
    """
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   278
    unresolved_deps = []
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   279
    for node_path in graph.keys():
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   280
        node = graph[node_path]
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   281
        resolved = []
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   282
        for dep in node.dependencies:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   283
            if dep not in node_cache.keys():
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   284
                logging.warning('Could not resolve %s for %s' % (dep, node.node_path))
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   285
                if dep not in unresolved_deps:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   286
                    unresolved_deps.append(dep)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   287
                node.unresolved.append(dep)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   288
            else:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   289
                solutions = node_cache[dep]
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   290
                proposed = solutions[0]
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   291
                if proposed not in resolved:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   292
                    resolved.append(proposed)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   293
                node.interesting += filter(lambda x: x not in node.interesting, solutions[1:])
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   294
        node.dependencies = resolved
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   295
        graph[node_path] = node
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   296
    if len(unresolved_deps) > 0:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   297
        logging.warning('There were %d unresolved dependencies.' % (len(unresolved_deps), ))
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   298
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   299
def build_graph(root):
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   300
    """Walk nodes from the directory root provided looking for bld.inf files.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   301
    Graph will be built from the referened production MMP files.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   302
    """
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   303
    if not os.path.isdir(root):
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   304
        logging.fatal('%s is not a directory, aborting...' % (root, ))
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   305
        exit(1)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   306
    os.path.walk(root, make_nodes, None)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   307
    connect_nodes()
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   308
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   309
def save_graph(path):
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   310
    """Serialize the graph object to path. This will be a Python object pickle at
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   311
    the highest available protocol version for this Python install.
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   312
    """
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   313
    graph_file = None
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   314
    try:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   315
        graph_file = open(path, 'wb')
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   316
    except IOError, e:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   317
        logging.error('Could not write graph to file: %s' % (repr(e), ))
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   318
        exit(1)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   319
    pickle.dump(graph, graph_file, pickle.HIGHEST_PROTOCOL)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   320
    graph_file.close()
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   321
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   322
# Main:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   323
if __name__ == '__main__':
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   324
    parser = OptionParser()
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   325
    parser.set_description(__doc__)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   326
    parser.add_option('-g', '--graph', dest='graph_file', 
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   327
                      help='File name to write the graph to.', 
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   328
                      metavar='GRAPH_FILE', default='dependencies.graph')
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   329
    parser.add_option('-r', '--root', dest='graph_root',
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   330
                      help='Directory to recursively build a graph from, usually root of source tree.',
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   331
                      metavar='SOURCE_ROOT', default='.')
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   332
    parser.add_option('-v', '--verbose', dest='verbose',
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   333
                      help='Verbose logging, will show all warnings as graph is generated. Recommend redirect!',
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   334
                      action='store_true', default=False)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   335
    (options, args) = parser.parse_args()
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   336
    if not options.verbose:
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   337
        logging.disable(logging.ERROR)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   338
    print 'Walking source from "%s"\nThis can take some time with large source trees...' % (options.graph_root, )
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   339
    build_graph(options.graph_root)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   340
    print 'Found %d components consisting of %d binaries.' % (len(graph), len(node_cache))
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   341
    print 'Wriing graph to %s' % (options.graph_file)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   342
    save_graph(options.graph_file)
842a773e65f2 Adding some dependency analysis scripts
James Aley <jamesa@symbian.org>
parents:
diff changeset
   343
    print '...done!'