* ./bootstrap:

- New: Complete rewrite of builCoriolis.py & merge with easyChams to provide
        a graphical interface. Asides to the GUI, when run in graphic mode all
        settings are kept from run to run. Meaning that once the initial setup
        is done, a user may completly forget where things are... The new tool
        is named <ccb> for 'Coriolis & Chams Builder'.
          The Builder is now a module, that is split into multiples files.
        The old buildCoriolis.py is kept for the time beeing to ensure a smooth
        transition.
This commit is contained in:
Jean-Paul Chaput 2013-01-12 14:57:35 +00:00
parent ceda10e523
commit b99ccda839
15 changed files with 2131 additions and 825 deletions

View File

@ -7,6 +7,7 @@
list(INSERT CMAKE_MODULE_PATH 0 "${Bootstrap_SOURCE_DIR}/cmake_modules/")
find_package(Bootstrap REQUIRED)
find_package(PythonSitePackages REQUIRED)
print_cmake_module_path()
setup_sysconfdir("${CMAKE_INSTALL_PREFIX}")
@ -17,8 +18,12 @@
OWNER_READ GROUP_READ WORLD_READ
OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)
install(FILES buildCoriolis.py
install(DIRECTORY builder
DESTINATION ${PYTHON_SITE_PACKAGES} )
install(FILES ccb.py
DESTINATION bin
RENAME ccb
PERMISSIONS OWNER_WRITE
OWNER_READ GROUP_READ WORLD_READ
OWNER_EXECUTE GROUP_EXECUTE WORLD_EXECUTE)

View File

@ -29,6 +29,7 @@ projects = [ { 'name' : 'bootstrap'
, "equinox"
, "solstice"
, "unicorn"
, "testbench"
#, "ispd"
, "cumulus"
, "stratus1"

View File

@ -1,831 +1,10 @@
#!/usr/bin/env python
import sys
import re
import os
import os.path
import datetime
import socket
import subprocess
import optparse
class ErrorMessage ( Exception ):
def __init__ ( self, code, *arguments ):
self._code = code
self._errors = [ 'Malformed call to ErrorMessage()'
, '%s' % str(arguments) ]
text = None
if len(arguments) == 1:
if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n')
else:
self._errors = arguments[0]
elif len(arguments) > 1:
text = list(arguments)
if text:
self._errors = []
while len(text[0]) == 0: del text[0]
lstrip = 0
if text[0].startswith('[ERROR]'): lstrip = 8
for line in text:
if line[0:lstrip ] == ' '*lstrip or \
line[0:lstrip-1] == '[ERROR]':
self._errors += [ line[lstrip:] ]
else:
self._errors += [ line.lstrip() ]
return
def __str__ ( self ):
if not isinstance(self._errors,list):
return "[ERROR] %s" % self._errors
formatted = "\n"
for i in range(len(self._errors)):
if i == 0: formatted += "[ERROR] %s" % self._errors[i]
else: formatted += " %s" % self._errors[i]
if i+1 < len(self._errors): formatted += "\n"
return formatted
def addMessage ( self, message ):
if not isinstance(self._errors,list):
self._errors = [ self._errors ]
if isinstance(message,list):
for line in message:
self._errors += [ line ]
else:
self._errors += [ message ]
return
def terminate ( self ):
print self
sys.exit(self._code)
def _getCode ( self ): return self._code
code = property(_getCode)
class Project:
def __init__ ( self, name, tools, repository ):
self._name = name
self._tools = tools
self._repository = repository
self._actives = []
return
def getName ( self ): return self._name
def getTools ( self ): return self._tools
def getRepository ( self ): return self._repository
def getActives ( self ): return self._actives
def hasTool ( self, tool ): return tool in self._tools
def desactivate ( self ):
self._active = []
return
def activateAll ( self ):
self._actives = self._tools
return
def activate ( self, tools ):
# Build the ordered list.
for tool in self._tools:
if (tool in tools) and not (tool in self._actives):
self._actives += [ tool ]
# Find the tools not part of the project.
rejecteds = []
for tool in tools:
if not (tool in self._tools) and (not tool in rejecteds):
rejecteds += [ tool ]
return rejecteds
class ProjectBuilder:
def __init__ ( self ):
self._projects = []
self._standalones = []
self._svnTag = "x"
self._svnMethod = None
self._projectDir = 'coriolis-2.x'
self._rootDir = os.path.join ( os.environ["HOME"], self._projectDir )
self._packageName = None
self._packageVersion = None
self._packageExcludes = []
self._packageProject = []
self._quiet = False
self._buildMode = "Release"
self._rmBuild = False
self._doBuild = True
self._noCache = False
self._enableShared = "ON"
self._enableDoc = "OFF"
self._checkDatabase = "OFF"
self._checkDeterminism = "OFF"
self._verboseMakefile = "OFF"
self._libMode = "Shared"
self._makeArguments = []
self._environment = os.environ
self._guessOs ()
self._updateSecondary ()
return
def __setattr__ ( self, attribute, value ):
if attribute[0] == "_":
self.__dict__[attribute] = value
return
if attribute == "svnTag": self._svnTag = value
elif attribute == "svnMethod": self._svnMethod = value
elif attribute == "projectDir": self._projectDir = value
elif attribute == "rootDir": self._rootDir = os.path.expanduser(value)
elif attribute == "packageName": self._packageName = value
elif attribute == "packageVersion": self._packageVersion = value
elif attribute == "quiet": self._quiet = value
elif attribute == "buildMode": self._buildMode = value
elif attribute == "rmBuild": self._rmBuild = value
elif attribute == "doBuild": self._doBuild = value
elif attribute == "noCache": self._noCache = value
elif attribute == "enableShared": self._enableShared = value
elif attribute == "enableDoc": self._enableDoc = value
elif attribute == "enableShared": self._enableShared = value
elif attribute == "checkDatabase": self._checkDatabase = value
elif attribute == "checkDeterminism": self._checkDeterminism = value
elif attribute == "verboseMakefile": self._verboseMakefile = value
elif attribute == "makeArguments": self._makeArguments = value.split ()
elif attribute == "libMode": self._libMode = value
self._updateSecondary ()
return
def _updateSecondary ( self ):
#self._rootDir = os.path.join ( os.environ["HOME"], self._projectDir )
self._rpmbuildDir = os.path.join ( self._rootDir , "rpmbuild" )
self._debbuildDir = os.path.join ( self._rootDir , "debbuild" )
self._tmppathDir = os.path.join ( self._rpmbuildDir, "tmp" )
self._tarballDir = os.path.join ( self._rootDir , "tarball" )
self._archiveDir = os.path.join ( self._tarballDir , "%s-%s.%s" % (self._packageName
,self._packageVersion
,self._svnTag) )
self._sourceDir = os.path.join ( self._rootDir , "src" )
self._osDir = os.path.join ( self._rootDir
, self._osType
, "%s.%s" % (self._buildMode,self._libMode) )
self._buildDir = os.path.join ( self._osDir, "build" )
self._installDir = os.path.join ( self._osDir, "install" )
if self._enableShared == "ON": self._libMode = "Shared"
else: self._libMode = "Static"
self._specFileIn = os.path.join ( self._sourceDir, "bootstrap", "%s.spec.in"%self._packageName )
self._specFile = os.path.join ( self._sourceDir, "bootstrap", "%s.spec" %self._packageName )
self._debianDir = os.path.join ( self._sourceDir, "bootstrap", "debian" )
self._debChangelogIn = os.path.join ( self._debianDir, "changelog.in" )
self._debChangelog = os.path.join ( self._debianDir, "changelog" )
self._sourceTarBz2 = "%s-%s.%s.tar.bz2" % (self._packageName,self._packageVersion,self._svnTag)
self._binaryTarBz2 = "%s-binary-%s.%s-1.slsoc6.tar.bz2" % (self._packageName,self._packageVersion,self._svnTag)
self._distribPatch = os.path.join ( self._sourceDir, "bootstrap", "%s-for-distribution.patch"%self._packageName )
return
def _guessOs ( self ):
self._libSuffix = None
self._osSlsoc6x_64 = re.compile (".*Linux.*el6.*x86_64.*")
self._osSlsoc6x = re.compile (".*Linux.*el6.*")
self._osSLSoC5x_64 = re.compile (".*Linux.*el5.*x86_64.*")
self._osSLSoC5x = re.compile (".*Linux.*(el5|2.6.23.13.*SoC).*")
self._osLinux_64 = re.compile (".*Linux.*x86_64.*")
self._osLinux = re.compile (".*Linux.*")
self._osFreeBSD8x_amd64 = re.compile (".*FreeBSD 8.*amd64.*")
self._osFreeBSD8x_64 = re.compile (".*FreeBSD 8.*x86_64.*")
self._osFreeBSD8x = re.compile (".*FreeBSD 8.*")
self._osDarwin = re.compile (".*Darwin.*")
uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE )
lines = uname.stdout.readlines()
if self._osSlsoc6x_64.match(lines[0]):
self._osType = "Linux.slsoc6x_64"
self._libSuffix = "64"
elif self._osSlsoc6x .match(lines[0]): self._osType = "Linux.slsoc6x"
elif self._osSLSoC5x_64.match(lines[0]):
self._osType = "Linux.SLSoC5x_64"
self._libSuffix = "64"
elif self._osSLSoC5x .match(lines[0]): self._osType = "Linux.SLSoC5x"
elif self._osLinux_64 .match(lines[0]):
self._osType = "Linux.x86_64"
self._libSuffix = "64"
elif self._osLinux .match(lines[0]): self._osType = "Linux.i386"
elif self._osDarwin .match(lines[0]): self._osType = "Darwin"
elif self._osFreeBSD8x_amd64.match(lines[0]):
self._osType = "FreeBSD.8x.amd64"
self._libSuffix = "64"
elif self._osFreeBSD8x_64.match(lines[0]):
self._osType = "FreeBSD.8x.x86_64"
self._libSuffix = "64"
elif self._osFreeBSD8x .match(lines[0]): self._osType = "FreeBSD.8x.i386"
else:
uname = subprocess.Popen ( ["uname", "-sr"], stdout=subprocess.PIPE )
self._osType = uname.stdout.readlines()[0][:-1]
print "[WARNING] Unrecognized OS: \"%s\"." % lines[0][:-1]
print " (using: \"%s\")" % self._osType
return
def _guessSvnTag ( self, project ):
revisionPattern = re.compile ( r"^Revision:\s*(?P<revision>\d+)" )
projectSvnDir = os.path.join ( self._svnMethod+project.getRepository() )
command = [ "svn", "info", projectSvnDir ]
svnInfo = subprocess.Popen ( command, stdout=subprocess.PIPE )
for line in svnInfo.stdout.readlines():
m = revisionPattern.match ( line )
if m:
self._svnTag = m.group("revision")
print "Latest revision of project %s is %s." % (project.getName(),self._svnTag)
self._updateSecondary ()
return
print "[WARNING] Cannot guess revision for project \"%s\"." % project.getName()
print " (using: \"x\")"
return
def _configure ( self, fileIn, file ):
fdFileIn = open ( fileIn, "r" )
fdFile = open ( file , "w" )
for line in fdFileIn.readlines():
stable = False
substituted0 = line
while not stable:
substituted1 = re.sub ( r"@svntag@" , self._svnTag , substituted0 )
substituted1 = re.sub ( r"@coriolisTop@", "/opt/coriolis2", substituted1 )
if substituted0 == substituted1: stable = True
else: substituted0 = substituted1
fdFile.write ( substituted0 )
fdFileIn.close ()
fdFile.close ()
return
def _doSpec ( self ):
self._configure ( self._specFileIn, self._specFile )
return
def _doDebChangelog ( self ):
self._configure ( self._debChangelogIn, self._debChangelog )
return
def _execute ( self, command, error ):
sys.stdout.flush ()
sys.stderr.flush ()
child = subprocess.Popen ( command, env=self._environment, stdout=None )
(pid,status) = os.waitpid ( child.pid, 0 )
status >>= 8
if status != 0:
ErrorMessage( status, "%s (status:%d)."%(error,status) ).terminate()
return
def _enableTool ( self, tool ):
return
def _build ( self, tool ):
toolSourceDir = os.path.join ( self._sourceDir, tool )
toolBuildDir = os.path.join ( self._buildDir , tool )
# Supplied directly in the CMakeLists.txt.
#cmakeModules = os.path.join ( self._installDir, "share", "cmake", "Modules" )
if not os.path.isdir(toolSourceDir):
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
return
if self._rmBuild:
print "Removing tool build directory: \"%s\"." % toolBuildDir
command = [ "/bin/rm", "-rf", toolBuildDir ]
self._execute ( command, "Removing tool build directory" )
if not os.path.isdir(toolBuildDir):
print "Creating tool build directory: \"%s\"." % toolBuildDir
os.makedirs ( toolBuildDir )
os.chdir ( toolBuildDir )
command = ["cmake", "-D", "CMAKE_BUILD_TYPE:STRING=%s" % self._buildMode
, "-D", "BUILD_SHARED_LIBS:STRING=%s" % self._enableShared
#, "-D", "CMAKE_MODULE_PATH:STRING=%s" % cmakeModules
, toolSourceDir ]
self._execute ( command, "First CMake failed" )
os.chdir ( toolBuildDir )
if self._noCache:
cmakeCache = os.path.join(toolBuildDir,"CMakeCache.txt")
if os.path.isfile ( cmakeCache ): os.unlink ( cmakeCache )
command = ["cmake", "-D", "CMAKE_BUILD_TYPE:STRING=%s" % self._buildMode
, "-D", "BUILD_SHARED_LIBS:STRING=%s" % self._enableShared
, "-D", "BUILD_DOC:STRING=%s" % self._enableDoc
, "-D", "CHECK_DATABASE:STRING=%s" % self._checkDatabase
, "-D", "CHECK_DETERMINISM:STRING=%s" % self._checkDeterminism
, "-D", "CMAKE_VERBOSE_MAKEFILE:STRING=%s" % self._verboseMakefile
, "-D", "CMAKE_INSTALL_PREFIX:STRING=%s" % self._installDir
]
if self._libSuffix:
command += [ "-D", "LIB_SUFFIX:STRING=%s" % self._libSuffix ]
command += [ toolSourceDir ]
self._execute ( command, "Second CMake failed" )
if self._doBuild:
command = [ "make" ]
#command += [ "DESTDIR=%s" % self._installDir ]
if self._enableDoc == "ON":
#if tool == "crlcore" or tool == "stratus1":
if tool == "stratus1":
command += [ "dvi", "safepdf", "html" ]
command += self._makeArguments
print "Make command:", command
sys.stdout.flush ()
self._execute ( command, "Build failed" )
return
def _svnStatus ( self, tool ):
toolSourceDir = os.path.join ( self._sourceDir , tool )
if not os.path.isdir(toolSourceDir):
if not self._quiet:
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
return
os.chdir ( toolSourceDir )
print "Checking SVN status of tool: ", tool
command = [ "svn", "status", "-u", "-q" ]
self._execute ( command, "svn status -u -q" )
print
return
def _svnDiff ( self, tool ):
toolSourceDir = os.path.join ( self._sourceDir , tool )
if not os.path.isdir(toolSourceDir):
if not self._quiet:
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
return
os.chdir ( toolSourceDir )
print "Doing a SVN diff of tool: ", tool
command = [ "svn", "diff" ]
if self._svnTag != "x":
command += [ "--revision", self._svnTag ]
self._execute ( command, "svn diff %s" % tool )
print
return
def _svnUpdate ( self, tool ):
toolSourceDir = os.path.join ( self._sourceDir , tool )
if not os.path.isdir(toolSourceDir):
if not self._quiet:
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir)
return
os.chdir ( toolSourceDir )
print "Doing a SVN update of tool: ", tool
command = [ "svn", "update" ]
self._execute ( command, "svn update" )
print
return
def _svnCheckout ( self, tool ):
project = self.getToolProject ( tool )
if not project:
print ErrorMessage( 0, "Tool \"%s\" is not part of any project."%tool
,"Cannot guess the SVN repository." )
return
if not project.getRepository ():
print ErrorMessage( 0, "Project \"%s\" isn't associated to a repository."%project.getName() )
return
if not os.path.isdir(self._sourceDir):
print ErrorMessage( 0, "Source directory <%s> doesn't exists. Creating."%self._sourceDir )
os.makedirs( self._sourceDir )
toolSvnTrunkDir = os.path.join ( self._svnMethod+project.getRepository(), tool, "trunk" )
os.chdir ( self._sourceDir )
print "Doing a SVN checkout of tool: ", tool
command = [ "svn", "co", toolSvnTrunkDir, tool ]
if self._svnTag != "x":
command += [ "--revision", self._svnTag ]
self._execute ( command, "svn checkout %s" % tool )
print
return
def _svnExport ( self, tool ):
project = self.getToolProject ( tool )
if not project:
print ErrorMessage( 0, "Tool \"%s\" is not part of any project."%tool
, "Cannot guess the SVN repository.")
return
if not project.getRepository ():
print ErrorMessage( 0, "Project \"%s\" isn't associated to a repository."%project.getName() )
return
toolSvnTrunkDir = os.path.join ( self._svnMethod+project.getRepository(), tool, "trunk" )
if not os.path.isdir ( self._archiveDir ):
os.mkdir ( self._archiveDir )
os.chdir ( self._archiveDir )
toolExportDir = os.path.join ( self._archiveDir, tool )
if os.path.isdir ( toolExportDir ):
print "Removing tool export (tarball) directory: \"%s\"." % toolExportDir
command = [ "/bin/rm", "-r", toolExportDir ]
self._execute ( command, "Removing tool export (tarball) directory" )
print "Doing a SVN export of tool: ", tool
command = [ "svn", "export", toolSvnTrunkDir, toolExportDir ]
if self._svnTag != "x":
command += [ "--revision", self._svnTag ]
self._execute ( command, "svn export %s" % toolExportDir )
print
return
def getProject ( self, name ):
for project in self._projects:
if project.getName() == name:
return project
return None
def getToolProject ( self, name ):
for project in self._projects:
if project.hasTool(name):
return project
return None
def register ( self, project ):
for registered in self._projects:
if registered.getName() == project.getName():
print ErrorMessage( 0, "Project \"%s\" is already registered (ignored)." )
return
self._projects += [ project ]
return
def _setEnvironment ( self, systemVariable, userVariable ):
if not self._environment.has_key(systemVariable) or self._environment[systemVariable] == "":
if not self._environment.has_key(userVariable) or self._environment[userVariable] == "" :
self._environment[ systemVariable ] = self._installDir
print "[WARNING] Neither <%s> nor <%s> environment variables are sets." \
% (systemVariable,userVariable)
print " Setting <%s> to <%s>." % (systemVariable,self._installDir)
else:
self._environment[ systemVariable ] = self._environment[ userVariable ]
if not self._quiet:
print "Setting <%s> to <%s>." % (systemVariable,self._environment[systemVariable])
if self._environment.has_key(userVariable):
print "Transmitting <%s> as <%s>." % (userVariable,self._environment[userVariable])
return
def _commandTemplate ( self, tools, projects, command ):
# Set or guess the various projects TOP environment variables.
for project in self._projects:
topVariable = "%s_TOP" % project.getName().upper()
topUserVariable = "%s_USER_TOP" % project.getName().upper()
self._setEnvironment ( topVariable, topUserVariable )
if tools:
# Checks if the requested tools are in the various projects.
self._standalones = tools
for project in self._projects:
self._standalones = project.activate ( self._standalones )
for tool in self._standalones:
print "[WARNING] Tool \"%s\" is not part of any project." % tool
if projects:
for projectName in projects:
project = self.getProject ( projectName )
if not project:
ErrorMessage( 1, "No project of name \"%s\"."%projectName ).terminate()
project.activateAll()
if not tools and not projects:
for project in self._projects:
project.activateAll ()
for project in self._projects:
for tool in project.getActives():
print "\nProcessing tool: \"%s\"." % tool
getattr(self,command) ( tool )
for tool in self._standalones:
print "\nProcessing tool: \"%s\"." % tool
getattr(self,command) ( tool )
return
def enable ( self, tools, projects ):
self._commandTemplate ( tools, projects, "_enableTool" )
return
def enabledTools ( self ):
tools = []
for project in self._projects:
tools += project.getActives()
return tools
def build ( self, tools, projects ):
self._commandTemplate ( tools, projects, "_build" )
return
def svnStatus ( self, tools, projects ):
self._commandTemplate ( tools, projects, "_svnStatus" )
return
def svnUpdate ( self, tools, projects ):
self._commandTemplate ( tools, projects, "_svnUpdate" )
return
def svnCheckout ( self, tools, projects ):
self._commandTemplate ( tools, projects, "_svnCheckout" )
return
def svnDiff ( self, tools, projects ):
self._commandTemplate ( tools, projects, "_svnDiff" )
return
def svnExport ( self, tools, projects ):
self._commandTemplate ( tools, projects, "_svnExport" )
return
def svnTarball ( self, tools, projects ):
if self._svnTag == "x":
self._guessSvnTag ( self.getProject(projects[0]) )
self._doSpec ()
self._doDebChangelog ()
if os.path.isdir(self._tarballDir):
print "Removing previous tarball directory: \"%s\"." % self._tarballDir
command = [ "/bin/rm", "-rf", self._tarballDir ]
self._execute ( command, "Removing top export (tarball) directory" )
print "Creating tarball directory: \"%s\"." % self._tarballDir
os.makedirs ( self._tarballDir )
self.svnExport ( tools, projects )
# Remove unpublisheds (yet) tools/files.
for item in self._packageExcludes:
command = [ "/bin/rm", "-rf", os.path.join(self._archiveDir,item) ]
self._execute ( command, "rm of %s failed" % item)
# Adds files neededs only for packaging purpose.
command = [ "/bin/cp", "-r", os.path.join(self._sourceDir ,"bootstrap","Makefile.package")
, os.path.join(self._archiveDir,"Makefile") ]
self._execute ( command, "copy of %s failed" % "boostrap/Makefile.package")
command = [ "/bin/cp", self._specFile, self._archiveDir ]
self._execute ( command, "Copying RPM spec file" )
command = [ "/bin/cp", "-r", self._debianDir, self._archiveDir ]
self._execute ( command, "Copying Debian/Ubuntu package control files" )
os.chdir ( self._archiveDir )
#command = [ "/usr/bin/patch", "--remove-empty-files"
# , "--no-backup-if-mismatch"
# , "-p0", "-i", self._distribPatch ]
#self._execute ( command, "patch for distribution command failed" )
os.chdir ( self._tarballDir )
command = [ "/bin/tar"
, "--exclude-backups"
, "--exclude-vcs"
, "-jcvf", self._sourceTarBz2, os.path.basename(self._archiveDir) ]
self._execute ( command, "tar command failed" )
print "Cleanup SVN export tarball archive directory: \"%s\"." % self._archiveDir
command = [ "/bin/rm", "-rf", self._archiveDir ]
self._execute ( command, "Removing archive export (tarball) directory" )
return
def userTarball ( self, tools, projects ):
self.enable( tools, projects )
userSourceTarBz2 = os.path.join ( self._tarballDir
, datetime.date.today().strftime('%s-%s-%%Y%%m%%d.tar.bz2'%
(self._packageName
,self._packageVersion)) )
excludes = []
for exclude in self._packageExcludes:
excludes += [ '--exclude='+exclude ]
os.chdir ( self._sourceDir )
command = [ "/bin/tar"
, "--exclude-backups"
, "--exclude-vcs"
, "--transform=s,^,%s/src/,"%self._projectDir ] \
+ excludes \
+ [ "-jcvf", userSourceTarBz2 ] \
+ self.enabledTools()
self._execute ( command, "tar command failed" )
return
def doRpm ( self ):
self.svnTarball ( [], self._packageProjects )
for rpmDir in [ "SOURCES", "SPECS", "BUILD", "tmp"
, "SRPMS", "RPMS/i386", "RPMS/i686", "RPMS/x86_64" ]:
rpmFullDir = os.path.join ( self._rpmbuildDir, rpmDir )
if not os.path.isdir(rpmFullDir):
os.makedirs ( rpmFullDir )
#rpmSpecFile = os.path.join ( self._rpmbuildDir, "SPECS" , "coriolis2.spec" )
rpmSourceFile = os.path.join ( self._rpmbuildDir, "SOURCES", self._sourceTarBz2 )
sourceFile = os.path.join ( self._tarballDir, self._sourceTarBz2 )
#if os.path.isfile ( rpmSpecFile ):
# os.unlink ( rpmSpecFile )
#os.symlink ( self._specFile, rpmSpecFile )
if not os.path.islink ( rpmSourceFile ):
os.symlink ( sourceFile, rpmSourceFile )
os.chdir ( self._rpmbuildDir )
command = [ "/usr/bin/rpmbuild"
, "--define", "_topdir %s" % self._rpmbuildDir
, "--define", "_tmppath %s" % self._tmppathDir
, "--define", "_enable_debug_packages 0"
, "-ta", "--with", "binarytar", rpmSourceFile ]
self._execute ( command, "Rebuild rpm packages" )
return
def doDeb ( self ):
self.svnTarball ( [], self._packageProjects )
if not os.path.isdir(self._debbuildDir):
os.makedirs ( self._debbuildDir )
os.chdir ( self._debbuildDir )
sourceFile = os.path.join ( self._tarballDir , self._sourceTarBz2 )
debOrigFile = os.path.join ( self._debbuildDir, "coriolis2_1.0.%s.orig.tar.bz2" % self._svnTag )
if not os.path.islink(debOrigFile):
os.link ( sourceFile, debOrigFile )
command = [ "/bin/tar", "jxf", debOrigFile ]
self._execute ( command, "Unpacking pristine sources" )
#command = [ "/bin/cp", "-r", self._debianDir, "." ]
#self._execute ( command, "Copying Debian/Ubuntu package control files" )
packageDir = os.path.join ( self._debbuildDir, "coriolis2-1.0.%s" % self._svnTag )
os.chdir ( packageDir )
self._environment["CFLAGS" ] = "-O2"
self._environment["CXXFLAGS"] = "-O2"
command = [ "/usr/bin/debuild", "-us", "-uc" ]
self._execute ( command, "Rebuild Debian packages" )
return
def loadConfiguration ( self, confFile ):
moduleGlobals = globals()
if not confFile:
print 'Making an educated guess to locate the configuration file:'
locations = [ os.path.abspath(os.path.dirname(sys.argv[0]))
, os.environ['HOME']+'/coriolis-2.x/src/bootstrap'
, os.environ['HOME']+'/coriolis/src/bootstrap'
, os.environ['HOME']+'/chams-2.x/src/bootstrap'
, os.environ['HOME']+'/chams/src/bootstrap'
, '/users/outil/coriolis/coriolis-2.x/src/bootstrap'
, self._rootDir+'/src/bootstrap'
]
for location in locations:
confFile = location + '/build.conf'
print ' <%s>' % confFile
if os.path.isfile(confFile): break
if not confFile:
ErrorMessage( 1, 'Cannot locate any configuration file.' ).terminate()
else:
if not os.path.isfile(confFile):
ErrorMessage( 1, 'Missing configuration file:', '<%s>'%confFile ).terminate()
print 'Reading configuration from:'
print ' <%s>' % options.conf
try:
execfile( confFile, moduleGlobals )
except Exception, e:
ErrorMessage( 1, 'An exception occured while loading the configuration file:'
, '<%s>\n' % (confFile)
, 'You should check for simple python errors in this file.'
, 'Error was:'
, '%s\n' % e ).terminate()
if moduleGlobals.has_key('projects'):
entryNb = 0
for entry in moduleGlobals['projects']:
entryNb += 1
if not entry.has_key('name'):
raise ErrorMessage( 1, 'Missing project name in project entry #%d.' % entryNb )
if not entry.has_key('tools'):
raise ErrorMessage( 1, 'Missing tools list in project entry #%d (<%s>).' \
% (entryNb,entry['name']) )
if not isinstance(entry['tools'],list):
raise ErrorMessage( 1, 'Tools item of project entry #%d (<%s>) is not a list.' \
% (entryNb,entry['name']) )
if not entry.has_key('repository'):
raise ErrorMessage( 1, 'Missing project repository in project entry #%d.' \
% entryNb )
self.register( Project(entry['name'],entry['tools'],entry['repository']) )
else:
ErrorMessage( 1, 'Configuration file is missing the \'project\' symbol.'
, '<%s>'%confFile ).terminate()
if moduleGlobals.has_key('projectdir'):
self.projectDir = moduleGlobals['projectdir']
if moduleGlobals.has_key('svnconfig'):
svnconfig = moduleGlobals['svnconfig']
if svnconfig.has_key('method'): self._svnMethod = svnconfig['method']
if moduleGlobals.has_key('package'):
package = moduleGlobals['package']
if package.has_key('name' ): self.packageName = package['name']
if package.has_key('version' ): self.packageVersion = package['version']
if package.has_key('excludes'):
if not isinstance(package['excludes'],list):
raise ErrorMessage( 1, 'Excludes of package configuration is not a list.')
self._packageExcludes = package['excludes']
if package.has_key('projects'):
if not isinstance(package['projects'],list):
raise ErrorMessage( 1, 'Projects to package is not a list.')
self._packageProjects = package['projects']
return
def showConfiguration ( self ):
print 'BuildCoriolis Configuration:'
if self._svnMethod:
print ' SVN Method: <%s>' % self._svnMethod
else:
print ' SVN Method not defined, will not be able to checkout/commit.'
for project in self._projects:
print ' project:%-15s repository:<%s>' % ( ('<%s>'%project.getName()), project.getRepository() )
toolOrder = 1
for tool in project.getTools():
print '%s%02d:<%s>' % (' '*26,toolOrder,tool)
toolOrder += 1
print
return
from builder import ErrorMessage
from builder.Builder import Builder
if __name__ == "__main__":
@ -869,7 +48,7 @@ if __name__ == "__main__":
parser.add_option ( "-u", "--check-deter", action="store_true" , dest="checkDeterminism", help="Enable Katabatic/Kite determinism checking (*very* slow)." )
( options, args ) = parser.parse_args ()
builder = ProjectBuilder ()
builder = Builder ()
builder.loadConfiguration ( options.conf )
if options.showConf:

View File

@ -0,0 +1,99 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Author : Jean-Paul Chaput |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./builder/AboutWidget.py" |
# +-----------------------------------------------------------------+
from PyQt4.QtCore import Qt
from PyQt4.QtGui import QPalette
from PyQt4.QtGui import QColor
from PyQt4.QtGui import QFont
from PyQt4.QtGui import QWidget
from PyQt4.QtGui import QFrame
from PyQt4.QtGui import QLabel
from PyQt4.QtGui import QVBoxLayout
from PyQt4.QtGui import QAction
from PyQt4.QtGui import QKeySequence
from PyQt4.QtGui import QApplication
class AboutWidget ( QWidget ):
def __init__ ( self, parent=None ):
QWidget.__init__ ( self, parent )
self.setFixedSize( 500, 400 )
self.setStyleSheet( 'background-color: #ffffdd;' )
topLine = QFrame()
topLine.setFrameShape( QFrame.HLine )
topLine.setLineWidth ( 2 )
botLine = QFrame()
botLine.setFrameShape( QFrame.HLine )
botLine.setLineWidth ( 2 )
title = QLabel( 'CCB' )
title.setAlignment( Qt.AlignCenter )
font = title.font()
font.setPointSize( 72 )
font.setWeight ( QFont.Bold )
title.setFont( font )
subTitle = QLabel( 'Coriolis & Chams Builder for the Dummies' )
subTitle.setAlignment( Qt.AlignCenter )
subTitle.setFont( QFont('Courier',10,QFont.Bold) )
authors = QLabel( 'Coriolis CAD System 1.0 . . . . . . . . ccb 1.0\n'
'Copyright (c) 2008-2013 . . . . . . . . . . UPMC\n'
'Authors . . . . . . . . . . . . . Damien Dupuis\n'
' . . . . . . . . . . . . Jean-Paul Chaput\n'
'E-Mail . . . . . . . . Jean-Paul.Chaput@lip6.fr'
)
authors.setAlignment( Qt.AlignCenter )
authors.setFont( QFont('Courier',10,QFont.Bold) )
vLayout = QVBoxLayout()
vLayout.addStretch(10)
vLayout.addWidget( topLine )
vLayout.addWidget( title )
vLayout.addStretch(1)
vLayout.addWidget( subTitle )
vLayout.addWidget( authors )
vLayout.addStretch(1)
vLayout.addWidget( botLine )
vLayout.addStretch(10)
frame = QFrame()
frame.setFrameShape ( QFrame.Box )
frame.setFrameShadow( QFrame.Sunken )
frame.setLayout ( vLayout )
frame.setLineWidth ( 1 )
vLayout = QVBoxLayout()
vLayout.addWidget( frame )
self.setLayout( vLayout )
self._exitAction = QAction( '&Exit', self )
self._exitAction.setStatusTip( 'Exit CCB (settings are saved)' )
self._exitAction.setShortcut ( QKeySequence('CTRL+Q') )
self._exitAction.triggered.connect( QApplication.closeAllWindows )
self.addAction( self._exitAction )
self._closeAction = QAction( '&Close', self )
self._closeAction.setStatusTip( 'Close the About Window' )
self._closeAction.setShortcut ( QKeySequence('CTRL+A') )
self._closeAction.triggered.connect( self.close )
self.addAction( self._closeAction )
return

View File

@ -0,0 +1,543 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Author : Jean-Paul Chaput |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./builder/Builder.py" |
# +-----------------------------------------------------------------+
import sys
import re
import os
import os.path
import datetime
import subprocess
from . import ErrorMessage
from Project import Project
from Configuration import Configuration
class Builder:
def __init__ ( self ):
self._conf = Configuration()
self._quiet = False
self._rmBuild = False
self._doBuild = True
self._noCache = False
self._enableShared = "ON"
self._enableDoc = "OFF"
self._checkDatabase = "OFF"
self._checkDeterminism = "OFF"
self._verboseMakefile = "OFF"
self._makeArguments = []
self._environment = os.environ
return
def __setattr__ ( self, attribute, value ):
if attribute[0] == "_":
self.__dict__[attribute] = value
return
if attribute in self._conf.getAllIds(): setattr( self._conf, attribute, value )
if attribute == "quiet": self._quiet = value
elif attribute == "rmBuild": self._rmBuild = value
elif attribute == "doBuild": self._doBuild = value
elif attribute == "noCache": self._noCache = value
elif attribute == "enableDoc": self._enableDoc = value
elif attribute == "enableShared": self._enableShared = value
elif attribute == "checkDatabase": self._checkDatabase = value
elif attribute == "checkDeterminism": self._checkDeterminism = value
elif attribute == "verboseMakefile": self._verboseMakefile = value
elif attribute == "makeArguments": self._makeArguments = value.split ()
return
def __getattr__ ( self, attribute ):
if attribute[0] != "_":
if attribute == 'conf': return self._conf
if attribute in self._conf.getAllIds():
return getattr( self._conf, attribute )
if not self.__dict__.has_key(attribute):
raise ErrorMessage( 1, 'Builder has no attribute <%s>.'%attribute )
return self.__dict__[attribute]
def _guessSvnTag ( self, project ):
revisionPattern = re.compile ( r"^Revision:\s*(?P<revision>\d+)" )
projectSvnDir = os.path.join ( self.svnMethod+project.getRepository() )
command = [ "svn", "info", projectSvnDir ]
svnInfo = subprocess.Popen ( command, stdout=subprocess.PIPE )
for line in svnInfo.stdout.readlines():
m = revisionPattern.match ( line )
if m:
self.svnTag = m.group("revision")
print "Latest revision of project %s is %s." % (project.getName(),self.svnTag)
return
print "[WARNING] Cannot guess revision for project \"%s\"." % project.getName()
print " (using: \"x\")"
return
def _configure ( self, fileIn, file ):
fdFileIn = open ( fileIn, "r" )
fdFile = open ( file , "w" )
for line in fdFileIn.readlines():
stable = False
substituted0 = line
while not stable:
substituted1 = re.sub ( r"@svntag@" , self.svnTag, substituted0 )
substituted1 = re.sub ( r"@coriolisTop@", "/opt/coriolis2" , substituted1 )
if substituted0 == substituted1: stable = True
else: substituted0 = substituted1
fdFile.write ( substituted0 )
fdFileIn.close ()
fdFile.close ()
return
def _doSpec ( self ):
self._configure ( self.specFileIn, self.specFile )
return
def _doDebChangelog ( self ):
self._configure ( self.debChangelogIn, self.debChangelog )
return
def _execute ( self, command, error ):
sys.stdout.flush ()
sys.stderr.flush ()
child = subprocess.Popen ( command, env=self._environment, stdout=None )
(pid,status) = os.waitpid ( child.pid, 0 )
status >>= 8
if status != 0:
ErrorMessage( status, "%s (status:%d)."%(error,status) ).terminate()
return
def _enableTool ( self, tool ):
return
def _build ( self, tool ):
toolSourceDir = os.path.join ( self.sourceDir, tool )
toolBuildDir = os.path.join ( self.buildDir , tool )
# Supplied directly in the CMakeLists.txt.
#cmakeModules = os.path.join ( self.installDir, "share", "cmake", "Modules" )
if not os.path.isdir(toolSourceDir):
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
return
if self._rmBuild:
print "Removing tool build directory: \"%s\"." % toolBuildDir
command = [ "/bin/rm", "-rf", toolBuildDir ]
self._execute ( command, "Removing tool build directory" )
if not os.path.isdir(toolBuildDir):
print "Creating tool build directory: \"%s\"." % toolBuildDir
os.makedirs ( toolBuildDir )
os.chdir ( toolBuildDir )
command = ["cmake", "-D", "CMAKE_BUILD_TYPE:STRING=%s" % self.buildMode
, "-D", "BUILD_SHARED_LIBS:STRING=%s" % self.enableShared
#, "-D", "CMAKE_MODULE_PATH:STRING=%s" % cmakeModules
, toolSourceDir ]
self._execute ( command, "First CMake failed" )
os.chdir ( toolBuildDir )
if self._noCache:
cmakeCache = os.path.join(toolBuildDir,"CMakeCache.txt")
if os.path.isfile ( cmakeCache ): os.unlink ( cmakeCache )
command = ["cmake", "-D", "CMAKE_BUILD_TYPE:STRING=%s" % self.buildMode
, "-D", "BUILD_SHARED_LIBS:STRING=%s" % self.enableShared
, "-D", "BUILD_DOC:STRING=%s" % self._enableDoc
, "-D", "CHECK_DATABASE:STRING=%s" % self._checkDatabase
, "-D", "CHECK_DETERMINISM:STRING=%s" % self._checkDeterminism
, "-D", "CMAKE_VERBOSE_MAKEFILE:STRING=%s" % self._verboseMakefile
, "-D", "CMAKE_INSTALL_PREFIX:STRING=%s" % self.installDir
]
if self.libSuffix:
command += [ "-D", "LIB_SUFFIX:STRING=%s" % self.libSuffix ]
command += [ toolSourceDir ]
self._execute ( command, "Second CMake failed" )
if self._doBuild:
command = [ "make" ]
#command += [ "DESTDIR=%s" % self.installDir ]
if self._enableDoc == "ON":
#if tool == "crlcore" or tool == "stratus1":
if tool == "stratus1":
command += [ "dvi", "safepdf", "html" ]
command += self._makeArguments
print "Make command:", command
sys.stdout.flush ()
self._execute ( command, "Build failed" )
return
def _svnStatus ( self, tool ):
toolSourceDir = os.path.join ( self.sourceDir , tool )
if not os.path.isdir(toolSourceDir):
if not self._quiet:
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
return
os.chdir ( toolSourceDir )
print "Checking SVN status of tool: ", tool
command = [ "svn", "status", "-u", "-q" ]
self._execute ( command, "svn status -u -q" )
print
return
def _svnDiff ( self, tool ):
toolSourceDir = os.path.join ( self.sourceDir , tool )
if not os.path.isdir(toolSourceDir):
if not self._quiet:
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir )
return
os.chdir ( toolSourceDir )
print "Doing a SVN diff of tool: ", tool
command = [ "svn", "diff" ]
if self.svnTag != "x":
command += [ "--revision", self.svnTag ]
self._execute ( command, "svn diff %s" % tool )
print
return
def _svnUpdate ( self, tool ):
toolSourceDir = os.path.join ( self.sourceDir , tool )
if not os.path.isdir(toolSourceDir):
if not self._quiet:
print ErrorMessage( 0, "Missing tool source directory: \"%s\" (skipped)."%toolSourceDir)
return
os.chdir ( toolSourceDir )
print "Doing a SVN update of tool: ", tool
command = [ "svn", "update" ]
self._execute ( command, "svn update" )
print
return
def _svnCheckout ( self, tool ):
project = self.getToolProject ( tool )
if not project:
print ErrorMessage( 0, "Tool \"%s\" is not part of any project."%tool
,"Cannot guess the SVN repository." )
return
if not project.getRepository ():
print ErrorMessage( 0, "Project \"%s\" isn't associated to a repository."%project.getName() )
return
if not os.path.isdir(self.sourceDir):
print ErrorMessage( 0, "Source directory <%s> doesn't exists. Creating."%self.sourceDir )
os.makedirs( self.sourceDir )
toolSvnTrunkDir = os.path.join ( self.svnMethod+project.getRepository(), tool, "trunk" )
os.chdir ( self.sourceDir )
print "Doing a SVN checkout of tool: ", tool
command = [ "svn", "co", toolSvnTrunkDir, tool ]
if self.svnTag != "x":
command += [ "--revision", self.svnTag ]
self._execute ( command, "svn checkout %s" % tool )
print
return
def _svnExport ( self, tool ):
project = self.getToolProject ( tool )
if not project:
print ErrorMessage( 0, "Tool \"%s\" is not part of any project."%tool
, "Cannot guess the SVN repository.")
return
if not project.getRepository ():
print ErrorMessage( 0, "Project \"%s\" isn't associated to a repository."%project.getName() )
return
toolSvnTrunkDir = os.path.join ( self.svnMethod+project.getRepository(), tool, "trunk" )
if not os.path.isdir ( self.archiveDir ):
os.mkdir ( self.archiveDir )
os.chdir ( self.archiveDir )
toolExportDir = os.path.join ( self.archiveDir, tool )
if os.path.isdir ( toolExportDir ):
print "Removing tool export (tarball) directory: \"%s\"." % toolExportDir
command = [ "/bin/rm", "-r", toolExportDir ]
self._execute ( command, "Removing tool export (tarball) directory" )
print "Doing a SVN export of tool: ", tool
command = [ "svn", "export", toolSvnTrunkDir, toolExportDir ]
if self.svnTag != "x":
command += [ "--revision", self.svnTag ]
self._execute ( command, "svn export %s" % toolExportDir )
print
return
def _setEnvironment ( self, systemVariable, userVariable ):
if not self._environment.has_key(systemVariable) or self._environment[systemVariable] == "":
if not self._environment.has_key(userVariable) or self._environment[userVariable] == "" :
self._environment[ systemVariable ] = self.installDir
print "[WARNING] Neither <%s> nor <%s> environment variables are sets." \
% (systemVariable,userVariable)
print " Setting <%s> to <%s>." % (systemVariable,self.installDir)
else:
self._environment[ systemVariable ] = self._environment[ userVariable ]
if not self._quiet:
print "Setting <%s> to <%s>." % (systemVariable,self._environment[systemVariable])
if self._environment.has_key(userVariable):
print "Transmitting <%s> as <%s>." % (userVariable,self._environment[userVariable])
return
def _commandTemplate ( self, tools, projects, command ):
# Set or guess the various projects TOP environment variables.
for project in self.projects:
topVariable = "%s_TOP" % project.getName().upper()
topUserVariable = "%s_USER_TOP" % project.getName().upper()
self._setEnvironment ( topVariable, topUserVariable )
if tools:
# Checks if the requested tools are in the various projects.
self.standalones = tools
for project in self.projects:
self.standalones = project.activate ( self.standalones )
for tool in self.standalones:
print "[WARNING] Tool \"%s\" is not part of any project." % tool
if projects:
for projectName in projects:
project = self.getProject ( projectName )
if not project:
ErrorMessage( 1, "No project of name \"%s\"."%projectName ).terminate()
project.activateAll()
if not tools and not projects:
for project in self.projects:
project.activateAll ()
for project in self.projects:
for tool in project.getActives():
print "\nProcessing tool: \"%s\"." % tool
getattr(self,command) ( tool )
for tool in self.standalones:
print "\nProcessing tool: \"%s\"." % tool
getattr(self,command) ( tool )
return
def enable ( self, tools, projects ):
self._commandTemplate ( tools, projects, "_enableTool" )
return
def enabledTools ( self ):
tools = []
for project in self.projects:
tools += project.getActives()
return tools
def build ( self, tools, projects ):
self._commandTemplate ( tools, projects, "_build" )
return
def svnStatus ( self, tools, projects ):
self._commandTemplate ( tools, projects, "_svnStatus" )
return
def svnUpdate ( self, tools, projects ):
self._commandTemplate ( tools, projects, "_svnUpdate" )
return
def svnCheckout ( self, tools, projects ):
self._commandTemplate ( tools, projects, "_svnCheckout" )
return
def svnDiff ( self, tools, projects ):
self._commandTemplate ( tools, projects, "_svnDiff" )
return
def svnExport ( self, tools, projects ):
self._commandTemplate ( tools, projects, "_svnExport" )
return
def svnTarball ( self, tools, projects ):
if self.svnTag == "x":
self._guessSvnTag ( self.getProject(projects[0]) )
self._doSpec ()
self._doDebChangelog ()
if os.path.isdir(self.tarballDir):
print "Removing previous tarball directory: \"%s\"." % self.tarballDir
command = [ "/bin/rm", "-rf", self.tarballDir ]
self._execute ( command, "Removing top export (tarball) directory" )
print "Creating tarball directory: \"%s\"." % self.tarballDir
os.makedirs ( self.tarballDir )
self.svnExport ( tools, projects )
# Remove unpublisheds (yet) tools/files.
for item in self.packageExcludes:
command = [ "/bin/rm", "-rf", os.path.join(self.archiveDir,item) ]
self._execute ( command, "rm of %s failed" % item)
# Adds files neededs only for packaging purpose.
command = [ "/bin/cp", "-r", os.path.join(self.sourceDir ,"bootstrap","Makefile.package")
, os.path.join(self.archiveDir,"Makefile") ]
self._execute ( command, "copy of %s failed" % "boostrap/Makefile.package")
command = [ "/bin/cp", self.specFile, self.archiveDir ]
self._execute ( command, "Copying RPM spec file" )
command = [ "/bin/cp", "-r", self.debianDir, self.archiveDir ]
self._execute ( command, "Copying Debian/Ubuntu package control files" )
os.chdir ( self.archiveDir )
#command = [ "/usr/bin/patch", "--remove-empty-files"
# , "--no-backup-if-mismatch"
# , "-p0", "-i", self.distribPatch ]
#self._execute ( command, "patch for distribution command failed" )
os.chdir ( self.tarballDir )
command = [ "/bin/tar"
, "--exclude-backups"
, "--exclude-vcs"
, "-jcvf", self.sourceTarBz2, os.path.basename(self.archiveDir) ]
self._execute ( command, "tar command failed" )
print "Cleanup SVN export tarball archive directory: \"%s\"." % self.archiveDir
command = [ "/bin/rm", "-rf", self.archiveDir ]
self._execute ( command, "Removing archive export (tarball) directory" )
return
def userTarball ( self, tools, projects ):
self.enable( tools, projects )
userSourceTarBz2 = os.path.join ( self.tarballDir
, datetime.date.today().strftime('%s-%s-%%Y%%m%%d.tar.bz2'%
(self.packageName
,self.packageVersion)) )
excludes = []
for exclude in self.packageExcludes:
excludes += [ '--exclude='+exclude ]
os.chdir ( self.sourceDir )
command = [ "/bin/tar"
, "--exclude-backups"
, "--exclude-vcs"
, "--transform=s,^,%s/src/,"%self.projectDir ] \
+ excludes \
+ [ "-jcvf", userSourceTarBz2 ] \
+ self.enabledTools()
self._execute ( command, "tar command failed" )
return
def doRpm ( self ):
self.svnTarball ( [], self.packageProjects )
for rpmDir in [ "SOURCES", "SPECS", "BUILD", "tmp"
, "SRPMS", "RPMS/i386", "RPMS/i686", "RPMS/x86_64" ]:
rpmFullDir = os.path.join ( self.rpmbuildDir, rpmDir )
if not os.path.isdir(rpmFullDir):
os.makedirs ( rpmFullDir )
#rpmSpecFile = os.path.join ( self.rpmbuildDir, "SPECS" , "coriolis2.spec" )
rpmSourceFile = os.path.join ( self.rpmbuildDir, "SOURCES", self.sourceTarBz2 )
sourceFile = os.path.join ( self.tarballDir, self.sourceTarBz2 )
#if os.path.isfile ( rpmSpecFile ):
# os.unlink ( rpmSpecFile )
#os.symlink ( self.specFile, rpmSpecFile )
if not os.path.islink ( rpmSourceFile ):
os.symlink ( sourceFile, rpmSourceFile )
os.chdir ( self.rpmbuildDir )
command = [ "/usr/bin/rpmbuild"
, "--define", "_topdir %s" % self.rpmbuildDir
, "--define", "_tmppath %s" % self.tmppathDir
, "--define", "_enable_debug_packages 0"
, "-ta", "--with", "binarytar", rpmSourceFile ]
self._execute ( command, "Rebuild rpm packages" )
return
def doDeb ( self ):
self.svnTarball ( [], self.packageProjects )
if not os.path.isdir(self.debbuildDir):
os.makedirs ( self.debbuildDir )
os.chdir ( self.debbuildDir )
sourceFile = os.path.join ( self.tarballDir , self.sourceTarBz2 )
debOrigFile = os.path.join ( self.debbuildDir, "coriolis2_1.0.%s.orig.tar.bz2" % self.svnTag )
if not os.path.islink(debOrigFile):
os.link ( sourceFile, debOrigFile )
command = [ "/bin/tar", "jxf", debOrigFile ]
self._execute ( command, "Unpacking pristine sources" )
#command = [ "/bin/cp", "-r", self.debianDir, "." ]
#self._execute ( command, "Copying Debian/Ubuntu package control files" )
packageDir = os.path.join ( self.debbuildDir, "coriolis2-1.0.%s" % self.svnTag )
os.chdir ( packageDir )
self._environment["CFLAGS" ] = "-O2"
self._environment["CXXFLAGS"] = "-O2"
command = [ "/usr/bin/debuild", "-us", "-uc" ]
self._execute ( command, "Rebuild Debian packages" )
return
def loadConfiguration ( self, confFile ): self._conf.load( confFile )
def showConfiguration ( self ): self._conf.show()

