Ubuntu22.04+Python3.10+Boost1.80编译警告问题求助
解决Ubuntu 22.04 + Python 3.10 + Boost 1.80下的PyEval_CallMethod弃用警告
问题背景
从Ubuntu 18.04(Boost 1.76 + Python 3.6)迁移到Ubuntu 22.04(Boost 1.80 + Python 3.10)后,编译代码时只要引入<boost/python.hpp>就会触发PyEval_CallMethod的弃用警告。Boost是通过以下命令编译的:
./bootstrap.sh --with-python=/usr/bin/python3.10 ./b2 --prefix=/tmp/ --with-python
具体警告信息:
/mnt/fs/users/iliak/system_clean/Strategies/../External/include/boost/python/call_method.hpp:61:26: warning: ‘PyObject* PyEval_CallMethod(PyObject*, const char*, const char*, ...)’ is deprecated [-Wdeprecated-declarations] 61 | PyObject* const result = | ~~~~~~~~~~~~~~~~~^~~ 62 | PyEval_CallMethod( | ~~~~~~~~~~~~~~~~~~ 63 | self | ~~~~ 64 | , const_cast<char*>(name) | ~~~~~~~~~~~~~~~~~~~~~~~~~ 65 | , const_cast<char*>("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")") | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 66 | BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil) | ~ In file included from /usr/include/python3.10/Python.h:130, from /mnt/fs/users/iliak/system_clean/Strategies/../External/include/boost/python/detail/wrap_python.hpp:178, from /mnt/fs/users/iliak/system_clean/Strategies/../External/include/boost/python/detail/prefix.hpp:13, from /mnt/fs/users/iliak/system_clean/Strategies/../External/include/boost/python/args.hpp:8, from /mnt/fs/users/iliak/system_clean/Strategies/../External/include/boost/python.hpp:11, from /mnt/fs/users/iliak/system_clean/Strategies/../Engine/CandlesManager.h:7:
原因分析
Python 3.10开始将PyEval_CallMethod标记为弃用API,官方推荐使用PyObject_CallMethod或PyObject_CallMethodObjArgs替代;而Boost.Python 1.80的call_method.hpp源码中仍在调用这个已被弃用的函数,因此编译时触发警告。之前的Python 3.6环境中该函数尚未被标记弃用,所以没有这个问题。
解决办法
1. 临时屏蔽弃用警告
如果暂时不想修改Boost源码或升级版本,可以通过以下两种方式屏蔽警告:
- 编译选项添加:在编译命令中加入
-Wno-deprecated-declarations,直接忽略所有弃用警告。 - 宏定义屏蔽:在包含
<boost/python.hpp>之前定义Boost提供的屏蔽宏,确保头文件顺序正确:
#define PY_SSIZE_T_CLEAN #include <Python.h> #define BOOST_PYTHON_DISABLE_DEPRECATED_WARNINGS #include <boost/python.hpp>
2. 升级Boost到修复版本
Boost 1.81及后续版本已经修复了这个问题,将PyEval_CallMethod替换为Python 3.10兼容的API。可以下载最新稳定版Boost,重新编译安装:
# 下载并解压最新Boost源码 ./bootstrap.sh --with-python=/usr/bin/python3.10 ./b2 --prefix=/your/install/path --with-python sudo ./b2 install
3. 手动修改Boost源码并重新编译
如果无法升级Boost,可以手动修改boost/python/call_method.hpp中的代码,将PyEval_CallMethod替换为PyObject_CallMethod:
找到文件中调用PyEval_CallMethod的代码段(对应警告行61-66),替换为:
PyObject* const result = PyObject_CallMethod( self, const_cast<char*>(name), const_cast<char*>("(" BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FIXED, "O") ")"), BOOST_PP_REPEAT_1ST(N, BOOST_PYTHON_FAST_ARG_TO_PYTHON_GET, nil) );
修改完成后重新执行Boost的编译安装命令即可。
内容的提问来源于stack exchange,提问作者Ilia
相关产品推荐
相关产品推荐

