pybind11尽管规格说明

发布于 2025-02-05 09:01:10 字数 2174 浏览 1 评论 0 原文

我试图用Pybind11将一些C ++代码暴露于Python。我特别想执行某个C ++标准(例如C ++ 11),因为需要在不同的系统上编译相同的.cpp文件。 中添加setuptools。

ext_modules = [
    Pybind11Extension(
        modulename,
        sources=[filename],
        language='c++',
        cxx_std=11
    ),
]

按照官方的示例在此 python setup.py install 在我的Windows机器和Linux机器上(实际上是使用Linux Backend的Google Colab)。我通过添加 py :: print(__ cplusplus); 在代码中检查了使用的标准。在Linux计算机上,添加 CXX_STD = 11 后,标准从C ++ 14更改为C ++ 11。但是,在我自己的Windows机器上,标准保留为C ++ 98。在这两种情况下,裸露的代码均可以为将其导入为模块(Windows上的.pyd文件和Linux上的一个.SO文件),并按预期工作。这很奇怪,因为:

(1)根据 pybind11extension 的文档,它“用pybind11构建C ++ 11+扩展模块。”。当最小要求为C ++ 11时,成功地使用C ++ 98编译我的代码并不能使我的代码保持一致。

(2)我有GCC版本8.1.0(通过检查 g ++ -v ),该版本应支持C ++的最新标准。此外,如果我使用G ++命令来编译普通的CPP文件,则说C ++ 14,这意味着C ++ 14是默认值。

标准的这种差异引起了很多麻烦,因为有时代码在我的Windows机器上起作用,但是在Linux上编译时会失败。

现在,我对C ++编译器的内容相对较新,因此我可能会缺少明显的东西。有什么想法解决这个问题吗?

更新:经过一些讨论,似乎 setup.py 在Windows上使用MSVC。然后,这个问题成为 this ,它仍未解决( setup.cfg 提到的方法不起作用。我可以指定 - 编译器MSVC ,但如果我写 - 编译器mingw32 < /code>它引起了几个错误: gcc:error: /ehsc:no这样的文件或目录< /code < /code>, gcc:error: /bigobj:no of Spe文件或目录,<代码> GCC:错误:/std:C ++ 14:没有这样的文件或目录)。

更新2:使用Spectras的方法,可以证实 setup.py 使用MSVC,它也具有C ++ 14作为Ernerist可能的标准。但是,我仍然想执行GCC,以便在Windows和Linux上使用相同的编译器。为了执行GCC,我尝试了以下命令(env_csmar是我的磁盘f下的anaconda虚拟环境):

d:\ mingw-w64 \ x86_64-8.1.0.0.0-posix-seh-seh-seh-seh-seh-seh-rt_v6-rev0 gcc.exe -static -shared -ssd = c ++ 11 -dms_win64 -fpic“ -if:\ ... \ env_csmar \ lib \ lib \ lib \ site -packages \ pybind11 \ include” - 包括“” -lf:\ ... \ env_csmar \ libs'-c example_cpp.cpp -o example_cpp.o

此作用,并且可以将.O文件导入我的窗口上的模块。但是,它仍然说它是使用MSVC和C ++ 14( #IFDEF _MSVC_LANG )编译的。为什么这是?

I am trying to expose some c++ code to Python with pybind11. I specifically would like to enforce a certain c++ standard (say c++11), as the same .cpp file would need to be compiled on different systems. Following the official example to compile with setuptools in this repository, I modified part of the code as follows:

ext_modules = [
    Pybind11Extension(
        modulename,
        sources=[filename],
        language='c++',
        cxx_std=11
    ),
]

I ran python setup.py install on my windows machine and a Linux machine (it's actually Google Colab, which uses Linux backend). I checked the standard used by adding py::print(__cplusplus); in code. On the Linux machine, the standard changed from c++14 to c++ 11 after adding cxx_std=11. However, on my own windows machine, the standard remained as c++98. In both cases, the exposed code can be sucefully imported as a module (a .pyd file on windows and a .so file on linux) and works as intended. This is very strange because:

(1) According to the documentation for Pybind11Extension, it "Build a C++11+ Extension module with pybind11.". It does not make sence for my code to be compiled with c++98 successfully when the minimum requirement is c++11.

(2) I have gcc version 8.1.0 (by checking g++ -v), which should support the latest standard of c++. Additionally, if I use g++ command to compile a normal cpp file, it says c++14, which means c++14 is the default.

This difference of standard is causing a lot of trouble because sometimes code works on my windows machine but fails when compiled on Linux.

Now, I am relatively new to stuff about c++ compilers, so I might be missing something obvious. Any idea how to solve this?

Update: After some discussion it seems that setup.py uses MSVC on windows. This question then becomes a duplicate of this, which remains unsolved (the setup.cfg method mentioned does not work. I could specify --compiler msvc but if I write --compiler mingw32 it raise several errors: gcc: error: /EHsc: No such file or directory, gcc: error: /bigobj: No such file or directory, gcc: error: /std:c++14: No such file or directory).

Update 2: With the method by spectras it is confirmed that setup.py uses MSVC, which also has c++14 as earlist possible standard. However, I still want to enforce GCC so I could have the same compiler on windows and linux. To enforce GCC, I tried the following command (env_csmar is an anaconda virtual environment under my disk F):

D:\mingw-w64\x86_64-8.1.0-posix-seh-rt_v6-rev0\mingw64\bin\gcc.exe -static -shared -std=c++11 -DMS_WIN64 -fPIC "-IF:\...\env_csmar\lib\site-packages\pybind11\include" "-IF:\...\env_csmar\include" "-L F:\...\env_csmar\libs" -c example_cpp.cpp -o example_cpp.o

This works, and the .o file can be imported as a module on my windows. However, it still says it is compiled with MSVC and under c++14 (from #ifdef _MSVC_LANG). Why is this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

我偏爱纯白色 2025-02-12 09:01:10

您没有在Windows上使用C ++ 98构建。

您之所以感到困惑,是因为默认情况下msvc 总是报告代码>作为 199711 ,出于兼容原因,它使用了什么标准。

可以使用 /zc:__ cplusplus:__ cplusplus 开关。

另外,您可以使用_msvc_lang nofollow noreferrer“> predecined acro 。如果定义了它,则使用MSVC(或编译器模拟它)构建,然后_MSVC_LANG将准确反映要执行的语言标准。

类似……

#ifdef _MSVC_LANG
py::print(_MSVC_LANG)
#else
py::print(__cplusplus)
#endif

应该做的问题。

You did not build using C++98 on Windows.

You got confused because by default MSVC always reports __cplusplus as 199711, no matter what standard it is using, for compatibility reasons.

This behavior can be disabled with the /Zc:__cplusplus switch.

Alternatively, you can use _MSVC_LANG predefined macro. If it is defined, then you are building with MSVC (or a compiler emulating it) and then _MSVC_LANG will accurately reflect the language standard being enforced.

Something like…

#ifdef _MSVC_LANG
py::print(_MSVC_LANG)
#else
py::print(__cplusplus)
#endif

…should do the trick.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文