First steps toward developing a Windows installer

This commit is contained in:
Ray Speth
2012-01-03 23:07:58 +00:00
parent 5343eea5f1
commit 084666bef3
4 changed files with 154 additions and 1 deletions

View File

@@ -13,6 +13,8 @@ Basic usage:
'scons test-clean' - Delete files created while running the
regression tests.
'scons msi' - Build a Windows installer (.msi) for Cantera
"""
from buildutils import *
@@ -646,10 +648,15 @@ env['ct_tutdir'] = pjoin(env['prefix'], 'tutorials')
env['ct_mandir'] = pjoin(env['prefix'], 'man1')
env['ct_matlab_dir'] = pjoin(env['prefix'], 'matlab', 'toolbox')
# Always set the stage directory before building an MSI installer
if 'msi' in COMMAND_LINE_TARGETS:
env['stage_dir'] = 'stage'
env['prefix'] = '.'
# Directories where things will be staged for package creation. These
# variables should always be used by the Install(...) targets
if env['stage_dir']:
instRoot = pjoin(os.getcwd(), env['stage_dir'], env['prefix'].strip('/'))
instRoot = pjoin(os.getcwd(), env['stage_dir'], stripDrive(env['prefix']).strip('/\\'))
env['python_prefix'] = instRoot
else:
instRoot = env['prefix']

View File

@@ -0,0 +1,67 @@
<?xml version='1.0' encoding='windows-1252'?>
<Wix xmlns='http://schemas.microsoft.com/wix/2006/wi'>
<Product Name='Cantera 2.0' Id='1B36CAF0-279D-11E1-8979-001FBC085391'
UpgradeCode='2340BEE1-279D-11E1-A4AA-001FBC085391'
Language='1033' Codepage='1252' Version='2.0.0'
Manufacturer='Cantera Developers'>
<Package Id='*' Keywords='Installer' Description="Cantera 2.0 Installer"
InstallerVersion='100' Languages='1033' Compressed='yes' SummaryCodepage='1252' />
<Media Id='1' Cabinet='cantera.cab' EmbedCab='yes' DiskPrompt='CD-ROM #1' />
<Property Id='DiskPrompt' Value="Cantera Installation Disk" />
<Directory Id='TARGETDIR' Name='SourceDir'>
<Directory Id='ProgramFilesFolder' Name='PFiles'>
<Directory Id='INSTALLDIR' Name='Cantera'>
<Directory Id='bin' Name='bin'>
<Component Id='MainExecutable' Guid='0ABCA730-279D-11E1-984E-001FBC085391'>
<File Id='ck2ctiEXE' Name='ck2cti.exe' DiskId='1' Source='../../stage/bin/ck2cti.exe' KeyPath='yes'>
<!-- <Shortcut Id="startmenuFoobar10" Directory="ProgramMenuDir" Name="Foobar 1.0" -->
<!-- WorkingDirectory='INSTALLDIR' Icon="Foobar10.exe" IconIndex="0" Advertise="yes" /> -->
<!-- <Shortcut Id="desktopFoobar10" Directory="DesktopFolder" Name="Foobar 1.0" -->
<!-- WorkingDirectory='INSTALLDIR' Icon="Foobar10.exe" IconIndex="0" Advertise="yes" /> -->
</File>
</Component>
<!-- <Component Id='HelperLibrary' Guid='YOURGUID-6BE3-460D-A14F-75658D16550B'> -->
<!-- <File Id='HelperDLL' Name='Helper.dll' DiskId='1' Source='Helper.dll' KeyPath='yes' /> -->
<!-- </Component> -->
<!-- <Component Id='Manual' Guid='YOURGUID-574D-4A9A-A266-5B5EC2C022A4'> -->
<!-- <File Id='Manual' Name='Manual.pdf' DiskId='1' Source='Manual.pdf' KeyPath='yes'> -->
<!-- <Shortcut Id='startmenuManual' Directory='ProgramMenuDir' Name='Instruction Manual' Advertise='yes' /> -->
<!-- </File> -->
<!-- </Component> -->
</Directory>
</Directory>
</Directory>
<!-- <Directory Id="ProgramMenuFolder" Name="Programs"> -->
<!-- <Directory Id="ProgramMenuDir" Name="Foobar 1.0"> -->
<!-- <Component Id="ProgramMenuDir" Guid="YOURGUID-7E98-44CE-B049-C477CC0A2B00"> -->
<!-- <RemoveFolder Id='ProgramMenuDir' On='uninstall' /> -->
<!-- <RegistryValue Root='HKCU' Key='Software\[Manufacturer]\[ProductName]' Type='string' Value='' KeyPath='yes' /> -->
<!-- </Component> -->
<!-- </Directory> -->
<!-- </Directory> -->
<!-- <Directory Id="DesktopFolder" Name="Desktop" /> -->
</Directory>
<Feature Id='Complete' Level='1'>
<ComponentRef Id='MainExecutable' />
<!-- <ComponentRef Id='HelperLibrary' /> -->
<!-- <ComponentRef Id='Manual' /> -->
<!-- <ComponentRef Id='ProgramMenuDir' /> -->
</Feature>
<!-- <Icon Id="Foobar10.exe" SourceFile="FoobarAppl10.exe" /> -->
<!-- <Shortcut Id="desktopFoobar10" Directory="DesktopFolder" Name="Foobar 1.0" WorkingDirectory='INSTALLDIR' Icon="Foobar10.ico" IconIndex="0" /> -->
<!-- <Icon Id="Foobar10.ico" SourceFile="FoobarAppl10.ico" /> -->
</Product>
</Wix>

View File

@@ -0,0 +1,69 @@
try:
# Prefer LXML for its pretty printer, but xml.etree works fine.
import lxml.etree as et
have_lxml = True
except ImportError:
import xml.etree.ElementTree as et
have_lxml = False
wix = et.Element("Wix", {'xmlns': 'http://schemas.microsoft.com/wix/2006/wi'})
def Directory(parent, Id, Name):
return et.SubElement(parent, 'Directory',
dict(Id=Id, Name=Name))
def FileComponent(parent, componentId, fileId, Guid, Name, Source, DiskId='1', KeyPath='yes'):
c = et.SubElement(parent, "Component",
dict(Id=componentId, Guid=Guid))
f = et.SubElement(c, "File",
dict(Id=fileId,
Name=Name,
Source=Source,
DiskId=DiskId,
KeyPath=KeyPath))
return c,f
product = et.SubElement(wix, "Product",
dict(Name='Cantera 2.0',
Id='1B36CAF0-279D-11E1-8979-001FBC085391',
UpgradeCode='2340BEE1-279D-11E1-A4AA-001FBC085391',
Language='1033',
Codepage='1252',
Version='2.0.0',
Manufacturer='Cantera Developers'))
package = et.SubElement(product, "Package",
dict(Id='*',
Keywords='Installer',
Description="Cantera 2.0 Installer",
InstallerVersion='100',
Languages='1033',
Compressed='yes',
SummaryCodepage='1252'))
# Required boilerplate refering to nonexistent installation media
media = et.SubElement(product, "Media",
dict(Id='1',
Cabinet='cantera.cab',
EmbedCab='yes',
DiskPrompt='CD-ROM #1'))
diskprompt = et.SubElement(product, "Property",
dict(Id='DiskPrompt',
Value="Cantera Installation Disk"))
targetdir = Directory(product, 'TARGETDIR', 'SourceDir')
pfiles = Directory(targetdir, 'ProgramFilesFolder', 'PFiles')
instdir = Directory(pfiles, 'INSTALLDIR', 'Cantera')
bindir = Directory(instdir, 'bin', 'bin')
ck2cti = FileComponent(bindir, 'MainExecutable', 'ck2ctiEXE',
'0ABCA730-279D-11E1-984E-001FBC085391',
'ck2cti.exe', '../../stage/bin/ck2cti.exe')
complete = et.SubElement(product, 'Feature', dict(Id='Complete', Level='1'))
mainExec = et.SubElement(complete, 'ComponentRef', dict(Id='MainExecutable'))
if have_lxml:
print et.tostring(wix, pretty_print=True)
else:
print et.tostring(wix)

View File

@@ -291,6 +291,16 @@ def psplit(s):
return path
def stripDrive(s):
"""
Remove a Windows drive letter specification from a path.
"""
if len(s) > 1 and s[1] == ':':
return s[2:]
else:
return s
def which(program):
""" Replicates the functionality of the 'which' shell command """
def is_exe(fpath):