WiX now generates a 64-bit MSI when appropriate
This commit is contained in:
parent
c8e1f291fa
commit
fc57f75da7
2 changed files with 142 additions and 123 deletions
|
|
@ -911,7 +911,8 @@ env.Depends(finish_install, installTargets)
|
|||
install_cantera = Alias('install', finish_install)
|
||||
|
||||
def build_wxs(target, source, env):
|
||||
wxsgen.make_wxs(env['stage_dir'], str(target[0]))
|
||||
wxs = wxsgen.WxsGenerator(env['stage_dir'], env['TARGET_ARCH']=='amd64')
|
||||
wxs.make_wxs(str(target[0]))
|
||||
|
||||
if 'msi' in COMMAND_LINE_TARGETS:
|
||||
wxs_target = env.Command(pjoin('build', 'wix', 'cantera.wxs'),
|
||||
|
|
|
|||
|
|
@ -2,23 +2,147 @@ import os, sys
|
|||
import uuid
|
||||
import xml.etree.ElementTree as et
|
||||
|
||||
CANTERA_UUID = uuid.UUID('1B36CAF0-279D-11E1-8979-001FBC085391')
|
||||
class WxsGenerator(object):
|
||||
def __init__(self, stageDir, x64=False):
|
||||
self.prefix = stageDir
|
||||
self.x64 = x64
|
||||
|
||||
def Directory(parent, Id, Name):
|
||||
return et.SubElement(parent, 'Directory',
|
||||
dict(Id=Id, Name=Name))
|
||||
# Use separate UUIDs for 64- and 32-bit components
|
||||
if self.x64:
|
||||
self.CANTERA_UUID = uuid.UUID('F707EB9E-3723-11E1-A99F-525400631BAF')
|
||||
self.pfilesName = 'ProgramFiles64Folder'
|
||||
else:
|
||||
self.CANTERA_UUID = uuid.UUID('1B36CAF0-279D-11E1-8979-001FBC085391')
|
||||
self.pfilesName = 'ProgramFilesFolder'
|
||||
|
||||
def FileComponent(parent, componentId, fileId, Name, Source, DiskId='1', KeyPath='yes'):
|
||||
guid = str(uuid.uuid5(CANTERA_UUID, componentId))
|
||||
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
|
||||
def Directory(self, parent, Id, Name):
|
||||
return et.SubElement(parent, 'Directory',
|
||||
dict(Id=Id, Name=Name))
|
||||
|
||||
def FileComponent(self, parent, componentId, fileId, Name, Source,
|
||||
DiskId='1', KeyPath='yes'):
|
||||
guid = str(uuid.uuid5(self.CANTERA_UUID, componentId))
|
||||
|
||||
fields = {'Win64': 'yes'} if self.x64 else {}
|
||||
c = et.SubElement(parent, "Component",
|
||||
dict(Id=componentId, Guid=guid, **fields))
|
||||
|
||||
fields = {'ProcessorArchitecture': 'x64'} if self.x64 else {}
|
||||
f = et.SubElement(c, "File",
|
||||
dict(Id=fileId,
|
||||
Name=Name,
|
||||
Source=Source,
|
||||
DiskId=DiskId,
|
||||
KeyPath=KeyPath,
|
||||
**fields))
|
||||
return c,f
|
||||
|
||||
def addDirectoryContents(self, directory, parent, feature):
|
||||
"""
|
||||
directory: name of the directory to add
|
||||
parent: the Element for the parent directory
|
||||
feature: the Element for the feature to add the files to
|
||||
"""
|
||||
#self.prefix: path to the parent directory
|
||||
directories = {}
|
||||
|
||||
directories[directory] = self.Directory(parent, directory, directory)
|
||||
for path, dirs, files in os.walk('/'.join((self.prefix, directory))):
|
||||
path = path.replace(self.prefix + '/', '', 1).replace('\\', '/')
|
||||
for d in dirs:
|
||||
dpath = '/'.join((path, d))
|
||||
ID = dpath.replace('/', '_')
|
||||
directories[dpath] = self.Directory(directories[path], ID, d)
|
||||
|
||||
for f in files:
|
||||
ID = '_'.join((path, f)).replace('/', '_')
|
||||
self.FileComponent(directories[path], ID, ID, f,
|
||||
'/'.join((self.prefix, path, f)))
|
||||
et.SubElement(feature, 'ComponentRef', dict(Id=ID))
|
||||
|
||||
return directories
|
||||
|
||||
def make_wxs(self, outFile):
|
||||
wix = et.Element("Wix", {'xmlns': 'http://schemas.microsoft.com/wix/2006/wi'})
|
||||
product = et.SubElement(wix, "Product",
|
||||
dict(Name='Cantera 2.0',
|
||||
Id=str(self.CANTERA_UUID),
|
||||
UpgradeCode='2340BEE1-279D-11E1-A4AA-001FBC085391',
|
||||
Language='1033',
|
||||
Codepage='1252',
|
||||
Version='2.0.0',
|
||||
Manufacturer='Cantera Developers'))
|
||||
|
||||
fields = {'Platform': 'x64'} if self.x64 else {}
|
||||
package = et.SubElement(product, "Package",
|
||||
dict(Id='*',
|
||||
Keywords='Installer',
|
||||
Description="Cantera 2.0 Installer",
|
||||
InstallerVersion='310',
|
||||
Languages='1033',
|
||||
Compressed='yes',
|
||||
SummaryCodepage='1252', **fields))
|
||||
|
||||
# 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"))
|
||||
|
||||
# Directories
|
||||
targetdir = self.Directory(product, 'TARGETDIR', 'SourceDir')
|
||||
pfiles = self.Directory(targetdir, self.pfilesName, 'PFiles')
|
||||
instdir = self.Directory(pfiles, 'INSTALLDIR', 'Cantera')
|
||||
|
||||
# Features
|
||||
core = et.SubElement(product, 'Feature',
|
||||
dict(Id='Core', Level='1',
|
||||
Title='Cantera',
|
||||
Description='Cantera base files',
|
||||
Display='expand',
|
||||
ConfigurableDirectory='INSTALLDIR',
|
||||
AllowAdvertise='no',
|
||||
Absent='disallow'))
|
||||
devel = et.SubElement(product, 'Feature',
|
||||
dict(Id='DevTools', Level='1000',
|
||||
Title='Develpment Tools',
|
||||
Description='Header files and static libraries needed to develop applications that use Cantera.',
|
||||
Display='expand',
|
||||
AllowAdvertise='no'))
|
||||
extras = et.SubElement(product, 'Feature',
|
||||
dict(Id='Extras', Level='1',
|
||||
Title='Extras',
|
||||
Description='Demos, tutorials and templates which show you some ways of using Cantera.',
|
||||
Display='expand',
|
||||
AllowAdvertise='no'))
|
||||
|
||||
# Files
|
||||
includes = self.addDirectoryContents('include', instdir, devel)
|
||||
binaries = self.addDirectoryContents('bin', instdir, core)
|
||||
lib_dir = self.addDirectoryContents('lib', instdir, devel)
|
||||
data_dir = self.addDirectoryContents('data', instdir, core)
|
||||
demos_dir = self.addDirectoryContents('demos', instdir, extras)
|
||||
templates_dir = self.addDirectoryContents('templates', instdir, extras)
|
||||
tutorials_dir = self.addDirectoryContents('tutorials', instdir, extras)
|
||||
|
||||
# Wix UI
|
||||
et.SubElement(product, 'UIRef', dict(Id='WixUI_FeatureTree'))
|
||||
et.SubElement(product, 'UIRef', dict(Id='WixUI_ErrorProgressText'))
|
||||
et.SubElement(product, 'Property', dict(Id='WIXUI_INSTALLDIR',
|
||||
Value='INSTALLDIR'))
|
||||
|
||||
# License
|
||||
et.SubElement(product, 'WixVariable',
|
||||
dict(Id='WixUILicenseRtf', Value='platform/windows/License.rtf'))
|
||||
|
||||
# Format and save as XML
|
||||
indent(wix)
|
||||
tree = et.ElementTree(wix)
|
||||
tree.write(outFile)
|
||||
|
||||
|
||||
def indent(elem, level=0):
|
||||
|
|
@ -38,112 +162,6 @@ def indent(elem, level=0):
|
|||
elem.tail = i
|
||||
|
||||
|
||||
def addDirectoryContents(prefix, directory, parent, feature):
|
||||
"""
|
||||
prefix: path to the parent directory
|
||||
directory: name of the directory to add
|
||||
parent: the Element for the parent directory
|
||||
feature: the Element for the feature to add the files to
|
||||
"""
|
||||
directories = {}
|
||||
|
||||
directories[directory] = Directory(parent, directory, directory)
|
||||
for path, dirs, files in os.walk('/'.join((prefix, directory))):
|
||||
path = path.replace(prefix + '/', '', 1).replace('\\', '/')
|
||||
for d in dirs:
|
||||
dpath = '/'.join((path, d))
|
||||
ID = dpath.replace('/', '_')
|
||||
directories[dpath] = Directory(directories[path], ID, d)
|
||||
|
||||
for f in files:
|
||||
ID = '_'.join((path, f)).replace('/', '_')
|
||||
FileComponent(directories[path], ID, ID, f,
|
||||
'/'.join((prefix, path, f)))
|
||||
et.SubElement(feature, 'ComponentRef', dict(Id=ID))
|
||||
|
||||
return directories
|
||||
|
||||
|
||||
def make_wxs(stageDir, outFile):
|
||||
wix = et.Element("Wix", {'xmlns': 'http://schemas.microsoft.com/wix/2006/wi'})
|
||||
product = et.SubElement(wix, "Product",
|
||||
dict(Name='Cantera 2.0',
|
||||
Id=str(CANTERA_UUID),
|
||||
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"))
|
||||
|
||||
# Directories
|
||||
targetdir = Directory(product, 'TARGETDIR', 'SourceDir')
|
||||
pfiles = Directory(targetdir, 'ProgramFilesFolder', 'PFiles')
|
||||
instdir = Directory(pfiles, 'INSTALLDIR', 'Cantera')
|
||||
|
||||
# Features
|
||||
core = et.SubElement(product, 'Feature',
|
||||
dict(Id='Core', Level='1',
|
||||
Title='Cantera',
|
||||
Description='Cantera base files',
|
||||
Display='expand',
|
||||
ConfigurableDirectory='INSTALLDIR',
|
||||
AllowAdvertise='no',
|
||||
Absent='disallow'))
|
||||
devel = et.SubElement(product, 'Feature',
|
||||
dict(Id='DevTools', Level='1000',
|
||||
Title='Develpment Tools',
|
||||
Description='Header files and static libraries needed to develop applications that use Cantera.',
|
||||
Display='expand',
|
||||
AllowAdvertise='no'))
|
||||
extras = et.SubElement(product, 'Feature',
|
||||
dict(Id='Extras', Level='1',
|
||||
Title='Extras',
|
||||
Description='Demos, tutorials and templates which show you some ways of using Cantera.',
|
||||
Display='expand',
|
||||
AllowAdvertise='no'))
|
||||
|
||||
# Files
|
||||
includes = addDirectoryContents(stageDir, 'include', instdir, devel)
|
||||
binaries = addDirectoryContents(stageDir, 'bin', instdir, core)
|
||||
lib_dir = addDirectoryContents(stageDir, 'lib', instdir, devel)
|
||||
data_dir = addDirectoryContents(stageDir, 'data', instdir, core)
|
||||
demos_dir = addDirectoryContents(stageDir, 'demos', instdir, extras)
|
||||
templates_dir = addDirectoryContents(stageDir, 'templates', instdir, extras)
|
||||
tutorials_dir = addDirectoryContents(stageDir, 'tutorials', instdir, extras)
|
||||
|
||||
# Wix UI
|
||||
et.SubElement(product, 'UIRef', dict(Id='WixUI_FeatureTree'))
|
||||
et.SubElement(product, 'UIRef', dict(Id='WixUI_ErrorProgressText'))
|
||||
et.SubElement(product, 'Property', dict(Id='WIXUI_INSTALLDIR',
|
||||
Value='INSTALLDIR'))
|
||||
|
||||
# License
|
||||
et.SubElement(product, 'WixVariable',
|
||||
dict(Id='WixUILicenseRtf', Value='platform/windows/License.rtf'))
|
||||
|
||||
# Format and save as XML
|
||||
indent(wix)
|
||||
tree = et.ElementTree(wix)
|
||||
tree.write(outFile)
|
||||
|
||||
def usage():
|
||||
print "Usage: wxsgen <stageDir> <outputFile>"
|
||||
|
|
@ -153,4 +171,4 @@ if __name__ == '__main__':
|
|||
usage()
|
||||
sys.exit()
|
||||
|
||||
make_wxs(sys.argv[1], sys.argv[2])
|
||||
WxsGenerator(sys.argv[1]).make_wxs(sys.argv[2])
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue