Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在windows/visual studio上使用waf构建python扩展模块?_Python_Windows_Visual Studio_Swig_Waf - Fatal编程技术网

如何在windows/visual studio上使用waf构建python扩展模块?

如何在windows/visual studio上使用waf构建python扩展模块?,python,windows,visual-studio,swig,waf,Python,Windows,Visual Studio,Swig,Waf,我试图找出如何使用构建python扩展模块,但我遇到了难题。考虑一个简单的树,如: foo.h #pragma once class Foo { public: Foo(); const int &a() const; int &a(); private: int m_a; }; inline const int &Foo::a() const { return m_a; } inline int &Foo::a() { return m_

我试图找出如何使用构建python扩展模块,但我遇到了难题。考虑一个简单的树,如:

foo.h

#pragma once

class Foo {
public:
  Foo();
  const int &a() const;
  int &a();

private:
  int m_a;
};

inline const int &Foo::a() const { return m_a; }

inline int &Foo::a() { return m_a; }
foo.cpp

#include "foo.h"

Foo::Foo() : m_a(0) {}
#include <iostream>

#include "foo.h"

using namespace std;
int main() {
  Foo foo;
  cout << foo.a() << endl;
  foo.a() = 10;
  cout << foo.a() << endl;
}
foo.i

%module foo

%{
#include "foo.h"
%}

%include "foo.h"
main.cpp

#include "foo.h"

Foo::Foo() : m_a(0) {}
#include <iostream>

#include "foo.h"

using namespace std;
int main() {
  Foo foo;
  cout << foo.a() << endl;
  foo.a() = 10;
  cout << foo.a() << endl;
}
wscript

import subprocess
from pathlib import Path


def configure(conf):
    conf.env.MSVC_VERSIONS = ["msvc 15.0"]
    conf.env.MSVC_TARGETS = ["x86"]
    conf.load("msvc python swig")
    conf.check_python_version((3, 6, 8))

    # This method is not working properly on windows/virtualenv
    # conf.check_python_headers()

    # Maybe something like this could help?
    # from distutils import sysconfig
    # print(sysconfig.get_python_inc())

    conf.check_swig_version()


def build(bld):
    bld.program(source=["main.cpp", "foo.cpp"], cxxflags=["/EHsc"], target="test")

    bld.shlib(
        features="cxx",
        source="foo.cpp",
        target="foo",
        includes=".",
        export_includes=".",
        name="FOO",
    )

    # bld.program(
    #     source = 'main.cpp',
    #     target = 'main',
    #     use = ['FOO'],
    #     rpath = ['$ORIGIN'],
    # )

    # bld(
    #     features = 'cxx cxxshlib pyext',
    #     source = 'foo.i',
    #     target = '_foo',
    #     swig_flags = '-c++ -python -Wall',
    #     includes = '.',
    #     use  = 'FOO',
    #     rpath = ['$ORIGIN', ],
    #  )


def run(bld):
    root_path = Path(bld.path.abspath())
    subprocess.run(str(root_path / "build/test.exe"))
我在这里已经面临的第一个问题是,当我执行
waf distclean configure build
时,会出现以下错误:

(py382_64) D:\swigtest>waf distclean configure build
'distclean' finished successfully (0.006s)
Setting top to                           : D:\swigtest
Setting out to                           : D:\swigtest\build
Checking for program 'CL'                : C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\bin\HostX86\x86\CL.exe
Checking for program 'CL'                : C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\bin\HostX86\x86\CL.exe
Checking for program 'LINK'              : C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\bin\HostX86\x86\LINK.exe
Checking for program 'LIB'               : C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\VC\Tools\MSVC\14.26.28801\bin\HostX86\x86\LIB.exe
Checking for program 'MT'                : C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x86\MT.exe
Checking for program 'RC'                : C:\Program Files (x86)\Windows Kits\10\bin\10.0.18362.0\x86\RC.exe
Checking for program 'python'            : d:\virtual_envs\py368_32\scripts\python.exe
Checking for program 'swig'              : D:\software\swig\swig.exe
Checking for python version >= 3.6.8     : 3.6.8
Checking for swig version                : 4.0.0
'configure' finished successfully (1.538s)
Waf: Entering directory `D:\swigtest\build'
[1/5] Compiling foo.cpp
[2/5] Compiling main.cpp
[3/5] Compiling foo.cpp
foo.cpp

foo.cpp

[4/5] Linking build\foo.dll
main.cpp

[5/5] Linking build\test.exe
Waf: Leaving directory `D:\swigtest\build'
Build failed
-> missing file: 'D:\\swigtest\\build\\foo.lib'