View File

@ -0,0 +1,76 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Author : Damien Dupuis |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./builder/BuilderGui.py" |
# +-----------------------------------------------------------------+
from PyQt4.QtGui import QTabWidget
from PyQt4.QtGui import QApplication
from PyQt4.QtGui import QMainWindow
from PyQt4.QtGui import QAction
from PyQt4.QtGui import QKeySequence
from OptionsWidget import OptionsWidget
from CompileWidget import CompileWidget
from ConfigureWidget import ConfigureWidget
from AboutWidget import AboutWidget
class BuilderGui ( QMainWindow ):
def __init__ ( self, confFile, parent=None ):
QMainWindow.__init__( self, parent )
self.setWindowTitle( 'Coriolis/Chams Builder' )
self._tabWidget = QTabWidget()
self._configureWidget = ConfigureWidget(confFile)
self._optionsWidget = OptionsWidget(self._configureWidget.conf)
self._compileWidget = CompileWidget()
self._aboutWidget = AboutWidget()
self._tabWidget.addTab( self._optionsWidget , 'Options' )
self._tabWidget.addTab( self._compileWidget , 'Compile' )
self._tabWidget.addTab( self._configureWidget, 'Configure' )
self.setCentralWidget( self._tabWidget )
self._compileWidget.conf = self._configureWidget
self._compileWidget.options = self._optionsWidget
self._exitAction = QAction( '&Exit', self )
self._exitAction.setStatusTip( 'Exit CCB (settings are saved)' )
self._exitAction.setShortcut ( QKeySequence('CTRL+Q') )
self._exitAction.triggered.connect( QApplication.closeAllWindows )
self._saveAction = QAction( '&Save Settings', self )
self._saveAction.setStatusTip( 'Save Settings' )
self._saveAction.setShortcut ( QKeySequence('CTRL+S') )
self._saveAction.triggered.connect( self._configureWidget.saveSettings )
self._saveAction.triggered.connect( self._optionsWidget.saveSettings )
self._saveAction.triggered.connect( self._compileWidget.saveSettings )
self._aboutAction = QAction( '&About', self )
self._aboutAction.setStatusTip( 'A Word About Who\'s Responsible for This Thing' )
self._aboutAction.setShortcut ( QKeySequence('CTRL+A') )
self._aboutAction.triggered.connect( self._aboutWidget.show )
fileMenu = self.menuBar().addMenu( 'File' )
fileMenu.addAction( self._exitAction )
fileMenu.addAction( self._saveAction )
fileMenu.addAction( self._aboutAction )
return
def closeEvent ( self, event ):
self._configureWidget.saveSettings()
self._optionsWidget .saveSettings()
self._compileWidget .saveSettings()
event.accept()
return

