root/branches/Carsten_PtrWork2/Tools/scons-build/BuildInfoScanner.py

Revision 563, 7.0 kB (checked in by cneumann, 2 years ago)

changed: moved some utility code to separate files.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1
2 import os
3 import os.path
4 import sys
5
6 import SConsAddons.Util as sca_util
7 from LibraryUtils import *
8
9 pj = os.path.join
10
11 class BuildInfoScanner(object):
12     """
13     Recursively scans a directory tree for build.info files and constructs
14     a list of libraries and their dependencies from their contents.
15     
16     - Finding build.info files:
17         Every file found can override the settings inherited from parent
18         directories.
19         - Keep a stack of library names, we add to the top library.
20         - All subdirectories of the baseDir are scanned, unless it is in
21         ignoredDirs.
22         - File names are relative to baseDir
23     
24     - Evaluating a build.info file:
25         Input variables:
26         - option_pass: If True, we only collect options.
27         - opts:        Either None or an Options object to add options to.
28         - platform:    The current plarform string.
29         - compiler:    The current compiler being used.
30         Output variables:
31         - library: Name of the library to which the current directory belongs.
32         - stop_traversal: If True, ignore this directory and everything below it.
33     
34         - osg_dep_libs: List of OpenSG library names, this library depends upon (for linking).
35         - libs: List of external library names, this library depends upon.
36         - frameworks: List of framework names, this library depends upon.
37         - cpppath: Additional include paths for building.
38         - libpath: Additional library paths for linking.
39         - frameworkpath: Additional framework paths to set.
40     
41         - osg_test_libs: List of OpenSG library names, this library depends
42                         upon for builing tests.
43         - other_test_libs: List of external library names, this library depends
44                             upon for building tests.
45         - test_cpppath: Additional include paths for building tests.
46         - test_libpath: Additional library paths for linking tests.
47     """
48
49     def __init__(self, baseDir, opts, env, ignoredDirs = None, verbose = False):
50         self.baseDir       = baseDir
51         self.ignoredDirs   = ignoredDirs
52         self.opts          = opts
53         self.env           = env
54         self.platform      = sca_util.GetPlatform();
55         self.verbose       = verbose
56        
57         self.libMap        = {}
58         self.libNameStack  = []
59         self.libAttributes = ["osg_dep_libs", "libs", "frameworks", "cpppath",
60                               "libpath", "frameworkpath","osg_test_libs",
61                               "other_test_libs","test_cpppath", "test_libpath"]
62    
63     def scan(self, scanDir = ""):
64         """Scan for build.info files in baseDir/scanDir keeping all file paths
65            relative to baseDir.
66            Returns the library map constructed from the files.
67         """
68         self._recursiveScan(scanDir)
69         return self.libMap
70
71     def _recursiveScan(self, scanDir = ""):
72         """The actual recursive scanning routine.
73         """
74         fullDir = pj(self.baseDir, scanDir)
75         scanDirContents = [pj(scanDir, f) for f in os.listdir(fullDir)]
76         files = [f for f in scanDirContents if os.path.isfile(pj(self.baseDir, f))]
77         dirs  = [d for d in scanDirContents if os.path.isdir(pj(self.baseDir, d))]
78        
79         hasBuildInfo = os.path.exists(pj(fullDir, "build.info"))
80        
81         if hasBuildInfo:
82             biFilename = pj(fullDir, "build.info")
83            
84             if self.verbose:
85                 print "    Reading: ", biFilename
86             else:
87                 sys.stdout.write(".")
88            
89             biDict = dict([("option_pass",    False),
90                            ("opts",           self.opts),
91                            ("platform",       self.platform),
92                            ("compiler",       self.env["CXX"]),
93                            ("stop_traversal", False)])
94            
95             for attrib in self.libAttributes:
96                 biDict[attrib] = []
97            
98             execfile(biFilename, biDict)
99            
100             if biDict["stop_traversal"]:
101                 if self.verbose:
102                     print "    Pruning traversal."
103                 return False
104            
105             if not biDict.has_key("library") or biDict["library"] == None:
106                 print "ERROR: No 'library' specified in build.info file: ", biFilename
107                 sys.exit(1)
108            
109             libName = biDict["library"]
110             if not self.libMap.has_key(libName):
111                 self.libMap[libName] = LibraryInfo(name = libName)
112                 if self.verbose:
113                     print "Created new LibraryInfo: ", libName
114            
115             self.libNameStack.append(libName)
116            
117             if self.verbose:
118                 print "Library name: ", libName
119            
120             # Add all the lib options from the evaluation
121             # - Only add on the unique ones
122             for attrib in self.libAttributes:
123                 attribList = getattr(self.libMap[libName], attrib)
124                 attribList.extend([a for a in biDict[attrib] if a not in attribList])
125        
126         # Collect source files from all directories and put them into
127         # the active library object
128         testFiles     = [f for f in files if (os.path.basename(f).startswith("test") and
129                                               os.path.splitext(f)[1] in [".cpp",".cc",".mm"])];
130         unittestFiles = [f for f in files if (os.path.basename(f).endswith("Test.cpp") and
131                                               os.path.basename(f).startswith("OSG"))]
132         sourceFiles   = [f for f in files if (os.path.splitext(f)[1] in [".cpp", ".cc", ".mm"] and
133                                               os.path.basename(f).startswith("OSG") and
134                                               f not in testFiles and f not in unittestFiles)]
135         headerFiles   = [f for f in files if (os.path.splitext(f)[1] in [".h", ".inl", ".ins", ".hpp"] and
136                                               os.path.basename(f).startswith("OSG"))]
137        
138         # Add files to their library object
139         if (len(testFiles) or len(unittestFiles) or
140             len(sourceFiles) or len(headerFiles)):
141             if len(self.libNameStack) == 0 or self.libNameStack[-1] == "":
142                 print "ERROR: Attempt to add source files without library.  " + \
143                       "In dir: %s" % fullDir
144                 sys.exit(1)
145             libName = self.libNameStack[-1]
146             self.libMap[libName].source_files   += sourceFiles
147             self.libMap[libName].header_files   += headerFiles
148             self.libMap[libName].test_files     += testFiles
149             self.libMap[libName].unittest_files += unittestFiles
150        
151         # Recurse into subdirectories
152         for d in dirs:
153             if not os.path.basename(d) in self.ignoredDirs:
154                 popStack = self._recursiveScan(d)
155                 if popStack:
156                     del self.libNameStack[-1]
157        
158         # return if anything was added to the libNameStack
159         if hasBuildInfo:
160             return True
161         else:
162             return False
Note: See TracBrowser for help on using the browser.