问题:我如何解决这个小问题?在任何情况下,我这里的主要问题是,在windows上使用和waf生成python扩展模块的正确方法是什么?

您可以通过将库类型从共享(
shlib
)更改为静态(
stlib
)来修复当前构建,即

要构建python扩展模块,可以使用以下方法:

def build(bld):
    bld.program(source=["main.cpp", "foo.cpp"], cxxflags=["/EHsc"], target="test")

    bld.stlib(
        features="cxx",
        source="foo.cpp",
        target="foo",
        includes=".",
        export_includes=".",
        name="FOO",
    )

    bld(
        features = 'cxx cxxshlib pyext',
        source = 'foo.i',
        target = '_foo.pyd',
        swig_flags = '-c++ -python -Wall',
        includes = '.',
        use = 'FOO',
    )
这将把dll库输出到名为
\u foo.pyd
的文件和python脚本
foo.py

我并不是说这是正确的方法,但它对我起了作用

此外,在使用扩展名时(例如从foo import foo导入的
),请确保这些文件位于python的搜索路径上(使用
PYTHONPATH
sys.path.append
),否则可能会出现以下错误:

  • ModuleNotFoundError:没有名为“\u foo”的模块
  • ImportError:导入时DLL加载失败\u foo:参数不正确
我在尝试直接从主目录运行
main.py
时遇到了第二个错误,并通过在
sys.path.append
调用
main.py
中使用绝对(而不是相对)路径解决了它

编辑
我使用的是python 3.8.5和Visual Studio 2017
下面是完整的wscript
您需要更改cxflags、LDFLAGS中引用的Python头和库的路径(尽管我想有更好的配置方法)

编辑2 最初我得到的是注释中提到的错误,但现在我发现我无意中绕过了,将
foo.I
中的模块声明从文件的顶部移动到底部

%{
#include "foo.h"
%}

%include "foo.h"

%module foo

我建议您从没有waf的
waf
开始,并了解swig是什么。你应该生成C++包装源,而不是从你的类FO中产生一个简单的DLL。为什么你假设我以前没有使用过Sigg?事实上,这些年来我一直在使用swig 1)手动2)与setuptools 3)与定制构建系统4)与cmake。。。所以现在我只是想了解如何将它与
waf
一起使用。不幸的是,您将在github上看到的一些小示例已经损坏,或者只是在unix上工作。。。是的,我知道你需要生成C++包装,但是在达到这个点之前(你会看到注释代码)我试图找出一些以前的必要条件;您的输出没有说明任何有关生成包装器的内容—只编译foo.cpp、main.cpp和链接foo.dll。再次,我建议你看看在引擎盖下做了什么,并将其与不使用waf解决包装问题进行比较。嗯,从你的评论中,我清楚地看到,我的问题没有正确地传达给观众。好的,明天如果我有时间的话,我会发布这些步骤,你是如何手工编译这些简单的东西的,以及如何将这些步骤翻译成waf的。是的,我想使用waf主要是因为我试图包装的实际项目非常复杂,有几个依赖项。。。这是waf应该发光的地方:)好主意。可能使用CMake或Python的distutils的小项目,您正在使用waf进行工作。我尝试运行您的示例,但它对我不起作用,它告诉我类似于
无法打开文件D:\swigtest\build\foo.swigwrap\u 3.cxx:无效参数
。我正在尝试使用VirtualNV btw运行此脚本。。。不管怎样,你能把你的完整的wscript上传过来,这样我就可以在这里复制了吗?也。。。这个
conf.check\u python\u headers()
在这里工作不正常。您使用的是哪一个python版本,visual studio版本?谢谢,这里有一点您的脚本,我想这不是查找python include/libs的正确方法,但比使用硬编码路径要好。。在任何情况下,由于某种原因,当我运行
waf build
时,它告诉我
无法打开文件D:\swigtest\build\foo.swigwrap_2.cxx:无效参数
,并且在build文件夹中没有生成包装器代码。明天我会继续看这个,你的答案已经值得+1思考这是我研究过的课程,这是我的,我想知道你为什么没有得到这个错误:/我提到的错误已经被修复了
%{
#include "foo.h"
%}

%include "foo.h"

%module foo