diff --git a/Include/Python.h b/Include/Python.h
index 4c7c9a4..e53a765 100644
--- a/Include/Python.h
+++ b/Include/Python.h
@@ -133,4 +133,13 @@
 #include "fileutils.h"
 #include "pyfpe.h"
 
+/* Define portable noinline attribute */
+#if _MSC_VER
+#define Py_NOINLINE _declspec(noinline)
+#elif __clang__ || __GNUC__
+#define Py_NOINLINE __attribute__ ((noinline))
+#else
+#define Py_NOINLINE
+#endif
+
 #endif /* !Py_PYTHON_H */
diff --git a/Lib/distutils/_msvccompiler.py b/Lib/distutils/_msvccompiler.py
index b120273..da92bd4 100644
--- a/Lib/distutils/_msvccompiler.py
+++ b/Lib/distutils/_msvccompiler.py
@@ -105,22 +105,23 @@ def _get_vc_env(plat_spec):
         env['py_vcruntime_redist'] = vcruntime
     return env
 
-def _find_exe(exe, paths=None):
+def _find_exe(cmd, paths=None):
     """Return path to an MSVC executable program.
 
     Tries to find the program in several places: first, one of the
     MSVC program search paths from the registry; next, the directories
     in the PATH environment variable.  If any of those work, return an
     absolute path that is known to exist.  If none of them work, just
-    return the original program name, 'exe'.
+    return the original program name, 'cmd'.
     """
     if not paths:
         paths = os.getenv('path').split(os.pathsep)
     for p in paths:
-        fn = os.path.join(os.path.abspath(p), exe)
-        if os.path.isfile(fn):
-            return fn
-    return exe
+        fn = os.path.join(os.path.abspath(p), cmd)
+        for abs_path in [fn, fn+'.exe']:
+            if os.path.isfile(abs_path):
+                return abs_path
+    return cmd
 
 # A map keyed by get_platform() return values to values accepted by
 # 'vcvarsall.bat'. Always cross-compile from x86 to work with the
@@ -199,11 +200,15 @@ class MSVCCompiler(CCompiler) :
             raise DistutilsPlatformError("Unable to find a compatible "
                 "Visual Studio installation.")
 
+        compiler_to_use = os.environ.get('CC', 'cl').strip()
+        linker_to_use = os.environ.get('LD', 'link').strip()
+        archiver_to_use = os.environ.get('AR', 'lib').strip()
+
         self._paths = vc_env.get('path', '')
         paths = self._paths.split(os.pathsep)
-        self.cc = _find_exe("cl.exe", paths)
-        self.linker = _find_exe("link.exe", paths)
-        self.lib = _find_exe("lib.exe", paths)
+        self.cc = _find_exe(compiler_to_use, paths)
+        self.linker = _find_exe(linker_to_use, paths)
+        self.lib = _find_exe(archiver_to_use, paths)
         self.rc = _find_exe("rc.exe", paths)   # resource compiler
         self.mc = _find_exe("mc.exe", paths)   # message compiler
         self.mt = _find_exe("mt.exe", paths)   # message compiler
@@ -224,7 +229,8 @@ class MSVCCompiler(CCompiler) :
         self.compile_options = [
             '/nologo', '/Ox', '/W3', '/GL', '/DNDEBUG'
         ]
