Boost 和 Python 3.x

发布于 2024-10-30 05:06:36 字数 46 浏览 5 评论 0原文

boost.python 如何处理 Python 3?只有Python 2吗?

How does boost.python deal with Python 3? Is it Python 2 only?

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

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

发布评论

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

评论(8

云之铃。 2024-11-06 05:06:36

较新版本的 Boost 应该可以与 Python V3.x 一起正常工作。这种支持已经在很久以前添加了,我相信是在 2009 年成功的 Google Summer of Code 项目之后。

将 Python V3 与 Boost 一起使用的方法是通过添加以下内容来正确配置构建系统: 例如:

using python : 3.1 : /your_python31_root ;

到您的用户配置中。卡纸文件。

Newer versions of Boost should work fine with Python V3.x. This support has been added quite some time ago, I believe after a successful Google Summer of Code project back in 2009.

The way to use Python V3 with Boost is to properly configure the build system by adding for instance:

using python : 3.1 : /your_python31_root ;

to your user-config.jam file.

是伱的 2024-11-06 05:06:36

为此,需要使用 python3 构建 libboostpython。 这不适用于 boost 1.58(Ubuntu 16.04 附带),因此请确保下载最新的 boost 发行版。我刚刚用 boost_1_64_0 做到了这一点。

如上所述,在您的 boost 代码分发中找到“user-config.jam”文件,并将其复制到 $HOME。

cp /path/to/boost_1_64_0/tools/build/example/user-config.jam $HOME

然后编辑 python 行(最后一行),如下所示:

using python : 3.5 : /usr/bin/python3 : /usr/include/python3.5m : /usr/lib ;

This is true for Ubuntu 16.04。您可以使用 pkg-config 找到正确的包含目录。

user@computer > pkg-config --cflags python3
-I/usr/include/python3.5m -I/usr/include/x86_64-linux-gnu/python3.5m

你只需要第一个包含目录。

然后从头开始构建Boost。 (抱歉。)我将其安装到 /usr/local

cd /path/to/boost_1_64_0
./bootstrap.sh --prefix=/usr/local
./b2 
sudo ./b2 install

现在跳入 python 示例目录,并构建教程

cd /path/to/boost_1_64_0/libs/python/example/tutorial
bjam

如果您安装了 boost 系统,则将无法正确构建,因为在幕后,bjam 正在使用链接到 libboostpython g++ 参数“-lboost”。但是,在 Ubuntu 16.04 上,这只会找到“/usr/lib/x86_64-linux-gnu/libboost_python-py27.so.1.58.0”,然后 python 绑定将无法加载。事实上,你会得到他的错误:

ImportError: /usr/lib/x86_64-linux-gnu/libboost_python-py27.so.1.58.0: undefined symbol: PyClass_Type

如果你想查看 bjam 正在使用的 g++ 命令,请执行以下操作:

user@computer > bjam -d2 -a | grep g++
g++  -ftemplate-depth-128 -O0 -fno-inline -Wall -g -fPIC -I/usr/include/python3.5m -c -o "hello.o" "hello.cpp"
g++ -o hello_ext.so -Wl,-h -Wl,hello_ext.so -shared -Wl,--start-group hello.o  -Wl,-Bstatic  -Wl,-Bdynamic -lboost_python -ldl -lpthread -lutil -Wl,--end-group

在这里我们看到问题,你需要在“-lboost_python”之前添加“-L/usr/includ/lib” 。因此,执行此命令以正确链接共享库:

g++ -o hello_ext.so -Wl,-h -Wl,hello_ext.so -shared -Wl,--start-group hello.o  -Wl,-Bstatic  -Wl,-Bdynamic -L/usr/local/lib -lboost_python -ldl -lpthread -lutil -Wl,--end-group

您可能需要重新运行 ldconfig (或重新启动)

sudo ldconfig

并且您终于准备好了:

user@computer > python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import hello_ext
>>> hello_ext.greet()
'hello, world'
>>> exit()

libboostpython needs to be built with python3 in order to do this. This doesn't work with boost 1.58 (which comes with Ubuntu 16.04), so make sure you download the latest boost distribution. I just did this with boost_1_64_0.

As mentioned above, find the file "user-config.jam" in you boost code distribution, and copy it to $HOME.

cp /path/to/boost_1_64_0/tools/build/example/user-config.jam $HOME

Then edit the python line (the last line) so that is says:

using python : 3.5 : /usr/bin/python3 : /usr/include/python3.5m : /usr/lib ;

This is correct for Ubuntu 16.04. You can use pkg-config to find the correct include directory.

user@computer > pkg-config --cflags python3
-I/usr/include/python3.5m -I/usr/include/x86_64-linux-gnu/python3.5m

And you only need the first include directory.

Then build boost from scratch. (Sorry.) I install it to /usr/local

cd /path/to/boost_1_64_0
./bootstrap.sh --prefix=/usr/local
./b2 
sudo ./b2 install

Now jump into the python example directory, and build the tutorial

cd /path/to/boost_1_64_0/libs/python/example/tutorial
bjam

This will not build correctly if you have a system install of boost, because, under the hood, bjam is linking to libboostpython using the g++ parameter "-lboost". But, on Ubuntu 16.04, this will just go and find "/usr/lib/x86_64-linux-gnu/libboost_python-py27.so.1.58.0", and then the python bindings will fail to load. In fact, you'll get his error:

ImportError: /usr/lib/x86_64-linux-gnu/libboost_python-py27.so.1.58.0: undefined symbol: PyClass_Type

If you want to see the g++ commands that bjam is using, do this:

user@computer > bjam -d2 -a | grep g++
g++  -ftemplate-depth-128 -O0 -fno-inline -Wall -g -fPIC -I/usr/include/python3.5m -c -o "hello.o" "hello.cpp"
g++ -o hello_ext.so -Wl,-h -Wl,hello_ext.so -shared -Wl,--start-group hello.o  -Wl,-Bstatic  -Wl,-Bdynamic -lboost_python -ldl -lpthread -lutil -Wl,--end-group

Here we see the problem, you need "-L/usr/includ/lib" just before "-lboost_python". So execute this to link the shared library correctly:

g++ -o hello_ext.so -Wl,-h -Wl,hello_ext.so -shared -Wl,--start-group hello.o  -Wl,-Bstatic  -Wl,-Bdynamic -L/usr/local/lib -lboost_python -ldl -lpthread -lutil -Wl,--end-group

You may need to rerun ldconfig (or reboot)

sudo ldconfig

And you are finally ready to go:

user@computer > python3
Python 3.5.2 (default, Nov 17 2016, 17:05:23) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import hello_ext
>>> hello_ext.greet()
'hello, world'
>>> exit()
宛菡 2024-11-06 05:06:36

是的,这个问题非常老了,但是我必须做一些这里的任何答案中都没有指定的事情(尽管它是根据一些建议构建的),所以我会快速记下我的整个过程:

  1. 下载 boost_X_Y_Z。 tar.bz2(我使用了 boost 1.68.0)
  2. tar --bzip2 -xf boost_1_68_0.tar.bz2(您希望文件夹临时放置的位置)
  3. cd boost_1_68_0
  4. ./bootstrap.sh --with-python-version=3.6 --prefix=/usr/local
  5. ./b2
  6. sudo ./bjam install
  7. cp tools/build/example/user-config.jam $HOME,然后修改此文件的内容为 using python : 3.6 : /usr/bin/python3 : /usr/include/python3 .6m : /usr/lib ; (或适合您环境的任何文件夹)

给定此 C++ 源文件 BoostPythonHelloWorld.cpp

#include <boost/python.hpp>

char const* say_hi()
{
    return "Hi!";
}

BOOST_PYTHON_MODULE(BoostPythonHelloWorld)
{
    boost::python::def("say_hi", say_hi);
}

以及此 Python 脚本 BoostPythonHelloWorld.py:

import BoostPythonHelloWorld
print(BoostPythonHelloWorld.say_hi())

它可以这样编译和运行:

gcc -c -fPIC -I/path/to/boost_1_68_0 -I/usr/include/python3.6 /other_path/to/BoostPythonHelloWorld.cpp
gcc -shared -Wall -Werror -Wl,--export-dynamic BoostPythonHelloWorld.o -L/path/to/boost_1_68_0/stage/lib -lboost_python36 -o BoostPythonHelloWorld.so
python3 BoostPythonHelloWorld.py

对我来说不同的部分是 -Wl,--export-dynamic BoostPythonHelloWorld.o,我在其他地方没有看到过,我是收到有关未定义符号的 Python 错误,直到我添加了该符号。

希望这可以帮助某人!

Yes this question is super old, but I had to do something that wasn't specified in any of the answers here (though it was built off some of the suggestions), so I'll quickly jot down my entire process:

  1. Download boost_X_Y_Z.tar.bz2 (I used boost 1.68.0)
  2. tar --bzip2 -xf boost_1_68_0.tar.bz2 (where you want folder to be temporarily)
  3. cd boost_1_68_0
  4. ./bootstrap.sh --with-python-version=3.6 --prefix=/usr/local
  5. ./b2
  6. sudo ./bjam install
  7. cp tools/build/example/user-config.jam $HOME, then modify the contents of this file to say using python : 3.6 : /usr/bin/python3 : /usr/include/python3.6m : /usr/lib ; (or whatever folders are appropriate for your environment)

Given this C++ source file BoostPythonHelloWorld.cpp:

#include <boost/python.hpp>

char const* say_hi()
{
    return "Hi!";
}

BOOST_PYTHON_MODULE(BoostPythonHelloWorld)
{
    boost::python::def("say_hi", say_hi);
}

And this Python script BoostPythonHelloWorld.py:

import BoostPythonHelloWorld
print(BoostPythonHelloWorld.say_hi())

It can be compiled and ran as such:

gcc -c -fPIC -I/path/to/boost_1_68_0 -I/usr/include/python3.6 /other_path/to/BoostPythonHelloWorld.cpp
gcc -shared -Wall -Werror -Wl,--export-dynamic BoostPythonHelloWorld.o -L/path/to/boost_1_68_0/stage/lib -lboost_python36 -o BoostPythonHelloWorld.so
python3 BoostPythonHelloWorld.py

The part that was different for me was -Wl,--export-dynamic BoostPythonHelloWorld.o, I had not seen that anywhere else, and I was getting a Python error concerning an undefined symbol until I added that.

Hope this helps someone down the line!

谎言月老 2024-11-06 05:06:36

如果您收到“错误:没有 /python_for_extension 的最佳替代方案”,请确保

using python : 3.4 : C:\\Python34 : C:\\Python34\\include : C:\\Python34\\libs ;

仅在用户配置中.jam 位于您的主路径中,而不是其他地方。
在windows下用mingw(toolset=gcc)或MSVC(toolset=msvc)编译时使用双反斜杠。
使用 cmd 而不是 msys 进行编译,如果您还安装了 python 2.7,请将其从该 shell 的 PATH 中删除。
首先

bootstrap.bat gcc/msvc

假设您通过 PATH 可以使用 gcc/msvc 工具(/ 作为替代方案,但只使用一个,或者离开)

然后您也可以

booststrap.sh --with-bjam=b2

在 msys 中生成一个project-config.jam,但需要将其编辑为删除“using python”和“/usr”,..

然后下面的“

b2 variant=debug/shared link=static/shared toolset=gcc/msvc > b2.log

使用静态python快速入门示例”对我不起作用,尽管我更愿意不使用boost_python dll。

我没有在linux上尝试过,但那里应该更简单。

If you get "error: No best alternative for /python_for_extension" be sure to have

using python : 3.4 : C:\\Python34 : C:\\Python34\\include : C:\\Python34\\libs ;

only in user-config.jam in your home path and nowhere else.
Use double backslashes when compiling under windows with mingw (toolset=gcc) or MSVC (toolset=msvc).
Compile with cmd, not msys, and if you also have python 2.7 installed remove that from PATH in that shell.
First do

bootstrap.bat gcc/msvc

assuming you have the gcc/msvc tools available via PATH (/ for the alternatives, but use only one, or leave away)

Afterward you can also do

booststrap.sh --with-bjam=b2

in msys to generate a project-config.jam, but need to edit it to remove the "using python" and "/usr",..

Then the following

b2 variant=debug/shared link=static/shared toolset=gcc/msvc > b2.log

With static the python quickstart examples did not work for me, although I would prefer to do without the boost_python dll.

I did not try on linux, but it should be more straightforward there.

天涯沦落人 2024-11-06 05:06:36

指定 python 发行版

./bootstrap.sh --with-python=<path to your python binary>

您甚至可以通过例如

./bootstrap.sh --with-python=python3

对于您系统的 python3 或

./bootstrap.sh --with-python=$VIRTUAL_ENV/bin/python

当前活动的虚拟环境 python 的 python 版本。

You can even specify the python distribution via

./bootstrap.sh --with-python=<path to your python binary>

e.g.

./bootstrap.sh --with-python=python3

for your system's python3 or

./bootstrap.sh --with-python=$VIRTUAL_ENV/bin/python

for the python version of your currently active virtual env python.

黑寡妇 2024-11-06 05:06:36

请参阅了解如何使用python构建boost。它展示了使用 Visual Studio 10.0 (2010) 使用 python2 进行构建的方法。但我对我当前正在处理的项目执行了相同的过程,它在 python 3.5 和 Visual Studio 14.1 (2017) 中运行良好。

如果您在构建时遇到此错误 python boost 项目,只需将 BOOST_ALL_NO_LIB 值添加到项目属性中的预处理器定义(在 C\C++ > 预处理器选项卡内)即可。
另外,不要忘记将 boost.dll 文件位置添加到系统路径中。

Refer this to know how to build boost with python. It shows the way to build with python2 with Visual Studio 10.0 (2010). But I go through the same procedure for a project that I am currently working on and it works fine with python 3.5 and Visual Studio 14.1 (2017).

If you get this error when building your python boost project, just add BOOST_ALL_NO_LIB value to Preprocessor Definitions (inside C\C++ > preprocessor tab) in your project properties.
And also, do not forget to add boost .dll files location to your system path.

弄潮 2024-11-06 05:06:36

当 Python 的路径包含空格时,您将陷入困境。经过大量的尝试和错误,我终于得到了一些可行的东西。看看我的 user-config.jam (它必须位于我的主目录中,bjam 才能找到它):

import toolset : using ;

using python : 3.6
         : \"C:\\Program\ Files\ (x86)\\Microsoft\ Visual\ Studio\\Shared\\Python36_64\\python.exe\"
         : C:\\Program\ Files\ (x86)\\Microsoft\ Visual\ Studio\\Shared\\Python36_64\\include
         : C:\\Program\ Files\ (x86)\\Microsoft\ Visual\ Studio\\Shared\\Python36_64\\libs
         ;

不一致的引用是有意为之的,而且似乎是必需的。有了这个,我可以构建 boost-python 并将其用作 CMakeLists.txt 中的 Boost::python36。尽管如此,仍然存在一个问题:我必须手动链接到 python,即

target_link_libraries(MyTarget
    Boost::boost Boost::python36
"C:/Program Files (x86)/Microsoft Visual Studio/Shared/Python36_64/libs/python36.lib")
target_include_directories(MyTarget PRIVATE
    "C:/Program Files (x86)/Microsoft Visual Studio/Shared/Python36_64/include")

When the path to Python contains spaces, you will be in for quite a ride. After a whole lot of trial and error, I finally managed to get something that works. Behold my user-config.jam (which has to be in my home directory for bjam to find it):

import toolset : using ;

using python : 3.6
         : \"C:\\Program\ Files\ (x86)\\Microsoft\ Visual\ Studio\\Shared\\Python36_64\\python.exe\"
         : C:\\Program\ Files\ (x86)\\Microsoft\ Visual\ Studio\\Shared\\Python36_64\\include
         : C:\\Program\ Files\ (x86)\\Microsoft\ Visual\ Studio\\Shared\\Python36_64\\libs
         ;

The inconsistent quoting is intended and seems to be required. With this I can build boost-python and use it as Boost::python36 in my CMakeLists.txt. Still, one issue remains: I have to link to python manually viz

target_link_libraries(MyTarget
    Boost::boost Boost::python36
"C:/Program Files (x86)/Microsoft Visual Studio/Shared/Python36_64/libs/python36.lib")
target_include_directories(MyTarget PRIVATE
    "C:/Program Files (x86)/Microsoft Visual Studio/Shared/Python36_64/include")
铁憨憨 2024-11-06 05:06:36

在我的例子中添加“使用Python:3等”进入我的主目录中的 user-config.jam 不起作用。我必须将该行添加到 project-config.jam 中,它位于解压后的 boost 的根目录中。

具体来说,该行是:

using python : 3.9 : /usr/bin/python3 : /usr/include/python3.9 : /usr/lib ;

boost的版本是1_78_0

In my case adding "Using Python : 3 etc." into user-config.jam in my home directory didn't work. I had to add the line into project-config.jam instead, which resides in the root directory of unpacked boost.

Specifically the line was:

using python : 3.9 : /usr/bin/python3 : /usr/include/python3.9 : /usr/lib ;

and the version of boost was 1_78_0

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