提升和 Python 3.x

30
boost.python如何处理Python 3? 它只支持Python 2吗?

1
似乎他们正在处理这个问题。http://www.boost.org/doc/libs/1_46_0/libs/python/doc/news.html - mkaes
8个回答

23

较新版本的Boost与Python V3.x兼容良好。这一支持很久以前就加入了,我相信是在2009年一个成功的Google Summer of Code项目之后。

使用Python V3和Boost的方法是通过正确配置构建系统来实现,例如添加:

using python : 3.1 : /your_python31_root ;

将其添加到你的 user-config.jam 文件。


5
如果系统中已经安装了Python并且可以检测到(在通常的位置),您只需要运行./bootstrap.sh --with-python-version=X.Y即可。如果没有安装,您可以在命令行上指定这些选项(而不是编辑文件)。请参见 ./bootstrap.sh --help - miguel.martin
原来,Python路径和分号之间的空格很重要! - RPM

10

为了做到这一点,需要使用Python3编译libboostpython。但是,在Ubuntu 16.04中内置的Boost 1.58不支持此功能。因此,请确保下载最新的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 ;

对于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实际上是使用g ++参数“-lboost”链接到libboostpython。但在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()

这对我非常有帮助。让我的项目能够使用自定义安装的所有内容(gcc、python3、boost)的关键是编辑我的 project-config.jam 文件,正如你所指示的那样。即调整 using python: 行以列出每个 Python3 解释器的二进制可执行文件、包含它的 include 文件夹和 lib 目录。在重新构建 Boost 并安装后,我的项目可以正确地使用 Python 3 进行构建。谢谢! - ofloveandhate
讲解得很清楚,非常有帮助! - Coderji

7

是的,这个问题很老了,但是我必须做一些在这里的任何答案中都没有指定的事情(尽管它是建立在一些建议的基础上),所以我会快速记录下我的整个过程:

  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错误,该错误与未定义的符号有关。

希望这能对后来的人有所帮助!


这个特定的答案对我有效:https://dev59.com/5Wcs5IYBdhLWcg3wym4h#24086375 我使用的是最新版本boost_1_71_0。 - Pulkit Pahwa
获取可用选项 ./bootstrap.sh --help。与 Python 相关的有 3 个选项:--with-python=PYTHON、--with-python-root=DIR 和 --with-python-version=X.Y。如果命令选项有效,则更倾向于修改 user-config.jam。后者可能存在潜在问题,如果您的 Python3 从一个源更改为另一个源。 - Kemin Zhou

4
如果你收到“error: No best alternative for /python_for_extension”的错误提示,请确保已经安装好了相关的扩展。
using python : 3.4 : C:\\Python34 : C:\\Python34\\include : C:\\Python34\\libs ;

只在用户配置文件 user-config.jam 中使用,并且不要在其他地方使用。 在使用 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上尝试过,但那里应该更为简单。

3
你可以通过以下方式指定 Python 发行版:
./bootstrap.sh --with-python=<path to your python binary>

e.g.

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

针对您系统的python3或

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

用于当前活动虚拟环境 Python 版本的 Python 版本。


1
当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")

1
在我的情况下,将“Using Python: 3等”添加到位于我的主目录中的user-config.jam文件中并没有起作用。相反,我不得不将该行添加到位于未打包的boost根目录中的project-config.jam文件中。
具体来说,该行是: using python: 3.9: /usr/bin/python3: /usr/include/python3.9: /usr/lib;
而boost的版本是1_78_0。

1

请参考this,了解如何使用python构建boost。该文档展示了如何在Visual Studio 10.0 (2010)中使用python2进行构建。但是我按照相同的步骤在我的项目中使用python 3.5和Visual Studio 14.1 (2017)进行构建,一切正常。

如果您在构建Python Boost项目时遇到this error错误,请在项目属性中的C\C++ > 预处理器选项卡下添加BOOST_ALL_NO_LIB值。
同时,请不要忘记将boost .dll文件路径添加到系统路径中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接