def generate_wxi(src, output_filename=None, id=None, diskId=None):
    add_wix_to_path()

    prefix = "analysis_tool_"

    while src[-1] in ('/', '\\'):
        src = src[:-1]
    name = os.path.basename(src)
    id = id or prefix + name.replace('-', '_').replace(' ', '_')
    output_filename = output_filename or _adjacent_file(id + ".wxi")

    import subprocess

    def check_call(args):
        print " ".join(args)
        subprocess.check_call(args)

    check_call(['heat', 'dir', _adjacent_file(src), '-template', 'fragment', '-sreg', '-scom',
      '-o', output_filename, '-ag', '-cg', id, '-srd', '-var', 'var.' + id, '-dr', id, '-nologo'])

    tree = ElementTree.parse(output_filename, parser=CommentedTreeBuilder()).getroot()
    tree.insert(0, ElementTree.Comment('generated with gen_analysis_tool_wxi.py %s\n' % src))
    tree.insert(0, ElementTree.ProcessingInstruction('define', '%s=%s' % (id, os.path.normpath(src))))
    parent_map = dict((c, p) for p in tree.getiterator() for c in p)
    for file in tree.findall(".//{http://schemas.microsoft.com/wix/2006/wi}Component/{http://schemas.microsoft.com/wix/2006/wi}File"):
        if file.get('Source', '').find('.svn') != -1:
            comp = parent_map[file]
            parent_map[comp].remove(comp)
    for dir in tree.findall(".//{http://schemas.microsoft.com/wix/2006/wi}Directory"):
        if dir.get('Name', '') == '.svn':
            for dirref in tree.findall(".//{http://schemas.microsoft.com/wix/2006/wi}DirectoryRef"):
                if dirref.get('Id', '') == dir.get('Id', ''):
                    frag = parent_map[dirref]
                    parent_map[frag].remove(frag)
            parent_map[dir].remove(dir)
    if diskId:
        for component in tree.findall(".//{http://schemas.microsoft.com/wix/2006/wi}Component"):
            component.attrib['DiskId'] = diskId

    # add registry nodes
    componentGroup = tree.findall(".//{http://schemas.microsoft.com/wix/2006/wi}ComponentGroup[@Id='" + id + "']")[0]
    componentRegistry = ElementTree.SubElement(componentGroup, 'ns0:Component', {'Id': id + '_RegistryEntry', 'Directory': id, 'Guid': '*', 'Win64': 'no'})

    manifest = None
    with open(os.path.join(src, 'analysis_tool.manifest.json'), 'r') as f_p:
        manifest = json.load(f_p)

    for tool_name in manifest:

        registryKey = ElementTree.SubElement(componentRegistry, 'ns0:RegistryKey', {'Root': 'HKLM', 'Key': 'Software\\META\\AnalysisTools\\' + tool_name})
        ElementTree.SubElement(registryKey, 'ns0:RegistryValue', {'Name': 'InstallLocation', 'Type': 'string', 'Value': '[INSTALLDIR]\\analysis_tools\\' + name})
        ElementTree.SubElement(registryKey, 'ns0:RegistryValue', {'Name': 'Version', 'Type': 'string', 'Value': manifest[tool_name]['version']})
        ElementTree.SubElement(registryKey, 'ns0:RegistryValue', {'Name': 'OutputDirectory', 'Type': 'string', 'Value': '[INSTALLDIR]\\analysis_tools\\' + name + '\\' + manifest[tool_name]['outputDirectory']})
        ElementTree.SubElement(registryKey, 'ns0:RegistryValue', {'Name': 'RunCommand', 'Type': 'string', 'Value': manifest[tool_name]['runCommand']})
        ElementTree.SubElement(registryKey, 'ns0:RegistryValue', {'Name': 'RequiredInterpreter', 'Type': 'string', 'Value': manifest[tool_name]['requiredInterpreter']})

    ElementTree.ElementTree(tree).write(output_filename, xml_declaration=True)

    return name, id