-        self.compile_options.append('/MD' if self._vcruntime_redist else '/MT')
+        if not os.getenv("DISTUTILS_USE_SDK"):
+            self.compile_options.append('/MD' if self._vcruntime_redist else '/MT')
 
         self.compile_options_debug = [
             '/nologo', '/Od', '/MDd', '/Zi', '/W3', '/D_DEBUG'
@@ -247,6 +253,11 @@ class MSVCCompiler(CCompiler) :
         self.ldflags_static = [*ldflags]
         self.ldflags_static_debug = [*ldflags_debug]
 
+        self.compile_options.extend(os.environ.get('CFLAGS', '').strip().split())
+        self.compile_options_debug.extend(os.environ.get('CFLAGS', '').strip().split())
+        self.ldflags_shared.extend(os.environ.get('LDFLAGS', '').strip().split())
+        self.ldflags_shared_debug.extend(os.environ.get('LDFLAGS', '').strip().split())
+
         self._ldflags = {
             (CCompiler.EXECUTABLE, None): self.ldflags_exe,
             (CCompiler.EXECUTABLE, False): self.ldflags_exe,
@@ -507,7 +518,7 @@ class MSVCCompiler(CCompiler) :
     # ccompiler.py.
 
     def library_dir_option(self, dir):
-        return "/LIBPATH:" + dir
+        return "/LIBPATH:" + dir.replace('"', '').rstrip('\\')
 
     def runtime_library_dir_option(self, dir):
         raise DistutilsPlatformError(
diff --git a/Lib/distutils/msvc9compiler.py b/Lib/distutils/msvc9compiler.py
index 2119127..cbba8e0 100644
--- a/Lib/distutils/msvc9compiler.py
+++ b/Lib/distutils/msvc9compiler.py
@@ -349,12 +349,15 @@ class MSVCCompiler(CCompiler) :
             raise DistutilsPlatformError("--plat-name must be one of %s" %
                                          (ok_plats,))
 
-        if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"):
+        compiler_to_use = os.environ.get('CC', 'cl').strip()
+        linker_to_use = os.environ.get('LD', 'link').strip()
+        archiver_to_use = os.environ.get('AR', 'lib').strip()
+        if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe(compiler_to_use):
             # Assume that the SDK set up everything alright; don't try to be
             # smarter
-            self.cc = "cl.exe"
-            self.linker = "link.exe"
-            self.lib = "lib.exe"
+            self.cc = compiler_to_use
+            self.linker = linker_to_use
+            self.lib = archiver_to_use
             self.rc = "rc.exe"
             self.mc = "mc.exe"
         else:
@@ -383,9 +386,9 @@ class MSVCCompiler(CCompiler) :
                        "version of the compiler, but it isn't installed."
                        % self.__product)
 
-            self.cc = self.find_exe("cl.exe")
-            self.linker = self.find_exe("link.exe")
-            self.lib = self.find_exe("lib.exe")
+            self.cc = self.find_exe(compiler_to_use)
+            self.linker = self.find_exe(linker_to_use)
+            self.lib = self.find_exe(archiver_to_use)
             self.rc = self.find_exe("rc.exe")   # resource compiler
             self.mc = self.find_exe("mc.exe")   # message compiler
             #self.set_path_env_var('lib')
@@ -418,9 +421,13 @@ class MSVCCompiler(CCompiler) :
             self.ldflags_shared_debug = [
                 '/DLL', '/nologo', '/INCREMENTAL:no', '/DEBUG'
                 ]
+            self.ldflags_shared_debug.extend(os.environ.get('LDFLAGS', '').strip().split())
         self.ldflags_static = [ '/nologo']
 
         self.initialized = True
+        self.compile_options.extend(os.environ.get('CFLAGS', '').strip().split())
+        self.compile_options_debug.extend(os.environ.get('CFLAGS', '').strip().split())
+        self.ldflags_shared.extend(os.environ.get('LDFLAGS', '').strip().split())
 
     # -- Worker methods ------------------------------------------------
 
@@ -740,7 +747,7 @@ class MSVCCompiler(CCompiler) :
     # ccompiler.py.
 
     def library_dir_option(self, dir):
-        return "/LIBPATH:" + dir
+        return '/LIBPATH:' + dir.replace('"', '').rstrip('\\')
 
     def runtime_library_dir_option(self, dir):
         raise DistutilsPlatformError(
@@ -768,24 +775,25 @@ class MSVCCompiler(CCompiler) :
 
     # Helper methods for using the MSVC registry settings
 
-    def find_exe(self, exe):
+    def find_exe(self, cmd):
         """Return path to an MSVC executable program.
 
         Tries to find the program in several places: first, one of the
         MSVC program search paths from the registry; next, the directories
         in the PATH environment variable.  If any of those work, return an
         absolute path that is known to exist.  If none of them work, just
-        return the original program name, 'exe'.
+        return the original program name, 'cmd'.
         """
         for p in self.__paths:
-            fn = os.path.join(os.path.abspath(p), exe)
-            if os.path.isfile(fn):
-                return fn
+            fn = os.path.join(os.path.abspath(p), cmd)
+            for abs_path in [fn, fn+'.exe']:
+                if os.path.isfile(abs_path):
+                    return abs_path
 
         # didn't find it; try existing path
         for p in os.environ['Path'].split(';'):
-            fn = os.path.join(os.path.abspath(p),exe)
-            if os.path.isfile(fn):
-                return fn
-
-        return exe
+            fn = os.path.join(os.path.abspath(p), cmd)
+            for abs_path in [fn, fn+'.exe']:
+                if os.path.isfile(abs_path):
+                    return abs_path
+        return cmd
diff --git a/Lib/distutils/msvccompiler.py b/Lib/distutils/msvccompiler.py
index 1048cd4..6bbf333 100644
--- a/Lib/distutils/msvccompiler.py
+++ b/Lib/distutils/msvccompiler.py
@@ -247,12 +247,15 @@ class MSVCCompiler(CCompiler) :
 
     def initialize(self):
         self.__paths = []
-        if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe("cl.exe"):
+        compiler_to_use = os.environ.get('CC', 'cl').strip()
+        linker_to_use = os.environ.get('LD', 'link').strip()
+        archiver_to_use = os.environ.get('AR', 'lib').strip()
+        if "DISTUTILS_USE_SDK" in os.environ and "MSSdk" in os.environ and self.find_exe(compiler_to_use):
             # Assume that the SDK set up everything alright; don't try to be
             # smarter
-            self.cc = "cl.exe"
-            self.linker = "link.exe"
-            self.lib = "lib.exe"
+            self.cc = compiler_to_use
+            self.linker = linker_to_use
+            self.lib = archiver_to_use
             self.rc = "rc.exe"
             self.mc = "mc.exe"
         else:
@@ -264,9 +267,9 @@ class MSVCCompiler(CCompiler) :
                        "version of the compiler, but it isn't installed."
                        % self.__product)
 
-            self.cc = self.find_exe("cl.exe")
-            self.linker = self.find_exe("link.exe")
-            self.lib = self.find_exe("lib.exe")
+            self.cc = self.find_exe(compiler_to_use)
+            self.linker = self.find_exe(linker_to_use)
+            self.lib = self.find_exe(archiver_to_use)
             self.rc = self.find_exe("rc.exe")   # resource compiler
             self.mc = self.find_exe("mc.exe")   # message compiler
             self.set_path_env_var('lib')
@@ -306,6 +309,10 @@ class MSVCCompiler(CCompiler) :
         self.ldflags_static = [ '/nologo']
 
         self.initialized = True
+        self.compile_options.extend(os.environ.get('CFLAGS', '').strip().split())
+        self.compile_options_debug.extend(os.environ.get('CFLAGS', '').strip().split())
+        self.ldflags_shared.extend(os.environ.get('LDFLAGS', '').strip().split())
+        self.ldflags_shared_debug.extend(os.environ.get('LDFLAGS', '').strip().split())
 
     # -- Worker methods ------------------------------------------------
 
@@ -534,7 +541,7 @@ class MSVCCompiler(CCompiler) :
     # ccompiler.py.
 
     def library_dir_option(self, dir):
-        return "/LIBPATH:" + dir
+        return '/LIBPATH:' + dir.replace('"', '').rstrip('\\')
 
     def runtime_library_dir_option(self, dir):
         raise DistutilsPlatformError(
@@ -562,27 +569,28 @@ class MSVCCompiler(CCompiler) :
 
     # Helper methods for using the MSVC registry settings
 
-    def find_exe(self, exe):
+    def find_exe(self, cmd):
         """Return path to an MSVC executable program.
 
         Tries to find the program in several places: first, one of the
         MSVC program search paths from the registry; next, the directories
         in the PATH environment variable.  If any of those work, return an
         absolute path that is known to exist.  If none of them work, just
-        return the original program name, 'exe'.
+        return the original program name, 'cmd'.
         """
         for p in self.__paths:
-            fn = os.path.join(os.path.abspath(p), exe)
-            if os.path.isfile(fn):
-                return fn
+            fn = os.path.join(os.path.abspath(p), cmd)
+            for abs_path in [fn, fn+'.exe']:
+                if os.path.isfile(abs_path):
+                    return abs_path
 
         # didn't find it; try existing path
         for p in os.environ['Path'].split(';'):
-            fn = os.path.join(os.path.abspath(p),exe)
-            if os.path.isfile(fn):
-                return fn
-
-        return exe
+            fn = os.path.join(os.path.abspath(p), cmd)
+            for abs_path in [fn, fn+'.exe']:
+                if os.path.isfile(abs_path):
+                    return abs_path
+        return cmd
 
     def get_msvc_paths(self, path, platform='x86'):
         """Get a list of devstudio directories (include, lib or path).
diff --git a/Lib/distutils/spawn.py b/Lib/distutils/spawn.py
index ce85901..d05f67a 100644
--- a/Lib/distutils/spawn.py
+++ b/Lib/distutils/spawn.py
@@ -51,6 +51,7 @@ def _nt_quote_args(args):
     # contains quotes?  What other magic characters, other than spaces,
     # have to be escaped?  Is there an escaping mechanism other than
     # quoting?)
+
     for i, arg in enumerate(args):
         if ' ' in arg:
             args[i] = '"%s"' % arg
diff --git a/Lib/distutils/tests/test_spawn.py b/Lib/distutils/tests/test_spawn.py
index 5edc24a..6f677f7 100644
--- a/Lib/distutils/tests/test_spawn.py
+++ b/Lib/distutils/tests/test_spawn.py
@@ -22,7 +22,6 @@ class SpawnTestCase(support.TempdirManager,
             res = _nt_quote_args(args)
             self.assertEqual(res, wanted)
 
-
     @unittest.skipUnless(os.name in ('nt', 'posix'),
                          'Runs only under posix or nt')
     def test_spawn(self):
diff --git a/Lib/site.py b/Lib/site.py
index f20c692..1988090 100644
--- a/Lib/site.py
+++ b/Lib/site.py
@@ -474,6 +474,24 @@ def venv(known_paths):
     return known_paths
 
 
+def setenv():
+    """Set environment for additional binaries"""
+    if sys.platform == 'win32':
+        def extendkey(key, value):
+            if os.getenv(key) is None:
+                os.environ[key] = value
+            else:
+                os.environ[key] = os.pathsep.join([value] + os.environ[key].split(os.pathsep))
+
+        for redist in ['DLLs', r'DLLs\mkl', ]:
+            redist_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), redist)
+
+            if os.path.exists(redist_dir):
+                extendkey('PATH', redist_dir)
+
+    # nothing (yet) on non-windows
+
+
 def execsitecustomize():
     """Run custom site specific code, if available."""
     try:
@@ -532,6 +550,7 @@ def main():
     setquit()
     setcopyright()
     sethelper()
+    setenv()
     if not sys.flags.isolated:
         enablerlcompleter()
     execsitecustomize()
diff --git a/Modules/signalmodule.c b/Modules/signalmodule.c
index e27075b..f3910f1 100644
--- a/Modules/signalmodule.c
+++ b/Modules/signalmodule.c
@@ -1593,6 +1593,7 @@ _clear_pending_signals(void)
     }
 }
 
+Py_NOINLINE
 void
 PyOS_AfterFork(void)
 {
diff --git a/Python/ceval.c b/Python/ceval.c
index 9cac771..aaa3385 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -711,6 +711,7 @@ PyEval_EvalFrame(PyFrameObject *f) {
     return PyEval_EvalFrameEx(f, 0);
 }
 
+Py_NOINLINE
 PyObject *
 PyEval_EvalFrameEx(PyFrameObject *f, int throwflag)
 {
diff --git a/Python/import.c b/Python/import.c
index cd865a5..dec5233 100644
--- a/Python/import.c
+++ b/Python/import.c
@@ -331,6 +331,7 @@ static const char * const sys_files[] = {
 
 /* Un-initialize things, as good as we can */
 
+Py_NOINLINE
 void
 PyImport_Cleanup(void)
 {
diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c
index a4f7f82..da3c40b 100644
--- a/Python/pylifecycle.c
+++ b/Python/pylifecycle.c
@@ -474,6 +474,7 @@ Py_InitializeEx(int install_sigs)
     _Py_InitializeEx_Private(install_sigs, 1);
 }
 
+Py_NOINLINE
 void
 Py_Initialize(void)
 {
@@ -548,6 +549,7 @@ flush_std_files(void)
 
 */
 
+Py_NOINLINE
 int
 Py_FinalizeEx(void)
 {
diff --git a/Python/pystate.c b/Python/pystate.c
index 65c244e..ea989be 100644
--- a/Python/pystate.c
+++ b/Python/pystate.c
@@ -382,6 +382,7 @@ _PyState_ClearModules(void)
     }
 }
 
+Py_NOINLINE
 void
 PyThreadState_Clear(PyThreadState *tstate)
 {
@@ -523,6 +524,7 @@ PyThreadState_Get(void)
 }
 
 
+Py_NOINLINE
 PyThreadState *
 PyThreadState_Swap(PyThreadState *newts)
 {
diff --git a/setup.py b/setup.py
index f04bf22..354143f 100644
--- a/setup.py
+++ b/setup.py
@@ -1978,6 +1978,8 @@ class PyBuildExt(build_ext):
                    '_ctypes/cfield.c']
         depends = ['_ctypes/ctypes.h']
         math_libs = self.detect_math_libs()
+        cflags = sysconfig.get_config_var('CFLAGS')
+        is_static = re.search(r'-static', cflags)
 
         if host_platform == 'darwin':
             sources.append('_ctypes/malloc_closure.c')
@@ -2040,7 +2042,7 @@ class PyBuildExt(build_ext):
                           'ffi_wrapper_h'.format(ffi_h))
         ffi_lib = None
         if ffi_inc is not None:
-            for lib_name in ('ffi', 'ffi_pic'):
+            for lib_name in ('ffi', 'ffi_pic' if is_static else 'ffi'):
                 if (self.compiler.find_library_file(lib_dirs, lib_name)):
                     ffi_lib = lib_name
                     break
