如何使用 Python、pybind11 和 Mingw-w64 构建 setup.py 以编译 C++ 扩展?

Raf*_*ael 8 c++ python distutils mingw-w64 pybind11

我目前正在尝试编写一个“setup.py”脚本,当用户安装 python 包时,它会自动编译我与“pybind11”绑定的 C++ 扩展。在 Windows 中,使用“VS19 MSVC”编译器实现它没有任何问题。但是,如果用户安装了“MinGW-w64”,我会尝试实现它。

这些是包文件:

**main.cpp**

    #include <pybind11/pybind11.h>
    
    int add(int i, int j) {
        返回 i + j;
    }
    
    命名空间 py = pybind11;
    
    PYBIND11_MODULE(pybind11_example, m) {
    
        m.def("添加", &add);
    }
**main.cpp**

    #include <pybind11/pybind11.h>
    
    int add(int i, int j) {
        return i + j;
    }
    
    namespace py = pybind11;
    
    PYBIND11_MODULE(pybind11_example, m) {
    
        m.def("add", &add);
    }

将两个文件放在同一文件夹中并从命令提示符运行:

**setup.py**

    from setuptools import setup, Extension
    import pybind11
    
    ext_modules = [
        Extension(
            'pybind11_example',
            sources = ['main.cpp'],
            include_dirs=[pybind11.get_include()],
            language='c++'
        ),
    ]
    
    setup(
        name='pybind11_example',
        ext_modules=ext_modules
    )
Run Code Online (Sandbox Code Playgroud)

如果用户VS19 MSVC安装了编译器,它会成功生成**pybind11_example.pyd**可以测试与 python 一起运行的文件:

    python setup.py build
Run Code Online (Sandbox Code Playgroud)

但是,如果用户Mingw-w64安装了编译器,则会引发错误,指出需要 Visual Studio 2015。

请注意,我可以很容易地编写**main.cpp****pybind11_example.pyd**手动Mingw-w64运行:

    g++ -static -shared -std=c++11 -DMS_WIN64 -fPIC -I C:\...\Python\Python38\Lib\site-packages\pybind11\include -I C:\ ... \Python\Python38\include -L C:\ ... \Python\Python38\libs main.cpp -o pybind11_example.pyd -lPython38
Run Code Online (Sandbox Code Playgroud)

有没有办法写成**setup.py**,如果用户有带MinGW-w64编译器的Windows,在安装包时自动编译**main.cpp****pybind11_example.pyd**,而无需手动制作?

Pak*_*ula 2

检查这个问题的答案。他们尝试解决相反的情况,强制使用 msvc 而不是 mingw,但 setup.cfg 的方法可能会对您有所帮助。

这里答案演示了如何根据安装工具所做的选择来指定命令行参数:如果是 msvc,则为一组参数,对于 mingw 则为另一组。

我相信第二种方法应该适合您的需求 - 无论安装哪个编译器,您都拥有正确的命令行来构建模块。