Skip to content

Commit c66e06c

Browse files
petrutlucian94alexpilotti
authored andcommitted
Statically link the VC runtime
Before switching to distutils, we were statically linking the VC runtime. distutils, on the other hand, is enforcing dynamic linking. The reason is that some extensions were hitting some runtime limitations when statically linking it: https://bugs.python.org/issue38597 This admittedly hacky patch will override the hardcoded distutils /MD flag. It should work with all the supported Python versions. For future versions, we're probably going to request the Python community a better way of statically linking the runtime when aware of the limitations.
1 parent cb5f014 commit c66e06c

2 files changed

Lines changed: 40 additions & 0 deletions

File tree

PyMI/README.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@ version, use the following:
122122
123123
python setup.py bdist_wheel
124124
125+
Make sure to use the Visual Studio toolset that matches the Python version
126+
that you're targetting: https://wiki.python.org/moin/WindowsCompilers.
127+
128+
By default, we're statically linking the VC runtime. To enable dynamic
129+
linking, set ``$env:PYMI_VCRUNTIME_DYNAMIC_LINKING="y"``.
130+
125131
Debug builds
126132
^^^^^^^^^^^^
127133

setup.py

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
from distutils import _msvccompiler
2+
from distutils import ccompiler
13
import os
24
import setuptools
35

@@ -6,6 +8,38 @@
68
except ImportError:
79
pass
810

11+
12+
# MSVCP140.dll isn't included by Python along with the C runtime,
13+
# for which reason we're going to statically link it for now.
14+
# This can be disabled using the PYMI_VCRUNTIME_DYNAMIC_LINKING
15+
# flag.
16+
# Unfortunately distutils harcodes the "/MD" flag.
17+
class Compiler(_msvccompiler.MSVCCompiler):
18+
def initialize(self, *args, **kwargs):
19+
super(Compiler, self).initialize(*args, **kwargs)
20+
21+
dynamically_link_runtime = os.environ.get(
22+
"PYMI_VCRUNTIME_DYNAMIC_LINKING", "").lower() in (
23+
"yes", "y", "1", "true", "t")
24+
if not dynamically_link_runtime:
25+
self._statically_link_runtime()
26+
27+
def _statically_link_runtime(self):
28+
if '/MD' in self.compile_options:
29+
self.compile_options.remove('/MD')
30+
self.compile_options.append('/MT')
31+
if '/MDd' in self.compile_options_debug:
32+
self.compile_options_debug.remove('/MDd')
33+
self.compile_options_debug.append('/MTd')
34+
35+
36+
def new_compiler(plat=None, compiler=None, verbose=0, dry_run=0, force=0):
37+
return Compiler(None, dry_run, force)
38+
39+
40+
ccompiler.new_compiler = new_compiler
41+
42+
943
# Setuptools requires relative paths
1044
mi_dir = 'MI'
1145
pymi_dir = 'PyMI'

0 commit comments

Comments
 (0)