[cig-commits] r7418 - in cs/buildbot/trunk/buildbot: . scripts
leif at geodynamics.org
leif at geodynamics.org
Sat Jun 23 02:51:49 PDT 2007
Author: leif
Date: 2007-06-23 02:51:49 -0700 (Sat, 23 Jun 2007)
New Revision: 7418
Added:
cs/buildbot/trunk/buildbot/cig.ico
Modified:
cs/buildbot/trunk/buildbot/scripts/packager.py
Log:
Mostly-working auto-generated Windows installer.
Added: cs/buildbot/trunk/buildbot/cig.ico
===================================================================
(Binary files differ)
Property changes on: cs/buildbot/trunk/buildbot/cig.ico
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Modified: cs/buildbot/trunk/buildbot/scripts/packager.py
===================================================================
--- cs/buildbot/trunk/buildbot/scripts/packager.py 2007-06-23 07:00:30 UTC (rev 7417)
+++ cs/buildbot/trunk/buildbot/scripts/packager.py 2007-06-23 09:51:49 UTC (rev 7418)
@@ -1,23 +1,112 @@
import os, sys, platform
from popen2 import Popen4
+from glob import glob
+from os.path import basename, dirname, isabs, isfile
from buildbot.meta import Config, getPackageAndVersion
-def pairUp(l):
- pairs = []
+class PackingList(object):
+ def __init__(self, config, opSys, python):
+ self.all = []
+ self.stripList = []
+ packingList = self.all
+ stripList = self.stripList
+
+ exe = ""
+ if opSys == "win":
+ exe = ".exe"
+ libglob = "bin/*%s*.dll"
+ elif opSys == "linux":
+ libglob = "lib/lib%s*.so*"
+ elif opSys == "darwin":
+ libglob = "lib/lib%s*.dylib"
+ else:
+ sys.exit("unknown OS: " + opSys)
+ self.exe = exe
+
+ self.directories = []
+ for d in config.packaging.directories:
+ packingList.append(d)
+ self.directories.append(d)
+
+ self.programs = []
+ for p in config.packaging.programs:
+ p = "bin/" + p + exe
+ packingList.append(p)
+ stripList.append(p)
+ self.programs.append(p)
+
+ self.scripts = []
+ for s in config.packaging.scripts:
+ s = "bin/" + s
+ packingList.append(s)
+ self.scripts.append(s)
+
+ self.libraries = []
+ for l in config.packaging.libraries:
+ if l == "mpi":
+ l = "mpich"
+ l = libglob % l
+ libs = glob(l)
+ packingList.extend(libs)
+ stripList.extend(libs)
+ self.libraries.extend(libs)
+
+ self.python = []
+ self.misc = []
+ for p in config.packaging.python:
+ p = "lib/" + python + "/site-packages/" + p
+ # Here we use glob expansion b/c eggs make the actual
+ # directory names hard to determine.
+ entries = glob(p)
+ packingList.extend(entries)
+ for e in entries:
+ if isfile(e):
+ self.misc.append(e)
+ else:
+ self.directories.append(e)
+
+ cig = [("CIG", "cig", "http://www.geodynamics.org/")]
+ self.urls = cig + tupleUp(config.packaging.urls, 3)
+
+ return
+
+
+ def addFile(self, f):
+ self.misc.append(f)
+
+ def addDirectory(self, d):
+ self.directories.append(d)
+
+
+ def files(self):
+ for f in self.programs:
+ yield f
+ for f in self.scripts:
+ yield f
+ for f in self.libraries:
+ yield f
+ for f in self.misc:
+ yield f
+ return
+
+
+def tupleUp(l, n):
+ tuples = []
i = iter(l)
try:
while True:
- x = i.next()
- y = i.next()
- pairs.append((x, y))
+ t = []
+ for count in xrange(n):
+ t.append(i.next())
+ tuples.append(tuple(t))
except StopIteration:
pass
- return pairs
+ return tuples
-def spawn(**cmd):
+def spawn(*cmd):
print ' '.join(cmd)
child = Popen4(cmd)
@@ -44,39 +133,157 @@
return output[0]
+def itwindirs(l):
+ for src in l:
+ if isabs(src):
+ dest = src[1:]
+ src = cygpath("-w", src)
+ else:
+ dest = src
+ src = src.replace("/", "\\")
+ dest = "{app}\\" + dest.replace("/", "\\")
+ yield src, dest
+ return
+
+
+def itwinfiles(l):
+ for f in l:
+ d = dirname(f)
+ f = f.replace("/", "\\")
+ d = d.replace("/", "\\")
+ yield f, d
+ return
+
+
+def installCigIcon(prefix):
+ import buildbot
+ cigIco = dirname(buildbot.__file__) + "/cig.ico"
+ os.system("cp %s %s" % (cigIco, prefix))
+ return
+
+
def generateBashrc(prefix, package, info):
- bashrc = "." package.lower() + "rc"
+ bashrc = "." + package.lower() + "rc"
s = open(prefix + "/" + bashrc, "w")
- bashrc = {
+ stuff = {
"line": "-" * len(info["AppVerName"]),
}
- bashrc.update(info)
+ stuff.update(info)
s.write(
-"""
+r"""
-export PATH=/bin:$PATH
+export PATH=/usr/bin:/bin:$PATH
echo %(line)s
echo %(AppVerName)s
echo %(line)s
PS1='\[\e]0;\w\a\]\n\[\e[32m\]\u@\h \[\e[33m\]\w\[\e[0m\]\n\$ '
-""" % bashrc
+""" % stuff
)
return bashrc
-def generateISS(info, config, bashrc, python):
+# Minimal set of Cygwin binaries, as determined while preparing for CFEM 2006.
+def minCygwin(python):
+ l = [
+ "[.exe",
+ "bash.exe",
+ "cat.exe",
+ "cp.exe",
+ "cygiconv-2.dll",
+ "cygintl-3.dll",
+ "cygintl-8.dll",
+ "cygncurses-8.dll",
+ "cygpath.exe",
+ "cygreadline6.dll",
+ # This is given special treatment.
+ #"cygwin1.dll",
+ "echo.exe",
+ "gunzip.exe",
+ "lib" + python + ".dll",
+ "ln.exe",
+ "ls.exe",
+ "pwd.exe",
+ "python.exe",
+ python + ".exe",
+ "rm.exe",
+ "sed.exe",
+ "sh.exe",
+ "tar.exe",
+ "vi",
+ "vim.exe",
+ "which.exe",
+ ]
+ l = ["/bin/" + b for b in l]
+ l.extend([
+ "/lib/lapack/cygblas.dll",
+ "/lib/lapack/cyglapack.dll",
+ ])
+ return l
+
+def installMungedCygwinDLL(prefix):
+ # We don't require that the user has Cygwin installed. At the
+ # same time, we need to avoid conflicts if they *do* have it
+ # installed.
+
+ # Therefore, we install a munged copy of "cygwin1.dll", performing
+ # the following transformations:
+ # Cygnus Solutions -> Cigwin Solutions
+ # cygwin1S4 -> cigwin1S4
+ # These are the registry key name and the shared memory object
+ # name, respectively.
+
+ # N.B.: It is significant that the replacement string is the same
+ # length as the original string. Otherwise, the DLL would become
+ # corrupted.
+
+ # This gives us the freedom to create our own chrooted environment
+ # using Cygwin's mounts, without messing-up the Cygwin registry on
+ # systems that do have Cygwin installed. Registry clean-up at
+ # uninstall is also made easy.
+
+ # Ugly, yes; but so much easier than building a custom Cygwin from
+ # source...
+ status = os.system("""sed -b """
+ """-e "s/Cygnus Solutions/Cigwin Solutions/g" """
+ """-e s/cygwin1S4/cigwin1S4/g """
+ """/bin/cygwin1.dll > %s/bin/cygwin1.dll""" % prefix)
+ if status != 0:
+ sys.exit("sed: exit %d" % status)
+ return
+
+
+def installMinimalCygwin(prefix, python, pl):
+
+ binaries = minCygwin(python)
+ for b in binaries:
+ command = "cp %s %s/bin" % (b, prefix)
+ print command
+ status = os.system(command)
+ if status != 0:
+ sys.exit("cp: exit %d" % status)
+ f = basename(b)
+ pl.addFile("bin/" + f)
+
+ installMungedCygwinDLL(prefix)
+ pl.addFile("bin/cygwin1.dll")
+
+ pl.addDirectory("/lib/" + python)
+
+ return
+
+
+def generateISS(info, pl, bashrc, python):
s = open("buildbot.iss", "w")
# [Setup]
s.write(
-"""
-; Inno Setup Script generated by BuildBot
+"""; Inno Setup Script generated by BuildBot
[Setup]
AppName=%(AppName)s
@@ -109,16 +316,12 @@
[Files]
"""
)
- for d in config.packaging.directories:
- s.write("""Source: "%(dir)s\*"; DestDir: "{app}\\%(dir)s"; Flags: ignoreversion recursesubdirs\n""" % {'dir': d})
- for f in config.packaging.programs:
- s.write("""Source: "bin\\%s"; DestDir: "{app}\\bin"; Flags: ignoreversion\n""" % f)
- for f in config.packaging.scripts:
- s.write("""Source: "bin\\%s"; DestDir: "{app}\\bin"; Flags: ignoreversion\n""" % f)
- for d in config.packaging.python:
- s.write("""Source: "lib\\%(python)\\site-packages\\%(dir)s\\*"; DestDir: "{app}\\lib\\%(python)\\site-packages\\%(dir)s"; Flags: ignoreversion recursesubdirs\n""" %
- {'dir': d, 'python', python})
- s.write("""Source: "%(bashrc)s"; DestDir: "{app}"; Flags: ignoreversion\n""" % {'bashrc': bashrc})
+ for src, dest in itwindirs(pl.directories):
+ s.write("""Source: "%s\\*"; DestDir: "%s"; Flags: ignoreversion recursesubdirs\n""" % (src, dest))
+ for f, d in itwinfiles(pl.files()):
+ s.write("""Source: "%s"; DestDir: "{app}\\%s"; Flags: ignoreversion\n""" % (f, d))
+ for f in [bashrc, "cig.ico"]:
+ s.write("""Source: "%s"; DestDir: "{app}"; Flags: ignoreversion\n""" % f)
# [Dirs]
@@ -172,9 +375,7 @@
# [INI]
s.write("""[INI]\n""")
- urls = ["cig", "http://www.geodynamics.org/"] + config.urls
- urls = pairUp(urls)
- for filename, url in urls:
+ for name, filename, url in pl.urls:
s.write("""Filename: "{app}\\%(filename)s.url"; Section: "InternetShortcut"; Key: "URL"; String: "%(url)s"\n""" %
{'filename': filename, 'url': url})
@@ -187,19 +388,35 @@
Name: "{userdesktop}\\%(AppName)s"; Filename: "{app}\\bin\\bash.exe"; Tasks: desktopicon; Parameters: "--init-file %(bashrc)s -i"; WorkingDir: "{app}"; IconFilename: "{app}\\cig.ico"
""" % {'AppName': info['AppName'], 'bashrc': bashrc}
)
- for filename, url in urls:
- s.write("""Name: "{group}\CIG"; Filename: "{app}\cig.url"\n""" % (displayName, filename))
+ for name, filename, url in pl.urls:
+ s.write("""Name: "{group}\\%s"; Filename: "{app}\\%s.url"\n""" % (name, filename))
+ s.write("""Name: "{group}\Uninstall %(AppName)s"; Filename: "{uninstallexe}"\n""" % info)
+
+
+ # [Run]
s.write(
"""
-Name: "{group}\Uninstall %(AppName)s"; Filename: "{uninstallexe}"
+[Run]
+Filename: "{app}\\bin\\bash.exe"; Description: "Launch %(AppName)s"; Parameters: "--init-file %(bashrc)s -i"; WorkingDir: "{app}"; Flags: nowait postinstall skipifsilent
-""" % info
+""" % {'AppName': info['AppName'], 'bashrc': bashrc}
)
+
+ # [UninstallDelete]
+ s.write("""[UninstallDelete]\n""")
+ for name, filename, url in pl.urls:
+ s.write("""Type: files; Name: "{app}\%s.url"\n""" % filename)
+ for filename in [".bash_history"]:
+ s.write("""Type: files; Name: "{app}\%s"\n""" % filename)
+
+ s.write("\n; end of file\n")
+
return
-def createWindowsInstaller(python, prefix, package, version, config):
+def createWindowsInstaller(python, prefix, package, version, pl,
+ installer):
sourceDir = cygpath("-w", prefix)
@@ -209,13 +426,66 @@
"SourceDir": sourceDir,
}
+ installMinimalCygwin(prefix, python, pl)
+
+ installCigIcon(prefix)
bashrc = generateBashrc(prefix, package, info)
- generateISS(python, info, config, bashrc, python)
+ generateISS(info, pl, bashrc, python)
+ os.system("unix2dos buildbot.iss")
+
+ status = os.system("iscc buildbot.iss")
+ if status != 0:
+ sys.exit("iscc: exit %d" % status)
+
+ status = os.system("mv %s/Output/setup.exe %s.exe" % (prefix, installer))
+ if status != 0:
+ sys.exit("mv: exit %d" % status)
+
return
+def stripBinaries(pl, opSys):
+ strip = "strip"
+ if opSys == "darwin":
+ # Just plain "strip" renders our Python interpreter unusable
+ # by extension modules.
+ strip = "strip -S"
+ status = os.system(strip + " " + " ".join(pl.stripList))
+ if status != 0:
+ sys.exit("strip: exit %d" % status)
+ return
+
+
+def rewriteScripts(pl, prefix, opSys):
+ # Tweak the shebang line of scripts so they are relative instead
+ # of absolute.
+
+ if opSys == "win":
+ # chrooted environment
+ relative = "#!/bin/%s"
+ else:
+ relative = "#!/usr/bin/env %s"
+ absolute = "#!" + prefix + "/bin/"
+
+ for script in pl.scripts:
+ s = open(script, "r")
+ lines = s.readlines()
+ s.close()
+ shebang = lines[0]
+ if shebang.startswith(absolute):
+ interpreter = shebang[len(absolute):]
+ shebang = relative % interpreter
+ s = open(script, "w")
+ s.write(shebang)
+ for line in lines[1:]:
+ s.write(line)
+ s.close()
+
+ return
+
+
def mkpkg():
buildnumber = int(sys.argv[1])
revision = sys.argv[2]
@@ -224,6 +494,8 @@
else:
revision = "forced"
opSys = platform.system().lower()
+ if opSys.startswith("cygwin"):
+ opSys = "win"
arch = opSys + "-" + platform.machine()
tag = "b%04d-%s" % (buildnumber, revision)
python = os.environ['PYTHON']
@@ -239,29 +511,6 @@
if config.packaging is None:
sys.exit('no packaging configuation; try "svn propedit buildbot:config ."')
- packingList = []
- stripList = []
-
- for d in config.packaging.directories:
- packingList.append(d)
-
- for p in config.packaging.programs:
- p = "bin/" + p
- packingList.append(p)
- stripList.append(p)
-
- for s in config.packaging.scripts:
- packingList.append("bin/" + s)
-
- for l in config.packaging.libraries:
- l = "lib/" + l
- packingList.append(l)
- stripList.append(l)
-
- for p in config.packaging.python:
- p = "lib/" + python + "/site-packages/" + p
- packingList.append(p)
-
if opSys == "linux":
# We only need one of these; do it on Linux only.
archive = distdir + ".tar.gz"
@@ -269,29 +518,25 @@
os.system("make dist")
os.system("mv " + archive + " " + taggedArchive)
- print "strip", stripList
- print "pack", packingList
-
workdir = os.getcwd()
os.chdir(prefix)
- strip = "strip"
- if opSys == "darwin":
- # Just plain "strip" renders our Python interpreter unusable
- # by extension modules.
- strip = "strip -S"
- status = os.system(strip + " " + " ".join(stripList))
- if status != 0:
- sys.exit("strip: exit %d" % status)
+ pl = PackingList(config, opSys, python)
+ print "strip", pl.stripList
+ print "pack", pl.all
+
+ stripBinaries(pl, opSys)
+ rewriteScripts(pl, prefix, opSys)
+
os.chdir(workdir)
+ distdir_arch = distdir + "-" + arch
if opSys == "darwin" or opSys == "linux":
# No .dmg on Mac for now.
- distdir_arch = distdir + "-" + arch
os.system("rm " + distdir_arch)
os.system("ln -s " + prefix + " " + distdir_arch)
- packingList = [distdir_arch + "/" + m for m in packingList]
+ packingList = [distdir_arch + "/" + m for m in pl.all]
archive = distdir_arch + ".tar.gz"
taggedArchive = tag + "-" + archive
os.system("tar cvzf " + archive + " " + " ".join(packingList))
@@ -299,8 +544,9 @@
sys.exit("tar: exit %d" % status)
os.system("mv " + archive + " " + taggedArchive)
- elif opSys == "cygwin":
- createWindowsInstaller(python, prefix, package, version, config)
+ elif opSys == "win":
+ createWindowsInstaller(python, prefix, package, version, pl,
+ tag + "-" + distdir_arch)
else:
sys.exit("unknown OS: " + opSys)
@@ -308,4 +554,4 @@
if __name__ == "__main__":
- mkpkg("0001", "1234")
+ mkpkg()
More information about the cig-commits
mailing list