View File

@ -0,0 +1,209 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Author : Damien Dupuis |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./builder/CompileWidget.py" |
# +-----------------------------------------------------------------+
import re
import subprocess
from PyQt4.QtCore import Qt
from PyQt4.QtCore import pyqtSignal
from PyQt4.QtCore import QSettings
from PyQt4.QtGui import QFont
from PyQt4.QtGui import QColor
from PyQt4.QtGui import QPalette
from PyQt4.QtGui import QTextCharFormat
from PyQt4.QtGui import QWidget
from PyQt4.QtGui import QLabel
from PyQt4.QtGui import QPushButton
from PyQt4.QtGui import QCheckBox
from PyQt4.QtGui import QGroupBox
from PyQt4.QtGui import QButtonGroup
from PyQt4.QtGui import QVBoxLayout
from PyQt4.QtGui import QHBoxLayout
from PyQt4.QtGui import QGridLayout
from PyQt4.QtGui import QScrollArea
from PyQt4.QtGui import QComboBox
from PyQt4.QtGui import QLineEdit
from PyQt4.QtGui import QTextEdit
from PyQt4.QtGui import QFileDialog
from PyQt4.QtGui import QProgressBar
from PyQt4.QtGui import QApplication
from builder.Highlighter import Highlighter
class CompileWidget ( QWidget ):
progress = pyqtSignal(int)
def __init__ ( self, parent=None ):
QWidget.__init__ ( self, parent )
self._options = None
self._conf = None
self._go = QPushButton( 'Go' )
self._go.setMaximumWidth( 100 )
font = self._go.font()
font.setPointSizeF( font.pointSizeF()*2.0 )
font.setWeight ( QFont.Bold )
self._go.setFont( font )
self._go.clicked.connect( self.go )
self._saveLog = QPushButton( 'Save' )
saveLogLabel = QLabel( 'Log File:' )
saveLogBrowse = QPushButton( '&Browse' )
saveLogBrowse.clicked.connect( self.browseSaveLog )
self._saveLogEdit = QLineEdit( '' )
gLayout = QGridLayout()
gLayout.addWidget( saveLogLabel , 0, 0, 1, 1, Qt.AlignRight )
gLayout.addWidget( self._saveLogEdit, 0, 1, 1, 6 )
gLayout.addWidget( saveLogBrowse , 0, 7, 1, 1 )
self._console = QTextEdit()
self._console.setLineWrapMode( QTextEdit.NoWrap )
self._console.setMinimumSize ( 800, 400 )
palette = self._console.palette()
palette.setColor( QPalette.Base, QColor.fromRgb(255,255,221) ) # ffffdd.
self._console.setPalette( palette )
font = QFont( 'Bitstream Vera Sans Mono', self._console.font().pointSize() )
self._console.setFont( font )
self._highlighter = Highlighter( self._console.document() )
self._progressBar = QProgressBar()
self._progressBar.setRange ( 0, 100 )
self._progressBar.setTextVisible( True )
hLayout = QHBoxLayout()
hLayout.addStretch()
hLayout.addWidget( self._go )
hLayout.addStretch()
hLayout.addWidget( self._saveLog )
hLayout.addStretch()
vLayout = QVBoxLayout()
vLayout.addLayout( hLayout )
vLayout.addLayout( gLayout )
vLayout.addWidget( self._progressBar )
vLayout.addWidget( self._console )
self.setLayout( vLayout )
self.progress.connect( self._progressBar.setValue )
self._saveLog.clicked.connect( self.saveLog )
self.readSettings()
return
def _setOptions ( self, options ): self._options = options
def _setConf ( self, conf ): self._conf = conf
def _getOptions ( self ): return self._options
def _getConf ( self ): return self._conf
options = property( _getOptions, _setOptions )
conf = property( _getConf , _setConf )
def browseSaveLog ( self ):
self._saveLogEdit.setText( QFileDialog.getSaveFileName(self
,'Select Log File Report'
,self._saveLogEdit.text()
,'Report Files (*.log *.txt)') )
return
def saveLog ( self ):
if self._saveLogEdit.text():
fd = open( self._saveLogEdit.text(), 'w+' )
fd.write( self._console.toPlainText() )
fd.close()
return
def shellCommand ( self ):
command = [ 'buildCoriolis.py' ]
for project in self.options.projects:
for tool in project.actives:
command += [ '--tool='+tool ]
toolsCount = len(command) - 1
if self.conf.rootDir: command += [ '--root=%s'%self.conf.rootDir ]
if self.options.svnUpdate: command += [ '--svn-update' ]
if self.options.svnStatus: command += [ '--svn-update' ]
if self.options.enableDoc: command += [ '--doc' ]
if self.options.noCache: command += [ '--no-cache' ]
if self.options.rmBuild: command += [ '--rm-build' ]
if self.options.verbose: command += [ '--verbose' ]
if self.options.make:
makeArguments='install '+self.options.threads
command += [ '--make=%s'%makeArguments ]
if self.options.buildMode == 'Debug':
command += [ '--debug' ]
return toolsCount, command
def go ( self ):
rePercentage = re.compile(r'^\[\s*(?P<percent>\d+)%\].*')
reProcessTool = re.compile(r'^Processing tool:\s*"(?P<tool>.+)"')
if not self.options or not self.conf: return
toolsCount, command = self.shellCommand()
if not toolsCount: return
self._progressBar.reset()
self._progressBar.setRange( 0, toolsCount*100 )
strCommand = command[0]
for arg in command[1:]:
strCommand += ' ' + arg
strCommand += '\n\n'
self._console.setFontItalic( True )
self._console.insertPlainText( strCommand )
self._console.setFontItalic( False )
toolsDone = -1
builderProcess = subprocess.Popen( command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT )
while True:
line = builderProcess.stdout.readline()
if line == '': break
m = rePercentage.match( line )
if m:
self.progress.emit( toolsDone*100+int(m.group('percent')) )
else:
m = reProcessTool.match( line )
if m:
toolsDone += 1
self._console.insertPlainText( line )
scrollBar = self._console.verticalScrollBar()
scrollBar.setValue( scrollBar.maximum() )
QApplication.processEvents()
builderProcess.wait()
if builderProcess.returncode == None:
pass
return
def readSettings ( self ):
settings = QSettings()
self._saveLogEdit.setText( settings.value('compile/saveLog').toString() )
return
def saveSettings ( self ):
settings = QSettings()
settings.setValue( 'compile/saveLog', self._saveLogEdit.text() )
return

