【问题标题】:PyInstaller OS Library Dependencies and ChrootPyInstaller 操作系统库依赖项和 Chroot
【发布时间】:2020-06-12 01:19:39
【问题描述】:

PyInstaller documentation 状态

PyInstaller 不包含在任何安装此操作系统时都应该存在的库。例如在 GNU/Linux 中,它不会捆绑来自 /lib 或 /usr/lib 的任何文件,假设这些文件可以在每个系统中找到。

但是,目标环境可能安装了同一组库的不同版本。有没有办法找出 pyisntaller 生成的二进制文件所依赖的所有操作系统库?

我使用 pyisntaller 创建了一个二进制文件my_app/myapp。然后用ldd列出它所依赖的所有.so文件,并将它们全部复制到分发目录中。在我的假设中,生成的 dist 目录可以用作 chroot 环境的根目录。但是它不起作用。

来自ldd 输出:

# ldd my_app/my_app 
    linux-vdso.so.1 (0x00007ffdddc67000)
    libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f6d3342f000)
    libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f6d33212000)
    libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6d32e21000)
    /lib64/ld-linux-x86-64.so.2 (0x00007f6d3384e000)

看起来只有这些库是必需的依赖项:

# ls -l lib
-rwxr-xr-x 1 root root  170960 Apr 16  2018 ld-2.27.so
-rwxr-xr-x 1 root root 2030544 Apr 16  2018 libc-2.27.so
lrwxrwxrwx 1 root root      12 Apr 16  2018 libc.so.6 -> libc-2.27.so
-rw-r--r-- 1 root root   14560 Apr 16  2018 libdl-2.27.so
lrwxrwxrwx 1 root root      13 Apr 16  2018 libdl.so.2 -> libdl-2.27.so
lrwxrwxrwx 1 root root      14 May 23  2017 libz.so.1 -> libz.so.1.2.11
-rw-r--r-- 1 root root  116960 May 23  2017 libz.so.1.2.11

当我运行chroot ./ /lib/ld-2.27.so /my_app/my_app时,屏幕显示

[26499] PyInstaller Bootloader 3.x
[26499] LOADER: Cannot get fullpath for /my_app/my_app
[26499] LOADER: homepath is /my_app
[26499] LOADER: _MEIPASS2 is NULL
[26499] LOADER: archivename is /my_app/my_app
[26499] LOADER: Extracting binaries
[26499] LOADER: Executing self as child
[26499] LOADER: set _MEIPASS2 to /my_app
[26499] LOADER: LD_LIBRARY_PATH=/my_app
[26499] LOADER: Registering signal handlers
[26500] Failed to exec: No such file or directory

最后一行应该是[99] PyInstaller Bootloader 3.x,程序应该从那里继续。

我知道 chroot 会起作用,因为它会在复制整个 / 时起作用。

【问题讨论】:

    标签: python dependencies pyinstaller chroot


    【解决方案1】:

    错误消息Failed to exec: No such file or directory 是由于ld 必须位于路径/lib64/ld-linux-x86-64.so.2。尽管它指向的实际文件实际上是ld-2.27.so

    ls -l /lib64/
    /lib64/ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.27.so
    

    修复后,新的错误消息会更有意义,它指向丢失的libpthread...

    深入研究 PyInstaller 内部,它在内部至少打包了三个其他二进制可执行文件:一个 python 解释器和两个用于引导加载程序的二进制文件。因此,在 PyInstaller 使用的 python 上运行ldd,并在站点包目录下的这两个引导加载程序上运行,这将是所需的所有依赖项。以上libpthread...是python解释器所需要的。

    ldd 输出显示它希望库文件位于/lib/x86_64-linux-gnu/ 下,而不是/lib/

    lib/lib64/最终的内容是:

    # ls -l lib
    -rwxr-xr-x    170960 Apr 16  2018 ld-2.27.so
    -rwxr-xr-x   2030544 Apr 16  2018 libc-2.27.so
    lrwxrwxrwx        12 Apr 16  2018 libc.so.6 -> libc-2.27.so
    -rw-r--r--     14560 Apr 16  2018 libdl-2.27.so
    lrwxrwxrwx        13 Apr 16  2018 libdl.so.2 -> libdl-2.27.so
    lrwxrwxrwx        17 Sep 10 11:05 libexpat.so.1 -> libexpat.so.1.6.7
    -rw-r--r--    202880 Sep 10 11:05 libexpat.so.1.6.7
    -rw-r--r--   1700792 Apr 16  2018 libm-2.27.so
    lrwxrwxrwx        12 Apr 16  2018 libm.so.6 -> libm-2.27.so
    -rwxr-xr-x    144976 Apr 16  2018 libpthread-2.27.so
    lrwxrwxrwx        18 Apr 16  2018 libpthread.so.0 -> libpthread-2.27.so
    -rw-r--r--     10592 Apr 16  2018 libutil-2.27.so
    lrwxrwxrwx        15 Apr 16  2018 libutil.so.1 -> libutil-2.27.so
    lrwxrwxrwx        14 May 23  2017 libz.so.1 -> libz.so.1.2.11
    -rw-r--r--    116960 May 23  2017 libz.so.1.2.11
    lrwxrwxrwx         1 Feb 27 17:14 x86_64-linux-gnu -> .
    
    # ls -l lib64
    lrwxrwxrwx   32 Apr 16  2018 ld-linux-x86-64.so.2 -> /lib/x86_64-linux-gnu/ld-2.27.so
    

    这似乎运作良好。

    此目录可能会在内核的裸机上运行,​​而无需在 rootfs 中包含其他用户空间应用程序。它变得非常有趣。

    【讨论】:

    • 构建中排除的库由 pyinstaller 文件 PyInstaller/depend/dylib.py 中名为 _unix_excludes 的变量列出。在填充中注释掉行将允许包含这些库。该变量适用于 Linux 操作系统,其他操作系统的其他变量在同一个文件中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-21
    • 1970-01-01
    • 2021-12-31
    • 2017-03-09
    • 2021-01-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多