【发布时间】:2011-07-29 05:09:09
【问题描述】:
boost.python 如何处理 Python 3?只有 Python 2 吗?
【问题讨论】:
标签: c++ python boost python-3.x boost-python
boost.python 如何处理 Python 3?只有 Python 2 吗?
【问题讨论】:
标签: c++ python boost python-3.x boost-python
较新版本的 Boost 应该可以在 Python V3.x 上正常工作。这种支持是在很久以前添加的,我相信在 2009 年成功的 Google Summer of Code 项目之后。
将 Python V3 与 Boost 一起使用的方法是通过添加实例来正确配置构建系统:
using python : 3.1 : /your_python31_root ;
到您的 user-config.jam 文件。
【讨论】:
./bootstrap.sh --with-python-version=X.Y 安装在系统上并且可以检测到(在通常的位置),您可以简单地执行此操作。如果没有,您可以在命令行上指定这些选项(而不是编辑文件)。见./bootstrap.sh --help
为了做到这一点,需要使用 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 ;
这对于 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
你只需要第一个包含目录。
然后从头开始构建提升。 (对不起。)我将它安装到 /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()
【讨论】:
project-config.jam 文件。即,调整using python :... 行以列出python3 解释器的每个二进制可执行文件、它的包含文件夹和lib 目录。重新构建 boost 并安装后,我的项目使用 python 3 正确构建。谢谢!
是的,这个问题已经很老了,但是我必须做一些没有在此处的任何答案中指定的事情(尽管它是建立在一些建议的基础上的),所以我会快速记下我的整个过程:
tar --bzip2 -xf boost_1_68_0.tar.bz2(您希望文件夹临时存放的位置)cd boost_1_68_0./bootstrap.sh --with-python-version=3.6 --prefix=/usr/local./b2sudo ./bjam installcp 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 错误。
希望这可以帮助某人!
【讨论】:
如果您收到“错误:/python_for_extension 没有最佳替代方案”,请确保有
using python : 3.4 : C:\\Python34 : C:\\Python34\\include : C:\\Python34\\libs ;
only in user-config.jam 在您的主路径中,其他任何地方都没有。 使用 mingw (toolset=gcc) 或 MSVC (toolset=msvc) 在 windows 下编译时使用双反斜杠。 使用 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
虽然我更愿意不使用 boost_python dll,但使用静态的 python 快速入门示例对我不起作用。
我没有在 linux 上尝试过,但那里应该更简单。
【讨论】:
您甚至可以通过
指定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 版本。
【讨论】:
当 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")
【讨论】:
请参阅this 以了解如何使用python 构建boost。它展示了使用 Visual Studio 10.0 (2010) 构建 python2 的方法。但我对我目前正在从事的项目执行相同的程序,它适用于 python 3.5 和 Visual Studio 14.1 (2017)。
如果您在构建 python boost 项目时得到 this error,只需在项目属性中将 BOOST_ALL_NO_LIB 值添加到 Preprocessor Definitions(在 C\C++ > 预处理器选项卡中)。
另外,不要忘记将boost .dll 文件位置添加到您的系统路径中。
【讨论】:
在我的例子中添加“使用 Python:3 等”进入我的主目录中的 user-config.jam 不起作用。我不得不将这一行添加到 project-config.jam 中,它位于未打包的 boost 的根目录中。
具体是:
使用python:3.9:/usr/bin/python3:/usr/include/python3.9:/usr/lib;
boost的版本是1_78_0
【讨论】: