有些python模块需要以编译源码的方式安装,在ubuntu上有自带的gcc可以编译,然而在windows上,只能用msvc的编译器。python会推荐使用某版本的编译器,但事实上,我们可以用现有的任何MSVC编译环境完成编译。MSVC可以不用重新安装,可以直接用本机上有的MSVC(甚至不需要图形界面,只要可以使用命令行即可)。
windows下python的编译环境主要的配置文件有两个,一个文件是_msvccompiler.py文件,另外一个文件是msvc.py。如果你安装的虚拟python目录是X:\virtual_python\Python38_msvc,那么就是X:\virtual_python\Python38_msvc\Lib\site-packages\setuptools\_distutils\_msvccompiler.py和X:\virtual_python\Python38_msvc\Lib\site-packages\setuptools\msvc.py。
大多需要编译的源文件都需要vs2017以上才能支持,下面以visual studio 2017为例,介绍如何修改这两个文件。
1._msvccompiler.py
找到函数initialize,修改self._paths这一句,改为vs2017对应的路径即可。这里是把
self._paths = vc_env.get('path', '')
这一句注释掉,改成了
self._paths = 'J:/VS/Visual Studio 2017 Ultimate/VC/Tools/MSVC/14.10.25017/bin/HostX64/x64;J:/VS/Visual Studio 2017 Ultimate/Common7/IDE'
def initialize(self, plat_name=None):
# multi-init means we would need to check platform same each time...
assert not self.initialized, "don't init multiple times"
if plat_name is None:
plat_name = get_platform()
# sanity check for platforms to prevent obscure errors later.
if plat_name not in PLAT_TO_VCVARS:
raise DistutilsPlatformError(
f"--plat-name must be one of {tuple(PLAT_TO_VCVARS)}"
)
# Get the vcvarsall.bat spec for the requested platform.
plat_spec = PLAT_TO_VCVARS[plat_name]
vc_env = _get_vc_env(plat_spec)
if not vc_env:
raise DistutilsPlatformError(
"Unable to find a compatible Visual Studio installation."
)
self._configure(vc_env)
#self._paths = vc_env.get('path', '')
#vs2017
self._paths = 'J:/VS/Visual Studio 2017 Ultimate/VC/Tools/MSVC/14.10.25017/bin/HostX64/x64;J:/VS/Visual Studio 2017 Ultimate/Common7/IDE'
下面还有编译和链接的一些选项,可以根据需要修改,例如在ldflags加入'/VERBOSE'可以显示一些额外信息等。
2. msvc.py
def msvc14_get_vc_env(plat_spec):
"""
Patched "distutils._msvccompiler._get_vc_env" for support extra
Microsoft Visual C++ 14.X compilers.
Set environment without use of "vcvarsall.bat".
Parameters
----------
plat_spec: str
Target architecture.
Return
------
dict
environment
"""
# Always use backport from CPython 3.8
try:
#return _msvc14_get_vc_env(plat_spec)
#2017
env = dict(include='J:\\VS\\Visual Studio 2017 Ultimate\\VC\\INCLUDE;G:\\vs2015_C\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.10240.0\\ucrt;G:\\vs2015_C\\Program Files (x86)\\Windows Kits\\8.0\\Include\\shared;G:\\vs2015_C\\Program Files (x86)\\Windows Kits\8.0\\Include\\um;D:\\Visual Studio 2017 Enterprise\\VC\\Tools\\MSVC\\14.10.25017\\include',lib='J:\\VS\\Visual Studio 2017 Ultimate\\VC\\LIB";"J:\\VS\\Visual Studio 2017 Ultimate\\VC\\ATLMFC\\LIB\\amd64";"J:\\VS\\Visual Studio 2017 Ultimate\\DIA SDK\\LIB\\amd64";G:\\vs2015_C\\Program Files (x86)\\Windows Kits\\8.0\\Lib\\win8\\um\\x64;D:\\Visual Studio 2017 Enterprise\\VC\\Tools\\MSVC\\14.10.25017\\lib\\x64;G:\\vs2015_C\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.10240.0\\ucrt\\x64', py_vcruntime_redist='')
return env
找到
把return _msvc14_get_vc_env(plat_spec)注释掉,改为
env = dict(include='J:\\VS\\Visual Studio 2017 Ultimate\\VC\\INCLUDE;G:\\vs2015_C\\Program Files (x86)\\Windows Kits\\10\\Include\\10.0.10240.0\\ucrt;G:\\vs2015_C\\Program Files (x86)\\Windows Kits\\8.0\\Include\\shared;G:\\vs2015_C\\Program Files (x86)\\Windows Kits\8.0\\Include\\um;D:\\Visual Studio 2017 Enterprise\\VC\\Tools\\MSVC\\14.10.25017\\include',lib='J:\\VS\\Visual Studio 2017 Ultimate\\VC\\LIB";"J:\\VS\\Visual Studio 2017 Ultimate\\VC\\ATLMFC\\LIB\\amd64";"J:\\VS\\Visual Studio 2017 Ultimate\\DIA SDK\\LIB\\amd64";G:\\vs2015_C\\Program Files (x86)\\Windows Kits\\8.0\\Lib\\win8\\um\\x64;D:\\Visual Studio 2017 Enterprise\\VC\\Tools\\MSVC\\14.10.25017\\lib\\x64;G:\\vs2015_C\\Program Files (x86)\\Windows Kits\\10\\Lib\\10.0.10240.0\\ucrt\\x64', py_vcruntime_redist='')
return env
以上是在64位python中使用64位编译器的修改方法。vs 2017改成其他的版本,例如2015,2012都没有问题。重申一下,想要省心省力的话,编译器可以用免安装的。
如果是32位python,需要使用32位的编译器,方法类似,只要把编译器的路径和库文件的路径修改为32位的路径即可。
修改后可以用一个简单的helloword例子进行测试。请见下一篇文章《用vs studio编译一个c python 模块》