我试图用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?
发布评论
评论(1)
您没有在Windows上使用C ++ 98构建。
您之所以感到困惑,是因为默认情况下msvc 总是报告代码>作为
199711
,出于兼容原因,它使用了什么标准。可以使用
/zc:__ cplusplus:__ cplusplus
开关。另外,您可以使用_msvc_lang nofollow noreferrer“> predecined acro 。如果定义了它,则使用MSVC(或编译器模拟它)构建,然后_MSVC_LANG将准确反映要执行的语言标准。
类似……
应该做的问题。
You did not build using C++98 on Windows.
You got confused because by default MSVC always reports
__cplusplus
as199711
, 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…
…should do the trick.