Example #2
0
def build_msi(offline, source_wxs='META_x64.wxs'):
    get_nuget_packages()

    generate_license_rtf()

    add_wix_to_path()

    def get_wixobj(file):
        return os.path.splitext(file)[0] + ".wixobj"

    def adjacent_file(file):
        return os.path.join(this_dir, file)

    gen_analysis_tool_wxi.main(r"..\analysis_tools", diskId='5')

    # gen_dir_from_vc: "explicit is better than implicit"
    #  consider: generated files are left on disk after an svn switch, and get included in an installer that shouldn't have them
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\PCC\PCC", )
    gen_dir_wxi.gen_dir_from_vc(
        r"..\src\Python27Packages\isis_meta\isis_meta", )
    gen_dir_wxi.gen_dir_from_vc(
        r"..\src\Python27Packages\material_library\MaterialLibraryInterface", )
    gen_dir_wxi.gen_dir_from_vc(
        r"..\src\Python27Packages\meta_nrmm\meta_nrmm", )
    gen_dir_wxi.gen_dir_from_vc(
        r"..\src\Python27Packages\py_modelica\py_modelica", )
    gen_dir_wxi.gen_dir_from_vc(
        r"..\src\Python27Packages\py_modelica_exporter\py_modelica_exporter", )
    gen_dir_wxi.gen_dir_from_vc(
        r"..\src\Python27Packages\cad_library\cad_library", )
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\run_mdao", )
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\testbenchexecutor", )
    gen_dir_wxi.gen_dir_from_vc(r"..\meta\DesignDataPackage\lib\python",
                                "DesignDataPackage_python.wxi",
                                "DesignDataPackage_python")
    gen_dir_wxi.main(r"..\docs\_build\html")
    #gen_dir_wxi.main(r"CAD_Installs\Proe ISIS Extensions", "Proe_ISIS_Extensions_x64.wxi", "Proe_ISIS_Extensions_x64", diskId='4')  # do not call gen_dir_from_vc, it would exclude CADCreoCreateAssembly.exe
    gen_dir_wxi.gen_dir_from_vc(r"..\meta\CyPhyML\icons", )
    gen_dir_wxi.gen_dir_from_vc(r"..\models\Validation", )

    import package_python
    bin_file_map = package_python.compileall()
    bin_file_map.update(package_python.zipall())
    gen_dir_wxi.gen_dir_from_vc(r"..\bin", diskId='3', file_map=bin_file_map)
    bin_mods()
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\chipfit_display", )
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\layout_json", )
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\SpiceVisualizer")
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\spice_viewer")
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\cam2gerber")
    gen_dir_wxi.gen_dir_from_vc(
        r"..\src\Python27Packages\get_bom_with_eagle_xref")
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\runCentroidUlp")
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\runEagleUlp")
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\runDrc")
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\CADVisualizer")
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\get_eagle_path")

    def get_command_output(cmd):
        p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
        out, err = p.communicate()
        return out.strip()

    def get_vcsversion():
        p = subprocess.Popen("git rev-list HEAD --count".split(),
                             stdout=subprocess.PIPE)
        out, err = p.communicate()
        return str(int(out.strip() or '651') - 650)

    vcsversion = get_vcsversion()

    def get_vcsdescribe():
        out = get_command_output("git describe --match v*".split())
        if out:
            return out
        # if there is no tag, use v0.1.1-[revision count]-g[short hash]
        return "v0.1.1-" + vcsversion + "-g" + get_command_output(
            "git rev-parse --short HEAD")

    def parse_describe(describe):
        m = re.match('^v(\\d+\\.\\d+\\.\\d+)((?:-[a-zA-Z_]+)?-(\\d+)-\\w+)?$',
                     describe)
        if not m:
            raise ValueError(
                'Invalid tag "{}". Must be in format v0.1.2 or v0.1.2-vendor'.
                format(describe))
        return m.groups()[0] + '.' + (m.groups()[2] or '0')

    assert parse_describe('v0.16.1') == '0.16.1.0'
    assert parse_describe('v0.16.1-21-g57742becee') == '0.16.1.21'
    assert parse_describe('v0.16.1-vendor-21-g57742becee') == '0.16.1.21'
    vcsdescription = get_vcsdescribe()
    version = parse_describe(vcsdescription)

    print "Version description: " + vcsdescription
    print "Installer version: " + version
    sourcedir = os.path.relpath(this_dir) + '/'

    def get_githash():
        p = subprocess.Popen("git rev-parse --short HEAD".split(),
                             stdout=subprocess.PIPE)
        out, err = p.communicate()
        #if p.returncode:
        #    raise subprocess.CalledProcessError(p.returncode, 'svnversion')
        return out.strip() or 'unknown'

    vcshash = get_githash()

    import glob
    sources_all = glob.glob(sourcedir + '*.wxi') + glob.glob(sourcedir +
                                                             source_wxs)
    sources = []
    include_wxis = []

    # For each each ComponentGroupRef in "source_wxs" and "analysis_tools.wxi",
    # add its corresponding file to "include_wxis"
    for wxs in glob.glob(sourcedir +
                         source_wxs) + glob.glob(sourcedir +
                                                 'analysis_tools.wxi'):
        print 'Processing WXS: ' + wxs
        tree = ET.parse(wxs)
        root = tree.getroot()
        #print root
        all_nodes = root.findall('.//')
        for node in all_nodes:
            if node.tag == '{http://schemas.microsoft.com/wix/2006/wi}ComponentGroupRef':
                include_wxis.append(node.attrib['Id'] + '.wxi')
                include_wxis.append(node.attrib['Id'] + '_x64.wxi')
            if node.tag == '{http://schemas.microsoft.com/wix/2006/wi}ComponentRef':
                include_wxis.append(node.attrib['Id'].rsplit(".", 1)[0] +
                                    '.wxi')
                include_wxis.append(node.attrib['Id'].rsplit(".", 1)[0] +
                                    '_x64.wxi')

    # For each file in include_wxis, check for ComponentGroupRef and ComponentRef.
    # Add any that you find
    index = 0
    while index < len(include_wxis):
        wxi = include_wxis[index]
        index += 1

        if not os.path.exists(wxi):
            continue

        tree = ET.parse(wxi)
        root = tree.getroot()

        all_nodes = root.findall('.//')
        for node in all_nodes:
            if node.tag == '{http://schemas.microsoft.com/wix/2006/wi}ComponentGroupRef':
                include_wxis.append(node.attrib['Id'] + '.wxi')
                include_wxis.append(node.attrib['Id'] + '_x64.wxi')
            if node.tag == '{http://schemas.microsoft.com/wix/2006/wi}ComponentRef':
                include_wxis.append(node.attrib['Id'].rsplit(".", 1)[0] +
                                    '.wxi')
                include_wxis.append(node.attrib['Id'].rsplit(".", 1)[0] +
                                    '_x64.wxi')

    include_wxis = set((wxi.lower() for wxi in include_wxis))
    sources = [
        source for source in sources_all
        if (os.path.basename(source).lower() in include_wxis)
    ]
    sources.append(source_wxs)

    if len(sources) == 0:
        raise Exception("0 sources found in " + sourcedir)

    defines = [('InterpreterBin', '../src/bin')]

    def get_mta_versions(mta_file):
        import uuid
        metaproject = win32com.client.Dispatch("MGA.MgaMetaProject")
        metaproject.Open('MGA=' + mta_file)
        try:
            return ("{" + str(uuid.UUID(bytes_le=metaproject.GUID)).upper() +
                    "}", metaproject.Version)
        finally:
            metaproject.Close()

    cyphy_versions = get_mta_versions(
        adjacent_file('../generated/CyPhyML/models/CyPhyML.mta'))
    defines.append(('GUIDSTRCYPHYML', cyphy_versions[0]))
    defines.append(('VERSIONSTRCYPHYML', cyphy_versions[1]))

    defines.append(('VERSIONSTR', version))
    defines.append(('VCSHASH', vcshash))
    defines.append(('VCSDESCRIPTION', vcsdescription))
    defines.append(('Compressed', ("yes" if offline else "no")))

    from multiprocessing.pool import ThreadPool
    pool = ThreadPool()
    pool_exceptions = []

    def candle(source):
        try:
            arch = ['-arch', ('x86' if source.find('x64') == -1 else 'x64')]
            system(['candle', '-ext', 'WiXUtilExtension'] +
                   ['-d' + d[0] + '=' + d[1] for d in defines] + arch +
                   ['-out', get_wixobj(source), source] + ['-nologo'])
        except Exception as e:
            pool_exceptions.append(sys.exc_info())
            raise

    candle_results = pool.map_async(candle, sources, chunksize=1)
    pool.close()
    pool.join()
    if pool_exceptions:
        six.reraise(*pool_exceptions[0])
    assert candle_results.successful()

    #ignore warning 1055, ICE82 from VC10 merge modules
    # ICE69: Mismatched component reference. Entry 'reg491FAFEB7F990D99C4A4D719B2A95253' of the Registry table belongs to component 'CyPhySoT.dll'. However, the formatted string in column 'Value' references file 'CyPhySoT.ico' which belongs to component 'CyPhySoT.ico'
    # ICE60: The file fil_5b64d789d9ad5473bc580ea7258a0fac is not a Font, and its version is not a companion file reference. It should have a language specified in the Language column.
    if source_wxs.startswith("META"):

        def download():
            try:
                download_bundle_deps('META_bundle_x64.wxs')
            except Exception as e:
                pool_exceptions.append(sys.exc_info())

        import threading
        download_thread = threading.Thread(target=download)
        download_thread.start()

        import datetime
        starttime = datetime.datetime.now()
        system([
            'light',
            '-sw1055',
            '-sice:ICE82',
            '-sice:ICE57',
            '-sice:ICE60',
            '-sice:ICE69',
            '-ext',
            'WixNetFxExtension',
            '-ext',
            'WixUIExtension',
            '-ext',
            'WixUtilExtension',
            # '-cc', os.path.join(this_dir, 'cab_cache'), '-reusecab', # we were getting errors during installation relating to corrupted cab files => disable cab cache
            # udm.pyd depends on UdmDll_VC10
            '-o',
            os.path.splitext(source_wxs)[0] + ".msi"
        ] + [get_wixobj(file) for file in sources] + [
            'UdmDll_VS10.wixlib', 'UdmDll_VC11_x64.wixlib',
            'UdmDll_VC14.wixlib'
        ])

        download_thread.join()
        if pool_exceptions:
            six.reraise(*pool_exceptions[0])
        system(
            'candle.exe META_bundle_x64.wxs -ext WixBalExtension -ext WixUtilExtension -ext WixDependencyExtension'
            .split() + ['-d' + d[0] + '=' + d[1] for d in defines])
        system(
            'candle.exe META_bundle_ba.wxi -ext WixBalExtension -ext WixUtilExtension -ext WixDependencyExtension'
            .split() + ['-d' + d[0] + '=' + d[1] for d in defines])
        system((
            'light.exe -o META_bundle_x64' + ('_offline' if offline else '') +
            '.exe META_bundle_ba.wixobj META_bundle_x64.wixobj -ext WixBalExtension -ext WixUtilExtension -ext WixDependencyExtension -ext WixNetFxExtension'
        ).split())

        print "elapsed time: %d seconds" % (datetime.datetime.now() -
                                            starttime).seconds
    else:
        msm_output = os.path.splitext(source_wxs)[0] + ".msm"
        system(['light', '-ext', 'WixUtilExtension', '-o', msm_output] +
               [get_wixobj(file) for file in sources])
