Skip to content

Commit

Permalink
Don't mangle Visual C++ runtime redistributable DLLs
Browse files Browse the repository at this point in the history
Mangling these offers questionable benefit. Also, it is believed that at
least one of these DLLs uses process-global state, and having 2 versions
in the same process can cause problems.
  • Loading branch information
adang1345 committed Aug 1, 2024
1 parent 7912ebe commit 1259b78
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 16 deletions.
17 changes: 16 additions & 1 deletion delvewheel/_dll_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,22 @@ def platform_tag_to_type(cls, tag: str) -> typing.Optional['MachineType']:
}

# Set of regular expressions of DLLs whose names should not be mangled.
no_mangle_regexes = {}
# Currently, these consist of the Microsoft Visual C++ runtime redistributable
# files. Mangling these offers questionable benefit, as they are meant to be
# shared among different applications, and most have a version number in the
# filename. Also, if one of these DLLs uses process-global state, then having 2
# versions of that DLL loaded into the same process could cause issues.
no_mangle_regexes = {
re.compile(r'vcruntime\d.*\.dll'), # Microsoft C runtime
re.compile(r'vccorlib\d.*\.dll'), # Microsoft VC WinRT core
re.compile(r'msvcp[\d_].*\.dll'), # Microsoft C/C++ runtime
re.compile(r'msvcr(t|\d.*)\.dll'), # Microsoft C runtime
re.compile(r'concrt\d.*\.dll'), # Microsoft concurrency runtime
re.compile(r'mfcm?\d.*\.dll'), # Microsoft Foundation Class
re.compile(r'vcamp\d.*\.dll'), # Microsoft C++ AMP runtime
re.compile(r'vcomp(\d.*|)\.dll'), # Microsoft C/C++ OpenMP runtime
re.compile(r'ucrtbase(d|_.*|)\.dll'), # Microsoft C runtime
}

