【问题标题】:Python ImportError when attempting to import sqlite3 module尝试导入 sqlite3 模块时出现 Python ImportError
【发布时间】:2014-07-08 22:22:11
【问题描述】:

我正在尝试为基于 arm 的嵌入式设备交叉编译 Python 2.7.3。我已经成功地编译它(基于这些说明:http://randomsplat.com/id5-cross-compiling-python-for-embedded-linux.html)并且所有测试都在目标设备上通过,所以我相信构建过程可以正常工作。我已经交叉编译了 sqlite3(版本 3.8.5)并将其包含在 python 交叉编译过程中,它似乎很好(它不再列在构建过程结束时未找到的模块中)。

我在实际尝试在目标设备上导入 sqlite3 库时遇到了困难,我收到下面列出的错误(python 使用 -v 标志运行)。

Python 2.7.3 (default, Jul  7 2014, 19:06:12) 
[GCC 3.4.6] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import sqlite3

import sqlite3 # directory /mnt/card/arm-python/lib/python2.7/sqlite3
# /mnt/card/arm-python/lib/python2.7/sqlite3/__init__.pyc matches /mnt/card/arm-python/lib/python2.7/sqlite3/__init__.py
import sqlite3 # precompiled from /mnt/card/arm-python/lib/python2.7/sqlite3/__init__.pyc
# /mnt/card/arm-python/lib/python2.7/sqlite3/dbapi2.pyc matches /mnt/card/arm-python/lib/python2.7/sqlite3/dbapi2.py
import sqlite3.dbapi2 # precompiled from /mnt/card/arm-python/lib/python2.7/sqlite3/dbapi2.pyc
dlopen("/mnt/card/arm-python/lib/python2.7/lib-dynload/datetime.so", 2);
import datetime # dynamically loaded from /mnt/card/arm-python/lib/python2.7/lib-dynload/datetime.so
dlopen("/mnt/card/arm-python/lib/python2.7/lib-dynload/time.so", 2);
import time # dynamically loaded from /mnt/card/arm-python/lib/python2.7/lib-dynload/time.so
dlopen("/mnt/card/arm-python/lib/python2.7/lib-dynload/_sqlite3.so", 2);
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/mnt/card/arm-python/lib/python2.7/sqlite3/__init__.py", line 24, in <module>
    from dbapi2 import *
  File "/mnt/card/arm-python/lib/python2.7/sqlite3/dbapi2.py", line 27, in <module>
    from _sqlite3 import *
ImportError: File not found

它似乎在抱怨“找不到文件”,但我已经浏览了输出中列出的所有路径,所有文件似乎都存在。我可以做些什么来进一步诊断这个问题?

【问题讨论】:

  • 所以_sqlite3.so 存在于lib-dynload 位置?此处的错误消息可能会产生误导,它只是无法加载库文件。
  • 是的,文件存在于/mnt/card/arm-python/lib/python2.7/lib-dynload/_sqlite3.so
  • 加载库看起来确实有问题,因为我将_sqlite3.so 移动到一个临时文件并将datetime.so 复制到_sqlite3.so 作为测试。在导入期间,它现在抱怨模块没有定义函数init_sqlite3,这表明它可以加载库。怀疑是sqlite3的交叉编译有问题。

标签: python sqlite arm cross-compiling embedded-linux


【解决方案1】:

我已经设法让它工作了,虽然我不认为我完全理解发生了什么,我对编译 C/C++ 代码以及整个静态/共享库和链接如何工作并不熟悉,也许有人可以阐明这里实际发生的情况。无论如何,这就是我解决它的方法。

首先我在 python 进程上运行了 strace(Linux 调试工具):

strace /mnt/card/arm-python/bin/python

这会在 python 进程启动时输出大量输出,一旦它稳定下来,我就尝试导入 sqlite 库:

import sqlite3

这将产生更多的输出,其中大部分与打开您正在导入的模块中涉及的文件有关。然后我注意到它设法打开了_sqlite3.so,但不久之后它尝试加载在库路径($LD_LIBRARY_PATH)上找不到的libsqlite3.so

open("/mnt/card/arm-python/lib/python2.7/lib-dynload/_sqlite3.so", O_RDONLY|O_LARGEFILE) = 5
...
open("/lib/libsqlite3.so.0", O_RDONLY)  = -1 ENOENT (No such file or directory)
open("/usr/lib/libsqlite3.so.0", O_RDONLY) = -1 ENOENT (No such file or directory)

我将libsqlite3.so.0.8.6从我的构建机器上交叉编译的sqlite库中的/lib目录复制到嵌入式arm设备上的/mnt/card,并将其重命名为libsqlite3.so.0。然后,我将 /mnt/card 添加到 $LD_LIBRARY_PATH,因为该路径中的现有位置位于只读文件系统上。

然后我尝试再次导入 sqlite3,一切似乎都运行良好。那么lib-dynload里面的东西有什么作用,libsqlite3.so.0也有什么作用呢?

【讨论】:

    猜你喜欢
    • 2012-11-16
    • 2017-06-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-09
    • 2013-12-14
    • 1970-01-01
    • 2021-12-05
    相关资源
    最近更新 更多