问题现象
$ devtool modify u-boot
File: '/usr/lib/python3.8/sysconfig.py', lineno: 431, function: _init_posix
0427:def _init_posix(vars):
0428: """Initialize the module as appropriate for POSIX systems."""
0429: # _sysconfigdata is generated at build time, see _generate_posix_vars()
0430: name = _get_sysconfigdata_name()
*** 0431: _temp = __import__(name, globals(), locals(), ['build_time_vars'], 0)
0432: build_time_vars = _temp.build_time_vars
0433: vars.update(build_time_vars)
0434:
0435:def _init_non_posix(vars):
Exception: ModuleNotFoundError: No module named '_sysconfigdata'
分析定位
通过 --keep-temp
选项保留日志等临时文件以辅助定位:
$ devtool modify --keep-temp u-boot
ERROR: Logfile of failure stored in: /home/runsisi/working/bmc/openbmc-2.8.0/build/romulus/tmp/work/romulus-openbmc-linux-gnueabi/u-boot-aspeed/1_v2016.07+gitAUTOINC+59428fe010-r0/devtooltmp-68hlmktt/temp/log.do_unpack.2424525
NOTE: Tasks Summary: Attempted 114 tasks of which 112 didn't need to be rerun and 1 failed.
INFO: Preserving temporary directory /home/runsisi/working/bmc/openbmc-2.8.0/build/romulus/tmp/work/romulus-openbmc-linux-gnueabi/u-boot-aspeed/1_v2016.07+gitAUTOINC+59428fe010-r0/devtooltmp-68hlmktt
ERROR: Extracting source for u-boot-aspeed failed
但是即使分析日志,也看不出来太多问题。
devtool 实际上只是 bitbake 的一个客户端,会自动启动 bitbake 服务端(如果没有启动的话),我们也可以手工启动:
$ bitbake -m
$ bitbake --server-only
$ ls build/romulus/bitbake.sock
build/romulus/bitbake.sock
$ ps aux | grep bitbake
runsisi 2425021 0.0 0.0 60216 47664 ? S 00:13 0:00 python3 /home/runsisi/working/bmc/openbmc-2.8.0/poky/bitbake/bin/bitbake --server-only
-v, --verbose Enable tracing of shell tasks (with 'set -x'). Also
print bb.note(...) messages to stdout (in addition to
writing them to ${T}/log.do_<task>).
-D, --debug Increase the debug level. You can specify this more
than once. -D sets the debug level to 1, where only
bb.debug(1, ...) messages are printed to stdout; -DD
sets the debug level to 2, where both bb.debug(1, ...)
and bb.debug(2, ...) messages are printed; etc.
Without -D, no debug messages are printed. Note that
-D only affects output to stdout. All debug messages
are written to ${T}/log.do_taskname, regardless of the
debug level.
--server-only Run bitbake without a UI, only starting a server
(cooker) process.
但 bitbake 是多进程架构,没法前台运行:
# bitbake/lib/bb/server/process.py
class BitBakeServer(object):
bb.daemonize.createDaemon(self._startServer, logfile)
devtool 的请求最终发给 bitbake 服务进程进行处理:
# scripts/lib/devtool/standard.py
def modify():
tinfoil = setup_tinfoil
_extract_source(tinfoil)
def _extract_source(tinfoil):
tinfoil.build_targets()
但是,可以通过使用增加日志打印的手段进行调试,修改代码之后需要执行 bitbake -m
杀掉已有的 bitbake 进程,否则新代码不会加载。
通过打印可以确认在 devtool_post_unpack
中调用 sysconfig.get_config_vars()
会出错:
# meta/classes/devtool-source.bbclass
python devtool_post_unpack()
import sysconfig
bb.warn(str(sysconfig.get_config_vars()))
再进一步,是 _get_sysconfigdata_name
拿到模块名是 _sysconfigdata
,通过显式的将 name
赋值为 _sysconfigdata__x86_64-linux-gnu
问题得以规避:
# /usr/lib/python3.8/sysconfig.py
def _get_sysconfigdata_name():
return os.environ.get('_PYTHON_SYSCONFIGDATA_NAME',
'_sysconfigdata_{abi}_{multiarch}'.format(
abi=sys.abiflags,
multiarch=getattr(sys.implementation, '_multiarch', ''),
))
def _init_posix(vars):
"""Initialize the module as appropriate for POSIX systems."""
# _sysconfigdata is generated at build time, see _generate_posix_vars()
name = _get_sysconfigdata_name()
name = '_sysconfigdata__x86_64-linux-gnu'
_temp = __import__(name, globals(), locals(), ['build_time_vars'], 0)
build_time_vars = _temp.build_time_vars
vars.update(build_time_vars)
通过打印可知 sys.implementation
的值并不为空,问题显然出在 _PYTHON_SYSCONFIGDATA_NAME
环境变量上,该环境变量被显示赋值成了 _sysconfigdata
,实际上,在代码里能找到对该环境变量相关的处理和说明(注意 u-boot-aspeed.inc 显式 inherit 了 python3native):
# meta/lib/oe/prservice.py
def prserv_make_conn(d, check = False):
# Otherwise this fails when called from recipes which e.g. inherit python3native (which sets _PYTHON_SYSCONFIGDATA_NAME) with:
# No module named '_sysconfigdata'
if '_PYTHON_SYSCONFIGDATA_NAME' in os.environ:
del os.environ['_PYTHON_SYSCONFIGDATA_NAME']
解决方案
照葫芦画瓢,对 devtool_post_unpack
增加相应的处理(新版本 OpenBMC python3native.bbclass 已没有对 _PYTHON_SYSCONFIGDATA_NAME
的处理):
# meta/classes/devtool-source.bbclass
python devtool_post_unpack() {
# Otherwise this fails when called from recipes which e.g. inherit python3native (which sets _PYTHON_SYSCONFIGDATA_NAME) with:
# No module named '_sysconfigdata'
if '_PYTHON_SYSCONFIGDATA_NAME' in os.environ:
del os.environ['_PYTHON_SYSCONFIGDATA_NAME']
至此,问题得以解决。
当然,通过上面的分析可知,还有一个更简单的规避手段:
$ sudo ln -s /usr/lib/python3.8/_sysconfigdata__x86_64-linux-gnu.py /usr/lib/python3.8/_sysconfigdata.py
记得执行 bitbake -m
以启动新的 bitbake 服务进程。
最后修改于 2024-01-03