Example #3
0
def build_msi():
    get_nuget_packages()

    add_wix_to_path()
    def get_wixobj(file):
        return os.path.splitext(file)[0] + ".wixobj"
    def adjacent_file(file):
        return os.path.join(os.path.dirname(__file__), file)

    gen_analysis_tool_wxi.main(r"..\analysis_tools", diskId='5')

    # gen_dir_from_vc: "explicit is better than implicit"
    #  consider: generated files are left on disk after an svn switch, and get included in an installer that shouldn't have them
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\PCC\PCC",)
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\isis_meta\isis_meta",)
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\material_library\MaterialLibraryInterface",)
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\meta_nrmm\meta_nrmm",)
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\py_modelica\py_modelica",)
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\py_modelica_exporter\py_modelica_exporter",)
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\cad_library\cad_library",)
    gen_dir_wxi.gen_dir_from_vc(r"..\meta\DesignDataPackage\lib\python", "DesignDataPackage_python.wxi", "DesignDataPackage_python")
    gen_dir_wxi.main(r"CAD_Installs\Proe ISIS Extensions", "Proe_ISIS_Extensions_x64.wxi", "Proe_ISIS_Extensions_x64", diskId='4') # do not call gen_dir_from_vc, it would exclude CADCreoCreateAssembly.exe
    gen_dir_wxi.gen_dir_from_vc(r"..\WebGME",)
    gen_dir_wxi.gen_dir_from_vc(r"..\meta\CyPhyML\icons",)
    gen_dir_wxi.gen_dir_from_vc(r"..\models\MassSpringDamper",)
    gen_dir_wxi.gen_dir_from_vc(r"..\models\Validation",)
    gen_dir_wxi.gen_dir_from_vc(r"..\bin", diskId='3')
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\PCC\PCC",)
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\isis_meta\isis_meta",)
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\meta_nrmm\meta_nrmm",)
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\py_modelica\py_modelica",)
    gen_dir_wxi.gen_dir_from_vc(r"..\src\Python27Packages\py_modelica_exporter\py_modelica_exporter",)
    gen_dir_wxi.gen_dir_from_vc(r"..\src\CADAssembler\Python", id="CADPython")
    gen_dir_wxi.gen_dir_from_vc(r"..\meta\DesignDataPackage\lib\python", "DesignDataPackage_python.wxi", "DesignDataPackage_python")

    def get_svnversion():
        p = subprocess.Popen("git rev-list HEAD --count".split(), stdout=subprocess.PIPE)
        out, err = p.communicate()
        return out.strip() or '5'
        #import subprocess
        #p = subprocess.Popen(['svnversion', '-n', adjacent_file('..')], stdout=subprocess.PIPE)
        #out, err = p.communicate()
        #if p.returncode:
        #    raise subprocess.CalledProcessError(p.returncode, 'svnversion')
        #return out
    svnversion = get_svnversion()
    
    print "SVN version: " + str(get_svnversion())
    sourcedir = adjacent_file('')

    def get_gitversion():
        p = subprocess.Popen("git rev-parse --short HEAD".split(), stdout=subprocess.PIPE)
        out, err = p.communicate()
        #if p.returncode:
        #    raise subprocess.CalledProcessError(p.returncode, 'svnversion')
        return out.strip() or 'unknown'
    
    gitversion = get_gitversion()
    
    import glob
    if len(sys.argv[1:]) > 0:
        source_wxs = sys.argv[1]
    else:
        source_wxs = 'META_x64.wxs'
    sources_all = glob.glob(sourcedir + '*.wxi') + glob.glob(sourcedir + source_wxs)
    sources = []
    include_wxis = []

    # For each each ComponentGroupRef in "source_wxs" and "analysis_tools.wxi",
    # add its corresponding file to "include_wxis"
    for wxs in glob.glob(sourcedir + source_wxs) + glob.glob(sourcedir + 'analysis_tools.wxi'):
        print 'Processing WXS: ' + wxs
        tree = ET.parse(wxs)
        root = tree.getroot()
        #print root
        all_nodes = root.findall('.//')
        for node in all_nodes:
            if node.tag == '{http://schemas.microsoft.com/wix/2006/wi}ComponentGroupRef':
                include_wxis.append(node.attrib['Id'] + '.wxi')
                include_wxis.append(node.attrib['Id'] + '_x64.wxi')
                if 'Proe' in node.attrib['Id'] + '_x64.wxi':
                    print node.attrib['Id'] + '_x64.wxi'
            if node.tag == '{http://schemas.microsoft.com/wix/2006/wi}ComponentRef':
                include_wxis.append(node.attrib['Id'].rsplit( ".", 1 )[ 0 ] + '.wxi')
                include_wxis.append(node.attrib['Id'].rsplit( ".", 1 )[ 0 ] + '_x64.wxi')

    # For each file in include_wxis, check for ComponentGroupRef and ComponentRef.
    # Add any that you find
    index = 0
    while index < len(include_wxis):
        wxi = include_wxis[index]
        index += 1

        if not os.path.exists(wxi):
            continue

        tree = ET.parse(wxi)
        root = tree.getroot()

        all_nodes = root.findall('.//')
        for node in all_nodes:
            if node.tag == '{http://schemas.microsoft.com/wix/2006/wi}ComponentGroupRef':
                include_wxis.append(node.attrib['Id'] + '.wxi')
                include_wxis.append(node.attrib['Id'] + '_x64.wxi')
            if node.tag == '{http://schemas.microsoft.com/wix/2006/wi}ComponentRef':
                include_wxis.append(node.attrib['Id'].rsplit( ".", 1 )[ 0 ] + '.wxi')
                include_wxis.append(node.attrib['Id'].rsplit( ".", 1 )[ 0 ] + '_x64.wxi')

    sources = [source for source in sources_all if (os.path.basename(source) in include_wxis)]
    sources.append(source_wxs)

    if len(sources) == 0:
        raise Exception("0 sources found in " + sourcedir)

    defines = [ ('InterpreterBin', '../src/bin') ]

    def get_mta_versions(mta_file):
        import uuid
        metaproject = win32com.client.Dispatch("MGA.MgaMetaProject")
        metaproject.Open('MGA=' + mta_file)
        try:
            return ("{" + str(uuid.UUID(bytes_le=metaproject.GUID)).upper() + "}", metaproject.Version)
        finally:
            metaproject.Close()

    cyphy_versions = get_mta_versions(adjacent_file('../generated/CyPhyML/models/CyPhyML.mta'))
    defines.append(('GUIDSTRCYPHYML', cyphy_versions[0]))
    defines.append(('VERSIONSTRCYPHYML', cyphy_versions[1]))
    
    
    version = '14.13.'
    if 'M' in svnversion:
        version = version + '1'
    else:
        # this will crash for switched or sparse checkouts
        version = version + str(int(svnversion))
    print 'Installer version: ' + version
    defines.append(('VERSIONSTR', version))
    defines.append(('SVNVERSION', svnversion))
    defines.append(('GITVERSION', gitversion))

    from multiprocessing.pool import ThreadPool
    pool = ThreadPool()
    pool_exceptions = []
    def candle(source):
        try:
            arch = [ '-arch', ('x86' if source.find('x64') == -1 else 'x64') ]
            system(['candle', '-ext', 'WiXUtilExtension'] + ['-d' + d[0] + '=' + d[1] for d in defines ] + arch + [ '-out', get_wixobj(source), source] + ['-nologo'])
        except Exception as e:
            pool_exceptions.append(e)
            raise
    candle_results = pool.map_async(candle, sources, chunksize=1)
    pool.close()
    pool.join()
    if pool_exceptions:
        raise pool_exceptions[0]
    assert candle_results.successful()

    #ignore warning 1055, ICE82 from VC10 merge modules
    # ICE69: Mismatched component reference. Entry 'reg491FAFEB7F990D99C4A4D719B2A95253' of the Registry table belongs to component 'CyPhySoT.dll'. However, the formatted string in column 'Value' references file 'CyPhySoT.ico' which belongs to component 'CyPhySoT.ico'
    # ICE60: The file fil_5b64d789d9ad5473bc580ea7258a0fac is not a Font, and its version is not a companion file reference. It should have a language specified in the Language column.
    if source_wxs.startswith("META"):
        import datetime
        starttime = datetime.datetime.now()
        system(['light', '-sw1055', '-sice:ICE82', '-sice:ICE57', '-sice:ICE60', '-sice:ICE69', '-ext', 'WixNetFxExtension', '-ext', 'WixUIExtension', '-ext', 'WixUtilExtension', 
            # '-cc', os.path.join(this_dir, 'cab_cache'), '-reusecab', # we were getting errors during installation relating to corrupted cab files => disable cab cache
            '-o', os.path.splitext(source_wxs)[0] + ".msi"] + [ get_wixobj(file) for file in sources ])
        print "elapsed time: %d seconds" % (datetime.datetime.now() - starttime).seconds
    else:
        msm_output = os.path.splitext(source_wxs)[0] + ".msm"
        system(['light', '-ext', 'WixUtilExtension', '-o', msm_output] + [ get_wixobj(file) for file in sources ])