View File

@ -0,0 +1,293 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Author : Jean-Paul Chaput |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./builder/Configuration.py" |
# +-----------------------------------------------------------------+
import sys
import re
import os
import os.path
import datetime
import subprocess
from . import ErrorMessage
from Project import Project
class Configuration ( object ):
PrimaryNames = \
[ 'confFile', 'projects', 'standalones'
, 'svnTag', 'svnMethod'
, 'projectDir', 'rootDir'
, 'packageName', 'packageVersion', 'packageExcludes', 'packageProject'
, 'osType', 'libSuffix', 'buildMode', 'libMode', 'enableShared'
]
SecondaryNames = \
[ 'rpmbuildDir' , 'debbuildDir' , 'tmppathDir' , 'tarballDir'
, 'archiveDir' , 'sourceDir' , 'osDir' , 'buildDir'
, 'installDir' , 'specFileIn' , 'specFile'
, 'debianDir' , 'debChangelogIn', 'debChangelog', 'sourceTarBz2'
, 'binaryTarBz2', 'distribPatch'
]
def __init__ ( self ):
self._confFile = None
self._projects = []
self._standalones = []
self._svnTag = "x"
self._svnMethod = None
self._projectDir = 'coriolis-2.x'
self._rootDir = os.path.join ( os.environ["HOME"], self._projectDir )
self._packageName = None
self._packageVersion = None
self._packageExcludes = []
self._packageProject = []
self._enableShared = 'ON'
self._buildMode = 'Release'
# Secondary (derived) variables.
# Setup by _updateSecondary().
self._guessOs()
self._updateSecondary()
return
def __setattr__ ( self, attribute, value ):
if attribute in Configuration.SecondaryNames:
print ErrorMessage( 1, 'Attempt to write in read-only attribute <%s> in Configuration.'%attribute )
return
if attribute[0] == '_':
self.__dict__[attribute] = value
return
if attribute == 'rootDir': value = os.path.expanduser(value)
elif attribute == 'enableShared' and value != 'ON': value = 'OFF'
self.__dict__['_'+attribute] = value
self._updateSecondary()
return
def __getattr__ ( self, attribute ):
if attribute[0] != '_': attribute = '_'+attribute
if not self.__dict__.has_key(attribute):
raise ErrorMessage( 1, 'Configuration has no attribute <%s>.'%attribute )
return self.__dict__[attribute]
def _updateSecondary ( self ):
if self._enableShared == "ON": self._libMode = "Shared"
else: self._libMode = "Static"
#self._rootDir = os.path.join ( os.environ["HOME"], self._projectDir )
self._rpmbuildDir = os.path.join ( self._rootDir , "rpmbuild" )
self._debbuildDir = os.path.join ( self._rootDir , "debbuild" )
self._tmppathDir = os.path.join ( self._rpmbuildDir, "tmp" )
self._tarballDir = os.path.join ( self._rootDir , "tarball" )
self._archiveDir = os.path.join ( self._tarballDir , "%s-%s.%s" % (self._packageName
,self._packageVersion
,self._svnTag) )
self._sourceDir = os.path.join ( self._rootDir , "src" )
self._osDir = os.path.join ( self._rootDir
, self._osType
, "%s.%s" % (self._buildMode,self._libMode) )
self._buildDir = os.path.join ( self._osDir, "build" )
self._installDir = os.path.join ( self._osDir, "install" )
self._specFileIn = os.path.join ( self._sourceDir, "bootstrap", "%s.spec.in"%self._packageName )
self._specFile = os.path.join ( self._sourceDir, "bootstrap", "%s.spec" %self._packageName )
self._debianDir = os.path.join ( self._sourceDir, "bootstrap", "debian" )
self._debChangelogIn = os.path.join ( self._debianDir, "changelog.in" )
self._debChangelog = os.path.join ( self._debianDir, "changelog" )
self._sourceTarBz2 = "%s-%s.%s.tar.bz2" % (self._packageName,self._packageVersion,self._svnTag)
self._binaryTarBz2 = "%s-binary-%s.%s-1.slsoc6.tar.bz2" % (self._packageName,self._packageVersion,self._svnTag)
self._distribPatch = os.path.join ( self._sourceDir, "bootstrap", "%s-for-distribution.patch"%self._packageName )
return
def _guessOs ( self ):
self._libSuffix = None
self._osSlsoc6x_64 = re.compile (".*Linux.*el6.*x86_64.*")
self._osSlsoc6x = re.compile (".*Linux.*el6.*")
self._osSLSoC5x_64 = re.compile (".*Linux.*el5.*x86_64.*")
self._osSLSoC5x = re.compile (".*Linux.*(el5|2.6.23.13.*SoC).*")
self._osLinux_64 = re.compile (".*Linux.*x86_64.*")
self._osLinux = re.compile (".*Linux.*")
self._osFreeBSD8x_amd64 = re.compile (".*FreeBSD 8.*amd64.*")
self._osFreeBSD8x_64 = re.compile (".*FreeBSD 8.*x86_64.*")
self._osFreeBSD8x = re.compile (".*FreeBSD 8.*")
self._osDarwin = re.compile (".*Darwin.*")
uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE )
lines = uname.stdout.readlines()
if self._osSlsoc6x_64.match(lines[0]):
self._osType = "Linux.slsoc6x_64"
self._libSuffix = "64"
elif self._osSlsoc6x .match(lines[0]): self._osType = "Linux.slsoc6x"
elif self._osSLSoC5x_64.match(lines[0]):
self._osType = "Linux.SLSoC5x_64"
self._libSuffix = "64"
elif self._osSLSoC5x .match(lines[0]): self._osType = "Linux.SLSoC5x"
elif self._osLinux_64 .match(lines[0]):
self._osType = "Linux.x86_64"
self._libSuffix = "64"
elif self._osLinux .match(lines[0]): self._osType = "Linux.i386"
elif self._osDarwin .match(lines[0]): self._osType = "Darwin"
elif self._osFreeBSD8x_amd64.match(lines[0]):
self._osType = "FreeBSD.8x.amd64"
self._libSuffix = "64"
elif self._osFreeBSD8x_64.match(lines[0]):
self._osType = "FreeBSD.8x.x86_64"
self._libSuffix = "64"
elif self._osFreeBSD8x .match(lines[0]): self._osType = "FreeBSD.8x.i386"
else:
uname = subprocess.Popen ( ["uname", "-sr"], stdout=subprocess.PIPE )
self._osType = uname.stdout.readlines()[0][:-1]
print "[WARNING] Unrecognized OS: \"%s\"." % lines[0][:-1]
print " (using: \"%s\")" % self._osType
return
def getPrimaryIds ( self ): return Configuration.PrimaryNames
def getSecondaryIds ( self ): return Configuration.SecondaryNames
def getAllIds ( self ): return Configuration.PrimaryNames + Configuration.SecondaryNames
def register ( self, project ):
for registered in self._projects:
if registered.getName() == project.getName():
print ErrorMessage( 0, "Project \"%s\" is already registered (ignored)." )
return
self._projects += [ project ]
return
def getProject ( self, name ):
for project in self._projects:
if project.getName() == name:
return project
return None
def getToolProject ( self, name ):
for project in self._projects:
if project.hasTool(name):
return project
return None
def load ( self, confFile ):
moduleGlobals = globals()
if not confFile:
print 'Making an educated guess to locate the configuration file:'
locations = [ os.path.abspath(os.path.dirname(sys.argv[0]))
, os.environ['HOME']+'/coriolis-2.x/src/bootstrap'
, os.environ['HOME']+'/coriolis/src/bootstrap'
, os.environ['HOME']+'/chams-2.x/src/bootstrap'
, os.environ['HOME']+'/chams/src/bootstrap'
, '/users/outil/coriolis/coriolis-2.x/src/bootstrap'
, self._rootDir+'/src/bootstrap'
]
for location in locations:
self._confFile = location + '/build.conf'
print ' <%s>' % self._confFile
if os.path.isfile(self._confFile): break
if not self._confFile:
ErrorMessage( 1, 'Cannot locate any configuration file.' ).terminate()
else:
print 'Using user-supplied configuration file:'
print ' <%s>' % confFile
self._confFile = confFile
if not os.path.isfile(self._confFile):
ErrorMessage( 1, 'Missing configuration file:', '<%s>'%self._confFile ).terminate()
print 'Reading configuration from:'
print ' <%s>' % self._confFile
try:
execfile( self._confFile, moduleGlobals )
except Exception, e:
ErrorMessage( 1, 'An exception occured while loading the configuration file:'
, '<%s>\n' % (self._confFile)
, 'You should check for simple python errors in this file.'
, 'Error was:'
, '%s\n' % e ).terminate()
if moduleGlobals.has_key('projects'):
entryNb = 0
for entry in moduleGlobals['projects']:
entryNb += 1
if not entry.has_key('name'):
raise ErrorMessage( 1, 'Missing project name in project entry #%d.' % entryNb )
if not entry.has_key('tools'):
raise ErrorMessage( 1, 'Missing tools list in project entry #%d (<%s>).' \
% (entryNb,entry['name']) )
if not isinstance(entry['tools'],list):
raise ErrorMessage( 1, 'Tools item of project entry #%d (<%s>) is not a list.' \
% (entryNb,entry['name']) )
if not entry.has_key('repository'):
raise ErrorMessage( 1, 'Missing project repository in project entry #%d.' \
% entryNb )
self.register( Project(entry['name'],entry['tools'],entry['repository']) )
else:
ErrorMessage( 1, 'Configuration file is missing the \'project\' symbol.'
, '<%s>'%self._confFile ).terminate()
if moduleGlobals.has_key('projectdir'):
self.projectDir = moduleGlobals['projectdir']
if moduleGlobals.has_key('svnconfig'):
svnconfig = moduleGlobals['svnconfig']
if svnconfig.has_key('method'): self._svnMethod = svnconfig['method']
if moduleGlobals.has_key('package'):
package = moduleGlobals['package']
if package.has_key('name' ): self.packageName = package['name']
if package.has_key('version' ): self.packageVersion = package['version']
if package.has_key('excludes'):
if not isinstance(package['excludes'],list):
raise ErrorMessage( 1, 'Excludes of package configuration is not a list.')
self._packageExcludes = package['excludes']
if package.has_key('projects'):
if not isinstance(package['projects'],list):
raise ErrorMessage( 1, 'Projects to package is not a list.')
self._packageProjects = package['projects']
return
def show ( self ):
print 'CCB Configuration:'
if self._svnMethod:
print ' SVN Method: <%s>' % self._svnMethod
else:
print ' SVN Method not defined, will not be able to checkout/commit.'
for project in self._projects:
print ' project:%-15s repository:<%s>' % ( ('<%s>'%project.getName()), project.getRepository() )
toolOrder = 1
for tool in project.getTools():
print '%s%02d:<%s>' % (' '*26,toolOrder,tool)
toolOrder += 1
print
return

