【问题标题】:Boost and Python 3.xBoost 和 Python 3.x
【发布时间】:2011-07-29 05:09:09
【问题描述】:

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

【问题讨论】:

标签: c++ python boost python-3.x boost-python


【解决方案1】:

较新版本的 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
【解决方案2】:

为了做到这一点,需要使用 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()

【讨论】:

  • 这对我很有帮助。如您所指,让我的项目使用自定义安装的所有内容(gcc、python3、boost)构建的关键是编辑我的project-config.jam 文件。即,调整using python :... 行以列出python3 解释器的每个二进制可执行文件、它的包含文件夹和lib 目录。重新构建 boost 并安装后,我的项目使用 python 3 正确构建。谢谢!
  • 很好解释。很有帮助!
【解决方案3】:

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

  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 错误。

希望这可以帮助某人!

【讨论】:

【解决方案4】:

如果您收到“错误:/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 上尝试过,但那里应该更简单。

【讨论】:

    【解决方案5】:

    您甚至可以通过

    指定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 版本。

    【讨论】:

      【解决方案6】:

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

      【讨论】:

        【解决方案7】:

        请参阅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 文件位置添加到您的系统路径中。

        【讨论】:

          【解决方案8】:

          在我的例子中添加“使用 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

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2010-12-19
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多