在 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.expRunGA.lib 创建您的@ 987654328@。也就是说,它正在为您导出一个.dll,然后将其重命名为.pyd

这与您在 Linux 上看到的不同,在 Linux 上您可能只会得到 RunGA.oRunGA.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 模块的主要内容,如果未能解决你的问题,请参考以下文章

scons安装和使用

linux自动化构建工具-scons指南

如何使用 Eclipse CDT 构建 SCons 项目?

使用 SCons 着色编译器诊断

SCons — 程序构建工具

WSL + Scons:无此类文件或目录