View File

@ -0,0 +1,195 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Author : Damien Dupuis |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./builder/ConfigureWidget.py" |
# +-----------------------------------------------------------------+
from PyQt4.QtCore import Qt
from PyQt4.QtCore import QVariant
from PyQt4.QtCore import pyqtSignal
from PyQt4.QtCore import QSettings
from PyQt4.QtGui import QFont
from PyQt4.QtGui import QWidget
from PyQt4.QtGui import QGridLayout
from PyQt4.QtGui import QHBoxLayout
from PyQt4.QtGui import QVBoxLayout
from PyQt4.QtGui import QLabel
from PyQt4.QtGui import QPushButton
from PyQt4.QtGui import QLineEdit
from PyQt4.QtCore import QModelIndex
from PyQt4.QtCore import QAbstractTableModel
from PyQt4.QtGui import QAbstractItemView
from PyQt4.QtGui import QHeaderView
from PyQt4.QtGui import QTableView
from PyQt4.QtGui import QGroupBox
from PyQt4.QtGui import QFileDialog
from PyQt4.QtGui import QApplication
from Configuration import Configuration
class ConfSettingsModel ( QAbstractTableModel ):
HeaderFont = QApplication.font()
PrimaryFont = QFont('Courier',HeaderFont.pointSize()-2,QFont.Normal)
SecondaryFont = QFont('Courier',HeaderFont.pointSize()-2,QFont.Normal)
ValueFont = QFont('Courier',HeaderFont.pointSize()-2,QFont.Bold)
def __init__ ( self, conf, parent=None ):
ConfSettingsModel.HeaderFont.setBold( True )
ConfSettingsModel.SecondaryFont.setItalic( True )
QAbstractTableModel.__init__( self, parent )
self._conf = conf
self._ids = self._conf.getAllIds()
return
def data ( self, index, role ):
if role == Qt.SizeHintRole:
if index.column() == 0: return 300
else: return -1
elif role == Qt.FontRole:
if index.column() == 0:
if index.row() >= len(self._conf.getPrimaryIds()):
return ConfSettingsModel.SecondaryFont
return ConfSettingsModel.PrimaryFont
else:
return ConfSettingsModel.ValueFont
elif role == Qt.DisplayRole:
row = index.row()
if row < self.rowCount():
if index.column() == 0: return self._ids[row]
elif index.column() == 1: return getattr( self._conf, self._ids[row] )
return QVariant()
def headerData ( self, section, orientation, role ):
if orientation == Qt.Vertical: return QVariant()
if role == Qt.FontRole: return ConfSettingsModel.HeaderFont
if role != Qt.DisplayRole: return QVariant()
if section == 0: return 'Setting'
elif section == 1: return 'Value'
return QVariant('?')
def rowCount ( self, index=QModelIndex() ): return len(self._ids)
def columnCount ( self, index=QModelIndex() ): return 2
class ConfSettingsWidget ( QWidget ):
def __init__ ( self, conf, parent=None ):
QWidget.__init__( self, parent )
self._rowHeight = 20
self._view = QTableView()
self._view.setShowGrid ( False )
self._view.setAlternatingRowColors( True )
self._view.setSelectionBehavior ( QAbstractItemView.SelectRows )
#self._view.setSortingEnabled ( True )
#self._view.installEventFilter ( self )
horizontalHeader = self._view.horizontalHeader ()
horizontalHeader.setStretchLastSection ( True )
horizontalHeader.setMinimumSectionSize ( 150 )
horizontalHeader.setResizeMode ( QHeaderView.ResizeToContents )
horizontalHeader.setDefaultSectionSize ( 150 )
verticalHeader = self._view.verticalHeader ();
verticalHeader.setVisible ( False );
verticalHeader.setDefaultSectionSize ( self._rowHeight );
self._baseModel = ConfSettingsModel( conf )
self._view.setModel( self._baseModel );
self._view.horizontalHeader().setStretchLastSection( True );
self._view.resizeColumnToContents( 0 );
peanoDataLayout = QGridLayout();
peanoDataLayout.addWidget( self._view, 0, 0, 1, 1 );
self.setLayout ( peanoDataLayout );
return
class ConfigureWidget ( QWidget ):
def __init__ ( self, confFile, parent=None ):
QWidget.__init__ ( self, parent )
self._confFile = confFile
self._conf = Configuration()
self._rootDir = ''
rootDirLabel = QLabel( 'Root Directory' )
rootDirBrowse = QPushButton( '&Browse' )
rootDirBrowse.clicked.connect( self.browseRootDir )
self._rootDirEdit = QLineEdit( '' )
#self._rootDirEdit.setFixedWidth( 600 )
gLayout = QGridLayout()
gLayout.addWidget( rootDirLabel , 0, 0, 1, 1 )
gLayout.addWidget( self._rootDirEdit, 0, 1, 1, 6 )
gLayout.addWidget( rootDirBrowse , 0, 7, 1, 1 )
groupDirs = QGroupBox( 'Directories' )
groupDirs.setLayout( gLayout )
gLayout = QGridLayout()
groupConf = QGroupBox( 'Configuration' )
groupConf.setLayout( gLayout )
vLayout = QVBoxLayout()
vLayout.addWidget ( groupDirs )
vLayout.addWidget ( groupConf )
#vLayout.addStretch()
self.setLayout( vLayout )
self._rootDirEdit.textChanged.connect( self.rootDirChanged )
self.readSettings()
noteLabel = QLabel( 'Those settings can be changed only by editing build.conf' )
gLayout.addWidget( noteLabel , 0, 0, 1, 1 )
gLayout.addWidget( ConfSettingsWidget(self._conf), 1, 0, 1, 1 )
def _getRootDir ( self ): return self._rootDir
def _getConf ( self ): return self._conf
rootDir = property( _getRootDir )
conf = property( _getConf )
def rootDirChanged ( self, rootDir ):
self._rootDir = rootDir
return
def browseRootDir ( self ):
self._rootDirEdit.setText( QFileDialog.getExistingDirectory(self,'Select the Building Root Directory') )
return
def readSettings ( self ):
settings = QSettings()
self._rootDirEdit.setText( settings.value('conf/rootDir').toString() )
if not self._confFile and settings.value('conf/confFile'):
self._confFile = str( settings.value('conf/confFile').toString() )
self._conf.load( self._confFile )
return
def saveSettings ( self ):
settings = QSettings()
settings.setValue( 'conf/rootDir' , self._rootDirEdit.text() )
settings.setValue( 'conf/confFile', self._confFile )
return

