在 Windows 下使用 SCons 构建 boost::python 模块
Posted
技术标签:
【中文标题】在 Windows 下使用 SCons 构建 boost::python 模块【英文标题】:Building boost::python module with SCons under Windows 【发布时间】:2015-06-02 23:50:10 【问题描述】:我目前也在尝试使用 scons 构建一个 boost::python 模块。我设法在网上找到了一些代码 sn-ps 并将它们拼接在一起,以便它在 Linux 上正确构建。但是我在 Windows 上遇到了一些重大问题(使用 Visual Studio 2013 编译器)。代码如下:
import distutils.sysconfig, os,sys
def TOOL_BOOST_DISTUTILS(env):
vars = distutils.sysconfig.get_config_vars('CC', 'CXX', 'OPT', 'BASECFLAGS', 'CCSHARED', 'LDSHARED', 'SO')
for i in range(len(vars)):
if vars[i] is None:
vars[i] = ""
(cc, cxx, opt, basecflags, ccshared, ldshared, so_ext) = vars
env.AppendUnique(CPPPATH=[distutils.sysconfig.get_python_inc(), "D:/boost-vs2013/include/boost-1_57"])
if sys.platform == "win32":
print "Configuring for Windows"
env.AppendUnique(CXXFLAGS=["/MD","/EHsc"])
else:
env.AppendUnique(LIBS="boost_python")
env.AppendUnique(CXXFLAGS =["-std=c++11"])
env['SHLIBSUFFIX']=so_ext
env.AppendUnique(LIBPATH = [distutils.sysconfig.get_python_inc()+"/libs", distutils.sysconfig.PREFIX+"/libs","D:/boost-vs2013/lib"])
Default('.')
env=Environment(tools=['default', TOOL_BOOST_DISTUTILS],TARGET_ARCH = 'x86')
env.SharedLibrary(target='RunGA', source=['RunGA.cpp'])
在构建过程中,会创建以下文件:
运行GA.obj
运行GA.pyd
运行GA.exp
运行GA.lib
要导入模块,我需要一个 .dll 文件而不是 .lib,但我不确定如何正确执行此操作。
编辑 04.06.15: 尝试导入 RunGA 模块(通过“导入 RunGA”)时,我收到以下错误消息: 'ImportError: DLL load failed : 找不到指定的模块。'
EDIT2 04.06.15:
我已经设法解决了这个问题。事实证明,项目目录和系统路径中缺少带有 boost python 的 .dll 文件,而 RunGA.pyd 依赖于它。谢谢大家的帮助。
【问题讨论】:
pyd 是您要导入的文件。它是一个 dll,只是具有不同的扩展名。在 python 中输入“import RunGA”时会收到什么错误消息?它会在python路径中寻找RunGA.pyd,然后RunGA很可能会在系统路径中寻找其他dll,这是不同的。 @KennyOstrom 我编辑了帖子,为您的问题添加了答案。 这意味着python找到了它,但是加载dll(pyd)时出现操作系统错误。用depends.exe检查dll依赖。 我编辑了我的答案,用更多的话说同样的话。 【参考方案1】:您正在生成所需的 .dll,它刚刚被重命名为 .pyd 文件。在你的 python 模块加载它之前,它可能还需要在它的文件名中有一个前导 _
。您可以通过将以下行附加到您的 SConstruct 来获得它...
if sys.platform == "win32":
print "Configuring for Windows"
env.AppendUnique(CXXFLAGS=["/MD","/EHsc"])
env.Replace(LDMODULEPREFIX='_',
SHLIBPREFIX='_')
您可能看到的构建顺序是从您的RunGA.cpp
文件构建RunGA.obj
,然后构建库RunGA.lib
,然后使用RunGA.exp
和RunGA.lib
创建您的@ 987654328@。也就是说,它正在为您导出一个.dll
,然后将其重命名为.pyd
。
这与您在 Linux 上看到的不同,在 Linux 上您可能只会得到 RunGA.o
、RunGA.py
和 _RunGA.so
。在 Linux 上,动态库需要命名为 _MODULE.so
,在 Windows 上,需要命名为 _MODULE.pyd
。
【讨论】:
【参考方案2】:您已经在构建正确的文件,但您的问题表明您不知道如何导入。
有两个步骤。首先 python 必须找到并加载 dll https://docs.python.org/2/tutorial/modules.html
假设您有“C:\path\RunGA.pyd” 而RunGA的依赖都在系统路径上
set PYTHONPATH=C:\path
python
>>>import RunGA
然后pyd(实际上是一个dll)必须成功加载。例如,您几乎肯定会有“boost_pythonversion.dll”依赖项。您配置了构建环境以找到它,但它可能不在系统路径上,任何可执行文件都无法找到它(例如 python,它尝试导入模块,但找不到它的其他依赖项)。
http://www.dependencywalker.com/ 之类的程序对于确定加载另一个 dll 所需的 dll 非常方便。
【讨论】:
以上是关于在 Windows 下使用 SCons 构建 boost::python 模块的主要内容,如果未能解决你的问题,请参考以下文章