# ignore_names_x86 is a set containing the lowercase names of all DLLs that can
# be assumed to be present on 32-bit x86 Windows 7 SP1 or later. These are all
Expand Down
33 changes: 18 additions & 15 deletions tests/run_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ def test_basic(self):
check_call(['delvewheel', 'repair', '--add-path', 'iknowpy', 'iknowpy/iknowpy-1.5.3-cp312-cp312-win_amd64.whl'])
with zipfile.ZipFile('wheelhouse/iknowpy-1.5.3-cp312-cp312-win_amd64.whl') as wheel:
for path in zipfile.Path(wheel, 'iknowpy.libs/').iterdir():
if path.name in ('.load-order-iknowpy-1.5.3',):
if path.name in ('.load-order-iknowpy-1.5.3', 'concrt140.dll', 'msvcp140.dll'):
continue
self.assertTrue(is_mangled(path.name), f'{path.name} is mangled')
self.assertTrue(import_iknowpy_successful())
Expand All @@ -237,7 +237,7 @@ def test_no_mangle_1(self):
check_call(['delvewheel', 'repair', '--add-path', 'iknowpy', '--no-mangle', 'iKnOwEnGiNe.dLl', 'iknowpy/iknowpy-1.5.3-cp312-cp312-win_amd64.whl'])
with zipfile.ZipFile('wheelhouse/iknowpy-1.5.3-cp312-cp312-win_amd64.whl') as wheel:
for path in zipfile.Path(wheel, 'iknowpy.libs/').iterdir():
if path.name in ('.load-order-iknowpy-1.5.3',):
if path.name in ('.load-order-iknowpy-1.5.3', 'concrt140.dll', 'msvcp140.dll'):
continue
if path.name.startswith('iKnowEngine'):
self.assertFalse(is_mangled(path.name), f'{path.name} is not mangled')
Expand All @@ -250,7 +250,7 @@ def test_no_mangle_2(self):
check_call(['delvewheel', 'repair', '--add-path', 'iknowpy', '--no-mangle', 'iKnowEngine.dll;iKnowBase.dll', 'iknowpy/iknowpy-1.5.3-cp312-cp312-win_amd64.whl'])
with zipfile.ZipFile('wheelhouse/iknowpy-1.5.3-cp312-cp312-win_amd64.whl') as wheel:
for path in zipfile.Path(wheel, 'iknowpy.libs/').iterdir():
if path.name in ('.load-order-iknowpy-1.5.3',):
if path.name in ('.load-order-iknowpy-1.5.3', 'concrt140.dll', 'msvcp140.dll'):
continue
if path.name.startswith('iKnowEngine') or path.name.startswith('iKnowBase'):
self.assertFalse(is_mangled(path.name), f'{path.name} is not mangled')
Expand Down Expand Up @@ -291,7 +291,7 @@ def test_add_dll_1(self):
with zipfile.ZipFile('wheelhouse/iknowpy-1.5.3-cp312-cp312-win_amd64.whl') as wheel:
kernel32_found = False
for path in zipfile.Path(wheel, 'iknowpy.libs/').iterdir():
if path.name in ('.load-order-iknowpy-1.5.3',):
if path.name in ('.load-order-iknowpy-1.5.3', 'concrt140.dll', 'msvcp140.dll'):
continue
if path.name.startswith('kernel32'):
self.assertFalse(is_mangled(path.name), f'{path.name} is not mangled')
Expand All @@ -306,7 +306,7 @@ def test_add_dll_1_exist(self):
check_call(['delvewheel', 'repair', '--add-path', 'iknowpy', '--add-dll', 'iKnowEngine.dll', 'iknowpy/iknowpy-1.5.3-cp312-cp312-win_amd64.whl'])
with zipfile.ZipFile('wheelhouse/iknowpy-1.5.3-cp312-cp312-win_amd64.whl') as wheel:
for path in zipfile.Path(wheel, 'iknowpy.libs/').iterdir():
if path.name in ('.load-order-iknowpy-1.5.3',):
if path.name in ('.load-order-iknowpy-1.5.3', 'concrt140.dll', 'msvcp140.dll'):
continue
self.assertTrue(is_mangled(path.name), f'{path.name} is mangled')
self.assertTrue(import_iknowpy_successful())
Expand All @@ -317,7 +317,7 @@ def test_add_dll_2_repeat(self):
with zipfile.ZipFile('wheelhouse/iknowpy-1.5.3-cp312-cp312-win_amd64.whl') as wheel:
kernel32_found = False
for path in zipfile.Path(wheel, 'iknowpy.libs/').iterdir():
if path.name in ('.load-order-iknowpy-1.5.3',):
if path.name in ('.load-order-iknowpy-1.5.3', 'concrt140.dll', 'msvcp140.dll'):
continue
if path.name.startswith('kernel32'):
self.assertFalse(is_mangled(path.name), f'{path.name} is not mangled')
Expand All @@ -334,7 +334,7 @@ def test_add_dll_2(self):
kernelbase_found = False
with zipfile.ZipFile('wheelhouse/iknowpy-1.5.3-cp312-cp312-win_amd64.whl') as wheel:
for path in zipfile.Path(wheel, 'iknowpy.libs/').iterdir():
if path.name in ('.load-order-iknowpy-1.5.3',):
if path.name in ('.load-order-iknowpy-1.5.3', 'concrt140.dll', 'msvcp140.dll'):
continue
if path.name.lower().startswith('kernel32'):
self.assertFalse(is_mangled(path.name), f'{path.name} is not mangled')
Expand Down Expand Up @@ -401,7 +401,7 @@ def test_ignore_existing(self):
check_call(['delvewheel', 'repair', '--add-path', 'iknowpy', '--ignore-existing', 'iknowpy/iknowpy-1.5.3-0ignore-cp312-cp312-win_amd64.whl'])
with zipfile.ZipFile('wheelhouse/iknowpy-1.5.3-0ignore-cp312-cp312-win_amd64.whl') as wheel:
for path in zipfile.Path(wheel, 'iknowpy.libs/').iterdir():
if path.name in ('.load-order-iknowpy-1.5.3',):
if path.name in ('.load-order-iknowpy-1.5.3', 'concrt140.dll', 'msvcp140.dll'):
continue
if any(path.name.startswith(x) for x in ('iKnowBase', 'iKnowShell', 'iKnowCore', 'iKnowALI', 'msvcp140')):
self.assertFalse(is_mangled(path.name), f'{path.name} is not mangled')
Expand All @@ -418,7 +418,10 @@ def test_analyze_existing(self):
i = 0
for path in zipfile.Path(wheel, 'simpleext-0.0.1.data/platlib/').iterdir():
self.assertTrue(any(path.name.startswith(x) for x in ('icudt74', 'msvcp140', 'simpledll')))
self.assertTrue(is_mangled(path.name))
if path.name.startswith('msvcp140'):
self.assertFalse(is_mangled(path.name))
else:
self.assertTrue(is_mangled(path.name))
i += 1
self.assertEqual(3, i)

