mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-09 03:04:10 -04:00
More robust removal of CRT dependencies from dlls in the windows build
Fixes a problem with the 64-bit ImageMagick core DLL getting corrupted by the old removal process.
This commit is contained in:
parent
9c7851ea05
commit
4e7ce1fece
@ -1,6 +1,6 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
# vim:fileencoding=UTF-8:ts=4:sw=4:sta:et:sts=4:ai
|
||||||
from __future__ import with_statement
|
from __future__ import with_statement, print_function
|
||||||
|
|
||||||
__license__ = 'GPL v3'
|
__license__ = 'GPL v3'
|
||||||
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
__copyright__ = '2009, Kovid Goyal <kovid@kovidgoyal.net>'
|
||||||
@ -50,6 +50,50 @@ def walk(dir):
|
|||||||
for f in record[-1]:
|
for f in record[-1]:
|
||||||
yield os.path.join(record[0], f)
|
yield os.path.join(record[0], f)
|
||||||
|
|
||||||
|
# Remove CRT dep from manifests {{{
|
||||||
|
def get_manifest_from_dll(dll):
|
||||||
|
import win32api, pywintypes
|
||||||
|
LOAD_LIBRARY_AS_DATAFILE = 2
|
||||||
|
d = win32api.LoadLibraryEx(os.path.abspath(dll), 0, LOAD_LIBRARY_AS_DATAFILE)
|
||||||
|
try:
|
||||||
|
resources = win32api.EnumResourceNames(d, 24)
|
||||||
|
except pywintypes.error as err:
|
||||||
|
if err.winerror == 1812:
|
||||||
|
return None, None # no resource section (probably a .pyd file)
|
||||||
|
raise
|
||||||
|
if resources:
|
||||||
|
return resources[0], win32api.LoadResource(d, 24, resources[0])
|
||||||
|
return None, None
|
||||||
|
|
||||||
|
def update_manifest(dll, rnum, manifest):
|
||||||
|
import win32api
|
||||||
|
h = win32api.BeginUpdateResource(dll, 0)
|
||||||
|
win32api.UpdateResource(h, 24, rnum, manifest)
|
||||||
|
win32api.EndUpdateResource(h, 0)
|
||||||
|
|
||||||
|
_crt_pat = re.compile(r'Microsoft\.VC\d+\.CRT')
|
||||||
|
|
||||||
|
def remove_CRT_from_manifest(dll, log=print):
|
||||||
|
from lxml import etree
|
||||||
|
rnum, manifest = get_manifest_from_dll(dll)
|
||||||
|
if manifest is None:
|
||||||
|
return
|
||||||
|
root = etree.fromstring(manifest)
|
||||||
|
found = False
|
||||||
|
for ai in root.xpath('//*[local-name()="assemblyIdentity" and @name]'):
|
||||||
|
name = ai.get('name')
|
||||||
|
if _crt_pat.match(name):
|
||||||
|
p = ai.getparent()
|
||||||
|
pp = p.getparent()
|
||||||
|
pp.remove(p)
|
||||||
|
if len(pp) == 0:
|
||||||
|
pp.getparent().remove(pp)
|
||||||
|
found = True
|
||||||
|
if found:
|
||||||
|
manifest = etree.tostring(root, pretty_print=True)
|
||||||
|
update_manifest(dll, rnum, manifest)
|
||||||
|
log('\t', os.path.basename(dll))
|
||||||
|
# }}}
|
||||||
|
|
||||||
class Win32Freeze(Command, WixMixIn):
|
class Win32Freeze(Command, WixMixIn):
|
||||||
|
|
||||||
@ -101,26 +145,12 @@ class Win32Freeze(Command, WixMixIn):
|
|||||||
The dependency on the CRT is removed from the manifests of all DLLs.
|
The dependency on the CRT is removed from the manifests of all DLLs.
|
||||||
This allows the CRT loaded by the .exe files to be used instead.
|
This allows the CRT loaded by the .exe files to be used instead.
|
||||||
'''
|
'''
|
||||||
search_pat = re.compile(r'(?is)<dependency>.*Microsoft\.VC\d+\.CRT')
|
self.info('Removing CRT dependency from manifests of:')
|
||||||
repl_pat = re.compile(
|
|
||||||
r'(?is)<dependency>.*?Microsoft\.VC\d+\.CRT.*?</dependency>')
|
|
||||||
|
|
||||||
for dll in chain(walk(self.dll_dir), walk(self.plugins_dir)):
|
for dll in chain(walk(self.dll_dir), walk(self.plugins_dir)):
|
||||||
bn = self.b(dll)
|
bn = self.b(dll)
|
||||||
if bn.rpartition('.')[-1] not in {'dll', 'pyd'}:
|
if bn.lower().rpartition('.')[-1] not in {'dll', 'pyd'}:
|
||||||
continue
|
continue
|
||||||
with open(dll, 'rb') as f:
|
remove_CRT_from_manifest(dll, self.info)
|
||||||
raw = f.read()
|
|
||||||
match = search_pat.search(raw)
|
|
||||||
if match is None:
|
|
||||||
continue
|
|
||||||
self.info('Removing CRT dependency from manifest of: %s'%bn)
|
|
||||||
# Blank out the bytes corresponding to the dependency specification
|
|
||||||
nraw = repl_pat.sub(lambda m: b' '*len(m.group()), raw)
|
|
||||||
if len(nraw) != len(raw) or nraw == raw:
|
|
||||||
raise Exception('Something went wrong with %s'%bn)
|
|
||||||
with open(dll, 'wb') as f:
|
|
||||||
f.write(nraw)
|
|
||||||
|
|
||||||
def initbase(self):
|
def initbase(self):
|
||||||
if self.e(self.base):
|
if self.e(self.base):
|
||||||
@ -276,10 +306,9 @@ class Win32Freeze(Command, WixMixIn):
|
|||||||
if not x.endswith('.dll'):
|
if not x.endswith('.dll'):
|
||||||
os.remove(self.j(dirpath, x))
|
os.remove(self.j(dirpath, x))
|
||||||
|
|
||||||
print
|
self.info('\nAdding third party dependencies')
|
||||||
print 'Adding third party dependencies'
|
|
||||||
|
|
||||||
print '\tAdding misc binary deps'
|
self.info('\tAdding misc binary deps')
|
||||||
bindir = os.path.join(SW, 'bin')
|
bindir = os.path.join(SW, 'bin')
|
||||||
for x in ('pdftohtml', 'pdfinfo', 'pdftoppm'):
|
for x in ('pdftohtml', 'pdfinfo', 'pdftoppm'):
|
||||||
shutil.copy2(os.path.join(bindir, x+'.exe'), self.base)
|
shutil.copy2(os.path.join(bindir, x+'.exe'), self.base)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user