【问题标题】:The executable file does not find the library if called from the application compiled by Pyinstaller如果从 Pyinstaller 编译的应用程序调用,可执行文件找不到库
【发布时间】:2021-10-08 12:49:04
【问题描述】:

从使用pyinstaller 构建的应用程序运行mysqlbinlog 进程时,会出现以下错误消息:

mysqlbinlog: /opt/myapp/libz.so.1: version `ZLIB_1.2.9 'not found (required by mysqlbinlog)

我进行了几次测试并注意到发生这种情况是因为pyinstaller 在安装应用程序的目录中放置了libz.so.1 的旧版本,而不是mysqlbinlog 所需的版本。如果您删除此文件/opt/myapp/libz.so.1,则问题将得到解决,因为使用的是库的系统版本。

一个简单的解决方案是从捆绑包中删除libz.so.1,但我不确定之后该应用程序能否在不同版本的系统上正常工作。

在通过子进程运行命令时,有什么方法可以强制应用不使用位于应用安装目录中的库?

其他信息:

使用以下命令在 docker 容器 centos:7.2.1511 中构建应用程序:

pyinstaller myapp.py --clean --name=myapp

这个bug在Ubuntu 20.04.3 LTS上稳定模拟

mysqlbinlog 通过子进程运行,命令如下:

subprocess.run(command_args, check = True, shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE)

【问题讨论】:

    标签: python subprocess pyinstaller


    【解决方案1】:

    Linux 有一个环境变量 LD_LIBRARY_PATH,它指定了搜索系统库的目录。 Pyinstaller 以这样一种方式替换此变量,即在包本身中搜索程序所需的库,从而使 Pyinstaller 编译的应用程序的工作独立于系统库。

    同时,LD_LIBRARY_PATH 变量的旧值保存在 LD_LIBRARY_PATH_ORIG 环境变量中。因此,在启动第三方进程时,只需为其设置正确的环境:从 LD_LIBRARY_PATH_ORIG 写入 LD_LIBRARY_PATH 值。

    摘自documentation

    LD_LIBRARY_PATH / LIBPATH 注意事项

    此环境变量用于发现库,它是库搜索路径 - 在 GNU/Linux 和 *BSD LD_LIBRARY_PATH 上使用,在 AIX 上是 LIBPATH。

    如果存在,PyInstaller 将原始值保存到 *_ORIG,然后修改搜索路径,以便捆绑代码首先找到捆绑的库。 但是,如果您的代码执行系统程序,您通常不希望该系统程序加载您的捆绑库(可能与您的系统程序不兼容) - 它应该像通常那样从系统位置加载正确的库。

    因此你需要在用系统程序创建子进程之前恢复原来的路径。

    替换环境变量的代码:

    env = dict(os.environ) # make a copy of the environment
    lp_key = 'LD_LIBRARY_PATH' # for GNU/Linux and *BSD.
    lp_orig = env.get(lp_key + '_ORIG')
    if lp_orig is not None:
        env[lp_key] = lp_orig # restore the original, unmodified value
    else:
        # This happens when LD_LIBRARY_PATH was not set.
        # Remove the env var as a last resort:
        env.pop(lp_key, None)
    p = Popen(system_cmd, ..., env=env) # create the process
    

    【讨论】:

      猜你喜欢
      • 2018-06-08
      • 1970-01-01
      • 2016-10-08
      • 2022-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-04
      • 2019-09-19
      相关资源
      最近更新 更多