Expand All @@ -433,7 +436,7 @@ def test_ignore_in_wheel(self):
check_call(['delvewheel', 'repair', '--add-path', 'iknowpy', '--ignore-in-wheel', 'iknowpy/iknowpy-1.5.3-0ignore-cp312-cp312-win_amd64.whl'])
with zipfile.ZipFile('wheelhouse/iknowpy-1.5.3-0ignore-cp312-cp312-win_amd64.whl') as wheel:
for path in zipfile.Path(wheel, 'iknowpy.libs/').iterdir():
if path.name in ('.load-order-iknowpy-1.5.3',):
if path.name in ('.load-order-iknowpy-1.5.3', 'concrt140.dll', 'msvcp140.dll'):
continue
if any(path.name.startswith(x) for x in ('iKnowBase', 'iKnowShell', 'iKnowCore', 'iKnowALI', 'msvcp140')):
self.assertFalse(is_mangled(path.name), f'{path.name} is not mangled')
Expand All @@ -451,7 +454,7 @@ def test_ignore_existing_override(self):
iknowengine_found = False
with zipfile.ZipFile('wheelhouse/iknowpy-1.5.3-0ignore-cp312-cp312-win_amd64.whl') as wheel:
for path in zipfile.Path(wheel, 'iknowpy.libs/').iterdir():
if path.name in ('.load-order-iknowpy-1.5.3',):
if path.name in ('.load-order-iknowpy-1.5.3', 'concrt140.dll', 'msvcp140.dll'):
continue
if any(path.name.startswith(x) for x in ('iKnowEngine', 'iKnowBase', 'iKnowShell', 'iKnowCore', 'iKnowALI', 'msvcp140')):
self.assertFalse(is_mangled(path.name), f'{path.name} is not mangled')
Expand Down Expand Up @@ -1275,7 +1278,7 @@ def test_repair_basic(self):
check_call(['delvewheel', 'repair', '--add-path', 'iknowpy', 'iknowpy/iknowpy-1.5.3-cp312-cp312-win_amd64.whl'])
with zipfile.ZipFile('wheelhouse/iknowpy-1.5.3-cp312-cp312-win_amd64.whl') as wheel:
for path in zipfile.Path(wheel, 'iknowpy.libs/').iterdir():
if path.name in ('.load-order-iknowpy-1.5.3',):
if path.name in ('.load-order-iknowpy-1.5.3', 'concrt140.dll', 'msvcp140.dll'):
continue
self.assertTrue(is_mangled(path.name), f'{path.name} is mangled')

Expand All @@ -1284,7 +1287,7 @@ def test_repair_no_mangle_1(self):
check_call(['delvewheel', 'repair', '--add-path', 'iknowpy', '--no-mangle', 'iKnOwEnGiNe.dLl', 'iknowpy/iknowpy-1.5.3-cp312-cp312-win_amd64.whl'])
with zipfile.ZipFile('wheelhouse/iknowpy-1.5.3-cp312-cp312-win_amd64.whl') as wheel:
for path in zipfile.Path(wheel, 'iknowpy.libs/').iterdir():
if path.name in ('.load-order-iknowpy-1.5.3',):
if path.name in ('.load-order-iknowpy-1.5.3', 'concrt140.dll', 'msvcp140.dll'):
continue
if path.name.startswith('iKnowEngine'):
self.assertFalse(is_mangled(path.name), f'{path.name} is not mangled')
Expand All @@ -1296,7 +1299,7 @@ def test_repair_no_mangle_2(self):
check_call(['delvewheel', 'repair', '--add-path', 'iknowpy', '--no-mangle', 'iKnowEngine.dll:iKnowBase.dll', 'iknowpy/iknowpy-1.5.3-cp312-cp312-win_amd64.whl'])
with zipfile.ZipFile('wheelhouse/iknowpy-1.5.3-cp312-cp312-win_amd64.whl') as wheel:
for path in zipfile.Path(wheel, 'iknowpy.libs/').iterdir():
if path.name in ('.load-order-iknowpy-1.5.3',):
if path.name in ('.load-order-iknowpy-1.5.3', 'concrt140.dll', 'msvcp140.dll'):
continue
if path.name.startswith('iKnowEngine') or path.name.startswith('iKnowBase'):
self.assertFalse(is_mangled(path.name), f'{path.name} is not mangled')
Expand All @@ -1309,7 +1312,7 @@ def test_add_dll_1(self):
with zipfile.ZipFile('wheelhouse/iknowpy-1.5.3-cp312-cp312-win_amd64.whl') as wheel:
kernel32_found = False
for path in zipfile.Path(wheel, 'iknowpy.libs/').iterdir():
if path.name in ('.load-order-iknowpy-1.5.3',):
if path.name in ('.load-order-iknowpy-1.5.3', 'concrt140.dll', 'msvcp140.dll'):
continue
if path.name.startswith('kernel32'):
self.assertFalse(is_mangled(path.name), f'{path.name} is not mangled')
Expand Down

0 comments on commit 1259b78

Please sign in to comment.