View File

@ -0,0 +1,80 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Author : Damien Dupuis |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./builder/Highlighter.py" |
# +-----------------------------------------------------------------+
import re
from PyQt4.QtCore import Qt
from PyQt4.QtGui import QFont
from PyQt4.QtGui import QColor
from PyQt4.QtGui import QTextCharFormat
from PyQt4.QtGui import QSyntaxHighlighter
class Highlighter ( QSyntaxHighlighter ):
Normal = 0x0001
Bold = 0x0002
Italic = 0x0004
ttyBackground = QColor.fromRgb( 255, 255, 221 ) # #ffffdd
ttyBlack = QColor.fromRgb( 46, 52, 54 ) # #2e3436
ttyRed = QColor.fromRgb( 204, 0, 0 ) # #cc0000
ttyGreen = QColor.fromRgb( 78, 154, 6 ) # #4e9a06
ttyYellow = QColor.fromRgb( 196, 160, 0 ) # #c4a000
ttyBlue = QColor.fromRgb( 52, 101, 164 ) # #3465a4
ttyViolet = QColor.fromRgb( 117, 80, 123 ) # #75507b
ttyCyan = QColor.fromRgb( 6, 152, 154 ) # #06989a
ttyGrey = QColor.fromRgb( 211, 215, 207 ) # #d3d7cf
ttyLightBlack = QColor.fromRgb( 85, 87, 83 ) # #555753
ttyLightRed = QColor.fromRgb( 239, 41, 41 ) # #ef2929
ttyLightGreen = QColor.fromRgb( 138, 226, 52 ) # #8ae234
ttyLightYellow = QColor.fromRgb( 252, 233, 79 ) # #fce94f
ttyLightBlue = QColor.fromRgb( 114, 159, 207 ) # #729fcf
ttyLightViolet = QColor.fromRgb( 173, 127, 168 ) # #ad7fa8
ttyLightCyan = QColor.fromRgb( 52, 226, 226 ) # #34e2e2
ttyLightGrey = QColor.fromRgb( 238, 238, 236 ) # #eeeeec
Rules = [ [ttyLightViolet, Bold , re.compile(r'^Scanning.*'), None]
, [ttyLightRed , Bold , re.compile(r'^Linking.*'), None]
, [ttyLightGreen , Normal , re.compile(r'^\[(?P<percent>\s*\d+)%\]\s*(?P<message>Building.*)'), None]
, [ttyLightGreen , Bold , re.compile(r'^\[(?P<percent>\s*\d+)%\]\s*(?P<message>Built target.*)'), None]
, [ttyLightBlue , Normal , re.compile(r'^\[(?P<percent>\s*\d+)%\]\s*(?P<message>Generating.*moc_.*)'), None]
, [ttyLightBlue , Bold , re.compile(r'^Generating.*'), None]
, [ttyLightCyan , Normal , re.compile(r'^Install the project.*'), None]
, [ttyCyan , Bold , re.compile(r'^-- Install.*'), None]
, [ttyCyan , Bold|Italic, re.compile(r'^-- Up-to-date.*'), None]
]
def __init__ ( self, parent=None ):
QSyntaxHighlighter.__init__ ( self, parent )
for rule in Highlighter.Rules:
if not rule[3]:
rule[3] = QTextCharFormat()
rule[3].setForeground( rule[0] )
if rule[1] & Highlighter.Normal: rule[3].setFontWeight( QFont.Normal )
if rule[1] & Highlighter.Bold: rule[3].setFontWeight( QFont.Bold )
if rule[1] & Highlighter.Italic: rule[3].setFontItalic( True )
return
def highlightBlock ( self, line ):
for rule in Highlighter.Rules:
m = rule[2].match(line)
if m:
if m.groupdict().has_key('percent'):
self.setFormat( 7, len(line), rule[3] )
else:
self.setFormat( 0, len(line), rule[3] )
return

