Carsten Neumann wrote:
>       Hi,
> 
> Allen Bierbaum wrote:
>> Gerrit Voss wrote:
>>> For example some of the stuff in SConstruct (roughly up to line 500)
>>> should be in scons-addons (from an OpenSG only perspective). So it is
>>> reusable for people who want to write their own applications.
>>>   
>> I agree there is a lot of utility code in there.  I am not sure if it 
>> all makes sense in scons-addons (some of it does), but the OpenSG part 
>> IMHO should actually be put into some utility libraries in 
>> OpenSG2/Tools/scons-build  where the LibraryUtils module currently is.  
> 
> I had a patch for this, but before I had a chance to convince myself
> that it completely works, there were changes to SConstruct that
> diff/patch were unable to merge in and simply concatenated both variants
> of the file :(
> Anyway, I'll recreate that patch ASAP.

here it is. I did not commit it, because it's not fully tested and I was
using cpu time for building NFIO stuff - which worked with this one applied.

Changelog:

* Tools/scons-build/BuildInfoScanner.py: new file.
* Tools/scons-build/RevisionTagWriter.py: new file.
* SConstruct: removed BuildInfoScanner and RevisionTagWriter code,
include and use the new files instead.

        Carsten
Index: Tools/scons-build/BuildInfoScanner.py
===================================================================
--- Tools/scons-build/BuildInfoScanner.py	(revision 0)
+++ Tools/scons-build/BuildInfoScanner.py	(revision 0)
@@ -0,0 +1,162 @@
+
+import os
+import os.path
+import sys
+
+import SConsAddons.Util as sca_util
+from LibraryUtils import *
+
+pj = os.path.join
+
+class BuildInfoScanner(object):
+    """
+    Recursively scans a directory tree for build.info files and constructs
+    a list of libraries and their dependencies from their contents.
+    
+    - Finding build.info files:
+        Every file found can override the settings inherited from parent
+        directories.
+        - Keep a stack of library names, we add to the top library.
+        - All subdirectories of the baseDir are scanned, unless it is in
+        ignoredDirs.
+        - File names are relative to baseDir
+    
+    - Evaluating a build.info file:
+        Input variables:
+        - option_pass: If True, we only collect options.
+        - opts:        Either None or an Options object to add options to.
+        - platform:    The current plarform string.
+        - compiler:    The current compiler being used.
+        Output variables:
+        - library: Name of the library to which the current directory belongs.
+        - stop_traversal: If True, ignore this directory and everything below it.
+    
+        - osg_dep_libs: List of OpenSG library names, this library depends upon (for linking).
+        - libs: List of external library names, this library depends upon.
+        - frameworks: List of framework names, this library depends upon.
+        - cpppath: Additional include paths for building.
+        - libpath: Additional library paths for linking.
+        - frameworkpath: Additional framework paths to set.
+    
+        - osg_test_libs: List of OpenSG library names, this library depends
+                        upon for builing tests.
+        - other_test_libs: List of external library names, this library depends
+                            upon for building tests.
+        - test_cpppath: Additional include paths for building tests.
+        - test_libpath: Additional library paths for linking tests.
+    """
+
+    def __init__(self, baseDir, opts, env, ignoredDirs = None, verbose = False):
+        self.baseDir       = baseDir
+        self.ignoredDirs   = ignoredDirs
+        self.opts          = opts
+        self.env           = env
+        self.platform      = sca_util.GetPlatform();
+        self.verbose       = verbose
+        
+        self.libMap        = {}
+        self.libNameStack  = []
+        self.libAttributes = ["osg_dep_libs", "libs", "frameworks", "cpppath",
+                              "libpath", "frameworkpath","osg_test_libs",
+                              "other_test_libs","test_cpppath", "test_libpath"]
+    
+    def scan(self, scanDir = ""):
+        """Scan for build.info files in baseDir/scanDir keeping all file paths
+           relative to baseDir.
+           Returns the library map constructed from the files.
+        """
+        self._recursiveScan(scanDir)
+        return self.libMap
+
+    def _recursiveScan(self, scanDir = ""):
+        """The actual recursive scanning routine.
+        """
+        fullDir = pj(self.baseDir, scanDir)
+        scanDirContents = [pj(scanDir, f) for f in os.listdir(fullDir)]
+        files = [f for f in scanDirContents if os.path.isfile(pj(self.baseDir, f))]
+        dirs  = [d for d in scanDirContents if os.path.isdir(pj(self.baseDir, d))]
+        
+        hasBuildInfo = os.path.exists(pj(fullDir, "build.info"))
+        
+        if hasBuildInfo:
+            biFilename = pj(fullDir, "build.info")
+            
+            if self.verbose:
+                print "    Reading: ", biFilename
+            else:
+                sys.stdout.write(".")
+            
+            biDict = dict([("option_pass",    False),
+                           ("opts",           self.opts),
+                           ("platform",       self.platform),
+                           ("compiler",       self.env["CXX"]),
+                           ("stop_traversal", False)])
+            
+            for attrib in self.libAttributes:
+                biDict[attrib] = []
+            
+            execfile(biFilename, biDict)
+            
+            if biDict["stop_traversal"]:
+                if self.verbose:
+                    print "    Pruning traversal."
+                return False
+            
+            if not biDict.has_key("library") or biDict["library"] == None:
+                print "ERROR: No 'library' specified in build.info file: ", biFilename
+                sys.exit(1)
+            
+            libName = biDict["library"]
+            if not self.libMap.has_key(libName):
+                self.libMap[libName] = LibraryInfo(name = libName)
+                if self.verbose:
+                    print "Created new LibraryInfo: ", libName
+            
+            self.libNameStack.append(libName)
+            
+            if self.verbose:
+                print "Library name: ", libName
+            
+            # Add all the lib options from the evaluation
+            # - Only add on the unique ones
+            for attrib in self.libAttributes:
+                attribList = getattr(self.libMap[libName], attrib)
+                attribList.extend([a for a in biDict[attrib] if a not in attribList])
+        
+        # Collect source files from all directories and put them into
+        # the active library object
+        testFiles     = [f for f in files if (os.path.basename(f).startswith("test") and
+                                              os.path.splitext(f)[1] in [".cpp",".cc",".mm"])];
+        unittestFiles = [f for f in files if (os.path.basename(f).endswith("Test.cpp") and
+                                              os.path.basename(f).startswith("OSG"))]
+        sourceFiles   = [f for f in files if (os.path.splitext(f)[1] in [".cpp", ".cc", ".mm"] and
+                                              os.path.basename(f).startswith("OSG") and
+                                              f not in testFiles and f not in unittestFiles)]
+        headerFiles   = [f for f in files if (os.path.splitext(f)[1] in [".h", ".inl", ".ins", ".hpp"] and
+                                              os.path.basename(f).startswith("OSG"))]
+        
+        # Add files to their library object
+        if (len(testFiles) or len(unittestFiles) or
+            len(sourceFiles) or len(headerFiles)):
+            if len(self.libNameStack) == 0 or self.libNameStack[-1] == "":
+                print "ERROR: Attempt to add source files without library.  " + \
+                      "In dir: %s" % fullDir
+                sys.exit(1)
+            libName = self.libNameStack[-1]
+            self.libMap[libName].source_files   += sourceFiles
+            self.libMap[libName].header_files   += headerFiles
+            self.libMap[libName].test_files     += testFiles
+            self.libMap[libName].unittest_files += unittestFiles
+        
+        # Recurse into subdirectories
+        for d in dirs:
+            if not os.path.basename(d) in self.ignoredDirs:
+                popStack = self._recursiveScan(d)
+                if popStack:
+                    del self.libNameStack[-1]
+        
+        # return if anything was added to the libNameStack
+        if hasBuildInfo:
+            return True
+        else:
+            return False

Property changes on: Tools/scons-build/BuildInfoScanner.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Index: Tools/scons-build/RevisionTagWriter.py
===================================================================
--- Tools/scons-build/RevisionTagWriter.py	(revision 0)
+++ Tools/scons-build/RevisionTagWriter.py	(revision 0)
@@ -0,0 +1,112 @@
+
+import os;
+import os.path;
+
+pj = os.path.join;
+
+# If we have pysvn, load it
+try:
+    import pysvn
+    have_pysvn = True
+except:
+    have_pysvn = False
+
+
+class RevisionTagWriter(object):
+    """
+    For each library the corresponding <Libname>Def.cpp file is located and
+    the highest revision number of any of the lib's source files is recorded
+    together with a marker if the lib contains local changes.
+    """
+    def __init__(self, libMap):
+        """
+        Create a new tag writer that uses the libraries from the given libMap.
+        Also checks if pysvn is available - without it tagging is not possible.
+        """
+        if not have_pysvn:
+            raise "The module pysvn is required to perform revision tagging!"
+        
+        self.libMap        = libMap
+        self.maxRev        = 0
+        self.svnClient     = pysvn.Client()
+        self.versionString = open("VERSION").readline().strip()
+    
+    def run(self):
+        """
+        Write revision tags.
+        """
+        for (libName, libObj) in self.libMap.iteritems():
+            libMaxRev   = 0
+            modifiedStr = ""
+            
+            for file in libObj.source_files + libObj.header_files:
+                filename = pj("Source", file)
+                
+                fileRev, fileModified = self._getSVNInfo(filename)
+                
+                if libMaxRev < fileRev:
+                    libMaxRev = fileRev
+                
+                # we modify the <libname>Def.cpp files ourselves
+                if fileModified and filename[-7:] != "Def.cpp":
+                    print "%s: file %s is modified!" % (libName, filename)
+                    modifiedStr = " !MODIFIED!"
+            
+            if modifiedStr != "":
+                print "%s: There are modified files, revision might be inaccurate!" % libName
+            print "%s: Highest revision: %d." % (libName, libMaxRev)
+            
+            if self.maxRev < libMaxRev:
+                self.maxRev = libMaxRev
+            
+            for file in libObj.source_files:
+                if file[-7:] == "Def.cpp":
+                    filename = pj("Source", file)
+                    fileInfo = self.svnClient.info(filename)
+                    repoPath = fileInfo.url[len(fileInfo.repos):-len(filename)-1]
+                    
+                    fileContents = open(filename).readlines()
+                    for i in range(len(fileContents)):
+                        if fileContents[i][:22] == '#define SVN_REVISION "':
+                            fileContents[i] = '#define SVN_REVISION "%d  (%s)%s"\n' % (libMaxRev, repoPath, modifiedStr)
+                            break
+                    open(filename, "w").writelines(fileContents)
+        
+        # Update the documentation mainfile
+        # Find the high version for stuff in Doc/, too
+        modifiedStr = ""
+        for file in glob.glob("Doc/*"):
+            print file
+            fileRev, fileMod = self._getSVNInfo(file)
+            
+            if self.maxRev < fileRev:
+                self.maxRev = fileRev
+            if fileMod:
+                modifiedStr = " !Modified!"
+        
+        filename     = "Doc/mainpage.dox"
+        fileContents = open(filename).readlines()
+        for i in range(len(fileContents)):
+            if fileContents[i][:7] == 'version':
+                fileContents[i] = 'version %s r%d %s\n' % (self.versionString, self.maxRev, modifiedStr)
+                break
+        open(filename,'w').writelines(fileContents)
+
+    def _getSVNInfo(self, filename):
+        """
+           Get the svn info for the given file.
+           Returns a version, modified tuple.
+        """
+        fileInfo   = self.svnClient.info  (filename)
+        fileStatus = self.svnClient.status(filename)
+        
+        fileRev = 0
+        fileMod = False
+        
+        # Ignore unversioned files
+        if pysvn.wc_status_kind.unversioned != fileStatus[0].text_status and \
+           pysvn.wc_status_kind.ignored     != fileStatus[0].text_status:
+            fileRev = fileInfo.revision.number
+            fileMod = pysvn.wc_status_kind.modified == fileStatus[0].text_status
+
+        return fileRev, fileMod

Property changes on: Tools/scons-build/RevisionTagWriter.py
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native

Index: SConstruct
===================================================================
--- SConstruct	(revision 546)
+++ SConstruct	(working copy)
@@ -40,6 +40,9 @@
 from LibraryUtils import *
 from sets import Set
 
+from BuildInfoScanner import BuildInfoScanner
+from RevisionTagWriter import RevisionTagWriter
+
 # If we have pysvn, load it
 try:
    import pysvn
@@ -235,263 +238,6 @@
          for i in self.value.split(os.pathsep):
             exec("env.Append(%s = [i])" % self.key)
 
-# -------------------------------- #
-# --- build.info file handling --- #
-# -------------------------------- #
-
-class BuildInfoScanner(object):
-    """
-    Recursively scans a directory tree for build.info files and constructs
-    a list of libraries and their dependencies from their contents.
-    
-    - Finding build.info files:
-        Every file found can override the settings inherited from parent
-        directories.
-        - Keep a stack of library names, we add to the top library.
-        - All subdirectories of the baseDir are scanned, unless it is in
-        ignoredDirs.
-        - File names are relative to baseDir
-    
-    - Evaluating a build.info file:
-        Input variables:
-        - option_pass: If True, we only collect options.
-        - opts:        Either None or an Options object to add options to.
-        - platform:    The current plarform string.
-        - compiler:    The current compiler being used.
-        Output variables:
-        - library: Name of the library to which the current directory belongs.
-        - stop_traversal: If True, ignore this directory and everything below it.
-    
-        - osg_dep_libs: List of OpenSG library names, this library depends upon (for linking).
-        - libs: List of external library names, this library depends upon.
-        - frameworks: List of framework names, this library depends upon.
-        - cpppath: Additional include paths for building.
-        - libpath: Additional library paths for linking.
-        - frameworkpath: Additional framework paths to set.
-    
-        - osg_test_libs: List of OpenSG library names, this library depends
-                        upon for builing tests.
-        - other_test_libs: List of external library names, this library depends
-                            upon for building tests.
-        - test_cpppath: Additional include paths for building tests.
-        - test_libpath: Additional library paths for linking tests.
-    """
-
-    def __init__(self, baseDir, ignoredDirs = None, verbose = False):
-        self.baseDir       = baseDir
-        self.ignoredDirs   = ignoredDirs
-        self.verbose       = verbose
-        
-        self.libMap        = {}
-        self.libNameStack  = []
-        self.libAttributes = ["osg_dep_libs", "libs", "frameworks", "cpppath",
-                              "libpath", "frameworkpath","osg_test_libs",
-                              "other_test_libs","test_cpppath", "test_libpath"]
-    
-    def scan(self, scanDir = ""):
-        """Scan for build.info files in baseDir/scanDir keeping all file paths
-           relative to baseDir.
-           Returns the library map constructed from the files.
-        """
-        self._recursiveScan(scanDir)
-        return self.libMap
-
-    def _recursiveScan(self, scanDir = ""):
-        """The actual recursive scanning routine.
-        """
-        fullDir = pj(self.baseDir, scanDir)
-        scanDirContents = [pj(scanDir, f) for f in os.listdir(fullDir)]
-        files = [f for f in scanDirContents if os.path.isfile(pj(self.baseDir, f))]
-        dirs  = [d for d in scanDirContents if os.path.isdir(pj(self.baseDir, d))]
-        
-        hasBuildInfo = os.path.exists(pj(fullDir, "build.info"))
-        
-        if hasBuildInfo:
-            biFilename = pj(fullDir, "build.info")
-            
-            if self.verbose:
-                print "    Reading: ", biFilename
-            else:
-                sys.stdout.write(".")
-            
-            biDict = dict([("option_pass",    False),
-                           ("opts",           opts),
-                           ("platform",       platform),
-                           ("compiler",       common_env["CXX"]),
-                           ("stop_traversal", False)])
-            
-            for attrib in self.libAttributes:
-                biDict[attrib] = []
-            
-            execfile(biFilename, biDict)
-            
-            if biDict["stop_traversal"]:
-                if self.verbose:
-                    print "    Pruning traversal."
-                return False
-            
-            if not biDict.has_key("library") or biDict["library"] == None:
-                print "ERROR: No 'library' specified in build.info file: ", biFilename
-                sys.exit(1)
-            
-            libName = biDict["library"]
-            if not self.libMap.has_key(libName):
-                self.libMap[libName] = LibraryInfo(name = libName)
-                if self.verbose:
-                    print "Created new LibraryInfo: ", libName
-            
-            self.libNameStack.append(libName)
-            
-            if self.verbose:
-                print "Library name: ", libName
-            
-            # Add all the lib options from the evaluation
-            # - Only add on the unique ones
-            for attrib in self.libAttributes:
-                attribList = getattr(self.libMap[libName], attrib)
-                attribList.extend([a for a in biDict[attrib] if a not in attribList])
-        
-        # Collect source files from all directories and put them into
-        # the active library object
-        testFiles     = [f for f in files if (os.path.basename(f).startswith("test") and
-                                              os.path.splitext(f)[1] in [".cpp",".cc",".mm"])];
-        unittestFiles = [f for f in files if (os.path.basename(f).endswith("Test.cpp") and
-                                              os.path.basename(f).startswith("OSG"))]
-        sourceFiles   = [f for f in files if (os.path.splitext(f)[1] in [".cpp", ".cc", ".mm"] and
-                                              os.path.basename(f).startswith("OSG") and
-                                              f not in testFiles and f not in unittestFiles)]
-        headerFiles   = [f for f in files if (os.path.splitext(f)[1] in [".h", ".inl", ".ins", ".hpp"] and
-                                              os.path.basename(f).startswith("OSG"))]
-        
-        # Add files to their library object
-        if (len(testFiles) or len(unittestFiles) or
-            len(sourceFiles) or len(headerFiles)):
-            if len(self.libNameStack) == 0 or self.libNameStack[-1] == "":
-                print "ERROR: Attempt to add source files without library.  " + \
-                      "In dir: %s" % fullDir
-                sys.exit(1)
-            libName = self.libNameStack[-1]
-            self.libMap[libName].source_files   += sourceFiles
-            self.libMap[libName].header_files   += headerFiles
-            self.libMap[libName].test_files     += testFiles
-            self.libMap[libName].unittest_files += unittestFiles
-        
-        # Recurse into subdirectories
-        for d in dirs:
-            if not os.path.basename(d) in self.ignoredDirs:
-                popStack = self._recursiveScan(d)
-                if popStack:
-                    del self.libNameStack[-1]
-        
-        # return if anything was added to the libNameStack
-        if hasBuildInfo:
-            return True
-        else:
-            return False
-
-# ----------------------------- #
-# --- revision tag handling --- #
-# ----------------------------- #
-
-class RevisionTagWriter(object):
-    """
-    For each library the corresponding <Libname>Def.cpp file is located and
-    the highest revision number of any of the lib's source files is recorded
-    together with a marker if the lib contains local changes.
-    """
-    def __init__(self, libMap):
-        """
-        Create a new tag writer that uses the libraries from the given libMap.
-        Also checks if pysvn is available - without it tagging is not possible.
-        """
-        if not have_pysvn:
-            raise "The module pysvn is require to perform revision tagging!"
-        
-        self.libMap = libMap
-        self.maxRev = 0
-        self.svnClient = pysvn.Client()
-    
-    def run(self):
-        """
-        Write revision tags.
-        """
-        for (libName, libObj) in self.libMap.iteritems():
-            libMaxRev   = 0
-            modifiedStr = ""
-            
-            for file in libObj.source_files + libObj.header_files:
-                filename = pj("Source", file)
-                
-                fileRev, fileModified = self._getSVNInfo(filename)
-                
-                if libMaxRev < fileRev:
-                    libMaxRev = fileRev
-                
-                # we modify the <libname>Def.cpp files ourselves
-                if fileModified and filename[-7:] != "Def.cpp":
-                    print "%s: file %s is modified!" % (libName, filename)
-                    modifiedStr = " !MODIFIED!"
-            
-            if modifiedStr != "":
-                print "%s: There are modified files, revision might be inaccurate!" % libName
-            print "%s: Highest revision: %d." % (libName, libMaxRev)
-            
-            if self.maxRev < libMaxRev:
-                self.maxRev = libMaxRev
-            
-            for file in libObj.source_files:
-                if file[-7:] == "Def.cpp":
-                    filename = pj("Source", file)
-                    fileInfo = self.svnClient.info(filename)
-                    repoPath = fileInfo.url[len(fileInfo.repos):-len(filename)-1]
-                    
-                    fileContents = open(filename).readlines()
-                    for i in range(len(fileContents)):
-                        if fileContents[i][:22] == '#define SVN_REVISION "':
-                            fileContents[i] = '#define SVN_REVISION "%d  (%s)%s"\n' % (libMaxRev, repoPath, modifiedStr)
-                            break
-                    open(filename, "w").writelines(fileContents)
-        
-        # Update the documentation mainfile
-        # Find the high version for stuff in Doc/, too
-        modifiedStr = ""
-        for file in glob.glob("Doc/*"):
-            print file
-            fileRev, fileMod = self._getSVNInfo(file)
-            
-            if self.maxRev < fileRev:
-                self.maxRev = fileRev
-            if fileMod:
-                modifiedStr = " !Modified!"
-        
-        filename     = "Doc/mainpage.dox"
-        fileContents = open(filename).readlines()
-        for i in range(len(fileContents)):
-            if fileContents[i][:7] == 'version':
-                fileContents[i] = 'version %s r%d %s\n' % (opensg_version_string, self.maxRev, modifiedStr)
-                break
-        open(filename,'w').writelines(fileContents)
-
-    def _getSVNInfo(self, filename):
-        """
-           Get the svn info for the given file.
-           Returns a version, modified tuple.
-        """
-        fileInfo   = self.svnClient.info  (filename)
-        fileStatus = self.svnClient.status(filename)
-        
-        fileRev = 0
-        fileMod = False
-        
-        # Ignore unversioned files
-        if pysvn.wc_status_kind.unversioned != fileStatus[0].text_status and \
-           pysvn.wc_status_kind.ignored     != fileStatus[0].text_status:
-            fileRev = fileInfo.revision.number
-            fileMod = pysvn.wc_status_kind.modified == fileStatus[0].text_status
-
-        return fileRev, fileMod
-
-
 # ---------------------------------------------------------------------------- #
 # ----------------------------- Main build setup ----------------------------- #
 # ---------------------------------------------------------------------------- #
@@ -839,7 +585,8 @@
    # Trigger recursive scanning of library directorties
    if not verbose_build:
       print "Scanning libraries: ",
-   biScanner = BuildInfoScanner("Source", [".svn", "ES", "EGL"], verbose_build)
+   biScanner = BuildInfoScanner("Source", opts, common_env, 
+                                [".svn", "ES", "EGL"], verbose_build)
    lib_map   = biScanner.scan()
    if not verbose_build:
       print "  found %s libraries" % len(lib_map)
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
Opensg-core mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensg-core

Reply via email to