如何使用 mingw-w64、Python 和 pybind11 手动构建 C++ 扩展?
How can I build manually C++ extension with mingw-w64, Python and pybind11?
我的最终目标是从我的 C++ 代码编译 Python C++ 扩展。目前,为了开始,我正在关注 pybind11
文档第一步中的一个简单示例。我的工作环境是 Windows 7 Professional 64 位,mingw-w64 (x86_64-8.1.0-posix-seh-rt_v6-rev0) 和 Anaconda3 with Python 3.7.4 64 位。我有 2 个文件。第一个是 C++ 文件 -- example.cpp
#include <pybind11/pybind11.h>
int add(int i, int j) {
return i + j;
}
PYBIND11_MODULE(example, m) {
m.doc() = "pybind11 example plugin"; // optional module docstring
m.def("add", &add, "A function which adds two numbers");
}
我使用以下命令编译 C++ 文件:
C:/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/g++.exe -shared -std=c++11 -DMS_WIN64 -fPIC -ID:\Users\ADAS\anaconda3\Include -ID:\Users\ADAS\anaconda3\Library\include -ID:\Users\ADAS\anaconda3\pkgs\python-3.7.4-h5263a28_0\include -Wall -LD:\Users\ADAS\anaconda3\Lib -LD:\Users\ADAS\anaconda3\pkgs\python-3.7.4-h5263a28_0\libs example.cpp -o example.dll -lPython37
编译成功,得到example.dll
个文件
在下一步我 运行 以下 Python 代码 -- example.py:
import example
def main():
i, j = (1, 2)
res = example.add(i, j)
print("%d + %d = %d" % (i, j, res))
if __name__ == '__main__':
main()
我遇到了一个问题。 import example
行似乎没有给我任何警告或错误,但是 res = example.add(i, j)
行给我一个错误:
AttributeError: module 'example' has no attribute 'add'
在 Ubuntu 18.04 下,我成功编译并 运行 在 Python 上面的示例中,但在我的办公室我只有 Windows 7.
问题:我的设置或命令行有什么问题?是否可以在不更改 Windows 下的当前 C++ 编译器(mingw-w64 版本 8.1)的情况下解决此问题?
难以置信!问题只是编译文件的文件扩展名。一旦我将 .dll
更改为 .pyd
,Python 示例 (example.py
) 就是 运行 没有任何问题!
所以新的命令行是:
C:/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/g++.exe -shared -std=c++11 -DMS_WIN64 -fPIC -ID:\Users\ADAS\anaconda3\Include -ID:\Users\ADAS\anaconda3\Library\include -ID:\Users\ADAS\anaconda3\pkgs\python-3.7.4-h5263a28_0\include -Wall -LD:\Users\ADAS\anaconda3\Lib -LD:\Users\ADAS\anaconda3\pkgs\python-3.7.4-h5263a28_0\libs example.cpp -o example.pyd -lPython37
因为我对命令行参数做了一些实验,所以我将再次检查所有编译器参数以确保它给出成功的结果。如果仍然需要进行一些更改,我会通知您。
更新 1:
根据Python3默认设置,Windows下编译的C++文件的完整扩展名必须是.cp37-win_amd64.pyd
.
我们可以通过终端命令获取扩展名:
python -c "from distutils import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX'))"
这相当于 pybind11 文档中的 python3-config --extension-suffix
。 python3-config
脚本未在 Windows 环境中实现(至少在 Anaconda3 发行版中)。
我的最终目标是从我的 C++ 代码编译 Python C++ 扩展。目前,为了开始,我正在关注 pybind11
文档第一步中的一个简单示例。我的工作环境是 Windows 7 Professional 64 位,mingw-w64 (x86_64-8.1.0-posix-seh-rt_v6-rev0) 和 Anaconda3 with Python 3.7.4 64 位。我有 2 个文件。第一个是 C++ 文件 -- example.cpp
#include <pybind11/pybind11.h>
int add(int i, int j) {
return i + j;
}
PYBIND11_MODULE(example, m) {
m.doc() = "pybind11 example plugin"; // optional module docstring
m.def("add", &add, "A function which adds two numbers");
}
我使用以下命令编译 C++ 文件:
C:/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/g++.exe -shared -std=c++11 -DMS_WIN64 -fPIC -ID:\Users\ADAS\anaconda3\Include -ID:\Users\ADAS\anaconda3\Library\include -ID:\Users\ADAS\anaconda3\pkgs\python-3.7.4-h5263a28_0\include -Wall -LD:\Users\ADAS\anaconda3\Lib -LD:\Users\ADAS\anaconda3\pkgs\python-3.7.4-h5263a28_0\libs example.cpp -o example.dll -lPython37
编译成功,得到example.dll
个文件
在下一步我 运行 以下 Python 代码 -- example.py:
import example
def main():
i, j = (1, 2)
res = example.add(i, j)
print("%d + %d = %d" % (i, j, res))
if __name__ == '__main__':
main()
我遇到了一个问题。 import example
行似乎没有给我任何警告或错误,但是 res = example.add(i, j)
行给我一个错误:
AttributeError: module 'example' has no attribute 'add'
在 Ubuntu 18.04 下,我成功编译并 运行 在 Python 上面的示例中,但在我的办公室我只有 Windows 7.
问题:我的设置或命令行有什么问题?是否可以在不更改 Windows 下的当前 C++ 编译器(mingw-w64 版本 8.1)的情况下解决此问题?
难以置信!问题只是编译文件的文件扩展名。一旦我将 .dll
更改为 .pyd
,Python 示例 (example.py
) 就是 运行 没有任何问题!
所以新的命令行是:
C:/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/bin/g++.exe -shared -std=c++11 -DMS_WIN64 -fPIC -ID:\Users\ADAS\anaconda3\Include -ID:\Users\ADAS\anaconda3\Library\include -ID:\Users\ADAS\anaconda3\pkgs\python-3.7.4-h5263a28_0\include -Wall -LD:\Users\ADAS\anaconda3\Lib -LD:\Users\ADAS\anaconda3\pkgs\python-3.7.4-h5263a28_0\libs example.cpp -o example.pyd -lPython37
因为我对命令行参数做了一些实验,所以我将再次检查所有编译器参数以确保它给出成功的结果。如果仍然需要进行一些更改,我会通知您。
更新 1:
根据Python3默认设置,Windows下编译的C++文件的完整扩展名必须是.cp37-win_amd64.pyd
.
我们可以通过终端命令获取扩展名:
python -c "from distutils import sysconfig; print(sysconfig.get_config_var('EXT_SUFFIX'))"
这相当于 pybind11 文档中的 python3-config --extension-suffix
。 python3-config
脚本未在 Windows 环境中实现(至少在 Anaconda3 发行版中)。