View File

@ -0,0 +1,179 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Author : Damien Dupuis |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./builder/OptionsWidget.py" |
# +-----------------------------------------------------------------+
import re
import subprocess
from PyQt4.QtCore import Qt
from PyQt4.QtCore import pyqtSignal
from PyQt4.QtCore import QSettings
from PyQt4.QtGui import QColor
from PyQt4.QtGui import QWidget
from PyQt4.QtGui import QPushButton
from PyQt4.QtGui import QCheckBox
from PyQt4.QtGui import QGroupBox
from PyQt4.QtGui import QButtonGroup
from PyQt4.QtGui import QVBoxLayout
from PyQt4.QtGui import QHBoxLayout
from PyQt4.QtGui import QGridLayout
from PyQt4.QtGui import QScrollArea
from PyQt4.QtGui import QComboBox
from builder.Project import Project
from builder.ConfigureWidget import ConfigureWidget
from builder.ProjectWidgets import ProjectWidgets
class OptionsWidget ( QWidget ):
progress = pyqtSignal(int)
def __init__ ( self, conf, parent=None ):
QWidget.__init__ ( self, parent )
self._conf = conf
self._projects = []
for project in self._conf.projects:
self._projects += [ ProjectWidgets(project) ]
gLayout = QGridLayout()
for column in range(len(self._projects)):
self._projects[column].addToLayout( column, gLayout )
toolsGroup = QGroupBox( 'Projects && Tools' )
toolsGroup.setLayout( gLayout )
scrollToolsGroup = QScrollArea()
scrollToolsGroup.setMinimumHeight( 400 )
#scrollToolsGroup.setVerticalScrollBarPolicy( Qt.ScrollBarAlwaysOn )
scrollToolsGroup.setWidget( toolsGroup )
self._buildMode = QComboBox()
self._buildMode.addItems( ('Release', 'Debug') )
self._svnUpdate = QCheckBox( 'SVN Update' )
self._svnStatus = QCheckBox( 'SVN Status' )
self._make = QCheckBox( 'Build' )
self._enableDoc = QCheckBox( 'Build Documentation' )
self._noCache = QCheckBox( 'Remove previous CMake cache' )
self._rmBuild = QCheckBox( 'Cleanup Build Directory' )
self._verbose = QCheckBox( 'Display Compiler Commands' )
self._threads = QComboBox()
for j in range(16):
self._threads.addItem( '-j%d'%(j+1), j+1 )
self._commandGroup = QButtonGroup()
self._commandGroup.setExclusive( True )
self._commandGroup.addButton( self._svnUpdate )
self._commandGroup.addButton( self._svnStatus )
self._commandGroup.addButton( self._make )
vLayout = QVBoxLayout()
vLayout.addWidget( self._svnUpdate )
vLayout.addWidget( self._svnStatus )
vLayout.addWidget( self._make )
vLayout.addStretch()
commandGroup = QGroupBox( 'Command' )
commandGroup.setLayout( vLayout )
vLayout = QVBoxLayout()
vLayout.addWidget( self._buildMode )
vLayout.addWidget( self._enableDoc )
vLayout.addWidget( self._noCache )
vLayout.addWidget( self._rmBuild )
vLayout.addStretch()
optionsGroup = QGroupBox( 'Command Options' )
optionsGroup.setLayout( vLayout )
vLayout = QVBoxLayout()
vLayout.addWidget( self._threads )
vLayout.addWidget( self._verbose )
vLayout.addStretch()
miscGroup = QGroupBox( 'Misc. Options' )
miscGroup.setLayout( vLayout )
hLayout = QHBoxLayout()
hLayout.addWidget( commandGroup )
hLayout.addWidget( optionsGroup )
hLayout.addWidget( miscGroup )
commands = QWidget()
commands.setLayout( hLayout )
vLayout = QVBoxLayout()
vLayout.addWidget( commands )
vLayout.addWidget( scrollToolsGroup )
vLayout.addStretch()
self.setLayout( vLayout )
self.readSettings()
return
def _getProjects ( self ): return self._projects
def _getBuildMode ( self ): return self._buildMode.currentText()
def _getThreads ( self ): return self._threads.currentText()
def _getSvnUpdate ( self ): return self._svnUpdate.isChecked()
def _getSvnStatus ( self ): return self._svnStatus.isChecked()
def _getMake ( self ): return self._make.isChecked()
def _getEnableDoc ( self ): return self._enableDoc.isChecked()
def _getNoCache ( self ): return self._noCache.isChecked()
def _getRmBuild ( self ): return self._rmBuild.isChecked()
def _getVerbose ( self ): return self._verbose.isChecked()
projects = property( _getProjects )
buildMode = property( _getBuildMode )
threads = property( _getThreads )
svnUpdate = property( _getSvnUpdate )
svnStatus = property( _getSvnStatus )
make = property( _getMake )
enableDoc = property( _getEnableDoc )
noCache = property( _getNoCache )
rmBuild = property( _getRmBuild )
verbose = property( _getVerbose )
def readSettings ( self ):
settings = QSettings()
self._svnUpdate.setChecked( settings.value('builder/svnUpdate').toBool() )
self._svnStatus.setChecked( settings.value('builder/svnStatus').toBool() )
self._make .setChecked( settings.value('builder/make' ).toBool() )
self._enableDoc.setChecked( settings.value('builder/enableDoc').toBool() )
self._noCache .setChecked( settings.value('builder/noCache' ).toBool() )
self._rmBuild .setChecked( settings.value('builder/rmBuild' ).toBool() )
self._verbose .setChecked( settings.value('builder/verbose' ).toBool() )
buildModeName = settings.value('builder/buildMode').toString()
index = self._buildMode.findText( buildModeName )
if index >= 0: self._buildMode.setCurrentIndex( index )
threads = settings.value('builder/threads').toString()
index = self._threads.findText( threads )
if index >= 0: self._threads.setCurrentIndex( index )
for project in self._projects: project.readFromSettings()
return
def saveSettings ( self ):
settings = QSettings()
settings.setValue('builder/svnUpdate', self._svnUpdate.isChecked() )
settings.setValue('builder/svnStatus', self._svnStatus.isChecked() )
settings.setValue('builder/make' , self._make .isChecked() )
settings.setValue('builder/enableDoc', self._enableDoc.isChecked() )
settings.setValue('builder/buildMode', self._buildMode.currentText() )
settings.setValue('builder/noCache' , self._noCache .isChecked() )
settings.setValue('builder/rmBuild' , self._rmBuild .isChecked() )
settings.setValue('builder/verbose' , self._verbose .isChecked() )
settings.setValue('builder/threads' , self._threads .currentText() )
for project in self._projects: project.saveToSettings()
return

View File

@ -0,0 +1,51 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Author : Jean-Paul Chaput |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./builder/Project.py" |
# +-----------------------------------------------------------------+
class Project ( object ):
def __init__ ( self, name, tools, repository ):
self._name = name
self._tools = tools
self._repository = repository
self._actives = []
return
def getName ( self ): return self._name
def getTools ( self ): return self._tools
def getRepository ( self ): return self._repository
def getActives ( self ): return self._actives
def hasTool ( self, tool ): return tool in self._tools
def desactivate ( self ):
self._active = []
return
def activateAll ( self ):
self._actives = self._tools
return
def activate ( self, tools ):
# Build the ordered list.
for tool in self._tools:
if (tool in tools) and not (tool in self._actives):
self._actives += [ tool ]
# Find the tools not part of the project.
rejecteds = []
for tool in tools:
if not (tool in self._tools) and (not tool in rejecteds):
rejecteds += [ tool ]
return rejecteds

View File

@ -0,0 +1,76 @@
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC/LIP6 2012-2012, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Author : Jean-Paul Chaput |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./builder/ProjectWidget.py" |
# +-----------------------------------------------------------------+
from PyQt4.QtCore import Qt
from PyQt4.QtCore import QObject
from PyQt4.QtCore import QSettings
from PyQt4.QtGui import QPushButton
from PyQt4.QtGui import QCheckBox
class ProjectWidgets ( QObject ):
def __init__ ( self, project ):
self._project = project
self._projectButton = QPushButton( self._project.getName() )
self._projectButton.setStyleSheet( 'font-weight: bold;' )
self._toolsCheckBoxes = []
for tool in self._project.getTools():
self._toolsCheckBoxes += [ QCheckBox( tool ) ]
#self._projectButton.clicked.connect( self.toggleToolsVisibility )
return
def _getProjectButton ( self ): return self._projectButton
def _getToolsCheckBoxes ( self ): return self._toolsCheckBoxes
def _getActives ( self ):
actives = []
for toolCb in self._toolsCheckBoxes:
if toolCb.isChecked(): actives += [ str(toolCb.text()) ]
return actives
projectButton = property( _getProjectButton )
toolsCheckBoxes = property( _getToolsCheckBoxes )
actives = property( _getActives )
def addToLayout( self, column, layout ):
layout.addWidget( self._projectButton, 0, column, Qt.AlignLeft )
for row in range(len(self._toolsCheckBoxes)):
layout.addWidget( self._toolsCheckBoxes[row], row+1, column, Qt.AlignTop )
return
#def toggleToolsVisibility ( self ):
# self._visibleTools = not self._visibleTools
# for toolCb in self._toolsCheckBoxes:
# toolCb.setVisible( self._visibleTools )
# return
def readFromSettings ( self ):
settings = QSettings()
for toolCb in self._toolsCheckBoxes:
toolId = 'tools/'+self._project.getName()+'/'+toolCb.text()
toolCb.setChecked( settings.value(toolId).toBool() )
return
def saveToSettings ( self ):
settings = QSettings()
for toolCb in self._toolsCheckBoxes:
toolId = 'tools/'+self._project.getName()+'/'+toolCb.text()
settings.setValue( toolId, toolCb.isChecked() )
return

View File

@ -0,0 +1,64 @@
# -*- mode:Python -*-
import sys
class ErrorMessage ( Exception ):
def __init__ ( self, code, *arguments ):
self._code = code
self._errors = [ 'Malformed call to ErrorMessage()'
, '%s' % str(arguments) ]
text = None
if len(arguments) == 1:
if isinstance(arguments[0],Exception): text = str(arguments[0]).split('\n')
else:
self._errors = arguments[0]
elif len(arguments) > 1:
text = list(arguments)
if text:
self._errors = []
while len(text[0]) == 0: del text[0]
lstrip = 0
if text[0].startswith('[ERROR]'): lstrip = 8
for line in text:
if line[0:lstrip ] == ' '*lstrip or \
line[0:lstrip-1] == '[ERROR]':
self._errors += [ line[lstrip:] ]
else:
self._errors += [ line.lstrip() ]
return
def __str__ ( self ):
if not isinstance(self._errors,list):
return "[ERROR] %s" % self._errors
formatted = "\n"
for i in range(len(self._errors)):
if i == 0: formatted += "[ERROR] %s" % self._errors[i]
else: formatted += " %s" % self._errors[i]
if i+1 < len(self._errors): formatted += "\n"
return formatted
def addMessage ( self, message ):
if not isinstance(self._errors,list):
self._errors = [ self._errors ]
if isinstance(message,list):
for line in message:
self._errors += [ line ]
else:
self._errors += [ message ]
return
def terminate ( self ):
print self
sys.exit(self._code)
def _getCode ( self ): return self._code
code = property(_getCode)

256
bootstrap/ccb.py Executable file
View File

@ -0,0 +1,256 @@
#!/usr/bin/env python
#
# -*- mode:Python -*-
#
# This file is part of the Coriolis Software.
# Copyright (c) UPMC/LIP6 2008-2012, All Rights Reserved
#
# +-----------------------------------------------------------------+
# | C O R I O L I S |
# | C o r i o l i s / C h a m s B u i l d e r |
# | |
# | Authors : Jean-Paul Chaput |
# | Damien Dupuis |
# | E-mail : Jean-Paul.Chaput@asim.lip6.fr |
# | =============================================================== |
# | Python : "./ccb.py" |
# +-----------------------------------------------------------------+
showTrace = True
try:
import sys
import os.path
import optparse
import traceback
import distutils.sysconfig
import subprocess
import re
except ImportError, e:
module = str(e).split()[-1]
print '[ERROR] The <%s> python module or symbol cannot be loaded.' % module
print ' Please check your standard Python installation, it may have problems.'
quit()
def safeImport ( moduleName, symbol=None ):
try:
module = __import__( moduleName, globals(), locals(), symbol )
except ImportError, e:
print '[ERROR] The <%s> python module or symbol cannot be loaded.' % moduleName
print ' Please check the integrity of the <coriolis/boostrap> package.'
if showTrace: traceback.print_tb(sys.exc_info()[2])
sys.exit(1)
except Exception, e:
print '[ERROR] An exception occured while importing module <%s>. Is is a bug,' % moduleName
print ' you may want to report it...'
print ' %s' % e
if showTrace: traceback.print_tb(sys.exc_info()[2])
sys.exit(2)
if symbol: return module.__dict__[symbol]
return module
def guessOs ():
libDir = 'lib'
osSlsoc6x_64 = re.compile (".*Linux.*el6.*x86_64.*")
osSlsoc6x = re.compile (".*Linux.*el6.*")
osSLSoC5x_64 = re.compile (".*Linux.*el5.*x86_64.*")
osSLSoC5x = re.compile (".*Linux.*(el5|2.6.23.13.*SoC).*")
osLinux_64 = re.compile (".*Linux.*x86_64.*")
osLinux = re.compile (".*Linux.*")
osFreeBSD8x_amd64 = re.compile (".*FreeBSD 8.*amd64.*")
osFreeBSD8x_64 = re.compile (".*FreeBSD 8.*x86_64.*")
osFreeBSD8x = re.compile (".*FreeBSD 8.*")
osDarwin = re.compile (".*Darwin.*")
uname = subprocess.Popen ( ["uname", "-srm"], stdout=subprocess.PIPE )
lines = uname.stdout.readlines()
if osSlsoc6x_64.match(lines[0]):
osType = "Linux.slsoc6x_64"
libDir = "lib64"
elif osSlsoc6x .match(lines[0]): osType = "Linux.slsoc6x"
elif osSLSoC5x_64.match(lines[0]):
osType = "Linux.SLSoC5x_64"
libDir = "lib64"
elif osSLSoC5x .match(lines[0]): osType = "Linux.SLSoC5x"
elif osLinux_64.match(lines[0]):
osType = "Linux.x86_64"
libDir = "lib64"
elif osLinux .match(lines[0]): osType = "Linux.i386"
elif osDarwin.match(lines[0]): osType = "Darwin"
elif osFreeBSD8x_amd64.match(lines[0]):
osType = "FreeBSD.8x.amd64"
libDir = "lib64"
elif osFreeBSD8x_64.match(lines[0]):
osType = "FreeBSD.8x.x86_64"
libDir = "lib64"
elif osFreeBSD8x.match(lines[0]):
osType = "FreeBSD.8x.i386"
else:
uname = subprocess.Popen ( ["uname", "-sr"], stdout=subprocess.PIPE )
osType = uname.stdout.readlines()[0][:-1]
print "[WARNING] Unrecognized OS: \"%s\"." % lines[0][:-1]
print " (using: \"%s\")" % osType
return osType, libDir
def guessPythonSitePackage ():
pathes = distutils.sysconfig.get_python_lib().split('/')[-2:]
return os.path.join( pathes[0], pathes[1] )
def autoLocate ():
print 'Making an educated guess to locate myself:'
sitePackage = guessPythonSitePackage()
osType, libDir = guessOs()
builderDir = None
locations = [ os.path.abspath(os.path.dirname(sys.argv[0]))
, os.environ['HOME']+'/coriolis-2.x/src/bootstrap'
, os.environ['HOME']+'/coriolis/src/bootstrap'
, os.environ['HOME']+'/chams-1.x/src/bootstrap'
, os.environ['HOME']+'/chams/src/bootstrap'
, '/users/outil/coriolis/coriolis-2.x/src/bootstrap'
, os.environ['HOME']+'/coriolis-2.x/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage
, os.environ['HOME']+'/chams-1.x/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage
, os.environ['HOME']+'/chams/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage
, '/users/outil/coriolis/coriolis-2.x/'+osType+'/Release.Shared/install/'+libDir+'/'+sitePackage
]
for location in locations:
print ' <%s>' % location,
if os.path.isfile(location + '/builder/__init__.py'):
if not builderDir:
builderDir = location
print '(Found*)'
else:
print '(Found)'
else:
print '(No)'
if not builderDir:
print '[ERROR] Failed to locate the builder modules in any of the normal pathes.'
print ' Please check your Coriolis/Bootsrap installation.'
if showTrace: traceback.print_tb(sys.exc_info()[2])
sys.exit(1)
sys.path.insert( 0, builderDir )
return
# -------------------------------------------------------------------
# CCB Main Part.
autoLocate()
parser = optparse.OptionParser ()
parser.add_option ( "-g", "--gui" , action="store_true" , dest="gui" , help="Lauch the graphical interface." )
# Build relateds.
parser.add_option ( "-c", "--conf", type="string", dest="conf" , help="Fichier de configuration." )
parser.add_option ( "--show-conf" , action="store_true" , dest="showConf" , help="Display the Project/Tools configuration, then exit." )
parser.add_option ( "-q", "--quiet" , action="store_true" , dest="quiet" , help="Do not print all the informative messages." )
parser.add_option ( "-r", "--release" , action="store_true" , dest="release" , help="Build a <Release> aka optimized version." )
parser.add_option ( "-d", "--debug" , action="store_true" , dest="debug" , help="Build a <Debug> aka (-g) version." )
parser.add_option ( "-s", "--static" , action="store_true" , dest="static" , help="Try to link statically, as much as possible." )
parser.add_option ( "--doc" , action="store_true" , dest="doc" , help="Enable the documentation building (uses with -j1)." )
parser.add_option ( "-v", "--verbose" , action="store_true" , dest="verboseMakefile" , help="Tells CMake to print all compilation commands." )
parser.add_option ( "--root" , action="store" , type="string", dest="rootDir" , help="The root directory (default: <~/coriolis-2.x/>)." )
parser.add_option ( "--no-build" , action="store_true" , dest="noBuild" , help="Do *not* build anything (by default: build)." )
parser.add_option ( "--no-cache" , action="store_true" , dest="noCache" , help="Remove previous CMake cache before building." )
parser.add_option ( "--rm-build" , action="store_true" , dest="rmBuild" , help="Remove previous build directoty before building." )
parser.add_option ( "--make" , action="store" , type="string", dest="makeArguments", help="Arguments to pass to make (ex: \"-j4 install\")." )
parser.add_option ( "--project" , action="append" , type="string", dest="projects" , help="The name of a project to build (may appears any number of time)." )
parser.add_option ( "-t", "--tool" , action="append" , type="string", dest="tools" , help="The name of a tool to build (may appears any number of time)." )
# SVN repository relateds.
parser.add_option ( "--svn-tag" , action="store" , type="string", dest="svnTag" , help="Explicitly select a SVN tag (for SVN related commands)." )
parser.add_option ( "--svn-method" , action="store" , type="string", dest="svnMethod" , help="Allows to sets the svn checkout method (svn+ssh://coriolis.soc.lip6.fr)." )
parser.add_option ( "--svn-status" , action="store_true" , dest="svnStatus" , help="Check status against the SVN repository." )
parser.add_option ( "--svn-diff" , action="store_true" , dest="svnDiff" , help="Perform a diff against the SVN repository." )
parser.add_option ( "--svn-update" , action="store_true" , dest="svnUpdate" , help="Update to the latest SVN version *or* the one given by svn-tag." )
parser.add_option ( "--svn-checkout" , action="store_true" , dest="svnCheckout", help="Checkout the latest SVN version *or* the one given by svn-tag." )
# Miscellaneous.
parser.add_option ( "--user-tarball" , action="store_true" , dest="userTarball", help="Regenerate a tarball from checked out sources (in <root>/tarball/." )
parser.add_option ( "--tarball" , action="store_true" , dest="tarball" , help="Regenerate a tarball (in <root>/tarball/." )
parser.add_option ( "--rpm" , action="store_true" , dest="doRpm" , help="Regenerate RPM packages." )
parser.add_option ( "--deb" , action="store_true" , dest="doDeb" , help="Regenerate Debian/Ubuntu packages." )
# Katabatic/Kite specific options.
parser.add_option ( "-D", "--check-db" , action="store_true" , dest="checkDb" , help="Enable Katabatic/Kite data-base checking (*very* slow)." )
parser.add_option ( "-u", "--check-deter", action="store_true" , dest="checkDeterminism", help="Enable Katabatic/Kite determinism checking (*very* slow)." )
(options, args) = parser.parse_args ()
if options.gui:
ErrorMessage = safeImport( 'builder' , 'ErrorMessage' )
QApplication = safeImport( 'PyQt4.QtGui' , 'QApplication' )
BuilderGui = safeImport( 'builder.BuilderGui', 'BuilderGui' )
try:
app = QApplication( sys.argv )
app.setOrganizationName ( 'UPMC' )
app.setOrganizationDomain( 'lip6.fr' )
app.setApplicationName ( 'CoriolisBuilder' )
gui = BuilderGui( options.conf )
gui.show()
rcode = app.exec_()
sys.exit( rcode )
except ErrorMessage, e:
print e
if showTrace: traceback.print_tb(sys.exc_info()[2])
sys.exit(2)
except Exception, e:
print '[ERROR] An exception occured while running the Qt application.'
print ' %s' % e
if showTrace: traceback.print_tb(sys.exc_info()[2])
sys.exit(2)
else:
ErrorMessage = safeImport( 'builder' , 'ErrorMessage' )
Builder = safeImport( 'builder.Builder', 'Builder' )
try:
builder = Builder()
builder.loadConfiguration( options.conf )
if options.showConf:
builder.showConfiguration ()
sys.exit(0)
if options.quiet: builder.quiet = True
if options.release: builder.buildMode = "Release"
if options.debug: builder.buildMode = "Debug"
if options.static: builder.enableShared = "OFF"
if options.doc: builder.enableDoc = "ON"
if options.checkDb: builder.checkDatabase = "ON"
if options.checkDeterminism: builder.enableDeterminism = "ON"
if options.verboseMakefile: builder.verboseMakefile = "ON"
if options.rootDir: builder.rootDir = options.rootDir
if options.noBuild: builder.doBuild = False
if options.noCache: builder.noCache = True
if options.rmBuild: builder.rmBuild = True
if options.makeArguments: builder.makeArguments = options.makeArguments
if options.svnMethod: builder.svnMethod = options.svnMethod
if options.svnTag: builder.svnTag = options.svnTag
if options.svnStatus: builder.svnStatus ( tools=options.tools, projects=options.projects )
elif options.svnUpdate: builder.svnUpdate ( tools=options.tools, projects=options.projects )
elif options.svnDiff: builder.svnDiff ( tools=options.tools, projects=options.projects )
elif options.svnCheckout: builder.svnCheckout ( tools=options.tools, projects=options.projects )
elif options.userTarball: builder.userTarball ( tools=options.tools, projects=options.projects )
elif options.tarball: builder.svnTarball ( tools=options.tools, projects=options.projects )
elif options.doRpm: builder.doRpm ()
elif options.doDeb: builder.doDeb ()
else: builder.build ( tools=options.tools, projects=options.projects )
except ErrorMessage, e:
print e
if showTrace: traceback.print_tb(sys.exc_info()[2])
sys.exit(e.code)
except KeyboardInterrupt, e:
print '\n[ERROR] Interrupted by user\'s request (CTRL+C)'
sys.exit(1)
sys.exit(0)